mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-09-01 22:18:43 +00:00
core: connection plan api; check connection plan before connecting in terminal api (#3176)
This commit is contained in:
@@ -44,6 +44,10 @@ chatDirectTests = do
|
||||
describe "duplicate contacts" $ do
|
||||
it "duplicate contacts are separate (contacts don't merge)" testDuplicateContactsSeparate
|
||||
it "new contact is separate with multiple duplicate contacts (contacts don't merge)" testDuplicateContactsMultipleSeparate
|
||||
describe "invitation link connection plan" $ do
|
||||
it "invitation link ok to connect" testPlanInvitationLinkOk
|
||||
it "own invitation link" testPlanInvitationLinkOwn
|
||||
it "connecting via invitation link" testPlanInvitationLinkConnecting
|
||||
describe "SMP servers" $ do
|
||||
it "get and set SMP servers" testGetSetSMPServers
|
||||
it "test SMP server connection" testTestSMPServerConnection
|
||||
@@ -236,6 +240,69 @@ testDuplicateContactsMultipleSeparate =
|
||||
alice `hasContactProfiles` ["alice", "bob", "bob", "bob"]
|
||||
bob `hasContactProfiles` ["bob", "alice", "alice", "alice"]
|
||||
|
||||
testPlanInvitationLinkOk :: HasCallStack => FilePath -> IO ()
|
||||
testPlanInvitationLinkOk =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/c"
|
||||
inv <- getInvitation alice
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: ok to connect"
|
||||
|
||||
bob ##> ("/c " <> inv)
|
||||
bob <## "confirmation sent!"
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: ok to connect" -- conn_req_inv is forgotten after connection
|
||||
|
||||
alice <##> bob
|
||||
|
||||
testPlanInvitationLinkOwn :: HasCallStack => FilePath -> IO ()
|
||||
testPlanInvitationLinkOwn tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/c"
|
||||
inv <- getInvitation alice
|
||||
alice ##> ("/_connect plan 1 " <> inv)
|
||||
alice <## "invitation link: own link"
|
||||
|
||||
alice ##> ("/c " <> inv)
|
||||
alice <## "confirmation sent!"
|
||||
alice
|
||||
<### [ "alice_1 (Alice): contact is connected",
|
||||
"alice_2 (Alice): contact is connected"
|
||||
]
|
||||
|
||||
alice ##> ("/_connect plan 1 " <> inv)
|
||||
alice <## "invitation link: ok to connect" -- conn_req_inv is forgotten after connection
|
||||
|
||||
alice @@@ [("@alice_1", lastChatFeature), ("@alice_2", lastChatFeature)]
|
||||
alice `send` "@alice_2 hi"
|
||||
alice
|
||||
<### [ WithTime "@alice_2 hi",
|
||||
WithTime "alice_1> hi"
|
||||
]
|
||||
alice `send` "@alice_1 hey"
|
||||
alice
|
||||
<### [ WithTime "@alice_1 hey",
|
||||
WithTime "alice_2> hey"
|
||||
]
|
||||
alice @@@ [("@alice_1", "hey"), ("@alice_2", "hey")]
|
||||
|
||||
testPlanInvitationLinkConnecting :: HasCallStack => FilePath -> IO ()
|
||||
testPlanInvitationLinkConnecting tmp = do
|
||||
inv <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/c"
|
||||
getInvitation alice
|
||||
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||
bob ##> ("/c " <> inv)
|
||||
bob <## "confirmation sent!"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> inv)
|
||||
bob <## "invitation link: connecting"
|
||||
|
||||
testContactClear :: HasCallStack => FilePath -> IO ()
|
||||
testContactClear =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
|
||||
@@ -57,6 +57,12 @@ chatGroupTests = do
|
||||
it "leaving groups with unused host contacts deletes incognito profiles" testGroupLinkIncognitoUnusedHostContactsDeleted
|
||||
it "group link member role" testGroupLinkMemberRole
|
||||
it "leaving and deleting the group joined via link should NOT delete previously existing direct contacts" testGroupLinkLeaveDelete
|
||||
describe "group link connection plan" $ do
|
||||
it "group link ok to connect; known group" testPlanGroupLinkOkKnown
|
||||
it "group is known if host contact was deleted" testPlanHostContactDeletedGroupLinkKnown
|
||||
it "own group link" testPlanGroupLinkOwn
|
||||
it "connecting via group link" testPlanGroupLinkConnecting
|
||||
it "re-join existing group after leaving" testPlanGroupLinkLeaveRejoin
|
||||
describe "group message errors" $ do
|
||||
it "show message decryption error" testGroupMsgDecryptError
|
||||
it "should report ratchet de-synchronization, synchronize ratchets" testGroupSyncRatchet
|
||||
@@ -2251,6 +2257,237 @@ testGroupLinkLeaveDelete =
|
||||
bob <## "alice (Alice)"
|
||||
bob <## "cath (Catherine)"
|
||||
|
||||
testPlanGroupLinkOkKnown :: HasCallStack => FilePath -> IO ()
|
||||
testPlanGroupLinkOkKnown =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
gLink <- getGroupLink alice "team" GRMember True
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: ok to connect"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
alice <## "bob invited to group #team via your group link"
|
||||
alice <## "#team: bob joined the group",
|
||||
do
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
bob <## "#team: you joined the group"
|
||||
]
|
||||
alice #> "#team hi"
|
||||
bob <# "#team alice> hi"
|
||||
bob #> "#team hey"
|
||||
alice <# "#team bob> hey"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
testPlanHostContactDeletedGroupLinkKnown :: HasCallStack => FilePath -> IO ()
|
||||
testPlanHostContactDeletedGroupLinkKnown =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
gLink <- getGroupLink alice "team" GRMember True
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
alice <## "bob invited to group #team via your group link"
|
||||
alice <## "#team: bob joined the group",
|
||||
do
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
bob <## "#team: you joined the group"
|
||||
]
|
||||
alice #> "#team hi"
|
||||
bob <# "#team alice> hi"
|
||||
bob #> "#team hey"
|
||||
alice <# "#team bob> hey"
|
||||
|
||||
alice <##> bob
|
||||
threadDelay 500000
|
||||
bob ##> "/d alice"
|
||||
bob <## "alice: contact is deleted"
|
||||
alice <## "bob (Bob) deleted contact with you"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
testPlanGroupLinkOwn :: HasCallStack => FilePath -> IO ()
|
||||
testPlanGroupLinkOwn tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
gLink <- getGroupLink alice "team" GRMember True
|
||||
|
||||
alice ##> ("/_connect plan 1 " <> gLink)
|
||||
alice <## "group link: own link for group #team"
|
||||
|
||||
alice ##> ("/c " <> gLink)
|
||||
alice <## "connection request sent!"
|
||||
alice <## "alice_1 (Alice): accepting request to join group #team..."
|
||||
alice
|
||||
<### [ "alice_1 (Alice): contact is connected",
|
||||
"alice_1 invited to group #team via your group link",
|
||||
"#team: alice_1 joined the group",
|
||||
"alice_2 (Alice): contact is connected",
|
||||
"#team_1: you joined the group",
|
||||
"contact alice_2 is merged into alice_1",
|
||||
"use @alice_1 <message> to send messages"
|
||||
]
|
||||
alice `send` "#team 1"
|
||||
alice
|
||||
<### [ WithTime "#team 1",
|
||||
WithTime "#team_1 alice_1> 1"
|
||||
]
|
||||
alice `send` "#team_1 2"
|
||||
alice
|
||||
<### [ WithTime "#team_1 2",
|
||||
WithTime "#team alice_1> 2"
|
||||
]
|
||||
|
||||
alice ##> ("/_connect plan 1 " <> gLink)
|
||||
alice <## "group link: own link for group #team"
|
||||
|
||||
-- group works if merged contact is deleted
|
||||
alice ##> "/d alice_1"
|
||||
alice <## "alice_1: contact is deleted"
|
||||
|
||||
alice `send` "#team 3"
|
||||
alice
|
||||
<### [ WithTime "#team 3",
|
||||
WithTime "#team_1 alice_1> 3"
|
||||
]
|
||||
alice `send` "#team_1 4"
|
||||
alice
|
||||
<### [ WithTime "#team_1 4",
|
||||
WithTime "#team alice_1> 4"
|
||||
]
|
||||
|
||||
testPlanGroupLinkConnecting :: HasCallStack => FilePath -> IO ()
|
||||
testPlanGroupLinkConnecting tmp = do
|
||||
gLink <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
getGroupLink alice "team" GRMember True
|
||||
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
withTestChat tmp "alice" $ \alice -> do
|
||||
alice
|
||||
<### [ "1 group links active",
|
||||
"#team: group is empty",
|
||||
"bob (Bob): accepting request to join group #team..."
|
||||
]
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: connecting"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "group link: connecting"
|
||||
|
||||
testPlanGroupLinkLeaveRejoin :: HasCallStack => FilePath -> IO ()
|
||||
testPlanGroupLinkLeaveRejoin =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
gLink <- getGroupLink alice "team" GRMember True
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "bob (Bob): contact is connected"
|
||||
alice <## "bob invited to group #team via your group link"
|
||||
alice <## "#team: bob joined the group",
|
||||
do
|
||||
bob <## "alice (Alice): contact is connected"
|
||||
bob <## "#team: you joined the group"
|
||||
]
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "group link: known group #team"
|
||||
bob <## "use #team <message> to send messages"
|
||||
|
||||
bob ##> "/leave #team"
|
||||
concurrentlyN_
|
||||
[ do
|
||||
bob <## "#team: you left the group"
|
||||
bob <## "use /d #team to delete the group",
|
||||
alice <## "#team: bob left the group"
|
||||
]
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: ok to connect"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob_1 (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ alice
|
||||
<### [ "bob_1 (Bob): contact is connected",
|
||||
"bob_1 invited to group #team via your group link",
|
||||
EndsWith "joined the group",
|
||||
"contact bob_1 is merged into bob",
|
||||
"use @bob <message> to send messages"
|
||||
],
|
||||
bob
|
||||
<### [ "alice_1 (Alice): contact is connected",
|
||||
"#team_1: you joined the group",
|
||||
"contact alice_1 is merged into alice",
|
||||
"use @alice <message> to send messages"
|
||||
]
|
||||
]
|
||||
|
||||
alice #> "#team hi"
|
||||
bob <# "#team_1 alice> hi"
|
||||
bob #> "#team_1 hey"
|
||||
alice <# "#team bob> hey"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> gLink)
|
||||
bob <## "group link: known group #team_1"
|
||||
bob <## "use #team_1 <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "group link: known group #team_1"
|
||||
bob <## "use #team_1 <message> to send messages"
|
||||
|
||||
testGroupMsgDecryptError :: HasCallStack => FilePath -> IO ()
|
||||
testGroupMsgDecryptError tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
|
||||
+161
-4
@@ -28,6 +28,11 @@ chatProfileTests = do
|
||||
it "delete connection requests when contact link deleted" testDeleteConnectionRequests
|
||||
it "auto-reply message" testAutoReplyMessage
|
||||
it "auto-reply message in incognito" testAutoReplyMessageInIncognito
|
||||
describe "contact address connection plan" $ do
|
||||
it "contact address ok to connect; known contact" testPlanAddressOkKnown
|
||||
it "own contact address" testPlanAddressOwn
|
||||
it "connecting via contact address" testPlanAddressConnecting
|
||||
it "re-connect with deleted contact" testPlanAddressContactDeletedReconnected
|
||||
describe "incognito" $ do
|
||||
it "connect incognito via invitation link" testConnectIncognitoInvitationLink
|
||||
it "connect incognito via contact address" testConnectIncognitoContactAddress
|
||||
@@ -369,7 +374,8 @@ testDeduplicateContactRequests = testChat3 aliceProfile bobProfile cathProfile $
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "alice (Alice): contact already exists"
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
alice @@@ [("@bob", lastChatFeature)]
|
||||
bob @@@ [("@alice", lastChatFeature), (":2", ""), (":1", "")]
|
||||
bob ##> "/_delete :1"
|
||||
@@ -382,7 +388,8 @@ testDeduplicateContactRequests = testChat3 aliceProfile bobProfile cathProfile $
|
||||
bob @@@ [("@alice", "hey")]
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "alice (Alice): contact already exists"
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
alice <##> bob
|
||||
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "hi"), (0, "hey"), (1, "hi"), (0, "hey")])
|
||||
@@ -440,7 +447,8 @@ testDeduplicateContactRequestsProfileChange = testChat3 aliceProfile bobProfile
|
||||
(alice <## "robert (Robert): contact is connected")
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "alice (Alice): contact already exists"
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
alice @@@ [("@robert", lastChatFeature)]
|
||||
bob @@@ [("@alice", lastChatFeature), (":3", ""), (":2", ""), (":1", "")]
|
||||
bob ##> "/_delete :1"
|
||||
@@ -455,7 +463,8 @@ testDeduplicateContactRequestsProfileChange = testChat3 aliceProfile bobProfile
|
||||
bob @@@ [("@alice", "hey")]
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "alice (Alice): contact already exists"
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
alice <##> bob
|
||||
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "hi"), (0, "hey"), (1, "hi"), (0, "hey")])
|
||||
@@ -566,6 +575,154 @@ testAutoReplyMessageInIncognito = testChat2 aliceProfile bobProfile $
|
||||
]
|
||||
]
|
||||
|
||||
testPlanAddressOkKnown :: HasCallStack => FilePath -> IO ()
|
||||
testPlanAddressOkKnown =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/ad"
|
||||
cLink <- getContactLink alice True
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
alice <#? bob
|
||||
alice @@@ [("<@bob", "")]
|
||||
alice ##> "/ac bob"
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
alice <##> bob
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
testPlanAddressOwn :: HasCallStack => FilePath -> IO ()
|
||||
testPlanAddressOwn tmp =
|
||||
withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/ad"
|
||||
cLink <- getContactLink alice True
|
||||
|
||||
alice ##> ("/_connect plan 1 " <> cLink)
|
||||
alice <## "contact address: own address"
|
||||
|
||||
alice ##> ("/c " <> cLink)
|
||||
alice <## "connection request sent!"
|
||||
alice <## "alice_1 (Alice) wants to connect to you!"
|
||||
alice <## "to accept: /ac alice_1"
|
||||
alice <## ("to reject: /rc alice_1 (the sender will NOT be notified)")
|
||||
alice @@@ [("<@alice_1", ""), (":2","")]
|
||||
alice ##> "/ac alice_1"
|
||||
alice <## "alice_1 (Alice): accepting contact request..."
|
||||
alice
|
||||
<### [ "alice_1 (Alice): contact is connected",
|
||||
"alice_2 (Alice): contact is connected"
|
||||
]
|
||||
|
||||
alice @@@ [("@alice_1", lastChatFeature), ("@alice_2", lastChatFeature)]
|
||||
alice `send` "@alice_2 hi"
|
||||
alice
|
||||
<### [ WithTime "@alice_2 hi",
|
||||
WithTime "alice_1> hi"
|
||||
]
|
||||
alice `send` "@alice_1 hey"
|
||||
alice
|
||||
<### [ WithTime "@alice_1 hey",
|
||||
WithTime "alice_2> hey"
|
||||
]
|
||||
alice @@@ [("@alice_1", "hey"), ("@alice_2", "hey")]
|
||||
|
||||
alice ##> ("/_connect plan 1 " <> cLink)
|
||||
alice <## "contact address: own address"
|
||||
|
||||
alice ##> ("/c " <> cLink)
|
||||
alice <## "alice_2 (Alice): contact already exists"
|
||||
|
||||
testPlanAddressConnecting :: HasCallStack => FilePath -> IO ()
|
||||
testPlanAddressConnecting tmp = do
|
||||
cLink <- withNewTestChat tmp "alice" aliceProfile $ \alice -> do
|
||||
alice ##> "/ad"
|
||||
getContactLink alice True
|
||||
withNewTestChat tmp "bob" bobProfile $ \bob -> do
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "connection request sent!"
|
||||
withTestChat tmp "alice" $ \alice -> do
|
||||
alice <## "Your address is active! To show: /sa"
|
||||
alice <## "bob (Bob) wants to connect to you!"
|
||||
alice <## "to accept: /ac bob"
|
||||
alice <## "to reject: /rc bob (the sender will NOT be notified)"
|
||||
alice ##> "/ac bob"
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
threadDelay 500000
|
||||
bob @@@ [("@alice", "")]
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: connecting to contact alice"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "contact address: connecting to contact alice"
|
||||
|
||||
testPlanAddressContactDeletedReconnected :: HasCallStack => FilePath -> IO ()
|
||||
testPlanAddressContactDeletedReconnected =
|
||||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
alice ##> "/ad"
|
||||
cLink <- getContactLink alice True
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
alice <#? bob
|
||||
alice ##> "/ac bob"
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
alice <##> bob
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "contact address: known contact alice"
|
||||
bob <## "use @alice <message> to send messages"
|
||||
|
||||
alice ##> "/d bob"
|
||||
alice <## "bob: contact is deleted"
|
||||
bob <## "alice (Alice) deleted contact with you"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob (Bob) wants to connect to you!"
|
||||
alice <## "to accept: /ac bob"
|
||||
alice <## "to reject: /rc bob (the sender will NOT be notified)"
|
||||
alice ##> "/ac bob"
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
concurrently_
|
||||
(bob <## "alice_1 (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
|
||||
alice #> "@bob hi"
|
||||
bob <# "alice_1> hi"
|
||||
bob #> "@alice_1 hey"
|
||||
alice <# "bob> hey"
|
||||
|
||||
bob ##> ("/_connect plan 1 " <> cLink)
|
||||
bob <## "contact address: known contact alice_1"
|
||||
bob <## "use @alice_1 <message> to send messages"
|
||||
|
||||
bob ##> ("/c " <> cLink)
|
||||
bob <## "contact address: known contact alice_1"
|
||||
bob <## "use @alice_1 <message> to send messages"
|
||||
|
||||
testConnectIncognitoInvitationLink :: HasCallStack => FilePath -> IO ()
|
||||
testConnectIncognitoInvitationLink = testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
|
||||
Reference in New Issue
Block a user