Skip to content

test: pin the uri-safety classifier's own contract - #1262

Merged
mrbobbytables merged 1 commit into
mainfrom
quality/test-uri-safety-contract
Oct 10, 2026
Merged

mrbobbytables merged 1 commit into
mainfrom
quality/test-uri-safety-contract

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Adds tests/uri-safety.test.mjs — the first test that imports
scripts/lib/uri-safety.mjs directly.

That module is the shared decision point for both content gates
(scripts/lib/svg-active-content.mjs:24 and
scripts/lib/mdx-active-content.mjs:29 both import from it), and its header
states that a divergence between the two gates is "a bypass of whichever gate is
more permissive". Until now no file under tests/ imported it: every assertion
about it was made through findActiveContent / findRemoteReferences on a whole
SVG or Markdown document, so the predicate's own boundaries were reached only
through whichever values those fixtures happened to carry.

20 tests, pinning today's behaviour of four exports:

  • decodeEntities — hexadecimal and decimal references with and without the
    terminating semicolon; the out-of-range guard (� and �
    are handed back unchanged rather than thrown out of String.fromCodePoint);
    all seven named references; an unrecognised name left as written.
  • normalizeUri — the deliberate second decode pass (: → :),
    whitespace and control-character stripping, lowercasing, and non-string
    coercion.
  • activeScheme — each of the four script-executing schemes; reference- and
    control-character-obscured forms; the scheme-boundary rule in both
    directions (url(javascript:…) matches, xjavascript:, not-javascript:,
    x.javascript: and x+javascript: do not); the same boundary for data:;
    all nine active data: media types plus the +xml suffix rule; the inert
    types (image/png, font/woff2, data:,) left alone.
    Also records that foo javascript:alert(1) is not flagged — normalizeUri
    removes the space before the boundary test, so no scheme boundary survives.
    That answer was previously unstated anywhere.
  • describeTarget — both sides of the 120-character cut, including that the
    truncated form is itself exactly 120 characters.

No production code changes; this records existing behaviour only.

Scope and open-PR overlap

remoteTarget is deliberately excluded. #1249 is open and changes exactly
that function (slashless http: authorities) along with
tests/svg-active-content.test.mjs. The four exports covered here are untouched
by #1249 and by #1255, and this PR adds one new file and edits nothing else, so
the diffs do not overlap. A follow-up can extend this file to remoteTarget
once #1249 lands.

Verification

Repository revision 365e11f (main), node v26.10.0, TZ=UTC:

  • node --test tests/uri-safety.test.mjs → 20 pass, 0 fail.
  • npm run test:unit:coverage:check → exit 0;
    src files | 100.00 | 100.00 | 9015/9015 lines | 2715/2715 regions
    (region denominator rises from 2713 as the direct import attributes
    uri-safety.mjs's regions to the file itself), harness files and
    all files unchanged.
  • npx prettier --check tests/uri-safety.test.mjs → clean.

Related Issue

Closes #1261


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

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

scripts/lib/uri-safety.mjs is the shared decision point for the SVG and
MDX content gates, but no file under tests/ imported it: every assertion
about decodeEntities, normalizeUri, activeScheme and describeTarget was
made indirectly, through findActiveContent/findRemoteReferences on a
whole SVG or Markdown document.

Add tests/uri-safety.test.mjs, which imports the module directly and
records today's behaviour for each of those four exports -- both
numeric-reference forms and the out-of-range guard, the named
references, the deliberate second decode pass, control-character
stripping, every script-executing scheme, the scheme-boundary rule in
both directions, the active data: media types and the +xml suffix rule,
the inert ones, and both sides of describeTarget's 120-character cut.

remoteTarget is deliberately left out: #1249 is open over that function.

No production code changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <quality@hive.kubestellar.io>
@hivecommons-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 keep the hold label until a human removes it. Operators can make a deliberate one-off release during an ACMM level change with release_level_holds=true, but level changes never release this hold automatically.

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] scripts/lib/uri-safety.mjs, the predicate both content gates share, has no direct unit test

1 participant