2525)
2626
2727
28+ @pytest .fixture
29+ def mock_aries_controller ():
30+ """Create a mock aries controller with default setup."""
31+ mock_controller = AsyncMock ()
32+ mock_controller .did_exchange .create_request = AsyncMock (
33+ return_value = created_connection
34+ )
35+ mock_controller .connection .get_connections = AsyncMock (
36+ return_value = AsyncMock (results = [])
37+ )
38+ return mock_controller
39+
40+
41+ @pytest .fixture
42+ def mock_patches ():
43+ """Setup common patches used across multiple tests."""
44+ with (
45+ patch ("app.routes.connections.client_from_auth" ) as mock_client_from_auth ,
46+ patch (
47+ "app.routes.connections.conn_record_to_connection" ,
48+ return_value = created_connection ,
49+ ) as mock_conn_record ,
50+ ):
51+ yield mock_client_from_auth , mock_conn_record
52+
53+
54+ def setup_controller_context (mock_client_from_auth , mock_controller ):
55+ """Setup the controller context for the mock client."""
56+ mock_client_from_auth .return_value .__aenter__ .return_value = mock_controller
57+
58+
59+ async def call_create_did_exchange_request (** kwargs ):
60+ """Helper to call create_did_exchange_request with default values."""
61+ defaults = {
62+ "their_public_did" : test_their_public_did ,
63+ "alias" : None ,
64+ "goal" : None ,
65+ "goal_code" : None ,
66+ "my_label" : None ,
67+ "reuse_connection" : True ,
68+ "use_did" : None ,
69+ "use_did_method" : None ,
70+ "use_public_did" : False ,
71+ "auth" : "mocked_auth" ,
72+ }
73+ defaults .update (kwargs )
74+ return await create_did_exchange_request (** defaults )
75+
76+
77+ def assert_get_connections_called (mock_controller , should_be_called = True ):
78+ """Assert whether get_connections was called as expected."""
79+ if should_be_called :
80+ mock_controller .connection .get_connections .assert_awaited_once_with (
81+ their_public_did = test_their_public_did
82+ )
83+ else :
84+ mock_controller .connection .get_connections .assert_not_awaited ()
85+
86+
87+ def assert_create_request_called (
88+ mock_controller , should_be_called = True , ** expected_params
89+ ):
90+ """Assert whether create_request was called as expected."""
91+ if should_be_called :
92+ defaults = {
93+ "their_public_did" : test_their_public_did ,
94+ "alias" : None ,
95+ "auto_accept" : True ,
96+ "goal" : None ,
97+ "goal_code" : None ,
98+ "my_label" : None ,
99+ "protocol" : "didexchange/1.1" ,
100+ "use_did" : None ,
101+ "use_did_method" : None ,
102+ "use_public_did" : False ,
103+ }
104+ defaults .update (expected_params )
105+ mock_controller .did_exchange .create_request .assert_awaited_once_with (** defaults )
106+ else :
107+ mock_controller .did_exchange .create_request .assert_not_awaited ()
108+
109+
28110@pytest .mark .anyio
29111@pytest .mark .parametrize (
30112 "body_params, expected_alias, expected_use_did, expected_use_did_method, expected_use_public_did" ,
@@ -59,52 +141,38 @@ async def test_create_did_exchange_request_success(
59141 expected_use_did ,
60142 expected_use_did_method ,
61143 expected_use_public_did ,
144+ mock_aries_controller ,
145+ mock_patches ,
62146):
63- mock_aries_controller = AsyncMock ()
64- mock_aries_controller .did_exchange .create_request = AsyncMock (
65- return_value = created_connection
66- )
147+ mock_client_from_auth , mock_conn_record = mock_patches
148+ setup_controller_context (mock_client_from_auth , mock_aries_controller )
67149
68- with (
69- patch ("app.routes.connections.client_from_auth" ) as mock_client_from_auth ,
70- patch (
71- "app.routes.connections.conn_record_to_connection" ,
72- return_value = created_connection ,
73- ),
74- ):
75- mock_client_from_auth .return_value .__aenter__ .return_value = (
76- mock_aries_controller
77- )
150+ if not body_params :
151+ body_params = {}
78152
79- if not body_params :
80- body_params = {}
81-
82- response = await create_did_exchange_request (
83- their_public_did = test_their_public_did ,
84- alias = body_params .get ("alias" ),
85- goal = body_params .get ("goal" ),
86- goal_code = body_params .get ("goal_code" ),
87- my_label = body_params .get ("my_label" ),
88- use_did = body_params .get ("use_did" ),
89- use_did_method = body_params .get ("use_did_method" ),
90- use_public_did = body_params .get ("use_public_did" , False ),
91- auth = "mocked_auth" ,
92- )
153+ response = await call_create_did_exchange_request (
154+ alias = body_params .get ("alias" ),
155+ goal = body_params .get ("goal" ),
156+ goal_code = body_params .get ("goal_code" ),
157+ my_label = body_params .get ("my_label" ),
158+ reuse_connection = body_params .get ("reuse_connection" , True ),
159+ use_did = body_params .get ("use_did" ),
160+ use_did_method = body_params .get ("use_did_method" ),
161+ use_public_did = body_params .get ("use_public_did" , False ),
162+ )
93163
94- assert response == created_connection
95-
96- mock_aries_controller .did_exchange .create_request .assert_awaited_once_with (
97- their_public_did = test_their_public_did ,
98- alias = expected_alias ,
99- auto_accept = True ,
100- goal = body_params .get ("goal" ),
101- goal_code = body_params .get ("goal_code" ),
102- my_label = body_params .get ("my_label" ),
103- protocol = "didexchange/1.1" ,
104- use_did = expected_use_did ,
105- use_did_method = expected_use_did_method ,
106- use_public_did = expected_use_public_did ,
107- )
164+ assert response == created_connection
165+
166+ assert_create_request_called (
167+ mock_aries_controller ,
168+ alias = expected_alias ,
169+ goal = body_params .get ("goal" ),
170+ goal_code = body_params .get ("goal_code" ),
171+ my_label = body_params .get ("my_label" ),
172+ use_did = expected_use_did ,
173+ use_did_method = expected_use_did_method ,
174+ use_public_did = expected_use_public_did ,
175+ )
108176
109177
110178@pytest .mark .anyio
@@ -117,26 +185,106 @@ async def test_create_did_exchange_request_success(
117185 ],
118186)
119187async def test_create_did_exchange_request_fail_acapy_error (
120- exception_class , expected_status_code , expected_detail
188+ exception_class ,
189+ expected_status_code ,
190+ expected_detail ,
191+ mock_aries_controller ,
192+ mock_patches ,
121193):
122- mock_aries_controller = AsyncMock ()
194+ mock_client_from_auth , mock_conn_record = mock_patches
123195 mock_aries_controller .did_exchange .create_request = AsyncMock (
124196 side_effect = exception_class (status = expected_status_code , reason = expected_detail )
125197 )
198+ setup_controller_context (mock_client_from_auth , mock_aries_controller )
126199
127- with (
128- patch ("app.routes.connections.client_from_auth" ) as mock_client_from_auth ,
129- pytest .raises (HTTPException , match = expected_detail ) as exc ,
130- patch ("app.routes.connections.conn_record_to_connection" ),
131- ):
132- mock_client_from_auth .return_value .__aenter__ .return_value = (
133- mock_aries_controller
134- )
135-
136- await create_did_exchange_request (
137- their_public_did = test_their_public_did ,
138- alias = None ,
139- auth = "mocked_auth" ,
140- )
200+ with pytest .raises (HTTPException , match = expected_detail ) as exc :
201+ await call_create_did_exchange_request (alias = None )
141202
142203 assert exc .value .status_code == expected_status_code
204+
205+
206+ @pytest .mark .anyio
207+ @pytest .mark .parametrize (
208+ "reuse_connection, existing_connections, should_get_connections, should_create_request, expected_response" ,
209+ [
210+ # When reuse_connection=True and completed connection exists, return existing
211+ (
212+ True ,
213+ [
214+ ConnRecord (
215+ connection_id = "existing_id" ,
216+ state = "completed" ,
217+ rfc23_state = "completed" ,
218+ their_did = test_their_public_did ,
219+ )
220+ ],
221+ True ,
222+ False ,
223+ "existing_connection" ,
224+ ),
225+ # When reuse_connection=True but only non-completed connections exist, create new
226+ (
227+ True ,
228+ [
229+ ConnRecord (
230+ connection_id = "non_completed_id" ,
231+ state = "request-sent" ,
232+ rfc23_state = "request-sent" ,
233+ their_did = test_their_public_did ,
234+ )
235+ ],
236+ True ,
237+ True ,
238+ "new_connection" ,
239+ ),
240+ # When reuse_connection=True but no existing connections, create new
241+ (True , [], True , True , "new_connection" ),
242+ # When reuse_connection=False, always create new (don't check existing)
243+ (
244+ False ,
245+ [
246+ ConnRecord (
247+ connection_id = "existing_id" ,
248+ state = "completed" ,
249+ rfc23_state = "completed" ,
250+ their_did = test_their_public_did ,
251+ )
252+ ],
253+ False ,
254+ True ,
255+ "new_connection" ,
256+ ),
257+ ],
258+ )
259+ async def test_create_did_exchange_request_reuse_scenarios (
260+ reuse_connection ,
261+ existing_connections ,
262+ should_get_connections ,
263+ should_create_request ,
264+ expected_response ,
265+ mock_aries_controller ,
266+ mock_patches ,
267+ ):
268+ """Test various scenarios for connection reuse behavior."""
269+ mock_client_from_auth , mock_conn_record = mock_patches
270+
271+ # Setup existing connections
272+ mock_aries_controller .connection .get_connections = AsyncMock (
273+ return_value = AsyncMock (results = existing_connections )
274+ )
275+
276+ # Determine expected return value
277+ if expected_response == "existing_connection" and existing_connections :
278+ expected_connection = existing_connections [0 ]
279+ mock_conn_record .return_value = expected_connection
280+ else :
281+ expected_connection = created_connection
282+ mock_conn_record .return_value = created_connection
283+
284+ setup_controller_context (mock_client_from_auth , mock_aries_controller )
285+
286+ response = await call_create_did_exchange_request (reuse_connection = reuse_connection )
287+
288+ assert response == expected_connection
289+ assert_get_connections_called (mock_aries_controller , should_get_connections )
290+ assert_create_request_called (mock_aries_controller , should_create_request )
0 commit comments