Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor CSV export #4293

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1-api-changes/add-columns-to-export
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The team CSV export endpoint has gained two extra columns: `last_active` and `status`. The streaming behaviour has also been improved.
1 change: 1 addition & 0 deletions integration/integration.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ library
API.GundeckInternal
API.Nginz
API.Spar
API.Stern
MLS.Util
Notifications
RunAllTests
Expand Down
26 changes: 26 additions & 0 deletions integration/test/API/BrigInternal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,29 @@ getPasswordResetCode :: (HasCallStack, MakesValue domain) => domain -> String ->
getPasswordResetCode domain email = do
req <- baseRequest domain Brig Unversioned "i/users/password-reset-code"
submit "GET" $ req & addQueryParams [("email", email)]

data PutSSOId = PutSSOId
{ scimExternalId :: Maybe String,
subject :: Maybe String,
tenant :: Maybe String
}

instance Default PutSSOId where
def =
PutSSOId
{ scimExternalId = Nothing,
subject = Nothing,
tenant = Nothing
}

putSSOId :: (HasCallStack, MakesValue user) => user -> PutSSOId -> App Response
putSSOId user args = do
uid <- objId user
req <- baseRequest user Brig Unversioned (joinHttpPath ["i", "users", uid, "sso-id"])
submit "PUT" $
req
& addJSONObject
[ "scim_external_id" .= args.scimExternalId,
"subject" .= args.subject,
"tenant" .= args.tenant
]
6 changes: 6 additions & 0 deletions integration/test/API/Galley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -727,3 +727,9 @@ getTeamNotifications user mSince =
baseRequest user Galley Versioned "teams/notifications" >>= \req ->
submit "GET"
$ addQueryParams [("since", since) | since <- maybeToList mSince] req

-- | https://staging-nginz-https.zinfra.io/v6/api/swagger-ui/#/default/get_teams__tid__members_csv
getTeamMembersCsv :: (HasCallStack, MakesValue user) => user -> String -> App Response
getTeamMembersCsv user tid = do
req <- baseRequest user Galley Versioned (joinHttpPath ["teams", tid, "members", "csv"])
submit "GET" req
8 changes: 8 additions & 0 deletions integration/test/API/Stern.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module API.Stern where

import Testlib.Prelude

getTeamActivity :: (HasCallStack, MakesValue domain) => domain -> String -> App Response
getTeamActivity domain tid =
baseRequest domain Stern Unversioned (joinHttpPath ["team-activity-info", tid])
>>= submit "GET"
35 changes: 22 additions & 13 deletions integration/test/SetupHelpers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,35 @@ createTeam :: (HasCallStack, MakesValue domain) => domain -> Int -> App (Value,
createTeam domain memberCount = do
owner <- createUser domain def {team = True} >>= getJSON 201
tid <- owner %. "team" & asString
members <- for [2 .. memberCount] $ \_ -> createTeamMember owner tid
members <- for [2 .. memberCount] $ \_ -> createTeamMember owner def
pure (owner, tid, members)

createTeamMember ::
(HasCallStack, MakesValue inviter) =>
inviter ->
String ->
App Value
createTeamMember inviter tid = createTeamMemberWithRole inviter tid "member"
data CreateTeamMember = CreateTeamMember
{ role :: String
}

createTeamMemberWithRole ::
instance Default CreateTeamMember where
def = CreateTeamMember {role = "member"}

createTeamMember ::
(HasCallStack, MakesValue inviter) =>
inviter ->
String ->
String ->
CreateTeamMember ->
App Value
createTeamMemberWithRole inviter _ role = do
createTeamMember inviter args = do
newUserEmail <- randomEmail
invitation <- postInvitation inviter (PostInvitation (Just newUserEmail) (Just role)) >>= getJSON 201
invitationCode <- getInvitationCode inviter invitation >>= getJSON 200 >>= (%. "code") & asString
invitation <-
postInvitation
inviter
def
{ email = Just newUserEmail,
role = Just args.role
}
>>= getJSON 201
invitationCode <-
(getInvitationCode inviter invitation >>= getJSON 200)
%. "code"
& asString
let body =
AddUser
{ name = Just newUserEmail,
Expand Down
26 changes: 26 additions & 0 deletions integration/test/Test/Client.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import API.Brig
import qualified API.Brig as API
import API.BrigCommon
import API.Gundeck
import API.Stern
import Control.Lens hiding ((.=))
import Control.Monad.Codensity
import Control.Monad.Reader
import Data.Aeson hiding ((.=))
import qualified Data.ByteString.Char8 as B8
import Data.ProtoLens.Labels ()
import Data.Time.Clock.POSIX
import Data.Time.Clock.System
Expand Down Expand Up @@ -42,6 +44,30 @@ testClientLastActive = do
<$> parseTimeM False defaultTimeLocale "%Y-%m-%dT%H:%M:%SZ" tm1
assertBool "last_active is earlier than expected" $ ts1 >= now

testTeamActivity :: (HasCallStack) => App ()
testTeamActivity = do
(alice, tid, [bob, charlie]) <- createTeam OwnDomain 3
[alice1, _alice2] <- replicateM 2 $ addClient alice def >>= getJSON 201
[_bob1, _bob2] <- replicateM 2 $ addClient bob def >>= getJSON 201
charlie1 <- addClient charlie def >>= getJSON 201

for_ [(alice, alice1), (charlie, charlie1)] $ \(u, cl) -> do
clientId <- cl %. "id" & asString
void $ getNotifications u def {client = Just clientId}

let row (u, t) = do
uid <- u %. "id" & asString
pure (uid, t)

expectedRows <- sort <$> traverse row [(alice, True), (bob, False), (charlie, True)]

bindResponse (getTeamActivity alice tid) $ \resp -> do
resp.status `shouldMatchInt` 200
for_ (zip (sort (B8.lines resp.body)) expectedRows) $ \(r, (uid, active)) -> do
let [actualUser, timestamp] = B8.split ',' r
B8.unpack actualUser `shouldMatch` uid
B8.null timestamp `shouldMatch` not active

testListClientsIfBackendIsOffline :: (HasCallStack) => App ()
testListClientsIfBackendIsOffline = do
resourcePool <- asks (.resourcePool)
Expand Down
2 changes: 1 addition & 1 deletion integration/test/Test/Conversation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ testDeleteTeamMemberLimitedEventFanout :: (HasCallStack) => App ()
testDeleteTeamMemberLimitedEventFanout = do
-- Alex will get removed from the team
(alice, team, [alex, alison]) <- createTeam OwnDomain 3
ana <- createTeamMemberWithRole alice team "admin"
ana <- createTeamMember alice def {role = "admin"}
[amy, bob] <- for [OwnDomain, OtherDomain] $ flip randomUser def
forM_ [amy, bob] $ connectTwoUsers alice
[aliceId, alexId, amyId, alisonId, anaId, bobId] <- do
Expand Down
12 changes: 6 additions & 6 deletions integration/test/Test/ExternalPartner.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ testExternalPartnerPermissions :: (HasCallStack) => App ()
testExternalPartnerPermissions = do
(owner, tid, u1 : u2 : u3 : _) <- createTeam OwnDomain 4

partner <- createTeamMemberWithRole owner tid "partner"
partner <- createTeamMember owner def {role = "partner"}

-- a partner should not be able to create conversation with 2 additional users or more
void $ postConversation partner (defProteus {team = Just tid, qualifiedUsers = [u1, u2]}) >>= getJSON 403
Expand Down Expand Up @@ -58,23 +58,23 @@ testExternalPartnerPermissions = do
testExternalPartnerPermissionsMls :: (HasCallStack) => App ()
testExternalPartnerPermissionsMls = do
-- external partners should not be able to create (MLS) conversations
(owner, tid, _) <- createTeam OwnDomain 2
bobExt <- createTeamMemberWithRole owner tid "partner"
(owner, _, _) <- createTeam OwnDomain 2
bobExt <- createTeamMember owner def {role = "partner"}
bobExtClient <- createMLSClient def bobExt
bindResponse (postConversation bobExtClient defMLS) $ \resp -> do
resp.status `shouldMatchInt` 403

testExternalPartnerPermissionMlsOne2One :: (HasCallStack) => App ()
testExternalPartnerPermissionMlsOne2One = do
(owner, tid, alice : _) <- createTeam OwnDomain 2
bobExternal <- createTeamMemberWithRole owner tid "partner"
(owner, _, alice : _) <- createTeam OwnDomain 2
bobExternal <- createTeamMember owner def {role = "partner"}
void $ getMLSOne2OneConversation alice bobExternal >>= getJSON 200

testExternalPartnerPermissionsConvName :: (HasCallStack) => App ()
testExternalPartnerPermissionsConvName = do
(owner, tid, u1 : _) <- createTeam OwnDomain 2

partner <- createTeamMemberWithRole owner tid "partner"
partner <- createTeamMember owner def {role = "partner"}

conv <- postConversation partner (defProteus {team = Just tid, qualifiedUsers = [u1]}) >>= getJSON 201

Expand Down
3 changes: 2 additions & 1 deletion integration/test/Test/MLS/Services.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# OPTIONS -Wno-ambiguous-fields #-}
module Test.MLS.Services where

import API.Brig
Expand All @@ -13,7 +14,7 @@ testWhitelistUpdatePermissions = do
(owner, tid, []) <- createTeam OwnDomain 1

-- Create a team admin
admin <- createTeamMemberWithRole owner tid "admin"
admin <- createTeamMember owner def {role = "admin"}

-- Create a service
email <- randomEmail
Expand Down
7 changes: 4 additions & 3 deletions integration/test/Test/Search.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# OPTIONS -Wno-ambiguous-fields #-}
module Test.Search where

import qualified API.Brig as BrigP
Expand All @@ -19,9 +20,9 @@ testSearchContactForExternalUsers = do
owner <- randomUser OwnDomain def {BrigI.team = True}
tid <- owner %. "team" & asString

partner <- createTeamMemberWithRole owner tid "partner"
tm1 <- createTeamMember owner tid
tm2 <- createTeamMember owner tid
partner <- createTeamMember owner def {role = "partner"}
tm1 <- createTeamMember owner def
tm2 <- createTeamMember owner def

-- a team member can search for contacts
bindResponse (BrigP.searchContacts tm1 (owner %. "name") OwnDomain) $ \resp ->
Expand Down
4 changes: 2 additions & 2 deletions integration/test/Test/TeamSettings.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import Testlib.Prelude
testTeamSettingsUpdate :: (HasCallStack) => App ()
testTeamSettingsUpdate = do
(ownerA, tidA, [mem]) <- createTeam OwnDomain 2
partner <- createTeamMemberWithRole ownerA tidA "partner"
partner <- createTeamMember ownerA def {role = "partner"}

bindResponse (putAppLockSettings tidA ownerA def) $ \resp -> do
resp.status `shouldMatchInt` 200
Expand All @@ -45,7 +45,7 @@ testTeamSettingsUpdate = do
testTeamPropertiesUpdate :: (HasCallStack) => App ()
testTeamPropertiesUpdate = do
(ownerA, tidA, [mem]) <- createTeam OwnDomain 2
partner <- createTeamMemberWithRole ownerA tidA "partner"
partner <- createTeamMember ownerA def {role = "partner"}

bindResponse (putTeamProperties tidA ownerA def) $ \resp -> do
resp.status `shouldMatchInt` 200
Expand Down
Loading
Loading