@@ -50,6 +50,8 @@ defmodule Trogon.Commanded.TestSupport.CommandHandlerCase do
5050 use ExUnit.CaseTemplate
5151
5252 alias Commanded.Aggregate.Multi
53+ alias Commanded.Middleware.Pipeline
54+ alias Commanded.Middleware.ExtractAggregateIdentity
5355 alias Trogon.Commanded.TestSupport.CommandHandlerCase
5456
5557 using opts do
@@ -106,61 +108,38 @@ defmodule Trogon.Commanded.TestSupport.CommandHandlerCase do
106108 end
107109 end
108110
109- def assert_events (
110- initial_events ,
111- command ,
112- expected_events ,
113- aggregate_module ,
114- command_handler_module
115- ) do
116- assert { :ok , _state , events } =
117- aggregate_run (
118- aggregate_module ,
119- command_handler_module ,
120- initial_events ,
121- command
122- )
123-
124- actual_events = List . wrap ( events )
125- expected_events = List . wrap ( expected_events )
126-
127- assert actual_events == expected_events
128- end
129-
130- def assert_state (
131- initial_events ,
132- command ,
133- expected_state ,
134- aggregate_module ,
135- command_handler_module
136- ) do
137- assert { :ok , state , _events } =
138- aggregate_run (
139- aggregate_module ,
140- command_handler_module ,
141- initial_events ,
142- command
143- )
144-
145- assert state == expected_state
146- end
147-
148- def assert_error (
149- initial_events ,
150- command ,
151- expected_error ,
152- aggregate_module ,
153- command_handler_module
154- ) do
155- assert { :error , reason } =
156- aggregate_run (
157- aggregate_module ,
158- command_handler_module ,
159- initial_events ,
160- command
161- )
162-
163- assert reason == expected_error
111+ def assert_events ( initial_events , command , expected_events , aggregate_module , command_handler_module ) do
112+ run_and_assert ( initial_events , command , aggregate_module , command_handler_module , fn
113+ { :ok , _state , events } ->
114+ assert List . wrap ( events ) == List . wrap ( expected_events )
115+
116+ { :error , reason } ->
117+ flunk ( "Expected success but got error: #{ inspect ( reason ) } " )
118+ end )
119+ end
120+
121+ def assert_state ( initial_events , command , expected_state , aggregate_module , command_handler_module ) do
122+ run_and_assert ( initial_events , command , aggregate_module , command_handler_module , fn
123+ { :ok , state , _events } ->
124+ assert state == expected_state
125+
126+ { :error , reason } ->
127+ flunk ( "Expected success but got error: #{ inspect ( reason ) } " )
128+ end )
129+ end
130+
131+ def assert_error ( initial_events , command , expected_error , aggregate_module , command_handler_module ) do
132+ run_and_assert ( initial_events , command , aggregate_module , command_handler_module , fn
133+ { :error , reason } -> assert reason == expected_error
134+ { :ok , _state , _events } -> flunk ( "Expected error #{ inspect ( expected_error ) } , but command succeeded" )
135+ end )
136+ end
137+
138+ defp run_and_assert ( initial_events , command , aggregate_module , command_handler_module , assertion_fn ) do
139+ assert is_list ( initial_events ) , "Initial events must be a list of events"
140+ validate_identity_configuration ( command , aggregate_module )
141+ result = aggregate_run ( aggregate_module , command_handler_module , initial_events , command )
142+ assertion_fn . ( result )
164143 end
165144
166145 defp aggregate_run ( aggregate_module , command_handler_module , initial_events , command ) do
@@ -238,4 +217,71 @@ defmodule Trogon.Commanded.TestSupport.CommandHandlerCase do
238217 |> List . wrap ( )
239218 |> Enum . reduce ( state , & evolver . ( & 2 , & 1 ) )
240219 end
220+
221+ defp validate_identity_configuration ( command , aggregate_module ) do
222+ command_module = command . __struct__
223+
224+ command_has_identity? =
225+ function_exported? ( command_module , :aggregate_identifier , 0 ) and
226+ function_exported? ( command_module , :identity_prefix , 0 )
227+
228+ aggregate_has_identity? =
229+ function_exported? ( aggregate_module , :identifier , 0 ) and
230+ function_exported? ( aggregate_module , :identity_prefix , 0 )
231+
232+ if command_has_identity? and aggregate_has_identity? do
233+ validate_identifier_match ( command_module , aggregate_module )
234+ validate_prefix_match ( command_module , aggregate_module )
235+ validate_aggregate_uuid_extraction ( command , command_module )
236+ else
237+ :ok
238+ end
239+ end
240+
241+ defp validate_identifier_match ( command_module , aggregate_module ) do
242+ command_identifier = command_module . aggregate_identifier ( )
243+ aggregate_identifier = aggregate_module . identifier ( )
244+
245+ assert command_identifier == aggregate_identifier , """
246+ Identity field mismatch between command and aggregate.
247+
248+ Command #{ inspect ( command_module ) } uses #{ inspect ( command_identifier ) }
249+ Aggregate #{ inspect ( aggregate_module ) } uses #{ inspect ( aggregate_identifier ) }
250+ """
251+ end
252+
253+ defp validate_prefix_match ( command_module , aggregate_module ) do
254+ command_prefix = command_module . identity_prefix ( )
255+ aggregate_prefix = aggregate_module . identity_prefix ( )
256+
257+ assert command_prefix == aggregate_prefix , """
258+ Identity prefix mismatch between command and aggregate.
259+
260+ Command #{ inspect ( command_module ) } uses #{ inspect ( command_prefix ) }
261+ Aggregate #{ inspect ( aggregate_module ) } uses #{ inspect ( aggregate_prefix ) }
262+ """
263+ end
264+
265+ defp validate_aggregate_uuid_extraction ( command , command_module ) do
266+ identifier = command_module . aggregate_identifier ( )
267+ identity_prefix = command_module . identity_prefix ( )
268+
269+ pipeline =
270+ % Pipeline { command: command , identity: identifier , identity_prefix: identity_prefix }
271+ |> ExtractAggregateIdentity . before_dispatch ( )
272+
273+ case pipeline do
274+ % Pipeline { assigns: % { aggregate_uuid: uuid } } when is_binary ( uuid ) and uuid != "" ->
275+ :ok
276+
277+ _ ->
278+ flunk ( """
279+ Failed to extract aggregate UUID from command.
280+
281+ Command: #{ inspect ( command ) }
282+ Identity field: #{ inspect ( identifier ) }
283+ Identity prefix: #{ inspect ( identity_prefix ) }
284+ """ )
285+ end
286+ end
241287end
0 commit comments