2026-09-18 22:06:14 UTC · branch ? at ? · ran on Mac155.local · triggered by console:Mac155
deployable tree 240e7415da42 · 3,682 files — a deploy is gated on matching this exactly
Pure in-process tests — no database. These use the repo's `_FakeDB` or call functions directly, so they prove logic, not wiring.
Tests that drive the mounted FastAPI app against a real Mongo. These are the ones that prove a route exists, is reachable, and is authorised — the class of defect unit tests have repeatedly passed straight through.
Node's built-in runner over the pure logic extracted into `lib/`. Fast and exhaustive over what it sees; it does not render a component or touch a route.
2,749 tests · 2,749 passed · 29.2 s
Renders real React components and asserts on the produced markup — the tier that can catch a screen that never reaches its data or an overlay that is not a dialog.
Drives a real browser against a running frontend and backend. Opt-in: it needs both servers up, and a tier that cannot reach them is reported as an error, never as a pass.
Three walks of the monitoring script replayed against DEMO in real Chrome with the SAME walks/facts/mask code the nightly production comparison uses. A DOM change that breaks capture fails the gate here, not the night. DEMO only: a write step may execute there and never in production.
The harness's own tests: the report model, the coverage ratchet, the console's queue and session, and the deploy gate. This tier exists because the gate now decides whether a deploy may happen — a broken gate would ship untested code and report success.
ruff, mypy and the TypeScript compiler — findings that need no test to run.
35,384 of 35,648 statements · branches 89.0%. The vertical rule marks the 90% target.
Read this percentage with its scope. This runner measures only the files a test imported — an untested module is absent from the denominator rather than scored 0%, so this number cannot fall when untested code is added. File reach is the honest headline: 196 of 798 source files reached (25%).
No route measurement in this run — the backend tier did not execute, so nothing can be said about which endpoints are exercised.
Each point is one harness run, oldest at the left. Series are direct-labelled, so identity never rests on colour alone.
No test failed and none errored. Note that this is a statement about the tiers that ran — check the tier list above for any marked “could not run”.
| Test | Outcome | Time | Tier |
|---|---|---|---|
| lib/a11y-structure.test.ts::the scan finds the pages — otherwise everything below passes vacuously | passed | 100 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the dashboard offers a skip link to a real target | passed | 2 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the skip link is reachable by keyboard but not visible by default | passed | 1 ms | Frontend · unit |
| lib/a11y-structure.test.ts::every navigation landmark is named | passed | 1 ms | Frontend · unit |
| lib/a11y-structure.test.ts::no page renders a select with neither a label nor an aria-label | passed | 1642 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the unlabelled-select allow-list has no stale entries | passed | 1633 ms | Frontend · unit |
| lib/a11y-structure.test.ts::every select in the app has an accessible name | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the select scanner actually finds selects | passed | 1593 ms | Frontend · unit |
| lib/a11y-structure.test.ts::a rendered failure banner is announced, not just coloured | passed | 1660 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the shared error banner really is an alert, not a polite status | passed | 1 ms | Frontend · unit |
| lib/a11y-structure.test.ts::an error empty state really is an alert, and an ordinary one is not | passed | 1 ms | Frontend · unit |
| lib/a11y-structure.test.ts::no page hangs a click handler on a plain div or span | passed | 1595 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the clickable-non-control list has no stale entries | passed | 1483 ms | Frontend · unit |
| lib/a11y-structure.test.ts::no form control draws its boundary with the decorative border token | passed | 737 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the form-control border scanner actually finds controls | passed | 654 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the comment stripper leaves comment-like text inside strings alone | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the comment stripper removes both comment forms | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the comment stripper keeps a comment marker inside a template literal | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::an escaped quote does not end the string | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::every form control has a programmatic accessible name | passed | 769 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the unnamed-control allow-list has no stale entries | passed | 763 ms | Frontend · unit |
| lib/a11y-structure.test.ts::a placeholder is not accepted as an accessible name | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the control-border guard still catches the decorative token alone | passed | 0 ms | Frontend · unit |
| lib/a11y-structure.test.ts::a repeated row action names the row it acts on | passed | 54 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the bare-row-action allow-list has no stale entries | passed | 54 ms | Frontend · unit |
| lib/a11y-structure.test.ts::the row-action scanner does not flag a table heading | passed | 0 ms | Frontend · unit |
| lib/access-labels.test.ts::every realm has a label | passed | 9 ms | Frontend · unit |
| lib/access-labels.test.ts::no label is blank | passed | 1 ms | Frontend · unit |
| lib/access-labels.test.ts::BREP is named, and named as staff rather than as a patient | passed | 1 ms | Frontend · unit |
| lib/account-kinds.test.ts::the console does not offer to create a platform admin | passed | 7 ms | Frontend · unit |
| lib/account-kinds.test.ts::no option names a raw hanType | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::every option explains what the account can do | passed | 1 ms | Frontend · unit |
| lib/account-kinds.test.ts::email is normalised the same way the server normalises it | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::a clinician account asks for the role that decides billing | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::the form states one reason at a time, in filling order | passed | 1 ms | Frontend · unit |
| lib/account-kinds.test.ts::a kind the console cannot create is refused before it is sent | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::a reused account is never reported as created | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::an account created without its invite says so | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::the happy path is the only outcome that claims the invite went | passed | 6 ms | Frontend · unit |
| lib/account-kinds.test.ts::a response that created nothing is not dressed up as progress | passed | 0 ms | Frontend · unit |
| lib/account-kinds.test.ts::kindLabel never renders an internal token to a user | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::every spelling of an account type resolves the same way | passed | 11 ms | Frontend · unit |
| lib/account-type.test.ts::an unrecognised code holds nothing rather than the nearest match | passed | 1 ms | Frontend · unit |
| lib/account-type.test.ts::a session carrying only `role` is still recognised | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::hanType wins when both claims are present | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::staff are not owners and the owner-only nav stays hidden | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::globalAdmin grants business administration but not the platform | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::a patient holds nothing | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::the client and server capability tables agree on the shape | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::BM is a managed business, not a business owner | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::QA 26_8_14 §1.1: reading the money is a separate capability | passed | 1 ms | Frontend · unit |
| lib/account-type.test.ts::a practice's own admin reads its money; a Medical Assistant does not | passed | 0 ms | Frontend · unit |
| lib/account-type.test.ts::money is held by the finance JOBS, whatever the account type (2026-09-10) | passed | 1 ms | Frontend · unit |
| lib/account-type.test.ts::a managed business is never handed the operator's takings | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::severity dialects collapse onto one scale, critical included | passed | 7 ms | Frontend · unit |
| lib/action-center.test.ts::severity always carries a text label, never colour alone | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::needs-action-now is a UNION of urgent and overdue, not an intersection | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::needs-action-now is zero on an empty queue | passed | 3 ms | Frontend · unit |
| lib/action-center.test.ts::relative time reads forwards and backwards | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::overdue label appears only when actually overdue | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::an empty filter means no restriction, NOT match-nothing | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::source, severity and kind chips narrow | passed | 2 ms | Frontend · unit |
| lib/action-center.test.ts::only-drafts and only-overdue narrow | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::search matches patient, clinic, counterparty and doctor, case-insensitively | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::filters combine as AND | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::toggle adds then removes | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::grouping by patient keeps the server's order and rolls up the worst severity | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::items with no patient never merge into one anonymous group | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::group summaries pluralise like a person would | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::no source or kind is rendered as a raw slug | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::a reading renders as a clinician would say it, and nothing is invented | passed | 1 ms | Frontend · unit |
| lib/action-center.test.ts::an unconfigured channel is stated as OFF, in words | passed | 4 ms | Frontend · unit |
| lib/action-center.test.ts::a configured channel shows its recipients or model | passed | 0 ms | Frontend · unit |
| lib/action-center.test.ts::degraded is true when any channel is off and false when all are on | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::an address is required, and so is a branch | passed | 7 ms | Frontend · unit |
| lib/affiliation.test.ts::a malformed address is refused before the round-trip | passed | 1 ms | Frontend · unit |
| lib/affiliation.test.ts::a well-formed invitation passes | passed | 1 ms | Frontend · unit |
| lib/affiliation.test.ts::addresses are normalised so one person is one affiliation | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::an existing affiliation at ANOTHER branch does not block this one | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::re-inviting somebody with a pending invitation is allowed and recognised | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::a pending invitation is never counted as a provider | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::removing an accepted affiliation and revoking an invitation are different acts | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::the empty state says what would fill it, and counts what is waiting | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::a successful send is reported as sent | passed | 2 ms | Frontend · unit |
| lib/affiliation.test.ts::a stored-but-unsent invitation says so, and says why | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::an unsent invitation is a warning, not an error | passed | 1 ms | Frontend · unit |
| lib/affiliation.test.ts::the non-production link is surfaced either way | passed | 0 ms | Frontend · unit |
| lib/affiliation.test.ts::a missing response is treated as not sent | passed | 0 ms | Frontend · unit |
| lib/after-write.test.ts::a scope nobody wrote to does not ask for a refetch | passed | 5 ms | Frontend · unit |
| lib/after-write.test.ts::a write is seen once by the reader that comes back | passed | 2 ms | Frontend · unit |
| lib/after-write.test.ts::a mark is CONSUMED — one write, one refetch | passed | 1 ms | Frontend · unit |
| lib/after-write.test.ts::scopes do not leak into one another | passed | 1 ms | Frontend · unit |
| lib/after-write.test.ts::several writes before one return still cost one refetch | passed | 0 ms | Frontend · unit |
| lib/after-write.test.ts::isWritten reports without taking | passed | 0 ms | Frontend · unit |
| lib/after-write.test.ts::it needs no browser storage at all | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::alerts and escalations are counted separately | passed | 11 ms | Frontend · unit |
| lib/alert-metrics.test.ts::an escalation is counted from either producer | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::patient counts are the caseload, not the volume | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::alerts outside the month are excluded | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::a branch filter narrows the report | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::addressed and unaddressed always sum to the total | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::the report names who to look at, worst first | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::an empty month reports zeros rather than blanks | passed | 3 ms | Frontend · unit |
| lib/alert-metrics.test.ts::monthKey and monthBounds round-trip | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::the CSV quotes anything that could break a column | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::the CSV states the ladder breakdown, not just a total | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::a reading with no breach gets no highlight at all | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::a critical breach is red and says so in words | passed | 1 ms | Frontend · unit |
| lib/alert-metrics.test.ts::low and high are distinguished by words, not by shade | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::every tone carries a text label and a description | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::the severity vocabularies from the different ingest paths all normalise | passed | 0 ms | Frontend · unit |
| lib/alert-metrics.test.ts::direction comes from the rule relation, and MAX wins a mixed breach | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule is identified by ruleId, which is what 608 of 616 rows carry | passed | 6 ms | Frontend · unit |
| lib/alert-rule.test.ts::a legacy row keyed on readRuleId is still reachable | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule with no id at all yields an empty string, never 'undefined' | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::blank and whitespace ids do not count as an identity | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule matches under either field | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule with no threshold is refused — it could never fire | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule needs a name | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::a slipped decimal point is refused rather than saved | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::an upper limit below its lower limit is refused | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a valid rule passes | passed | 2 ms | Frontend · unit |
| lib/alert-rule.test.ts::only the thresholds actually set are stored | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a form with nothing set stores nothing, rather than a zero | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::Edit opens on what is actually stored | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a round trip through the form does not lose a threshold | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::each metric offers its own thresholds and no others | passed | 0 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule with no thresholds describes itself as unable to fire | passed | 1 ms | Frontend · unit |
| lib/alert-rule.test.ts::a rule describes its thresholds in words | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::the patient scope is read from the query string | passed | 4 ms | Frontend · unit |
| lib/alerts-scope.test.ts::an encoded patient id round-trips | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::scoping keeps only that patient's alerts | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::both id fields are matched, because the two producers disagree | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::no scope means no filtering at all | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::the banner names the patient, falling back to a readable id | passed | 1 ms | Frontend · unit |
| lib/alerts-scope.test.ts::clearing the scope preserves the rest of the query state | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::patient ids render readably | passed | 0 ms | Frontend · unit |
| lib/alerts-scope.test.ts::the empty state says which question it is answering | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::searchSections: an empty query returns every section in menu order | passed | 9 ms | Frontend · unit |
| lib/app-tour.test.ts::searchSections: a section is found through one of its screens | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::searchSections: every word must match, in any order and case | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::matchingScreens: narrows to the matching screens | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::matchingScreens: a section matched on its own text still shows its screens | passed | 0 ms | Frontend · unit |
| lib/app-tour.test.ts::sectionForHref: finds the section holding a screen, ignoring the query string | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::hiddenMoneyNote: a count and a reason, and nothing when there are none | passed | 1 ms | Frontend · unit |
| lib/app-tour.test.ts::initialApp: the caller's own app when the server sent it, else the first | passed | 0 ms | Frontend · unit |
| lib/app-tour.test.ts::screenCount and mediaLength read naturally | passed | 0 ms | Frontend · unit |
| lib/assign-outcome.test.ts::Liv Jones's reply is a FAILURE: nothing written, stay on the form | passed | 4 ms | Frontend · unit |
| lib/assign-outcome.test.ts::the refusal names the patient and the person — never a raw id | passed | 1 ms | Frontend · unit |
| lib/assign-outcome.test.ts::an unknown staff id is described, not printed | passed | 0 ms | Frontend · unit |
| lib/assign-outcome.test.ts::consent pending is said in words | passed | 0 ms | Frontend · unit |
| lib/assign-outcome.test.ts::every patient assigned: success, refetch, leave | passed | 6 ms | Frontend · unit |
| lib/assign-outcome.test.ts::some assigned: the listing must refetch, but the form stays | passed | 2 ms | Frontend · unit |
| lib/assign-outcome.test.ts::an unreadable reply is not a yes | passed | 1 ms | Frontend · unit |
| lib/assign-outcome.test.ts::fewer assigned than asked, with no error named, is still not a clean success | passed | 0 ms | Frontend · unit |
| lib/assign-outcome.test.ts::the care-plan page reads the reply before it leaves or claims success | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::the scope is always stated in words | passed | 5 ms | Frontend · unit |
| lib/audit.test.ts::an unrecognised scope is reported as incomplete, not as everything | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::the actor is named, never rendered as a raw id | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::an account with no handle says so rather than showing its id | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::an anonymous request is labelled as such, not as a missing name | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::the id is still available as secondary detail | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::a failed sign-in is severity refused even when the outcome says otherwise | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::severity always has text, never colour alone | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::a refusal reason is translated into words a person can act on | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::an unknown reason code is shown rather than hidden | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::the attempted login is surfaced — on a failure it is the only identity | passed | 1 ms | Frontend · unit |
| lib/audit.test.ts::the endpoint is grouped by route template, not by concrete path | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::actions are labelled in plain language | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::an unmapped action shows its own name rather than a blank | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::no offered window exceeds what the server will honour | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::an unknown window key falls back to a stated default, not to zero | passed | 0 ms | Frontend · unit |
| lib/audit.test.ts::the ISO instant is available for reconciling with a server log | passed | 6 ms | Frontend · unit |
| lib/automation-audit.test.ts::modeTone / modeLabel map the three modes | passed | 3 ms | Frontend · unit |
| lib/automation-audit.test.ts::groupByArea preserves area order and groups items | passed | 3 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the vocabulary comes from the server and an unknown kind is SHOWN | passed | 4 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a vocabulary the server does not send falls back to the known order | passed | 3 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the server's order is respected — a kind it omits is not drawn | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::age is the only urgency signal, and a missing stamp is not 'today' | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::waiting reads in the unit a person thinks in | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the window prints what it is NOT showing | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the backlog view says so instead of naming a period | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the money line says the money has not LEFT, not that it is unpaid | passed | 45 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a claim with no amount is counted apart, never folded in as zero | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a caller who may not see money gets the claim count and no dollar | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::no claims means no money sentence at all | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::the empty state comes from the record, never from the row count | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a flat cleared line says WHICH kind of flat it is | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::every item kind has a title, a verb and a label | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::an unknown kind still renders rather than vanishing | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a billing item's summary carries the amount, the route and the codes | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a summary is never mistaken for the message | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a chart series is drawn for every category, colour and all | passed | 1 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::a category with no colour still gets one rather than disappearing | passed | 0 ms | Frontend · unit |
| lib/autopilot-drafts.test.ts::money formats to two places with thousands separators | passed | 1 ms | Frontend · unit |
| lib/batch-approval.test.ts::agrees with the server about what may be batched | passed | 12 ms | Frontend · unit |
| lib/batch-approval.test.ts::never batches a patient-facing kind | passed | 0 ms | Frontend · unit |
| lib/batch-approval.test.ts::fails closed on a kind nobody has classified | passed | 1 ms | Frontend · unit |
| lib/batch-approval.test.ts::every excluded kind gives the operator a reason | passed | 0 ms | Frontend · unit |
| lib/batch-approval.test.ts::a partial failure is never summarised as a success | passed | 1 ms | Frontend · unit |
| lib/batch-approval.test.ts::a clean batch reads as a clean batch | passed | 0 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::names the person and why they qualify | passed | 2 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::never renders an identifier as the name | passed | 1 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::says when choosing this person will create an account | passed | 1 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::submits the value the server gave, untouched | passed | 0 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::shows the server's reason and never composes its own | passed | 1 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::shows nothing once there is something to choose | passed | 0 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::keeps the two pickers' reasons apart | passed | 0 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::is detected rather than silently rendering blank | passed | 2 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::accepts a value that matches by either id | passed | 2 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::treats nobody-chosen as legitimate | passed | 0 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::offers nobody before the roster has loaded | passed | 6 ms | Frontend · unit |
| lib/bhi-care-team.test.ts::carries no reason until the server gives one | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::the id shapes this platform actually produces are recognised as ids | passed | 4 ms | Frontend · unit |
| lib/bhi-grid.test.ts::real names are not mistaken for ids | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::a patient with no resolvable name is labelled, never rendered as an id | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::a resolved name is shown as-is | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::the care team lists names and drops anything id-shaped | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::diagnosis falls back to the bare code, because a code IS the clinical fact | passed | 3 ms | Frontend · unit |
| lib/bhi-grid.test.ts::branch options come from the rows, named, de-duplicated and sorted | passed | 40 ms | Frontend · unit |
| lib/bhi-grid.test.ts::a branch with no name says so rather than showing a bare id | passed | 1 ms | Frontend · unit |
| lib/bhi-grid.test.ts::filtering by branch excludes other branches | passed | 1 ms | Frontend · unit |
| lib/bhi-grid.test.ts::the assessment filter separates assessed from not-yet-assessed | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::search matches the things a human knows | passed | 1 ms | Frontend · unit |
| lib/bhi-grid.test.ts::search does NOT match the internal id | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::the ended tab shows exactly what the active tab does not | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::a care-teamed patient with no enrolment gets its own bucket | passed | 1 ms | Frontend · unit |
| lib/bhi-grid.test.ts::an awaiting patient is on NEITHER the active nor the ended tab | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::pending is recognised from the flag as well as the status | passed | 0 ms | Frontend · unit |
| lib/bhi-grid.test.ts::an awaiting patient is still searchable and still branch-filtered | passed | 0 ms | Frontend · unit |
| lib/bhi-triage.test.ts::a missing score is distinguished from a score of zero | passed | 6 ms | Frontend · unit |
| lib/bhi-triage.test.ts::tier tones follow the urgency order and never collapse safety into info | passed | 1 ms | Frontend · unit |
| lib/bhi-triage.test.ts::changeFromBaseline reports improvement as negative, and refuses to guess | passed | 0 ms | Frontend · unit |
| lib/bhi-triage.test.ts::trendText spells out the direction rather than relying on a sign | passed | 0 ms | Frontend · unit |
| lib/bhi-triage.test.ts::daysSince and agoText treat 'never' as never, not as today | passed | 0 ms | Frontend · unit |
| lib/bhi-triage.test.ts::rowsInTier defaults an unranked row to steady rather than dropping it | passed | 3 ms | Frontend · unit |
| lib/bhi-triage.test.ts::headline says an empty caseload is empty instead of rendering nothing | passed | 1 ms | Frontend · unit |
| lib/billing-nav.test.ts::the account QA reported is offered neither money screen | passed | 8 ms | Frontend · unit |
| lib/billing-nav.test.ts::a biller works billing AND reads the money (2026-09-10) | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a business account with no finance job is offered neither (2026-09-10) | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a job that is not a finance job sees no money, whatever else it does | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::every module but the books (2026-09-12): the revenue cycle opens, the books do not | passed | 1 ms | Frontend · unit |
| lib/billing-nav.test.ts::the books go to the jobs that hold books:read, and a revocation outranks them | passed | 1 ms | Frontend · unit |
| lib/billing-nav.test.ts::the admin tiers and the practice RCM desk read the money; the practice manager does not | passed | 6 ms | Frontend · unit |
| lib/billing-nav.test.ts::a revoked capability wins over the job that would grant it | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a patient is offered nothing | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::an absent session is refused rather than defaulted open | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::longest prefix wins, so revenue-charts is decided by its own rule | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a non-money screen is never hidden by this filter | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a section emptied by the filter is dropped, not left as a bare heading | passed | 1 ms | Frontend · unit |
| lib/billing-nav.test.ts::the filter keeps what it is entitled to keep | passed | 2 ms | Frontend · unit |
| lib/billing-nav.test.ts::a Monitoring Specialist is offered none of the money screens | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::an RCM Biller is offered every money screen | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a patient keeps their OWN bills, and only those | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::the patient exception is for patients — staff do not inherit it | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a doctor with no finance job loses the practice-money screens | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::a Bookkeeper is offered the books (the owner-only rule hid it from them) | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::the count-only ops screens stay offered — the server redacts their dollars | passed | 0 ms | Frontend · unit |
| lib/billing-nav.test.ts::'Everything else' loses the money screens too | passed | 7 ms | Frontend · unit |
| lib/billing-nav.test.ts::nav-resolved applies the money filter AFTER the workspace | passed | 2 ms | Frontend · unit |
| lib/billing-nav.test.ts::the mirrored role names are the ones the server grants rcm: keys to | passed | 1 ms | Frontend · unit |
| lib/billing-nav.test.ts::HR & Payroll opens payroll and nothing else in the books (2026-09-10) | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::a branch with billing providers lists them | passed | 9 ms | Frontend · unit |
| lib/billing-provider.test.ts::the row states why it qualifies | passed | 1 ms | Frontend · unit |
| lib/billing-provider.test.ts::a row from an older backend says what it knows, not more | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::no providers and no billable providers are different states | passed | 1 ms | Frontend · unit |
| lib/billing-provider.test.ts::an empty branch offers no busywork | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::a gap always carries the action that closes it | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::a mixed branch reports both counts | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::singular and plural both read correctly | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::billable requires BOTH an NPI and a taxonomy | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::undefined from the server is not a crash | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::clinical staff are never described as providers | passed | 1 ms | Frontend · unit |
| lib/billing-provider.test.ts::an employed clinician who may render is surfaced, not hidden | passed | 0 ms | Frontend · unit |
| lib/billing-provider.test.ts::a provider row states either its basis or its gap, never nothing | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::has the same statuses and the same successors | passed | 8 ms | Frontend · unit |
| lib/billing-send.test.ts::never lets a draft jump straight to approved | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::always allows a batch to be walked back | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::never applies the numbers gate to a withdrawal | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::treats a sent batch as final | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::refuses Mark ready with the server's own reason | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::does not invent a verdict the server never sent | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::still refuses an impossible move even without a verdict | passed | 2 ms | Frontend · unit |
| lib/billing-send.test.ts::offers Mark ready once the numbers hold up | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::does not block on a warning | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::is available on an empty draft — the case QA reported | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::is available in every workflow state | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::is unavailable only when nothing was ever generated | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::shows the name when there is one | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::marks a row whose stored name IS its id — the reported defect | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::marks a row the server could not resolve at all | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::never returns the bare id, which would read as a name | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::orders short-month tiers beside the full ones | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::is empty for a month with nothing billable | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::does not silently drop a code it has never heard of | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::distinguishes the two numbers, so 0 of 41 is legible | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::says so plainly when nothing is billable | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::counts the audit rows separately from the billable ones | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::says nothing about audit rows when there are none | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::offers delete for a month nobody signed off | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::refuses every signed-off month and names the alternative | passed | 3 ms | Frontend · unit |
| lib/billing-send.test.ts::reads the history, not just today's status | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::prefers the server's own verdict over the local derivation | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::treats archived as a shelf, not a status | passed | 0 ms | Frontend · unit |
| lib/billing-send.test.ts::names what a delete destroys instead of asking 'are you sure?' | passed | 1 ms | Frontend · unit |
| lib/billing-send.test.ts::keeps the delete rule the same rule the route applies | passed | 2 ms | Frontend · unit |
| lib/books-invoices.test.ts::the All filter is a non-empty key, because useFetch skips an empty one | passed | 2 ms | Frontend · unit |
| lib/books-invoices.test.ts::the page keys its list fetch on listKey, never on the raw filter | passed | 2 ms | Frontend · unit |
| lib/books-invoices.test.ts::a draft can only be approved | passed | 3 ms | Frontend · unit |
| lib/books-invoices.test.ts::an approved invoice can go back, out, be paid or be voided | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::a sent invoice with a payment can no longer be voided | passed | 1 ms | Frontend · unit |
| lib/books-invoices.test.ts::a caller is offered only what their job may do | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::paid and void offer nothing | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::every status has a label | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::say overdue, today, or due in | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::says nothing is outstanding when nothing is | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::names the overdue share | passed | 55 ms | Frontend · unit |
| lib/books-invoices.test.ts::parses code, state and realmId | passed | 1 ms | Frontend · unit |
| lib/books-invoices.test.ts::names what did not arrive | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::reads a decline as a decline | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::unconfigured first | passed | 1 ms | Frontend · unit |
| lib/books-invoices.test.ts::then the missing key at rest | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::then not connected, then connected with the company name | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::counts days | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::summarise a run | passed | 15 ms | Frontend · unit |
| lib/books-invoices.test.ts::normalise or refuse | passed | 1 ms | Frontend · unit |
| lib/books-invoices.test.ts::shows the practice's name, never its key | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::starts on a customer only when a person already tied it to this practice | passed | 1 ms | Frontend · unit |
| lib/books-invoices.test.ts::lists the closest name first but does not pick it | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::does not offer another practice's customer, and says how many it left out | passed | 0 ms | Frontend · unit |
| lib/books-invoices.test.ts::the page puts the practice on the candidate row and builds the picker from raiseChoice | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::formats cents with sign and padding | passed | 64 ms | Frontend · unit |
| lib/books.test.ts::parses dollar strings a human would actually type | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::refuses what it cannot read instead of posting a zero | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::refuses a third decimal rather than rounding for the user | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::adds cents where floats would drift | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::recognises a balanced entry | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::a single line is not double entry | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::reports the imbalance rather than hiding it | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::splits a draft into debit and credit totals | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::a complete balanced entry has nothing blocking it | passed | 3 ms | Frontend · unit |
| lib/books.test.ts::names a missing date and memo | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::says by how much an entry is out | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::flags a zero line | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::needs two usable lines | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::resolves a month to its first and last day, leap years included | passed | 4 ms | Frontend · unit |
| lib/books.test.ts::rejects a month that is not one | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::rolls back over a year boundary | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::parses rows and skips a header | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::reports the line number of a row it cannot read, and does not drop it silently | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::rejects a zero-amount row | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::says so when there is nothing to import | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::honours quoted commas in a description | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::handles an escaped quote | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::grades match confidence | passed | 0 ms | Frontend · unit |
| lib/books.test.ts::an empty account is never reported as fully reconciled | passed | 1 ms | Frontend · unit |
| lib/books.test.ts::counts what is left | passed | 0 ms | Frontend · unit |
| lib/branch-access.test.ts::a missing branchAccess block is reported, never rendered as 'none' | passed | 4 ms | Frontend · unit |
| lib/branch-access.test.ts::the badge names the clearance level, not a clinic count, when unrestricted | passed | 1 ms | Frontend · unit |
| lib/branch-access.test.ts::a confined login's badge counts the clinics it is confined to | passed | 0 ms | Frontend · unit |
| lib/branch-access.test.ts::unassigned is stated as unassigned — QA's literal question | passed | 0 ms | Frontend · unit |
| lib/branch-access.test.ts::assigned-and-confined is a different sentence from assigned-and-not | passed | 0 ms | Frontend · unit |
| lib/branch-access.test.ts::a patient is told clinic assignments do not apply, not that they have none | passed | 4 ms | Frontend · unit |
| lib/branch-access.test.ts::the server's own sentences are passed through, never rewritten | passed | 1 ms | Frontend · unit |
| lib/branch-access.test.ts::a clinic that arrives nameless is labelled, never shown as its id | passed | 1 ms | Frontend · unit |
| lib/branch-access.test.ts::a malformed clinic row cannot crash the panel | passed | 3 ms | Frontend · unit |
| lib/branch-filter.test.ts::the global option comes first and is the empty value | passed | 4 ms | Frontend · unit |
| lib/branch-filter.test.ts::the global label is the same string everywhere | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::archived branches are never offered | passed | 12 ms | Frontend · unit |
| lib/branch-filter.test.ts::same-named branches are disambiguated, not collapsed | passed | 43 ms | Frontend · unit |
| lib/branch-filter.test.ts::a branch with no name falls back to its id, never to blank | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::options are sorted so the list is scannable | passed | 1 ms | Frontend · unit |
| lib/branch-filter.test.ts::an empty branch list yields just the global option | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::global matches every row; a branch matches only its own | passed | 1 ms | Frontend · unit |
| lib/branch-filter.test.ts::a row with no branch is excluded by a specific branch filter | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::shortId is stable and short enough to read | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::an empty branch list explains itself instead of rendering nothing | passed | 1 ms | Frontend · unit |
| lib/branch-filter.test.ts::same-named branches are told apart by CITY, not by an id suffix | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::the id suffix survives where the city cannot disambiguate | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::a city is read from either shape the record carries it in | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::a unique name is never decorated | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::duplicate names are reported so a human can resolve them | passed | 1 ms | Frontend · unit |
| lib/branch-filter.test.ts::an archived branch is not counted as a duplicate | passed | 0 ms | Frontend · unit |
| lib/branch-filter.test.ts::branches with no name at all are not reported as duplicates of each other | passed | 0 ms | Frontend · unit |
| lib/branch-scope.test.ts::the branch list DEFAULTS to every store | passed | 21 ms | Frontend · unit |
| lib/branch-scope.test.ts::the Branches screen asks for `unmanaged` | passed | 1 ms | Frontend · unit |
| lib/branch-scope.test.ts::no OTHER screen narrows the branch list | passed | 242 ms | Frontend · unit |
| lib/branch-scope.test.ts::the guard reads the real files | passed | 80 ms | Frontend · unit |
| lib/branch-scope.test.ts::the Branches screen asks the programmes card for branches only | passed | 1 ms | Frontend · unit |
| lib/branch-scope.test.ts::the Client Practices screen asks for managed businesses only | passed | 6 ms | Frontend · unit |
| lib/branch-scope.test.ts::the Client Practices screen does not carry a second list of every clinic | passed | 1 ms | Frontend · unit |
| lib/branch-scope.test.ts::no screen mounts the programmes card without saying which store | passed | 323 ms | Frontend · unit |
| lib/branch-scope.test.ts::the programmes card keeps `scope` required | passed | 2 ms | Frontend · unit |
| lib/business-context.test.ts::no context means no header — an ordinary request is unchanged | passed | 13 ms | Frontend · unit |
| lib/business-context.test.ts::entering a business sends its branch id on every call | passed | 1 ms | Frontend · unit |
| lib/business-context.test.ts::leaving clears it | passed | 1 ms | Frontend · unit |
| lib/business-context.test.ts::a context set by one user does NOT scope another user's session | passed | 0 ms | Frontend · unit |
| lib/business-context.test.ts::corrupt or truncated storage is treated as no context, never as a crash | passed | 1 ms | Frontend · unit |
| lib/business-context.test.ts::a context with no stored name falls back to the id rather than blank | passed | 0 ms | Frontend · unit |
| lib/business-context.test.ts::the banner never claims the operator IS the clinic | passed | 1 ms | Frontend · unit |
| lib/business-context.test.ts::with no context the banner renders nothing at all | passed | 0 ms | Frontend · unit |
| lib/business-context.test.ts::the header name matches the one the server reads | passed | 2 ms | Frontend · unit |
| lib/call-list.test.ts::dormant and at-risk are the bands that read as urgent | passed | 4 ms | Frontend · unit |
| lib/call-list.test.ts::a clinic never called says so rather than rendering a dash | passed | 0 ms | Frontend · unit |
| lib/call-list.test.ts::last-called wording is relative and plain | passed | 0 ms | Frontend · unit |
| lib/call-list.test.ts::an overdue next-call says how overdue | passed | 0 ms | Frontend · unit |
| lib/call-list.test.ts::filter matches contact names and talking points, not just the clinic | passed | 1 ms | Frontend · unit |
| lib/call-list.test.ts::filter ANDs terms so two words narrow rather than widen | passed | 0 ms | Frontend · unit |
| lib/call-list.test.ts::tel href strips formatting so the click actually dials | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::consent item is a communication gate | passed | 4 ms | Frontend · unit |
| lib/care-autopilot.test.ts::careplan item is a clinical gate with a friendly plan label | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::ops_comm surfaces the cadence label + subject | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::monitoring escalation shows severity + reading type | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::recruit is a communication invite | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::careteam item is a clinical one-click team assignment (P1) | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::adherence nudge is a communication item (P2) | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::BHI screening is a communication item (Phase B) | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::billing item summarizes plan/month/codes/route and sits in the billing gate | passed | 1 ms | Frontend · unit |
| lib/care-autopilot.test.ts::route + adapter labels are human-readable | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::planLabel humanizes the combined plan | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::gateOf prefers the backend-stamped gate | passed | 0 ms | Frontend · unit |
| lib/care-autopilot.test.ts::splitByGate routes items into three columns (incl. careteam + adherence) | passed | 3 ms | Frontend · unit |
| lib/care-autopilot.test.ts::level helpers describe the manual→autopilot ramp | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::an ineligible clinician is listed and disabled, never hidden | passed | 5 ms | Frontend · unit |
| lib/care-ownership.test.ts::an eligible clinician is selectable and carries no warning | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::the owner list has no credential gate — that is why the role exists | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::no eligible supervisor anywhere is a different problem from none assigned | passed | 4 ms | Frontend · unit |
| lib/care-ownership.test.ts::billable says so plainly | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::not billable always carries the next step | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::a missing billing payload is treated as not billable, not as billable | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::escalation always names somebody, or says plainly that nobody is named | passed | 1 ms | Frontend · unit |
| lib/care-ownership.test.ts::a fallback to the supervisor SAYS it is a fallback | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::an unknown repId still renders — the id beats a blank line | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::assigning one role does not clear the other | passed | 3 ms | Frontend · unit |
| lib/care-ownership.test.ts::clearing a role is expressible, and distinct from not touching it | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::both roles can be set in one call | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::an automatic assignment never reads as a clinician's decision | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::with nobody assigned, it names who will be taken | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::with nobody eligible, it carries the reason and not just the absence | passed | 3 ms | Frontend · unit |
| lib/care-ownership.test.ts::with several eligible, nothing is assigned and it says why | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::the Care Plan line names the person, never the id | passed | 1 ms | Frontend · unit |
| lib/care-ownership.test.ts::the Care Plan line says an unbillable month is unbillable | passed | 0 ms | Frontend · unit |
| lib/care-ownership.test.ts::an unresolvable name says so rather than falling back to the id | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::roleOptions filters the provisioned roster by role, case-insensitively | passed | 5 ms | Frontend · unit |
| lib/care-team-options.test.ts::a saved member missing from the roster is KEPT, not dropped | passed | 1 ms | Frontend · unit |
| lib/care-team-options.test.ts::a saved member still on the roster is not duplicated or flagged | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::an unknown saved id still renders rather than disappearing | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::stale options say why they are unusual | passed | 1 ms | Frontend · unit |
| lib/care-team-options.test.ts::seedFromRows rehydrates a single saved plan | passed | 3 ms | Frontend · unit |
| lib/care-team-options.test.ts::bulk edit seeds only the fields every selected row agrees on | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::conflicting care plans leave the plan unset rather than guessing | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::an unprovisioned branch offers NO ONE — no corp-staff fallback | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::the hard block does not erase an assignment already on the record | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::seedFromRows tolerates empty input and missing team | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::staleAssignments names the roles the roster can no longer supply | passed | 1 ms | Frontend · unit |
| lib/care-team-options.test.ts::a legacy-worded physician is offered for Doctor, matched on the role KEY | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::without the key the legacy wording still finds nobody — that WAS the bug | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::the key never widens a role — a support specialist is not a doctor | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::a member with no roleKeys still matches on the recorded text | passed | 0 ms | Frontend · unit |
| lib/care-team-options.test.ts::an empty roleKey argument does not match a member with no keys | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::offers only that clinic's physician | passed | 5 ms | Frontend · unit |
| lib/care-team-scope.test.ts::unions a person's roles across the teams they sit on | passed | 1 ms | Frontend · unit |
| lib/care-team-scope.test.ts::an empty answer is empty, never the whole practice | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::offers nothing at all | passed | 1 ms | Frontend · unit |
| lib/care-team-scope.test.ts::says which patient and what to do, rather than widening | passed | 1 ms | Frontend · unit |
| lib/care-team-scope.test.ts::one clinic-less patient blocks a whole bulk selection | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::names the clinic the list came from | passed | 1 ms | Frontend · unit |
| lib/care-team-scope.test.ts::counts them when a bulk selection spans clinics, and warns | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::says nothing when there is nothing to say | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::reports ids that resolved to no patient | passed | 0 ms | Frontend · unit |
| lib/care-team-scope.test.ts::a failed fetch offers nothing rather than falling back | passed | 0 ms | Frontend · unit |
| lib/care-time-history.test.ts::this screen defaults to the clinic month, and the URL round-trips it | passed | 18 ms | Frontend · unit |
| lib/care-time-history.test.ts::the heading prefers the server's label because only it knows the clinic's month | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::the sentence says WHICH timestamp the window was answered on | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::the tiles answer the practice manager's question: who is still under 20 with days left | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::the month sentence and the under-20 worklist | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::bands keep their order and colour on every chart | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::an activity keeps one colour; an unknown one takes the next slot, deterministically | passed | 3 ms | Frontend · unit |
| lib/care-time-history.test.ts::rank rows become a bar chart, top N by minutes | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::a row is shown at the server's clinic-zone instant, falling back to the object | passed | 3 ms | Frontend · unit |
| lib/care-time-history.test.ts::search is cosmetic narrowing over what came back | passed | 1 ms | Frontend · unit |
| lib/care-time-history.test.ts::a facet option names the person, the count and the minutes | passed | 2 ms | Frontend · unit |
| lib/care-time-history.test.ts::a capped page says so, and says the totals are not capped | passed | 1 ms | Frontend · unit |
| lib/care-time-row.test.ts::the author's name is shown when the server resolved one | passed | 10 ms | Frontend · unit |
| lib/care-time-row.test.ts::an unresolved author is named in words, never by id | passed | 1 ms | Frontend · unit |
| lib/care-time-row.test.ts::a whitespace-only name counts as unresolved | passed | 2 ms | Frontend · unit |
| lib/care-time-row.test.ts::the role is shown as recorded | passed | 0 ms | Frontend · unit |
| lib/care-time-row.test.ts::an unrecorded role is an em dash, not a guess | passed | 0 ms | Frontend · unit |
| lib/care-time-row.test.ts::the role is never derived from the id's prefix | passed | 1 ms | Frontend · unit |
| lib/care-time-row.test.ts::a known author with no role on file keeps their name | passed | 0 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: twenty-seven modules, three of them platform-only | passed | 5 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: every platform-only module states why | passed | 1 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: every module has routes, screens and verbs | passed | 0 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: module keys and verb keys are unique | passed | 1 ms | Frontend · unit |
| lib/catalog.test.ts::moduleForRoute: longest prefix wins, so nesting is not ambiguity | passed | 1 ms | Frontend · unit |
| lib/catalog.test.ts::moduleForRoute: an unknown path belongs to nobody | passed | 0 ms | Frontend · unit |
| lib/catalog.test.ts::moduleForNav: every screen resolves to its module | passed | 13 ms | Frontend · unit |
| lib/catalog.test.ts::holdsVerb: admin holds everything, operator holds the rest | passed | 8 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: every screen it names exists as a page | passed | 7 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: every nav href in nav.ts has a module or is ungated | passed | 7 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: five SoD pairs, all naming real modules and roles | passed | 0 ms | Frontend · unit |
| lib/catalog.test.ts::presets: each is either a standing role or a set of assignments | passed | 0 ms | Frontend · unit |
| lib/catalog.test.ts::presets: none writes both sides of an SoD pair | passed | 1 ms | Frontend · unit |
| lib/catalog.test.ts::presets: the marketer is scoped per practice, never globally | passed | 1 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: exactly one shared-mailbox admin exception, with a review date | passed | 3 ms | Frontend · unit |
| lib/catalog.test.ts::catalogue: the committed file equals a fresh generation | passed | 215 ms | Frontend · unit |
| lib/ccm.test.ts::an ICD-10 code is recognised by shape, case-insensitively | passed | 3 ms | Frontend · unit |
| lib/ccm.test.ts::chosen labels map back to codes; a typed code is custom; free text is named | passed | 3 ms | Frontend · unit |
| lib/ccm.test.ts::a complete form is not blocked | passed | 4 ms | Frontend · unit |
| lib/ccm.test.ts::each missing piece is named, in the order a person fixes it | passed | 1 ms | Frontend · unit |
| lib/ccm.test.ts::a bare tick box is not consent — only a document or a documented verbal consent | passed | 0 ms | Frontend · unit |
| lib/ccm.test.ts::the minutes line says how far from 99490, and why a patient cannot bill | passed | 0 ms | Frontend · unit |
| lib/ccm.test.ts::the consent line names what is on file | passed | 1 ms | Frontend · unit |
| lib/ccm.test.ts::the server's refusals read as sentences | passed | 0 ms | Frontend · unit |
| lib/ccm.test.ts::Onboarding offers CCM only at a practice that runs it | passed | 0 ms | Frontend · unit |
| lib/ccm.test.ts::Enrol a patient lands on Onboarding filtered to the practice | passed | 0 ms | Frontend · unit |
| lib/ccm.test.ts::monthKey is local YYYY-MM | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::the clock floors, exactly as the ledger counts | passed | 3 ms | Frontend · unit |
| lib/chart-review.test.ts::the clock cannot exceed the cap, however long the tab was open | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::a clock that has not started, or runs backwards, is zero not NaN | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::the cap is named in the text, so 60 does not look like a stuck timer | passed | 1 ms | Frontend · unit |
| lib/chart-review.test.ts::a restarted clock explains itself rather than looking broken | passed | 1 ms | Frontend · unit |
| lib/chart-review.test.ts::an ordinary session says nothing about abandonment | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::logging what was measured is always allowed | passed | 1 ms | Frontend · unit |
| lib/chart-review.test.ts::more than measured needs a reason — the server's rule, said first | passed | 2 ms | Frontend · unit |
| lib/chart-review.test.ts::the cap is refused on the screen, not only at the server | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::a negative or non-numeric figure is refused | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::the adjustment warning fires before the write, not after | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::the period names what will be reviewed | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::zero minutes is stated, never left blank | passed | 0 ms | Frontend · unit |
| lib/chart-review.test.ts::an empty period offers both ways out and calls neither an error | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::fit bands are ordered high to low so the first match wins | passed | 8 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a missing score is below the line rather than top decile | passed | 1 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a derived provider count SAYS it was estimated | passed | 1 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::an unknown provider count says unknown, never zero | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::singular and plural both read correctly | passed | 1 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a state-level Medicare share is marked as an estimate | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::an unresolved density says so rather than printing 0% | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a switched-off programme names its own switch | passed | 1 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::the programme switch is reported BEFORE the deployment gate | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a held deployment names APP_MODE and not the mail server | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a dry run is its own tone, not 'held' and not 'live' | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::an unknown sending state is held, never live | passed | 5 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::overdue is stated in days and never as an epoch artefact | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::tasks rank overdue first, then by oldest due | passed | 3 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::ranking does not mutate the caller's array | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::every channel has a human label | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::ordering keeps EVERY channel, including the empty ones | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::an empty funnel carries the server's explanation through | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::blockers name what is missing rather than hiding the row | passed | 0 ms | Frontend · unit |
| lib/client-growth-outreach.test.ts::a complete row has no blockers | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::won and lost are not board columns | passed | 6 ms | Frontend · unit |
| lib/client-growth.test.ts::every column carries a value total and an empty column still renders | passed | 1 ms | Frontend · unit |
| lib/client-growth.test.ts::every stage has a label AND a sentence saying what it means | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::a prospect with no timestamp has an UNKNOWN age, not an age of zero | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::days in stage counts from stageEnteredAt, falling back only if absent | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::staleness is judged against the STAGE's own threshold | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::a closed prospect is never stale | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::the chase list is ordered by how far PAST its own threshold each one is | passed | 1 ms | Frontend · unit |
| lib/client-growth.test.ts::an absent amount renders as an em dash, never as $0 | passed | 51 ms | Frontend · unit |
| lib/client-growth.test.ts::funnel bars scale to the WIDEST stage, not to the total | passed | 1 ms | Frontend · unit |
| lib/client-growth.test.ts::funnel bars survive an all-zero funnel without dividing by zero | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::an empty portfolio says so rather than reporting all-clear | passed | 1 ms | Frontend · unit |
| lib/client-growth.test.ts::the attention count includes NOT STARTED, not only at-risk and critical | passed | 1 ms | Frontend · unit |
| lib/client-growth.test.ts::one practice is not pluralised | passed | 0 ms | Frontend · unit |
| lib/client-growth.test.ts::every health band has a tone, so two screens cannot disagree | passed | 0 ms | Frontend · unit |
| lib/clinic-clock.test.ts::the zone comes off the row, and the two clinic zones disagree | passed | 58 ms | Frontend · unit |
| lib/clinic-clock.test.ts::a row with no zone falls back to the platform default, never the viewer | passed | 1 ms | Frontend · unit |
| lib/clinic-clock.test.ts::an abbreviation or a numeric offset is not a zone | passed | 0 ms | Frontend · unit |
| lib/clinic-clock.test.ts::the calendar day is the clinic's, and the two clinics disagree at the edge | passed | 3 ms | Frontend · unit |
| lib/clinic-clock.test.ts::same-clinic-day agrees with the escalation dedupe the backend runs | passed | 1 ms | Frontend · unit |
| lib/clinic-clock.test.ts::a day is read at its own instant, so DST is handled | passed | 4 ms | Frontend · unit |
| lib/clinic-name.test.ts::an id stored as the name never renders as a name | passed | 3 ms | Frontend · unit |
| lib/clinic-name.test.ts::a real name renders | passed | 1 ms | Frontend · unit |
| lib/clinic-name.test.ts::a name that merely mentions the id is kept | passed | 0 ms | Frontend · unit |
| lib/clinic-name.test.ts::an empty or whitespace name is reported, not rendered blank | passed | 0 ms | Frontend · unit |
| lib/clinic-name.test.ts::with no branchId it still refuses an empty name | passed | 0 ms | Frontend · unit |
| lib/clinic-name.test.ts::the unnamed signal is detectable, so a screen can offer the remedy | passed | 0 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::both answers are offered and each states its consequence | passed | 5 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::the choice is the question, not the jargon | passed | 0 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::the default is the narrower authority | passed | 0 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::the demog payload carries every field the branch form collects | passed | 2 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::blank fields are dropped, not stored as empty strings | passed | 0 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::a clinic missing letterhead details is reported | passed | 1 ms | Frontend · unit |
| lib/clinic-operating-model.test.ts::a null demog is a gap, not a crash | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::offers exactly manager and representative | passed | 5 ms | Frontend · unit |
| lib/clinic-roster.test.ts::says in words that a manager cannot change the clinic's entitlements | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::an unknown role reads as the least authority, never the most | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::the only manager is flagged | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a second manager clears the flag | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a TERMINATED manager does not count as cover | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::the reason names the remedy, not just the refusal | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a clinic with no manager is a distinct state from one with a last manager | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::managers first, then by name | passed | 39 ms | Frontend · unit |
| lib/clinic-roster.test.ts::does not mutate its input | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::locks a recorded clinical identity on edit | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::does not lock a non-clinical person, who may later be credentialed | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::does not lock a NEW person — there is nothing recorded yet | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a new person defaults to representative, not manager | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::requires a name and a real address, because the address IS the login | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::refuses a clinical role AND a job title together | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::drops the designation for a clinician on the way out | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::round-trips an existing person without losing their credential | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::never says 'invitation sent' when the transport did not report one | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::says so plainly when it did go | passed | 2 ms | Frontend · unit |
| lib/clinic-roster.test.ts::prefers the temporary password when there is one — it is the way in | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a failed login is reported as a failed login, not as a hire | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::an unreported reason says so rather than reading as success | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a missing login object is not treated as a successful one | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::names the count for one clinic | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::names the count for several — the shape a confined staff member sees | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::never says 'you run' — the picker also serves staff who do not | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::an empty list is reported as a gap, not silently offered as zero clinics | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::treats a row with no employer as the practice's own — an older server sent neither field | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::refuses to edit PatientMD's staff, and says whose record it is | passed | 5 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a Branch Admin PatientMD employs does not count as the clinic's manager | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::the last-manager guard ignores PatientMD's staff | passed | 3 ms | Frontend · unit |
| lib/clinic-roster.test.ts::sorts the practice's own people before PatientMD's | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::reports the clinical teams a hire was added to, and says nothing when there are none | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::recognises the row by its provenance | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::never claims an employer it has no record of | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::cannot be edited or ended, and says which refusal it is | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::is not counted as a manager the clinic could lose | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::sorts after the people the screen can act on | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::a row from an older server, carrying neither field, is still the clinic's | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::permits shrinking at every flex level between header and select | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::bounds the select by the layout, not by today's longest name | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::ellipsises the overflow rather than clipping or wrapping it | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::never lets the Add-someone button be the thing that gives way | passed | 1 ms | Frontend · unit |
| lib/clinic-roster.test.ts::stops the subtitle from deciding whether the controls fit on the row | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::ellipsises the subtitle rather than growing the header | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::keeps the picker a fixed-width control regardless of the option list | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::gives the full name of the picked practice for the tooltip | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::is undefined when nothing is picked | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::is undefined — never a placeholder — for an id no option carries | passed | 0 ms | Frontend · unit |
| lib/clinic-roster.test.ts::is undefined for an option whose name is blank | passed | 4 ms | Frontend · unit |
| lib/clinic-scope.test.ts::does not offer 'All clinics' to somebody eligible for exactly one | passed | 3 ms | Frontend · unit |
| lib/clinic-scope.test.ts::selects that one clinic instead of leaving the label wider than the data | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::leaves an explicit choice alone | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::still offers the rollup to an operator who genuinely runs several | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::names the selected clinic when the rollup is available | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::says 'Unknown clinic' rather than rendering blank on a stale id | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::distinguishes 'no clinics assigned' from a count of zero | passed | 0 ms | Frontend · unit |
| lib/clinic-scope.test.ts::never auto-selects or offers a rollup while still loading | passed | 0 ms | Frontend · unit |
| lib/clinical-desk.test.ts::every gap screen has a route on disk | passed | 12 ms | Frontend · unit |
| lib/clinical-desk.test.ts::every gap screen is reachable from the doctor menu | passed | 0 ms | Frontend · unit |
| lib/clinical-desk.test.ts::each one records what it was found missing against, and why | passed | 1 ms | Frontend · unit |
| lib/clinical-desk.test.ts::no two gap screens share a slug or an endpoint | passed | 0 ms | Frontend · unit |
| lib/clinical-desk.test.ts::each gap screen's permission gate is a key this app actually grants | passed | 8 ms | Frontend · unit |
| lib/clinical-desk.test.ts::every screen marked live has an endpoint that actually exists in patientmd-core | passed | 4 ms | Frontend · unit |
| lib/clinical-desk.test.ts::the gap list is not silently empty | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::⌘K and Ctrl-K both open it | passed | 7 ms | Frontend · unit |
| lib/command-palette.test.ts::a bare k, and k with Alt, are somebody else's keystrokes | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::the hint printed is the chord the reader can actually type | passed | 1 ms | Frontend · unit |
| lib/command-palette.test.ts::arrow keys enter the list from the correct end | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::the highlight wraps, so the last item is one ArrowUp away | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::an empty list has no highlight — never index 0 | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::a stale cursor from a longer previous list is corrected, not trusted | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::option ids are namespaced per palette instance | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::four states, and 'nothing to search' is one of them | passed | 0 ms | Frontend · unit |
| lib/command-palette.test.ts::the matcher is untouched — same function, same answers | passed | 3 ms | Frontend · unit |
| lib/command-palette.test.ts::the search trigger is in the shell every portal shares | passed | 1 ms | Frontend · unit |
| lib/command-palette.test.ts::both search surfaces read the RESOLVED destination list | passed | 1 ms | Frontend · unit |
| lib/command-palette.test.ts::the nav still offers /dashboard/search — the palette adds, it does not replace | passed | 1 ms | Frontend · unit |
| lib/command-palette.test.ts::the trigger and the dialog share one accessible name | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::renders a NANP number the way a person reads one | passed | 2 ms | Frontend · unit |
| lib/comms.test.ts::leaves a short code alone | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::leaves an already-formatted or foreign number alone | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::survives an empty address | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::a resolved person shows their name | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::an unresolved number is shown AS a number, never as a name | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::a name that is just the address back again counts as unknown | passed | 2 ms | Frontend · unit |
| lib/comms.test.ts::prefers the name the vendor gave the room | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::names a 1:1 thread after the person | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::names a two-person group after both | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::summarises a larger group without hiding its size | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::never renders the thread id as a title | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::every severity has a label | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::an unknown severity still says something | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::tone and label are separate so one can be shown without the other | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::explains each kind in words a person can act on | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::an unrecognised kind still renders something | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::reads in the same units the backend reasons use | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::a missing timestamp is a dash, not 1970 | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::an SMS thread with RingCentral configured is answerable | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::an in-app thread says where to reply instead | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::a group with only Twilio explains what would go wrong | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::no transport at all says so rather than failing silently | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::a team archive is read-only and says why | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::open findings come before quiet threads however recent those are | passed | 3 ms | Frontend · unit |
| lib/comms.test.ts::clinical outranks billing even when billing is more recent | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::quiet threads fall back to newest first | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::does not mutate its input | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::an empty inbox sorts to an empty inbox | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::counts only the threads with something outstanding | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::an empty inbox needs no replies | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::names the practice's own number | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::SAYS SO when the practice is borrowing the shared number | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::reports the reason rather than an empty string when there is no number | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::still explains itself when handed nothing at all | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::calls a Twilio group what it is, before the send | passed | 1 ms | Frontend · unit |
| lib/comms.test.ts::treats a RingCentral group as the real room it is | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::never puts a broadcast warning on a 1:1 | passed | 0 ms | Frontend · unit |
| lib/comms.test.ts::badges the two modes differently | passed | 0 ms | Frontend · unit |
| lib/confirm-action-honest.test.ts::ConfirmAction never reports a failed request as queued | passed | 4 ms | Frontend · unit |
| lib/confirm-action-honest.test.ts::the check fires on the old shape (probe) | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::consent state is derived from the onboardFlow stamps | passed | 5 ms | Frontend · unit |
| lib/consent-gate.test.ts::a declined consent outranks an earlier signature | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::assignment is refused outright when nobody in the selection consented | passed | 13 ms | Frontend · unit |
| lib/consent-gate.test.ts::an empty selection is refused with a different message | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a consented patient may be assigned, silently | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::a mixed batch proceeds with the consented rows and names the skipped count | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::an id with no matching row is skipped, not assumed consented | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::once consent is recorded, sending and uploading both close | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a merely sent consent leaves both actions open | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::a manual upload counts as consent for the lockout | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::refMedia is recognised whether it is a list or a single value | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::single and bulk assignment land on the same dedicated page | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::the ids survive the round trip through the query string | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::a malformed or absent ids param yields nothing rather than a phantom row | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a consent DOCUMENT on file counts as consent even when the flag is false | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::an enrolment carried over from a legacy contract is its own state | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::it is NOT reported as consent received — the platform never saw one | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::...and it does not block the care plan of a patient already under care | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a decline still outranks a legacy enrolment | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a bulk assign includes legacy enrolments and still skips the unconsented | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::a Drive-ingested consent is a consent, and it is not called Digital | passed | 1 ms | Frontend · unit |
| lib/consent-gate.test.ts::a channel the record does not name reads Not recorded, never Digital | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::the migrated legacy channels are carried through, not flattened | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::the string the enrolment backfill writes is not a consent document | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::one document reached by two writers is counted once | passed | 0 ms | Frontend · unit |
| lib/consent-gate.test.ts::an app e-consent still reads as an app e-consent | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::a fresh link opens on the agreement and says the link keeps working | passed | 3 ms | Frontend · unit |
| lib/consent-journey.test.ts::registering interest moves them to signing, not to enrolled | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::a decline outranks everything and is never re-asked on the page | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::a recorded consent is terminal | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::the patient is never told which signature method 'counts' | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::asking for paper is its own stage, and still allows signing here | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::only the unanswered stages leave the practice waiting on the patient | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::the practice owes a form on paper, and owes a declined patient nothing | passed | 0 ms | Frontend · unit |
| lib/consent-journey.test.ts::an unrecognised status degrades to the safe stage, never to signed | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::reads the single-object refMedia the upload handler writes | passed | 5 ms | Frontend · unit |
| lib/consent-media.test.ts::reads the legacy CRefWithMedia list shape too | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::skips malformed entries rather than returning a broken link | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::a stored document links to the served file | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::a digital e-consent links to the signed record instead | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::ids are encoded | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::the link label reflects what will actually open | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::a failed consent fetch says WHY, not just that it failed | passed | 1 ms | Frontend · unit |
| lib/consent-media.test.ts::the Drive ingest's evidence entry resolves to a real document link | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::refMedia still wins when both shapes are present | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::the enrolment backfill's note never becomes a document link | passed | 0 ms | Frontend · unit |
| lib/consent-media.test.ts::a bare media id is a document, not nothing | passed | 0 ms | Frontend · unit |
| lib/consent-validation.test.ts::validateConsentFile rejects a missing file (Ticket 1.1) | passed | 3 ms | Frontend · unit |
| lib/consent-validation.test.ts::validateConsentFile rejects an empty file | passed | 0 ms | Frontend · unit |
| lib/consent-validation.test.ts::validateConsentFile accepts a PDF by MIME type | passed | 0 ms | Frontend · unit |
| lib/consent-validation.test.ts::validateConsentFile accepts a JPEG by extension when type is blank | passed | 0 ms | Frontend · unit |
| lib/consent-validation.test.ts::validateConsentFile rejects a non-PDF/JPEG document | passed | 9 ms | Frontend · unit |
| lib/consent-worklist.test.ts::age is measured from enrolment, and years are said as years | passed | 3 ms | Frontend · unit |
| lib/consent-worklist.test.ts::a device still out with no consent is named, because that is today's risk | passed | 0 ms | Frontend · unit |
| lib/consent-worklist.test.ts::no device out means no scare sentence | passed | 0 ms | Frontend · unit |
| lib/consent-worklist.test.ts::nothing unresolved says so plainly | passed | 0 ms | Frontend · unit |
| lib/consent-worklist.test.ts::an attestation is NEVER added to a filed document | passed | 0 ms | Frontend · unit |
| lib/consent-worklist.test.ts::outcomes that are neither are counted, not dropped | passed | 0 ms | Frontend · unit |
| lib/consent-worklist.test.ts::nothing resolved is stated rather than rendered as zeroes | passed | 0 ms | Frontend · unit |
| lib/constitution-faq.test.ts::the constitution is reachable from the frontend repo | passed | 3 ms | Frontend · unit |
| lib/constitution-faq.test.ts::the register parses and is not empty | passed | 5 ms | Frontend · unit |
| lib/constitution-faq.test.ts::every defect names a frontend test that exists | passed | 10 ms | Frontend · unit |
| lib/constitution-faq.test.ts::every defect names a frontend test that actually contains tests | passed | 40 ms | Frontend · unit |
| lib/constitution-faq.test.ts::no defect leaves either side blank | passed | 3 ms | Frontend · unit |
| lib/constitution-faq.test.ts::defect ids are unique | passed | 4 ms | Frontend · unit |
| lib/constitution-faq.test.ts::every row describes what went wrong, not what is now fine | passed | 3 ms | Frontend · unit |
| lib/contact-patient.test.ts::a bound patient is used immediately, with no picking step | passed | 3 ms | Frontend · unit |
| lib/contact-patient.test.ts::a bound patient is never widened into a pick-list | passed | 2 ms | Frontend · unit |
| lib/contact-patient.test.ts::without a bound patient, a supplied list is offered | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::precedence falls through fetched then seed | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::an empty fetch falls back rather than leaving the modal blank | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::rows without an id are discarded, not shown as blank entries | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::a bound patient with no id does not lock an empty context | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::the active patient is the bound one, whatever the list says | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::a stale selection resolves to null rather than to someone else | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::the modal has exactly the two tabs QA specified, in order | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::names come from either the row or its demog block | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::a nameless row shows its id, and an anonymous row says Patient | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::ids are read from any of the three key names in use | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::a missing phone stays empty instead of inheriting a demo number | passed | 0 ms | Frontend · unit |
| lib/contact-patient.test.ts::toContact produces exactly what the modal needs | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::an address matches whatever case and spacing it was stored in | passed | 4 ms | Frontend · unit |
| lib/contacts-merge.test.ts::a contact is told when its address is also on the mailing list | passed | 3 ms | Frontend · unit |
| lib/contacts-merge.test.ts::an UNSUBSCRIBED address never reads as subscribed | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::a contact with no address is never matched to anything | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::legacy provenance survives onto the contact row | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::subscribed addresses that are not contacts are listed as the gap | passed | 3 ms | Frontend · unit |
| lib/contacts-merge.test.ts::the same address in both collections is listed once, keeping the newer | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::a subscriber with no date sorts last, not to 1970 | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::an unsubscribed address is not offered as a gap to close | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::the summary counts contacts, subscriptions, the gap and the legacy carry-over | passed | 1 ms | Frontend · unit |
| lib/contacts-merge.test.ts::the summary says nothing about a gap or legacy rows when there are none | passed | 0 ms | Frontend · unit |
| lib/contacts-merge.test.ts::NO subscriber disappears in the merge | passed | 1 ms | Frontend · unit |
| lib/contacts-merge.test.ts::search reaches every field somebody would type | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::the palette parses — otherwise every check below passes vacuously | passed | 4 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::body text meets 4.5:1 on both surfaces | passed | 5 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::the primary colour works as TEXT, which is how links use it | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::a white label ON the primary colour also meets 4.5:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::destructive actions are legible in both directions | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::form field boundaries meet the 3:1 non-text threshold | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::the focus ring is visible against the surfaces it appears on | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::large text still needs 3:1 and headings clear it comfortably | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::every portal palette in the stylesheet is one this test measures | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::patient: body and action text meet 4.5:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::patient: field boundaries and the focus ring meet 3:1 | passed | 7 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::patient: the portal is actually distinguishable from the others | passed | 3 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::patient: danger is still red, not the brand colour | passed | 8 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::doctor: body and action text meet 4.5:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::doctor: field boundaries and the focus ring meet 3:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::doctor: the portal is actually distinguishable from the others | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::doctor: danger is still red, not the brand colour | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::business: body and action text meet 4.5:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::business: field boundaries and the focus ring meet 3:1 | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::business: the portal is actually distinguishable from the others | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::business: danger is still red, not the brand colour | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::the three portal primaries are inside sRGB, so nothing is mapped away | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::an out-of-gamut colour is detected, and an in-gamut one is not | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::gamut mapping holds hue and lightness, and only pulls chroma in | passed | 6 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::the ratio is order-independent and bounded, as WCAG defines it | passed | 1 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::relative luminance matches the known anchors | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::oklch converts to the sRGB a browser would render | passed | 0 ms | Frontend · unit |
| lib/contrast-tokens.test.ts::an unparseable colour scores 0 rather than passing | passed | 0 ms | Frontend · unit |
| lib/conveyor.test.ts::toneFor maps statuses to colour tones | passed | 3 ms | Frontend · unit |
| lib/conveyor.test.ts::statusLabel is human-readable | passed | 0 ms | Frontend · unit |
| lib/conveyor.test.ts::conveyorPercent computes progress | passed | 0 ms | Frontend · unit |
| lib/conveyor.test.ts::needsApproval flags pending human steps | passed | 0 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::fills the description when a known code is typed | passed | 10 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::swaps its own wording when the code changes | passed | 0 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::never replaces a description the biller typed | passed | 0 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::an unknown code clears only the module's own text | passed | 0 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::matches a code however it was typed | passed | 0 ms | Frontend · unit |
| lib/cpt-autofill.test.ts::the hint says where the wording came from — and says nothing before the reference loads | passed | 1 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::shows a conflict on the plan being logged | passed | 7 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::stays quiet about a different programme | passed | 1 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::a combined enrolment is checked against both | passed | 5 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::an unrecognised plan matches nothing rather than everything | passed | 0 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::never returns a blocking severity | passed | 0 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::one conflict shows its own headline and reason | passed | 1 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::several are counted, and the plural is not '1 clinics' | passed | 0 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::nothing at all renders nothing | passed | 0 ms | Frontend · unit |
| lib/cross-enrolment.test.ts::a practice outside the tenancy is reported without a name | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::an account with no trail says WHEN the evidence starts, never 'never' | passed | 69 ms | Frontend · unit |
| lib/customer-service.test.ts::with no trail at all the wording does not blame the account | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::a real last-seen renders as elapsed time | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::an unrecorded status is reported as unrecorded, never as active | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::relative time degrades to a date rather than '900d ago' | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::the tier refusal and the target refusal are never collapsed | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::an apex refused by the TARGET rule is told about the target | passed | 3 ms | Frontend · unit |
| lib/customer-service.test.ts::the control is offered only when BOTH halves allow it | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::no target selected is not the same as refused | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::the reason floor is mirrored so the button disables before the 400 | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::an empty source says WHICH kind of empty it is | passed | 10 ms | Frontend · unit |
| lib/customer-service.test.ts::every actor-kind chip renders even at zero | passed | 1 ms | Frontend · unit |
| lib/customer-service.test.ts::chips carry the out-of-window total so zero is legible | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::activity groups by actor, newest group first, counting refusals | passed | 1 ms | Frontend · unit |
| lib/customer-service.test.ts::a human and an agent with the same name are two groups | passed | 2 ms | Frontend · unit |
| lib/customer-service.test.ts::an unattributed row is labelled, not dropped | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::outcome tones cover every outcome the server emits | passed | 0 ms | Frontend · unit |
| lib/customer-service.test.ts::the people search narrows on what is already on screen | passed | 1 ms | Frontend · unit |
| lib/customer-service.test.ts::every label map covers every key the server can send | passed | 1 ms | Frontend · unit |
| lib/dark-variant-is-inert.test.ts::the dark variant is bound to a class, not to prefers-color-scheme | passed | 7 ms | Frontend · unit |
| lib/dark-variant-is-inert.test.ts::the stylesheet still declares itself light-only | passed | 3 ms | Frontend · unit |
| lib/dark-variant-is-inert.test.ts::nothing in the app sets the .dark class, so the variant stays inert | passed | 245 ms | Frontend · unit |
| lib/data-state.test.ts::a signed-out visitor gets labelled sample data | passed | 4 ms | Frontend · unit |
| lib/data-state.test.ts::a signed-in user with real rows sees them and no banner | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::a signed-in user with NO rows is told so — never given sample rows | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::a failed fetch surfaces an error and a retry — never sample rows | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::an error outranks whatever rows happened to be in hand | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::a signed-in session can NEVER be shown sample rows | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::a signed-out visitor with no sample data is told to sign in | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::the empty message names something the user can actually do | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::without a hint, the empty message still names the screen | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::an expired session says to sign in again, not 'error 401' | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::a 403 does NOT say the session expired | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::a server fault and a client fault read differently | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::a rate limit tells the user to wait rather than to retry now | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::a network failure points at the connection | passed | 2 ms | Frontend · unit |
| lib/data-state.test.ts::an unrecognised error never leaks a stack or a bare code | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: signed out gets a labelled sample, and only then | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: a signed-in caller never receives the sample | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: missing and error are DIFFERENT answers | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: only the error state offers a Retry | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: the error says what has NOT happened | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: a live record passes through with nothing to say | passed | 1 ms | Frontend · unit |
| lib/data-state.test.ts::resolveRecordState: a falsy-but-present record is not treated as missing | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::formMayRender: nothing is editable before the read settles | passed | 0 ms | Frontend · unit |
| lib/data-state.test.ts::formMayRender: only a mode with a record behind it gets a form | passed | 0 ms | Frontend · unit |
| lib/demographics-quality.test.ts::a complete record raises nothing | passed | 7 ms | Frontend · unit |
| lib/demographics-quality.test.ts::a pre-1970 date of birth is NOT an issue | passed | 0 ms | Frontend · unit |
| lib/demographics-quality.test.ts::a missing identity blocks; missing detail only warns | passed | 1 ms | Frontend · unit |
| lib/demographics-quality.test.ts::a nameless record cannot be assigned to | passed | 0 ms | Frontend · unit |
| lib/demographics-quality.test.ts::issues name the patient so the user knows who to fix | passed | 0 ms | Frontend · unit |
| lib/demographics-quality.test.ts::summary distinguishes blocked from merely incomplete | passed | 1 ms | Frontend · unit |
| lib/demographics-quality.test.ts::raw epoch detection recognises an unformatted timestamp | passed | 1 ms | Frontend · unit |
| lib/deployment-id.test.ts::next.config.ts reads the deployment id from the environment | passed | 3 ms | Frontend · unit |
| lib/deployment-id.test.ts::an absent deployment id degrades to the old behaviour, never to a crash | passed | 1 ms | Frontend · unit |
| lib/deployment-id.test.ts::the Dockerfile accepts and exports it | passed | 0 ms | Frontend · unit |
| lib/deployment-id.test.ts::compose passes it as a build arg to the ui service | passed | 1 ms | Frontend · unit |
| lib/deployment-id.test.ts::the deploy script computes one from the tree fingerprint | passed | 1 ms | Frontend · unit |
| lib/deployment-id.test.ts::the client cache cannot outlive a deploy by minutes | passed | 1 ms | Frontend · unit |
| lib/device-filter.test.ts::a device is findable by the patient holding it | passed | 3 ms | Frontend · unit |
| lib/device-filter.test.ts::the hardware fields still search as before | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::search is case- and whitespace-insensitive | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::an unassigned device does not crash the patient-name search | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::the placeholder names every field actually searched | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::the branch filter narrows to that branch | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::'all' and an absent filter both mean no branch narrowing | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::a device with no branch is excluded by a specific branch, not by 'all' | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::filters compose — branch AND text together | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::the category tab narrows by device group | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::a device with no received date is excluded from a dated window | passed | 3 ms | Frontend · unit |
| lib/device-filter.test.ts::the window is bounded at both ends | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::patients filter by name, email, device status and branch | passed | 1 ms | Frontend · unit |
| lib/device-filter.test.ts::status 'all' keeps everyone regardless of device count | passed | 0 ms | Frontend · unit |
| lib/device-filter.test.ts::the row type survives filtering, so callers keep their own fields | passed | 0 ms | Frontend · unit |
| lib/device-forms.test.ts::the vocabularies match app/modules/ops/device_forms.py and schemas.py, value for value | passed | 7 ms | Frontend · unit |
| lib/device-forms.test.ts::a new row names its clinic, patient, device and the fields a prompt box never asked for | passed | 8 ms | Frontend · unit |
| lib/device-forms.test.ts::an edit of a row written before the form existed is not held hostage to a back-fill | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::every message names the remedy (WCAG 2.1 SC 3.3.3) | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::a typed identifier is 15 or 16 digits; one picked from the patient's devices is stored as it is | passed | 2 ms | Frontend · unit |
| lib/device-forms.test.ts::a device line shows type, name, identifier and serial — and is never blank | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::an issue payload carries every field, and never who filed it | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::closing an issue needs a note; the reporter on the stored row is never sent back | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::a reported date in the future is refused | passed | 0 ms | Frontend · unit |
| lib/device-forms.test.ts::a return payload maps the patient to customerName and normalises the tracking number | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::what the return route refuses, the form refuses first | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::a caller who may not see money sends NO money key — the server refuses one from them | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::the billing desk's charges are parsed, totalled and validated | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::one device, one row per year per clinic | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::the returned date follows the returned status | passed | 1 ms | Frontend · unit |
| lib/device-forms.test.ts::the clinic is the patient's own when the caller manages it, else the one chosen, else none | passed | 0 ms | Frontend · unit |
| lib/device-forms.test.ts::a calendar day survives the round trip, and nonsense is not a date | passed | 0 ms | Frontend · unit |
| lib/device-health.test.ts::a patient whose readings are arriving is never counted as unmonitored | passed | 3 ms | Frontend · unit |
| lib/device-health.test.ts::every declared diagnosis has a tone and a place in the order | passed | 1 ms | Frontend · unit |
| lib/device-health.test.ts::diagnosis tones put no-device and never-activated at the top | passed | 0 ms | Frontend · unit |
| lib/device-health.test.ts::never transmitted is never rendered as a number of silent days | passed | 4 ms | Frontend · unit |
| lib/device-health.test.ts::needingAPerson excludes what the run repaired by itself | passed | 1 ms | Frontend · unit |
| lib/device-health.test.ts::the headline counts patients, not devices | passed | 1 ms | Frontend · unit |
| lib/device-health.test.ts::repairText stays silent when nothing was repaired | passed | 1 ms | Frontend · unit |
| lib/device-health.test.ts::groupByDiagnosis keeps severity order and drops empty groups | passed | 3 ms | Frontend · unit |
| lib/device-holders.test.ts::an empty query offers every holder — the list is the search space | passed | 5 ms | Frontend · unit |
| lib/device-holders.test.ts::name words match in any order, case-insensitively | passed | 3 ms | Frontend · unit |
| lib/device-holders.test.ts::a device identifier or a phone number finds its holder | passed | 1 ms | Frontend · unit |
| lib/device-holders.test.ts::the hint tells two Averys apart by the device each holds | passed | 1 ms | Frontend · unit |
| lib/device-holders.test.ts::the list is capped so a long clinic cannot render a thousand options | passed | 1 ms | Frontend · unit |
| lib/device-holders.test.ts::a holder becomes the row the device forms already take | passed | 0 ms | Frontend · unit |
| lib/device-orders.test.ts::a book where nothing has ever moved says exactly that | passed | 3 ms | Frontend · unit |
| lib/device-orders.test.ts::a book that moves entirely is not described as stuck | passed | 1 ms | Frontend · unit |
| lib/device-orders.test.ts::a mixed book reports both halves | passed | 0 ms | Frontend · unit |
| lib/device-orders.test.ts::no orders in the period is a different statement from none moving | passed | 0 ms | Frontend · unit |
| lib/device-orders.test.ts::reminders are only mentioned when some were actually sent | passed | 0 ms | Frontend · unit |
| lib/device-orders.test.ts::waiting time is the number with consequences on a book that does not move | passed | 1 ms | Frontend · unit |
| lib/device-orders.test.ts::an empty book says so rather than reporting a zero-day wait | passed | 0 ms | Frontend · unit |
| lib/device-orders.test.ts::a book younger than a day does not claim an age it cannot support | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::a clinic drop-off asks for nothing about a carrier | passed | 6 ms | Frontend · unit |
| lib/device-returns.test.ts::a carrier return names every missing address part, by field | passed | 1 ms | Frontend · unit |
| lib/device-returns.test.ts::the open payload never names a status, and upper-cases the state | passed | 1 ms | Frontend · unit |
| lib/device-returns.test.ts::a prepaid label never sends a bag, whatever the checkbox says | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::the address on file starts the form and never invents a city | passed | 1 ms | Frontend · unit |
| lib/device-returns.test.ts::a case on two attention lists is counted once | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::the attention order puts a parcel landing today first | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::delivered by the carrier does not read as finished | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::a leg's timeline marks what is done and what is current | passed | 1 ms | Frontend · unit |
| lib/device-returns.test.ts::a leg says what went wrong in the carrier's own words | passed | 1 ms | Frontend · unit |
| lib/device-returns.test.ts::tracking links go to the carrier, and only for a carrier we know | passed | 0 ms | Frontend · unit |
| lib/device-returns.test.ts::a pickup day does not slip a day west of Greenwich | passed | 74 ms | Frontend · unit |
| lib/device-stock.test.ts::an empty inventory says so rather than showing a row of zeros | passed | 3 ms | Frontend · unit |
| lib/device-stock.test.ts::the headline states each category it actually has | passed | 1 ms | Frontend · unit |
| lib/device-stock.test.ts::stock nobody has allocated is named, not silently absent | passed | 1 ms | Frontend · unit |
| lib/device-stock.test.ts::a partial allocation reads differently from a total one | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::a device out with a patient names the patient and the reason | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::a retired device is not moved | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::moving a device where it already is is refused before the request | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::no destination chosen asks for one rather than failing silently | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::an available device moves | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::a branch holding nothing says so | passed | 0 ms | Frontend · unit |
| lib/device-stock.test.ts::unallocated stock sorts last, real branches by name | passed | 51 ms | Frontend · unit |
| lib/device-stock.test.ts::the totals a screen renders are the ones the server sent | passed | 0 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::components/modal.tsx: the focus effect depends only on stable values | passed | 178 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::components/modal.tsx: the restore-focus effect is separate and depends on open | passed | 44 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::components/slide-over.tsx: the focus effect depends only on stable values | passed | 18 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::components/slide-over.tsx: the restore-focus effect is separate and depends on open | passed | 19 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::the scanner reads dependency arrays, not prose | passed | 2 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::does not flag a comment that names the banned dependency | passed | 1 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::prefers the form over the dismiss control | passed | 1 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::an explicit data-autofocus still wins | passed | 1 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::falls back to the dismiss control when there is nothing else | passed | 0 ms | Frontend · unit |
| lib/dialog-focus-stability.test.ts::returns null when there is nothing focusable, so the panel takes focus | passed | 0 ms | Frontend · unit |
| lib/dicom-metadata.test.ts::canEditDicom: clinician/owner/admin yes; patient/staff no; globalAdmin override | passed | 3 ms | Frontend · unit |
| lib/dicom-metadata.test.ts::cleanOverrides: only whitelisted + changed + trimmed non-empty | passed | 3 ms | Frontend · unit |
| lib/dicom-metadata.test.ts::cleanOverrides: nothing changed → empty object | passed | 0 ms | Frontend · unit |
| lib/dicom-metadata.test.ts::correctedSet: from meta.corrected | passed | 1 ms | Frontend · unit |
| lib/dicom-metadata.test.ts::seedForm: every editable tag present, stringified, blanks for missing | passed | 1 ms | Frontend · unit |
| lib/display-name.test.ts::names a person from whichever key the API used | passed | 3 ms | Frontend · unit |
| lib/display-name.test.ts::distinguishes nobody-assigned from cannot-be-named | passed | 0 ms | Frontend · unit |
| lib/display-name.test.ts::never falls back to the synthetic login handle | passed | 0 ms | Frontend · unit |
| lib/display-name.test.ts::never renders the identifier as a name | passed | 0 ms | Frontend · unit |
| lib/display-name.test.ts::isUnresolvedPerson fires on exactly the unresolved marker | passed | 0 ms | Frontend · unit |
| lib/display-name.test.ts::a role cell reports unassigned when the role holds no id | passed | 1 ms | Frontend · unit |
| lib/documents-surveys.test.ts::a known patient renders their name | passed | 4 ms | Frontend · unit |
| lib/documents-surveys.test.ts::an unknown patient never renders the raw id | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::a synthetic login handle is not treated as a name | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::the patient name links to the patient detail screen (2.2) | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::an assigned but unanswered assessment is incomplete | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::a score of zero is COMPLETE, not missing | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::an answered score with no timestamp is incomplete | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::the filter separates completed from pending | passed | 1 ms | Frontend · unit |
| lib/documents-surveys.test.ts::search matches the name, not the internal id | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::one row per patient, newest first, counting their documents | passed | 1 ms | Frontend · unit |
| lib/documents-surveys.test.ts::last taken ignores assessments that were never answered | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::document actions are disabled WITH a reason before any score exists | passed | 1 ms | Frontend · unit |
| lib/documents-surveys.test.ts::eFax says which detail is missing rather than merely being grey | passed | 1 ms | Frontend · unit |
| lib/documents-surveys.test.ts::contacting the patient never depends on an assessment existing | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::every action QA listed is present | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::assigning is blocked until a branch is chosen | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::the blocked reason names the FIRST thing missing | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::the summary reports what was DELIVERED | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::a total delivery failure never reads as success | passed | 0 ms | Frontend · unit |
| lib/documents-surveys.test.ts::a partial failure is reported as partial | passed | 0 ms | Frontend · unit |
| lib/dur-alerts.test.ts::severityTone maps severity to tone | passed | 3 ms | Frontend · unit |
| lib/dur-alerts.test.ts::rankAlerts orders most-severe first | passed | 3 ms | Frontend · unit |
| lib/dur-alerts.test.ts::alertSummary + blocksSubmit | passed | 2 ms | Frontend · unit |
| lib/dur-alerts.test.ts::hasContra: only absolute contraindications | passed | 0 ms | Frontend · unit |
| lib/dur-alerts.test.ts::highCodes: codes of high-severity alerts only | passed | 0 ms | Frontend · unit |
| lib/dur-alerts.test.ts::alertText: prefers message, then detail/title/code | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::the reported total is not an artefact of float addition | passed | 9 ms | Frontend · unit |
| lib/duration.test.ts::the total does not depend on the order the rows arrive in | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::non-numeric entries are skipped, not coerced to NaN | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::whole minutes render whole | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::a genuine fraction keeps its decimal | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::a missing value renders as zero, never as NaN or blank | passed | 0 ms | Frontend · unit |
| lib/duration.test.ts::long totals read as hours and minutes | passed | 0 ms | Frontend · unit |
| lib/e2e-credentials.test.ts::the e2e demo logins do not use the suppressed @patientmd.com addresses | passed | 5 ms | Frontend · unit |
| lib/e2e-credentials.test.ts::all three demo roles are addressed at the mailbox domain that exists | passed | 1 ms | Frontend · unit |
| lib/e2e-credentials.test.ts::a refused sign-in is raised, not returned as an absent session | passed | 1 ms | Frontend · unit |
| lib/ein.test.ts::formatting inserts the IRS hyphen and stops at nine digits | passed | 3 ms | Frontend · unit |
| lib/ein.test.ts::nine digits is the whole format rule | passed | 2 ms | Frontend · unit |
| lib/ein.test.ts::masking keeps the last four, which is what somebody checks it by | passed | 0 ms | Frontend · unit |
| lib/ein.test.ts::a partial EIN is not masked — there is nothing to hide yet | passed | 0 ms | Frontend · unit |
| lib/ein.test.ts::Verify & save requires the attestation the checkbox promises | passed | 0 ms | Frontend · unit |
| lib/ein.test.ts::the block states which of the two is missing | passed | 1 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a month key reads as a month; anything else is left alone | passed | 3 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a billing list is labelled with its month, its size and its status | passed | 1 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::no stamp reads as not checked — never as fine | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a stamp about a REBUILT list never reads as checked-and-current | passed | 2 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a batch where nothing reached a payer is bad, whatever else it says | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::an inactive patient outranks everything else in a stamp's tone | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::outcome counts leave out zeros and never render as an empty string | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::an unknown outcome word is shown as unclear, not as active | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::the plan leads with how many of the list can be checked, and prices it | passed | 77 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a list nobody can be checked on says why, and offers no price | passed | 0 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::the run button names the count and the rough cost | passed | 2 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::blockers are ranked by how many patients each holds back | passed | 3 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::a running batch polls; a finished or stopped one does not | passed | 1 ms | Frontend · unit |
| lib/eligibility-batch.test.ts::the picker's name filter is case-blind and empty means everyone | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a programme that cannot be derived never reads as 'nobody eligible' | passed | 9 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::an empty list says so plainly | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a populated list reports reachability, and tomorrow only when there is one | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a missing block is empty rather than throwing | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::the hidden count is what is NOT shown, never negative | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::collapsed, a long list shows eight and offers all of them | passed | 71 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::expanded, it shows every row it holds and offers the way back | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a list that is STILL cut says so rather than reading as complete | passed | 2 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a short list offers no control at all | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::exactly the collapsed count is not a truncated list | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::`held` never exceeds what arrived, and `total` never falls below it | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a missing or empty block does not throw and offers nothing | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::the next scan asks for the biggest list, not the sum of them | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::nothing short means no round trip | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::the client never asks for more than the server will give | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::the row ceiling mirrors the server's own | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a held send is never reported as a sent one | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a partial send reports both halves | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a recipient refused for being a patient on the list is named as that | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::no recipients at all is a gap, not a success | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a list nobody edited says nothing; an edited one says what changed | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a hand-added row is labelled and a derived one is not | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::adding or removing a patient needs a stated reason; amending does not | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::recipients accept every separator a person actually pastes | passed | 3 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a bad address is reported rather than swallowing the whole box | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::one mailbox spelled twice is one recipient, not two | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a clinic with no recipient says so before the button is pressed | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::a ready clinic names where the list is going | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: the four states say four different things | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: 'no payer on file' never claims the patient is uninsured | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: a matched row names what it was matched TO, never an id | passed | 5 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: a plan repeating the payer is not printed twice on the list | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: no block at all renders nothing, and claims nothing | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage summary: leads with what CAN be checked, drops the zeroes | passed | 1 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage summary: absent counts render no line, not '0 matched' | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: the mapping link appears only when there is something to map | passed | 0 ms | Frontend · unit |
| lib/eligibility-scan.test.ts::coverage: Cantera's real numbers add up to its whole list, not its page | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::has a human label for each field | passed | 4 ms | Frontend · unit |
| lib/emr-capture.test.ts::opens with the name and date of birth, as the panel prints them | passed | 3 ms | Frontend · unit |
| lib/emr-capture.test.ts::says what to do about a parsed value | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::anything a person stood behind is settled | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::an empty field asks for nothing | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::lists exactly the fields still awaiting a look | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::is disabled while the server reports a blocker | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::is enabled with nothing outstanding | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::is disabled once the capture is already confirmed | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::names how many are outstanding, singular and plural | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::an empty capture invites the two ways in | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::a complete capture says so | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::carries the server's reason | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::still says something when there is no reason | passed | 9 ms | Frontend · unit |
| lib/emr-capture.test.ts::strips the data-url prefix | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::takes images from a paste and ignores everything else | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::needs-more-information is its own answer, not a soft no | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::unknown prior authorization can never be read as not required | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::the two settled answers say which | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::names the destination, not the registry | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::the confirmation says the person is NOT a registry patient yet | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::still reads sensibly with no clinic name to hand | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::offers the four programmes the server accepts | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::refuses, and says why, when no clinic is chosen | passed | 1 ms | Frontend · unit |
| lib/emr-capture.test.ts::refuses a programme the server does not accept | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::still refuses while a field is unchecked, and counts them | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::refuses a capture that has already gone | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::allows it once the clinic, the programme and the fields are all settled | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::says something rather than nothing when there is no capture at all | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::readyToSend is exactly the negation of the reason, always | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::a healthy fleet is quiet about it | passed | 2 ms | Frontend · unit |
| lib/emr-capture.test.ts::distinguishes 'nothing configured' from 'nothing answered' | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::neither of those offers the attach button | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::says so when it is running on a backup host | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::a worker with no vision model is a DIFFERENT fault from a worker that is down | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::an unknown state never takes the capability away | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::offers Try again after a failure | passed | 2 ms | Frontend · unit |
| lib/emr-capture.test.ts::offers nothing before anything has been tried, or after a success | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::does not offer a retry that cannot possibly succeed | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::an older response with no readerConfigured flag keeps the old behaviour | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::shows the LAST failure, not the first | passed | 0 ms | Frontend · unit |
| lib/emr-capture.test.ts::no screen counts as read when the parse failed | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::queued and failed rows need a decision; the rest do not | passed | 3 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a row is actionable only when the SERVER says this session may approve | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a failed row is retried, not approved for the first time | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::the document says what it is, server label first | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::every status has words and a tone | passed | 1 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::the patient is named, and never by their id | passed | 9 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a row with no branch and an unnamed clinic say different things | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a visit date is the reader's calendar day, never UTC midnight | passed | 3 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::an instant renders as the local day; zero is not 1970 | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::the date line prefers the visit, then when it was queued | passed | 1 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::whenOf reads either writer's timestamp and never invents one | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::the soonest visit comes first; undated rows follow, oldest first | passed | 3 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::partition: waiting for a person, waiting for the agent, finished | passed | 1 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a picked clinic narrows by branch; the client never names a tenant | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a rejection needs a reason, and not an essay | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::an empty queue and a finished queue are different sentences | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a capped list says so instead of dropping the oldest silently | passed | 0 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::a failed load is never phrased as an empty queue | passed | 1 ms | Frontend · unit |
| lib/emr-chart-queue.test.ts::the approve dialog names the patient and the consequence | passed | 0 ms | Frontend · unit |
| lib/engagement-hub.test.ts::hubTiles reads only what /ms/reports/overview returns — no dollar tile | passed | 7 ms | Frontend · unit |
| lib/engagement-hub.test.ts::hubTiles treats a missing or non-numeric field as zero, never NaN | passed | 0 ms | Frontend · unit |
| lib/engagement-hub.test.ts::audienceSplit is empty when nobody was ever on the list | passed | 4 ms | Frontend · unit |
| lib/engagement-hub.test.ts::hubSentence says which kind of empty the screen is | passed | 2 ms | Frontend · unit |
| lib/engagement.test.ts::an unknown band is read as disengaged, never as engaged | passed | 3 ms | Frontend · unit |
| lib/engagement.test.ts::the weight line repeats the server's weights in the server's order | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::a delta needs two months; one month is a level with no movement | passed | 8 ms | Frontend · unit |
| lib/engagement.test.ts::adoption rows sort by active enrolments and carry the month-on-month movement | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::shares and missing-signal rows never divide by zero | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::the fourth band is drawn, labelled, and is NOT coloured as a failure | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::an unknown band still renders rather than vanishing | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::band rows are seeded so a band with nothing in it is a visible zero | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::the ceiling sentence names what nobody can earn, and disappears when nothing is blocked | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::coverage distinguishes 'not measured' from 'nothing observable' | passed | 0 ms | Frontend · unit |
| lib/engagement.test.ts::signal rows put a blocked signal above a merely weak one | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::the history says which kind of empty it is, never a blank chart | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::a clamped window says the chart is shorter than the control asked for | passed | 0 ms | Frontend · unit |
| lib/engagement.test.ts::a history that moved does not print the flat sentence | passed | 0 ms | Frontend · unit |
| lib/engagement.test.ts::movers are de-duplicated across up and down, biggest fall first | passed | 1 ms | Frontend · unit |
| lib/engagement.test.ts::an empty roster distinguishes 'filtered to nothing' from 'never scored' | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.lens.test.ts::a named lens is honoured | passed | 3 ms | Frontend · unit |
| lib/enrolment-readiness.lens.test.ts::an absent lens falls back to the default, never to nothing | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.lens.test.ts::the retired outreach route names the lens its content lives under | passed | 1 ms | Frontend · unit |
| lib/enrolment-readiness.lens.test.ts::the screen follows the URL rather than seeding from it once | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::eligibility and consent are never collapsed into one answer | passed | 4 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::both present is the only ready state | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::a received paper consent counts as consent | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::unchecked coverage is not reported as ineligible | passed | 1 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::a decline outranks everything else | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::consent in flight reads differently from consent never sent | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::both outstanding names both, and the action depends on which kind | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::status matching is case and whitespace tolerant | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::the summary names what is blocking, not just how many | passed | 16 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::every patient lands in exactly one bucket | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::an empty pipeline says so rather than showing zeros | passed | 0 ms | Frontend · unit |
| lib/enrolment-readiness.test.ts::the merge keeps every lens the four screens offered | passed | 1 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::every drill-down carries its entity onward, or says why not | passed | 20 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::the exemption list does not outlive the screens it names | passed | 1 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::the outbound-link scanner matches the shapes it was written for | passed | 1 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::a selected branch missing from the list is named, not blanked | passed | 1 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::an archived branch is not offered as a choice but is still nameable | passed | 1 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::a selection control never offers "all branches" | passed | 0 ms | Frontend · unit |
| lib/entity-context-carried.test.ts::the unaffiliated label is a sentence, not a blank | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::a branch drilled into is readable on the next screen | passed | 8 ms | Frontend · unit |
| lib/entity-context.test.ts::no context reads as no context, not as an empty one | passed | 1 ms | Frontend · unit |
| lib/entity-context.test.ts::a corporate is NEVER carried in a link | passed | 1 ms | Frontend · unit |
| lib/entity-context.test.ts::carrying a context replaces any context already on the href | passed | 1 ms | Frontend · unit |
| lib/entity-context.test.ts::switching entity kind does not leave the previous kind behind | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::clearing context removes only the context | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::an unresolved name shows the identifier, never blank | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::screens whose actions change someone's standing are marked | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::every carriable kind has a distinct parameter name | passed | 0 ms | Frontend · unit |
| lib/entity-context.test.ts::a href with no query survives a null context unchanged | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::an unrecorded sync says so and never guesses | passed | 3 ms | Frontend · unit |
| lib/environment-banner.test.ts::a recorded sync reports its age and size | passed | 58 ms | Frontend · unit |
| lib/environment-banner.test.ts::a dry run is named as one | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::a failed run is named, not filtered out | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::an ok status adds no noise | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::the strip appears whenever something is being held back | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::a normal live production session gets no strip | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::no data means no strip rather than a broken one | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::the headline names the mode and the detail names the consequence | passed | 3 ms | Frontend · unit |
| lib/environment-banner.test.ts::the detail promises that sign-in still works | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::tone distinguishes comparison from plain test mode | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::relative age rounds down to whole units | passed | 4 ms | Frontend · unit |
| lib/environment-banner.test.ts::an unknown age is unknown, not zero | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::a clock skew never renders as a sync in the future | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::a missed nightly run is called out | passed | 0 ms | Frontend · unit |
| lib/environment-banner.test.ts::unknown freshness is not reported as stale | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::a pre-1970 date of birth formats instead of rendering a dash | passed | 56 ms | Frontend · unit |
| lib/epoch-date.test.ts::post-1970 dates still format | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::numeric strings are accepted, as the API sometimes returns them | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::genuinely absent values render the fallback | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::ISO date strings still work | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::date input keeps the local calendar day | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::date input is empty, never a bogus date, when absent | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::age is computed from a pre-1970 birth | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::age is null rather than a wrong number when unknown | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::formats in the CLINIC's timezone, not the runner's own | passed | 2 ms | Frontend · unit |
| lib/epoch-date.test.ts::a viewer anywhere else sees the SAME clinic time, not their own local time | passed | 2 ms | Frontend · unit |
| lib/epoch-date.test.ts::the timezone abbreviation is always appended | passed | 2 ms | Frontend · unit |
| lib/epoch-date.test.ts::falls back to the universal formatter on a bad/unrecognised zone id, never throws | passed | 5 ms | Frontend · unit |
| lib/epoch-date.test.ts::an absent value is the fallback dash, not a crash | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::a missing clinic timezone defaults to America/Chicago rather than failing | passed | 5 ms | Frontend · unit |
| lib/epoch-date.test.ts::a calendar day is the CLINIC's day, not the viewer's | passed | 1 ms | Frontend · unit |
| lib/epoch-date.test.ts::an absent date is the fallback dash, not today | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::typed digits are read as the CLINIC's wall clock | passed | 1 ms | Frontend · unit |
| lib/epoch-date.test.ts::what is typed is what is read back — the round trip is the contract | passed | 1 ms | Frontend · unit |
| lib/epoch-date.test.ts::the offset is the one in force ON THAT DATE, not today's | passed | 2 ms | Frontend · unit |
| lib/epoch-date.test.ts::a wall-clock time that does not exist settles rather than throwing | passed | 2 ms | Frontend · unit |
| lib/epoch-date.test.ts::a malformed date is NaN, never silently 'now' | passed | 0 ms | Frontend · unit |
| lib/epoch-date.test.ts::a bad zone id falls back instead of throwing | passed | 1 ms | Frontend · unit |
| lib/epoch-date.test.ts::form defaults open on the clinic's today and now | passed | 3 ms | Frontend · unit |
| lib/epoch-date.test.ts::midnight is 00:00, not 24:00 | passed | 1 ms | Frontend · unit |
| lib/epoch-date.test.ts::the zone abbreviation follows the date, so a caption is never stale | passed | 1 ms | Frontend · unit |
| lib/era-batch.test.ts::shows an own batch's check | passed | 6 ms | Frontend · unit |
| lib/era-batch.test.ts::shows only what THIS practice was paid from a shared-account batch | passed | 1 ms | Frontend · unit |
| lib/era-batch.test.ts::never throws on the null check total the server sends for a shared batch | passed | 1 ms | Frontend · unit |
| lib/era-batch.test.ts::says a batch has no amount rather than printing $0.00 | passed | 1 ms | Frontend · unit |
| lib/era-batch.test.ts::sums only numeric amountPaid, and counts the postings returned | passed | 0 ms | Frontend · unit |
| lib/error-boundary.test.ts::the dashboard has an error boundary | passed | 3 ms | Frontend · unit |
| lib/error-boundary.test.ts::the error boundary is a Client Component | passed | 1 ms | Frontend · unit |
| lib/error-boundary.test.ts::the error boundary offers recovery through unstable_retry | passed | 1 ms | Frontend · unit |
| lib/error-boundary.test.ts::the headline says the screen failed, not that records are absent | passed | 1 ms | Frontend · unit |
| lib/error-boundary.test.ts::the error boundary explicitly separates 'failed' from 'none' | passed | 1 ms | Frontend · unit |
| lib/error-boundary.test.ts::the error boundary states plainly that nothing was changed | passed | 1 ms | Frontend · unit |
| lib/error-boundary.test.ts::the error boundary surfaces the digest for support | passed | 0 ms | Frontend · unit |
| lib/error-boundary.test.ts::the dashboard has route-level loading UI | passed | 0 ms | Frontend · unit |
| lib/error-boundary.test.ts::the loading skeleton announces itself to assistive technology | passed | 1 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the default ladder is three rungs | passed | 6 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the selectable lengths come from the server's bounds, not from guesses | passed | 2 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the consequence is stated in DAYS, which is the clinician's unit | passed | 1 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the consequence names the window the breach-days are counted in | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the window is the server's number, never recomputed here | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::same-day readings counting once is said, not assumed | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::a one-rung ladder is refused with the clinical reason, not a range | passed | 1 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::an over-long ladder is refused because it reads as switched off | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::a value inside the range has no complaint | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::the top rung is labelled as the top | passed | 0 ms | Frontend · unit |
| lib/escalation-ladder.test.ts::a non-default policy is flagged as deliberate | passed | 0 ms | Frontend · unit |
| lib/escalation.test.ts::slaTone maps SLA status to colour | passed | 4 ms | Frontend · unit |
| lib/escalation.test.ts::slaLabel reads clearly in each state | passed | 1 ms | Frontend · unit |
| lib/filing-review.test.ts::the reservation is stated in words, never implied by a missing button | passed | 14 ms | Frontend · unit |
| lib/filing-review.test.ts::a screen with nothing to file names the reason, not just the zero | passed | 67 ms | Frontend · unit |
| lib/filing-review.test.ts::no claims at all is distinguished from claims that cannot go | passed | 0 ms | Frontend · unit |
| lib/filing-review.test.ts::an absent STORE is a different empty from an empty store | passed | 0 ms | Frontend · unit |
| lib/filing-review.test.ts::when something CAN be filed both numbers are given | passed | 1 ms | Frontend · unit |
| lib/filing-review.test.ts::blockers are drawn in FIX order, not discovery order | passed | 1 ms | Frontend · unit |
| lib/filing-review.test.ts::a blocker the server names but this file has never heard of is SHOWN | passed | 0 ms | Frontend · unit |
| lib/filing-review.test.ts::every blocker names whose job it is | passed | 0 ms | Frontend · unit |
| lib/filing-review.test.ts::blockers rank by MONEY, and a zero one is kept rather than dropped | passed | 1 ms | Frontend · unit |
| lib/filing-review.test.ts::the diagnosis line says which of the three empties it is | passed | 2 ms | Frontend · unit |
| lib/filing-review.test.ts::money formats to two places with separators | passed | 1 ms | Frontend · unit |
| lib/filing-review.test.ts::rankedBlockers on no data is empty rather than throwing | passed | 2 ms | Frontend · unit |
| lib/focus-trap.test.ts::Tab wraps from the last element back to the first | passed | 7 ms | Frontend · unit |
| lib/focus-trap.test.ts::Shift+Tab wraps from the first element to the last | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::mid-list Tab is left to the browser | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::focus outside the dialog is pulled back to the right edge | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::a single focusable keeps focus on itself in both directions | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::an empty dialog does not intercept Tab | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::Tab can never land outside the dialog | passed | 1 ms | Frontend · unit |
| lib/focus-trap.test.ts::focus starts on the first focusable | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::data-autofocus wins when present | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::an out-of-range autofocus falls back rather than focusing nothing | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::a dialog with no focusable content yields null so the panel takes focus | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::the selector excludes tabindex=-1 | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::the selector excludes disabled controls | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::the selector covers the interactive elements this app actually uses | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::a dialog is labelled by an id derived from its own | passed | 0 ms | Frontend · unit |
| lib/focus-trap.test.ts::dialog ids are stable and sequential, not random | passed | 0 ms | Frontend · unit |
| lib/forbidden-test-host.test.ts::the PatientMD frontend suite is not running on a forbidden host | passed | 3 ms | Frontend · unit |
| lib/gender-surfaces.test.ts::no UI surface renders a gender without going through lib/gender.ts | passed | 387 ms | Frontend · unit |
| lib/gender-surfaces.test.ts::every allow-list entry still matches real code | passed | 361 ms | Frontend · unit |
| lib/gender-surfaces.test.ts::the scan actually finds the call sites it claims to guard | passed | 389 ms | Frontend · unit |
| lib/gender.test.ts::every gender value on production maps to an option the select offers | passed | 5 ms | Frontend · unit |
| lib/gender.test.ts::the regression itself: the raw stored value is not a valid option value | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::codes this app's own form writes round-trip unchanged | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::case and punctuation do not decide the answer | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::FHIR R4 AdministrativeGender maps in full | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::X12 5010 837P DMG03 letters map in full | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::absent means absent — never guessed into a value a human never chose | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::an unmappable stored value is shown, selectable, and saved back unchanged | passed | 2 ms | Frontend · unit |
| lib/gender.test.ts::a prototype key is data, not a lookup hit | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::labels read as words, whichever spelling is stored | passed | 7 ms | Frontend · unit |
| lib/gender.test.ts::no alias may invent a fifth code the select does not offer | passed | 1 ms | Frontend · unit |
| lib/gender.test.ts::every spelling on production reads as ONE word, whatever collection it came from | passed | 1 ms | Frontend · unit |
| lib/gender.test.ts::FHIR R4 AdministrativeGender is emitted lowercase, and only its four codes | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::X12 DMG03 is F, M or U and can never be anything else | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::a filter and a stored value meet in ONE vocabulary | passed | 0 ms | Frontend · unit |
| lib/gender.test.ts::a value we cannot map is never invented, on any projection | passed | 0 ms | Frontend · unit |
| lib/global-search.test.ts::empty query returns nothing | passed | 4 ms | Frontend · unit |
| lib/global-search.test.ts::matches label + href, multi-term AND | passed | 1 ms | Frontend · unit |
| lib/guest-join.test.ts::isPinFormat: 4-8 digits only | passed | 3 ms | Frontend · unit |
| lib/guest-join.test.ts::msUntil + expiryLabel | passed | 0 ms | Frontend · unit |
| lib/guest-join.test.ts::joinUrl: no double slash | passed | 0 ms | Frontend · unit |
| lib/guest-join.test.ts::guestStep: loading/pin/ready/joined | passed | 0 ms | Frontend · unit |
| lib/guide-shots.test.ts::a name is the server's grammar and nothing else | passed | 6 ms | Frontend · unit |
| lib/guide-shots.test.ts::the path is built after the shape check, not instead of it | passed | 0 ms | Frontend · unit |
| lib/guide-shots.test.ts::fetch each name once, in the order the reader meets them | passed | 2 ms | Frontend · unit |
| lib/guide-shots.test.ts::a name that could never be served is never requested | passed | 0 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::no permissions and no context yields only the ungated top items | passed | 7 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::platform staff with platform perms see the admin blocks, not the business ones | passed | 1 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::a business membership plus ops perms sees the Care Program; a bare permission without the entity does not | passed | 4 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::a patient-self session is NOT a business entity even with an entityType | passed | 5 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::requiresAnyPerm admits either permission; requiresPerm needs its exact one | passed | 1 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::the deliberately ungated business item follows its section's context alone | passed | 3 ms | Frontend · unit |
| lib/iam/nav-catalog.test.ts::synthetic gates: requiresRole, multi-perm requiresPerm, clinical context | passed | 1 ms | Frontend · unit |
| lib/impersonation.test.ts::the operator's session survives the round trip | passed | 4 ms | Frontend · unit |
| lib/impersonation.test.ts::nothing stashed reads as nothing, not as a crash | passed | 0 ms | Frontend · unit |
| lib/impersonation.test.ts::an EXPIRED operator session is discarded rather than restored | passed | 1 ms | Frontend · unit |
| lib/impersonation.test.ts::forgetting clears it | passed | 0 ms | Frontend · unit |
| lib/impersonation.test.ts::corrupt storage reads as nothing rather than throwing | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::puts the window and every server filter in the body, dropping blanks | passed | 5 ms | Frontend · unit |
| lib/inbox.test.ts::sends a custom range as since/until, never a preset key | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::the history reads 30 days when the list shows everything awaiting | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::knows when a people filter is on | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::counts awaiting-us over the rows and carries the backlog through | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::response time says over how many, and a dash when nothing was timed | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::hours read as minutes, hours or days | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::waiting text is empty when nothing is waiting | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::unattributed names the clinic and how many are waiting | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::the cap banner only appears when something was left out | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::the transport banner is silent when we could not ask | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::by channel | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::by finding kind and severity | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::awaiting only | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::keeps the server's order | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::toggle and active | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::an option names the person, the clinic and the count — never a raw id | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::channel chips follow the vocabulary order and omit zeros | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::every channel has a label and an unknown one still reads | passed | 0 ms | Frontend · unit |
| lib/inbox.test.ts::stacks only the channels that carried something | passed | 1 ms | Frontend · unit |
| lib/inbox.test.ts::the donut omits empty channels | passed | 0 ms | Frontend · unit |
| lib/input-labels.test.ts::no NEW input is left without a programmatically associated label | passed | 112 ms | Frontend · unit |
| lib/input-labels.test.ts::the frozen list has no stale entries | passed | 16 ms | Frontend · unit |
| lib/input-labels.test.ts::the registry's Add Single Patient form is fully associated | passed | 1 ms | Frontend · unit |
| lib/invite-failure.test.ts::the copy never depends on why the token failed — no oracle | passed | 5 ms | Frontend · unit |
| lib/invite-failure.test.ts::it names the environment mismatch, not only expiry | passed | 1 ms | Frontend · unit |
| lib/invite-failure.test.ts::it shows the host, so a wrong-environment link is visible | passed | 1 ms | Frontend · unit |
| lib/invite-failure.test.ts::an unknown host does not render the word undefined | passed | 4 ms | Frontend · unit |
| lib/invite-failure.test.ts::the title is stable | passed | 0 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::reads a missing or unknown status as draft — the truthful default | passed | 3 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::passes through the two real states | passed | 0 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::a draft can only be approved | passed | 3 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::an approved invoice can be reverted or sent | passed | 0 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::a sent invoice offers NOTHING — the remedy lives in QuickBooks | passed | 0 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::names the approver and the send channel — provenance in words | passed | 4 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::a draft says it is not yet approved — status in words, not colour alone | passed | 0 ms | Frontend · unit |
| lib/invoice-lifecycle.test.ts::three distinct tones, one per state | passed | 0 ms | Frontend · unit |
| lib/invoice-summary.test.ts::no invoices is zeros and an undefined A/R ratio — never 26 days | passed | 13 ms | Frontend · unit |
| lib/invoice-summary.test.ts::days in A/R is undefined when nothing was collected | passed | 0 ms | Frontend · unit |
| lib/invoice-summary.test.ts::days in A/R is outstanding over the average day's collection | passed | 0 ms | Frontend · unit |
| lib/invoice-summary.test.ts::collections by week needs a payment date — the issue date is not cash | passed | 1 ms | Frontend · unit |
| lib/invoice-summary.test.ts::nothing outstanding ages to zeros, not a fabricated $14,850 | passed | 3 ms | Frontend · unit |
| lib/job-removal.test.ts::heldJobRows: a removable job carries no reason; a refused one says why | passed | 42 ms | Frontend · unit |
| lib/job-removal.test.ts::heldJobRows: sorted by title, and a job stored twice is listed once | passed | 3 ms | Frontend · unit |
| lib/job-removal.test.ts::heldJobRows: a name the catalogue no longer defines follows the server's allowance | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::heldJobRows: FAILS CLOSED when the rules have not loaded | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::heldJobRows: nobody's jobs is an empty list, not a crash | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::readRemovalPlan: total over a malformed body | passed | 1 ms | Frontend · unit |
| lib/job-removal.test.ts::readRemovalPlan: falls back to the job key when no title is sent | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::planLines: names what they keep, what ends, and that money closes | passed | 1 ms | Frontend · unit |
| lib/job-removal.test.ts::planLines: an empty loss is EXPLAINED — a shared key survives through another job | passed | 1 ms | Frontend · unit |
| lib/job-removal.test.ts::planLines: removing the last job says they will hold none | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::planLines: hand-granted keys that will be cleared are named before the button | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::planLines: a no-op answers with the server's own note | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::confirmTitle names the job and the person | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::personLabel: name, else login, else id | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::reasonProblem: optional, bounded to what the audit stores | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::mayConfirm: only a checked, unrefused plan with a valid reason | passed | 0 ms | Frontend · unit |
| lib/job-removal.test.ts::removedMessage: a real removal and a no-op read differently | passed | 1 ms | Frontend · unit |
| lib/lead-funnel.test.ts::buildFunnel counts stages + win rate | passed | 3 ms | Frontend · unit |
| lib/lead-funnel.test.ts::buildFunnel handles empty | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::a 403 is a refusal, not a failure | passed | 3 ms | Frontend · unit |
| lib/load-outcome.test.ts::a 400 is an incomplete question | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::a 500 and a network error are both failures | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::401 is a failure, not a refusal — an expired session is fixed by signing in | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::no error at all is ok | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::statusOf tolerates anything | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::the refusal copy does NOT claim nothing is hidden | passed | 3 ms | Frontend · unit |
| lib/load-outcome.test.ts::the incomplete copy does not claim anybody was removed | passed | 0 ms | Frontend · unit |
| lib/load-outcome.test.ts::a genuine failure keeps the reassurance, which is where it is true | passed | 1 ms | Frontend · unit |
| lib/load-outcome.test.ts::the server's own detail is carried through, never swallowed | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::calls an operator-run clinic exactly that, not 'setup pending' | passed | 3 ms | Frontend · unit |
| lib/managed.test.ts::says a suspension keeps the grants | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::distinguishes a clinic that signs in for itself | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::adds the always-granted module without it being stored | passed | 3 ms | Frontend · unit |
| lib/managed.test.ts::drops a key no module owns | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::treats an empty tick set as the always-granted set only | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::never grants everything by default | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::reports billing's missing prerequisite instead of adding it | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::reports nothing once the prerequisite is ticked | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::names the module to tick, not the one already ticked | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::handles several gaps at once | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::locks only the always-granted one | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::labels every method it can be handed | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::says email is always available | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::refuses to remove email, with the lockout reason | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::refuses to remove the only proved factor | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::allows removing a spare factor | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::asks for length and never for composition | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::catches a mistyped confirmation | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::moves to the factor picker with no token | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::routes a first sign-in to a password change, not to a session | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::only completes on a real token | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::stays put on a response it does not understand | passed | 0 ms | Frontend · unit |
| lib/managed.test.ts::the modules dialog renders the not-offered list rather than dropping it | passed | 1 ms | Frontend · unit |
| lib/managed.test.ts::every not-offered section carries a reason, not just a label | passed | 1 ms | Frontend · unit |
| lib/manual-reading.test.ts::a round trip through the pickers preserves the instant | passed | 9 ms | Frontend · unit |
| lib/manual-reading.test.ts::an unparseable value yields empty pickers rather than NaN | passed | 2 ms | Frontend · unit |
| lib/manual-reading.test.ts::a missing date or time is refused with which one is missing | passed | 1 ms | Frontend · unit |
| lib/manual-reading.test.ts::31 February is refused, not rolled forward into March | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::a reading cannot be recorded in the future | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::a reading taken earlier today is accepted | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::the picker's max is today, so the future is unreachable by mouse | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::malformed shapes are refused rather than coerced | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::a patient label reads either roster key | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::a patient with no name is never labelled with their raw id | passed | 0 ms | Frontend · unit |
| lib/manual-reading.test.ts::the DOB disambiguates two patients with the same name | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::headings render with a stable anchor and are collected | passed | 8 ms | Frontend · unit |
| lib/markdown.test.ts::a paragraph joins its wrapped lines into one | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::bullet and numbered lists close before the next block | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::a wrapped list item is ONE item, and its bold survives the wrap | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::a list item's continuation does not swallow the next item or block | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::switching list type closes the previous list | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::tables render a head, a body and their own scroll container | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::bold, italic and inline code | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::code spans are literal — markup inside them is not rendered | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::safe links render, unsafe ones lose their href entirely | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::every text path escapes HTML before emitting markup | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::a heading id is escaped even when the heading contains markup | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::fenced code blocks are literal | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::blockquotes render their contents as markdown | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::horizontal rules are rules, not empty lists | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::slugify is stable, lowercase and bounded | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::empty and whitespace input render to nothing rather than throwing | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::a real guide fragment survives end to end | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::an image line becomes a figure with a caption and NO src | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::consecutive images are one group, so they lay out as a grid | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::every source but shot: is dropped to its caption — https included | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::an image inside running text degrades to its caption, with no stray ! | passed | 0 ms | Frontend · unit |
| lib/markdown.test.ts::a caption is escaped, not trusted | passed | 1 ms | Frontend · unit |
| lib/markdown.test.ts::figures sit between the prose around them | passed | 0 ms | Frontend · unit |
| lib/marketing-links-are-host-relative.test.ts::the marketing builder's default portal host is empty, not an environment | passed | 9 ms | Frontend · unit |
| lib/marketing-links-are-host-relative.test.ts::the build ARGs carry no hostname either | passed | 2 ms | Frontend · unit |
| lib/marketing-links-are-host-relative.test.ts::no built marketing page links to a specific environment | passed | 27 ms | Frontend · unit |
| lib/marketing-links-are-host-relative.test.ts::the login and sign-up links are present and root-relative | passed | 4 ms | Frontend · unit |
| lib/marketing-links-are-host-relative.test.ts::the hostname pattern matches what it is meant to and nothing else | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::every operation the seven tabs offered still has a screen | passed | 9 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::each surviving Patient Engagement screen renders something of its own | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::every retired screen forwards rather than 404s | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::the moved screens are Client Growth screens, not Patient Engagement ones | passed | 2 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::no screen falls back to sample data | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::the retired ?tab= links all still land somewhere | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::the mailing list is still reachable after being merged into Contacts | passed | 1 ms | Frontend · unit |
| lib/marketing-merge-parity.test.ts::Contacts kept every role the Address Book brought with it | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::the ledger is not empty and every entry is complete | passed | 4 ms | Frontend · unit |
| lib/merge-ledger.test.ts::entry ids are unique | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::every operation a merge inherited still has a home | passed | 10 ms | Frontend · unit |
| lib/merge-ledger.test.ts::every relocation says WHY, and points somewhere it could have stayed | passed | 0 ms | Frontend · unit |
| lib/merge-ledger.test.ts::every retired entry point still lands somewhere real | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::a retired entry point never lands back on itself | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::a merge that splits a list names the property test that proves it | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::no inventory has been quietly shortened | passed | 1 ms | Frontend · unit |
| lib/merge-ledger.test.ts::the ledger keeps its history: known entries are still present | passed | 0 ms | Frontend · unit |
| lib/modal-a11y.test.ts::the dialog primitives declare full dialog semantics | passed | 4 ms | Frontend · unit |
| lib/modal-a11y.test.ts::the primitives contain Tab and restore focus on close | passed | 1 ms | Frontend · unit |
| lib/modal-a11y.test.ts::no NEW overlay ships without dialog semantics | passed | 99 ms | Frontend · unit |
| lib/modal-a11y.test.ts::the frozen list does not outlive the overlays it names | passed | 70 ms | Frontend · unit |
| lib/modal-a11y.test.ts::the not-a-dialog exemptions still name real overlay-shaped regions | passed | 63 ms | Frontend · unit |
| lib/modal-a11y.test.ts::every hand-rolled overlay has been migrated | passed | 0 ms | Frontend · unit |
| lib/money-hidden.test.ts::only the server's own flag counts as hidden | passed | 3 ms | Frontend · unit |
| lib/money-hidden.test.ts::a 403 is a refusal; any other failure is not | passed | 0 ms | Frontend · unit |
| lib/money-hidden.test.ts::an absent amount is null, never a zero the server did not send | passed | 3 ms | Frontend · unit |
| lib/money-hidden.test.ts::the notes name no amount themselves | passed | 1 ms | Frontend · unit |
| lib/money-load.test.ts::a 403 is a refusal, not a fault | passed | 6 ms | Frontend · unit |
| lib/money-load.test.ts::any other failure quotes the server | passed | 1 ms | Frontend · unit |
| lib/money-load.test.ts::a bare 'HTTP 502' is reported as the status, not quoted | passed | 0 ms | Frontend · unit |
| lib/money-load.test.ts::a failure with no words and no status says so | passed | 0 ms | Frontend · unit |
| lib/money-load.test.ts::a network error's own words are kept | passed | 0 ms | Frontend · unit |
| lib/money-load.test.ts::statusOf reads only a numeric status | passed | 0 ms | Frontend · unit |
| lib/money-load.test.ts::a 403 decided by lib/money-hidden's isRefusal, not a second definition | passed | 0 ms | Frontend · unit |
| lib/money-screens.test.ts::each money page is gated on its own menu href | passed | 8 ms | Frontend · unit |
| lib/money-screens.test.ts::the gate refuses a Monitoring Specialist on every gated page | passed | 2 ms | Frontend · unit |
| lib/money-screens.test.ts::the money screens substitute no sample figures | passed | 14 ms | Frontend · unit |
| lib/money-screens.test.ts::the merchant seed module stays deleted | passed | 0 ms | Frontend · unit |
| lib/money-screens.test.ts::guard the guard: the scans still catch what they were written for | passed | 1 ms | Frontend · unit |
| lib/monitored.test.ts::'never transmitted' is its own answer and never a number | passed | 4 ms | Frontend · unit |
| lib/monitored.test.ts::the headline leads with the ones who need a call, not the healthy ones | passed | 1 ms | Frontend · unit |
| lib/monitored.test.ts::an empty roster says nobody is monitored AND nobody is waiting | passed | 0 ms | Frontend · unit |
| lib/monitored.test.ts::the window is explained as a PARTITION, so nothing reads as hidden | passed | 0 ms | Frontend · unit |
| lib/monitored.test.ts::a clinic filter must NAME what it withheld — Article III.10 | passed | 0 ms | Frontend · unit |
| lib/monitored.test.ts::rule 15 — an empty returns chart is not 'nothing came back' | passed | 1 ms | Frontend · unit |
| lib/monitored.test.ts::both spellings of blood pressure wear one label | passed | 0 ms | Frontend · unit |
| lib/monitored.test.ts::this module declares no vocabulary of its own — rule 13 | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the header carries five counts, the filters six | passed | 6 ms | Frontend · unit |
| lib/monitoring-board.test.ts::minutes are the floor of the measurement, capped at one encounter | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::elapsed renders m:ss and never goes negative | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::bulk approve excludes the item being read and offers nothing-new rows first | passed | 3 ms | Frontend · unit |
| lib/monitoring-board.test.ts::bulk approve never grows beyond what was scrolled past | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::keys are ignored while typing in a field | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the filter narrows by kind and by text over name, title and finding | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::severity dialects collapse to one scale | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the care-time line says what will be logged, or that nothing will | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the adapter presents a board item as the Action Center's queue shape | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::grouping keeps the server's order and folds a patient's items into one row | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the group summary speaks the desk's words, never a kind slug | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::needs action now is urgent OR overdue | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the backlog tile names the kinds, biggest first, or says nothing is waiting | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::history series carry a label and a colour per kind | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::measured minutes are stated honestly when the desk has not used the board | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::every kind is always present, in the board's fixed order | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::Alerts is on the page even for a practice that has never had one | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the window count and the backlog are carried separately | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::a kind with work in the window does not claim to be backlog | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the title says which number is which | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::a chip with no backlog says nothing about a backlog | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::resolving an item selects the one below it | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the LAST item falls back to the one above, and the only item to nothing | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::a key that is not on the list resolves to nothing rather than to row 0 | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::removing an item decrements its kind's count, the total and nothingNew | passed | 1 ms | Frontend · unit |
| lib/monitoring-board.test.ts::removing an alert does not touch nothingNew, and never goes below zero | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::removing a key that is not there returns the queue unchanged | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::the template list leads with the chosen activity's templates, by title | passed | 45 ms | Frontend · unit |
| lib/monitoring-board.test.ts::an activity with no templates offers every template under 'others' | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::a programme switch keeps an activity both lists share and clears the rest | passed | 0 ms | Frontend · unit |
| lib/monitoring-board.test.ts::a stored mode reads as its button, and an unknown one as itself | passed | 0 ms | Frontend · unit |
| lib/month-close.test.ts::only a rescuable row is presented as work | passed | 3 ms | Frontend · unit |
| lib/month-close.test.ts::state labels and tones say which is which in words | passed | 17 ms | Frontend · unit |
| lib/month-close.test.ts::usd never renders a missing amount as NaN on a billing screen | passed | 0 ms | Frontend · unit |
| lib/month-close.test.ts::a closed month is not urgent — it is over | passed | 1 ms | Frontend · unit |
| lib/month-close.test.ts::the headline leads with money that can still be saved, not the total | passed | 1 ms | Frontend · unit |
| lib/month-close.test.ts::nextStep gives one action, and explains an unreachable row instead | passed | 1 ms | Frontend · unit |
| lib/month-close.test.ts::a headline for a caller who may not see money names patients, never $0.00 | passed | 0 ms | Frontend · unit |
| lib/month-close.test.ts::a withheld patient amount is null, never a zero the server did not send | passed | 0 ms | Frontend · unit |
| lib/nav-distinct-screens.test.ts::no two entries in one app's menu land on the same screen | passed | 7 ms | Frontend · unit |
| lib/nav-distinct-screens.test.ts::every entry points at a page that actually exists | passed | 14 ms | Frontend · unit |
| lib/nav-distinct-screens.test.ts::no entry points at a page whose only job is to redirect | passed | 155 ms | Frontend · unit |
| lib/nav-distinct-screens.test.ts::a query string never carries the identity of a screen | passed | 2 ms | Frontend · unit |
| lib/nav-distinct-screens.test.ts::the guard covers every role menu, including the aliases | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::no standalone Ops heading survives in the business sidebar | passed | 3 ms | Frontend · unit |
| lib/nav.test.ts::the care programme is ONE section ordered by the patient journey | passed | 6 ms | Frontend · unit |
| lib/nav.test.ts::clinical and operational screens sit in the SAME module | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::Patient Engagement is one section, grouped by AUDIENCE | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::the B2B pipeline is NOT in Patient Engagement | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::Client Growth and Client Success are their own sections | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::the Rules Engine is reachable from the business sidebar | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::every business href is still reachable and unique | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::staff still lose exactly the owner-only surfaces, nothing more | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::the permission-derived nav mirrors the same structure | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::the permission-derived nav IS the static nav — full bidirectional parity | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::every menu item has an IAM permission gate, and no gate is stale | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::a label names ONE screen within a role's menu | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::no duplicate hrefs within a single role's menu | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::the Care-Time redirect is not offered as its own menu item | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::messaging is one parent group, not loose sidebar items | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::Contact Patient sits with the practice inbox, not on its own | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::the doctor's care programme carries the same journey stages | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::every role's menu is a handful of sections, each regrouped, none lost | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::every hanType spelling resolves to its role's menu, never the patient fallback | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::there is no second ops module beside Care Program | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::Training is the first thing a business user sees in the sidebar | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::Training is reachable exactly once | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::the training manual is not offered to patients | passed | 0 ms | Frontend · unit |
| lib/nav.test.ts::Carrier Accounts is the ONLY part of device returns outside the business app | passed | 1 ms | Frontend · unit |
| lib/nav.test.ts::Account Access is offered to platform admins and NOT to a business admin | passed | 1 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::the detector flags a real call in every spelling | passed | 4 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::prose about the rule is not a breach of it | passed | 1 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::a file's own function of the same name is not the browser's | passed | 1 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::the scan actually covered the app | passed | 0 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::no screen collects a value with the browser's prompt box | passed | 0 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::the Ops console uses none of the three, and has no allow-list entry to hide one in | passed | 0 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::the prompt allow-list is shrink-only: every entry still matches exactly what is there | passed | 0 ms | Frontend · unit |
| lib/no-browser-prompt.test.ts::confirm() and alert() may only go down | passed | 0 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::finds no site outside the frozen list | passed | 3 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::has no stale entry — a fixed file may not stay on the list | passed | 0 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::no frozen file grows a NEW one | passed | 0 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::the screens QA reported no longer name a tenant on their READS | passed | 1 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::no API helper accepts the caller's own tenant id as a parameter | passed | 1007 ms | Frontend · unit |
| lib/no-client-tenant.test.ts::the allow-list does not outlive the helpers it names | passed | 15 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::no screen decides signed-in-ness from a field the envelope may omit | passed | 265 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::the guard would catch the original defect | passed | 1 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::the guard does not flag a comment that quotes the banned expression | passed | 0 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::treats a token as the whole test for a session | passed | 1 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::resolves the tenant as corpId or userId, in that order | passed | 0 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::never invents a branch | passed | 1 ms | Frontend · unit |
| lib/no-corpid-signin-gate.test.ts::permits sample data only when signed out | passed | 0 ms | Frontend · unit |
| lib/no-fabricated-form-defaults.test.ts::no billing form opens pre-filled with a fabricated value | passed | 7 ms | Frontend · unit |
| lib/no-fabricated-form-defaults.test.ts::the scanner reads initialisers and not prose | passed | 3 ms | Frontend · unit |
| lib/no-fabricated-form-defaults.test.ts::an empty default is what the fix looks like | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::no screen falls back to an identifier where a name belongs | passed | 162 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::the allow-list does not outlive the files it names | passed | 3 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::the scanner actually matches the shape it was written for | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::a resolved name is returned as-is | passed | 1 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::the canonical server key wins over the legacy ones | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::an unresolvable person is named in words, never by id | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::the synthetic login handle is not a name | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::unassigned and unresolvable are different answers | passed | 0 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::search matches names and never identifiers | passed | 1 ms | Frontend · unit |
| lib/no-id-as-name.test.ts::an empty query matches everything | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::the scan reaches the screens at all | passed | 76 ms | Frontend · unit |
| lib/no-invented-records.test.ts::no screen substitutes invented records for a real answer | passed | 296 ms | Frontend · unit |
| lib/no-invented-records.test.ts::the allow-list names only files that still need it | passed | 313 ms | Frontend · unit |
| lib/no-invented-records.test.ts::every allow-list entry says why | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: empty-ternary is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: data-ternary is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: or-fallback is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: seed-merge is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: empty-if-seed is detected | passed | 1 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: catch-seed is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: catch-seed-call is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: a computed seed on the success path is detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: seed rows WRITTEN to the server on an empty read are detected | passed | 0 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: the signed-out preview and honest fallbacks are NOT flagged | passed | 1 ms | Frontend · unit |
| lib/no-invented-records.test.ts::probe: prose about the defect does not trip the guard | passed | 1 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::the scanner sees the files it is meant to scan | passed | 95 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::no new screen calls the API with a bare fetch | passed | 120 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::the frozen list carries no stale entries | passed | 106 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::the non-API allow-list carries no stale entries, and every entry gives a reason | passed | 145 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::an exempted file fetches a same-origin path, never the API base | passed | 1 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::apiFetch is exported for them to migrate onto | passed | 2 ms | Frontend · unit |
| lib/no-raw-api-fetch.test.ts::the shared client applies a deadline | passed | 3 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::clinical, billing and privacy screens NEVER seed on failure | passed | 3776 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::these screens use the shared data-state rule | passed | 6 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::no NEW screen starts seeding on failure | passed | 8967 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::the frozen list does not outlive the screens it names | passed | 8774 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::the settings form cannot save what it could not load | passed | 1 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::the widened scanner catches the lowercase-seed shape it was written for | passed | 0 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::the scanner does not flag an ordinary length check | passed | 0 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::the comment stripper removes prose and keeps code | passed | 0 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::a seed constant is caught whatever it is called | passed | 0 ms | Frontend · unit |
| lib/no-seed-on-failure.test.ts::importing a seed for a signed-out preview is still allowed | passed | 1 ms | Frontend · unit |
| lib/no-signed-in-user-as-subject.test.ts::no screen passes the session's own id into a subject-taking helper | passed | 150 ms | Frontend · unit |
| lib/no-signed-in-user-as-subject.test.ts::the helpers themselves take only a token | passed | 6 ms | Frontend · unit |
| lib/no-signed-in-user-as-subject.test.ts::neither helper puts a doctorId on the wire | passed | 5 ms | Frontend · unit |
| lib/no-unguarded-refetch.test.ts::the scanner finds effects at all | passed | 145 ms | Frontend · unit |
| lib/no-unguarded-refetch.test.ts::patient-identified screens drop stale responses | passed | 121 ms | Frontend · unit |
| lib/no-unguarded-refetch.test.ts::a patient-identified screen may never be added to the frozen list | passed | 0 ms | Frontend · unit |
| lib/no-unguarded-refetch.test.ts::no new unguarded refetch appears | passed | 133 ms | Frontend · unit |
| lib/no-unguarded-refetch.test.ts::the frozen list carries no stale entries | passed | 169 ms | Frontend · unit |
| lib/notes-draft.test.ts::mmss renders a transcript clock | passed | 3 ms | Frontend · unit |
| lib/notes-draft.test.ts::the doctor's edits win over the draft, and a struck section stays struck | passed | 0 ms | Frontend · unit |
| lib/notes-draft.test.ts::a note is signable only when bound to a patient with something in it | passed | 0 ms | Frontend · unit |
| lib/npi.test.ts::the check digit is computed over the 80840 issuer prefix | passed | 4 ms | Frontend · unit |
| lib/npi.test.ts::a valid NPI is accepted | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::a transposed pair is caught — the whole reason this runs at the keyboard | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::a repdigit string is refused even when it passes Luhn | passed | 0 ms | Frontend · unit |
| lib/npi.test.ts::punctuation is stripped, so a pasted 123-456-7893 works | passed | 0 ms | Frontend · unit |
| lib/npi.test.ts::an empty NPI is not an error — people are hired before the NPI arrives | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::a wrong length says how many digits were given | passed | 0 ms | Frontend · unit |
| lib/npi.test.ts::a taxonomy code may carry letters anywhere — 363LP2300N is real | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::a taxonomy code of the wrong length is refused | passed | 0 ms | Frontend · unit |
| lib/npi.test.ts::eligibility needs BOTH an NPI and a taxonomy, and says which is missing | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::every ineligible answer carries a next step | passed | 1 ms | Frontend · unit |
| lib/npi.test.ts::a stored NPI that fails its check digit is reported, not silently ignored | passed | 0 ms | Frontend · unit |
| lib/onboarding-history.test.ts::waiting for a care plan is named as the consequence it is | passed | 5 ms | Frontend · unit |
| lib/onboarding-history.test.ts::a pipeline with everyone enrolled is not described as a backlog | passed | 1 ms | Frontend · unit |
| lib/onboarding-history.test.ts::nobody entering is a different statement from nobody enrolled | passed | 0 ms | Frontend · unit |
| lib/onboarding-history.test.ts::a young pipeline does not claim an age it cannot support | passed | 0 ms | Frontend · unit |
| lib/onboarding-history.test.ts::the funnel caveat names the legacy enrolments that explain the gap | passed | 0 ms | Frontend · unit |
| lib/onboarding-history.test.ts::with no legacy enrolments the caveat is just the base note | passed | 0 ms | Frontend · unit |
| lib/onboarding.test.ts::a phase reports its own state, and a passed phase with open steps is 'catch up' | passed | 3 ms | Frontend · unit |
| lib/onboarding.test.ts::all six phases survive grouping, including an empty one | passed | 3 ms | Frontend · unit |
| lib/onboarding.test.ts::the plan opens on the phase to catch up, before the current one | passed | 1 ms | Frontend · unit |
| lib/onboarding.test.ts::remaining time counts only open steps and reads like a person wrote it | passed | 1 ms | Frontend · unit |
| lib/onboarding.test.ts::the greeting follows the viewer's clock | passed | 2 ms | Frontend · unit |
| lib/onboarding.test.ts::only an amount in a money section becomes currency — a count never does | passed | 73 ms | Frontend · unit |
| lib/onboarding.test.ts::sections needing attention come first; an unavailable one goes last | passed | 1 ms | Frontend · unit |
| lib/onboarding.test.ts::jobs read as words, and no job says what to do about it | passed | 1 ms | Frontend · unit |
| lib/onboarding.test.ts::tourHref: the patient app's tour lives on the guide, every other on Training | passed | 0 ms | Frontend · unit |
| lib/one-h1-per-page.test.ts::the dashboard shell renders no <h1> of its own | passed | 5 ms | Frontend · unit |
| lib/one-h1-per-page.test.ts::only shared header components render an <h1> inside components/ | passed | 33 ms | Frontend · unit |
| lib/one-h1-per-page.test.ts::the comment-stripper does not hide a real <h1> | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::the download path is derived from the id, on this application | passed | 5 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::an id with URL-significant characters cannot escape its segment | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::the saved file names the clinic and the month | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::a missing clinic or month falls back rather than collapsing | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::the reserved placeholder hosts are recognised as unopenable | passed | 1 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::an empty or unparseable URL is treated as no document | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::a relative path is not an external document | passed | 0 ms | Frontend · unit |
| lib/ops-billing-extract.test.ts::a genuinely reachable external document is left alone | passed | 0 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::a chosen clinic is the clinic | passed | 5 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::the rollup is not a clinic, and nothing is substituted for it | passed | 1 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::the refusal says what to do | passed | 1 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::no Ops screen falls back to a hard-coded clinic id | passed | 8 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::the three device screens take the clinic from the patient, through one rule | passed | 2 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::every other one of the eight asks the shared rule | passed | 2 ms | Frontend · unit |
| lib/ops-new-row-clinic.test.ts::the literal-fallback detector fires on the old line | passed | 0 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::the timesheet activities are the server's Literal, in its order | passed | 8 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::minutes are billed: no zero, no text, no 25-hour day, and no default | passed | 2 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::a timesheet payload is typed, and carries the clinic it was filed under | passed | 1 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::a contact needs a name; email and phone are checked only when given | passed | 1 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::an APCM row collects both insurance lines, nested the way the model stores them | passed | 1 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::a stored gender the vocabulary does not know round-trips instead of being blanked | passed | 2 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::an edit sends back what the form does not show, and never Mongo's _id | passed | 1 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::money is a dollar amount and CPT codes are five characters | passed | 0 ms | Frontend · unit |
| lib/ops-row-forms.test.ts::a call can be logged with no note, but not without a day to call again | passed | 1 ms | Frontend · unit |
| lib/option-search.test.ts::normalise folds case, accents and whitespace | passed | 8 ms | Frontend · unit |
| lib/option-search.test.ts::an empty query shows everything in the caller's order | passed | 1 ms | Frontend · unit |
| lib/option-search.test.ts::every token must match, in any order | passed | 10 ms | Frontend · unit |
| lib/option-search.test.ts::an accent in the data does not hide the row from a plain query | passed | 1 ms | Frontend · unit |
| lib/option-search.test.ts::the id and the hint are searched, so a pasted id still finds its row | passed | 2 ms | Frontend · unit |
| lib/option-search.test.ts::ranking: starts-with beats a word-start beats a substring | passed | 1 ms | Frontend · unit |
| lib/option-search.test.ts::the cap renders the best rows and counts the rest instead of dropping them | passed | 26 ms | Frontend · unit |
| lib/option-search.test.ts::arrow keys wrap and an empty list highlights nothing | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::imei: an empty value is refused and names what to look at | passed | 4 ms | Frontend · unit |
| lib/order-form.test.ts::imei: fifteen digits is accepted, sixteen (IMEISV) too | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::imei: the wrong length is refused and says how many were given | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::imei: punctuation from a sticker is stripped, not rejected | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::imei: letters alone are refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::imei: a Luhn failure WARNS and never blocks | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::imei: a valid check digit says nothing | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::tracking: carrier spacing is normalized to what a courier site takes | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::tracking: a half-pasted value is refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::tracking: punctuation is refused rather than silently dropped | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: a patient must be SELECTED, never typed | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::create: no clinic is refused, and the message names the fix | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::create: the clinic is never invented from a default | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: a vendor and a device name are both required | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: 'Other' takes its name from the free-text box | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: 'Other' with an empty name is refused, not saved as blank | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: units must be a whole number, one or more | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: a blank price is allowed and becomes zero | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: a negative price is refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: the payload carries the resolved patient id and clinic | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::create: the payload never carries a tenant id the client chose | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: appends the IMEI and tracking number, normalized | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::edit: only what changed is sent | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: a blank field means leave it alone, never clear it | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: a malformed IMEI is refused before anything is sent | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: a carrier with no tracking number is refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: marking shipped records the tracking number in the same save | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: marking shipped with no tracking number anywhere is refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: a value already on file counts — it is not re-typed | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::edit: marking delivered with no IMEI anywhere is refused | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::grid: a missing display value says so in words | passed | 1 ms | Frontend · unit |
| lib/order-form.test.ts::grid: a row missing anything the fulfillment person needs is flagged | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::grid: the rollup groups by clinic; a chosen clinic keeps the queue order | passed | 45 ms | Frontend · unit |
| lib/order-form.test.ts::grid: rows whose clinic could not be resolved sort LAST | passed | 0 ms | Frontend · unit |
| lib/order-form.test.ts::grid: search matches what a human reads, never the identifier | passed | 0 ms | Frontend · unit |
| lib/otp-input.test.ts::a pasted code keeps only its digits | passed | 3 ms | Frontend · unit |
| lib/otp-input.test.ts::a clean six-digit code is submittable | passed | 5 ms | Frontend · unit |
| lib/otp-input.test.ts::an empty field asks for the code rather than failing silently | passed | 1 ms | Frontend · unit |
| lib/otp-input.test.ts::a short code says how short, and is not sent | passed | 0 ms | Frontend · unit |
| lib/otp-input.test.ts::a long paste is refused, never silently truncated | passed | 0 ms | Frontend · unit |
| lib/otp-input.test.ts::null and undefined are handled like an empty field | passed | 0 ms | Frontend · unit |
| lib/otp-input.test.ts::the length matches the server's generator | passed | 0 ms | Frontend · unit |
| lib/party-picker.test.ts::one letter is not a search; two are | passed | 10 ms | Frontend · unit |
| lib/party-picker.test.ts::the line under a name says what kind of person and how to tell them apart | passed | 1 ms | Frontend · unit |
| lib/party-picker.test.ts::picking somebody twice is one recipient | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::the minimum matches the server's MIN_PASSWORD_LEN | passed | 3 ms | Frontend · unit |
| lib/password-policy.test.ts::a password exactly at the minimum is accepted | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::the refusal names the rule rather than restating that it failed | passed | 1 ms | Frontend · unit |
| lib/password-policy.test.ts::an empty password is refused, and not with the length message | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::NO composition rule is enforced, deliberately | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::the meter is advice and the gate is a contract — they may disagree | passed | 1 ms | Frontend · unit |
| lib/password-policy.test.ts::the meter rewards length at least as much as punctuation | passed | 1 ms | Frontend · unit |
| lib/password-policy.test.ts::the meter never indexes past its label list | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::confirmation must match, and an empty confirmation says what to do | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::the login identifier accepts anything the server resolves | passed | 0 ms | Frontend · unit |
| lib/password-policy.test.ts::only an empty identifier is refused | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::a blood-pressure reading yields all three of its metrics | passed | 10 ms | Frontend · unit |
| lib/patient-detail.test.ts::each device family contributes its own metrics | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::a reading with no recognised payload contributes nothing | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::a non-numeric value is dropped, not coerced | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::the summary reports count, highest, lowest and average per metric | passed | 7 ms | Frontend · unit |
| lib/patient-detail.test.ts::averages are rounded to one decimal | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::trend points come out chronological, whatever order they arrived in | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::a reading with no timestamp is excluded from the trend | passed | 2 ms | Frontend · unit |
| lib/patient-detail.test.ts::an over-long range is clamped and says so | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::a range inside the cap is left exactly alone | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::the default range is the last 30 days | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::inRange is inclusive of both ends | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::the CSV has one row per reading EVENT, not one per metric, and quotes defensively | passed | 4 ms | Frontend · unit |
| lib/patient-detail.test.ts::the patient header never renders a blank cell | passed | 2 ms | Frontend · unit |
| lib/patient-detail.test.ts::age is computed in whole years and omitted when unknowable | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::a negative epoch (born before 1970) is a real date, not raw digits | passed | 74 ms | Frontend · unit |
| lib/patient-detail.test.ts::the same epoch survives being serialized as a numeric string | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::an ISO date string still formats, and nonsense still says so | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::headerFields renders the formatted DOB, never the raw epoch | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::the clinic label never falls back to the raw branch id | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::address fields prefill from the row, and default to empty strings | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::readingTime accepts either timestamp field | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::no coverage of any kind yields no rows — so the card can say so | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::a bizpatient.coverageInfo row binds to the card's own fields | passed | 1 ms | Frontend · unit |
| lib/patient-detail.test.ts::sequencenum orders the rows whether it is a string, a number or absent | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::a carrier or member id the row does not carry is a dash, never blank | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::the pre-26_8_28 payor/carrier spellings still bind | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::onFile is a fallback for a patient with no coverages, and only then | passed | 0 ms | Frontend · unit |
| lib/patient-detail.test.ts::a malformed coverages entry is skipped, not rendered as a broken row | passed | 0 ms | Frontend · unit |
| lib/patient-export.test.ts::filename uses the patient's name, not their id (QA 26_8_25 §5) | passed | 4 ms | Frontend · unit |
| lib/patient-export.test.ts::filename falls back to the id only when no name is on file | passed | 5 ms | Frontend · unit |
| lib/patient-export.test.ts::patientDisplayName trims and joins first/last | passed | 2 ms | Frontend · unit |
| lib/patient-export.test.ts::ruleRangeRows reports 'no rules on file' rather than an empty table | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::ruleRangeRows renders a dash for a bound the rule doesn't set, never 0 | passed | 7 ms | Frontend · unit |
| lib/patient-export.test.ts::rulesFromMonitoring flattens the per-reading-type effective rule into flat rows | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::rulesFromMonitoring never throws on a missing/malformed entry | passed | 0 ms | Frontend · unit |
| lib/patient-export.test.ts::measurementsExportCsv consolidates one reading event per row (QA §2) | passed | 13 ms | Frontend · unit |
| lib/patient-export.test.ts::measurementsExportCsv never falls back to the raw id in the Patient cell | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::measurementsExportCsv appends TMS notes only when asked for | passed | 60 ms | Frontend · unit |
| lib/patient-export.test.ts::measurementsExportCsv's TMS-notes table is the SAME six columns as the Care Time PDF's own notes table (QA 26_8_25 §5.3) | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::measurementsExportCsv reads legacy-shaped care-time rows too (contractType/communicationMode, not carePlan/commMode) | passed | 0 ms | Frontend · unit |
| lib/patient-export.test.ts::toTmsPatientBlock reads the same demog.* fields headerFields does | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::toTmsPatientBlock never renders 'Invalid Date' when dob is unset | passed | 0 ms | Frontend · unit |
| lib/patient-export.test.ts::toTmsPatientBlock falls back to top-level dob/gender, same as headerFields | passed | 1 ms | Frontend · unit |
| lib/patient-export.test.ts::toTmsPatientBlock prefers demog.* over the top-level fallback when both exist | passed | 1 ms | Frontend · unit |
| lib/patient-find.test.ts::treats an email or MRN match as certain | passed | 2 ms | Frontend · unit |
| lib/patient-find.test.ts::treats a name-only match as one to CHECK, not as a match | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::keeps three levels, because two would lose the distinction that matters | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::trusts weakMatch even if the basis says otherwise | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::gives a reason, never a field name | passed | 1 ms | Frontend · unit |
| lib/patient-find.test.ts::names the date of birth in the caution when there is one to check | passed | 1 ms | Frontend · unit |
| lib/patient-find.test.ts::says so when there is no date of birth to check against | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::states that nothing has been merged when several records are held | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::says nothing at all about an ordinary single strong match | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::summarises three records across three rosters in one line | passed | 1 ms | Frontend · unit |
| lib/patient-find.test.ts::does not say '1 records' for a single row | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::never leaks a collection name to the screen | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::passes an unknown roster through rather than inventing a label | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::needs two characters | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::accepts four digits of a phone number | passed | 0 ms | Frontend · unit |
| lib/patient-find.test.ts::carries the EMR export's own column names | passed | 1 ms | Frontend · unit |
| lib/patient-find.test.ts::requires only a name | passed | 7 ms | Frontend · unit |
| lib/patient-find.test.ts::does not count whitespace as a name | passed | 0 ms | Frontend · unit |
| lib/pdf-sign.test.ts::placement: each corner, inset by margin, origin bottom-left | passed | 9 ms | Frontend · unit |
| lib/pdf-sign.test.ts::placement: clamps a box bigger than the page to 0 | passed | 0 ms | Frontend · unit |
| lib/pdf-sign.test.ts::signatureBlock: name + date, reason only when present | passed | 1 ms | Frontend · unit |
| lib/pdf-sign.test.ts::clampPage: in-range, over, under/NaN → last | passed | 0 ms | Frontend · unit |
| lib/pdf-sign.test.ts::receiptId: stable format ES-XXXXXX-YYYY | passed | 1 ms | Frontend · unit |
| lib/pdf-sign.test.ts::CORNERS covers all four | passed | 0 ms | Frontend · unit |
| lib/phase-chip.test.ts::every state x selected is pinned | passed | 18 ms | Frontend · unit |
| lib/phase-chip.test.ts::an unknown state falls back to a readable chip, never to no classes | passed | 0 ms | Frontend · unit |
| lib/phase-chip.test.ts::state is never carried by colour alone — every state has words (SC 1.4.1) | passed | 1 ms | Frontend · unit |
| lib/phase-chip.test.ts::the guard itself catches what shipped on 2026-09-16 | passed | 1 ms | Frontend · unit |
| lib/phase-chip.test.ts::no chip class uses dark:, an alpha text colour, an opacity or a palette text shade | passed | 1 ms | Frontend · unit |
| lib/phase-chip.test.ts::the component takes its chip classes from here and adds none of its own | passed | 2 ms | Frontend · unit |
| lib/phase-chip.test.ts::every state clears AA with room, in every portal — both text lines share this colour | passed | 7 ms | Frontend · unit |
| lib/phase-chip.test.ts::the selected ring and the state borders are visible as non-text (SC 1.4.11) | passed | 3 ms | Frontend · unit |
| lib/phase-chip.test.ts::the old foreground really does fail — the floor is measuring something | passed | 1 ms | Frontend · unit |
| lib/phone-format.test.ts::the country code is rendered, not stripped | passed | 7 ms | Frontend · unit |
| lib/phone-format.test.ts::a stored number with no country code assumes US rather than rendering unusable | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::a country code already inside the number is not doubled | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::non-US numbers keep their own code and are not forced into US grouping | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::an absent number shows the fallback, never a stray '+1' | passed | 1 ms | Frontend · unit |
| lib/phone-format.test.ts::tel href carries the country code so mobile dialers accept it | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::country code normalizes from any stored spelling | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::digits are extracted from any formatting | passed | 0 ms | Frontend · unit |
| lib/phone-format.test.ts::record helper accepts the field spellings actually stored | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::the hostname decides the portal, and only as its first label | passed | 4 ms | Frontend · unit |
| lib/portal-theme.test.ts::the middleware's app-mode maps to the same three portals | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::each account type wears the colours of the job it signs in to do | passed | 1 ms | Frontend · unit |
| lib/portal-theme.test.ts::an account we cannot classify is NEVER guessed into a colour | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::a session carrying only `role` still resolves — the 26_8_5 shape | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::the host wins whenever it names a portal | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::the account is consulted only when the host names nothing | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::the pre-paint bootstrap agrees with portalFromHost on every host | passed | 1 ms | Frontend · unit |
| lib/portal-theme.test.ts::the bootstrap reads the PATH when the host names no portal | passed | 1 ms | Frontend · unit |
| lib/portal-theme.test.ts::a stale session cannot repaint a login door | passed | 0 ms | Frontend · unit |
| lib/portal-theme.test.ts::the bootstrap cannot throw — a theme must not break the page | passed | 1 ms | Frontend · unit |
| lib/portal-theme.test.ts::every portal has a label and a theme colour | passed | 1 ms | Frontend · unit |
| lib/portal-theme.test.ts::the theme colour matches the primary the stylesheet renders | passed | 7 ms | Frontend · unit |
| lib/practice-console.test.ts::the device summary leads with what can be assigned, not with the total | passed | 4 ms | Frontend · unit |
| lib/practice-console.test.ts::a fully assigned fleet says so rather than saying zero spares | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::an empty device book says it is empty | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a partial IMEI matches — a biller reads the last digits off a sticker | passed | 1 ms | Frontend · unit |
| lib/practice-console.test.ts::search also matches the patient, the model and the serial | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::the status filter and the search compose | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::the device fee is finite and the screen says how many months are left | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a paid-off device says paid off, not $0.00 | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a month that never ran is distinguished from a month that found nobody | passed | 5 ms | Frontend · unit |
| lib/practice-console.test.ts::enrolled but nothing billable names the number enrolled | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a clinic named after its own identifier admits it | passed | 1 ms | Frontend · unit |
| lib/practice-console.test.ts::programme rows come back biggest first | passed | 1 ms | Frontend · unit |
| lib/practice-console.test.ts::unattributed money is the headline when there is any | passed | 1 ms | Frontend · unit |
| lib/practice-console.test.ts::an empty month invites the first upload rather than showing zeroes | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a fully reconciled month says so | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::the work queue puts denials first and the biggest balance on top | passed | 3 ms | Frontend · unit |
| lib/practice-console.test.ts::the collection rate is null while everything is still with the payer | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::the invoice shows both halves and where each came from | passed | 0 ms | Frontend · unit |
| lib/practice-console.test.ts::a month where every device is paid off says that, not 'no devices' | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::the default billing month is the one that just ended | passed | 5 ms | Frontend · unit |
| lib/programme-claims.test.ts::month labels are human, and non-months pass through untouched | passed | 1 ms | Frontend · unit |
| lib/programme-claims.test.ts::the four programmes match the backend's own list | passed | 2 ms | Frontend · unit |
| lib/programme-claims.test.ts::candidates split into billable, blocked and earned-nothing | passed | 1 ms | Frontend · unit |
| lib/programme-claims.test.ts::a patient with no lines but a blocking finding is blocked, not quiet | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::splitCandidates tolerates missing arrays rather than throwing | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::release messages carry the refusal reason verbatim | passed | 2 ms | Frontend · unit |
| lib/programme-claims.test.ts::a partial release says what is still held | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a clean release does not invent a held count | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a wholly simulated submission says NOTHING WAS FILED, first | passed | 1 ms | Frontend · unit |
| lib/programme-claims.test.ts::a real submission reports accepted, rejected and simulated separately | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a mixed batch flags the simulated portion even when some were accepted | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a refused submission shows the remedy alongside the reason | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::an incomplete claim is counted apart from one that could not be sent | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a batch where nothing was sent says so first, and says to submit again | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::a simulated batch with claims still waiting does not read as 'nothing filed' only | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::typed ICD-10 codes are parsed the way the server validates them | passed | 1 ms | Frontend · unit |
| lib/programme-claims.test.ts::the shape check mirrors ccm.vocabulary: a dot is required past three characters | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::suggested codes come only from the no_diagnosis_code finding | passed | 1 ms | Frontend · unit |
| lib/programme-claims.test.ts::saving a diagnosis says to re-assemble, naming the month | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::tones distinguish the states a person acts on differently | passed | 0 ms | Frontend · unit |
| lib/programme-claims.test.ts::collection rate is paid over BILLED, and is null when nothing was billed | passed | 0 ms | Frontend · unit |
| lib/provisioning.test.ts::a platform job mints a staff account, never a platform admin | passed | 5 ms | Frontend · unit |
| lib/provisioning.test.ts::a client-practice job mints a managed business | passed | 10 ms | Frontend · unit |
| lib/provisioning.test.ts::a kind the server did not offer is refused rather than sent | passed | 0 ms | Frontend · unit |
| lib/provisioning.test.ts::no jobs chosen has no answer | passed | 0 ms | Frontend · unit |
| lib/provisioning.test.ts::jobs from both realms have no single answer | passed | 0 ms | Frontend · unit |
| lib/provisioning.test.ts::one realm repeated is still one realm | passed | 1 ms | Frontend · unit |
| lib/provisioning.test.ts::an unknown realm resolves to nothing rather than guessing | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::toDocument then fromDocument is the identity | passed | 14 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::an ordinal score survives the round trip | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a score of 0 is kept, not treated as absent | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a boolean condition goes out as answerBoolean, never answerInteger | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::enableBehavior is emitted only with more than one condition | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::only answerable items BEFORE the target may gate it | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a branch on a LATER item is refused, not silently accepted | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::an ordered comparison against a yes/no answer is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a value that is not one of the enabler's codes is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::exists offers true/false whatever the item is | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a well-formed draft has nothing against it | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::activating without a licence note is refused, with the reason | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a crisis rule on a marketing questionnaire is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::the same crisis rule is fine on a treatment questionnaire | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a duplicate linkId is caught, because the ambiguity is silent | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a choice item with no options can never be answered | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a gap in the band table is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::an inverted band is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::code scoring naming an algorithm with no scorer is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::an unknown algorithm is NOT flagged when the list is unknown | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::scoring naming an item that is not there is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a dead enableWhen is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a non-semver version is refused | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::an empty questionnaire asks nothing | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a version only counts if it exceeds EVERY published one | passed | 1 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::a non-semver next version does not increase | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::nextVersion bumps the minor, and rescues a broken current | passed | 0 ms | Frontend · unit |
| lib/questionnaire-author.test.ts::flattenDraft reaches nested groups | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::a gated item is hidden until the gate opens | passed | 4 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::item 6 is asked of everybody, gate or no gate | passed | 4 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::enableBehavior all needs every condition | passed | 1 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::true is not 1, matching the server | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::an ordered comparison against a boolean is false, never coerced | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::exists false means enabled when NOT answered | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::a hidden group takes its whole subtree | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::required is judged after branching | passed | 3 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::progress counts only what the patient can see | passed | 1 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::progress on an empty questionnaire does not divide by zero | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::options keep their declared order and carry their display text | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::group headings come from the questionnaire, not the component | passed | 1 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::groups and display items are never rendered as questions | passed | 0 ms | Frontend · unit |
| lib/questionnaire-render.test.ts::flatten reaches nested groups | passed | 0 ms | Frontend · unit |
| lib/rbac.test.ts::isBusinessAdmin: owner (B) and admin (A) pass; staff/clinician/patient fail | passed | 3 ms | Frontend · unit |
| lib/rbac.test.ts::isBusinessAdmin: an explicit globalAdmin flag grants access regardless of hanType | passed | 0 ms | Frontend · unit |
| lib/rbac.test.ts::filterOwnerOnly hides owner-only items from staff, keeps them for admin | passed | 12 ms | Frontend · unit |
| lib/rbac.test.ts::pageAccessFor: staff readonly on Manage Business/Branches/Representatives, denied on owner-only | passed | 0 ms | Frontend · unit |
| lib/rbac.test.ts::canAccessHref lets staff reach Representatives read-only; owner-only surfaces stay blocked | passed | 1 ms | Frontend · unit |
| lib/rbac.test.ts::QA 26_8_14 §1.1: mayViewFinancials gates the Overview revenue tiles | passed | 1 ms | Frontend · unit |
| lib/rbac.test.ts::financial visibility is NOT the same question as managing configuration | passed | 1 ms | Frontend · unit |
| lib/rcm-billing.test.ts::engine choices: the three the UI offers, deterministic default listed first | passed | 8 ms | Frontend · unit |
| lib/rcm-billing.test.ts::footingStatus: foots vs does-not-foot with a specific mismatch reason | passed | 64 ms | Frontend · unit |
| lib/rcm-billing.test.ts::engineNote: null when honored; explains a fallback | passed | 0 ms | Frontend · unit |
| lib/rcm-billing.test.ts::money: two-decimal currency; em-dash for null | passed | 1 ms | Frontend · unit |
| lib/rcm-billing.test.ts::pdfsOnly: keeps only PDFs from a directory selection | passed | 0 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::rowText: flattens nested objects + arrays, lowercased | passed | 3 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::rowText: null/undefined values are skipped, no throw | passed | 0 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::filterRows: empty query returns all rows unchanged | passed | 3 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::filterRows: single term substring match on nested field | passed | 1 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::filterRows: multiple terms are AND-ed | passed | 0 ms | Frontend · unit |
| lib/rcm-flatview.test.ts::matchLabel: total when all shown, 'n of m' when filtered | passed | 0 ms | Frontend · unit |
| lib/rcm-months.test.ts::rows for you is the only verdict that means the feature is working here | passed | 7 ms | Frontend · unit |
| lib/rcm-months.test.ts::nothing for you but rows elsewhere is a DIFFERENT fact from never used | passed | 0 ms | Frontend · unit |
| lib/rcm-months.test.ts::zero everywhere says the feature has never been used by anybody | passed | 0 ms | Frontend · unit |
| lib/rcm-months.test.ts::none of the three verdicts is 'broken' | passed | 1 ms | Frontend · unit |
| lib/rcm-months.test.ts::the span reported is the span the DATA covers | passed | 1 ms | Frontend · unit |
| lib/rcm-months.test.ts::one month is not printed as a range from itself to itself | passed | 0 ms | Frontend · unit |
| lib/rcm-months.test.ts::rows whose month cannot be read are named, never silently dropped | passed | 0 ms | Frontend · unit |
| lib/rcm-months.test.ts::no record at all says so rather than reporting a zero-month span | passed | 1 ms | Frontend · unit |
| lib/rcm-practice.test.ts::never picks for somebody who holds several practices | passed | 3 ms | Frontend · unit |
| lib/rcm-practice.test.ts::selects the only practice, and puts it in the URL | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::honours a practice named in the URL | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::carries the tab's last choice across a sidebar link that dropped the query | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::drops a URL practice this login cannot see, and says so | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::does not resurrect a saved practice that is no longer on the list | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::asks nothing of a login with no practices — there is nothing to choose | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::tells a failed load apart from an empty one | passed | 1 ms | Frontend · unit |
| lib/rcm-practice.test.ts::names the one practice rather than counting it | passed | 0 ms | Frontend · unit |
| lib/rcm-practice.test.ts::says a sign-up status in words, never the raw code | passed | 0 ms | Frontend · unit |
| lib/rcm-remit.test.ts::eraPullSummary: error / empty / posted | passed | 4 ms | Frontend · unit |
| lib/rcm-remit.test.ts::eraPullSummary: a shared-account pull says whose claims it reached | passed | 0 ms | Frontend · unit |
| lib/rcm-remit.test.ts::eraPullSummary: 'not set up' is not 'could not reach' | passed | 1 ms | Frontend · unit |
| lib/rcm-remit.test.ts::priorAuthTone: approved / denied / pended | passed | 0 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the subtitle names the practice whose settings are shown, never an id | passed | 3 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the account in effect: its own, the shared one, or none — three sentences | passed | 1 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the simulator is never described as a vendor account | passed | 0 ms | Frontend · unit |
| lib/rcm-settings.test.ts::an unknown vendor id is shown as itself rather than dropped | passed | 0 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the picker leads with what 'nothing chosen' MEANS, and ends with the labelled simulator | passed | 3 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the simulator is offered once even if the catalogue lists it | passed | 0 ms | Frontend · unit |
| lib/rcm-settings.test.ts::the shared-account warning says whose claims a change moves | passed | 0 ms | Frontend · unit |
| lib/rcm-settings.test.ts::authorisation to transmit is reported, and says where it comes from | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::only 'active' says anything may be sent to a payer | passed | 10 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a draft with no gaps is told to submit, one with gaps is told how many | passed | 2 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::submit is only offered when the application is complete | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::gaps group into the order a practice can work in | passed | 3 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a mapping is incomplete until every required target has a column | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::confidence is three buckets, and the weakest one asks to be checked | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a failed totals check outranks a clean row count | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::the preview leads with what will NOT import | passed | 65 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a clean preview still says nothing has been written | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::an empty file and an all-rejected file are different messages | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a sweep cost always says it is an estimate | passed | 2 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::an unconfirmed payer match never reads as confirmed | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::cents format as currency and never as a bare number | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a compound group key renders its parts, never [object Object] | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::cells format by their declared kind | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::the three emptinesses produce three different notices | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a placeholder money total is flagged as not revenue | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::a report with rows and real money says nothing unnecessary | passed | 1 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::the parity sentence adds up and names what was only inferred | passed | 0 ms | Frontend · unit |
| lib/rcm-workflows.test.ts::verdict tones separate answered from not | passed | 0 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::a 403 is a refusal, not an error | passed | 4 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::a refusal never renders as an empty state | passed | 1 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::a 500 is still an error and still offers a Retry | passed | 1 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::401 says the session expired; 403 does not | passed | 1 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::isRefusalError reads the status, not the prose | passed | 0 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::a detail page refuses distinctly from not-found | passed | 1 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::an edit form never renders over a refusal | passed | 0 ms | Frontend · unit |
| lib/refusal-is-not-empty.test.ts::a signed-out viewer still gets the sample, not a refusal | passed | 0 ms | Frontend · unit |
| lib/registry-actions.test.ts::chart actions are gated on registration, not disabled outright | passed | 3 ms | Frontend · unit |
| lib/registry-actions.test.ts::message to doctor needs a registered, affiliated patient | passed | 0 ms | Frontend · unit |
| lib/registry-actions.test.ts::free patients cannot be contacted without consent | passed | 0 ms | Frontend · unit |
| lib/registry-actions.test.ts::contact needs at least one channel | passed | 0 ms | Frontend · unit |
| lib/registry-actions.test.ts::move to onboarding only on the Qualified tab for qualifying patients | passed | 0 ms | Frontend · unit |
| lib/registry-actions.test.ts::the synthetic rpm.patientmd.com handle never renders as an address | passed | 7 ms | Frontend · unit |
| lib/registry-actions.test.ts::CSV upload accepts any .csv, not one exact filename | passed | 1 ms | Frontend · unit |
| lib/registry-actions.test.ts::CSV validation is on columns, with header aliases | passed | 4 ms | Frontend · unit |
| lib/registry-insurance.test.ts::isSelfPay: explicit self_pay type | passed | 3 ms | Frontend · unit |
| lib/registry-insurance.test.ts::isSelfPay: explicit insured type wins over blank payer | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::isSelfPay: no coverage type + no payer => cash (US default) | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::isSelfPay: cash / self-pay free text | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::isSelfPay: named payer is insured | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::classifyPayer: Medicare vs Medicare Advantage | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::classifyPayer: Medicaid / TRICARE / commercial / blank | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coveragePayload: self-pay flag + normalized type | passed | 3 ms | Frontend · unit |
| lib/registry-insurance.test.ts::the production shape: a STRING sequencenum resolves as primary | passed | 1 ms | Frontend · unit |
| lib/registry-insurance.test.ts::a legacy row with NO sequencenum is still the primary coverage | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::Medicare HMO on a string sequencenum classifies as Medicare, not cash | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::effectiveSequences: strings, numbers, and gaps filled without collision | passed | 1 ms | Frontend · unit |
| lib/registry-insurance.test.ts::secondary and tertiary hydrate into their own form blocks | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::array order is not evidence: sequencenum wins over position | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::primaryCoverage: a patient whose ONLY row is a secondary still has it | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::an explicitly stored coverageType wins over classification | passed | 3 ms | Frontend · unit |
| lib/registry-insurance.test.ts::a real self-pay row still reads as self-pay | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coverageLabel: a plan identical to the payer is not printed twice | passed | 1 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coverageLabel: case and spacing do not make it a different plan | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coverageLabel: a plan that ADDS something is still shown | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coverageLabel: either half missing | passed | 0 ms | Frontend · unit |
| lib/registry-insurance.test.ts::coverageLabel: nothing on file returns '' and never a verdict | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::board body defaults: 20 per page, no filter params when all='all' | passed | 3 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::branch + doctor cascade map to branchId + ownerUserId | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::consent status maps correctly (incl. not-received → recd:false) | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::consent type + plan + search map through | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::missingQualifiedFields lists the blanks, empty when complete | passed | 3 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::addFormError: branch required, then phone (email OPTIONAL — QA 7/27), then name | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::isValidEmail | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::isValidPhone: NANP for +1 | passed | 1 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::dobError: future + too-old rejected, valid ok, empty allowed | passed | 3 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::pastDateError: last completed appointment cannot be in the future | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::validatePatientForm: phone required, email optional, aggregates field errors | passed | 1 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::a patient moved to onboarding leaves the Qualified tab | passed | 1 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::they are moved, not erased — All still holds them and Onboarding lists them | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::onboarded is not folded into qualifies — the verdict stays true | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::an absent onboarded flag is treated as not onboarded | passed | 0 ms | Frontend · unit |
| lib/registry-onboarding.test.ts::tabCounts uses the same predicate the tabs filter by | passed | 0 ms | Frontend · unit |
| lib/registry-order.test.ts::the verb distinguishes an edit from a creation | passed | 8 ms | Frontend · unit |
| lib/registry-order.test.ts::a row whose only stamp is dtCreate never says 'Updated' | passed | 1 ms | Frontend · unit |
| lib/registry-order.test.ts::no timestamp reads 'Not recorded', never a date and never a dash | passed | 0 ms | Frontend · unit |
| lib/registry-order.test.ts::the epoch is not presented as a recent change | passed | 0 ms | Frontend · unit |
| lib/registry-order.test.ts::relative days read the way a person would say them | passed | 72 ms | Frontend · unit |
| lib/registry-order.test.ts::a clock ahead of ours is not rendered as a future edit | passed | 0 ms | Frontend · unit |
| lib/registry-order.test.ts::the note says which kind of empty the grid is | passed | 1 ms | Frontend · unit |
| lib/registry-order.test.ts::the alphabetical order remains reachable and says so | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::representative: requires first name + email | passed | 5 ms | Frontend · unit |
| lib/rep-form.test.ts::representative: every row needs a branch | passed | 1 ms | Frontend · unit |
| lib/rep-form.test.ts::practitioner: clinical role IS the designation (row designation cleared) | passed | 3 ms | Frontend · unit |
| lib/rep-form.test.ts::non-clinical staff: designation is preserved | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::self-as-operator: needs a branch, emits an Operator responsibility, no personal info | passed | 1 ms | Frontend · unit |
| lib/rep-form.test.ts::edit: existing repId is carried through | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::new doctor login: clinician-app portal + temp password toast | passed | 1 ms | Frontend · unit |
| lib/rep-form.test.ts::new staff login: business-app portal + invite-sent when no temp password (prod) | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::reused account: link message, not a new-login toast | passed | 1 ms | Frontend · unit |
| lib/rep-form.test.ts::care-team count pluralizes | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a fresh Add-representative modal opens empty | passed | 5 ms | Frontend · unit |
| lib/rep-form.test.ts::closing after a save cannot leave the next rep holding the last one's branches | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a default branch is preselected — that is a choice, not leftover state | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::editing an existing rep opens on THEIR values, not blank | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a self-as-operator rep is recognised and its branches gathered | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::the Operator grant is not shown as an editable admin role | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a rep with no responsibilities still opens with one editable row | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::the country code defaults to +1 rather than empty | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a clinician's NPI and taxonomy reach the payload | passed | 1 ms | Frontend · unit |
| lib/rep-form.test.ts::a pasted NPI is normalised, and a lowercase taxonomy is upper-cased | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a blank credential saves — hiring precedes the NPI | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a transposed NPI is refused BEFORE the round-trip, not after | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a malformed taxonomy is refused | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a non-clinical person never carries a credential | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::switching to non-clinical does not smuggle a stale credential through | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::self-mode clears the credential explicitly | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::the form opens with the credential already on file | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::reopening for a different person does not retain the previous credential | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a practitioner gets a credential field | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::an employed PA gets one too, via their designation | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::a medical assistant does not | passed | 0 ms | Frontend · unit |
| lib/rep-form.test.ts::any one branch assignment being clinical is enough | passed | 0 ms | Frontend · unit |
| lib/rep-labels.test.ts::a practitioner's badge names their clinical role | passed | 5 ms | Frontend · unit |
| lib/rep-labels.test.ts::a non-clinical rep says so rather than showing a placeholder | passed | 0 ms | Frontend · unit |
| lib/rep-labels.test.ts::NO label ever degrades to a hyphen | passed | 3 ms | Frontend · unit |
| lib/rep-labels.test.ts::an uncatalogued value stays readable instead of blank | passed | 1 ms | Frontend · unit |
| lib/rep-labels.test.ts::a value the catalog has never heard of is humanized, not echoed raw | passed | 3 ms | Frontend · unit |
| lib/rep-labels.test.ts::an empty value yields an empty label, so the badge can be omitted | passed | 0 ms | Frontend · unit |
| lib/rep-labels.test.ts::a row lists its designation and admin grants together | passed | 0 ms | Frontend · unit |
| lib/rep-labels.test.ts::a directory-only row reads as Staff, which is a real state | passed | 0 ms | Frontend · unit |
| lib/rep-labels.test.ts::multiple admin grants are all shown | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a care-team row is recognised by either marker on its own | passed | 3 ms | Frontend · unit |
| lib/rep-provenance.test.ts::an admin cannot edit a care-team row, because there is nothing to edit | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a row with no id is never editable, whoever is asking | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a non-admin cannot edit an ordinary row either | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::the care-team reason wins over the permission reason | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::the reason names the remedy, not the prohibition | passed | 1 ms | Frontend · unit |
| lib/rep-provenance.test.ts::every care-team row gets its own React key | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::an empty roster says whether the clinical team was empty too | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a roster that is entirely clinical-team records says so | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a partly-recorded roster names the fraction | passed | 0 ms | Frontend · unit |
| lib/rep-provenance.test.ts::a fully recorded roster says nothing extra | passed | 0 ms | Frontend · unit |
| lib/report-pdf-style.test.ts::both PDF-export screens import the shared report style module | passed | 11 ms | Frontend · unit |
| lib/report-pdf-style.test.ts::reportFooterLine names neither screen specifically | passed | 1 ms | Frontend · unit |
| lib/report-pdf-style.test.ts::REPORT_MARGIN is a positive point value | passed | 0 ms | Frontend · unit |
| lib/request-rate.test.ts::up to the limit is admitted; the next identical request is refused | passed | 6 ms | Frontend · unit |
| lib/request-rate.test.ts::once tripped it STAYS tripped — a refused loop keeps looping | passed | 0 ms | Frontend · unit |
| lib/request-rate.test.ts::the storms that were measured trip within about three seconds | passed | 1 ms | Frontend · unit |
| lib/request-rate.test.ts::ordinary repetition never trips | passed | 1 ms | Frontend · unit |
| lib/request-rate.test.ts::a different screen, method, path or body is a different request | passed | 1 ms | Frontend · unit |
| lib/request-rate.test.ts::a key carries a hash of the body, never the body | passed | 0 ms | Frontend · unit |
| lib/request-rate.test.ts::memory follows activity, not history | passed | 3 ms | Frontend · unit |
| lib/request-rate.test.ts::outside a browser the guard answers yes — a server has one counter for every user | passed | 1 ms | Frontend · unit |
| lib/request-rate.test.ts::the refusal reads as an instruction a person can follow | passed | 1 ms | Frontend · unit |
| lib/request-rate.test.ts::req() consults the tripwire before any fetch | passed | 4 ms | Frontend · unit |
| lib/request-rate.test.ts::probe: the check fails on a req() that fetches without asking | passed | 1 ms | Frontend · unit |
| lib/request-timeout.test.ts::an ordinary call gets the default deadline | passed | 5 ms | Frontend · unit |
| lib/request-timeout.test.ts::a call may set its own deadline | passed | 0 ms | Frontend · unit |
| lib/request-timeout.test.ts::zero or negative disables the deadline deliberately | passed | 0 ms | Frontend · unit |
| lib/request-timeout.test.ts::the deadline aborts a request that never answers | passed | 47 ms | Frontend · unit |
| lib/request-timeout.test.ts::dispose stops the timer so a finished request leaves nothing pending | passed | 69 ms | Frontend · unit |
| lib/request-timeout.test.ts::a caller cancelling is NOT reported as a timeout | passed | 8 ms | Frontend · unit |
| lib/request-timeout.test.ts::an already-aborted caller signal aborts immediately | passed | 1 ms | Frontend · unit |
| lib/request-timeout.test.ts::with the deadline disabled the caller's signal still passes through | passed | 0 ms | Frontend · unit |
| lib/request-timeout.test.ts::with no deadline and no caller signal, fetch gets no signal | passed | 0 ms | Frontend · unit |
| lib/request-timeout.test.ts::dispose is safe to call twice | passed | 0 ms | Frontend · unit |
| lib/request-timeout.test.ts::the timeout message names the limit in seconds and says what to do | passed | 1 ms | Frontend · unit |
| lib/request-timeout.test.ts::timeouts carry 408 so callers can tell slow from wrong | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::the value axis is the instrument's whole range, not the observed one | passed | 4 ms | Frontend · unit |
| lib/results-timeline.test.ts::a point outside the declared range stretches the axis, never clips | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::with no bands the axis comes from the data alone | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::a single point does not divide by zero | passed | 1 ms | Frontend · unit |
| lib/results-timeline.test.ts::no points at all still yields a usable scale | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::y is a fraction UP from the baseline, so the caller flips it | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::x spans the observed time range, with no implied window | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::band bounds are inclusive at both ends, matching the published tables | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::a value outside every band is null, never the nearest | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::band rectangles are clipped to the axis | passed | 3 ms | Frontend · unit |
| lib/results-timeline.test.ts::a band entirely off the axis draws nothing | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::a first assessment has no trend, and is not reported as unchanged | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::the trend is the last two points in time, not in array order | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::a crisis whose response is not on this chart is still returned | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::author-stated thresholds say so; published ones say nothing | passed | 0 ms | Frontend · unit |
| lib/results-timeline.test.ts::recent is newest first and does not mutate its input | passed | 0 ms | Frontend · unit |
| lib/revenue-series.test.ts::no purchases is no data — never a fabricated year | passed | 5 ms | Frontend · unit |
| lib/revenue-series.test.ts::a month's gross and paid come from that month's rows, in that year only | passed | 3 ms | Frontend · unit |
| lib/revenue-series.test.ts::groups are named, and an unnamed key is one bucket rather than a raw id | passed | 1 ms | Frontend · unit |
| lib/revenue-series.test.ts::a full server page is reported as possibly partial | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::only the server's allowed targets are offered | passed | 5 ms | Frontend · unit |
| lib/role-assignment.test.ts::an account with nowhere to go offers nothing, and says so | passed | 1 ms | Frontend · unit |
| lib/role-assignment.test.ts::no targets loaded is distinguished from an empty list of targets | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::an unknown user id is reported as unknown, not as a disallowed move | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::assigning to the current realm is refused with the reason | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::a target outside the server's list is refused even if it is a known realm | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::a permitted move is allowed with no complaint | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::an empty user id asks for one rather than showing a broken form | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::a no-op is reported as a no-op, never as success | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::a real change explains what it does and does not affect | passed | 0 ms | Frontend · unit |
| lib/role-assignment.test.ts::an unknown realm falls back to its raw value, never to blank | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::every href in every workspace exists in the staff menu | passed | 3 ms | Frontend · unit |
| lib/role-workspace.test.ts::no workspace is empty | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::names are unique — two workspaces on one role name is unresolvable | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::selects the workspace for a single job role | passed | 1 ms | Frontend · unit |
| lib/role-workspace.test.ts::returns null when the person holds no job role | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::returns null when the person holds BOTH jobs | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::ignores permission roles that name no workspace | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::puts the job's screens first, in the job's order | passed | 3 ms | Frontend · unit |
| lib/role-workspace.test.ts::loses NOTHING — every href survives somewhere | passed | 3 ms | Frontend · unit |
| lib/role-workspace.test.ts::only the chartless billing jobs hide the remainder, and they show exactly their own screens | passed | 1 ms | Frontend · unit |
| lib/role-workspace.test.ts::shows no screen twice | passed | 2 ms | Frontend · unit |
| lib/role-workspace.test.ts::folds the remainder away but keeps it reachable | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::is the identity when there is no workspace | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::an ordinary staff session is untouched | passed | 1 ms | Frontend · unit |
| lib/role-workspace.test.ts::a biller opens on billing | passed | 0 ms | Frontend · unit |
| lib/role-workspace.test.ts::an unknown role still gets a menu | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a doctor gets a badge — the defect QA reported | passed | 13 ms | Frontend · unit |
| lib/roster-badges.test.ts::every practitioner role has a human label, not an enum value | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::an unknown role is title-cased rather than rendered raw or dropped | passed | 1 ms | Frontend · unit |
| lib/roster-badges.test.ts::clinical identity is listed before duties | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::duties from OTHER branches never appear on this branch's roster | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a duplicated designation is shown once | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a designation echoing the clinical role is not shown twice | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::administrative grants are badged and distinguishable from clinical ones | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a non-clinical staff member still gets their designation | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a missing phone is a stated absence, not an empty cell | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a phone is shown with its country code, normalised to + | passed | 0 ms | Frontend · unit |
| lib/roster-badges.test.ts::a nameless row falls back to the email local-part, never to blank | passed | 0 ms | Frontend · unit |
| lib/row-action.test.ts::the accessible name carries the row's subject | passed | 3 ms | Frontend · unit |
| lib/row-action.test.ts::an unnamed subject degrades to the bare verb, never to a position | passed | 0 ms | Frontend · unit |
| lib/row-action.test.ts::rowSubject prefers the fields it is given, in order | passed | 0 ms | Frontend · unit |
| lib/row-action.test.ts::rowSubject assembles a person's name when no field is named | passed | 0 ms | Frontend · unit |
| lib/row-action.test.ts::rowSubject NEVER falls back to an identifier | passed | 0 ms | Frontend · unit |
| lib/row-action.test.ts::a blank verb yields the subject rather than a leading space | passed | 0 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the reading summary reads every device shape and never invents | passed | 6 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::breaches come from the field production writes, and the rule text prefers the description | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the repeat note is only said when it is a repeat, and only for readings | passed | 0 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::severity is a word as well as a colour | passed | 3 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the closure line is honest about a legacy closure with no timestamp | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::grouping reuses the Action Center's grouper and keeps the server's order | passed | 2 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the cosmetic filter: empty means no restriction, never match-nothing | passed | 3 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::status tabs carry the server's counts and only Open is live on the backlog | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the legacy ?pt= from the RPM Listing still scopes, and ?patient= wins | passed | 5 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the flat list is newest first by the moment the row shows, and copies | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the flat list keeps the server's order for rows sharing a moment | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::a row's status is one word, and acknowledged is not addressed | passed | 0 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::display time is the reading's own moment when it has one, else the arrival | passed | 0 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the history CSV carries the same numbers as the screen and quotes defensively | passed | 1 ms | Frontend · unit |
| lib/rpm-alerts.test.ts::the closures note says what the chart cannot show | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::todayYmd is local, not UTC | passed | 6 ms | Frontend · unit |
| lib/rpm-listing.test.ts::an upcoming appointment cannot be in the past | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::Set TMS carries the patient so Care Time opens on them | passed | 1 ms | Frontend · unit |
| lib/rpm-listing.test.ts::alerts deep-link is scoped to the patient | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::alert tone escalates with count | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::branch filter matches the registry's semantics | passed | 3 ms | Frontend · unit |
| lib/rpm-listing.test.ts::care team summary names the lead and counts the rest | passed | 1 ms | Frontend · unit |
| lib/rpm-listing.test.ts::care team summary handles an empty or roleless team | passed | 1 ms | Frontend · unit |
| lib/rpm-listing.test.ts::send-document needs a channel to send on | passed | 1 ms | Frontend · unit |
| lib/rpm-listing.test.ts::view-measurements needs measurements | passed | 1 ms | Frontend · unit |
| lib/rpm-listing.test.ts::remove-patient needs an enrolment to end | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::the clinical-team hover never renders a raw database id | passed | 0 ms | Frontend · unit |
| lib/rpm-listing.test.ts::a real name still wins over the role placeholder | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::a row somebody can fix reads differently from one nobody can | passed | 5 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::every verdict has a label, so a status is never carried by colour alone | passed | 1 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::an unreachable patient is given the action that would change the answer | passed | 1 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::a patient reachable only by an unconsented text is told what to ask for | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::a declined patient is given NO action | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::the channel label mirrors the server rather than re-deriving it | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::the channel note explains an email that a reader would expect to be a text | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::select-all ticks only the rows that can actually be sent | passed | 2 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::the summary separates fixable from not eligible | passed | 3 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::the draft result says nothing was sent | passed | 1 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::the draft result reports who could not be contacted | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::drafting nothing says so rather than claiming success | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::tomorrow is computed from local date parts, never from toISOString | passed | 5 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::tomorrow rolls a year correctly | passed | 1 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::a row with no appointment time renders an em dash, not 'Invalid Date' | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::a patient waiting a fortnight reads as overdue | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::waiting time is worded, not only coloured | passed | 1 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::an unknown verdict from the server degrades safely | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::actionFor returns nothing for a row it has no advice about | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::channelLabel returns nothing when there is no contact detail at all | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::channelNote is empty when the channel needs no explanation | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::summarise of an empty clinic day is all zeroes, not a crash | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::selectableIds of an empty list is empty | passed | 0 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::apptTime renders a real timestamp | passed | 58 ms | Frontend · unit |
| lib/rpm-outreach.test.ts::waitingLabel and waitingTone handle a negative age without inventing urgency | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the columns are the list QA wrote, in that order | passed | 8 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the backend's ONE constant is identical | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a date splits into the sheet's plain integers and joins back | passed | 3 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the form holds ONE date and the body carries the split columns | passed | 2 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a draft round-trips the whole sheet unchanged | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a last appointment stored as MM-DD survives an edit that does not touch it | passed | 4 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the server's `sheet` is used as sent | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a row stored before this round maps without the server's help | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::names split first / middle / last, and one word is a first name | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a gender we cannot map is kept verbatim and flagged, never guessed | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a complete row is clean, and a phone OR an email is enough | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"firstName":" "} → firstName | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"lastName":""} → lastName | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"phone":"","emailId":""} → phone | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"emailId":"not-an-email"} → emailId | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"phone":"1111111111"} → phone | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"phone":"1235550112"} → phone | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"phoneprefix":"abc"} → phoneprefix | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"gender":"Q"} → gender | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"dobyear":"2999"} → dob | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"dobmonth":"2","dobday":"30"} → dob | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"dobyear":"1850"} → dob | passed | 2 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"lastapptyear":"2999"} → lastappt | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"state":"Illinois"} → state | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"zip":"6060"} → zip | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::refused: {"mrn":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx → mrn | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::today is allowed; tomorrow is not | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::US shape rules stop at the border; a foreign phone is length-checked | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::an incomplete row promoted in from a consent is not malformed | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the form requires a clinic, and says so on the clinic field | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::what the form normalises before it sends | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::phones read for people and store as digits | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::an error opens the section that holds it | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::secondary and tertiary insurance open only when they hold something | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the table says what a row still needs for the next stage | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the rollup does not block Add — only having no clinic at all does | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the CSV header is the contract, and quoting is RFC 4180 | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::formula-leading cells are neutralised (OWASP CSV injection) | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::a download's name carries no patient identifier | passed | 0 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the screen uses no native prompt/alert/confirm | passed | 2 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::'Choose a clinic first' is no longer loose text in the toolbar | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the clinic hint lives on the clinic field, tied by aria-describedby | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::the Action menu offers Edit details, and the form is wired for both modes | passed | 1 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::every sheet column is reachable from the form | passed | 3 ms | Frontend · unit |
| lib/rpm-patient-details.test.ts::patient data never goes into a query string | passed | 5 ms | Frontend · unit |
| lib/rule-scope.test.ts::the cascade runs corp → branch → doctor → patient | passed | 5 ms | Frontend · unit |
| lib/rule-scope.test.ts::every level has a label a clinician would recognise | passed | 1 ms | Frontend · unit |
| lib/rule-scope.test.ts::each level states what else an edit would change | passed | 1 ms | Frontend · unit |
| lib/rule-scope.test.ts::the badge names the NARROWEST level that set anything | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::a rule nobody has overridden reports the protocol default | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::mixed provenance is detectable | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::the per-field breakdown puts the narrowest overrides first | passed | 1 ms | Frontend · unit |
| lib/rule-scope.test.ts::field paths are rendered readably, not as dotted keys | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::an unknown level degrades to default rather than rendering raw | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::each level is visually distinct | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::a replacement names the rule it replaced and how much moved | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::an override identical to what it replaced says so | passed | 0 ms | Frontend · unit |
| lib/rule-scope.test.ts::no override at all is stated as the protocol default | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::pulls the field errors out of the wrapped envelope | passed | 6 ms | Frontend · unit |
| lib/save-error.test.ts::names the fields in the message, because the input may be scrolled away | passed | 1 ms | Frontend · unit |
| lib/save-error.test.ts::carries the request id on a server fault — the id QA had to read out of devtools | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::says plainly that nothing was written, which is the operator's real question | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::a timeout reads as retry, not as a bad form | passed | 1 ms | Frontend · unit |
| lib/save-error.test.ts::403 and 404 do not read as either | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::prefers the server's own words to ours | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::never surfaces a bare HTTP code as the whole message | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::"add" reads as "added" | passed | 1 ms | Frontend · unit |
| lib/save-error.test.ts::"update" reads as "updated" | passed | 0 ms | Frontend · unit |
| lib/save-error.test.ts::"save" reads as "saved" | passed | 0 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::a required challenge is recognised in both response shapes | passed | 10 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::a sent challenge is recognised and its message is kept verbatim | passed | 0 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::anything else is not a second-factor problem | passed | 0 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::the text option is offered only when the account holds that factor | passed | 0 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::the text option is not offered again once a code has been sent | passed | 0 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::a recovery code is passed through, a numeric code is normalised | passed | 1 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::the label says what will happen | passed | 1 ms | Frontend · unit |
| lib/second-factor-challenge.test.ts::the prompt names the authenticator app when that is the factor | passed | 0 ms | Frontend · unit |
| lib/seed-detect.computed.test.ts::catches the generator substituted on an empty result | passed | 50 ms | Frontend · unit |
| lib/seed-detect.computed.test.ts::catches it in a catch block too | passed | 3 ms | Frontend · unit |
| lib/seed-detect.computed.test.ts::does NOT flag transforming the rows that came back | passed | 11 ms | Frontend · unit |
| lib/seed-detect.computed.test.ts::the TMS Data Report no longer contains the shape | passed | 436 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees a seed set in a catch with an intervening statement | passed | 41 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees a seed set inside an `if` emptiness branch, not just a ternary | passed | 7 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees it through a try/catch block as well as a .catch() | passed | 4 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees a concise arrow body | passed | 2 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees seed as the initial state | passed | 16 ms | Frontend · unit |
| lib/seed-detect.test.ts::sees the emptiness ternary in both polarities | passed | 3 ms | Frontend · unit |
| lib/seed-detect.test.ts::allows the signed-out preview | passed | 3 ms | Frontend · unit |
| lib/seed-detect.test.ts::does not flag an ordinary empty-array fallback | passed | 2 ms | Frontend · unit |
| lib/seed-detect.test.ts::does not flag merely HOLDING a seed constant | passed | 2 ms | Frontend · unit |
| lib/seed-detect.test.ts::does not treat prose as code | passed | 8 ms | Frontend · unit |
| lib/seed-detect.test.ts::catches a constant with no seed-ish token in its name | passed | 3 ms | Frontend · unit |
| lib/seed-detect.test.ts::follows a renamed import | passed | 1 ms | Frontend · unit |
| lib/seed-detect.test.ts::catches a lowercase member access | passed | 1 ms | Frontend · unit |
| lib/seed-detect.test.ts::does not treat an unrelated import as sample data | passed | 2 ms | Frontend · unit |
| lib/seed-detect.test.ts::reports the line, so a failure names where to look | passed | 1 ms | Frontend · unit |
| lib/seed-detect.test.ts::parses TSX, not just TS | passed | 6 ms | Frontend · unit |
| lib/send-outcome.test.ts::a sent message is reported sent, with no noise beside it | passed | 3 ms | Frontend · unit |
| lib/send-outcome.test.ts::a held message says so, and carries the reason it was given | passed | 1 ms | Frontend · unit |
| lib/send-outcome.test.ts::held and failed are distinguished — they need different things from a person | passed | 0 ms | Frontend · unit |
| lib/send-outcome.test.ts::an answer we cannot read is NEVER reported as sent | passed | 1 ms | Frontend · unit |
| lib/send-outcome.test.ts::`sent: true` alone does not claim delivery | passed | 0 ms | Frontend · unit |
| lib/send-outcome.test.ts::a request that never arrived says nothing was sent | passed | 0 ms | Frontend · unit |
| lib/send-outcome.test.ts::every non-sent outcome carries a reason | passed | 0 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::the service worker precaches no HTML | passed | 6 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::the shell holds only assets whose content is fixed under their name | passed | 1 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::navigations are never answered from the cache | passed | 1 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::a navigation is retried once before the user is told the server is unreachable | passed | 1 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::the unreachable message is served as UTF-8 | passed | 1 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::the unreachable message does not assert that the user is offline | passed | 1 ms | Frontend · unit |
| lib/service-worker-shell.test.ts::the path classifier catches the paths that actually caused this | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::an exact href match wins over a shorter prefix | passed | 3 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::a child route with no menu entry still lights up its section | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::a query string on an href does not stop the match | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::an unlabelled section never owns a route | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::a route on nobody's menu answers -1, not 0 | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::an unlabelled section is always open | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::only the section owning the route opens by default | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::every labelled section is folded when the route is on nobody's menu | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::a manual toggle wins over the default, in both directions | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::opening a second section does not close the first | passed | 1 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::collapsedByDefault no longer decides anything | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::one chip per labelled section, in menu order | passed | 8 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::the chip index addresses the section, so duplicate labels stay distinct | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::exactly one chip is active, and none when the route is off-menu | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::the chip carries the section's own label, never an abbreviation | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::every role's menu yields a usable strip and folds by default | passed | 1 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::every business section is reachable from the strip | passed | 0 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::navigating into a section opens it, for every section of every menu | passed | 5 ms | Frontend · unit |
| lib/sidebar-sections.test.ts::body and header ids are distinct per section | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::stroke length is the path walked, not the distance between endpoints | passed | 3 ms | Frontend · unit |
| lib/signature.test.ts::ink accumulates across separate strokes | passed | 1 ms | Frontend · unit |
| lib/signature.test.ts::an untouched canvas and a single tap are both blank | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::a short but real signature is NOT blank | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::the image must be a PNG data URI within the server's cap | passed | 1 ms | Frontend · unit |
| lib/signature.test.ts::decoded length accounts for base64 padding | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::a drawn mark alone signs, and reports itself as drawn | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::a typed name alone signs | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::a drawn mark wins when the patient did both | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::nothing at all is refused with something to do about it | passed | 1 ms | Frontend · unit |
| lib/signature.test.ts::a smudge is refused OUT LOUD rather than filed as a signature | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::a smudge falls back to a typed name when there is one | passed | 1 ms | Frontend · unit |
| lib/signature.test.ts::real ink with no captured image is refused, not sent as typed | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::the payload omits the image entirely when the signature is typed | passed | 0 ms | Frontend · unit |
| lib/signature.test.ts::the size cap and PNG prefix still match the server's | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::every gap the server can name lands on an input of its own | passed | 3 ms | Frontend · unit |
| lib/signup-form.test.ts::a provider gap lands on that provider's own box, not the first one | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::an address gap lands on its street line, and a contact gap on its field | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::a missing document preselects its kind in the upload control | passed | 4 ms | Frontend · unit |
| lib/signup-form.test.ts::reads a state written either way, and does not guess at one it does not know | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::formats a ZIP+4 and leaves a malformed ZIP for the server to name | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::offers the clinic's address normalised, and nothing when the record holds none | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::an unrecognised state is kept as typed rather than silently emptied | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::compares two addresses by what a payer would read | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::fills legal name, taxonomy and pay-to address on an empty application, and says which | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::never replaces what a person typed | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::refuses to fill the billing NPI from an individual's record, and says why | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::a registry miss fills nothing and invents nothing | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::fills a rendering provider's empty name, taxonomy and licence state | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::refuses an organisation's NPI for a rendering provider | passed | 0 ms | Frontend · unit |
| lib/signup-form.test.ts::reads rows written before every field existed, and drops non-rows | passed | 1 ms | Frontend · unit |
| lib/signup-form.test.ts::edits and removes by position without touching the others | passed | 1 ms | Frontend · unit |
| lib/slide-over-padding.test.ts::the panel body is padded by default | passed | 3 ms | Frontend · unit |
| lib/slide-over-padding.test.ts::children go through the body wrapper, not straight into the panel | passed | 1 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::the body layout gives a definite height, may shrink, and scrolls | passed | 3 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::the layout is applied unconditionally — no caller value can remove it | passed | 1 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::the prop default carries padding only — layout is not the caller's to forget | passed | 0 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::the panel is a full-height flex column that cannot itself overflow the screen | passed | 1 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::the consumer sweep finds the callers (a sweep that finds nothing proves nothing) | passed | 0 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::no caller re-implements the wrapper's layout through bodyClassName to fight it | passed | 1 ms | Frontend · unit |
| lib/slide-over-scroll.test.ts::Add Clinical Team: header and footer are pinned, only the middle scrolls | passed | 1 ms | Frontend · unit |
| lib/sms-delivery.test.ts::normalizeStatus: lowercase, blank → unknown | passed | 3 ms | Frontend · unit |
| lib/sms-delivery.test.ts::statusTone: good/bad/pending | passed | 0 ms | Frontend · unit |
| lib/sms-delivery.test.ts::statusLabel: Title case, unknown → Queued | passed | 0 ms | Frontend · unit |
| lib/sms-delivery.test.ts::deliveryRateText | passed | 2 ms | Frontend · unit |
| lib/sms-delivery.test.ts::STATUS_FILTERS includes All + delivered + failed | passed | 1 ms | Frontend · unit |
| lib/sms-sender-not-client-chosen.test.ts::every screen that texts a patient is accounted for | passed | 5 ms | Frontend · unit |
| lib/sms-sender-not-client-chosen.test.ts::components/contact-patient.tsx does not choose the sending number | passed | 1 ms | Frontend · unit |
| lib/sms-sender-not-client-chosen.test.ts::app/dashboard/rpm/contact/page.tsx does not choose the sending number | passed | 0 ms | Frontend · unit |
| lib/sms-sender-not-client-chosen.test.ts::the scanner would notice a from-number if one came back | passed | 1 ms | Frontend · unit |
| lib/soap-context.test.ts::noteTs: reads dtAppt, tolerates string dates, 0 when absent | passed | 3 ms | Frontend · unit |
| lib/soap-context.test.ts::latestSoapNote: picks max timestamp | passed | 0 ms | Frontend · unit |
| lib/soap-context.test.ts::latestSoapNote: empty list → null; undated list → first row | passed | 2 ms | Frontend · unit |
| lib/soap-context.test.ts::soapSections: only non-empty sections, charted order, chief complaint first | passed | 3 ms | Frontend · unit |
| lib/soap-context.test.ts::hasSoapContent: false when null or all-blank, true otherwise | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::a fresh guard applies its result | passed | 3 ms | Frontend · unit |
| lib/stale-guard.test.ts::a cancelled guard drops the result | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::cancel is idempotent — React may call cleanup more than once | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::guards are independent — one run cancelling does not affect another | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::the slow response for the PREVIOUS patient never renders | passed | 36 ms | Frontend · unit |
| lib/stale-guard.test.ts::without the guard, the same sequence renders the wrong patient | passed | 31 ms | Frontend · unit |
| lib/stale-guard.test.ts::latestOnly keeps the newest of out-of-order responses | passed | 33 ms | Frontend · unit |
| lib/stale-guard.test.ts::latestOnly passes a lone response through | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::latestOnly discards by identity, not by value | passed | 22 ms | Frontend · unit |
| lib/stale-guard.test.ts::a rejected newer request does not resurrect an older one | passed | 23 ms | Frontend · unit |
| lib/stale-guard.test.ts::a payload naming another patient is refused | passed | 1 ms | Frontend · unit |
| lib/stale-guard.test.ts::a payload naming the current patient is accepted | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::an unstamped payload is accepted | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::an empty subjectId is not treated as a claim | passed | 0 ms | Frontend · unit |
| lib/stale-guard.test.ts::subject comparison is by value, not by reference type | passed | 0 ms | Frontend · unit |
| lib/statement-print.test.ts::fmtUSD: two decimals + separators, safe on junk | passed | 54 ms | Frontend · unit |
| lib/statement-print.test.ts::fmtStmtDate: em dash when absent, formats when present | passed | 12 ms | Frontend · unit |
| lib/statement-print.test.ts::statusTone: paid / overdue / open | passed | 0 ms | Frontend · unit |
| lib/statement-print.test.ts::amountDue: positive balance only, else 0 | passed | 0 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::a browser that refuses storage does not crash the business context | passed | 14 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::the hostile double really does throw — the guard is not passing on nothing | passed | 2 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::./session.ts touches storage only inside a try | passed | 2 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::./business-context.ts touches storage only inside a try | passed | 1 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::the structural check fails on an unguarded call — it is not inert | passed | 1 ms | Frontend · unit |
| lib/storage-never-throws.test.ts::the structural check ignores a comment that merely mentions getItem | passed | 1 ms | Frontend · unit |
| lib/store-census.test.ts::a working screen carries no explanation of an emptiness it does not have | passed | 3 ms | Frontend · unit |
| lib/store-census.test.ts::each kind gets its own heading, and an unknown kind still renders | passed | 0 ms | Frontend · unit |
| lib/store-census.test.ts::the per-store line says which kind of empty, never 'no data' | passed | 1 ms | Frontend · unit |
| lib/store-census.test.ts::a measured survivor is named on the line, and an absent one is not | passed | 1 ms | Frontend · unit |
| lib/suggest.test.ts::an empty field offers the list; typing narrows it, prefix first | passed | 5 ms | Frontend · unit |
| lib/suggest.test.ts::free text is allowed — a value not on the list suggests nothing and is kept | passed | 0 ms | Frontend · unit |
| lib/suggest.test.ts::once the field holds exactly one option there is nothing left to suggest | passed | 0 ms | Frontend · unit |
| lib/suggest.test.ts::a hint is searchable — a CPT code is found by its description | passed | 0 ms | Frontend · unit |
| lib/suggest.test.ts::a repeated option is one option | passed | 0 ms | Frontend · unit |
| lib/suggest.test.ts::no screen renders a native datalist — its popup cannot be themed | passed | 296 ms | Frontend · unit |
| lib/suggest.test.ts::the datalist guard fires on the real thing and not on a prop that happens to be called list | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::a named individual holding the job is offered the apex screens | passed | 4 ms | Frontend · unit |
| lib/superuser.test.ts::official@patientmd.com is refused even holding the job | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::holding no job is not apex however the address reads | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::a borrowed session is never apex | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::the second address on the session is checked too | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::dots and +tags fold on this domain, as Google folds them | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::a shared local part is recognised however it is spelled | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::apex hrefs are hidden from everyone else and shown to the apex | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::an ordinary href is never hidden by this filter | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::the reason is legible, because an outcome nobody understands is a ticket | passed | 1 ms | Frontend · unit |
| lib/superuser.test.ts::'Sign in as…' is the apex's alone again (2026-09-10) | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::a screen that IS apex-only stays apex-only | passed | 4 ms | Frontend · unit |
| lib/superuser.test.ts::platform STAFF are not offered the support door | passed | 0 ms | Frontend · unit |
| lib/superuser.test.ts::a borrowed session is offered neither, whatever it borrowed | passed | 0 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::one document cited four times is one source to a reader | passed | 10 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::untitled rows are dropped rather than rendered as a blank chip | passed | 1 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::the list is capped and renumbered from one | passed | 1 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::a citation can only ever link inside this app | passed | 1 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::a source with no path is still a source, just not a link | passed | 0 ms | Frontend · unit |
| lib/sylvie-citations.test.ts::the label never names the model or the provider | passed | 1 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::only a decline is surfaced to the reader | passed | 4 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::a missing verdict is not a decline | passed | 0 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::inScope=false is honoured even without a tier | passed | 0 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::the note is a boundary, not an apology or an error | passed | 1 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::every role gets three examples and an unknown role degrades | passed | 4 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::the examples are things the gate actually admits | passed | 1 ms | Frontend · unit |
| lib/sylvie-scope.test.ts::the debug line is for operators and stays out of the reply | passed | 0 ms | Frontend · unit |
| lib/sylvie-voice.test.ts::a typed turn carries no voice fields at all | passed | 6 ms | Frontend · unit |
| lib/sylvie-voice.test.ts::a fleet-transcribed turn carries its row id and nothing else | passed | 0 ms | Frontend · unit |
| lib/sylvie-voice.test.ts::a browser-recognised turn names its source so the server records the browser tier | passed | 0 ms | Frontend · unit |
| lib/sylvie-voice.test.ts::rendered keys come only from what the page published | passed | 1 ms | Frontend · unit |
| lib/sylvie-voice.test.ts::the engine label says where the voice came from | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::severity is the grading, and administrative never competes with critical | passed | 5 ms | Frontend · unit |
| lib/task-board.test.ts::severity reads as a word, and `administrative` is shortened | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::the headline leads with what is overdue, not with the total | passed | 1 ms | Frontend · unit |
| lib/task-board.test.ts::a board with rows and nothing overdue says so rather than staying silent | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::an empty board says the filters matched nothing, not that there is nothing | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::choosing a clinic must NAME what it withheld — Article III.10 | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::rule 15 — the three kinds of empty get three different sentences | passed | 1 ms | Frontend · unit |
| lib/task-board.test.ts::a close with no timestamp is counted and said, never charted silently | passed | 0 ms | Frontend · unit |
| lib/task-board.test.ts::ageing says nothing is open rather than drawing a zero-day oldest | passed | 1 ms | Frontend · unit |
| lib/task-board.test.ts::an open row with no arrival time is reported, not aged to today | passed | 4 ms | Frontend · unit |
| lib/task-board.test.ts::this module declares no vocabulary of its own — rule 13 | passed | 1 ms | Frontend · unit |
| lib/task-board.test.ts::every severity the server can send has a tone, and none is left default | passed | 0 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::simEnabled requires an explicit true | passed | 3 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::simEnabled fails closed on unknown or failed status | passed | 0 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::clampWindow keeps requests inside the server's bounds | passed | 3 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::clampWindow survives a blank number input | passed | 0 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::clampWindow truncates fractional input | passed | 0 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::runSummary pluralises alerts | passed | 0 ms | Frontend · unit |
| lib/telemetry-sim.test.ts::purgeTotal sums per-collection counts | passed | 0 ms | Frontend · unit |
| lib/tenant-scope.test.ts::global scope sends no tenant keys at all | passed | 5 ms | Frontend · unit |
| lib/tenant-scope.test.ts::a picked branch and corp are sent; nulls are omitted | passed | 1 ms | Frontend · unit |
| lib/tenant-scope.test.ts::extra fields survive alongside the scope | passed | 0 ms | Frontend · unit |
| lib/tenant-scope.test.ts::a JWT is never accepted as a tenant id | passed | 4 ms | Frontend · unit |
| lib/tenant-scope.test.ts::empty and non-string values are refused | passed | 1 ms | Frontend · unit |
| lib/tenant-scope.test.ts::forbidden stays distinct from empty | passed | 4 ms | Frontend · unit |
| lib/tenant-scope.test.ts::rows are counted, failures are failures | passed | 2 ms | Frontend · unit |
| lib/tenant-scope.test.ts::a non-array success body counts as empty, not as one row | passed | 0 ms | Frontend · unit |
| lib/tenant-scope.test.ts::every outcome has a line, and none of them invents data | passed | 2 ms | Frontend · unit |
| lib/threshold-trends.test.ts::a sane field passes | passed | 5 ms | Frontend · unit |
| lib/threshold-trends.test.ts::crossed min/max is caught at entry | passed | 3 ms | Frontend · unit |
| lib/threshold-trends.test.ts::urgent bounds must sit outside the normal band | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::partially-specified fields are fine | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::validateFields reports every bad field, not just the first | passed | 1 ms | Frontend · unit |
| lib/threshold-trends.test.ts::a trend number of zero is rejected because it silently disables the rule | passed | 1 ms | Frontend · unit |
| lib/threshold-trends.test.ts::negative trend numbers are rejected | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::a count that cannot fit its window is rejected | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::the protocol defaults themselves validate clean | passed | 1 ms | Frontend · unit |
| lib/threshold-trends.test.ts::only numeric keys are editable — action is a label, not a number | passed | 1 ms | Frontend · unit |
| lib/threshold-trends.test.ts::labels and units are human-readable | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::emptied trends are pruned so they do not shadow the default with nothing | passed | 0 ms | Frontend · unit |
| lib/threshold-trends.test.ts::validateOverride covers fields and trends together | passed | 0 ms | Frontend · unit |
| lib/time-window-hook-stability.test.ts::useTimeWindow's memo depends on no object identity | passed | 4 ms | Frontend · unit |
| lib/time-window-hook-stability.test.ts::the guard actually fires on the code that caused the incident | passed | 2 ms | Frontend · unit |
| lib/time-window-hook-stability.test.ts::a comment naming the forbidden identifier does not trip the guard | passed | 2 ms | Frontend · unit |
| lib/time-window.test.ts::the default is the last 24 hours and the presets mirror the server's keys | passed | 5 ms | Frontend · unit |
| lib/time-window.test.ts::a preset resolves to an absolute interval ending now | passed | 1 ms | Frontend · unit |
| lib/time-window.test.ts::URL round-trip: preset, custom and backlog | passed | 1 ms | Frontend · unit |
| lib/time-window.test.ts::the default preset writes NO parameter, so a clean URL stays clean | passed | 0 ms | Frontend · unit |
| lib/time-window.test.ts::toParams keeps unrelated parameters and replaces the window ones | passed | 0 ms | Frontend · unit |
| lib/time-window.test.ts::garbage in the URL falls back, and a half range is not promoted to a preset | passed | 0 ms | Frontend · unit |
| lib/time-window.test.ts::toQuery speaks the server's parameter names | passed | 0 ms | Frontend · unit |
| lib/time-window.test.ts::a custom range from two date inputs is half-open and local | passed | 2 ms | Frontend · unit |
| lib/time-window.test.ts::a bad custom range is refused with a sentence, never clamped | passed | 0 ms | Frontend · unit |
| lib/time-window.test.ts::labels never contain a raw millisecond value | passed | 68 ms | Frontend · unit |
| lib/time-window.test.ts::the neighbourhood sentence stops a quiet window reading as a quiet day | passed | 1 ms | Frontend · unit |
| lib/tms-draft.test.ts::an empty note box may be prefilled | passed | 3 ms | Frontend · unit |
| lib/tms-draft.test.ts::a box still holding the last draft may be refreshed | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::anything the specialist typed is hers and is never overwritten | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::verbatim is accepted, a change is edited, nothing offered is typed | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::edited is never reported when nothing was offered | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::recency reads as a person would say it | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::an undateable row says so rather than showing an epoch | passed | 0 ms | Frontend · unit |
| lib/tms-draft.test.ts::no precedent gets its own sentence and never a default note | passed | 1 ms | Frontend · unit |
| lib/tms-draft.test.ts::the notice carries the basis and how stale it is | passed | 1 ms | Frontend · unit |
| lib/tms-draft.test.ts::a candidate summary never renders a raw identifier | passed | 1 ms | Frontend · unit |
| lib/tms-draft.test.ts::preview collapses whitespace and truncates with an ellipsis | passed | 1 ms | Frontend · unit |
| lib/tms-report.test.ts::weight and pulse-ox readings are no longer dropped | passed | 6 ms | Frontend · unit |
| lib/tms-report.test.ts::a reading with no time or no number is not a row | passed | 1 ms | Frontend · unit |
| lib/tms-report.test.ts::both blood-pressure spellings are one section | passed | 4 ms | Frontend · unit |
| lib/tms-report.test.ts::each type gets legacy's columns, blood pressure first, newest row first | passed | 1 ms | Frontend · unit |
| lib/tms-report.test.ts::the summary says how many, on how many days, and the range | passed | 1 ms | Frontend · unit |
| lib/tms-report.test.ts::a type this report has never heard of is shown under its own name, not dropped | passed | 1 ms | Frontend · unit |
| lib/tms-report.test.ts::notes history reads the stored mode word as the button a person pressed | passed | 6 ms | Frontend · unit |
| lib/tms.test.ts::the suite is gated until a patient is chosen | passed | 4 ms | Frontend · unit |
| lib/tms.test.ts::every child section inherits the one selection | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::an id outside the roster still binds, but names nobody it cannot name | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::no selection means no context for any child to act on | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::care plan drives the activity list | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::encode then decode is lossless | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::an empty note round-trips as empty, not as the meta string | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::a note containing the separator survives decoding | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::legacy rows with separate fields still decode | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::whenToMs handles both the modern epoch and the legacy object | passed | 6 ms | Frontend · unit |
| lib/tms.test.ts::no screen infers a person's role from their id | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::CPT ladder: 99457 at 20 minutes, 99458 per further 20, capped at two | passed | 2 ms | Frontend · unit |
| lib/tms.test.ts::the PDF patient block carries the associated branch | passed | 2 ms | Frontend · unit |
| lib/tms.test.ts::a missing field prints a dash rather than vanishing | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::age is appended only when the DOB parses | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::column widths sum to the usable width, so nothing spills past the margin | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::notes are appended only for the reported patient, in the reported window | passed | 1 ms | Frontend · unit |
| lib/tms.test.ts::notes come out in chronological order | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::the window is inclusive of both end dates | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::the TMS-notes toggle defaults to OFF | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::the minutes tile is subtitled with the patient's name, never their id | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::a locked care plan names what IS on file, not what is forbidden | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::no plan on record is a distinct message from the wrong plan | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::only the patient's assigned care team is offered | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::no care team disables the control and says why, rather than going blank | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::an unloaded context offers nothing and claims nothing | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::reads contractType where carePlan is absent | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::reads communicationMode where commMode is absent | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::still prefers the modern spelling when both are present | passed | 0 ms | Frontend · unit |
| lib/tms.test.ts::an unpacked row keeps its own note rather than losing it | passed | 0 ms | Frontend · unit |
| lib/training-curriculum.test.ts::QA 26_8_20 named fourteen workflows and fourteen are offered | passed | 2 ms | Frontend · unit |
| lib/training-curriculum.test.ts::every workflow is distinguishable from every other | passed | 0 ms | Frontend · unit |
| lib/training-curriculum.test.ts::each workflow starts on a screen that is in the menu | passed | 0 ms | Frontend · unit |
| lib/training-curriculum.test.ts::each workflow says what it covers, in QA's words | passed | 0 ms | Frontend · unit |
| lib/training-curriculum.test.ts::no workflow is an empty shell | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::a portal that has not arrived yet is loading, not empty | passed | 5 ms | Frontend · unit |
| lib/training-portal.test.ts::a failed fetch is an error the reader can act on, never blank content | passed | 1 ms | Frontend · unit |
| lib/training-portal.test.ts::an empty body is an error, not a blank page that looks like an empty manual | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::html present means ready, carrying the version alongside it | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::an error wins over content — a stale document is not shown beside a failure | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::the version is reduced to its number for the header | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::a document that states no version produces no version claim | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::the subtitle names the version actually being read | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::the iframe sandbox never combines allow-scripts with allow-same-origin | passed | 0 ms | Frontend · unit |
| lib/training-portal.test.ts::the portal keeps its own scripts — dead lab checkboxes teach the wrong lesson | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::shows the codes between scanning and verifying | passed | 2 ms | Frontend · unit |
| lib/two-factor.test.ts::an already-enrolled account skips straight to done | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::accepts six digits and nothing else | passed | 1 ms | Frontend · unit |
| lib/two-factor.test.ts::strips whatever the authenticator app pasted in | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::a wrong six-digit code is still worth sending | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::says plainly when it is set up | passed | 1 ms | Frontend · unit |
| lib/two-factor.test.ts::names the consequence when it is required and missing | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::is quiet, not alarming, when it is merely not set up | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::names the masked backup number when there is one | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::warns before they run out, not after | passed | 1 ms | Frontend · unit |
| lib/two-factor.test.ts::names the route back when there are none left | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::says nothing at all before enrolment | passed | 0 ms | Frontend · unit |
| lib/two-factor.test.ts::lays the codes out two-up for printing | passed | 2 ms | Frontend · unit |
| lib/two-factor.test.ts::the text copy identifies the account it belongs to | passed | 1 ms | Frontend · unit |
| lib/universal-messaging.test.ts::the limit is the NARROWEST rung, not the first | passed | 4 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a ladder with no limited rung reports no limit | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a stale channel in the ladder is ignored, not thrown on | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::wouldBeCut is false when there is no limit at all | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a routine page has no deadline, and that is not 'overdue' | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a passed deadline reads as overdue, never as a negative | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a live deadline counts down in minutes and seconds | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a send where everybody was held does not read as a failure | passed | 1 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a send where everybody was refused says so plainly | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a partial send names both halves | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a preview says 'would reach', because it has not happened | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::no recipients is its own sentence | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::the refusal tally EXCLUDES deferrals | passed | 2 ms | Frontend · unit |
| lib/universal-messaging.test.ts::the tally is ordered by frequency and capped | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::hhmm renders a window boundary, clamped | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a tier with no verbs disables the button and says why | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a tier with no verbs and no declared reason still explains itself | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::a real tier enables the button | passed | 0 ms | Frontend · unit |
| lib/universal-messaging.test.ts::no module chosen is not the same as an empty tier | passed | 0 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::no prerendered page reads searchParams without a boundary above it | passed | 248 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::the scanner reaches the pages and the hook, or it proves nothing | passed | 79 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::the three exemptions are each real, and each for its own reason | passed | 0 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::reset-password specifically, because it is the page that broke | passed | 0 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::the model still flags the defect it was written for | passed | 0 ms | Frontend · unit |
| lib/use-search-params-needs-suspense.test.ts::the comment stripper neither hides a call nor invents one | passed | 1 ms | Frontend · unit |
| lib/version-skew.test.ts::a tab running a build the server has replaced is stale | passed | 3 ms | Frontend · unit |
| lib/version-skew.test.ts::stale is only ever asserted on POSITIVE evidence | passed | 0 ms | Frontend · unit |
| lib/version-skew.test.ts::the running id is read off <html data-dpl-id>, which Next injects itself | passed | 0 ms | Frontend · unit |
| lib/version-skew.test.ts::a probe that returns something other than our JSON never throws | passed | 0 ms | Frontend · unit |
| lib/version-skew.test.ts::polling backs off on failure and is capped | passed | 1 ms | Frontend · unit |
| lib/version-skew.test.ts::refocusing probes, but not on every alt-tab | passed | 0 ms | Frontend · unit |
| lib/version-skew.test.ts::the endpoint is NOT under /api, which Caddy proxies to FastAPI | passed | 1 ms | Frontend · unit |
| lib/version-skew.test.ts::the notice is mounted in the dashboard layout, not per screen | passed | 0 ms | Frontend · unit |
| lib/version-skew.test.ts::the notice offers a reload and never forces one | passed | 1 ms | Frontend · unit |
| lib/worklist-history.test.ts::a queue nobody has EVER worked says so, not 'nothing this week' | passed | 3 ms | Frontend · unit |
| lib/worklist-history.test.ts::a quiet window on a queue that does move is named as a quiet window | passed | 0 ms | Frontend · unit |
| lib/worklist-history.test.ts::closures that record no time are counted apart, never drawn | passed | 0 ms | Frontend · unit |
| lib/worklist-history.test.ts::no undated note when every closure carries a time | passed | 0 ms | Frontend · unit |
| lib/worklist-history.test.ts::age is the headline on a queue where nothing closes | passed | 1 ms | Frontend · unit |
| lib/worklist-history.test.ts::nothing still open is stated plainly rather than as a zero | passed | 0 ms | Frontend · unit |
| lib/worklist-history.test.ts::a queue younger than a day does not claim an age it cannot support | passed | 0 ms | Frontend · unit |
| lib/worklist.test.ts::band tones keep overdue as urgent as critical | passed | 2 ms | Frontend · unit |
| lib/worklist.test.ts::the action verb never claims the work is finished from the inbox | passed | 1 ms | Frontend · unit |
| lib/worklist.test.ts::overdueHours is null when work is not yet due | passed | 0 ms | Frontend · unit |
| lib/worklist.test.ts::dueText says 'No due time' rather than rendering a blank cell | passed | 0 ms | Frontend · unit |
| lib/worklist.test.ts::groupByBand keeps band order and drops empty bands | passed | 2 ms | Frontend · unit |
| lib/worklist.test.ts::the headline names unassigned work instead of only the viewer's own | passed | 0 ms | Frontend · unit |
| lib/worklist.test.ts::pressing counts critical and overdue together | passed | 0 ms | Frontend · unit |