From 8f6081de89575f8fc35a201035caef0499056147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Wed, 11 Nov 2026 22:23:07 +0100 Subject: [PATCH] test: delete text pins on things removed releases ago Five tests only read source or message files to assert that something long gone stays gone: the moodLog bridge (removed in July), the chart's target-adjust link (v1.16.8), the mood notes timeline, the medication detail page's old dose card and wizard host (v1.15.18), and the obsolete v1.34.1 copy keys. They protect no behaviour, and the general i18n guards already hold every key and placeholder across the ten locales, which the v1.34.1 list did for nine. The source-read baseline drops from 337 to 332. --- .../baselines/test-source-reads.json | 9 +- .../baselines/version-stamp-comments.json | 8 +- src/__tests__/moodlog-removal-guard.test.ts | 114 ----------- src/__tests__/v1341-locale-parity.test.ts | 187 ------------------ .../detail-page-history-surface.test.ts | 38 ---- .../health-chart-target-link-removed.test.ts | 53 ----- .../mood-notes-timeline-removed.test.ts | 85 -------- src/lib/http/retired-routes.ts | 3 +- 8 files changed, 5 insertions(+), 492 deletions(-) delete mode 100644 src/__tests__/moodlog-removal-guard.test.ts delete mode 100644 src/__tests__/v1341-locale-parity.test.ts delete mode 100644 src/app/medications/__tests__/detail-page-history-surface.test.ts delete mode 100644 src/components/charts/__tests__/health-chart-target-link-removed.test.ts delete mode 100644 src/components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts diff --git a/src/__tests__/baselines/test-source-reads.json b/src/__tests__/baselines/test-source-reads.json index ff3077a13..32735d50b 100644 --- a/src/__tests__/baselines/test-source-reads.json +++ b/src/__tests__/baselines/test-source-reads.json @@ -1,7 +1,7 @@ { "$comment": "tests that read a source file by path, per test file under src/. Maintained by src/__tests__/test-realism-ratchet.test.ts.", - "count": 337, - "total": 337, + "count": 332, + "total": 332, "entries": { "__tests__/account-payload-consumer-guard.test.ts": 1, "__tests__/admin-data-wipe-completeness.test.ts": 1, @@ -87,7 +87,6 @@ "__tests__/module-gate-record-scoped.test.ts": 1, "__tests__/mood-backup-completeness.test.ts": 1, "__tests__/mood-prediction-write-surface-guard.test.ts": 1, - "__tests__/moodlog-removal-guard.test.ts": 1, "__tests__/next-image-optimizer-guard.test.ts": 1, "__tests__/no-server-actions-guard.test.ts": 1, "__tests__/oidc-native-error-reasons-documented.test.ts": 1, @@ -141,7 +140,6 @@ "__tests__/unit-preference-display-guard.test.ts": 1, "__tests__/unit-suite-browser-install-guard.test.ts": 1, "__tests__/utc-day-key-allowlist-guard.test.ts": 1, - "__tests__/v1341-locale-parity.test.ts": 1, "__tests__/visit-link-guard.test.ts": 1, "__tests__/workout-canonical-identity-guard.test.ts": 1, "__tests__/write-rate-limit-guard.test.ts": 1, @@ -174,7 +172,6 @@ "app/insights/__tests__/page-skeletons.test.ts": 1, "app/insights/sleep/__tests__/empty-state-href.test.ts": 1, "app/measurements/__tests__/add-token-resolution.test.ts": 1, - "app/medications/__tests__/detail-page-history-surface.test.ts": 1, "components/__tests__/design-consistency-guards.test.tsx": 1, "components/__tests__/failed-read-never-empty.test.tsx": 1, "components/__tests__/motion-reduce-spin-coverage.test.ts": 1, @@ -182,7 +179,6 @@ "components/admin/__tests__/notification-test-failures.test.ts": 1, "components/charts/__tests__/chart-error-state.test.tsx": 1, "components/charts/__tests__/health-chart-overlay-defaults.test.tsx": 1, - "components/charts/__tests__/health-chart-target-link-removed.test.ts": 1, "components/charts/__tests__/mood-chart-polish.test.tsx": 1, "components/charts/__tests__/touch-action-guard.test.ts": 1, "components/cycle/__tests__/use-cycle-ring-has-dial.test.tsx": 1, @@ -206,7 +202,6 @@ "components/insights/coach-panel/__tests__/open-at-end.test.ts": 1, "components/insights/coach-panel/__tests__/panel-touch-targets.test.ts": 1, "components/insights/coach-panel/__tests__/scroll-to-bottom-button.test.tsx": 1, - "components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts": 1, "components/layout/__tests__/auth-shell-coach-hoist.test.ts": 1, "components/layout/__tests__/auth-shell-shared-record-doors.test.tsx": 1, "components/layout/__tests__/offline-banner.test.tsx": 1, diff --git a/src/__tests__/baselines/version-stamp-comments.json b/src/__tests__/baselines/version-stamp-comments.json index e93abac30..e56ebd105 100644 --- a/src/__tests__/baselines/version-stamp-comments.json +++ b/src/__tests__/baselines/version-stamp-comments.json @@ -1,7 +1,7 @@ { "$comment": "Comment lines that open with a release version, per file under src/. Maintained by src/__tests__/version-stamp-ratchet.test.ts.", - "count": 2881, - "total": 9184, + "count": 2877, + "total": 9177, "entries": { "__tests__/account-payload-consumer-guard.test.ts": 2, "__tests__/acting-account-boundary-guard.test.ts": 7, @@ -68,7 +68,6 @@ "__tests__/success-affordance-guard.test.ts": 8, "__tests__/timezone-explicit-formatter-guard.test.ts": 1, "__tests__/unit-preference-display-guard.test.ts": 2, - "__tests__/v1341-locale-parity.test.ts": 1, "__tests__/v1391-additive-contract.test.ts": 1, "__tests__/write-rate-limit-guard.test.ts": 1, "app/__tests__/dashboard-analytics-split.test.ts": 2, @@ -655,7 +654,6 @@ "app/mcp/__tests__/route.test.ts": 5, "app/measurements/page.tsx": 5, "app/medications/__tests__/category-filter.test.tsx": 2, - "app/medications/__tests__/detail-page-history-surface.test.ts": 1, "app/medications/__tests__/list-view-toggle.test.tsx": 5, "app/medications/__tests__/page-prefetch.test.tsx": 1, "app/medications/__tests__/take-all-due-affordance.test.tsx": 1, @@ -736,7 +734,6 @@ "components/charts/__tests__/health-chart-polish.test.tsx": 2, "components/charts/__tests__/health-chart-preloaded-coverage.test.tsx": 1, "components/charts/__tests__/health-chart-range.test.tsx": 3, - "components/charts/__tests__/health-chart-target-link-removed.test.ts": 1, "components/charts/__tests__/health-chart-vertical-markers.test.ts": 1, "components/charts/__tests__/medication-chart-polish.test.tsx": 1, "components/charts/__tests__/medication-compliance-chart-empty-state-gate.test.tsx": 1, @@ -1002,7 +999,6 @@ "components/insights/mood/__tests__/mood-discovered-relations.test.tsx": 3, "components/insights/mood/__tests__/mood-insights-sections-in-target.test.tsx": 1, "components/insights/mood/__tests__/mood-insights-sections-reveal.test.tsx": 1, - "components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts": 4, "components/insights/mood/__tests__/mood-tag-bars-muted.test.tsx": 1, "components/insights/mood/mood-better-days.tsx": 2, "components/insights/mood/mood-correlation-cards.tsx": 3, diff --git a/src/__tests__/moodlog-removal-guard.test.ts b/src/__tests__/moodlog-removal-guard.test.ts deleted file mode 100644 index c012aed0f..000000000 --- a/src/__tests__/moodlog-removal-guard.test.ts +++ /dev/null @@ -1,114 +0,0 @@ -/** - * The moodLog bridge stays removed. - * - * It was retired once before, in pieces: the Settings card went in June, the - * cron, webhook, credentials, ledger entry and roughly twenty i18n keys stayed - * behind, and for a month the code ran hourly against an upstream that had - * stopped answering while nothing on any screen said so. Half-removed was - * worse than either finished state. - * - * This test pins the finished state. It is a structural guard, not a - * behavioural one: it fails the moment a moodLog surface reappears, so a - * reintroduction has to be a decision someone writes down rather than a merge - * that slips through. - * - * What it deliberately does NOT forbid: the `MOODLOG` mood-entry source value - * and its label. Rows the bridge imported are the user's own history, they - * keep their provenance, and every read path must go on resolving it. - */ -import { readFileSync, existsSync } from "node:fs"; -import path from "node:path"; - -import { allJobDefinitions } from "@/lib/jobs/registry/index"; -import { describe, expect, it } from "vitest"; - -import { INTEGRATION_CADENCE } from "@/lib/integrations/sync-verdict"; -import { INTEGRATION_DISPLAY_NAMES } from "@/components/settings/integrations/integration-fallback-row"; - -const ROOT = path.resolve(__dirname, "../.."); - -const LOCALES = [ - "de", - "en", - "es", - "fr", - "it", - "pl", - "ko", - "nl", - "pt-BR", -] as const; - -/** Every path the retired bridge occupied. */ -const REMOVED_PATHS = [ - "src/lib/moodlog", - "src/lib/moodlog-secret.ts", - "src/lib/jobs/reminder/moodlog-sync.ts", - "src/app/api/integrations/moodlog", - "src/app/api/settings/moodlog", - "src/lib/validations/moodlog.ts", -]; - -/** Columns migration 0271 dropped. */ -const REMOVED_SCHEMA_FIELDS = [ - "moodLogUrlEncrypted", - "moodLogApiKeyEncrypted", - "moodLogEnabled", - "moodLogLastSyncedAt", - "moodLogWebhookSecret", - "moodLogGlobal", -]; - -describe("moodLog integration stays removed", () => { - it("has no moodLog module, route or validation file", () => { - for (const rel of REMOVED_PATHS) { - expect(existsSync(path.join(ROOT, rel)), `${rel} is back`).toBe(false); - } - }); - - it("declares no moodLog column on the Prisma schema", () => { - const schema = readFileSync( - path.join(ROOT, "prisma/schema.prisma"), - "utf8", - ); - for (const field of REMOVED_SCHEMA_FIELDS) { - expect(schema, `${field} is back on the schema`).not.toContain(field); - } - }); - - it("registers no moodlog queue, cron or handler binding", () => { - const queues = allJobDefinitions().map((job) => job.queue); - expect(queues.length).toBeGreaterThan(100); - expect(queues.filter((queue) => /mood-?log/i.test(queue))).toEqual([]); - }); - - it("carries no moodlog integration key on the status envelope", () => { - expect(Object.keys(INTEGRATION_CADENCE)).not.toContain("moodlog"); - expect(Object.keys(INTEGRATION_DISPLAY_NAMES)).not.toContain("moodlog"); - }); - - it("keeps no orphaned moodLog message key in any locale", () => { - for (const locale of LOCALES) { - const bundle = JSON.parse( - readFileSync(path.join(ROOT, `messages/${locale}.json`), "utf8"), - ) as { - settings: Record; - admin: Record; - }; - const orphans = [ - ...Object.keys(bundle.settings), - ...Object.keys(bundle.admin), - ].filter((key) => key.startsWith("moodLog")); - expect(orphans, `${locale} still carries moodLog keys`).toEqual([]); - } - }); - - it("still resolves the MOODLOG provenance of imported mood rows", () => { - // The other half of the contract: removing the bridge must not erase the - // history it wrote. The source badge label has to survive the removal. - const en = JSON.parse( - readFileSync(path.join(ROOT, "messages/en.json"), "utf8"), - ) as { mood: Record }; - expect(en.mood.sourceMoodlog).toBeTruthy(); - }); -}); diff --git a/src/__tests__/v1341-locale-parity.test.ts b/src/__tests__/v1341-locale-parity.test.ts deleted file mode 100644 index 4feaed2a2..000000000 --- a/src/__tests__/v1341-locale-parity.test.ts +++ /dev/null @@ -1,187 +0,0 @@ -import { readFileSync } from "node:fs"; -import { join } from "node:path"; - -import { describe, expect, it } from "vitest"; - -const ROOT = join(__dirname, "../.."); -const LOCALES = [ - "en", - "de", - "es", - "fr", - "it", - "pl", - "ko", - "nl", - "pt-BR", -] as const; - -const REQUIRED_KEYS = [ - // Security: adding a passkey now requires an existing sign-in factor. - "settings.passkeyReauth.title", - "settings.passkeyReauth.description", - "settings.passkeyReauth.methodLabel", - "settings.passkeyReauth.methods.password", - "settings.passkeyReauth.methods.totp", - "settings.passkeyReauth.methods.passkey", - "settings.passkeyReauth.methods.webauthn", - "settings.passkeyReauth.currentPassword", - "settings.passkeyReauth.authenticatorCode", - "settings.passkeyReauth.authenticatorPlaceholder", - "settings.passkeyReauth.verifyAndAdd", - // Integrations/imports: operator policy and Apple ECG terminal outcome. - "settings.nightscoutPrivateOperatorTitle", - "settings.nightscoutPrivateOperatorDescription", - "settings.sections.export.import.appleHealth.ecgResult", - // Existing terminal contracts reused by the final v1.34.1 call sites. - "insights.assessmentPreparing", - "insights.noAnalysisYet", - "common.loadFailed", - "common.networkError", - "settings.googleHealthSyncResult", - "settings.googleHealthSyncFailed", - // `settings.googleHealthBackfillInProgress` left this list in v1.42.4: the - // history-loading line became a sentence variant of the shared integration - // card (`settings.integrationCard.reason.dataArrivingHistory`). - "settings.syncOutcome.empty", - "settings.syncOutcome.partial", - "settings.syncOutcome.failed", - // Retained score, records, and navigation contracts. - // `insights.healthScore.method` was listed obsolete in v1.34.1 because its - // only reference was `METRIC_PROVENANCE.HEALTH_SCORE.methodKey`, which the - // card then passed as `method={null}` — a dangling reference, not a dead - // one. The score card now renders that method paragraph in its disclosure - // footer, so the key is a live contract again. - "insights.healthScore.method", - "insights.healthScore.bandSetter", - "insights.healthScore.versionAndNoise", - "insights.healthScore.methodVersion", - "insights.healthScore.source", - "records.allergies.add", - "records.allergies.addFirst", - "records.family.add", - "records.family.addFirst", - "admin.shell.sectionsNav", - "settings.shell.sectionsNav", -] as const; - -const OBSOLETE_KEYS = [ - "insights.healthScore.algorithmChanged", - "insights.healthScore.dismissAlgorithmChanged", - "insights.healthScore.composition", - "documents.detail.summary.regenerate", - "records.profileFacts.correct", - // v1.43 — the profile-facts card became the life-circumstances card, whose - // sections save on their own. - "records.profileFacts.save", - "settings.nightscoutPrivateHost", - "settings.nightscoutPrivateHostHelp", -] as const; - -const NEW_CALL_SITES = { - "src/components/settings/security-section/passkey-list-section.tsx": [ - "settings.passkeyReauth.title", - "settings.passkeyReauth.description", - "settings.passkeyReauth.methodLabel", - "settings.passkeyReauth.methods.password", - "settings.passkeyReauth.methods.totp", - "settings.passkeyReauth.methods.passkey", - "settings.passkeyReauth.methods.webauthn", - "settings.passkeyReauth.currentPassword", - "settings.passkeyReauth.authenticatorCode", - "settings.passkeyReauth.authenticatorPlaceholder", - "settings.passkeyReauth.verifyAndAdd", - ], - "src/components/settings/integrations/nightscout-card.tsx": [ - "settings.nightscoutPrivateOperatorTitle", - "settings.nightscoutPrivateOperatorDescription", - ], - "src/components/settings/import-panel/apple-health-import-card.tsx": [ - "settings.sections.export.import.appleHealth.ecgResult", - ], -} as const; - -type Catalog = Record; - -function readCatalog(locale: (typeof LOCALES)[number]): Catalog { - return JSON.parse( - readFileSync(join(ROOT, "messages", `${locale}.json`), "utf8"), - ) as Catalog; -} - -function resolveLeaf(catalog: Catalog, dottedKey: string): string | undefined { - let value: unknown = catalog; - for (const segment of dottedKey.split(".")) { - if (typeof value !== "object" || value === null || !(segment in value)) { - return undefined; - } - value = (value as Record)[segment]; - } - return typeof value === "string" ? value : undefined; -} - -function placeholders(message: string): string[] { - return [ - ...new Set( - [...message.matchAll(/\{([A-Za-z_][A-Za-z0-9_]*)\b/g)].map( - (match) => match[1], - ), - ), - ].sort(); -} - -describe("v1.34.1 locale reconciliation", () => { - it("wires every newly introduced user-facing state through a literal t() call", () => { - for (const [relativePath, keys] of Object.entries(NEW_CALL_SITES)) { - const source = readFileSync(join(ROOT, relativePath), "utf8"); - for (const key of keys) { - expect(source, `${relativePath} must translate ${key}`).toMatch( - new RegExp(`\\bt\\(\\s*["']${key.replaceAll(".", "\\.")}["']`), - ); - } - } - }); - - it("provides every final contract in all six locales with ICU parity", () => { - const catalogs = Object.fromEntries( - LOCALES.map((locale) => [locale, readCatalog(locale)]), - ) as Record<(typeof LOCALES)[number], Catalog>; - - for (const key of REQUIRED_KEYS) { - const english = resolveLeaf(catalogs.en, key); - expect(english, `messages/en.json is missing ${key}`).toBeTruthy(); - - for (const locale of LOCALES) { - const translated = resolveLeaf(catalogs[locale], key); - expect( - translated, - `messages/${locale}.json is missing ${key}`, - ).toBeTruthy(); - expect( - placeholders(translated ?? ""), - `messages/${locale}.json changed ICU placeholders for ${key}`, - ).toEqual(placeholders(english ?? "")); - } - } - }); - - it("removes only the v1.34.1 copy proven obsolete after final call-site inventory", () => { - for (const locale of LOCALES) { - const catalog = readCatalog(locale); - for (const key of OBSOLETE_KEYS) { - expect( - resolveLeaf(catalog, key), - `messages/${locale}.json still contains obsolete ${key}`, - ).toBeUndefined(); - } - } - - const productionSource = Object.keys(NEW_CALL_SITES) - .map((relativePath) => readFileSync(join(ROOT, relativePath), "utf8")) - .join("\n"); - for (const key of OBSOLETE_KEYS) { - expect(productionSource).not.toContain(`t("${key}")`); - expect(productionSource).not.toContain(`t('${key}')`); - } - }); -}); diff --git a/src/app/medications/__tests__/detail-page-history-surface.test.ts b/src/app/medications/__tests__/detail-page-history-surface.test.ts deleted file mode 100644 index ce95075fd..000000000 --- a/src/app/medications/__tests__/detail-page-history-surface.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * v1.15.18 — the `/medications/[id]` detail page is the tabbed shell. - * - * The page owns auth + the medication read and delegates the rest to - * `` (the tab strip, `?tab=` URL state, the hero - * and the wizard / advanced affordances). Source-level guards (the page - * is a client component with `use()` + hooks, so a full render is - * heavier than the contract warrants): - * - it renders `MedicationDetailTabs` and nothing tab-specific itself; - * - it carries no `TodaysDoseCard` (lives only on the list page); - * - it hosts neither the wizard nor the modal advanced sheet directly - * (those live inside the tab component). - */ - -import { readFileSync } from "node:fs"; -import { join } from "node:path"; -import { describe, expect, it } from "vitest"; - -const source = readFileSync( - join(process.cwd(), "src/app/medications/[id]/page.tsx"), - "utf8", -); - -describe("medication detail page is the tabbed shell (v1.15.18)", () => { - it("delegates to MedicationDetailTabs", () => { - expect(source).toContain("MedicationDetailTabs"); - }); - - it("does not import or render TodaysDoseCard", () => { - expect(source).not.toContain("TodaysDoseCard"); - expect(source).not.toContain("todays-dose-card"); - }); - - it("does not host the wizard or the modal advanced sheet directly", () => { - expect(source).not.toContain("AdvancedSettingsSheet"); - expect(source).not.toContain("MedicationWizardDialog"); - }); -}); diff --git a/src/components/charts/__tests__/health-chart-target-link-removed.test.ts b/src/components/charts/__tests__/health-chart-target-link-removed.test.ts deleted file mode 100644 index ea9102dd0..000000000 --- a/src/components/charts/__tests__/health-chart-target-link-removed.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * v1.16.8 — the in-header "adjust targets" link is gone from the chart - * card. The affordance duplicated the page-level target-adjust control - * in the insights sub-page header (``); the chart - * stays a read surface. Pinned at the source level (same convention as - * the auth-shell hoist contract) so the link doesn't quietly return on - * a future header rework. - */ -import { readFileSync } from "node:fs"; -import { resolve } from "node:path"; - -import { describe, expect, it } from "vitest"; - -import { readSource, readSourceFolder } from "@/__tests__/helpers/source-files"; - -const WEIGHT_PAGE_PATH = resolve( - __dirname, - "../../../app/insights/weight/page.tsx", -); -const BP_PAGE_PATH = resolve( - __dirname, - "../../../app/insights/blood-pressure/page.tsx", -); -const EN_BUNDLE_PATH = resolve(__dirname, "../../../../messages/en.json"); - -describe("v1.16.8 — chart-card target-adjust link removed", () => { - it("ships no targetSettingsHref prop or header link in the chart", () => { - // The component and every part it is built from (header included). - const source = [ - readSource("src/components/charts/health-chart.tsx", "HealthChart"), - ...readSourceFolder("src/components/charts/health-chart", { - floor: 9, - }).map(([, text]) => text), - ].join("\n"); - expect(source).not.toContain("targetSettingsHref"); - expect(source).not.toContain("chart-target-settings-link"); - expect(source).not.toContain("charts.adjustTargets"); - }); - - it("weight and blood-pressure pages no longer pass the link href", () => { - for (const path of [WEIGHT_PAGE_PATH, BP_PAGE_PATH]) { - const source = readFileSync(path, "utf8"); - expect(source).not.toContain("targetSettingsHref"); - } - }); - - it("the orphaned locale key is gone", () => { - const bundle = JSON.parse(readFileSync(EN_BUNDLE_PATH, "utf8")) as { - charts: Record; - }; - expect(bundle.charts.adjustTargets).toBeUndefined(); - }); -}); diff --git a/src/components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts b/src/components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts deleted file mode 100644 index efa37cfba..000000000 --- a/src/components/insights/mood/__tests__/mood-notes-timeline-removed.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { existsSync, readFileSync } from "node:fs"; -import { join } from "node:path"; - -const COMPONENT_DIR = join(__dirname, ".."); -const MOOD_LIST = join(__dirname, "../../../mood/mood-list.tsx"); -/** - * The two modules the mood insights surface is rendered from. The breakdown - * cluster lives behind `next/dynamic` in its own file; both are the surface. - */ -const INSIGHTS_SURFACE_FILES = [ - join(COMPONENT_DIR, "mood-insights-sections.tsx"), - join(COMPONENT_DIR, "mood-insights-breakdowns.tsx"), -]; - -/** - * v1.8.6 — the notes timeline display is removed from the mood insights - * surface (note capture on the form stays). These structural guards keep - * the surface from regressing back to a notes feed and keep long notes - * truncated in the entries table. - */ -describe("mood notes timeline removal", () => { - it("deletes the notes-timeline component file", () => { - expect(existsSync(join(COMPONENT_DIR, "mood-notes-timeline.tsx"))).toBe( - false, - ); - }); - - it("no longer renders the notes timeline from the insights sections", () => { - // Both halves of the surface: the eager module that paints the calendar - // and the assessment, and the deferred module that carries every - // breakdown. A guard reading only one of them would go quiet the moment - // the other grew a notes feed. - for (const file of INSIGHTS_SURFACE_FILES) { - const src = readFileSync(file, "utf8"); - expect(src).not.toContain("MoodNotesTimeline"); - expect(src).not.toContain("notesTimeline"); - expect(src).not.toContain("notesTimelineTitle"); - } - }); - - it("mounts the narrative feed in the insights sections", () => { - // v1.12.7 — the narrative one-liners now ride the merged "What stands out" - // card (`MoodWhatStandsOut`), which renders `MoodNarrativeFeed` internally. - // The structural guard tracks the mount point on the sections surface. - // - // v1.38 — that mount point moved into `mood-insights-breakdowns.tsx` when - // the below-the-fold cluster went behind `next/dynamic`. Read as the union - // of the two files, so the guard asserts the card is mounted SOMEWHERE on - // the surface rather than in one particular file — which is what it was - // always about. - const src = INSIGHTS_SURFACE_FILES.map((f) => readFileSync(f, "utf8")).join( - "\n", - ); - expect(src).toContain("MoodWhatStandsOut"); - expect(src).toContain("MoodInTargetTile"); - }); - - it("renders the narrative feed inside the merged what-stands-out card", () => { - const src = readFileSync( - join(COMPONENT_DIR, "mood-what-stands-out.tsx"), - "utf8", - ); - expect(src).toContain("MoodNarrativeFeed"); - expect(src).toContain("MoodDiscoveredRelations"); - }); -}); - -describe("mood entries table — long-note truncation", () => { - const src = readFileSync(MOOD_LIST, "utf8"); - - it("caps the note column width to prevent horizontal scroll", () => { - expect(src).toContain("max-w-[18rem]"); - }); - - it("clamps the note by default and exposes the full text via the row toggle", () => { - // v1.16.8 — the desktop hover tooltip is replaced by an expandable - // toggle (works on touch, preserves line breaks via pre-wrap). The - // default presentation stays clamped so the table keeps its density. - expect(src).toContain("line-clamp-2"); - expect(src).toContain("mood-note-toggle"); - expect(src).toContain("whitespace-pre-wrap"); - expect(src).not.toContain("TooltipContent"); - }); -}); diff --git a/src/lib/http/retired-routes.ts b/src/lib/http/retired-routes.ts index 22580e55c..d86cd6ccd 100644 --- a/src/lib/http/retired-routes.ts +++ b/src/lib/http/retired-routes.ts @@ -62,8 +62,7 @@ * other twenty-two are admin-console routes, operator diagnostics, aggregators * superseded in place, and the moodLog bridge — surfaces reachable only from * the operator's own browser, which ships with the server and reads no - * contract to find out what it talks to. `moodlog-removal-guard.test.ts` - * separately holds that bridge removed. Every entry after those five was + * contract to find out what it talks to. Every entry after those five was * written by the release that removed the path, which is where a tombstone * belongs. *