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

feat: add detour deactivated notifications #2837

Merged
merged 10 commits into from
Oct 8, 2024
13 changes: 12 additions & 1 deletion assets/src/components/notificationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
BlockWaiverReason,
NotificationType,
isBlockWaiverNotification,
DetourNotificationStatus,
} from "../realtime"
import { Route } from "../schedule"
import { formattedTime } from "../util/dateTime"
Expand Down Expand Up @@ -99,7 +100,17 @@ export const title = (notification: Notification) => {
}

case NotificationType.Detour: {
return "Detour - Active"
switch (notification.content.status) {
case DetourNotificationStatus.Activated: {
return "Detour - Active"
}
case DetourNotificationStatus.Deactivated: {
return "Detour - Closed"
}
}
// Typescript says this is unreachable,
// but eslint doesn't seem to get the memo
break
}

case NotificationType.BridgeMovement: {
Expand Down
6 changes: 6 additions & 0 deletions assets/src/models/notificationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import {
BlockWaiverNotification,
BridgeNotification,
DetourNotificationStatus,
Notification,
NotificationContentTypes,
NotificationType,
Expand Down Expand Up @@ -68,6 +69,10 @@ export const BridgeNotificationData = union([

export const DetourNotificationData = type({
__struct__: literal(NotificationType.Detour),
status: enums([
DetourNotificationStatus.Activated,
DetourNotificationStatus.Deactivated,
]),
detour_id: detourId,
headsign: string(),
route: string(),
Expand Down Expand Up @@ -136,6 +141,7 @@ export const notificationFromData = (
case NotificationType.Detour: {
content = {
$type: NotificationType.Detour,
status: notificationData.content.status,
detourId: notificationData.content.detour_id,
direction: notificationData.content.direction,
headsign: notificationData.content.headsign,
Expand Down
6 changes: 6 additions & 0 deletions assets/src/realtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,14 @@ export type BlockWaiverNotification = {
endTime: Date | null
}

export enum DetourNotificationStatus {
Activated = "activated",
Deactivated = "deactivated",
}

export type DetourNotification = {
$type: NotificationType.Detour
status: DetourNotificationStatus
detourId: DetourId
headsign: string
route: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`NotificationBellIcon activated detour notification renders when there are new detour notifications and user is not part of DetoursList 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--read"
>
<svg />
</span>
</div>
</body>
`;

exports[`NotificationBellIcon activated detour notification renders when there are new detour notifications and user is part of DetoursList group 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--unread"
>
<svg />
</span>
</div>
</body>
`;

exports[`NotificationBellIcon deactivated detour notification renders when there are new detour notifications and user is not part of DetoursList 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--read"
>
<svg />
</span>
</div>
</body>
`;

exports[`NotificationBellIcon deactivated detour notification renders when there are new detour notifications and user is part of DetoursList group 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--unread"
>
<svg />
</span>
</div>
</body>
`;

exports[`NotificationBellIcon renders when the drawer is closed and there are new notifications 1`] = `
<span
className="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--unread"
Expand Down Expand Up @@ -43,27 +91,3 @@ exports[`NotificationBellIcon renders when the drawer is open and there are not
}
/>
`;

exports[`NotificationBellIcon renders when there are new detour notifications and user is not part of DetoursList 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--read"
>
<svg />
</span>
</div>
</body>
`;

exports[`NotificationBellIcon renders when there are new detour notifications and user is part of DetoursList group 1`] = `
<body>
<div>
<span
class="c-notification-bell-icon c-notification-bell-icon--closed c-notification-bell-icon--unread"
>
<svg />
</span>
</div>
</body>
`;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`NotificationCard renders detour notification if user is in DetoursList group 1`] = `
exports[`NotificationCard renders activated detour notification if user is in DetoursList group 1`] = `
<body>
<div>
<div
Expand Down Expand Up @@ -43,19 +43,92 @@ exports[`NotificationCard renders detour notification if user is in DetoursList
<div
class="c-route-pill c-route-pill--bus"
>
2
4
</div>
<div>
<div
class="fw-semibold"
>
Headsign 2
Headsign 4
</div>
<div
class="fw-normal text-body-secondary"
>
From
Origin station 2
Origin station 4
</div>
<div
class="fw-normal"
>
Outbound
</div>
</div>
</div>
</div>
</div>
</div>
</button>
</div>
</div>
</body>
`;

exports[`NotificationCard renders detour deactivated notification if user is in DetoursList group 1`] = `
<body>
<div>
<div
aria-labelledby="card-label-:ri:"
class="c-card c-card--kiwi"
>
<button
class="c-card__left"
>
<div
class="c-card__left-content"
>
<div
class="c-card__top-row"
>
<div
class="c-card__title"
id="card-label-:ri:"
>
<span>
<svg />
</span>
Detour - Closed
</div>
<div
class="c-card__time"
>
0 min
</div>
</div>
<div
class="c-card__contents"
>
<div
class="c-card__body"
>
<div
class="d-flex flex-row gap-2"
>
<div
class="c-route-pill c-route-pill--bus"
>
1
</div>
<div>
<div
class="fw-semibold"
>
Headsign 1
</div>
<div
class="fw-normal text-body-secondary"
>
From
Origin station 1
</div>
<div
class="fw-normal"
Expand Down
66 changes: 45 additions & 21 deletions assets/tests/components/notificationBellIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { viewFactory } from "../factories/pagePanelStateFactory"
import {
blockWaiverNotificationFactory,
detourActivatedNotificationFactory,
detourDeactivatedNotificationFactory,
} from "../factories/notification"
import getTestGroups from "../../src/userTestGroups"
import { TestGroups } from "../../src/userInTestGroup"
Expand Down Expand Up @@ -142,28 +143,51 @@ describe("NotificationBellIcon", () => {
expect(tree).toMatchSnapshot()
})

test("renders when there are new detour notifications and user is part of DetoursList group", () => {
jest.mocked(getTestGroups).mockReturnValue([TestGroups.DetoursList])

const { baseElement } = render(
<StateDispatchProvider state={stateFactory.build()} dispatch={jest.fn()}>
<NotificationsContext.Provider value={unreadDetourNotificationState}>
<NotificationBellIcon />
</NotificationsContext.Provider>
</StateDispatchProvider>
)
describe.each([
{
type: "activated",
state: {
...unreadNotificationState,
notifications: detourActivatedNotificationFactory.buildList(2),
},
},
{
type: "deactivated",
state: {
...unreadNotificationState,
notifications: detourDeactivatedNotificationFactory.buildList(2),
},
},
])("$type detour notification", () => {
test("renders when there are new detour notifications and user is part of DetoursList group", () => {
jest.mocked(getTestGroups).mockReturnValue([TestGroups.DetoursList])

const { baseElement } = render(
<StateDispatchProvider
state={stateFactory.build()}
dispatch={jest.fn()}
>
<NotificationsContext.Provider value={unreadDetourNotificationState}>
<NotificationBellIcon />
</NotificationsContext.Provider>
</StateDispatchProvider>
)

expect(baseElement).toMatchSnapshot()
})
expect(baseElement).toMatchSnapshot()
})

test("renders when there are new detour notifications and user is not part of DetoursList", () => {
const { baseElement } = render(
<StateDispatchProvider state={stateFactory.build()} dispatch={jest.fn()}>
<NotificationsContext.Provider value={unreadDetourNotificationState}>
<NotificationBellIcon />
</NotificationsContext.Provider>
</StateDispatchProvider>
)
expect(baseElement).toMatchSnapshot()
test("renders when there are new detour notifications and user is not part of DetoursList", () => {
const { baseElement } = render(
<StateDispatchProvider
state={stateFactory.build()}
dispatch={jest.fn()}
>
<NotificationsContext.Provider value={unreadDetourNotificationState}>
<NotificationBellIcon />
</NotificationsContext.Provider>
</StateDispatchProvider>
)
expect(baseElement).toMatchSnapshot()
})
})
})
Loading
Loading