diff --git a/changelog.d/1-api-changes/delete-subconversation b/changelog.d/1-api-changes/delete-subconversation index 2f19069141..c3a53610ac 100644 --- a/changelog.d/1-api-changes/delete-subconversation +++ b/changelog.d/1-api-changes/delete-subconversation @@ -1 +1 @@ -Introduce an endpoint for deleting a subconversation (#2956, #3119) +Introduce an endpoint for deleting a subconversation (#2956, #3119, #3123) diff --git a/services/galley/test/integration/API/MLS.hs b/services/galley/test/integration/API/MLS.hs index 2feb46ca98..a47634c4d3 100644 --- a/services/galley/test/integration/API/MLS.hs +++ b/services/galley/test/integration/API/MLS.hs @@ -223,6 +223,7 @@ tests s = test s "reset a subconversation as a creator" (testDeleteSubConv SubConvMember), test s "reset a subconversation as a conversation member" (testDeleteSubConv ConvMember), test s "reset a subconversation as a random user" (testDeleteSubConv RandomUser), + test s "reset a subconversation and assert no leftover proposals" testJoinDeletedSubConvWithRemoval, test s "fail to reset a subconversation with wrong epoch" testDeleteSubConvStale, test s "leave a subconversation as a creator" (testLeaveSubConv True), test s "leave a subconversation as a non-creator" (testLeaveSubConv False), @@ -2793,6 +2794,47 @@ testDeleteSubConv deleterType = do "Old and new subconversation are not equal" (sub == newSub) +-- In this test case, Alice creates a subconversation, Bob joins and Alice +-- leaves. The leaving causes the backend to generate an external remove +-- proposal for the client by Alice. Next, Bob does not commit (simulating his +-- client crashing), and then deleting the subconversation after coming back up. +-- Then Bob creates a subconversation with the same subconversation ID and the +-- test asserts that both Alice and Bob get no events, which means the backend +-- does not resubmit the pending remove proposal for Alice's client. +testJoinDeletedSubConvWithRemoval :: TestM () +testJoinDeletedSubConvWithRemoval = do + [alice, bob] <- createAndConnectUsers [Nothing, Nothing] + runMLSTest $ do + [alice1, bob1] <- traverse createMLSClient [alice, bob] + void $ uploadNewKeyPackage bob1 + (_, qcnv) <- setupMLSGroup alice1 + void $ createAddCommit alice1 [bob] >>= sendAndConsumeCommitBundle + let subConvId = SubConvId "conference" + qsconvId <- createSubConv qcnv alice1 subConvId + void $ + createExternalCommit bob1 Nothing qsconvId + >>= sendAndConsumeCommitBundle + liftTest $ + leaveSubConv (ciUser alice1) (ciClient alice1) qcnv subConvId + !!! const 200 === statusCode + -- no committing by Bob of the backend-generated remove proposal for alice1 + -- (simulating his client crashing) + + do + sub <- + liftTest $ + responseJsonError + =<< getSubConv (qUnqualified bob) qcnv subConvId + do + void $ createSubConv qcnv bob1 subConvId + void . liftIO $ WS.assertNoEvent (3 # WS.Second) wss + testDeleteSubConvStale :: TestM () testDeleteSubConvStale = do alice <- randomQualifiedUser