Skip to content

Commit

Permalink
get notifications v3
Browse files Browse the repository at this point in the history
  • Loading branch information
battermann committed Oct 20, 2022
1 parent 50f891f commit af76d6d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 29 deletions.
21 changes: 20 additions & 1 deletion libs/wire-api/src/Wire/API/Routes/Public/Gundeck.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import Wire.API.Push.V2.Token
import Wire.API.Routes.MultiVerb
import Wire.API.Routes.Named
import Wire.API.Routes.Public
import Wire.API.Routes.Version

type GundeckAPI = PushAPI :<|> NotificationAPI

Expand Down Expand Up @@ -97,8 +98,9 @@ type NotificationAPI =
(Maybe QueuedNotification)
)
:<|> Named
"get-notifications"
"get-notifications@v2"
( Summary "Fetch notifications"
:> Until 'V3
:> ZUser
:> "notifications"
:> QueryParam' [Optional, Strict, Description "Only return notifications more recent than this"] "since" RawNotificationId
Expand All @@ -112,6 +114,23 @@ type NotificationAPI =
]
GetNotificationsResponse
)
:<|> Named
"get-notifications"
( Summary "Fetch notifications"
:> From 'V3
:> ZUser
:> "notifications"
:> QueryParam' [Optional, Strict, Description "Only return notifications more recent than this"] "since" NotificationId
:> QueryParam' [Optional, Strict, Description "Only return notifications targeted at the given client"] "client" ClientId
:> QueryParam' [Optional, Strict, Description "Maximum number of notifications to return"] "size" (Range 100 10000 Int32)
:> MultiVerb
'GET
'[JSON]
'[ ErrorResponse 'E.NotificationNotFound,
Respond 200 "Notification list" QueuedNotificationList
]
(Maybe QueuedNotificationList)
)

swaggerDoc :: Swagger.Swagger
swaggerDoc = toSwagger (Proxy @GundeckAPI)
16 changes: 14 additions & 2 deletions services/gundeck/src/Gundeck/API/Public.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ servantSitemap = pushAPI :<|> notificationAPI
notificationAPI =
Named @"get-notification-by-id" getById
:<|> Named @"get-last-notification" getLastNotification
:<|> Named @"get-notifications@v2" paginateUntilV2
:<|> Named @"get-notifications" paginate

addToken :: UserId -> ConnId -> Public.PushToken -> Gundeck (Either Public.AddTokenError Public.AddTokenSuccess)
Expand Down Expand Up @@ -98,13 +99,13 @@ listTokens = Push.listTokens
--
-- (arianvp): I am not sure why it is convenient for clients to distinct
-- between these two cases.
paginate ::
paginateUntilV2 ::
UserId ->
Maybe Public.RawNotificationId ->
Maybe ClientId ->
Maybe (Range 100 10000 Int32) ->
Gundeck Public.GetNotificationsResponse
paginate uid mbSince mbClient mbSize = do
paginateUntilV2 uid mbSince mbClient mbSize = do
let size = fromMaybe (unsafeRange 1000) mbSize
Notification.PaginateResult gap page <- Notification.paginate uid (join since) mbClient size
pure $
Expand All @@ -124,6 +125,17 @@ paginate uid mbSince mbClient mbSize = do
isV1UUID :: UUID -> Maybe UUID
isV1UUID u = if UUID.version u == 1 then Just u else Nothing

paginate ::
UserId ->
Maybe Public.NotificationId ->
Maybe ClientId ->
Maybe (Range 100 10000 Int32) ->
Gundeck (Maybe Public.QueuedNotificationList)
paginate uid mbSince mbClient mbSize = do
let size = fromMaybe (unsafeRange 1000) mbSize
Notification.PaginateResult gap page <- Notification.paginate uid mbSince mbClient size
pure $ if gap then Nothing else Just page

getById :: UserId -> Public.NotificationId -> Maybe ClientId -> Gundeck (Maybe Public.QueuedNotification)
getById = Notification.getById

Expand Down
77 changes: 51 additions & 26 deletions services/gundeck/test/integration/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,12 @@ tests s =
test s "Fetch all notifications" testFetchAllNotifs,
test s "Fetch new notifications" testFetchNewNotifs,
test s "No new notifications" testNoNewNotifs,
test s "Missing notifications" testMissingNotifs,
test s "Missing notifications (until API Version 3)" testMissingNotifsV2,
test s "Missing notifications (from API Version 3)" testMissingNotifsV3,
test s "Fetch last notification" testFetchLastNotif,
test s "No last notification" testNoLastNotif,
test s "Bad 'since' parameter" testFetchNotifBadSince,
test s "Bad 'since' parameter (until API Version 3)" testFetchNotifBadSinceV2,
test s "Bad 'since' parameter (from API Version 3)" testFetchNotifBadSinceV3,
test s "Fetch notification by ID" testFetchNotifById,
test s "Filter notifications by client" testFilterNotifByClient,
test s "Paging" testNotificationPaging
Expand Down Expand Up @@ -482,7 +484,7 @@ testFetchNewNotifs = do
get
( runGundeckR gu
. zUser ally
. path "notifications"
. paths ["v3", "notifications"]
. query [("since", Just (toByteString' (ns !! 1)))]
)
!!! do
Expand All @@ -498,31 +500,40 @@ testNoNewNotifs = do
get
( runGundeckR gu
. zUser ally
. path "notifications"
. paths ["v3", "notifications"]
. query [("since", Just (toByteString' n))]
)
!!! do
const 200 === statusCode
const (Just []) === parseNotificationIds

testMissingNotifs :: TestM ()
testMissingNotifs = do
gu <- view tsGundeck
other <- randomId
sendPush (buildPush other [(other, RecipientClientsAll)] (textPayload "hello"))
(old : _) <- map (view queuedNotificationId) <$> listNotifications other Nothing
ally <- randomId
sendPush (buildPush ally [(ally, RecipientClientsAll)] (textPayload "hello"))
ns <- listNotifications ally Nothing
get
( runGundeckR gu
. zUser ally
. path "notifications"
. query [("since", Just (toByteString' old))]
)
!!! do
const 404 === statusCode
const (Just ns) === parseNotifications
testMissingNotifsV2 :: TestM ()
testMissingNotifsV2 = do
testMissingNotifs "v2" $ \ns -> do
const 404 === statusCode
const (Just ns) === parseNotifications

testMissingNotifsV3 :: TestM ()
testMissingNotifsV3 =
testMissingNotifs "v2" $ const $ const 404 === statusCode

testMissingNotifs :: ByteString -> ([QueuedNotification] -> Assertions ()) -> TestM ()
testMissingNotifs version checks =
do
gu <- view tsGundeck
other <- randomId
sendPush (buildPush other [(other, RecipientClientsAll)] (textPayload "hello"))
(old : _) <- map (view queuedNotificationId) <$> listNotifications other Nothing
ally <- randomId
sendPush (buildPush ally [(ally, RecipientClientsAll)] (textPayload "hello"))
ns <- listNotifications ally Nothing
get
( runGundeckR gu
. zUser ally
. paths [version, "notifications"]
. query [("since", Just (toByteString' old))]
)
!!! checks ns

testFetchLastNotif :: TestM ()
testFetchLastNotif = do
Expand All @@ -543,8 +554,22 @@ testNoLastNotif = do
const 404 === statusCode
const (Just "not-found") =~= responseBody

testFetchNotifBadSince :: TestM ()
testFetchNotifBadSince = do
testFetchNotifBadSinceV3 :: TestM ()
testFetchNotifBadSinceV3 = do
gu <- view tsGundeck
ally <- randomId
sendPush (buildPush ally [(ally, RecipientClientsAll)] (textPayload "first"))
get
( runGundeckR gu
. zUser ally
. paths ["v3", "notifications"]
. query [("since", Just "jumberjack")]
)
!!! do
const 400 === statusCode

testFetchNotifBadSinceV2 :: TestM ()
testFetchNotifBadSinceV2 = do
gu <- view tsGundeck
ally <- randomId
sendPush (buildPush ally [(ally, RecipientClientsAll)] (textPayload "first"))
Expand Down Expand Up @@ -712,7 +737,7 @@ testNotificationPaging = do
maybe id (queryItem "client" . toByteString') c
. maybe id (queryItem "since" . toByteString') start
. queryItem "size" (toByteString' step)
r <- get (runGundeckR gu . path "/notifications" . zUser u . range) <!! const 200 === statusCode
r <- get (runGundeckR gu . paths ["v3", "notifications"] . zUser u . range) <!! const 200 === statusCode
let rs = decode =<< responseBody r
let (ns, more) = (fmap (view queuedNotifications) &&& fmap (view queuedHasMore)) rs
let count' = count + step
Expand Down Expand Up @@ -1093,7 +1118,7 @@ getNotifications u c =
get $
runGundeckR gu
. zUser u
. path "notifications"
. paths ["v3", "notifications"]
. maybe id (queryItem "client" . toByteString') c

getLastNotification :: UserId -> Maybe ClientId -> TestM (Response (Maybe BL.ByteString))
Expand Down

0 comments on commit af76d6d

Please sign in to comment.