Skip to content

Commit d0b89a9

Browse files
authored
Merge pull request openwallet-foundation#3721 from andrepestana-aot/feat/test-2818-regression
Regress test to check openwallet-foundation#2818 issue
2 parents e9ea2f1 + b6bddd1 commit d0b89a9

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from unittest.mock import AsyncMock, MagicMock
2+
import pytest
3+
from acapy_agent.connections.models.conn_record import ConnRecord
4+
from acapy_agent.protocols.coordinate_mediation.v1_0.route_manager import (
5+
CoordinateMediationV1RouteManager,
6+
)
7+
from contextlib import asynccontextmanager
8+
from acapy_agent.core.profile import Profile
9+
from acapy_agent.storage.base import BaseStorage
10+
from acapy_agent.cache.base import BaseCache
11+
from acapy_agent.storage.record import StorageRecord
12+
import json
13+
14+
15+
@asynccontextmanager
16+
async def make_profile():
17+
profile = MagicMock(spec=Profile)
18+
19+
# Mock settings
20+
settings_mock = {"some.setting": True}
21+
22+
# Mock storage with expected async methods
23+
storage_mock = MagicMock(spec=BaseStorage)
24+
25+
cache_mock = MagicMock(spec=BaseCache)
26+
cache_mock.clear = AsyncMock()
27+
28+
def custom_inject(cls):
29+
if cls.__name__ == "BaseStorage":
30+
return storage_mock
31+
elif cls.__name__ == "BaseWallet":
32+
return cache_mock
33+
else:
34+
return MagicMock()
35+
36+
# Mock session with .settings and .inject
37+
session_mock = AsyncMock()
38+
session_mock.settings = settings_mock
39+
session_mock.inject = MagicMock(return_value=storage_mock)
40+
session_mock.inject_or = MagicMock(return_value=cache_mock)
41+
session_mock.inject.side_effect = custom_inject
42+
43+
# Async context manager that yields session
44+
session_context_manager = AsyncMock()
45+
session_context_manager.__aenter__.return_value = session_mock
46+
session_context_manager.__aexit__.return_value = None
47+
48+
profile.session.return_value = session_context_manager
49+
50+
yield profile
51+
52+
53+
INVITATION_KEY = "B87peZJozsKpoUrNvdmsRdZyGN4cETNAvczo2n8tox5F"
54+
55+
56+
@pytest.mark.asyncio
57+
async def test_multiuse_invitation_does_not_raise():
58+
"""Two calls with the same invitation key must not raise and return the same connection."""
59+
60+
async with make_profile() as profile:
61+
conn_record = ConnRecord(
62+
invitation_key=INVITATION_KEY,
63+
state=ConnRecord.State.COMPLETED,
64+
their_role=ConnRecord.Role.REQUESTER,
65+
accept="auto",
66+
)
67+
68+
async with profile.session() as session:
69+
await conn_record.save(session)
70+
71+
# Mock the record that would be found in storage
72+
profile.session.return_value.__aenter__.return_value.inject.return_value.find_all_records.return_value = [
73+
StorageRecord(
74+
id="test-conn-id",
75+
type=ConnRecord.RECORD_TYPE,
76+
value=json.dumps(
77+
{
78+
k: v
79+
for k, v in conn_record.serialize().items()
80+
if k != "connection_id"
81+
}
82+
),
83+
tags={
84+
"invitation_key": INVITATION_KEY,
85+
"my_did": "did:example:123456789abcdefghi",
86+
},
87+
)
88+
]
89+
90+
# Initialize the route manager
91+
route_mgr = CoordinateMediationV1RouteManager()
92+
93+
# Call the method twice with the same input
94+
result1 = await route_mgr.connection_from_recipient_key(
95+
profile, recipient_key=INVITATION_KEY
96+
)
97+
result2 = await route_mgr.connection_from_recipient_key(
98+
profile, recipient_key=INVITATION_KEY
99+
)
100+
101+
# Verify both results are valid
102+
assert isinstance(result1, ConnRecord)
103+
assert isinstance(result2, ConnRecord)

0 commit comments

Comments
 (0)