Skip to content

test: cover the src/ JSX link and image hygiene contract (tests/jsx-link-hygiene.test.mjs) - #343

Open
kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-jsx-link-hygiene
Open

kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-jsx-link-hygiene

Conversation

@kubestellar-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Adds one new test-only file, tests/jsx-link-hygiene.test.mjs (4 tests). It is
the first test in this repository to read a JSX attribute.

Files claimed by this PR: tests/jsx-link-hygiene.test.mjs (new). Nothing
else — no production code, no workflow, no package.json, no lockfile, no new
dependency. It uses only node:test, node:assert/strict, node:fs,
node:path and node:url. It does not modify tests/helpers.mjs (claimed
by #231), does not import docusaurus.config.js (claimed by #275), and
adds no JSX transform or import path (claimed by #229) — it scans source
text, so it needs neither.

The gap

src/ holds 10 JSX files with 21 <a> tags (19 of them target="_blank")
and 8 <img> tags
, and nothing checks any of them.

The repository declares no ESLint configuration — no .eslintrc*, no
eslint.config.*, no eslintConfig key in package.json — so
eslint-plugin-jsx-a11y and react/jsx-no-target-blank, the rules that
normally own this ground, never run. npm run check is prettier, markdownlint,
cspell and markdown-link-check; none of them models JSX attributes.
docusaurus build compiles JSX without auditing it.

Every failure mode here is silent — clean build, green deploy:

  • target="_blank" with no rel hands the opened page a live window.opener
    handle back to this site (reverse tabnabbing). Modern browsers imply
    noopener; older ones and in-app webviews do not.
  • <img> with no alt makes a screen reader announce the file name.
  • A literal http:// href is blocked as mixed content on the https site.

All three hold on main today, which is the point: pinning a currently-green
invariant costs nothing and stops the first regression. The rel spellings are
already drifting — 10 anchors say rel="noreferrer" and 9 say
rel="noopener noreferrer" — so a future omission would read as one more
variant rather than a defect.

What the 4 tests assert

  1. Non-vacuity. The scan finds JSX sources, at least 10 anchors and at
    least 5 images, and every scanned <a> carries an href. That last
    clause is the real guard: a scanner that terminated a tag at the first >
    inside an attribute value would return truncated tags and every assertion
    below would pass by finding nothing.
  2. Every target="_blank" anchor has a literal rel whose token list includes
    noopener or noreferrer.
  3. Every <img> declares an alt attribute. alt="" is accepted — it is the
    correct, deliberate marking for the 6 decorative images here; a missing
    attribute is not.
  4. No literal href/src in src/ uses plain http://.

Implementation note

The scanner tracks quote and brace nesting when locating the end of an opening
tag, because this repository really does write > inside attribute values —
aria-label={${organization} — ${awardLabel}} in AwardsTimeline, and arrow
functions in MemberDirectory. Attributes whose value is a JSX expression
rather than a string literal are treated as not statically known and skipped,
so the test cannot produce a false failure on a computed rel.

It walks src/ by file extension rather than assuming one index.js per
component directory, so it keeps working after the MemberDirectory split in
#118.

Verification

  • node --test tests/jsx-link-hygiene.test.mjs4/4 pass at 00b44df.

  • Full suite node --test59/59 pass (55 before, +4).

  • Mutation-checked, not just run green. Four independent mutations of
    src/, each reverted afterwards, each failing exactly the intended test with
    a message naming the file:

    • removed rel="noreferrer" from CNCFProjectCard -> test 2 fails
    • changed a MetricsDashboard rel to "nofollow" -> test 2 fails
    • removed alt="" from a CommunityPeople image -> test 3 fails
    • downgraded the Footer CNCF href to http:// -> test 4 fails

    git status clean afterwards; the committed diff is the one new test file.

  • npx prettier --check tests/jsx-link-hygiene.test.mjs clean.

Coverage evidence

  • Unit: node --test --experimental-test-coverage, local clone of
    cncf/endusers at parent revision 00b44df after npm ci, node v26.8.2,
    2026-09-20. Baseline 55/55 pass with no test reading any JSX attribute;
    after, 59/59.
  • End-to-end: unobtainable, not absent — this repository declares no
    playwright/cypress/puppeteer and publishes no coverage artifact from any
    suite (tracked in [quality] CI publishes no coverage evidence, so coverage findings cannot be verified #186). No claim is made that these paths lack end-to-end
    coverage.

Related Issue

Closes #342 — merging this lands the only deliverable that issue describes, so nothing is left for it to track.


Filed by quality agent (hold-gated mode). Human review required.

— hive: agent=quality backend=copilot model=claude-opus-5

Adds tests/jsx-link-hygiene.test.mjs, asserting that every target="_blank"
anchor under src/ severs window.opener via rel, that every <img> declares an
alt attribute, and that no literal href/src uses plain http.

The repository declares no ESLint configuration, so eslint-plugin-jsx-a11y and
react/jsx-no-target-blank never run, and no existing test reads a JSX
attribute. All three invariants hold on main today; this pins them.

Closes #342

Signed-off-by: kubestellar-hive[bot] <kubestellar-hive@hive.kubestellar.io>
@kubestellar-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will automatically remove the hold label once current policy no longer requires a level hold for "quality". If this is an outreach PR, a human must review it and remove the label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] src/ JSX link and image hygiene is untested: 19 target="_blank" anchors and 8 images have no rel/alt/scheme guard

0 participants