306 lines
9.1 KiB
TypeScript
306 lines
9.1 KiB
TypeScript
/// <reference types="cypress" />
|
|
|
|
type NotificationRecord = {
|
|
id: string;
|
|
title: string;
|
|
event_type: string;
|
|
created_at: number;
|
|
message: string;
|
|
priority: string;
|
|
type: string;
|
|
seen: boolean;
|
|
status: string;
|
|
recipient?: { full_name: string };
|
|
};
|
|
|
|
const notificationHistoryPattern = /\/api\/proxy\/notifications(?:\?|$)/;
|
|
|
|
const makeNotification = (
|
|
overrides: Partial<NotificationRecord> = {},
|
|
): NotificationRecord => ({
|
|
id: "notification-1",
|
|
title: "Tender deadline reminder",
|
|
event_type: "push",
|
|
created_at: 1_717_934_400,
|
|
message: "A watched tender is closing soon and needs your attention.",
|
|
priority: "important",
|
|
type: "warning",
|
|
seen: false,
|
|
status: "sent",
|
|
recipient: { full_name: "E2E Admin One" },
|
|
...overrides,
|
|
});
|
|
|
|
const historyResponse = (
|
|
notifications: NotificationRecord[],
|
|
options: { offset?: number; total?: number; pages?: number } = {},
|
|
) => ({
|
|
success: true,
|
|
message: "ok",
|
|
data: notifications,
|
|
meta: {
|
|
offset: options.offset ?? 0,
|
|
limit: 10,
|
|
total: options.total ?? notifications.length,
|
|
page: Math.floor((options.offset ?? 0) / 10) + 1,
|
|
pages: options.pages ?? 1,
|
|
has_more: false,
|
|
},
|
|
});
|
|
|
|
const stubHeaderNotifications = (times = 1) => {
|
|
cy.intercept(
|
|
{
|
|
method: "GET",
|
|
url: "**/api/proxy/notifications/my**",
|
|
times,
|
|
},
|
|
{
|
|
statusCode: 200,
|
|
body: historyResponse([]),
|
|
},
|
|
).as("myNotifications");
|
|
};
|
|
|
|
describe("notification history", () => {
|
|
beforeEach(() => {
|
|
cy.setAuthCookies();
|
|
stubHeaderNotifications();
|
|
});
|
|
|
|
it("renders breadcrumbs, actions, columns, API rows, and details navigation", () => {
|
|
const notification = makeNotification();
|
|
|
|
cy.intercept("GET", notificationHistoryPattern, (req) => {
|
|
expect(req.query).to.include({
|
|
sort_by: "created_at",
|
|
sort_order: "desc",
|
|
offset: "0",
|
|
limit: "10",
|
|
});
|
|
req.reply({
|
|
statusCode: 200,
|
|
body: historyResponse([notification]),
|
|
});
|
|
}).as("notificationHistory");
|
|
|
|
cy.visit("/notification-history");
|
|
cy.wait("@notificationHistory");
|
|
|
|
cy.getByCy("breadcrumb-link-dashboard").should("be.visible");
|
|
cy.getByCy("breadcrumb-current-notification-history")
|
|
.should("be.visible")
|
|
.and("contain.text", "Notification history");
|
|
cy.getByCy("list-header-create-button").should(
|
|
"contain.text",
|
|
"Create notification",
|
|
);
|
|
|
|
[
|
|
"row",
|
|
"title",
|
|
"channel",
|
|
"created at",
|
|
"receiver",
|
|
"message",
|
|
"priority",
|
|
"type",
|
|
"seen",
|
|
"status",
|
|
"actions",
|
|
].forEach((column) => {
|
|
cy.contains("th", new RegExp(`^${column}$`, "i")).should("exist");
|
|
});
|
|
|
|
cy.contains("tr", notification.title)
|
|
.should("contain.text", notification.event_type)
|
|
.and("contain.text", notification.recipient?.full_name)
|
|
.and("contain.text", notification.priority)
|
|
.and("contain.text", notification.type)
|
|
.and("contain.text", notification.status)
|
|
.within(() => {
|
|
cy.get('button[data-tooltip-id="details"]').click();
|
|
});
|
|
|
|
cy.location("pathname").should(
|
|
"eq",
|
|
`/notification-history/${notification.id}`,
|
|
);
|
|
});
|
|
|
|
it("filters by seen state and search, then resets to the default list", () => {
|
|
const defaultNotification = makeNotification({
|
|
id: "notification-default",
|
|
title: "Default notification",
|
|
});
|
|
const filteredNotification = makeNotification({
|
|
id: "notification-filtered",
|
|
title: "Filtered urgent notice",
|
|
seen: true,
|
|
});
|
|
|
|
cy.intercept("GET", notificationHistoryPattern, (req) => {
|
|
const isFiltered =
|
|
req.query.seen === "true" && req.query.search === "urgent";
|
|
req.alias = isFiltered ? "filteredNotifications" : "defaultNotifications";
|
|
req.reply({
|
|
statusCode: 200,
|
|
body: historyResponse([
|
|
isFiltered ? filteredNotification : defaultNotification,
|
|
]),
|
|
});
|
|
});
|
|
|
|
cy.visit("/notification-history");
|
|
cy.wait("@defaultNotifications");
|
|
cy.contains(defaultNotification.title).should("be.visible");
|
|
|
|
cy.getByCy("notification-history-filter-panel-toggle").click();
|
|
cy.get('select[name="seen"]').select("true", { force: true });
|
|
cy.getByCy("notification-history-filter-search-input").type("urgent");
|
|
cy.getByCy("notification-history-filter-submit-button").click();
|
|
|
|
cy.wait("@filteredNotifications");
|
|
cy.location("search")
|
|
.should("include", "seen=true")
|
|
.and("include", "search=urgent");
|
|
cy.contains(filteredNotification.title).should("be.visible");
|
|
cy.contains(defaultNotification.title).should("not.exist");
|
|
cy.contains("2 active").should("be.visible");
|
|
|
|
cy.getByCy("notification-history-filter-reset-button").click();
|
|
cy.wait("@defaultNotifications");
|
|
cy.location("search").should("eq", "");
|
|
cy.contains(defaultNotification.title).should("be.visible");
|
|
});
|
|
|
|
it("filters notification history by user when a user is selected", () => {
|
|
const currentUserNotification = makeNotification({
|
|
id: "notification-current-user",
|
|
title: "Current user notification",
|
|
});
|
|
const selectedUserNotification = makeNotification({
|
|
id: "notification-selected-user",
|
|
title: "Selected user notification",
|
|
recipient: { full_name: "Notification Admin" },
|
|
});
|
|
|
|
cy.intercept("GET", notificationHistoryPattern, {
|
|
statusCode: 200,
|
|
body: historyResponse([currentUserNotification]),
|
|
}).as("currentUserNotifications");
|
|
|
|
cy.intercept("GET", "**/api/proxy/users**", {
|
|
statusCode: 200,
|
|
body: {
|
|
success: true,
|
|
message: "ok",
|
|
data: {
|
|
users: [
|
|
{
|
|
id: "64f9b24d2f1b2f0012345678",
|
|
full_name: "Notification Admin",
|
|
username: "notification-admin",
|
|
email: "notification-admin@example.com",
|
|
role: "admin",
|
|
status: "active",
|
|
},
|
|
],
|
|
},
|
|
meta: {
|
|
offset: 0,
|
|
limit: 20,
|
|
total: 1,
|
|
page: 1,
|
|
pages: 1,
|
|
has_more: false,
|
|
},
|
|
},
|
|
}).as("users");
|
|
|
|
cy.intercept("GET", notificationHistoryPattern, (req) => {
|
|
expect(req.query.user_id).to.eq("64f9b24d2f1b2f0012345678");
|
|
req.reply({
|
|
statusCode: 200,
|
|
body: historyResponse([selectedUserNotification]),
|
|
});
|
|
}).as("selectedUserNotifications");
|
|
|
|
cy.visit("/notification-history");
|
|
cy.wait("@currentUserNotifications");
|
|
cy.contains(currentUserNotification.title).should("be.visible");
|
|
|
|
cy.getByCy("notification-history-filter-panel-toggle").click();
|
|
cy.getByCy("notification-history-filter-user-select")
|
|
.siblings("button")
|
|
.click();
|
|
cy.getByCy("notification-history-filter-user-select-search").type(
|
|
"Notification Admin",
|
|
);
|
|
cy.wait("@users");
|
|
cy.getByCy("notification-history-filter-user-select-option")
|
|
.filter('[data-value="64f9b24d2f1b2f0012345678"]')
|
|
.click();
|
|
cy.getByCy("notification-history-filter-submit-button").click();
|
|
|
|
cy.wait("@selectedUserNotifications");
|
|
cy.location("search").should(
|
|
"include",
|
|
"user_id=64f9b24d2f1b2f0012345678",
|
|
);
|
|
cy.contains(selectedUserNotification.title).should("be.visible");
|
|
cy.contains(currentUserNotification.title).should("not.exist");
|
|
});
|
|
|
|
it("shows the current user filter when notification history is opened for the current user", () => {
|
|
const notification = makeNotification({
|
|
id: "notification-current-user-filter",
|
|
title: "Current user filtered notification",
|
|
});
|
|
|
|
cy.intercept("GET", notificationHistoryPattern, (req) => {
|
|
expect(req.query.user_id).to.eq("507f1f77bcf86cd799439011");
|
|
req.reply({
|
|
statusCode: 200,
|
|
body: historyResponse([notification]),
|
|
});
|
|
}).as("currentUserFilteredNotifications");
|
|
|
|
cy.visit("/notification-history?user_id=507f1f77bcf86cd799439011");
|
|
cy.wait("@currentUserFilteredNotifications");
|
|
|
|
cy.getByCy("notification-history-filter-panel-toggle").should(
|
|
"contain.text",
|
|
"1 active",
|
|
);
|
|
cy.getByCy("notification-history-filter-panel-toggle").click();
|
|
cy.getByCy("notification-history-filter-user-select")
|
|
.siblings("button")
|
|
.should("contain.text", "E2E Admin One");
|
|
cy.contains(notification.title).should("be.visible");
|
|
});
|
|
|
|
it("shows loading and empty states, and opens the create page", () => {
|
|
cy.intercept("GET", notificationHistoryPattern, (req) => {
|
|
req.reply({
|
|
delay: 900,
|
|
statusCode: 200,
|
|
body: historyResponse([]),
|
|
});
|
|
}).as("emptyNotificationHistory");
|
|
|
|
cy.visit("/notification-history");
|
|
cy.getByCy("table-skeleton").should("be.visible");
|
|
cy.wait("@emptyNotificationHistory");
|
|
cy.getByCy("table-skeleton").should("not.exist");
|
|
cy.getByCy("empty-list-message").should(
|
|
"contain.text",
|
|
"No notifications were found",
|
|
);
|
|
|
|
cy.getByCy("list-header-create-button").click();
|
|
cy.location("pathname").should("eq", "/notification-history/create");
|
|
cy.getByCy("breadcrumb-current-create-notification").should("be.visible");
|
|
});
|
|
});
|