Explorar el Código

Merge pull request #1536 from Avaiga/test/Alert

Unit test for Alert
Nam Nguyen hace 10 meses
padre
commit
24d7e476c6
Se han modificado 1 ficheros con 154 adiciones y 12 borrados
  1. 154 12
      frontend/taipy-gui/src/components/Taipy/Alert.spec.tsx

+ 154 - 12
frontend/taipy-gui/src/components/Taipy/Alert.spec.tsx

@@ -12,19 +12,20 @@
  */
 
 import React from "react";
-import { render } from "@testing-library/react";
+import { render, screen, waitFor } from "@testing-library/react";
 import "@testing-library/jest-dom";
 import { SnackbarProvider } from "notistack";
 
 import Alert from "./Alert";
 import { AlertMessage } from "../../context/taipyReducers";
+import userEvent from "@testing-library/user-event";
 
 const defaultMessage = "message";
 const defaultAlerts: AlertMessage[] = [{ atype: "success", message: defaultMessage, system: true, duration: 3000 }];
-const getAlertsWithType = (aType: string) => [{...defaultAlerts[0], atype: aType}];
+const getAlertsWithType = (aType: string) => [{ ...defaultAlerts[0], atype: aType }];
 
 class myNotification {
-    static requestPermission = jest.fn();
+    static requestPermission = jest.fn(() => Promise.resolve("granted"));
     static permission = "granted";
 }
 
@@ -32,29 +33,170 @@ describe("Alert Component", () => {
     beforeAll(() => {
         globalThis.Notification = myNotification as unknown as jest.Mocked<typeof Notification>;
     });
+    beforeEach(() => {
+        jest.clearAllMocks();
+    });
     it("renders", async () => {
-        const { getByText } = render(<SnackbarProvider><Alert alerts={defaultAlerts} /></SnackbarProvider>);
+        const { getByText } = render(
+            <SnackbarProvider>
+                <Alert alerts={defaultAlerts} />
+            </SnackbarProvider>,
+        );
         const elt = getByText(defaultMessage);
         expect(elt.tagName).toBe("DIV");
     });
     it("displays a success alert", async () => {
-        const { getByText } = render(<SnackbarProvider><Alert alerts={defaultAlerts} /></SnackbarProvider>);
+        const { getByText } = render(
+            <SnackbarProvider>
+                <Alert alerts={defaultAlerts} />
+            </SnackbarProvider>,
+        );
         const elt = getByText(defaultMessage);
-        expect(elt.closest(".notistack-MuiContent-success")).toBeInTheDocument()
+        expect(elt.closest(".notistack-MuiContent-success")).toBeInTheDocument();
     });
     it("displays an error alert", async () => {
-        const { getByText } = render(<SnackbarProvider><Alert alerts={getAlertsWithType("error")} /></SnackbarProvider>);
+        const { getByText } = render(
+            <SnackbarProvider>
+                <Alert alerts={getAlertsWithType("error")} />
+            </SnackbarProvider>,
+        );
         const elt = getByText(defaultMessage);
-        expect(elt.closest(".notistack-MuiContent-error")).toBeInTheDocument()
+        expect(elt.closest(".notistack-MuiContent-error")).toBeInTheDocument();
     });
     it("displays a warning alert", async () => {
-        const { getByText } = render(<SnackbarProvider><Alert alerts={getAlertsWithType("warning")} /></SnackbarProvider>);
+        const { getByText } = render(
+            <SnackbarProvider>
+                <Alert alerts={getAlertsWithType("warning")} />
+            </SnackbarProvider>,
+        );
         const elt = getByText(defaultMessage);
-        expect(elt.closest(".notistack-MuiContent-warning")).toBeInTheDocument()
+        expect(elt.closest(".notistack-MuiContent-warning")).toBeInTheDocument();
     });
     it("displays an info alert", async () => {
-        const { getByText } = render(<SnackbarProvider><Alert alerts={getAlertsWithType("info")} /></SnackbarProvider>);
+        const { getByText } = render(
+            <SnackbarProvider>
+                <Alert alerts={getAlertsWithType("info")} />
+            </SnackbarProvider>,
+        );
         const elt = getByText(defaultMessage);
-        expect(elt.closest(".notistack-MuiContent-info")).toBeInTheDocument()
+        expect(elt.closest(".notistack-MuiContent-info")).toBeInTheDocument();
+    });
+    it("gets favicon URL from document link tags", () => {
+        const link = document.createElement("link");
+        link.rel = "icon";
+        link.href = "/test-icon.png";
+        document.head.appendChild(link);
+        const alerts: AlertMessage[] = [
+            { atype: "success", message: "This is a system alert", system: true, duration: 3000 },
+        ];
+        render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        const linkElement = document.querySelector("link[rel='icon']");
+        if (linkElement) {
+            expect(linkElement.getAttribute("href")).toBe("/test-icon.png");
+        } else {
+            expect(true).toBe(false);
+        }
+        document.head.removeChild(link);
+    });
+
+    it("closes alert on close button click", async () => {
+        const alerts = [{ atype: "success", message: "Test Alert", duration: 3000, system: false }];
+        render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        const closeButton = await screen.findByRole("button", { name: /close/i });
+        await userEvent.click(closeButton);
+        await waitFor(() => {
+            const alertMessage = screen.queryByText("Test Alert");
+            expect(alertMessage).not.toBeInTheDocument();
+        });
+    });
+
+    it("Alert disappears when alert type is empty", async () => {
+        const alerts = [{ atype: "success", message: "Test Alert", duration: 3000, system: false }];
+        const { rerender } = render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        await screen.findByRole("button", { name: /close/i });
+        const newAlerts = [{ atype: "", message: "Test Alert", duration: 3000, system: false }];
+        rerender(
+            <SnackbarProvider>
+                <Alert alerts={newAlerts} />
+            </SnackbarProvider>,
+        );
+        await waitFor(() => {
+            const alertMessage = screen.queryByText("Test Alert");
+            expect(alertMessage).not.toBeInTheDocument();
+        });
+    });
+
+    it("does nothing when alert is undefined", async () => {
+        render(
+            <SnackbarProvider>
+                <Alert alerts={[]} />
+            </SnackbarProvider>,
+        );
+        expect(Notification.requestPermission).not.toHaveBeenCalled();
+    });
+
+    it("validates href when rel attribute is 'icon' and href is set", () => {
+        const link = document.createElement("link");
+        link.rel = "icon";
+        link.href = "/test-icon.png";
+        document.head.appendChild(link);
+        const alerts: AlertMessage[] = [
+            { atype: "success", message: "This is a system alert", system: true, duration: 3000 },
+        ];
+        render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        const linkElement = document.querySelector("link[rel='icon']");
+        expect(linkElement?.getAttribute("href")).toBe("/test-icon.png");
+        document.head.removeChild(link);
+    });
+
+    it("verifies default favicon for 'icon' rel attribute when href is unset/empty", () => {
+        const link = document.createElement("link");
+        link.rel = "icon";
+        document.head.appendChild(link);
+        const alerts: AlertMessage[] = [
+            { atype: "success", message: "This is a system alert", system: true, duration: 3000 },
+        ];
+        render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        const linkElement = document.querySelector("link[rel='icon']");
+        expect(linkElement?.getAttribute("href") || "/favicon.png").toBe("/favicon.png");
+        document.head.removeChild(link);
+    });
+
+    it("validates href when rel attribute is 'shortcut icon' and href is provided", () => {
+        const link = document.createElement("link");
+        link.rel = "shortcut icon";
+        link.href = "/test-shortcut-icon.png";
+        document.head.appendChild(link);
+        const alerts: AlertMessage[] = [
+            { atype: "success", message: "This is a system alert", system: true, duration: 3000 },
+        ];
+        render(
+            <SnackbarProvider>
+                <Alert alerts={alerts} />
+            </SnackbarProvider>,
+        );
+        const linkElement = document.querySelector("link[rel='shortcut icon']");
+        expect(linkElement?.getAttribute("href")).toBe("/test-shortcut-icon.png");
+        document.head.removeChild(link);
     });
 });