diff --git a/lib/mbti/publicProjection.ts b/lib/mbti/publicProjection.ts index a21e96ae9..fc48799be 100644 --- a/lib/mbti/publicProjection.ts +++ b/lib/mbti/publicProjection.ts @@ -45,6 +45,8 @@ const RESULT_SECTION_ORDER = [ "letters_intro", "overview", "trait_overview", + "traits.at_difference", + "faq", "traits.why_this_type", "traits.close_call_axes", "traits.adjacent_type_contrast", diff --git a/tests/contracts/mbti-result-section-registry.contract.test.ts b/tests/contracts/mbti-result-section-registry.contract.test.ts new file mode 100644 index 000000000..1e6fb9a85 --- /dev/null +++ b/tests/contracts/mbti-result-section-registry.contract.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, it } from "vitest"; +import type { ReportResponse } from "@/lib/api/v0_3"; +import { buildMbtiResultProjectionViewModel } from "@/lib/mbti/publicProjection"; +import reportReadyMbtiProjectionFixture from "@/tests/fixtures/report_ready.mbti.projection.json"; + +describe("MBTI result section registry", () => { + it("preserves the canonical A/T difference and FAQ sections in inventory order", () => { + const report = structuredClone(reportReadyMbtiProjectionFixture) as ReportResponse; + const projection = report.mbti_public_projection_v1 as { + sections?: Array>; + }; + + projection.sections = [ + ...(projection.sections ?? []), + { + key: "faq", + render: "bullets", + title: "Frequently asked questions", + payload: { + items: [{ question: "Synthetic question", answer: "Synthetic answer" }], + }, + }, + { + key: "traits.at_difference", + render: "rich_text", + title: "A/T identity layer", + body_md: "Synthetic A/T difference body.", + }, + ]; + + const viewModel = buildMbtiResultProjectionViewModel(report); + const keys = viewModel.sections.map((section) => section.key); + + expect(keys).toContain("traits.at_difference"); + expect(keys).toContain("faq"); + expect(keys.indexOf("trait_overview")).toBeLessThan(keys.indexOf("traits.at_difference")); + expect(keys.indexOf("traits.at_difference")).toBeLessThan(keys.indexOf("faq")); + expect(keys.indexOf("faq")).toBeLessThan(keys.indexOf("career.summary")); + expect(viewModel.sections.find((section) => section.key === "traits.at_difference")?.bodyMd).toBe( + "Synthetic A/T difference body." + ); + expect(viewModel.sections.find((section) => section.key === "faq")?.payload).toMatchObject({ + items: [{ question: "Synthetic question", answer: "Synthetic answer" }], + }); + }); +});