diff --git a/src/pages/SimpleProgram/SimpleProgram.tsx b/src/pages/SimpleProgram/SimpleProgram.tsx index 56020a4..0f63653 100644 --- a/src/pages/SimpleProgram/SimpleProgram.tsx +++ b/src/pages/SimpleProgram/SimpleProgram.tsx @@ -2,8 +2,9 @@ import React from "react"; import styles from "./SimpleProgram.module.css"; import useProgramStore from "../../utils/programStore.ts"; -/* ---------- Reusable UI ---------- */ - +/** + * Generic container box with a header and content area. + */ type BoxProps = { title: string; children: React.ReactNode; @@ -16,8 +17,10 @@ const Box: React.FC = ({ title, children }) => ( ); -/* ---------- Lists ---------- */ - +/** + * Renders a list of goals for a phase. + * Expects goal-like objects from the program store. + */ const GoalList: React.FC<{ goals: unknown[] }> = ({ goals }) => { if (!goals.length) { return

No goals defined.

; @@ -49,6 +52,9 @@ const GoalList: React.FC<{ goals: unknown[] }> = ({ goals }) => { ); }; +/** + * Renders a list of triggers for a phase. + */ const TriggerList: React.FC<{ triggers: unknown[] }> = ({ triggers }) => { if (!triggers.length) { return

No triggers defined.

; @@ -73,6 +79,9 @@ const TriggerList: React.FC<{ triggers: unknown[] }> = ({ triggers }) => { ); }; +/** + * Renders a list of norms for a phase. + */ const NormList: React.FC<{ norms: unknown[] }> = ({ norms }) => { if (!norms.length) { return

No norms defined.

; @@ -92,8 +101,9 @@ const NormList: React.FC<{ norms: unknown[] }> = ({ norms }) => { ); }; -/* ---------- Phase Grid ---------- */ - +/** + * Displays all phase-related information in a grid layout. + */ type PhaseGridProps = { norms: unknown[]; goals: unknown[]; @@ -104,31 +114,31 @@ const PhaseGrid: React.FC = ({ norms, goals, triggers, -}) => { - return ( -
- - - +}) => ( +
+ + + - - - + + + - - - + + + - -

No conditional norms defined.

-
- {/* Let er dus op dat deze erbij moeten */} -
- ); -}; - -/* ---------- Main Component ---------- */ + +

No conditional norms defined.

+
+
+); +/** + * Main program viewer. + * Reads all data from the program store and allows + * navigating between phases. + */ const SimpleProgram: React.FC = () => { const getPhaseIds = useProgramStore((s) => s.getPhaseIds); const getNormsInPhase = useProgramStore((s) => s.getNormsInPhase); diff --git a/test/pages/simpleProgram/SimpleProgram.tsx b/test/pages/simpleProgram/SimpleProgram.tsx new file mode 100644 index 0000000..22fcbbf --- /dev/null +++ b/test/pages/simpleProgram/SimpleProgram.tsx @@ -0,0 +1,83 @@ +import { render, screen, fireEvent } from "@testing-library/react"; +import SimpleProgram from "../../../src/pages/SimpleProgram/SimpleProgram"; +import useProgramStore from "../../../src/utils/programStore"; + +/** + * Helper to preload the program store before rendering. + */ +function loadProgram(phases: Record[]) { + useProgramStore.getState().setProgramState({ phases }); +} + +describe("SimpleProgram", () => { + beforeEach(() => { + loadProgram([]); + }); + + test("shows empty state when no program is loaded", () => { + render(); + expect(screen.getByText("No program loaded.")).toBeInTheDocument(); + }); + + test("renders first phase content", () => { + loadProgram([ + { + id: "phase-1", + norms: [{ id: "n1", norm: "Be polite" }], + goals: [{ id: "g1", description: "Finish task", achieved: true }], + triggers: [{ id: "t1", label: "Keyword trigger" }], + }, + ]); + + render(); + + expect(screen.getByText("Phase 1 / 1")).toBeInTheDocument(); + expect(screen.getByText("Be polite")).toBeInTheDocument(); + expect(screen.getByText("Finish task")).toBeInTheDocument(); + expect(screen.getByText("Keyword trigger")).toBeInTheDocument(); + }); + + test("allows navigating between phases", () => { + loadProgram([ + { + id: "phase-1", + norms: [], + goals: [], + triggers: [], + }, + { + id: "phase-2", + norms: [{ id: "n2", norm: "Be careful" }], + goals: [], + triggers: [], + }, + ]); + + render(); + + expect(screen.getByText("Phase 1 / 2")).toBeInTheDocument(); + + fireEvent.click(screen.getByText("Next ▶")); + + expect(screen.getByText("Phase 2 / 2")).toBeInTheDocument(); + expect(screen.getByText("Be careful")).toBeInTheDocument(); + }); + + test("prev button is disabled on first phase", () => { + loadProgram([ + { id: "phase-1", norms: [], goals: [], triggers: [] }, + ]); + + render(); + expect(screen.getByText("◀ Prev")).toBeDisabled(); + }); + + test("next button is disabled on last phase", () => { + loadProgram([ + { id: "phase-1", norms: [], goals: [], triggers: [] }, + ]); + + render(); + expect(screen.getByText("Next ▶")).toBeDisabled(); + }); +});