feat/Update_Controllers_to_Allow_for_Premium_Membership
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import React from "react";
|
||||
import "@testing-library/jest-dom";
|
||||
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
|
||||
import { api } from "./api";
|
||||
import OperationsPage from "./views/OperationsPage";
|
||||
|
||||
jest.mock("./api", () => ({
|
||||
api: {
|
||||
get: jest.fn(),
|
||||
post: jest.fn(),
|
||||
delete: jest.fn(),
|
||||
interceptors: { request: { use: jest.fn() }, response: { use: jest.fn() } },
|
||||
},
|
||||
getApiErrorMessage: (_error: unknown, fallback?: string) => fallback || "Request failed.",
|
||||
}));
|
||||
|
||||
const mockedApi = api as jest.Mocked<typeof api>;
|
||||
|
||||
const operation = {
|
||||
id: "11111111-1111-1111-1111-111111111111",
|
||||
taskType: "strategy_snapshot",
|
||||
status: "running",
|
||||
createdAtUtc: "2026-08-02T12:00:00Z",
|
||||
progressStage: "Analysing role",
|
||||
progressPercent: 40,
|
||||
canCancel: true,
|
||||
canRetry: false,
|
||||
};
|
||||
|
||||
const notification = {
|
||||
id: "22222222-2222-2222-2222-222222222222",
|
||||
operationId: operation.id,
|
||||
kind: "operation_failed",
|
||||
title: "Operation failed",
|
||||
message: "A background operation failed. Review it for details.",
|
||||
createdAtUtc: "2026-08-02T12:05:00Z",
|
||||
readAtUtc: null,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockedApi.get.mockImplementation((url: string) => Promise.resolve({
|
||||
data: url.startsWith("/operations") ? [operation] : [notification],
|
||||
} as any));
|
||||
mockedApi.post.mockResolvedValue({ data: {} } as any);
|
||||
mockedApi.delete.mockResolvedValue({ data: {} } as any);
|
||||
});
|
||||
|
||||
test("shows persistent operation and notification states with accessible actions", async () => {
|
||||
render(<OperationsPage />);
|
||||
|
||||
expect(await screen.findByText("strategy_snapshot")).toBeInTheDocument();
|
||||
expect(screen.getByText("Analysing role")).toBeInTheDocument();
|
||||
expect(screen.getByRole("progressbar", { name: "strategy_snapshot progress" })).toHaveAttribute("aria-valuenow", "40");
|
||||
expect(screen.getByText("Operation failed")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "Cancel" }));
|
||||
await waitFor(() => expect(mockedApi.post).toHaveBeenCalledWith(`/operations/${operation.id}/cancel`));
|
||||
|
||||
const markRead = screen.getByRole("button", { name: "Mark read" });
|
||||
await waitFor(() => expect(markRead).toBeEnabled());
|
||||
fireEvent.click(markRead);
|
||||
await waitFor(() => expect(mockedApi.post).toHaveBeenCalledWith(`/notifications/${notification.id}/read`));
|
||||
|
||||
const dismiss = screen.getByRole("button", { name: "Dismiss" });
|
||||
await waitFor(() => expect(dismiss).toBeEnabled());
|
||||
fireEvent.click(dismiss);
|
||||
await waitFor(() => expect(mockedApi.delete).toHaveBeenCalledWith(`/notifications/${notification.id}`));
|
||||
});
|
||||
|
||||
test("shows honest empty and failure states", async () => {
|
||||
mockedApi.get.mockResolvedValueOnce({ data: [] } as any).mockResolvedValueOnce({ data: [] } as any);
|
||||
const { unmount } = render(<OperationsPage />);
|
||||
expect(await screen.findByText("No notifications.")).toBeInTheDocument();
|
||||
expect(screen.getByText("No background operations yet.")).toBeInTheDocument();
|
||||
unmount();
|
||||
|
||||
mockedApi.get.mockRejectedValue(new Error("offline"));
|
||||
render(<OperationsPage />);
|
||||
expect(await screen.findByRole("alert")).toHaveTextContent("Operations could not be loaded.");
|
||||
});
|
||||
Reference in New Issue
Block a user