-
Notifications
You must be signed in to change notification settings - Fork 0
chore: apply 51278a70d remediations onto origin/main #851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,7 @@ | |
| 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}.`); | ||
|
Check failure on line 20 in tests/audit-navigation-auth-regressions.test.ts
|
||
| } | ||
| return contents.slice(start, end); | ||
| } | ||
|
|
@@ -92,23 +92,21 @@ | |
| it("gates private polling and mutations on local readiness plus authenticated status", () => { | ||
| const privateCapabilityContract = sourceSegment( | ||
| clinicalDashboardSource, | ||
| "const canUsePrivateApis =", | ||
| "// Local/demo guests can read the public library", | ||
| "const canRunSearch =", | ||
| ); | ||
| expect(privateCapabilityContract).toContain("const canUsePrivateApis ="); | ||
| expect(privateCapabilityContract).toContain( | ||
| 'localProjectReady && (localNoAuthMode || localDevCanAttemptPrivateApis || authStatus === "authenticated")', | ||
| 'const canUsePrivateApis = localProjectReady && authStatus === "authenticated";', | ||
| ); | ||
| expect(privateCapabilityContract).not.toMatch(/clientDemoMode/); | ||
| expect(privateCapabilityContract).not.toMatch(/localNoAuth|clientDemoMode/); | ||
|
|
||
| const pollingContract = sourceSegment( | ||
| clinicalDashboardSource, | ||
| "const shouldRefreshWorkState =", | ||
| "const [documentsResponse", | ||
| ); | ||
| expect(pollingContract).toContain( | ||
| "includeAdministrationData && (!administrationDataLoadedRef.current || now >= nextWorkStatePollRef.current)", | ||
| ); | ||
| expect(pollingContract).toContain("(canUsePrivateApis || serverDemoMode)"); | ||
| expect(pollingContract).not.toMatch(/localNoAuth|clientDemoMode/); | ||
|
|
||
| const labelMutationContract = sourceSegment( | ||
| clinicalDashboardSource, | ||
|
|
@@ -125,8 +123,8 @@ | |
| expect(uploadMutationContract).toContain("if (!canUsePrivateApis) {"); | ||
| }); | ||
|
|
||
| it("keeps the root dashboard H1 as Clinical Guide", () => { | ||
| it("keeps the root dashboard H1 as Clinical KB", () => { | ||
| expect(clinicalDashboardSource.match(/<h1\b/g)).toHaveLength(1); | ||
| expect(clinicalDashboardSource).toMatch(/<h1 className="sr-only">\s*Clinical Guide\s*<\/h1>/); | ||
| expect(clinicalDashboardSource).toMatch(/<h1 className="sr-only">\s*Clinical KB\s*<\/h1>/); | ||
|
Check failure on line 128 in tests/audit-navigation-auth-regressions.test.ts
|
||
|
Comment on lines
+126
to
+128
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Reconcile the H1 assertion with This test currently fails because the dashboard source does not match the exact 🧰 Tools🪛 GitHub Check: Unit coverage[failure] 128-128: [node] tests/audit-navigation-auth-regressions.test.ts > audit navigation and auth regressions > keeps the root dashboard H1 as Clinical KB \s*Clinica…/h1>
import { useRouter, useSearchParams } from "next/navigation"; 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -97,6 +97,40 @@ | |
| } | ||
| }); | ||
|
|
||
| it("keeps public redirect handlers in product routes and API handlers in the API section", () => { | ||
| const data = collectSiteMapData(); | ||
| const productSection = siteMap.slice( | ||
| siteMap.indexOf("## Main product routes"), | ||
| siteMap.indexOf("## Mode/query routes"), | ||
| ); | ||
| const apiSection = siteMap.slice(siteMap.indexOf("## API routes"), siteMap.indexOf("## Redirects")); | ||
| const expectedProductHandlers = [ | ||
| ["/applications", "src/app/applications/route.ts", "/tools"], | ||
| [ | ||
| "/differentials/presentations", | ||
| "src/app/differentials/presentations/route.ts", | ||
| "/differentials/presentations/[workflow-slug]", | ||
| ], | ||
| ["/medications", "src/app/medications/route.ts", "/?mode=prescribing"], | ||
| ] as const; | ||
|
|
||
| expect(data.apiRoutes.every((route) => route.route === "/api" || route.route.startsWith("/api/"))).toBe(true); | ||
| expect(data.publicRouteHandlers.some((route) => route.route === "/auth/callback")).toBe(true); | ||
| expect(data.publicRouteHandlers).toContainEqual({ | ||
| route: "/icons/[variant]", | ||
| file: "src/app/icons/[variant]/route.tsx", | ||
| }); | ||
| expect(apiSection).not.toContain("`/icons/[variant]`"); | ||
|
|
||
| for (const [route, file, target] of expectedProductHandlers) { | ||
| expect(data.publicRouteHandlers).toContainEqual({ route, file }); | ||
| expect(data.apiRoutes).not.toContainEqual({ route, file }); | ||
| expect(data.redirects).toContainEqual({ route, file, target }); | ||
| expect(productSection).toContain(`\`${route}\``); | ||
|
Check failure on line 129 in tests/site-map.test.ts
|
||
| expect(apiSection).not.toContain(`\`${route}\``); | ||
|
Comment on lines
+125
to
+130
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Regenerate the checked-in sitemap artifact. The test now requires these public handlers in 🧰 Tools🪛 GitHub Check: Unit coverage[failure] 129-129: [node] tests/site-map.test.ts > tracked sitemap > keeps public redirect handlers in product routes and API handlers in the API section
� 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| } | ||
| }); | ||
|
|
||
| it("documents seeded dynamic slugs", () => { | ||
| for (const service of serviceRecords) expectDocumentedRoute(service.slug); | ||
| for (const form of formRecords) expectDocumentedRoute(form.slug); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Align this source-link contract with the component.
The reported unit test fails because
form-detail-page.tsxdoes not contain the exact conditional required here. Restore the intended component contract or update this assertion to the component’s stable rendered structure; the current PR leaves CI failing.🧰 Tools
🪛 GitHub Check: Unit coverage
[failure] 209-209: [node] tests/audit-content-services-regressions.test.ts > content and services audit regressions > claims and renders a form source link only when the record has a URL
AssertionError: expected '"use client"; import { useRouter } fr…' to contain '{form.source?.url ? "Source link avai…'
@/components/ui-primitives"; import { FormCodeBadge, splitFormCode } from "@/components/forms/form-code-badge"; import { appModeHomeHref } from "@/lib/app-modes"; import { formCatalogDetails, type FormRecord } from "@/lib/form-ranker"; import type { ServiceChipTone, ServiceContact, ServiceCriterion, ServiceSummaryCard } from "@/lib/service-ranker"; import { readSavedRegistrySlugs, savedFormsStorageKey, writeSavedRegistrySlugs } from "@/lib/saved-registry-storage"; const missingText = "Not listed"; function hasText(value: string | null | undefined): value is string { return Boolean(value && value.trim().length > 0); } function displayText(value: string | null | undefined, fallback = missingText) { return hasText(value) ? value.trim() : fallback; } async function copyText(value: string) { if (navigator.clipboard?.writeText) { try { await navigator.clipboard.writeText(value); return; } catch { // Fall through to the legacy selection path for restricted browser contexts. } } const textArea = document.createElement("textarea"); textArea.value = value; textArea.setAttribute("readonly", ""); textArea.style.position = "fixed"; textArea.style.opacity = "0"; document.body.appendChild(textArea); textArea.select(); try { const copied = document.execCommand?.("copy"); if (copied === false) throw new Error("copy command rejected"); } finally { document.body.removeChild(textArea); } } function chipToneClass(tone: ServiceChipTone | null | undefined) { if (tone === "danger") return toneDanger; if (tone === "info") return toneInfo; if (tone === "warning") return toneWarning; if (tone === "success") return toneSuccess; return toneNeutral; } export function sourceToneClass(form: FormRecord) { const status = form.source?.status?.toLowerCase() ?? ""; if (/required|review|unverified|not verified|unchecked|pending|unknown|confirm/.test(status)) return toneWarning; if (form.verification?.locallyVerified === true) return toneSuccess; return toneNeutral; } function formCode(form: FormRecord) { const details = formCatalogDetails(form); if (details?.form) return details.form; if (form.slug.includes("transport")) return "4A"; if (form.slug.includes("capacity")) return "CAP"; if (form.slug.includes("clozapine")) return "CLZ"; if (form.slug.includes("handover")) return "SAFE"; return form.title .split(/\s+/) .map((part) => part[0]) .join("") .slice(0, 4) .toUpperCase(); } function formShortTitle(form: FormRecord) { const details = formCatalogDetails(form); return details?.form ?Form ${details.form}: displayText(form.catalogueLabel, "Form"); } function summaryIcon(card: ServiceSummaryCard) { const label =${card.id} ${card.label} ${card.title}.toLowerCase(); const Icon = label.includes("clock") ? Clock3 : label.includes("destination") || label.includes("place") || label.includes("route") ? MapPin : label.includes("authority") || label.includes("maker") ? UserRound : label.includes("criteria") || label.includes("threshold") ? Scale : ClipboardList; return ; } function summaryCardsFor(form: FormRecord): ServiceSummaryCard[] { if (form.summaryCards?.length) return form.summaryCards.slice(0, 4); return [ { id: "route", label: "Route", title: "Use pathway", detail: form.route }, { id: "eligibility", label: "Eligibility", title: "Patient fi🤖 Prompt for AI Agents
Source: Linters/SAST tools