core, ui: create all links with short links, config parameter to use large link data, use short link as address in user profile (#5991)

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
This commit is contained in:
Evgeny
2025-06-17 15:56:33 +04:00
committed by spaced4ndy
co-authored by spaced4ndy
parent c08a3e7c4a
commit e3e9ae2ffd
46 changed files with 413 additions and 323 deletions
+11 -1
View File
@@ -53,7 +53,7 @@ import Simplex.Messaging.Client (ProtocolClientConfig (..))
import Simplex.Messaging.Client.Agent (defaultSMPClientAgentConfig)
import Simplex.Messaging.Crypto.Ratchet (supportedE2EEncryptVRange)
import qualified Simplex.Messaging.Crypto.Ratchet as CR
import Simplex.Messaging.Protocol (srvHostnamesSMPClientVersion)
import Simplex.Messaging.Protocol (srvHostnamesSMPClientVersion, sndAuthKeySMPClientVersion)
import Simplex.Messaging.Server (runSMPServerBlocking)
import Simplex.Messaging.Server.Env.STM (ServerConfig (..), ServerStoreCfg (..), StartOptions (..), StorePaths (..), defaultMessageExpiration, defaultIdleQueueInterval, defaultNtfExpiration, defaultInactiveClientExpiration)
import Simplex.Messaging.Server.MsgStore.STM (STMMsgStore)
@@ -182,6 +182,13 @@ testAgentCfgSlow =
smpCfg = (smpCfg testAgentCfg) {serverVRange = mkVersionRange minClientSMPRelayVersion sendingProxySMPVersion} -- v8
}
testAgentCfgNoShortLinks :: AgentConfig
testAgentCfgNoShortLinks =
testAgentCfg
{ smpClientVRange = mkVersionRange (Version 1) sndAuthKeySMPClientVersion, -- v3
smpCfg = (smpCfg testAgentCfg) {serverVRange = mkVersionRange minClientSMPRelayVersion (Version 14)} -- before shortLinksSMPVersion
}
testCfg :: ChatConfig
testCfg =
defaultChatConfig
@@ -195,6 +202,9 @@ testCfg =
testCfgSlow :: ChatConfig
testCfgSlow = testCfg {agentConfig = testAgentCfgSlow}
testCfgNoShortLinks :: ChatConfig
testCfgNoShortLinks = testCfg {agentConfig = testAgentCfgNoShortLinks}
testAgentCfgVPrev :: AgentConfig
testAgentCfgVPrev =
testAgentCfg
+22 -22
View File
@@ -94,21 +94,21 @@ chatDirectTests = do
it "get and enable operators, accept conditions" testOperators
describe "async connection handshake" $ do
describe "connect when initiating client goes offline" $ do
it "curr" $ testAsyncInitiatingOffline testCfg testCfg
it "v5" $ testAsyncInitiatingOffline testCfgSlow testCfgSlow
it "v5/curr" $ testAsyncInitiatingOffline testCfgSlow testCfg
it "curr/v5" $ testAsyncInitiatingOffline testCfg testCfgSlow
it "curr" $ testAsyncInitiatingOffline True testCfg testCfg
it "v5" $ testAsyncInitiatingOffline False testCfgSlow testCfgSlow
it "v5/curr" $ testAsyncInitiatingOffline False testCfgSlow testCfg
it "curr/v5" $ testAsyncInitiatingOffline True testCfg testCfgSlow
describe "connect when accepting client goes offline" $ do
it "curr" $ testAsyncAcceptingOffline testCfg testCfg
it "v5" $ testAsyncAcceptingOffline testCfgSlow testCfgSlow
it "v5/curr" $ testAsyncAcceptingOffline testCfgSlow testCfg
it "curr/v5" $ testAsyncAcceptingOffline testCfg testCfgSlow
it "curr" $ testAsyncAcceptingOffline True testCfg testCfg
it "v5" $ testAsyncAcceptingOffline False testCfgSlow testCfgSlow
it "v5/curr" $ testAsyncAcceptingOffline False testCfgSlow testCfg
it "curr/v5" $ testAsyncAcceptingOffline True testCfg testCfgSlow
describe "connect, fully asynchronous (when clients are never simultaneously online)" $ do
it "curr" testFullAsyncFast
-- fails in CI
xit'' "v5" $ testFullAsyncSlow testCfgSlow testCfgSlow
xit'' "v5/curr" $ testFullAsyncSlow testCfgSlow testCfg
xit'' "curr/v5" $ testFullAsyncSlow testCfg testCfgSlow
xit'' "v5" $ testFullAsyncSlow False testCfgSlow testCfgSlow
xit'' "v5/curr" $ testFullAsyncSlow False testCfgSlow testCfg
xit'' "curr/v5" $ testFullAsyncSlow True testCfg testCfgSlow
describe "webrtc calls api" $ do
it "negotiate call" testNegotiateCall
#if !defined(dbPostgres)
@@ -183,9 +183,9 @@ chatDirectTests = do
testAddContact :: HasCallStack => SpecWith TestParams
testAddContact = versionTestMatrix2 runTestAddContact
where
runTestAddContact pqExpected alice bob = do
runTestAddContact pqExpected withShortLink alice bob = do
alice ##> "/_connect 1"
inv <- getInvitation alice
inv <- (if withShortLink then getInvitation else getInvitationNoShortLink) alice
bob ##> ("/_connect 1 " <> inv)
bob <## "confirmation sent!"
concurrently_
@@ -1237,12 +1237,12 @@ testOperators =
where
opts' = testOpts {coreOptions = testCoreOpts {smpServers = [], xftpServers = []}}
testAsyncInitiatingOffline :: HasCallStack => ChatConfig -> ChatConfig -> TestParams -> IO ()
testAsyncInitiatingOffline aliceCfg bobCfg ps = do
testAsyncInitiatingOffline :: HasCallStack => Bool -> ChatConfig -> ChatConfig -> TestParams -> IO ()
testAsyncInitiatingOffline withShortLink aliceCfg bobCfg ps = do
inv <- withNewTestChatCfg ps aliceCfg "alice" aliceProfile $ \alice -> do
threadDelay 250000
alice ##> "/c"
getInvitation alice
(if withShortLink then getInvitation else getInvitationNoShortLink) alice
withNewTestChatCfg ps bobCfg "bob" bobProfile $ \bob -> do
threadDelay 250000
bob ##> ("/c " <> inv)
@@ -1252,11 +1252,11 @@ testAsyncInitiatingOffline aliceCfg bobCfg ps = do
(bob <## "alice (Alice): contact is connected")
(alice <## "bob (Bob): contact is connected")
testAsyncAcceptingOffline :: HasCallStack => ChatConfig -> ChatConfig -> TestParams -> IO ()
testAsyncAcceptingOffline aliceCfg bobCfg ps = do
testAsyncAcceptingOffline :: HasCallStack => Bool -> ChatConfig -> ChatConfig -> TestParams -> IO ()
testAsyncAcceptingOffline withShortLink aliceCfg bobCfg ps = do
inv <- withNewTestChatCfg ps aliceCfg "alice" aliceProfile $ \alice -> do
alice ##> "/c"
getInvitation alice
(if withShortLink then getInvitation else getInvitationNoShortLink) alice
withNewTestChatCfg ps bobCfg "bob" bobProfile $ \bob -> do
threadDelay 250000
bob ##> ("/c " <> inv)
@@ -1283,12 +1283,12 @@ testFullAsyncFast ps = do
withTestChat ps "bob" $ \bob ->
bob <## "alice (Alice): contact is connected"
testFullAsyncSlow :: HasCallStack => ChatConfig -> ChatConfig -> TestParams -> IO ()
testFullAsyncSlow aliceCfg bobCfg ps = do
testFullAsyncSlow :: HasCallStack => Bool -> ChatConfig -> ChatConfig -> TestParams -> IO ()
testFullAsyncSlow withShortLink aliceCfg bobCfg ps = do
inv <- withNewTestChatCfg ps aliceCfg "alice" aliceProfile $ \alice -> do
threadDelay 250000
alice ##> "/c"
getInvitation alice
(if withShortLink then getInvitation else getInvitationNoShortLink) alice
withNewTestChatCfg ps bobCfg "bob" bobProfile $ \bob -> do
threadDelay 250000
bob ##> ("/c " <> inv)
+7 -7
View File
@@ -3442,7 +3442,7 @@ testPlanGroupLinkConnectingSlow ps = do
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
getGroupLinkNoShortLink alice "team" GRMember True
withNewTestChatCfg ps testCfgSlow "bob" bobProfile $ \bob -> do
threadDelay 100000
@@ -5865,13 +5865,13 @@ testMembershipProfileUpdateContactActive =
checkItems bob
alice ##> "/ad"
cLink <- getContactLink alice True
(sLink, _cLink) <- getContactLinks alice True
alice ##> "/pa on"
alice <## "new contact address set"
bob <## "alisa set new contact address, use /info alisa to view"
bob `hasContactProfiles` ["alisa", "bob"]
checkAliceProfileLink bob "alisa" cLink
checkAliceProfileLink bob "alisa" sLink
-- profile update does not remove contact address from profile
alice ##> "/p 'Alice Smith'"
@@ -5880,14 +5880,14 @@ testMembershipProfileUpdateContactActive =
bob <## "use @'Alice Smith' <message> to send messages"
bob `hasContactProfiles` ["Alice Smith", "bob"]
checkAliceProfileLink bob "'Alice Smith'" cLink
checkAliceProfileLink bob "'Alice Smith'" sLink
-- receiving group message does not remove contact address from profile
alice #> "#team team 2"
bob <# "#team 'Alice Smith'> team 2"
bob `hasContactProfiles` ["Alice Smith", "bob"]
checkAliceProfileLink bob "'Alice Smith'" cLink
checkAliceProfileLink bob "'Alice Smith'" sLink
checkItems bob
where
@@ -5899,13 +5899,13 @@ testMembershipProfileUpdateContactActive =
bob ##> "/_get chat #1 count=100"
rGrp <- chat <$> getTermLine bob
rGrp `shouldNotContain` [(0, "updated profile")]
checkAliceProfileLink bob name cLink = do
checkAliceProfileLink bob name sLink = do
bob ##> ("/info #team " <> name)
bob <## "group ID: 1"
bob <## "member ID: 1"
bob <##. "receiving messages via"
bob <##. "sending messages via"
bob <## ("contact address: " <> cLink)
bob <## ("contact address: " <> sLink)
bob <## "connection not verified, use /code command to see security code"
bob <## currentChatVRangeInfo
+141 -69
View File
@@ -48,10 +48,12 @@ chatProfileTests = do
it "deduplicate contact requests with profile change" testDeduplicateContactRequestsProfileChange
it "reject contact and delete contact link" testRejectContactAndDeleteUserContact
it "delete connection requests when contact link deleted" testDeleteConnectionRequests
-- TODO [short links] test auto-reply with current version, with connecting client not preparing contact
it "auto-reply message" testAutoReplyMessage
it "auto-reply message in incognito" testAutoReplyMessageInIncognito
describe "business address" $ do
it "create and connect via business address" testBusinessAddress
-- TODO [short links] test business auto-reply with current version, with connecting client not preparing contact
it "update profiles with business address" testBusinessUpdateProfiles
describe "contact address connection plan" $ do
it "contact address ok to connect; known contact" testPlanAddressOkKnown
@@ -60,6 +62,7 @@ chatProfileTests = do
it "connecting via contact address (slow handshake)" testPlanAddressConnectingSlow
it "re-connect with deleted contact" testPlanAddressContactDeletedReconnected
it "contact via address" testPlanAddressContactViaAddress
it "contact via short address" testPlanAddressContactViaShortAddress
describe "incognito" $ do
it "connect incognito via invitation link" testConnectIncognitoInvitationLink
it "connect incognito via contact address" testConnectIncognitoContactAddress
@@ -357,9 +360,9 @@ testProfileLink =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
alice ##> "/ad"
cLink <- getContactLink alice True
(sLink, _cLink) <- getContactLinks alice True
bob ##> ("/c " <> cLink)
bob ##> ("/c " <> sLink)
alice <#? bob
alice ##> "/ac bob"
alice <## "bob (Bob): accepting contact request, you can send messages to contact"
@@ -372,9 +375,9 @@ testProfileLink =
alice <## "new contact address set"
bob <## "alice set new contact address, use /info alice to view"
checkAliceProfileLink bob cLink
checkAliceProfileLink bob sLink
cath ##> ("/c " <> cLink)
cath ##> ("/c " <> sLink)
alice <#? cath
alice ##> "/ac cath"
alice <## "cath (Catherine): accepting contact request, you can send messages to contact"
@@ -383,7 +386,7 @@ testProfileLink =
(alice <## "cath (Catherine): contact is connected")
alice <##> cath
checkAliceProfileLink cath cLink
checkAliceProfileLink cath sLink
alice ##> "/pa off"
alice <## "contact address removed"
@@ -398,10 +401,10 @@ testProfileLink =
alice <## "new contact address set"
bob <## "alice set new contact address, use /info alice to view"
checkAliceProfileLink bob cLink
checkAliceProfileLink bob sLink
cath <## "alice set new contact address, use /info alice to view"
checkAliceProfileLink cath cLink
checkAliceProfileLink cath sLink
alice ##> "/da"
alice <## "Your chat address is deleted - accepted contacts will remain connected."
@@ -413,12 +416,12 @@ testProfileLink =
cath <## "alice removed contact address"
checkAliceNoProfileLink cath
where
checkAliceProfileLink cc cLink = do
checkAliceProfileLink cc sLink = do
cc ##> "/info alice"
cc <## "contact ID: 2"
cc <##. "receiving messages via"
cc <##. "sending messages via"
cc <## ("contact address: " <> cLink)
cc <## ("contact address: " <> sLink)
cc <## "you've shared main profile with this contact"
cc <## "connection not verified, use /code command to see security code"
cc <## "quantum resistant end-to-end encryption"
@@ -666,10 +669,10 @@ testDeleteConnectionRequests = testChat3 aliceProfile bobProfile cathProfile $
alice <#? cath
testAutoReplyMessage :: HasCallStack => TestParams -> IO ()
testAutoReplyMessage = testChat2 aliceProfile bobProfile $
testAutoReplyMessage = testChatCfg2 testCfgNoShortLinks aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad"
cLink <- getContactLink alice True
cLink <- getContactLinkNoShortLink alice True
alice ##> "/_auto_accept 1 on incognito=off text hello!"
alice <## "auto_accept on"
alice <## "auto reply:"
@@ -688,10 +691,10 @@ testAutoReplyMessage = testChat2 aliceProfile bobProfile $
]
testAutoReplyMessageInIncognito :: HasCallStack => TestParams -> IO ()
testAutoReplyMessageInIncognito = testChat2 aliceProfile bobProfile $
testAutoReplyMessageInIncognito = testChatCfg2 testCfgNoShortLinks aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad"
cLink <- getContactLink alice True
cLink <- getContactLinkNoShortLink alice True
alice ##> "/auto_accept on incognito=on text hello!"
alice <## "auto_accept on, incognito"
alice <## "auto reply:"
@@ -767,10 +770,10 @@ testBusinessAddress = testChat3 businessProfile aliceProfile {fullName = "Alice
(biz <# "#bob bob_1> hey there")
testBusinessUpdateProfiles :: HasCallStack => TestParams -> IO ()
testBusinessUpdateProfiles = testChat4 businessProfile aliceProfile bobProfile cathProfile $
testBusinessUpdateProfiles = testChatCfg4 testCfgNoShortLinks businessProfile aliceProfile bobProfile cathProfile $
\biz alice bob cath -> do
biz ##> "/ad"
cLink <- getContactLink biz True
cLink <- getContactLinkNoShortLink biz True
biz ##> "/auto_accept on business text Welcome"
biz <## "auto_accept on, business"
biz <## "auto reply:"
@@ -800,7 +803,7 @@ testBusinessUpdateProfiles = testChat4 businessProfile aliceProfile bobProfile c
biz ##> "/mr alisa alisa_1 admin"
biz <## "#alisa: you changed the role of alisa_1 to admin"
alice <## "#biz: biz_1 changed your role from member to admin"
connectUsers alice bob
connectUsersNoShortLink alice bob
alice ##> "/a #biz bob"
alice <## "invitation to join the group #biz sent to bob"
bob <## "#biz (Biz Inc): alisa invites you to join the group as member"
@@ -831,7 +834,7 @@ testBusinessUpdateProfiles = testChat4 businessProfile aliceProfile bobProfile c
alice <# "#biz robert> hi there"
biz <# "#alisa robert> hi there"
-- add business team member
connectUsers biz cath
connectUsersNoShortLink biz cath
biz ##> "/a #alisa cath"
biz <## "invitation to join the group #alisa sent to cath"
cath <## "#alisa: biz invites you to join the group as member"
@@ -1025,7 +1028,7 @@ testPlanAddressConnectingSlow :: HasCallStack => TestParams -> IO ()
testPlanAddressConnectingSlow ps = do
cLink <- withNewTestChatCfg ps testCfgSlow "alice" aliceProfile $ \alice -> do
alice ##> "/ad"
getContactLink alice True
getContactLinkNoShortLink alice True
withNewTestChatCfg ps testCfgSlow "bob" bobProfile $ \bob -> do
threadDelay 100000
@@ -1130,7 +1133,7 @@ testPlanAddressContactViaAddress =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad"
cLink <- getContactLink alice True
(_sLink, cLink) <- getContactLinks alice True
alice ##> "/pa on" -- not necessary, without it bob would receive profile update removing contact link
alice <## "new contact address set"
@@ -1151,10 +1154,6 @@ testPlanAddressContactViaAddress =
bob ##> ("/_connect plan 1 " <> cLink)
bob <## "contact address: known contact without connection alice"
let cLinkSchema2 = linkAnotherSchema cLink
bob ##> ("/_connect plan 1 " <> cLinkSchema2)
bob <## "contact address: known contact without connection alice"
-- terminal api
bob ##> ("/c " <> cLink)
connecting alice bob
@@ -1175,6 +1174,68 @@ testPlanAddressContactViaAddress =
#endif
connecting alice bob
where
connecting alice bob = do
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, you can send messages to contact"
concurrentlyN_
[ do
bob <## "alice set new contact address, use /info alice to view"
bob <## "alice (Alice): contact is connected",
alice <## "bob (Bob): contact is connected"
]
alice <##> bob
bob @@@ [("@alice", "hey")]
testPlanAddressContactViaShortAddress :: HasCallStack => TestParams -> IO ()
testPlanAddressContactViaShortAddress =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad"
(sLink, _) <- getContactLinks alice True
alice ##> "/pa on" -- not necessary, without it bob would receive profile update removing contact link
alice <## "new contact address set"
case A.parseOnly strP (B.pack sLink) of
Left _ -> error "error parsing contact link"
Right shortLink -> do
let profile = aliceProfile {contactLink = Just shortLink}
void $ withCCUser bob $ \user -> withCCTransaction bob $ \db -> runExceptT $ createContact db user profile
bob @@@ [("@alice", "")]
bob ##> "/delete @alice"
bob <## "alice: contact is deleted"
void $ withCCUser bob $ \user -> withCCTransaction bob $ \db -> runExceptT $ createContact db user profile
bob @@@ [("@alice", "")]
bob ##> ("/_connect plan 1 " <> sLink)
bob <## "contact address: known contact without connection alice"
-- terminal api
bob ##> ("/c " <> sLink)
connecting alice bob
bob ##> "/delete @alice"
bob <## "alice: contact is deleted"
alice ##> "/delete @bob"
alice <## "bob: contact is deleted"
void $ withCCUser bob $ \user -> withCCTransaction bob $ \db -> runExceptT $ createContact db user profile
bob @@@ [("@alice", "")]
-- GUI api
#if defined(dbPostgres)
bob ##> "/_connect contact 1 4"
#else
bob ##> "/_connect contact 1 2"
#endif
connecting alice bob
where
connecting alice bob = do
bob <## "connection request sent!"
alice <## "bob (Bob) wants to connect to you!"
@@ -1185,7 +1246,6 @@ testPlanAddressContactViaAddress =
concurrently_
(bob <## "alice (Alice): contact is connected")
(alice <## "bob (Bob): contact is connected")
alice <##> bob
bob @@@ [("@alice", "hey")]
@@ -1302,10 +1362,10 @@ testConnectIncognitoContactAddress = testChat2 aliceProfile bobProfile $
bob `hasContactProfiles` ["bob"]
testAcceptContactRequestIncognito :: HasCallStack => TestParams -> IO ()
testAcceptContactRequestIncognito = testChat3 aliceProfile bobProfile cathProfile $
testAcceptContactRequestIncognito = testChatCfg3 testCfgNoShortLinks aliceProfile bobProfile cathProfile $
\alice bob cath -> do
alice ##> "/ad"
cLink <- getContactLink alice True
cLink <- getContactLinkNoShortLink alice True
-- GUI /_accept api
bob ##> ("/c " <> cLink)
alice <#? bob
@@ -1415,7 +1475,7 @@ testSetConnectionIncognitoProhibitedDuringNegotiationSlow ps = do
inv <- withNewTestChatCfg ps testCfgSlow "alice" aliceProfile $ \alice -> do
threadDelay 250000
alice ##> "/connect"
getInvitation alice
getInvitationNoShortLink alice
withNewTestChatCfg ps testCfgSlow "bob" bobProfile $ \bob -> do
threadDelay 250000
bob ##> ("/c " <> inv)
@@ -1869,14 +1929,18 @@ testChangePCCUser = testChat2 aliceProfile bobProfile $
alice <## ""
_ <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
_ <- getTermLine alice
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection back to other user
alice ##> "/_set conn user :1 3"
alice <## "connection 1 changed from user alisa to user alisa2, new link:"
alice <## ""
inv <- getTermLine alice
_shortInv <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
inv <- getTermLine alice
alice ##> "/user alisa2"
showActiveUser alice "alisa2"
-- Connect
@@ -1907,6 +1971,8 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
alice <## ""
_ <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
_ <- getTermLine alice
alice `hasContactProfiles` ["alice"]
alice ##> "/user alisa"
showActiveUser alice "alisa"
@@ -1914,8 +1980,10 @@ testChangePCCUserFromIncognito = testChat2 aliceProfile bobProfile $
alice ##> "/_set conn user :1 1"
alice <## "connection 1 changed from user alisa to user alice, new link:"
alice <## ""
inv <- getTermLine alice
_shortInv <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
inv <- getTermLine alice
alice ##> "/user alice"
showActiveUser alice "alice (Alice)"
-- Connect
@@ -1941,8 +2009,10 @@ testChangePCCUserAndThenIncognito = testChat2 aliceProfile bobProfile $
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa, new link:"
alice <## ""
inv <- getTermLine alice
_shortInv <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
inv <- getTermLine alice
alice ##> "/user alisa"
showActiveUser alice "alisa"
-- Change connection to incognito and make sure it's attached to the newly created user profile
@@ -1992,8 +2062,10 @@ testChangePCCUserDiffSrv ps = do
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa, new link:"
alice <## ""
inv <- getTermLine alice
_shortInv <- getTermLine alice
alice <## ""
alice <## "The invitation link for old clients:"
inv <- getTermLine alice
alice `hasContactProfiles` ["alice"]
alice ##> "/user alisa"
showActiveUser alice "alisa"
@@ -2645,8 +2717,8 @@ testSetUITheme =
testShortLinkInvitation :: HasCallStack => TestParams -> IO ()
testShortLinkInvitation =
testChat2 aliceProfile bobProfile $ \alice bob -> do
alice ##> "/c short"
(inv, _) <- getShortInvitation alice
alice ##> "/c"
(inv, _) <- getInvitations alice
bob ##> ("/c " <> inv)
bob <## "confirmation sent!"
concurrently_
@@ -2660,8 +2732,8 @@ testShortLinkInvitation =
testPlanShortLinkInvitation :: HasCallStack => TestParams -> IO ()
testPlanShortLinkInvitation =
testChat3 aliceProfile bobProfile cathProfile $ \alice bob cath -> do
alice ##> "/c short"
(inv, _) <- getShortInvitation alice
alice ##> "/c"
(inv, _) <- getInvitations alice
alice ##> ("/_connect plan 1 " <> inv)
alice <## "invitation link: own link"
alice ##> ("/_connect plan 1 " <> slSimplexScheme inv)
@@ -2702,8 +2774,8 @@ slSimplexScheme sl = T.unpack $ T.replace "https://localhost/" "simplex:/" (T.pa
testShortLinkContactAddress :: HasCallStack => TestParams -> IO ()
testShortLinkContactAddress =
testChat4 aliceProfile bobProfile cathProfile danProfile $ \alice bob cath dan -> do
alice ##> "/ad short"
(shortLink, fullLink) <- getShortContactLink alice True
alice ##> "/ad"
(shortLink, fullLink) <- getContactLinks alice True
alice ##> ("/_connect plan 1 " <> shortLink)
alice <## "contact address: own address"
alice ##> ("/_connect plan 1 " <> slSimplexScheme shortLink)
@@ -2741,13 +2813,13 @@ testShortLinkJoinGroup :: HasCallStack => TestParams -> IO ()
testShortLinkJoinGroup =
testChat4 aliceProfile bobProfile cathProfile danProfile $ \alice bob cath dan -> do
threadDelay 100000
alice ##> "/ad short" -- create the address to test that it can co-exist with group link
_ <- getShortContactLink alice True
alice ##> "/ad" -- create the address to test that it can co-exist with group link
_ <- getContactLinks alice True
alice ##> "/g team"
alice <## "group #team is created"
alice <## "to add members use /a team <name> or /create link #team"
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
alice ##> ("/_connect plan 1 " <> shortLink)
alice <## "group link: own link for group #team"
alice ##> ("/_connect plan 1 " <> slSimplexScheme shortLink)
@@ -2810,8 +2882,8 @@ testShortLinkInvitationPrepareContact :: HasCallStack => TestParams -> IO ()
testShortLinkInvitationPrepareContact =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/_connect 1 short=on"
(shortLink, fullLink) <- getShortInvitation alice
alice ##> "/_connect 1"
(shortLink, fullLink) <- getInvitations alice
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "invitation link: ok to connect"
contactSLinkData <- getTermLine bob
@@ -2830,8 +2902,8 @@ testShortLinkInvitationPrepareContact =
testShortLinkInvitationImage :: HasCallStack => TestParams -> IO ()
testShortLinkInvitationImage = testChat2 aliceProfile bobProfile $ \alice bob -> do
bob ##> "/_connect 1 short=on"
(shortLink, fullLink) <- getShortInvitation bob
bob ##> "/_connect 1"
(shortLink, fullLink) <- getInvitations bob
alice ##> ("/_connect plan 1 " <> shortLink)
alice <## "invitation link: ok to connect"
contactSLinkData <- getTermLine alice
@@ -2852,8 +2924,8 @@ testShortLinkAddressPrepareContact :: HasCallStack => TestParams -> IO ()
testShortLinkAddressPrepareContact =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad short"
(shortLink, fullLink) <- getShortContactLink alice True
alice ##> "/ad"
(shortLink, fullLink) <- getContactLinks alice True
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "contact address: ok to connect"
contactSLinkData <- getTermLine bob
@@ -2884,8 +2956,8 @@ testShortLinkPrepareGroup =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice cath
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "group link: ok to connect"
groupSLinkData <- getTermLine bob
@@ -2916,8 +2988,8 @@ testShortLinkPrepareGroupReject =
testChatCfg3 cfg aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice cath
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "group link: ok to connect"
groupSLinkData <- getTermLine bob
@@ -2949,8 +3021,8 @@ testShortLinkChangePreparedContactUser =
bob ##> "/user bob"
showActiveUser bob "bob (Bob)"
alice ##> "/_connect 1 short=on"
(shortLink, fullLink) <- getShortInvitation alice
alice ##> "/_connect 1"
(shortLink, fullLink) <- getInvitations alice
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "invitation link: ok to connect"
contactSLinkData <- getTermLine bob
@@ -2998,8 +3070,8 @@ testShortLinkChangePreparedContactUserDuplicate =
bob ##> "/user bob"
showActiveUser bob "bob (Bob)"
alice ##> "/_connect 1 short=on"
(shortLink, fullLink) <- getShortInvitation alice
alice ##> "/_connect 1"
(shortLink, fullLink) <- getInvitations alice
bob ##> ("/_connect plan 1 " <> shortLink)
bob <## "invitation link: ok to connect"
contactSLinkData <- getTermLine bob
@@ -3047,8 +3119,8 @@ testShortLinkChangePreparedGroupUser =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice cath
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
bob ##> "/create user robert"
showActiveUser bob "robert"
@@ -3105,8 +3177,8 @@ testShortLinkChangePreparedGroupUserDuplicate =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice cath
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
bob ##> "/create user robert"
showActiveUser bob "robert"
@@ -3217,8 +3289,8 @@ testShortLinkInvitationSetIncognito :: HasCallStack => TestParams -> IO ()
testShortLinkInvitationSetIncognito =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/_connect 1 short=on"
(shortLink, fullLink) <- getShortInvitation alice
alice ##> "/_connect 1"
(shortLink, fullLink) <- getInvitations alice
alice ##> "/_set incognito :1 on"
aliceIncognito <- getTermLine alice
@@ -3256,8 +3328,8 @@ testShortLinkInvitationChangeUser =
alice ##> "/user alice"
showActiveUser alice "alice (Alice)"
alice ##> "/_connect 1 short=on"
_ <- getShortInvitation alice
alice ##> "/_connect 1"
_ <- getInvitations alice
alice ##> "/_set conn user :1 2"
alice <## "connection 1 changed from user alice to user alisa, new link:"
@@ -3289,8 +3361,8 @@ testShortLinkAddressChangeProfile :: HasCallStack => TestParams -> IO ()
testShortLinkAddressChangeProfile =
testChat2 aliceProfile bobProfile $
\alice bob -> do
alice ##> "/ad short"
(shortLink, fullLink) <- getShortContactLink alice True
alice ##> "/ad"
(shortLink, fullLink) <- getContactLinks alice True
alice ##> "/p alisa"
alice <## "user profile is changed to alisa (your 0 contacts are notified)"
@@ -3324,8 +3396,8 @@ testShortLinkAddressChangeAutoReply :: HasCallStack => TestParams -> IO ()
testShortLinkAddressChangeAutoReply =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
alice ##> "/ad short"
(shortLink, fullLink) <- getShortContactLink alice True
alice ##> "/ad"
(shortLink, fullLink) <- getContactLinks alice True
alice ##> "/_auto_accept 1 on incognito=off text welcome!"
alice <## "auto_accept on"
@@ -3378,8 +3450,8 @@ testShortLinkGroupChangeProfile =
testChat3 aliceProfile bobProfile cathProfile $
\alice bob cath -> do
createGroup2 "team" alice cath
alice ##> "/create link #team short"
(shortLink, fullLink) <- getShortGroupLink alice "team" GRMember True
alice ##> "/create link #team"
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
alice ##> "/gp team club"
alice <## "changed to #club"
+59 -34
View File
@@ -101,15 +101,15 @@ skip :: String -> SpecWith a -> SpecWith a
skip = before_ . pendingWith
-- Bool is pqExpected - see testAddContact
versionTestMatrix2 :: (HasCallStack => Bool -> TestCC -> TestCC -> IO ()) -> SpecWith TestParams
versionTestMatrix2 :: (HasCallStack => Bool -> Bool -> TestCC -> TestCC -> IO ()) -> SpecWith TestParams
versionTestMatrix2 runTest = do
it "current" $ testChat2 aliceProfile bobProfile (runTest True)
it "prev" $ testChatCfg2 testCfgVPrev aliceProfile bobProfile (runTest False)
it "prev to curr" $ runTestCfg2 testCfg testCfgVPrev (runTest False)
it "curr to prev" $ runTestCfg2 testCfgVPrev testCfg (runTest False)
it "old (1st supported)" $ testChatCfg2 testCfgV1 aliceProfile bobProfile (runTest False)
it "old to curr" $ runTestCfg2 testCfg testCfgV1 (runTest False)
it "curr to old" $ runTestCfg2 testCfgV1 testCfg (runTest False)
it "current" $ testChat2 aliceProfile bobProfile (runTest True True)
it "prev" $ testChatCfg2 testCfgVPrev aliceProfile bobProfile (runTest False True)
it "prev to curr" $ runTestCfg2 testCfg testCfgVPrev (runTest False True)
it "curr to prev" $ runTestCfg2 testCfgVPrev testCfg (runTest False True)
it "old (1st supported)" $ testChatCfg2 testCfgV1 aliceProfile bobProfile (runTest False False)
it "old to curr" $ runTestCfg2 testCfg testCfgV1 (runTest False True)
it "curr to old" $ runTestCfg2 testCfgV1 testCfg (runTest False False)
versionTestMatrix3 :: (HasCallStack => TestCC -> TestCC -> TestCC -> IO ()) -> SpecWith TestParams
versionTestMatrix3 runTest = do
@@ -506,35 +506,44 @@ dropPartialReceipt_ msg = case splitAt 2 msg of
getInvitation :: HasCallStack => TestCC -> IO String
getInvitation cc = do
(inv, _) <- getInvitation_ False cc
pure inv
(_, fullInv) <- getInvitations cc
pure fullInv
getShortInvitation :: HasCallStack => TestCC -> IO (String, String)
getShortInvitation = getInvitation_ True
getInvitations :: HasCallStack => TestCC -> IO (String, String)
getInvitations cc = do
shortInv <- getInvitation_ cc
cc <##. "The invitation link for old clients:"
fullInv <- getTermLine cc
pure (shortInv, fullInv)
getInvitation_ :: HasCallStack => Bool -> TestCC -> IO (String, String)
getInvitation_ short cc = do
getInvitationNoShortLink :: HasCallStack => TestCC -> IO String
getInvitationNoShortLink = getInvitation_
getInvitation_ :: HasCallStack => TestCC -> IO String
getInvitation_ cc = do
cc <## "pass this invitation link to your contact (via another channel):"
cc <## ""
inv <- getTermLine cc
cc <## ""
cc <## "and ask them to connect: /c <invitation_link_above>"
fullLink <-
if short
then do
cc <##. "The invitation link for old clients:"
getTermLine cc
else pure ""
pure (inv, fullLink)
getShortContactLink :: HasCallStack => TestCC -> Bool -> IO (String, String)
getShortContactLink cc created = do
shortLink <- getContactLink cc created
fullLink <- dropLinePrefix "The contact link for old clients: " =<< getTermLine cc
pure (shortLink, fullLink)
pure inv
getContactLink :: HasCallStack => TestCC -> Bool -> IO String
getContactLink cc created = do
(_shortLink, fullLink) <- getContactLinks cc created
pure fullLink
getContactLinks :: HasCallStack => TestCC -> Bool -> IO (String, String)
getContactLinks cc created = do
shortLink <- getContactLink_ cc created
fullLink <- dropLinePrefix "The contact link for old clients: " =<< getTermLine cc
pure (shortLink, fullLink)
getContactLinkNoShortLink :: HasCallStack => TestCC -> Bool -> IO String
getContactLinkNoShortLink = getContactLink_
getContactLink_ :: HasCallStack => TestCC -> Bool -> IO String
getContactLink_ cc created = do
cc <## if created then "Your new chat address is created!" else "Your chat address:"
cc <## ""
link <- getTermLine cc
@@ -550,14 +559,22 @@ dropLinePrefix line s
| line `isPrefixOf` s = pure $ drop (length line) s
| otherwise = error $ "expected to start from: " <> line <> ", got: " <> s
getShortGroupLink :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO (String, String)
getShortGroupLink cc gName mRole created = do
shortLink <- getGroupLink cc gName mRole created
getGroupLink :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO String
getGroupLink cc gName mRole created = do
(_shortLink, fullLink) <- getGroupLinks cc gName mRole created
pure fullLink
getGroupLinks :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO (String, String)
getGroupLinks cc gName mRole created = do
shortLink <- getGroupLink_ cc gName mRole created
fullLink <- dropLinePrefix "The group link for old clients: " =<< getTermLine cc
pure (shortLink, fullLink)
getGroupLink :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO String
getGroupLink cc gName mRole created = do
getGroupLinkNoShortLink :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO String
getGroupLinkNoShortLink = getGroupLink_
getGroupLink_ :: HasCallStack => TestCC -> String -> GroupMemberRole -> Bool -> IO String
getGroupLink_ cc gName mRole created = do
cc <## if created then "Group link is created!" else "Group link:"
cc <## ""
link <- getTermLine cc
@@ -646,12 +663,20 @@ showActiveUser cc name = do
cc <## "use /p <display name> to change it"
cc <## "(the updated profile will be sent to all your contacts)"
connectUsersNoShortLink :: HasCallStack => TestCC -> TestCC -> IO ()
connectUsersNoShortLink cc1 cc2 = connectUsers_ cc1 cc2 True
connectUsers :: HasCallStack => TestCC -> TestCC -> IO ()
connectUsers cc1 cc2 = do
connectUsers cc1 cc2 = connectUsers_ cc1 cc2 False
connectUsers_ :: HasCallStack => TestCC -> TestCC -> Bool -> IO ()
connectUsers_ cc1 cc2 noShortLink = do
name1 <- showName cc1
name2 <- showName cc2
cc1 ##> "/c"
inv <- getInvitation cc1
inv <- if noShortLink
then getInvitationNoShortLink cc1
else getInvitation cc1
cc2 ##> ("/c " <> inv)
cc2 <## "confirmation sent!"
concurrently_