@@ -490,6 +490,54 @@ describe("the commit stamp", () => {
490490
491491// B4. The job posts only when the pull request moves the report, so the decision has to be a
492492// tested function of the two reports rather than shell logic in the workflow.
493+ /**
494+ * `hasDelta` compares no `sensitive` field, and does not need one. Sensitivity reaches the rendered
495+ * comment only through `fixFirstSection`, whose primary sort key it is, and a route can only appear
496+ * there with a scored failure. A scored failure needs a try/catch in the body, `isTrivialExport`
497+ * rejects any export that has one, and a sensitive non-trivial export is therefore either accused
498+ * (`fail`) or guarded (`pass`) on `auth-boundary`, never `not-applicable`. So a flip that could move
499+ * the fix list always moves `auth-boundary`, which moves `checkContributions`, which is compared.
500+ *
501+ * Both halves are pinned here because the argument rests on that coupling: make a trivial route
502+ * capable of a scored failure and the first case below starts rendering a difference `hasDelta` cannot
503+ * see.
504+ */
505+ describe ( "a sensitivity flip" , ( ) => {
506+ const stub = `import { redirect } from "@remix-run/server-runtime";
507+ export const loader = () => redirect("/");` ;
508+ const stubSensitive = `import { redirect } from "@remix-run/server-runtime";
509+ import { createPersonalAccessToken } from "~/services/personalAccessToken.server";
510+ export const loader = () => redirect("/");` ;
511+
512+ it ( "renders nothing different on a route too trivial to reach the fix list" , ( ) => {
513+ const base = buildReport ( [ scanFile ( "resources.stub.ts" , stub ) ! ] , [ ] ) ;
514+ const head = buildReport ( [ scanFile ( "resources.stub.ts" , stubSensitive ) ! ] , [ ] ) ;
515+ expect ( base . entries [ 0 ] ! . sensitive ) . toBe ( false ) ;
516+ expect ( head . entries [ 0 ] ! . sensitive ) . toBe ( true ) ;
517+
518+ expect ( renderPrComment ( head , base ) ) . toBe ( renderPrComment ( base , base ) ) ;
519+ expect ( hasDelta ( head , base ) ) . toBe ( false ) ;
520+ } ) ;
521+
522+ it ( "moves auth-boundary, and so is caught, on a route that does real work" , ( ) => {
523+ const working = `export async function loader() {
524+ try { compute(); } catch (e) { return null; }
525+ }` ;
526+ const workingSensitive = `import { createPersonalAccessToken } from "~/services/personalAccessToken.server";
527+ export async function loader() {
528+ try { compute(); } catch (e) { return null; }
529+ }` ;
530+ const base = buildReport ( [ scanFile ( "resources.work.ts" , working ) ! ] , [ ] ) ;
531+ const head = buildReport ( [ scanFile ( "resources.work.ts" , workingSensitive ) ! ] , [ ] ) ;
532+
533+ const status = ( r : typeof base ) =>
534+ r . entries [ 0 ] ! . checks . find ( ( c ) => c . id === "auth-boundary" ) ! . status ;
535+ expect ( status ( base ) ) . toBe ( "not-applicable" ) ;
536+ expect ( status ( head ) ) . toBe ( "fail" ) ;
537+ expect ( hasDelta ( head , base ) ) . toBe ( true ) ;
538+ } ) ;
539+ } ) ;
540+
493541describe ( "hasDelta" , ( ) => {
494542 const trivial = `export const loader = () => new Response("ok");` ;
495543 const one = ( name : string , source : string ) => buildReport ( [ scanFile ( name , source ) ! ] , [ ] ) ;
0 commit comments