test(10-05): hygiene confines browser storage and self-tests each rule

- --hygiene refuses localStorage, sessionStorage, indexedDB or document.cookie
  outside admin/src/state/useSidebar.ts (T-10-22)
- --self-test plants each violation with a scratch test import, so the
  refusal must come from that rule and not from the untested-module check
This commit is contained in:
Jakub Zych
2026-09-27 18:15:05 +02:00
parent 07edc6ca29
commit fbef773a24

View File

@@ -202,19 +202,41 @@ run_self_test() {
echo "refuse: self-test hygiene rejected the clean scratch copy" >&2 echo "refuse: self-test hygiene rejected the clean scratch copy" >&2
exit 1 exit 1
} }
local plant # Each plant is imported by a scratch test, so only its own rule can fire;
for plant in vhtml fetch appname; do # the refusal must name that rule.
rm -rf "$scratch/admin/src/__plant" local plant want out
for plant in vhtml fetch appname storage; do
rm -rf "$scratch/admin/src/__plant" "$scratch/admin/tests/__plant.test.ts"
mkdir -p "$scratch/admin/src/__plant" mkdir -p "$scratch/admin/src/__plant"
case "$plant" in case "$plant" in
vhtml) printf '<template><div v-html="raw" /></template>\n' >"$scratch/admin/src/__plant/Plant.vue" ;; vhtml)
fetch) printf 'export const load = () => fetch("/x")\n' >"$scratch/admin/src/__plant/plant.ts" ;; printf '<template><div v-html="raw" /></template>\n' >"$scratch/admin/src/__plant/Plant.vue"
appname) printf '// Fonoteka\nexport {}\n' >"$scratch/admin/src/__plant/plant.ts" ;; printf "import Plant from '../src/__plant/Plant.vue'\n" >"$scratch/admin/tests/__plant.test.ts"
want="raw-HTML directive"
;;
fetch)
printf 'export const load = () => fetch("/x")\n' >"$scratch/admin/src/__plant/plant.ts"
want="direct fetch"
;;
appname)
printf '// Fonoteka\nexport {}\n' >"$scratch/admin/src/__plant/plant.ts"
want="application names"
;;
storage)
printf 'export const keep = (v: string) => localStorage.setItem("token", v)\n' >"$scratch/admin/src/__plant/plant.ts"
want="browser storage"
;;
esac esac
if (hygiene_checks "$scratch" "$APP") >/dev/null 2>&1; then [[ -f "$scratch/admin/tests/__plant.test.ts" ]] ||
printf "import '../src/__plant/plant'\n" >"$scratch/admin/tests/__plant.test.ts"
if out="$( (hygiene_checks "$scratch" "$APP") 2>&1)"; then
echo "refuse: self-test hygiene accepted a planted $plant" >&2 echo "refuse: self-test hygiene accepted a planted $plant" >&2
exit 1 exit 1
fi fi
if ! grep -q "$want" <<<"$out" || grep -q "imported by no test" <<<"$out"; then
echo "refuse: self-test hygiene rejected the $plant plant for the wrong reason: $out" >&2
exit 1
fi
done done
echo "phase10 self-test passed" echo "phase10 self-test passed"
} }
@@ -307,6 +329,10 @@ hygiene_checks() {
[[ -z "$hits" ]] || fail "admin/src/api/types.ts declares a shape instead of aliasing the generated schema: $hits" [[ -z "$hits" ]] || fail "admin/src/api/types.ts declares a shape instead of aliasing the generated schema: $hits"
hits="$(cd "$tree" && grep -nE '^export type [A-Za-z]+ = ' admin/src/api/types.ts | grep -vE "= (Schemas\['cabana\.[A-Za-z_-]+'\]|NonNullable<[A-Za-z]+Path\['get'\]\['parameters'\]\['query'\]>|[A-Za-z]+Path\['get'\]\['parameters'\]\['path'\])\$" || true)" hits="$(cd "$tree" && grep -nE '^export type [A-Za-z]+ = ' admin/src/api/types.ts | grep -vE "= (Schemas\['cabana\.[A-Za-z_-]+'\]|NonNullable<[A-Za-z]+Path\['get'\]\['parameters'\]\['query'\]>|[A-Za-z]+Path\['get'\]\['parameters'\]\['path'\])\$" || true)"
[[ -z "$hits" ]] || fail "admin/src/api/types.ts alias not onto the generated schema: $hits" [[ -z "$hits" ]] || fail "admin/src/api/types.ts alias not onto the generated schema: $hits"
# Browser storage holds only the sidebar flag (T-10-22), never a token.
hits="$(cd "$tree" && grep -rnE 'localStorage|sessionStorage|indexedDB|document\.cookie' admin/src 2>/dev/null |
grep -v '^admin/src/state/useSidebar.ts:' || true)"
[[ -z "$hits" ]] || fail "browser storage outside admin/src/state/useSidebar.ts: $hits"
# The embedded build loads nothing from another origin. # The embedded build loads nothing from another origin.
hits="$(cd "$tree" && grep -noE '(src|href)="(https?:)?//[^"]*"|url\((["'"'"']?)(https?:)?//' boardwalk/dist/index.html boardwalk/dist/assets/*.css 2>/dev/null || true)" hits="$(cd "$tree" && grep -noE '(src|href)="(https?:)?//[^"]*"|url\((["'"'"']?)(https?:)?//' boardwalk/dist/index.html boardwalk/dist/assets/*.css 2>/dev/null || true)"
[[ -z "$hits" ]] || fail "boardwalk/dist references another origin: $hits" [[ -z "$hits" ]] || fail "boardwalk/dist references another origin: $hits"