Repository: commanded/commanded
Pull request #558 (2024-06-19 22:28:31)

Use TypeProvider for process managers snapshot serialization
Addresses #538 


Patch:
diff --git a/lib/commanded/process_managers/process_manager_instance.ex b/lib/commanded/process_managers/process_manager_instance.ex
index 3772883..0be8789 100644
--- a/lib/commanded/process_managers/process_manager_instance.ex
+++ b/lib/commanded/process_managers/process_manager_instance.ex
@@ -6,7 +6,7 @@ defmodule Commanded.ProcessManagers.ProcessManagerInstance do
   require Logger
 
   alias Commanded.{Application, EventStore, Telemetry}
-  alias Commanded.EventStore.{RecordedEvent, SnapshotData}
+  alias Commanded.EventStore.{RecordedEvent, SnapshotData, TypeProvider}
   alias Commanded.ProcessManagers.{FailureContext, ProcessRouter}
 
   defmodule State do
@@ -551,14 +551,13 @@ defmodule Commanded.ProcessManagers.ProcessManagerInstance do
   defp persist_state(source_version, %State{} = state) do
     %State{
       application: application,
-      process_manager_module: process_manager_module,
       process_state: process_state
     } = state
 
     snapshot = %SnapshotData{
       source_uuid: snapshot_uuid(state),
       source_version: source_version,
-      source_type: Atom.to_string(process_manager_module),
+      source_type: TypeProvider.to_string(process_state),
       data: process_state
     }
 


Test patch:
diff --git a/test/process_managers/process_manager_instance_test.exs b/test/process_managers/process_manager_instance_test.exs
index 7389efb..f01e19a 100644
--- a/test/process_managers/process_manager_instance_test.exs
+++ b/test/process_managers/process_manager_instance_test.exs
@@ -17,11 +17,15 @@ defmodule Commanded.ProcessManagers.ProcessManagerInstanceTest do
   alias Commanded.Registration.LocalRegistry
   alias Commanded.UUID
 
+  alias Commanded.Serialization.ModuleNameTypeProvider
+  alias Commanded.Serialization.TypeProvider.Mock, as: MockTypeProvider
+
   setup :set_mox_global
   setup :verify_on_exit!
 
   setup do
     mock_event_store()
+    mock_type_provider()
 
     {:ok, registry_meta} = start_local_registry()
 
@@ -46,6 +50,12 @@ defmodule Commanded.ProcessManagers.ProcessManagerInstanceTest do
         {:error, :snapshot_not_found}
       end)
 
+      # Ensure a type provider call is made
+      expect(MockTypeProvider, :to_string, fn process_state ->
+        assert %TransferMoneyProcessManager{} = process_state
+        ModuleNameTypeProvider.to_string(process_state)
+      end)
+
       expect(MockEventStore, :record_snapshot, fn _adapter_meta, snapshot ->
         assert %SnapshotData{
                  data: %TransferMoneyProcessManager{
@@ -223,6 +233,20 @@ defmodule Commanded.ProcessManagers.ProcessManagerInstanceTest do
     stub(MockEventStore, :ack_event, fn _event_store, _pid, _event -> :ok end)
   end
 
+  defp mock_type_provider do
+    stub(MockTypeProvider, :to_string, fn struct -> ModuleNameTypeProvider.to_string(struct) end)
+    stub(MockTypeProvider, :to_struct, fn type -> ModuleNameTypeProvider.to_struct(type) end)
+
+    current_type_provider = Application.get_env(:commanded, :type_provider)
+    Application.put_env(:commanded, :type_provider, MockTypeProvider)
+
+    on_exit(fn ->
+      if current_type_provider,
+        do: Application.put_env(:commanded, :type_provider, current_type_provider),
+        else: Application.delete_env(:commanded, :type_provider)
+    end)
+  end
+
   defp start_local_registry do
     {:ok, registry_child_spec, registry_meta} = LocalRegistry.child_spec(MockApplication, [])
 
diff --git a/test/support/mocks.ex b/test/support/mocks.ex
index 6bfad3d..ad36fa5 100644
--- a/test/support/mocks.ex
+++ b/test/support/mocks.ex
@@ -1,3 +1,4 @@
 Mox.defmock(Commanded.EventStore.Adapters.Mock, for: Commanded.EventStore.Adapter)
 Mox.defmock(Commanded.Commands.MockRouter, for: Commanded.Commands.Router)
 Mox.defmock(Commanded.Application.Mock, for: Commanded.Application)
+Mox.defmock(Commanded.Serialization.TypeProvider.Mock, for: Commanded.EventStore.TypeProvider)