Files
ThothII/frontend/src/viewers/PhaseSummaryViewer.test.tsx
T

119 lines
4.5 KiB
TypeScript

import { render, screen } from "@testing-library/react";
import { PhaseSummaryViewer } from "./PhaseSummaryViewer";
import type { PhaseSummaryV2 } from "./artifactV2";
const phase: PhaseSummaryV2 = {
schema_version: 2,
phase: { id: "F5", num: 5, name: "sintesi" },
summary: "## Recap\nLa catena copre pazienti e impianti.",
checks: [
{ label: "Schema linking completo", status: "ok" },
{ label: "Join validati", status: "warn", detail: "Un join manuale non testato" },
{ label: "SQL eseguibile", status: "fail", detail: "Errore di sintassi" },
],
sections: [
{
title: "Criteri di selezione",
items: [
{
label: "Pazienti attivi",
table: "pazienti",
column: "stato",
value: "IS TRUE",
kind: "filter",
description: "Flag di stato attivo",
rationale: "Solo pazienti in follow-up",
},
],
},
],
tables: [
{
name: "pazienti",
role: "promoted",
description: "Anagrafica pazienti",
columns: [{ name: "stato", description: "Flag attivo", value_filter: "IS TRUE" }],
},
{ name: "log_accessi", role: "excluded", description: "Non pertinente" },
],
open_questions: ["Serve confermare la finestra temporale?"],
};
test("renders phase id/name header and markdown summary", () => {
render(<PhaseSummaryViewer phase={phase} />);
expect(screen.getByText(/F5/)).toBeInTheDocument();
expect(screen.getByText(/sintesi/)).toBeInTheDocument();
expect(screen.getByText("Recap")).toBeInTheDocument();
expect(screen.getByText(/La catena copre pazienti e impianti/)).toBeInTheDocument();
});
test("renders checks with status label and detail", () => {
render(<PhaseSummaryViewer phase={phase} />);
expect(screen.getByText("Schema linking completo")).toBeInTheDocument();
expect(screen.getByText("Join validati")).toBeInTheDocument();
expect(screen.getByText("Un join manuale non testato")).toBeInTheDocument();
expect(screen.getByText("SQL eseguibile")).toBeInTheDocument();
expect(screen.getByText("Errore di sintassi")).toBeInTheDocument();
});
test("renders sections with item label, table.column code-chip, and value badge", () => {
render(<PhaseSummaryViewer phase={phase} />);
expect(screen.getByText("Criteri di selezione")).toBeInTheDocument();
expect(screen.getByText("Pazienti attivi")).toBeInTheDocument();
expect(screen.getByText("pazienti.stato")).toBeInTheDocument();
expect(screen.getAllByText("IS TRUE").length).toBeGreaterThan(0);
expect(screen.getByText("Flag di stato attivo")).toBeInTheDocument();
expect(screen.getByText("Solo pazienti in follow-up")).toBeInTheDocument();
});
test("renders tables recap with promoted/excluded roles and columns", () => {
render(<PhaseSummaryViewer phase={phase} />);
expect(screen.getByText("pazienti")).toBeInTheDocument();
expect(screen.getByText(/promoted/i)).toBeInTheDocument();
expect(screen.getByText("log_accessi")).toBeInTheDocument();
expect(screen.getByText(/excluded/i)).toBeInTheDocument();
expect(screen.getByText("stato")).toBeInTheDocument();
expect(screen.getAllByText("IS TRUE").length).toBeGreaterThan(0);
});
test("renders open_questions as a bullet list", () => {
render(<PhaseSummaryViewer phase={phase} />);
expect(screen.getByText("Serve confermare la finestra temporale?")).toBeInTheDocument();
});
test("renders a legacy structured open question safely", () => {
const malformed = {
...phase,
open_questions: [
{
label: "pazienti_finale restituisce 0 righe",
question: "Verificare se i filtri sono troppo restrittivi",
},
],
} as unknown as PhaseSummaryV2;
render(<PhaseSummaryViewer phase={malformed} />);
expect(screen.getByText("Verificare se i filtri sono troppo restrittivi")).toBeInTheDocument();
});
test("renders a section with title only (no items key) without crashing", () => {
const proseOnly: PhaseSummaryV2 = {
schema_version: 2,
phase: { id: "F5", num: 5, name: "sintesi" },
sections: [{ title: "Note libere" }],
};
render(<PhaseSummaryViewer phase={proseOnly} />);
expect(screen.getByText("Note libere")).toBeInTheDocument();
});
test("omits open_questions section when empty and shows no 'undefined' text", () => {
const minimal: PhaseSummaryV2 = {
schema_version: 2,
phase: { id: "F1", num: 1, name: "domanda" },
};
render(<PhaseSummaryViewer phase={minimal} />);
expect(screen.queryByText(/undefined/i)).not.toBeInTheDocument();
expect(screen.getByText(/F1/)).toBeInTheDocument();
});