nxtgauge-frontend-solid/tests/vitest/components/AiChatWidget.test.tsx
Tracewebstudio Dev 0d63bb304e Add comprehensive test infrastructure and AI guardrails
- Add Vitest unit tests for AiChatWidget component
- Add Playwright E2E tests: ai-chat-widget, api, security, guardrails
- Add AI guardrails tests validating no phone/email leaks from Ollama
- Add security tests: auth, rate limiting, input validation, token handling
- Add API tests for AI endpoints and authentication
- Fix playwright.config.ts reporter path conflict
- Update CompanyJobsPage with AI generate buttons (orange icon, loading state)
- Fix AiChatWidget accessibility (role=dialog, aria-label, aria-modal)
- Add app.css spin animation for AI loading spinner
- Add Gitea Actions workflow for nightly CI tests
- Add TESTING.md documentation
2026-05-01 02:54:25 +02:00

89 lines
No EOL
2.4 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor } from "@solidjs/testing-library";
import { AiChatWidget } from "../../src/components/AiChatWidget";
global.fetch = vi.fn();
function createFetchMock(response: unknown, ok = true) {
return vi.mocked(fetch).mockResolvedValueOnce({
ok,
json: () => Promise.resolve(response),
} as Response);
}
describe("AiChatWidget", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("renders the floating button", () => {
render(() => <AiChatWidget />);
const button = screen.getByTitle("AI Assistant");
expect(button).toBeTruthy();
});
it("opens chat window on button click", async () => {
render(() => <AiChatWidget />);
const button = screen.getByTitle("AI Assistant");
fireEvent.click(button);
await waitFor(() => {
const header = screen.getByText("AI Assistant");
expect(header).toBeTruthy();
});
});
it("shows initial greeting message", () => {
render(() => <AiChatWidget />);
const button = screen.getByTitle("AI Assistant");
fireEvent.click(button);
const greeting = screen.getByText(/I'm your AI assistant/i);
expect(greeting).toBeTruthy();
});
it("shows error message when API fails", async () => {
vi.mocked(fetch).mockRejectedValueOnce(new Error("Network error"));
render(() => <AiChatWidget />);
const button = screen.getByTitle("AI Assistant");
fireEvent.click(button);
await waitFor(() => {
const input = screen.getByPlaceholder(/Ask/i);
fireEvent.change(input, { target: { value: "Test" } });
fireEvent.keyDown(input, { key: "Enter" });
});
await waitFor(
() => {
expect(screen.getByText(/contact support/i)).toBeTruthy();
},
{ timeout: 5000 }
);
});
it("displays user message after sending", async () => {
createFetchMock({
message: "Hello from AI",
conversation_id: "conv-123",
intent: "general",
confidence: 0.9,
});
render(() => <AiChatWidget />);
const button = screen.getByTitle("AI Assistant");
fireEvent.click(button);
await waitFor(() => {
const input = screen.getByPlaceholder(/Ask/i);
fireEvent.change(input, { target: { value: "Hello" } });
fireEvent.keyDown(input, { key: "Enter" });
});
await waitFor(() => {
expect(screen.getByText("Hello")).toBeTruthy();
});
});
});