Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions tests/audit-navigation-auth-regressions.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,20 +7,12 @@ import { describe, expect, it } from "vitest";
import { GET as redirectApplications, HEAD as headApplications } from "@/app/applications/route";
import { resolveDifferentialCompareHandoff } from "@/lib/differentials";
import { legacyHomeRedirectUrl } from "@/lib/legacy-home-redirect";
import { sourceSegment } from "./helpers/source-contract";

function source(relativePath: string) {
return readFileSync(resolve(process.cwd(), relativePath), "utf8");
}

function sourceSegment(contents: string, startMarker: string, endMarker: string) {
const start = contents.indexOf(startMarker);
const end = contents.indexOf(endMarker, start + startMarker.length);
if (start < 0 || end < 0) {
throw new Error(`Could not locate source segment from ${startMarker} to ${endMarker}.`);
}
return contents.slice(start, end);
}

const clinicalDashboardSource = source("src/components/ClinicalDashboard.tsx");
const masterSearchHeaderSource = source("src/components/clinical-dashboard/master-search-header.tsx");
const universalAlsoMatchesSource = source("src/components/clinical-dashboard/universal-search-also-matches.tsx");
Expand DownExpand Up@@ -103,6 +95,7 @@ describe("audit navigation and auth regressions", () => {
masterSearchHeaderSource,
"ref={modeMenuRef}",
'className={cn("relative z-[60]',
{ label: "master mode-menu focus boundary" },
);

expect(focusLeaveContract).toContain("onBlur={(event) => {");
Expand DownExpand Up@@ -135,16 +128,19 @@ describe("audit navigation and auth regressions", () => {
masterSearchHeaderSource,
"function renderModeMenuOption(",
"function renderModeMenuOptions()",
{ label: "mode-menu option prefetch" },
);
const openModeMenuWithFocus = sourceSegment(
masterSearchHeaderSource,
"function openModeMenuWithFocus(",
"function toggleModeMenu(",
{ label: "mode-menu focus-open prefetch" },
);
const toggleModeMenu = sourceSegment(
masterSearchHeaderSource,
"function toggleModeMenu(",
"function handleModeTriggerKeyDown(",
{ label: "mode-menu toggle prefetch" },
);

expect(masterSearchHeaderSource).toContain("function prefetchModeSelection(modeId: AppModeId)");
Expand DownExpand Up@@ -181,6 +177,7 @@ describe("audit navigation and auth regressions", () => {
clinicalDashboardSource,
"const showUniversalAlsoMatches =",
"const showDesktopHomeComposer =",
{ label: "also-matches visibility gate" },
);
expect(alsoMatchesGate).toContain('activeModeResultKind === "tools"');
expect(alsoMatchesGate).toContain('activeModeResultKind === "favourites"');
Expand All@@ -195,6 +192,7 @@ describe("audit navigation and auth regressions", () => {
clinicalDashboardSource,
"const uploadReadOnlyMode =",
"const canUsePrivateApis =",
{ label: "upload read-only capability" },
);
// Uploads stay writable in local no-auth; only explicit demo / auth-unavailable lock them.
expect(uploadReadOnlyContract).toContain("const uploadReadOnlyMode = resolveUploadReadOnlyMode({");
Expand All@@ -209,6 +207,7 @@ describe("audit navigation and auth regressions", () => {
clinicalDashboardSource,
"const canUsePrivateApis =",
"const canRunSearch =",
{ label: "private API capability" },
);
expect(privateCapabilityContract).toContain("const canUsePrivateApis =");
expect(privateCapabilityContract).toContain(
Expand All@@ -219,6 +218,7 @@ describe("audit navigation and auth regressions", () => {
clinicalDashboardSource,
"if (!nextDemoMode && !canUsePrivateApis) {",
"const shouldRefreshWorkState =",
{ label: "private polling capability" },
);
expect(pollingContract).toContain("if (!nextDemoMode && !canUsePrivateApis) {");
expect(pollingContract).toContain("setDocuments([]);");
Expand All@@ -228,13 +228,15 @@ describe("audit navigation and auth regressions", () => {
clinicalDashboardSource,
"const mutateDocumentLabel =",
"const handleDocumentDeleted =",
{ label: "private label mutation" },
);
expect(labelMutationContract).toContain("if (!canUsePrivateApis) return false;");

const uploadMutationContract = sourceSegment(
clinicalDashboardSource,
"function openUploadDrawer()",
"function openEvidenceDrawer()",
{ label: "private upload mutation" },
);
expect(uploadMutationContract).toContain("if (!canUseAdministrativeApis) {");
});
Expand DownExpand Up@@ -266,6 +268,7 @@ describe("audit navigation and auth regressions", () => {
uploadDesktopHookSource,
"export function useUploadDesktopLayout(",
"}",
{ label: "upload desktop layout hook" },
);
expect(useUploadDesktopLayoutBody).toMatch(
/return\s+useSyncExternalStore\(\s*subscribeToUploadDesktopLayout,\s*getUploadDesktopLayoutSnapshot,\s*\(\)\s*=>\s*false\s*\)/,
Expand All@@ -282,15 +285,27 @@ describe("audit navigation and auth regressions", () => {
});

it("leaves favourites universal matches to the favourites hub", () => {
const universalMatchesContract = sourceSegment(
const nonAnswerUniversalMatchesContract = sourceSegment(
clinicalDashboardSource,
"{showUniversalAlsoMatches &&",
"{showUniversalAlsoMatches &&\n (activeModeResultKind",
// The shared home now opens the mode-content chain, ahead of differentials.
"{showSharedHome ?",
{ label: "non-answer also-matches render branch" },
);
const answerUniversalMatchesContract = sourceSegment(
clinicalDashboardSource,
'{showUniversalAlsoMatches && activeModeResultKind === "answer" ? (',
"</section>",
{ label: "answer also-matches render branch" },
);

expect(universalMatchesContract).toContain("<UniversalSearchAlsoMatches modeId={searchMode}");
expect(universalMatchesContract).not.toContain('activeModeResultKind === "favourites"');
// Pin every dashboard-owned also-matches render branch. A third occurrence
// must be classified here rather than silently escaping the negative.
expect(clinicalDashboardSource.match(/\{showUniversalAlsoMatches &&/g)).toHaveLength(2);
for (const contract of [nonAnswerUniversalMatchesContract, answerUniversalMatchesContract]) {
expect(contract).toContain("<UniversalSearchAlsoMatches modeId={searchMode}");
expect(contract).not.toContain('activeModeResultKind === "favourites"');
}
// This test is about WHICH surface owns the favourites also-matches block,
// not about the expression feeding its query prop — that became
// `activeQuery` when the page took over live in-place filtering from the
Expand Down
10 changes: 7 additions & 3 deletions tests/document-section-nav-contract.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,8 @@ import { readFileSync } from "node:fs";

import { describe, expect, it } from "vitest";

import { sourceSegment } from "./helpers/source-contract";

/**
* Cheap wiring contract for document section navigation.
*
Expand DownExpand Up@@ -50,9 +52,11 @@ describe("document section navigation ownership", () => {
});

it("keeps document-viewer ui-smoke on the current phone section chrome", () => {
const documentViewerSmoke = uiSmokeSource.slice(
uiSmokeSource.indexOf('test("document viewer puts the PDF preview first'),
uiSmokeSource.indexOf('test("answer glass header overlays main'),
const documentViewerSmoke = sourceSegment(
uiSmokeSource,
'test("document viewer puts the PDF preview first',
'test("answer glass header overlays main',
{ label: "document viewer phone section smoke" },
);

expect(documentViewerSmoke).toContain('getByTestId("document-section-trigger")');
Expand Down
18 changes: 12 additions & 6 deletions tests/in-page-nav-playwright-contract.test.ts
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";

import { sourceSegment } from "./helpers/source-contract";

/**
* Guards the Production UI failures that blocked PR #1781:
*
Expand All@@ -20,9 +22,11 @@ const IN_PAGE_NAV_HEADER = "src/components/in-page-nav/in-page-nav-header.tsx";
describe("in-page-nav Playwright contract", () => {
it("prescribing smoke asserts the aria-label back name on both desktop and phone", () => {
const source = readFileSync(UI_SMOKE, "utf8");
const prescribingBlock = source.slice(
source.indexOf('test("prescribing workflow uses in-app medication routes'),
source.indexOf('test("tablet document chrome keeps one new-chat action'),
const prescribingBlock = sourceSegment(
source,
'test("prescribing workflow uses in-app medication routes',
'test("tablet document chrome keeps one new-chat action',
{ label: "prescribing smoke" },
);

expect(prescribingBlock).toContain('name: "Back to medications"');
Expand All@@ -36,9 +40,11 @@ describe("in-page-nav Playwright contract", () => {
// Medications exact inside medication-page-*; the back control lives in
// MedicationNavHeader with aria-label "Back to medications".
const source = readFileSync(UI_SMOKE, "utf8");
const quickLinksBlock = source.slice(
source.indexOf('test("answer results surface cross-mode quick links"'),
source.indexOf('test("answer mode keeps prior turns visible for follow-up questions"'),
const quickLinksBlock = sourceSegment(
source,
'test("answer results surface cross-mode quick links"',
'test("answer mode keeps prior turns visible for follow-up questions"',
{ label: "answer cross-mode quick-links smoke" },
);

expect(quickLinksBlock).toContain('name: "Back to medications"');
Expand Down
12 changes: 7 additions & 5 deletions tests/tools-search-directions-mockups.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,7 @@ import { describe, expect, it } from "vitest";
import { submittedToolIdsForMockup } from "../src/components/tools-search-directions-mockups";
import { normalizeSearchText } from "../src/lib/catalog-search";
import { toolCatalogRecords, toolSearchText } from "../src/lib/tools-catalog";
import { sourceSegment } from "./helpers/source-contract";

const source = readFileSync(new URL("../src/components/tools-search-directions-mockups.tsx", import.meta.url), "utf8");

Expand All@@ -23,7 +24,9 @@ describe("tools search direction mockup evidence", () => {
});

it("shows both representative queries at both widths for every direction", () => {
const showcase = source.slice(source.indexOf("function DirectionShowcase"), source.indexOf("const currentDefects"));
const showcase = sourceSegment(source, "function DirectionShowcase", "const currentDefects", {
label: "direction showcase frames",
});
expect(showcase).toContain('<DeviceFrame direction={direction.id} query="monitoring" device="phone" />');
expect(showcase).toContain('<DeviceFrame direction={direction.id} query="compare" device="phone" />');
expect(showcase).toContain('<DeviceFrame direction={direction.id} query="monitoring" device="desktop" />');
Expand All@@ -35,10 +38,9 @@ describe("tools search direction mockup evidence", () => {
});

it("keeps the ranked filter only for multi-match frames at both widths", () => {
const brief = source.slice(
source.indexOf("function BriefDirection"),
source.indexOf("function SegmentedCountBand"),
);
const brief = sourceSegment(source, "function BriefDirection", "function SegmentedCountBand", {
label: "brief direction ranked filter",
});
expect(brief).toContain('device === "desktop" && matches.length > 1');
expect(brief).toContain('device === "phone" && matches.length > 1');
expect(brief).not.toContain('device === "desktop" ? <AreaFilterRow');
Expand Down
Loading