Files
tm_panel/cypress/e2e/notifications/create-notification.cy.ts
T
AmirReza Jamali 169708e49d
continuous-integration/drone/push Build is passing
fix(companies): align optional numeric fields with API validation
Make employee_count, annual_revenue, and founded_year truly optional in
the create company form and payload. Add field validation docs and
Cypress e2e coverage for dashboard and notifications.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 11:47:45 +03:30

167 lines
5.2 KiB
TypeScript

/// <reference types="cypress" />
const emptyHistoryResponse = {
success: true,
message: "ok",
data: [],
meta: {
offset: 0,
limit: 10,
total: 0,
page: 1,
pages: 1,
has_more: false,
},
};
const stubNotificationReads = () => {
cy.intercept("GET", "**/api/proxy/notifications/my**", {
statusCode: 200,
body: emptyHistoryResponse,
});
cy.intercept("GET", /\/api\/proxy\/notifications(?:\?|$)/, {
statusCode: 200,
body: emptyHistoryResponse,
}).as("notificationHistory");
};
const chooseMultiSelectOption = (label: string, option: string) => {
cy.contains("label", new RegExp(`^${label}`, "i"))
.parent()
.find('div[tabindex="0"]')
.click();
cy.contains(
"div[class*='cursor-pointer']",
new RegExp(`^${option}$`),
).click();
};
describe("create notification", () => {
beforeEach(() => {
cy.setAuthCookies();
stubNotificationReads();
});
it("renders breadcrumbs and validates required fields and an invalid link", () => {
cy.visit("/notification-history/create");
cy.getByCy("breadcrumb-link-dashboard").should("be.visible");
cy.getByCy("breadcrumb-link-notifications").should(
"have.attr",
"href",
"/notification-history",
);
cy.getByCy("breadcrumb-current-create-notification")
.should("be.visible")
.and("contain.text", "Create Notification");
cy.get('textarea[name="description"]').type(
"Description entered so custom validation can run.",
);
cy.getByCy("admin-form-submit-button").click();
cy.get("p")
.filter(
(_index, element) =>
element.textContent?.trim() === "This field is required",
)
.should("have.length", 4);
cy.get('input[name="link"]').type("not-a-valid-url");
cy.get('input[name="title"]').type("Validation test");
cy.get('select[name="target"]').select("all_users", { force: true });
cy.get('select[name="priority"]').select("medium", { force: true });
cy.get('select[name="type"]').select("info", { force: true });
cy.get('textarea[name="description"]')
.clear()
.type("A valid notification message.");
cy.getByCy("admin-form-submit-button").click();
cy.contains("This field does not match the required pattern").should(
"be.visible",
);
});
it("loads role recipients and submits the expected notification payload", () => {
cy.intercept("POST", "**/api/proxy/notifications", (req) => {
expect(req.body).to.deep.equal({
title: "Planned maintenance",
target: "specific_role",
recipient: ["admin"],
channels: ["email", "push"],
link: "https://example.com/maintenance",
priority: "important",
type: "warning",
description: "The platform will be unavailable during maintenance.",
schedule_at: 0,
});
req.reply({
statusCode: 201,
body: {
success: true,
message: "Notification created successfully",
data: {},
},
});
}).as("createNotification");
cy.visit("/notification-history");
cy.wait("@notificationHistory");
cy.getByCy("list-header-create-button").click();
cy.location("pathname").should("eq", "/notification-history/create");
cy.get('input[name="title"]').type("Planned maintenance");
cy.get('select[name="target"]').select("specific_role", { force: true });
chooseMultiSelectOption("recipient", "Admin");
chooseMultiSelectOption("channels", "Email");
chooseMultiSelectOption("channels", "Push");
cy.get('input[name="link"]').type("https://example.com/maintenance");
cy.get('select[name="priority"]').select("important", { force: true });
cy.get('select[name="type"]').select("warning", { force: true });
cy.get('textarea[name="description"]').type(
"The platform will be unavailable during maintenance.",
);
cy.getByCy("admin-form-submit-button").click();
cy.wait("@createNotification");
cy.location("pathname").should("eq", "/notification-history");
cy.contains("Notification created successfully").should("be.visible");
});
it("loads specific users from the API and clears recipients when target changes", () => {
cy.intercept("GET", "**/api/proxy/users**", (req) => {
expect(req.query.offset).to.eq("0");
req.reply({
statusCode: 200,
body: {
success: true,
message: "ok",
data: {
users: [
{
id: "admin-recipient-1",
full_name: "Notification Admin",
username: "notification-admin",
},
],
},
meta: { offset: 0, limit: 10, total: 1 },
},
});
}).as("notificationRecipients");
cy.visit("/notification-history/create");
cy.get('select[name="target"]').select("specific_users", { force: true });
cy.wait("@notificationRecipients");
chooseMultiSelectOption("recipient", "Notification Admin");
cy.contains("span", "Notification Admin").should("be.visible");
cy.get('select[name="target"]').select("all_users", { force: true });
cy.contains("label", /^recipient/i)
.parent()
.find('[tabindex="-1"]')
.should("exist");
});
});