{-# OPTIONS_GHC -Wno-ambiguous-fields #-}
module Test.TeamCollaborators where
import qualified API.Brig as BrigP
import qualified API.BrigInternal as BrigI
import API.Common (randomName)
import API.Galley
import qualified API.GalleyInternal as Internal
import Data.Tuple.Extra
import Notifications (isConvLeaveNotif, isTeamCollaboratorAddedNotif, isTeamCollaboratorRemovedNotif, isTeamMemberLeaveNotif)
import SetupHelpers
import Testlib.Prelude
testCreateTeamCollaborator :: (HasCallStack) => App ()
testCreateTeamCollaborator :: HasCallStack => App ()
testCreateTeamCollaborator = do
(owner, team, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
user <- randomUser OwnDomain def
(_, userId) <- objQid user
withWebSockets [owner, alice] $ \[WebSocket
wsOwner, WebSocket
wsAlice] -> do
Value -> String -> Value -> [String] -> App Response
forall owner collaborator.
(MakesValue owner, MakesValue collaborator, HasCallStack) =>
owner -> String -> collaborator -> [String] -> App Response
addTeamCollaborator
Value
owner
String
team
Value
user
[ String
"create_team_conversation",
String
"implicit_connection"
]
App Response -> (Response -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack => Response -> App ()
Response -> App ()
assertSuccess
let checkEvent :: (MakesValue a) => a -> App ()
checkEvent :: forall a. MakesValue a => a -> App ()
checkEvent a
evt = do
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.data.permissions" App Value -> [String] -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` [String
"create_team_conversation", String
"implicit_connection"]
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.data.user" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
userId
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.team" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
team
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"transient" App Value -> Bool -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` Bool
False
HasCallStack => (Value -> App Bool) -> WebSocket -> App Value
(Value -> App Bool) -> WebSocket -> App Value
awaitMatch Value -> App Bool
forall a. (HasCallStack, MakesValue a) => a -> App Bool
isTeamCollaboratorAddedNotif WebSocket
wsOwner App Value -> (Value -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App ()
forall a. MakesValue a => a -> App ()
checkEvent
HasCallStack => Int -> WebSocket -> App ()
Int -> WebSocket -> App ()
assertNoEvent Int
1 WebSocket
wsAlice
bindResponse (getAllTeamCollaborators owner team) $ \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
res <- (Response
resp.json Maybe Value -> (Maybe Value -> App [Value]) -> App [Value]
forall a b. a -> (a -> b) -> b
& Maybe Value -> App [Value]
forall a. (HasCallStack, MakesValue a) => a -> App [Value]
asList) App [Value] -> ([Value] -> App Value) -> App (App Value)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> [Value] -> App Value
forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a
assertOne
res %. "user" `shouldMatch` userId
res %. "team" `shouldMatch` team
res %. "permissions" `shouldMatch` ["create_team_conversation", "implicit_connection"]
testTeamCollaboratorEndpointsForbiddenForOtherTeams :: (HasCallStack) => App ()
testTeamCollaboratorEndpointsForbiddenForOtherTeams :: HasCallStack => App ()
testTeamCollaboratorEndpointsForbiddenForOtherTeams = do
(owner, _team, _members) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
(_owner2, team2, _members2) <- createTeam OwnDomain 0
user <- randomUser OwnDomain def
addTeamCollaborator
owner
team2
user
[ "create_team_conversation",
"implicit_connection"
]
>>= assertStatus 403
getAllTeamCollaborators owner team2 >>= assertStatus 403
testCreateTeamCollaboratorPostTwice :: (HasCallStack) => App ()
testCreateTeamCollaboratorPostTwice :: HasCallStack => App ()
testCreateTeamCollaboratorPostTwice = do
(owner, team, _members) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
user <- randomUser OwnDomain def
let add =
Value -> String -> Value -> [String] -> App Response
forall owner collaborator.
(MakesValue owner, MakesValue collaborator, HasCallStack) =>
owner -> String -> collaborator -> [String] -> App Response
addTeamCollaborator
Value
owner
String
team
Value
user
[ String
"create_team_conversation",
String
"implicit_connection"
]
bindResponse add assertSuccess
bindResponse add $ assertStatus 409
testCollaboratorCanCreateTeamConv :: (HasCallStack) => TaggedBool "collaborator-has-team" -> App ()
testCollaboratorCanCreateTeamConv :: HasCallStack => TaggedBool "collaborator-has-team" -> App ()
testCollaboratorCanCreateTeamConv (TaggedBool Bool
collaboratorHasTeam) = do
(owner, team, _) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
1
(_, nonCollaboratingTeam, _) <- createTeam OwnDomain 1
collaborator <-
if collaboratorHasTeam
then head . thd3 <$> createTeam OwnDomain 2
else randomUser OwnDomain def
addTeamCollaborator owner team collaborator ["create_team_conversation"]
>>= assertSuccess
postConversation collaborator (defMLS {team = Just nonCollaboratingTeam}) `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
403
Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"label" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
"no-team-member"
postConversation collaborator (defMLS {team = Just team}) `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
201
Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"team" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
team
testImplicitConnectionAllowed :: (HasCallStack) => App ()
testImplicitConnectionAllowed :: HasCallStack => App ()
testImplicitConnectionAllowed = do
(owner, team, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
bob <- randomUser OwnDomain def
addTeamCollaborator
owner
team
bob
["implicit_connection"]
>>= assertSuccess
postOne2OneConversation bob alice team "chit-chat" >>= assertSuccess
getMLSOne2OneConversation bob alice >>= assertSuccess
postOne2OneConversation alice bob team "chat-chit" >>= assertSuccess
getMLSOne2OneConversation alice bob >>= assertSuccess
testImplicitConnectionNotConfigured :: (HasCallStack) => App ()
testImplicitConnectionNotConfigured :: HasCallStack => App ()
testImplicitConnectionNotConfigured = do
(owner, team, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
bob <- randomUser OwnDomain def
addTeamCollaborator
owner
team
bob
[]
>>= assertSuccess
postOne2OneConversation bob alice team "chit-chat" >>= assertLabel 403 "operation-denied"
postOne2OneConversation alice bob team "chat-chit" >>= assertSuccess
getMLSOne2OneConversation alice bob >>= assertSuccess
testImplicitConnectionNoCollaborator :: (HasCallStack) => App ()
testImplicitConnectionNoCollaborator :: HasCallStack => App ()
testImplicitConnectionNoCollaborator = do
(_owner0, team0, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
(owner1, team1, _users1) <- createTeam OwnDomain 2
bob <- randomUser OwnDomain def
addTeamCollaborator
owner1
team1
bob
["implicit_connection"]
>>= assertSuccess
postOne2OneConversation bob alice team0 "chit-chat" >>= assertLabel 403 "no-team-member"
testRemoveCollaboratorInTeamsO2O :: (HasCallStack) => App ()
testRemoveCollaboratorInTeamsO2O :: HasCallStack => App ()
testRemoveCollaboratorInTeamsO2O = do
(owner0, team0, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
(owner1, team1, [bob]) <- createTeam OwnDomain 2
charlie <- randomUser OwnDomain def
addTeamCollaborator owner0 team0 charlie ["implicit_connection"] >>= assertSuccess
addTeamCollaborator owner1 team1 charlie ["implicit_connection"] >>= assertSuccess
convId <-
postOne2OneConversation charlie alice team0 "chit-chat" `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
201
Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"qualified_id"
postOne2OneConversation charlie bob team1 "chit-chat" >>= assertSuccess
Internal.getConversation convId >>= assertSuccess
removeTeamCollaborator owner0 team0 charlie >>= assertSuccess
getMLSOne2OneConversation charlie alice >>= assertLabel 403 "not-connected"
postOne2OneConversation charlie alice team0 "chit-chat" >>= assertLabel 403 "no-team-member"
Internal.getConversation convId >>= assertLabel 404 "no-conversation"
getMLSOne2OneConversation charlie bob >>= assertSuccess
testRemoveCollaboratorInO2OConnected :: (HasCallStack) => App ()
testRemoveCollaboratorInO2OConnected :: HasCallStack => App ()
testRemoveCollaboratorInO2OConnected = do
(owner0, team0, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
bob <- randomUser OwnDomain def
connectTwoUsers alice bob
addTeamCollaborator owner0 team0 bob ["implicit_connection"] >>= assertSuccess
postOne2OneConversation bob alice team0 "chit-chat" >>= assertSuccess
removeTeamCollaborator owner0 team0 bob >>= assertSuccess
getMLSOne2OneConversation bob alice >>= assertSuccess
testRemoveCollaboratorInO2O :: (HasCallStack) => App ()
testRemoveCollaboratorInO2O :: HasCallStack => App ()
testRemoveCollaboratorInO2O = do
(owner0, team0, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
bob <- randomUser OwnDomain def
addTeamCollaborator owner0 team0 bob ["implicit_connection"] >>= assertSuccess
teamConvId <-
postOne2OneConversation bob alice team0 "chit-chat" `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
201
Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"qualified_id"
Internal.getConversation teamConvId >>= assertSuccess
connectTwoUsers alice bob
personalConvId <- postConversation alice defProteus {qualifiedUsers = [bob]} >>= getJSON 201
Internal.getConversation personalConvId >>= assertSuccess
removeTeamCollaborator owner0 team0 bob >>= assertSuccess
postOne2OneConversation bob alice team0 "chit-chat" >>= assertLabel 403 "no-team-member"
Internal.getConversation teamConvId >>= assertLabel 404 "no-conversation"
getMLSOne2OneConversation bob alice >>= assertSuccess
Internal.getConversation personalConvId >>= assertSuccess
testRemoveCollaboratorInTeamConversation :: (HasCallStack) => App ()
testRemoveCollaboratorInTeamConversation :: HasCallStack => App ()
testRemoveCollaboratorInTeamConversation = do
(owner, team, [alice, bob]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
3
conv <-
postConversation
owner
defProteus {team = Just team, qualifiedUsers = [alice, bob]}
>>= getJSON 201
withWebSockets [owner, alice, bob] $ \[WebSocket
wsOwner, WebSocket
wsAlice, WebSocket
wsBob] -> do
Value -> String -> Value -> App Response
forall owner collaborator.
(MakesValue owner, MakesValue collaborator, HasCallStack) =>
owner -> String -> collaborator -> App Response
removeTeamCollaborator Value
owner String
team Value
bob App Response -> (Response -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack => Response -> App ()
Response -> App ()
assertSuccess
bobId <- Value
bob Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"qualified_id"
bobUnqualifiedId <- bobId %. "id"
let checkLeaveEvent :: (MakesValue a, HasCallStack) => a -> App ()
checkLeaveEvent a
evt = do
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.data.user" App Value -> Value -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` Value
bobUnqualifiedId
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.team" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
team
checkRemoveEvent :: (MakesValue a, HasCallStack) => a -> App ()
checkRemoveEvent a
evt = do
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.data.user" App Value -> Value -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` Value
bobUnqualifiedId
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.team" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
team
checkConvLeaveEvent :: (MakesValue a, HasCallStack) => a -> App ()
checkConvLeaveEvent a
evt = do
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.data.qualified_user_ids" App Value -> [Value] -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` [Value
bobId]
a
evt a -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"payload.0.team" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
team
awaitMatch isTeamMemberLeaveNotif wsOwner >>= checkLeaveEvent
awaitMatch isTeamMemberLeaveNotif wsAlice >>= checkRemoveEvent
awaitMatch isTeamMemberLeaveNotif wsBob >>= checkLeaveEvent
awaitMatch isTeamCollaboratorRemovedNotif wsOwner >>= checkRemoveEvent
awaitMatch isConvLeaveNotif wsAlice >>= checkConvLeaveEvent
getConversation alice conv `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
otherMember <- [Value] -> App Value
forall (t :: * -> *) a. (HasCallStack, Foldable t) => t a -> App a
assertOne ([Value] -> App Value) -> App [Value] -> App Value
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< App Value -> App [Value]
forall a. (HasCallStack, MakesValue a) => a -> App [Value]
asList (Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"members.others")
otherMember %. "qualified_id" `shouldNotMatch` (bob %. "qualified_id")
getConversation bob conv `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
403
Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"label" App Value -> String -> App ()
forall a b.
(MakesValue a, MakesValue b, HasCallStack) =>
a -> b -> App ()
`shouldMatch` String
"access-denied"
Internal.getConversation conv `bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
otherMembers <- App Value -> App [Value]
forall a. (HasCallStack, MakesValue a) => a -> App [Value]
asList (Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"members.others")
traverse (%. "qualified_id") otherMembers `shouldMatchSet` traverse (%. "qualified_id") [owner, alice]
testUpdateCollaborator :: (HasCallStack) => App ()
testUpdateCollaborator :: HasCallStack => App ()
testUpdateCollaborator = do
(owner, team, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
bob <- randomUser OwnDomain def
addTeamCollaborator
owner
team
bob
["implicit_connection"]
>>= assertSuccess
postOne2OneConversation bob alice team "chit-chat" >>= assertSuccess
updateTeamCollaborator
owner
team
bob
["create_team_conversation", "implicit_connection"]
>>= assertSuccess
postOne2OneConversation bob alice team "chit-chat" >>= assertSuccess
updateTeamCollaborator
owner
team
bob
[]
>>= assertSuccess
postOne2OneConversation bob alice team "chit-chat" >>= assertLabel 403 "operation-denied"
testSearchFindsCollaborator :: (HasCallStack) => App ()
testSearchFindsCollaborator :: HasCallStack => App ()
testSearchFindsCollaborator = do
(owner, team, [alice]) <- Domain -> Int -> App (Value, String, [Value])
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> Int -> App (Value, String, [Value])
createTeam Domain
OwnDomain Int
2
(otherOwner, otherTeam, [bob, collab1]) <- createTeam OwnDomain 3
collab2 :: Value <- randomUser OwnDomain def
collab3 :: Value <-
BrigP.createApp otherOwner otherTeam def
`bindResponse` \Response
resp -> Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"user"
collab1Name <- collab1 %. "name" & asString
collab2Name <- collab2 %. "name" & asString
collab3Name <- collab3 %. "name" & asString
collab1Name' <- randomName
collab2Name' <- randomName
collab3Name' <- randomName
let assertFinds ::
(HasCallStack, MakesValue expectFound, MakesValue searcher) =>
String ->
expectFound ->
searcher ->
App ()
assertFinds String
searchTerm expectFound
expectFound searcher
searcher = do
Domain -> App ()
forall domain.
(HasCallStack, MakesValue domain) =>
domain -> App ()
BrigI.refreshIndex Domain
OwnDomain
searcher -> String -> Domain -> App Response
forall user searchTerm domain.
(MakesValue user, MakesValue searchTerm, MakesValue domain) =>
user -> searchTerm -> domain -> App Response
BrigP.searchContacts searcher
searcher String
searchTerm Domain
OwnDomain App Response -> (Response -> App ()) -> App ()
forall a.
HasCallStack =>
App Response -> (Response -> App a) -> App a
`bindResponse` \Response
resp -> do
Response
resp.status Int -> Int -> App ()
forall a. (MakesValue a, HasCallStack) => a -> Int -> App ()
`shouldMatchInt` Int
200
foundIds :: [String] <- Response
resp.json Maybe Value -> String -> App Value
forall a. (HasCallStack, MakesValue a) => a -> String -> App Value
%. String
"documents" App Value -> (Value -> App [Value]) -> App [Value]
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> App [Value]
forall a. (HasCallStack, MakesValue a) => a -> App [Value]
asList App [Value] -> ([Value] -> App [String]) -> App [String]
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Value -> App String) -> [Value] -> App [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Value -> App String
forall a. (HasCallStack, MakesValue a) => a -> App String
objId
expectedIds :: [String] <- (make >=> asList >=> mapM objId) expectFound
assertBool
("found: " <> show foundIds <> "; expected: " <> show expectedIds)
(sort foundIds == sort expectedIds)
for_ [owner, alice] $ assertFinds collab1Name ([] @Value)
for_ [otherOwner, bob] $ assertFinds collab1Name [collab1]
for_ [owner, alice] $ assertFinds collab2Name [collab2]
for_ [otherOwner, bob] $ assertFinds collab2Name [collab2]
for_ [owner, alice] $ assertFinds collab3Name ([] @Value)
for_ [otherOwner, bob] $ assertFinds collab3Name [collab3]
for_ [collab1, collab2, collab3]
$ \Value
collab ->
Value -> String -> Value -> [String] -> App Response
forall owner collaborator.
(MakesValue owner, MakesValue collaborator, HasCallStack) =>
owner -> String -> collaborator -> [String] -> App Response
addTeamCollaborator Value
owner String
team Value
collab [String
"implicit_connection"] App Response -> (Response -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack => Response -> App ()
Response -> App ()
assertSuccess
for_ [owner, alice] $ assertFinds collab1Name [collab1]
for_ [otherOwner, bob] $ assertFinds collab1Name [collab1]
for_ [owner, alice] $ assertFinds collab2Name [collab2]
for_ [otherOwner, bob] $ assertFinds collab2Name [collab2]
for_ [owner, alice] $ assertFinds collab3Name [collab3]
for_ [otherOwner, bob] $ assertFinds collab3Name [collab3]
for_ [(collab1, collab1Name'), (collab2, collab2Name'), (collab3, collab3Name')]
$ \(Value
collab, String
newName) -> do
let updateBody :: PutSelf
updateBody = (PutSelf
forall a. Default a => a
def :: BrigP.PutSelf) {BrigP.name = Just newName}
in Value -> PutSelf -> App Response
forall caller.
(HasCallStack, MakesValue caller) =>
caller -> PutSelf -> App Response
BrigP.putSelf Value
collab PutSelf
updateBody App Response -> (Response -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack => Response -> App ()
Response -> App ()
assertSuccess
for_ [owner, alice] $ assertFinds collab1Name' [collab1]
for_ [otherOwner, bob] $ assertFinds collab1Name' [collab1]
for_ [owner, alice] $ assertFinds collab2Name' [collab2]
for_ [otherOwner, bob] $ assertFinds collab2Name' [collab2]
for_ [owner, alice] $ assertFinds collab3Name' [collab3]
for_ [otherOwner, bob] $ assertFinds collab3Name' [collab3]
for_ [collab1, collab2, collab3]
$ \Value
collab -> do
Value -> String -> Value -> App Response
forall owner collaborator.
(MakesValue owner, MakesValue collaborator, HasCallStack) =>
owner -> String -> collaborator -> App Response
removeTeamCollaborator Value
owner String
team Value
collab App Response -> (Response -> App ()) -> App ()
forall a b. App a -> (a -> App b) -> App b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= HasCallStack => Response -> App ()
Response -> App ()
assertSuccess
for_ [owner, alice] $ assertFinds collab1Name' ([] @Value)
for_ [otherOwner, bob] $ assertFinds collab1Name' [collab1]
for_ [owner, alice] $ assertFinds collab2Name' [collab2]
for_ [otherOwner, bob] $ assertFinds collab2Name' [collab2]
for_ [owner, alice] $ assertFinds collab3Name' ([] @Value)
for_ [otherOwner, bob] $ assertFinds collab3Name' [collab3]
(_thirdOwner, _thirdTeam, [multiCollab]) <- createTeam OwnDomain 2
multiCollabName <- multiCollab %. "name" & asString
addTeamCollaborator owner team multiCollab ["implicit_connection"] >>= assertSuccess
addTeamCollaborator otherOwner otherTeam multiCollab ["implicit_connection"] >>= assertSuccess
for_ [owner, alice] $ assertFinds multiCollabName [multiCollab]
for_ [otherOwner, bob] $ assertFinds multiCollabName [multiCollab]