119 lines
4.5 KiB
TypeScript
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();
|
|
});
|