From 4375a839f65a905990f67de48340d973d2660f87 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Sat, 1 Aug 2026 09:38:22 +0000 Subject: [PATCH] core: test creating a user without making it active Two tests, both driving /_create user with JSON - the path the apps actually use, which no test covered before: - keepActiveUser creates the profile while leaving the active user alone, and the prepared contact can then be reassigned to it and connected. - omitting keepActiveUser still parses and still activates. This is a regression guard: iOS does not send the field, so if the record ever stopped accepting its absence, profile creation there would break silently. --- tests/ChatTests/Profiles.hs | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/ChatTests/Profiles.hs b/tests/ChatTests/Profiles.hs index c65306474c..5810417389 100644 --- a/tests/ChatTests/Profiles.hs +++ b/tests/ChatTests/Profiles.hs @@ -153,6 +153,8 @@ shortLinkTests = do it "connect to prepared contact incognito (via address)" testShortLinkAddressConnectPreparedContactIncognito it "change prepared contact user" testShortLinkChangePreparedContactUser it "change prepared contact user, new user has contact with the same name" testShortLinkChangePreparedContactUserDuplicate + it "create user keeping active user, then change prepared contact user" testCreateUserKeepingActiveUser + it "create user without keepActiveUser activates it" testCreateUserWithoutKeepActiveUser it "connect to prepared group incognito" testShortLinkConnectPreparedGroupIncognito it "change prepared group user" testShortLinkChangePreparedGroupUser it "change prepared group user, new user has group with the same name" testShortLinkChangePreparedGroupUserDuplicate @@ -3989,6 +3991,60 @@ testShortLinkChangePreparedContactUser = testChat2 aliceProfile bobProfile test bob @@@ [] bob `hasContactProfiles` ["bob"] +-- Creating a profile to accept an invitation must not switch the active user, +-- because the prepared contact is resolved under the active user by +-- APIChangePreparedContactUser - so the profile that owns it has to stay active +-- until the reassignment is done. +testCreateUserKeepingActiveUser :: HasCallStack => TestParams -> IO () +testCreateUserKeepingActiveUser = testChat2 aliceProfile bobProfile test + where + test alice bob = do + bob ##> "/_create user {\"profile\":{\"displayName\":\"robert\",\"fullName\":\"\"},\"pastTimestamp\":false,\"keepActiveUser\":true}" + -- the response carries the created user, not the active one + showActiveUser bob "robert" + -- ... and the active user is unchanged, with no switch back needed + bob ##> "/u" + showActiveUser bob "bob (Bob)" + + alice ##> "/_connect 1" + (shortLink, fullLink) <- getInvitations alice + bob ##> ("/_connect plan 1 " <> shortLink) + bob <## "invitation link: ok to connect" + contactSLinkData <- getTermLine bob + bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData) + bob <## "alice: contact is prepared" + + -- the reassignment works because bob is still active and owns the prepared contact + bob ##> "/_set contact user @4 2" + bob <## "contact alice changed from user bob to user robert" + + bob ##> "/user robert" + showActiveUser bob "robert" + + bob ##> "/_connect contact @4 text hello" + bob + <### [ "alice: connection started", + WithTime "@alice hello" + ] + alice <# "robert> hello" + concurrently_ + (bob <## "alice (Alice): contact is connected") + (alice <## "robert: contact is connected") + + alice <##> bob + alice `hasContactProfiles` ["alice", "robert"] + +-- Regression guard: clients that do not send keepActiveUser at all (iOS, CLI) +-- must still parse and must still get the new user activated. +testCreateUserWithoutKeepActiveUser :: HasCallStack => TestParams -> IO () +testCreateUserWithoutKeepActiveUser = testChat aliceProfile test + where + test alice = do + alice ##> "/_create user {\"profile\":{\"displayName\":\"alisa\",\"fullName\":\"\"},\"pastTimestamp\":false}" + showActiveUser alice "alisa" + alice ##> "/u" + showActiveUser alice "alisa" + testShortLinkChangePreparedContactUserDuplicate :: HasCallStack => TestParams -> IO () testShortLinkChangePreparedContactUserDuplicate = testChat2 aliceProfile bobProfile test where