Files
kandev/apps/web/components/settings/notification-events-table.test.tsx
T
João Salavisa e4c4efec18 feat(i18n): localize Settings > General > Notifications
Settings > General > Notifications held all of its copy as literals, so the page
stayed English under a locale switch. Every string now resolves through t() /
<Trans> at render, and the page is on the i18nGuardFiles allowlist so it cannot
drift back.

Event titles, sound preset names and the permission button label resolve from
maps of catalog keys rather than module-scope t(), so they follow a locale
switch. The Apprise install notice is a single <Trans> message so the link stays
inside the sentence. SCREENS in the pseudo-locale oracle gains a per-screen
allow list for text the frontend must not translate (backend-owned provider
names).
2026-08-02 01:49:44 +02:00

97 lines
3.5 KiB
TypeScript

import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
NOTIFICATION_EVENT_SESSION_CLARIFICATION_REQUESTED,
NOTIFICATION_EVENT_SESSION_TURN_FINISHED,
} from "@/lib/notifications/events";
import type { NotificationProvider } from "@/lib/types/http";
import { NotificationEventsTable } from "./notification-events-table";
function provider(overrides: Partial<NotificationProvider> = {}): NotificationProvider {
return {
id: "provider-1",
name: "Desktop Notifications",
type: "local",
config: {},
enabled: true,
events: [],
created_at: "",
updated_at: "",
...overrides,
};
}
function renderTable(tableEvents: string[], providers = [provider()], onTestProvider = vi.fn()) {
return render(
<NotificationEventsTable
tableProviders={providers}
baselineProviders={providers}
tableEvents={tableEvents}
onToggleEvent={vi.fn()}
onTestProvider={onTestProvider}
/>,
);
}
afterEach(cleanup);
describe("NotificationEventsTable", () => {
it("renders the translated title and description for a known event type", () => {
renderTable([NOTIFICATION_EVENT_SESSION_TURN_FINISHED]);
// Once in the mobile list and once in the desktop table; both are always
// mounted and hidden by CSS, so each string appears twice.
expect(screen.getAllByText("Agent turn finished")).toHaveLength(2);
expect(screen.getAllByText("Notify after each completed agent turn.")).toHaveLength(2);
});
it("falls back to the raw event type for an event the catalog does not know", () => {
renderTable(["session.some_future_event"]);
expect(screen.getAllByText("session.some_future_event")).toHaveLength(2);
expect(screen.getAllByText("Notify when this event occurs.")).toHaveLength(2);
});
it("names each checkbox with the event title and the provider name", () => {
renderTable([NOTIFICATION_EVENT_SESSION_CLARIFICATION_REQUESTED]);
expect(
screen.getAllByRole("checkbox", {
name: "Agent needs an answer for Desktop Notifications",
}),
).toHaveLength(2);
});
it("names and wires the test control for a remote provider", async () => {
const onTestProvider = vi.fn().mockResolvedValue(undefined);
const remote = provider({ id: "apprise-1", name: "Ops channel", type: "apprise" });
renderTable([NOTIFICATION_EVENT_SESSION_TURN_FINISHED], [remote], onTestProvider);
const buttons = screen.getAllByRole("button", {
name: "Send test notification for Ops channel",
});
expect(buttons).toHaveLength(2);
// Radix Tooltip does not open from synthetic pointer events in this
// environment; focus is the reliable path (apps/web/AGENTS.md).
fireEvent.focus(buttons[0]);
expect((await screen.findByRole("tooltip")).textContent).toBe("Send test notification");
fireEvent.click(buttons[0]);
expect(onTestProvider).toHaveBeenCalledWith("apprise-1");
});
it("omits the test control for the local provider, which cannot be tested remotely", () => {
renderTable([NOTIFICATION_EVENT_SESSION_TURN_FINISHED]);
expect(screen.queryByRole("button", { name: /Send test notification/ })).toBeNull();
});
it("reports an empty provider list instead of an empty table", () => {
renderTable([NOTIFICATION_EVENT_SESSION_TURN_FINISHED], []);
expect(screen.getByText("No providers configured yet.")).toBeTruthy();
expect(screen.queryByTestId("notification-events-desktop-table")).toBeNull();
});
});