Initial commit: CI Agent competitive-intelligence monitoring app
FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring, source collection, LLM-based change analysis, enrichment, and account security (Turnstile, escalating lockout, email verification).
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import { screen, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import AlertsPage from "@/app/(app)/alerts/page";
|
||||
import { renderWithQueryClient } from "./test-utils";
|
||||
|
||||
const COMPANIES = [
|
||||
{ id: "company-1", name: "Acme Mobility Systems" },
|
||||
{ id: "company-2", name: "Globex Corp" },
|
||||
];
|
||||
|
||||
const ALERTS = [
|
||||
{
|
||||
id: "alert-1",
|
||||
company_id: "company-1",
|
||||
detected_change_id: "change-1",
|
||||
title: "Base plan price increased",
|
||||
summary: "Pricing changed.",
|
||||
why_it_matters: "Signals margin pressure.",
|
||||
severity: "high",
|
||||
confidence: 0.82,
|
||||
read: false,
|
||||
resolved: false,
|
||||
created_at: new Date().toISOString(),
|
||||
},
|
||||
];
|
||||
|
||||
function mockFetchImplementation() {
|
||||
return vi.fn().mockImplementation((url: string) => {
|
||||
const path = url.replace("http://localhost:8000", "");
|
||||
if (path.startsWith("/api/v1/companies")) {
|
||||
return Promise.resolve({ ok: true, status: 200, json: async () => COMPANIES });
|
||||
}
|
||||
if (path.startsWith("/api/v1/alerts")) {
|
||||
return Promise.resolve({ ok: true, status: 200, json: async () => ALERTS });
|
||||
}
|
||||
return Promise.resolve({ ok: false, status: 404, json: async () => ({ detail: "not found" }) });
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubGlobal("fetch", mockFetchImplementation());
|
||||
});
|
||||
|
||||
describe("AlertsPage", () => {
|
||||
it("renders alerts with the resolved company name", async () => {
|
||||
renderWithQueryClient(<AlertsPage />);
|
||||
|
||||
expect(await screen.findByText("Base plan price increased")).toBeInTheDocument();
|
||||
const list = screen.getByRole("list");
|
||||
expect(within(list).getByText(/Acme Mobility Systems/)).toBeInTheDocument();
|
||||
expect(within(list).getByText("high")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("re-fetches with a severity filter when changed", async () => {
|
||||
const fetchMock = mockFetchImplementation();
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
const user = userEvent.setup();
|
||||
renderWithQueryClient(<AlertsPage />);
|
||||
|
||||
await screen.findByText("Base plan price increased");
|
||||
|
||||
await user.click(screen.getByRole("combobox", { name: "Filter by severity" }));
|
||||
await user.click(await screen.findByRole("option", { name: "Critical" }));
|
||||
|
||||
await waitFor(() => {
|
||||
const calledUrls = fetchMock.mock.calls.map((call) => call[0] as string);
|
||||
expect(calledUrls.some((u) => u.includes("severity=critical"))).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user