mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Merge branch 'master' into master-android
This commit is contained in:
+4
-4
@@ -8,7 +8,7 @@ import Test.Hspec
|
||||
|
||||
chatTests :: SpecWith FilePath
|
||||
chatTests = do
|
||||
chatDirectTests
|
||||
chatGroupTests
|
||||
chatFileTests
|
||||
chatProfileTests
|
||||
describe "direct tests" chatDirectTests
|
||||
describe "group tests" chatGroupTests
|
||||
describe "file tests" chatFileTests
|
||||
describe "profile tests" chatProfileTests
|
||||
|
||||
@@ -29,6 +29,7 @@ chatFileTests :: SpecWith FilePath
|
||||
chatFileTests = do
|
||||
describe "sending and receiving files" $ do
|
||||
describe "send and receive file" $ fileTestMatrix2 runTestFileTransfer
|
||||
describe "send file, receive and locally encrypt file" $ fileTestMatrix2 runTestFileTransferEncrypted
|
||||
it "send and receive file inline (without accepting)" testInlineFileTransfer
|
||||
xit'' "accept inline file transfer, sender cancels during transfer" testAcceptInlineFileSndCancelDuringTransfer
|
||||
it "send and receive small file inline (default config)" testSmallInlineFileTransfer
|
||||
@@ -95,6 +96,37 @@ runTestFileTransfer alice bob = do
|
||||
dest <- B.readFile "./tests/tmp/test.pdf"
|
||||
dest `shouldBe` src
|
||||
|
||||
runTestFileTransferEncrypted :: HasCallStack => TestCC -> TestCC -> IO ()
|
||||
runTestFileTransferEncrypted alice bob = do
|
||||
connectUsers alice bob
|
||||
alice #> "/f @bob ./tests/fixtures/test.pdf"
|
||||
alice <## "use /fc 1 to cancel sending"
|
||||
bob <# "alice> sends file test.pdf (266.0 KiB / 272376 bytes)"
|
||||
bob <## "use /fr 1 [<dir>/ | <path>] to receive it"
|
||||
bob ##> "/fr 1 encrypt=on ./tests/tmp"
|
||||
bob <## "saving file 1 from alice to ./tests/tmp/test.pdf"
|
||||
Just (CFArgs key nonce) <- J.decode . LB.pack <$> getTermLine bob
|
||||
concurrently_
|
||||
(bob <## "started receiving file 1 (test.pdf) from alice")
|
||||
(alice <## "started sending file 1 (test.pdf) to bob")
|
||||
|
||||
concurrentlyN_
|
||||
[ do
|
||||
bob #> "@alice receiving here..."
|
||||
-- uncomment this and below to test encryption error in encryptFile
|
||||
-- bob <## "cannot write file ./tests/tmp/test.pdf: test error, received file not encrypted"
|
||||
bob <## "completed receiving file 1 (test.pdf) from alice",
|
||||
alice
|
||||
<### [ WithTime "bob> receiving here...",
|
||||
"completed sending file 1 (test.pdf) to bob"
|
||||
]
|
||||
]
|
||||
src <- B.readFile "./tests/fixtures/test.pdf"
|
||||
-- dest <- B.readFile "./tests/tmp/test.pdf"
|
||||
-- dest `shouldBe` src
|
||||
Right dest <- chatReadFile "./tests/tmp/test.pdf" (strEncode key) (strEncode nonce)
|
||||
LB.toStrict dest `shouldBe` src
|
||||
|
||||
testInlineFileTransfer :: HasCallStack => FilePath -> IO ()
|
||||
testInlineFileTransfer =
|
||||
testChatCfg2 cfg aliceProfile bobProfile $ \alice bob -> do
|
||||
|
||||
+263
-118
@@ -68,19 +68,12 @@ chatGroupTests = do
|
||||
it "should send delivery receipts in group depending on configuration" testConfigureGroupDeliveryReceipts
|
||||
describe "direct connections in group are not established based on chat protocol version" $ do
|
||||
describe "3 members group" $ do
|
||||
testNoDirect _0 _0 False -- True
|
||||
testNoDirect _0 _1 False -- True
|
||||
testNoDirect _0 _0 True
|
||||
testNoDirect _0 _1 True
|
||||
testNoDirect _1 _0 False
|
||||
testNoDirect _1 _1 False
|
||||
describe "4 members group" $ do
|
||||
testNoDirect4 _0 _0 _0 False False False -- True True True
|
||||
testNoDirect4 _0 _0 _1 False False False -- True True True
|
||||
testNoDirect4 _0 _1 _0 False False False -- True True False
|
||||
testNoDirect4 _0 _1 _1 False False False -- True True False
|
||||
testNoDirect4 _1 _0 _0 False False False -- False False True
|
||||
testNoDirect4 _1 _0 _1 False False False -- False False True
|
||||
testNoDirect4 _1 _1 _0 False False False
|
||||
testNoDirect4 _1 _1 _1 False False False
|
||||
it "members have different local display names in different groups" testNoDirectDifferentLDNs
|
||||
it "member should connect to contact when profile match" testConnectMemberToContact
|
||||
describe "create member contact" $ do
|
||||
it "create contact with group member with invitation message" testMemberContactMessage
|
||||
it "create contact with group member without invitation message" testMemberContactNoMessage
|
||||
@@ -88,6 +81,7 @@ chatGroupTests = do
|
||||
it "prohibited to repeat sending x.grp.direct.inv" testMemberContactProhibitedRepeatInv
|
||||
it "invited member replaces member contact reference if it already exists" testMemberContactInvitedConnectionReplaced
|
||||
it "share incognito profile" testMemberContactIncognito
|
||||
it "sends and updates profile when creating contact" testMemberContactProfileUpdate
|
||||
where
|
||||
_0 = supportedChatVRange -- don't create direct connections
|
||||
_1 = groupCreateDirectVRange
|
||||
@@ -101,17 +95,6 @@ chatGroupTests = do
|
||||
<> (if noConns then " : 2 <!!> 3" else " : 2 <##> 3")
|
||||
)
|
||||
$ testNoGroupDirectConns supportedChatVRange vrMem2 vrMem3 noConns
|
||||
testNoDirect4 vrMem2 vrMem3 vrMem4 noConns23 noConns24 noConns34 =
|
||||
it
|
||||
( "host " <> vRangeStr supportedChatVRange
|
||||
<> (", 2nd mem " <> vRangeStr vrMem2)
|
||||
<> (", 3rd mem " <> vRangeStr vrMem3)
|
||||
<> (", 4th mem " <> vRangeStr vrMem4)
|
||||
<> (if noConns23 then " : 2 <!!> 3" else " : 2 <##> 3")
|
||||
<> (if noConns24 then " : 2 <!!> 4" else " : 2 <##> 4")
|
||||
<> (if noConns34 then " : 3 <!!> 4" else " : 3 <##> 4")
|
||||
)
|
||||
$ testNoGroupDirectConns4Members supportedChatVRange vrMem2 vrMem3 vrMem4 noConns23 noConns24 noConns34
|
||||
|
||||
testGroup :: HasCallStack => FilePath -> IO ()
|
||||
testGroup =
|
||||
@@ -240,7 +223,7 @@ testGroupShared alice bob cath checkMessages = do
|
||||
alice `send` "@bob hey"
|
||||
alice
|
||||
<### [ "@bob hey",
|
||||
"member #team bob does not have associated contact, creating contact",
|
||||
"member #team bob does not have direct connection, creating",
|
||||
"peer chat protocol version range incompatible"
|
||||
]
|
||||
when checkMessages $ threadDelay 1000000
|
||||
@@ -657,7 +640,7 @@ testGroupDeleteInvitedContact =
|
||||
alice `send` "@bob hey"
|
||||
alice
|
||||
<### [ WithTime "@bob hey",
|
||||
"member #team bob does not have associated contact, creating contact",
|
||||
"member #team bob does not have direct connection, creating",
|
||||
"contact for member #team bob is created",
|
||||
"sent invitation to connect directly to member #team bob"
|
||||
]
|
||||
@@ -2658,56 +2641,140 @@ testNoGroupDirectConns hostVRange mem2VRange mem3VRange noDirectConns tmp =
|
||||
createGroup3 "team" alice bob cath
|
||||
if noDirectConns
|
||||
then contactsDontExist bob cath
|
||||
else bob <##> cath
|
||||
else contactsExist bob cath
|
||||
where
|
||||
contactsDontExist bob cath = do
|
||||
bob ##> "@cath hi"
|
||||
bob <## "no contact cath"
|
||||
cath ##> "@bob hi"
|
||||
cath <## "no contact bob"
|
||||
bob ##> "/contacts"
|
||||
bob <## "alice (Alice)"
|
||||
cath ##> "/contacts"
|
||||
cath <## "alice (Alice)"
|
||||
contactsExist bob cath = do
|
||||
bob ##> "/contacts"
|
||||
bob
|
||||
<### [ "alice (Alice)",
|
||||
"cath (Catherine)"
|
||||
]
|
||||
cath ##> "/contacts"
|
||||
cath
|
||||
<### [ "alice (Alice)",
|
||||
"bob (Bob)"
|
||||
]
|
||||
bob <##> cath
|
||||
|
||||
testNoGroupDirectConns4Members :: HasCallStack => VersionRange -> VersionRange -> VersionRange -> VersionRange -> Bool -> Bool -> Bool -> FilePath -> IO ()
|
||||
testNoGroupDirectConns4Members hostVRange mem2VRange mem3VRange mem4VRange noConns23 noConns24 noConns34 tmp =
|
||||
withNewTestChatCfg tmp testCfg {chatVRange = hostVRange} "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChatCfg tmp testCfg {chatVRange = mem2VRange} "bob" bobProfile $ \bob -> do
|
||||
withNewTestChatCfg tmp testCfg {chatVRange = mem3VRange} "cath" cathProfile $ \cath -> do
|
||||
withNewTestChatCfg tmp testCfg {chatVRange = mem4VRange} "dan" danProfile $ \dan -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
connectUsers alice dan
|
||||
addMember "team" alice dan GRMember
|
||||
dan ##> "/j team"
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: dan joined the group",
|
||||
do
|
||||
dan <## "#team: you joined the group"
|
||||
dan
|
||||
<### [ "#team: member bob (Bob) is connected",
|
||||
"#team: member cath (Catherine) is connected"
|
||||
],
|
||||
aliceAddedDan bob,
|
||||
aliceAddedDan cath
|
||||
]
|
||||
if noConns23
|
||||
then contactsDontExist bob cath
|
||||
else bob <##> cath
|
||||
if noConns24
|
||||
then contactsDontExist bob dan
|
||||
else bob <##> dan
|
||||
if noConns34
|
||||
then contactsDontExist cath dan
|
||||
else cath <##> dan
|
||||
testNoDirectDifferentLDNs :: HasCallStack => FilePath -> IO ()
|
||||
testNoDirectDifferentLDNs =
|
||||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
alice ##> "/g club"
|
||||
alice <## "group #club is created"
|
||||
alice <## "to add members use /a club <name> or /create link #club"
|
||||
addMember "club" alice bob GRAdmin
|
||||
bob ##> "/j club"
|
||||
concurrently_
|
||||
(alice <## "#club: bob joined the group")
|
||||
(bob <## "#club: you joined the group")
|
||||
addMember "club" alice cath GRAdmin
|
||||
cath ##> "/j club"
|
||||
concurrentlyN_
|
||||
[ alice <## "#club: cath joined the group",
|
||||
do
|
||||
cath <## "#club: you joined the group"
|
||||
cath <## "#club: member bob_1 (Bob) is connected",
|
||||
do
|
||||
bob <## "#club: alice added cath_1 (Catherine) to the group (connecting...)"
|
||||
bob <## "#club: new member cath_1 is connected"
|
||||
]
|
||||
|
||||
testGroupLDNs alice bob cath "team" "bob" "cath"
|
||||
testGroupLDNs alice bob cath "club" "bob_1" "cath_1"
|
||||
|
||||
alice `hasContactProfiles` ["alice", "bob", "cath"]
|
||||
bob `hasContactProfiles` ["bob", "alice", "cath", "cath"]
|
||||
cath `hasContactProfiles` ["cath", "alice", "bob", "bob"]
|
||||
where
|
||||
aliceAddedDan :: HasCallStack => TestCC -> IO ()
|
||||
aliceAddedDan cc = do
|
||||
cc <## "#team: alice added dan (Daniel) to the group (connecting...)"
|
||||
cc <## "#team: new member dan is connected"
|
||||
contactsDontExist cc1 cc2 = do
|
||||
name1 <- userName cc1
|
||||
name2 <- userName cc2
|
||||
cc1 ##> ("@" <> name2 <> " hi")
|
||||
cc1 <## ("no contact " <> name2)
|
||||
cc2 ##> ("@" <> name1 <> " hi")
|
||||
cc2 <## ("no contact " <> name1)
|
||||
testGroupLDNs alice bob cath gName bobLDN cathLDN = do
|
||||
alice ##> ("/ms " <> gName)
|
||||
alice
|
||||
<### [ "alice (Alice): owner, you, created group",
|
||||
"bob (Bob): admin, invited, connected",
|
||||
"cath (Catherine): admin, invited, connected"
|
||||
]
|
||||
|
||||
bob ##> ("/ms " <> gName)
|
||||
bob
|
||||
<### [ "alice (Alice): owner, host, connected",
|
||||
"bob (Bob): admin, you, connected",
|
||||
ConsoleString (cathLDN <> " (Catherine): admin, connected")
|
||||
]
|
||||
|
||||
cath ##> ("/ms " <> gName)
|
||||
cath
|
||||
<### [ "alice (Alice): owner, host, connected",
|
||||
ConsoleString (bobLDN <> " (Bob): admin, connected"),
|
||||
"cath (Catherine): admin, you, connected"
|
||||
]
|
||||
|
||||
alice #> ("#" <> gName <> " hello")
|
||||
concurrentlyN_
|
||||
[ bob <# ("#" <> gName <> " alice> hello"),
|
||||
cath <# ("#" <> gName <> " alice> hello")
|
||||
]
|
||||
bob #> ("#" <> gName <> " hi there")
|
||||
concurrentlyN_
|
||||
[ alice <# ("#" <> gName <> " bob> hi there"),
|
||||
cath <# ("#" <> gName <> " " <> bobLDN <> "> hi there")
|
||||
]
|
||||
cath #> ("#" <> gName <> " hey")
|
||||
concurrentlyN_
|
||||
[ alice <# ("#" <> gName <> " cath> hey"),
|
||||
bob <# ("#" <> gName <> " " <> cathLDN <> "> hey")
|
||||
]
|
||||
|
||||
testConnectMemberToContact :: HasCallStack => FilePath -> IO ()
|
||||
testConnectMemberToContact =
|
||||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
connectUsers alice bob
|
||||
connectUsers alice cath
|
||||
createGroup2 "team" bob cath
|
||||
bob ##> "/a #team alice"
|
||||
bob <## "invitation to join the group #team sent to alice"
|
||||
alice <## "#team: bob invites you to join the group as member"
|
||||
alice <## "use /j team to accept"
|
||||
alice ##> "/j team"
|
||||
concurrentlyN_
|
||||
[ do
|
||||
alice <## "#team: you joined the group"
|
||||
alice <## "#team: member cath_1 (Catherine) is connected"
|
||||
alice <## "member #team cath_1 is merged into cath",
|
||||
do
|
||||
bob <## "#team: alice joined the group",
|
||||
do
|
||||
cath <## "#team: bob added alice_1 (Alice) to the group (connecting...)"
|
||||
cath <## "#team: new member alice_1 is connected"
|
||||
cath <## "member #team alice_1 is merged into alice"
|
||||
]
|
||||
alice <##> cath
|
||||
alice #> "#team hello"
|
||||
bob <# "#team alice> hello"
|
||||
cath <# "#team alice> hello"
|
||||
cath #> "#team hello too"
|
||||
bob <# "#team cath> hello too"
|
||||
alice <# "#team cath> hello too"
|
||||
|
||||
alice ##> "/contacts"
|
||||
alice
|
||||
<### [ "bob (Bob)",
|
||||
"cath (Catherine)"
|
||||
]
|
||||
cath ##> "/contacts"
|
||||
cath
|
||||
<### [ "alice (Alice)",
|
||||
"bob (Bob)"
|
||||
]
|
||||
alice `hasContactProfiles` ["alice", "bob", "cath"]
|
||||
cath `hasContactProfiles` ["cath", "alice", "bob"]
|
||||
|
||||
testMemberContactMessage :: HasCallStack => FilePath -> IO ()
|
||||
testMemberContactMessage =
|
||||
@@ -2715,7 +2782,7 @@ testMemberContactMessage =
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
-- TODO here and in following tests there would be no direct contacts initially, after "no direct conns" functionality is uncommented
|
||||
-- alice and bob delete contacts, connect
|
||||
alice ##> "/d bob"
|
||||
alice <## "bob: contact is deleted"
|
||||
bob ##> "/d alice"
|
||||
@@ -2723,7 +2790,7 @@ testMemberContactMessage =
|
||||
|
||||
alice ##> "@#team bob hi"
|
||||
alice
|
||||
<### [ "member #team bob does not have associated contact, creating contact",
|
||||
<### [ "member #team bob does not have direct connection, creating",
|
||||
"contact for member #team bob is created",
|
||||
"sent invitation to connect directly to member #team bob",
|
||||
WithTime "@bob hi"
|
||||
@@ -2739,29 +2806,44 @@ testMemberContactMessage =
|
||||
bob #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")])
|
||||
alice <##> bob
|
||||
|
||||
-- bob and cath connect
|
||||
bob ##> "@#team cath hi"
|
||||
bob
|
||||
<### [ "member #team cath does not have direct connection, creating",
|
||||
"contact for member #team cath is created",
|
||||
"sent invitation to connect directly to member #team cath",
|
||||
WithTime "@cath hi"
|
||||
]
|
||||
cath
|
||||
<### [ "#team bob is creating direct contact bob with you",
|
||||
WithTime "bob> hi"
|
||||
]
|
||||
concurrently_
|
||||
(bob <## "cath (Catherine): contact is connected")
|
||||
(cath <## "bob (Bob): contact is connected")
|
||||
|
||||
cath #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")])
|
||||
bob <##> cath
|
||||
|
||||
testMemberContactNoMessage :: HasCallStack => FilePath -> IO ()
|
||||
testMemberContactNoMessage =
|
||||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
alice ##> "/d bob"
|
||||
alice <## "bob: contact is deleted"
|
||||
bob ##> "/d alice"
|
||||
bob <## "alice: contact is deleted"
|
||||
-- bob and cath connect
|
||||
bob ##> "/_create member contact #1 3"
|
||||
bob <## "contact for member #team cath is created"
|
||||
|
||||
alice ##> "/_create member contact #1 2"
|
||||
alice <## "contact for member #team bob is created"
|
||||
|
||||
alice ##> "/_invite member contact @4" -- cath is 3, new bob contact is 4
|
||||
alice <## "sent invitation to connect directly to member #team bob"
|
||||
bob <## "#team alice is creating direct contact alice with you"
|
||||
bob ##> "/_invite member contact @3"
|
||||
bob <## "sent invitation to connect directly to member #team cath"
|
||||
cath <## "#team bob is creating direct contact bob with you"
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(bob <## "cath (Catherine): contact is connected")
|
||||
(cath <## "bob (Bob): contact is connected")
|
||||
|
||||
bob #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")])
|
||||
alice <##> bob
|
||||
cath #$> ("/_get chat #1 count=1", chat, [(0, "started direct connection with you")])
|
||||
bob <##> cath
|
||||
|
||||
testMemberContactProhibitedContactExists :: HasCallStack => FilePath -> IO ()
|
||||
testMemberContactProhibitedContactExists =
|
||||
@@ -2782,30 +2864,25 @@ testMemberContactProhibitedRepeatInv =
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
alice ##> "/d bob"
|
||||
alice <## "bob: contact is deleted"
|
||||
bob ##> "/d alice"
|
||||
bob <## "alice: contact is deleted"
|
||||
bob ##> "/_create member contact #1 3"
|
||||
bob <## "contact for member #team cath is created"
|
||||
|
||||
alice ##> "/_create member contact #1 2"
|
||||
alice <## "contact for member #team bob is created"
|
||||
|
||||
alice ##> "/_invite member contact @4 text hi" -- cath is 3, new bob contact is 4
|
||||
alice
|
||||
<### [ "sent invitation to connect directly to member #team bob",
|
||||
WithTime "@bob hi"
|
||||
]
|
||||
alice ##> "/_invite member contact @4 text hey"
|
||||
alice <## "bad chat command: x.grp.direct.inv already sent"
|
||||
bob ##> "/_invite member contact @3 text hi"
|
||||
bob
|
||||
<### [ "#team alice is creating direct contact alice with you",
|
||||
WithTime "alice> hi"
|
||||
<### [ "sent invitation to connect directly to member #team cath",
|
||||
WithTime "@cath hi"
|
||||
]
|
||||
bob ##> "/_invite member contact @3 text hey"
|
||||
bob <## "bad chat command: x.grp.direct.inv already sent"
|
||||
cath
|
||||
<### [ "#team bob is creating direct contact bob with you",
|
||||
WithTime "bob> hi"
|
||||
]
|
||||
concurrently_
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(bob <## "cath (Catherine): contact is connected")
|
||||
(cath <## "bob (Bob): contact is connected")
|
||||
|
||||
alice <##> bob
|
||||
bob <##> cath
|
||||
|
||||
testMemberContactInvitedConnectionReplaced :: HasCallStack => FilePath -> IO ()
|
||||
testMemberContactInvitedConnectionReplaced tmp = do
|
||||
@@ -2819,7 +2896,7 @@ testMemberContactInvitedConnectionReplaced tmp = do
|
||||
|
||||
alice ##> "@#team bob hi"
|
||||
alice
|
||||
<### [ "member #team bob does not have associated contact, creating contact",
|
||||
<### [ "member #team bob does not have direct connection, creating",
|
||||
"contact for member #team bob is created",
|
||||
"sent invitation to connect directly to member #team bob",
|
||||
WithTime "@bob hi"
|
||||
@@ -2836,20 +2913,20 @@ testMemberContactInvitedConnectionReplaced tmp = do
|
||||
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "received invitation to join group team as admin"), (0, "hi"), (0, "security code changed")] <> chatFeatures)
|
||||
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
subscriptions bob
|
||||
subscriptions bob 1
|
||||
|
||||
checkConnectionsWork alice bob
|
||||
|
||||
withTestChat tmp "alice" $ \alice -> do
|
||||
subscriptions alice
|
||||
subscriptions alice 2
|
||||
|
||||
withTestChat tmp "bob" $ \bob -> do
|
||||
subscriptions bob
|
||||
subscriptions bob 1
|
||||
|
||||
checkConnectionsWork alice bob
|
||||
|
||||
withTestChat tmp "cath" $ \cath -> do
|
||||
subscriptions cath
|
||||
subscriptions cath 1
|
||||
|
||||
-- group messages work
|
||||
alice #> "#team hello"
|
||||
@@ -2865,8 +2942,9 @@ testMemberContactInvitedConnectionReplaced tmp = do
|
||||
(alice <# "#team cath> hey team")
|
||||
(bob <# "#team cath> hey team")
|
||||
where
|
||||
subscriptions cc = do
|
||||
cc <## "2 contacts connected (use /cs for the list)"
|
||||
subscriptions :: TestCC -> Int -> IO ()
|
||||
subscriptions cc n = do
|
||||
cc <## (show n <> " contacts connected (use /cs for the list)")
|
||||
cc <## "#team: connected to server(s)"
|
||||
checkConnectionsWork alice bob = do
|
||||
alice <##> bob
|
||||
@@ -2924,14 +3002,9 @@ testMemberContactIncognito =
|
||||
cath `hasContactProfiles` ["cath", "alice", T.pack bobIncognito, T.pack cathIncognito]
|
||||
|
||||
-- bob creates member contact with cath - both share incognito profile
|
||||
bob ##> ("/d " <> cathIncognito)
|
||||
bob <## (cathIncognito <> ": contact is deleted")
|
||||
cath ##> ("/d " <> bobIncognito)
|
||||
cath <## (bobIncognito <> ": contact is deleted")
|
||||
|
||||
bob ##> ("@#team " <> cathIncognito <> " hi")
|
||||
bob
|
||||
<### [ ConsoleString ("member #team " <> cathIncognito <> " does not have associated contact, creating contact"),
|
||||
<### [ ConsoleString ("member #team " <> cathIncognito <> " does not have direct connection, creating"),
|
||||
ConsoleString ("contact for member #team " <> cathIncognito <> " is created"),
|
||||
ConsoleString ("sent invitation to connect directly to member #team " <> cathIncognito),
|
||||
WithTime ("i @" <> cathIncognito <> " hi")
|
||||
@@ -2975,3 +3048,75 @@ testMemberContactIncognito =
|
||||
[ alice <# ("#team " <> cathIncognito <> "> hey"),
|
||||
bob ?<# ("#team " <> cathIncognito <> "> hey")
|
||||
]
|
||||
|
||||
testMemberContactProfileUpdate :: HasCallStack => FilePath -> IO ()
|
||||
testMemberContactProfileUpdate =
|
||||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
|
||||
bob ##> "/p rob Rob"
|
||||
bob <## "user profile is changed to rob (Rob) (your 1 contacts are notified)"
|
||||
alice <## "contact bob changed to rob (Rob)"
|
||||
alice <## "use @rob <message> to send messages"
|
||||
|
||||
cath ##> "/p kate Kate"
|
||||
cath <## "user profile is changed to kate (Kate) (your 1 contacts are notified)"
|
||||
alice <## "contact cath changed to kate (Kate)"
|
||||
alice <## "use @kate <message> to send messages"
|
||||
|
||||
alice #> "#team hello"
|
||||
bob <# "#team alice> hello"
|
||||
cath <# "#team alice> hello"
|
||||
|
||||
bob #> "#team hello too"
|
||||
alice <# "#team rob> hello too"
|
||||
cath <# "#team bob> hello too" -- not updated profile
|
||||
|
||||
cath #> "#team hello there"
|
||||
alice <# "#team kate> hello there"
|
||||
bob <# "#team cath> hello there" -- not updated profile
|
||||
|
||||
bob `send` "@cath hi"
|
||||
bob
|
||||
<### [ "member #team cath does not have direct connection, creating",
|
||||
"contact for member #team cath is created",
|
||||
"sent invitation to connect directly to member #team cath",
|
||||
WithTime "@cath hi"
|
||||
]
|
||||
cath
|
||||
<### [ "#team bob is creating direct contact bob with you",
|
||||
WithTime "bob> hi"
|
||||
]
|
||||
concurrentlyN_
|
||||
[ do
|
||||
bob <## "contact cath changed to kate (Kate)"
|
||||
bob <## "use @kate <message> to send messages"
|
||||
bob <## "kate (Kate): contact is connected",
|
||||
do
|
||||
cath <## "contact bob changed to rob (Rob)"
|
||||
cath <## "use @rob <message> to send messages"
|
||||
cath <## "rob (Rob): contact is connected"
|
||||
]
|
||||
|
||||
bob ##> "/contacts"
|
||||
bob
|
||||
<### [ "alice (Alice)",
|
||||
"kate (Kate)"
|
||||
]
|
||||
cath ##> "/contacts"
|
||||
cath
|
||||
<### [ "alice (Alice)",
|
||||
"rob (Rob)"
|
||||
]
|
||||
alice `hasContactProfiles` ["alice", "rob", "kate"]
|
||||
bob `hasContactProfiles` ["rob", "alice", "kate"]
|
||||
cath `hasContactProfiles` ["kate", "alice", "rob"]
|
||||
|
||||
bob #> "#team hello too"
|
||||
alice <# "#team rob> hello too"
|
||||
cath <# "#team rob> hello too" -- updated profile
|
||||
|
||||
cath #> "#team hello there"
|
||||
alice <# "#team kate> hello there"
|
||||
bob <# "#team kate> hello there" -- updated profile
|
||||
|
||||
+3
-1
@@ -69,7 +69,9 @@ skipComparisonForDownMigrations =
|
||||
[ -- on down migration msg_delivery_events table moves down to the end of the file
|
||||
"20230504_recreate_msg_delivery_events_cleanup_messages",
|
||||
-- on down migration idx_chat_items_timed_delete_at index moves down to the end of the file
|
||||
"20230529_indexes"
|
||||
"20230529_indexes",
|
||||
-- table and index definitions move down the file, so fields are re-created as not unique
|
||||
"20230914_member_probes"
|
||||
]
|
||||
|
||||
getSchema :: FilePath -> FilePath -> IO String
|
||||
|
||||
Reference in New Issue
Block a user