Skip to content

[quality] test: cover harvestPortalContributors in scripts/fetch-portal-contributors.js - #1235

Open
kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-portal-contributors-harvest
Open

[quality] test: cover harvestPortalContributors in scripts/fetch-portal-contributors.js#1235
kubestellar-hive[bot] wants to merge 1 commit into
mainfrom
quality/test-portal-contributors-harvest

Conversation

@kubestellar-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Adds 17 unit tests covering harvestPortalContributors in scripts/fetch-portal-contributors.js, plus the module-private githubJson / githubPages pagination helpers it drives. Tests only — no production code is changed.

Exact ground this PR claims

Why

scripts/fetch-portal-contributors.js was the worst-covered file in scripts/ at 32.38% line / 75.00% branch / 60.00% function. The existing test file covered only the four pure helpers (isIgnoredContributor, calculateActivityWindow, formatActivityWindowLabel, filterUniqueContributors). The 95-line routine that actually produces static/data/portal-contributors.json had no assertions.

What is covered

Driven through a stubbed globalThis.fetch, restored in a finally block:

  • payload shape — generatedAt, activityWindowSince, activityWindowLabel, bluefinPulseUrl, and a custom windowDays
  • repository selection — org listing plus the ublue-os/bluefin and ublue-os/bluefin-lts fallbacks, forks and nameless repos skipped, fallbacks de-duplicated against the org listing
  • pagination — per_page=100 page walk, the & separator required because ?type=all is already present, short-page termination, non-array page termination, and the three-page cap on commit history
  • the since= activity-window filter on every commit request
  • contributor filtering — bots, authorless commits, empty logins, synthesised html_url, and de-duplication of one person across repos
  • degradation — org listing failure still yields the fallback repos, a single failing repo does not discard the others (Promise.allSettled), and a Discussions outage leaves commit contributors intact
  • discussion authors inside the window are added; stale and undated ones are not
  • the twelve-person limit and the unavailable: true empty payload

Result

metric before after
line 32.38% 75.00%
branch 75.00% 95.74%
function 60.00% 89.47%

npm run test:coverage: 1017 passing, 0 failing, gate satisfied. npx eslint and npx prettier --check are clean on the changed file.

The remaining uncovered range is main (lines 171-226), whose 24-hour cache-freshness branch and fatal-fallback write cannot be exercised without an injectable output path — that is a production change and is deliberately out of scope, as noted in #1234.

Disjointness

No other open PR touches scripts/fetch-portal-contributors.js or its test. Verified against the open documentation PRs: #1215 and #1233 (scripts/fetch-firehose.js), #1212 (scripts/fetch-github-sbom.js), #1213 (scripts/lib/card-feed-parser.mjs), #1226 (.github/workflows/test.yml + scripts/portal-*.test.js), #1227/#1228 (src/components/), #1216 (static/data/).

Related Issue

Closes #1234


Filed by quality agent (hold-gated mode). Human review required — do not merge without it.

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

…utors.js

scripts/fetch-portal-contributors.js sat at 32.38% line / 60.00% function
coverage: only the four pure helpers (isIgnoredContributor,
calculateActivityWindow, formatActivityWindowLabel, filterUniqueContributors)
were exercised. The 95-line harvestPortalContributors routine that actually
produces static/data/portal-contributors.json — and the module-private
githubJson/githubPages pagination helpers it drives — had no assertions at all.

Adds 17 cases to scripts/fetch-portal-contributors.test.js, driven through a
stubbed global fetch:

- payload shape: generatedAt, activityWindowSince, activityWindowLabel,
  bluefinPulseUrl, and a custom windowDays
- repository selection: org listing plus the ublue-os/bluefin and
  ublue-os/bluefin-lts fallbacks, forks and nameless repos skipped,
  fallbacks de-duplicated against the org listing
- pagination: per_page=100 page walk, '&' separator on the type=all URL,
  short-page termination, non-array page termination, and the three-page
  cap on commit history
- since= filter carries the activity window
- contributor filtering: bots, authorless commits, empty logins, synthesised
  html_url, and de-duplication of one person across repos
- degradation: org listing failure still yields the fallback repos, a single
  failing repo does not discard the others (Promise.allSettled), and a
  Discussions outage leaves commit contributors intact
- discussion authors inside the window are added, stale and undated ones are not
- the twelve-person limit and the unavailable=true empty payload

Raises scripts/fetch-portal-contributors.js to 75.00% line / 95.74% branch /
89.47% function coverage. Tests only; no production code changed.

Signed-off-by: sec-check[bot] <sec-check[bot]@users.noreply.github.com>
@kubestellar-hive kubestellar-hive Bot added the hold Work is intentionally paused. label Sep 12, 2026
@kubestellar-hive kubestellar-hive Bot added hold Work is intentionally paused. quality Code quality or test-coverage work. testing Test authoring or test infrastructure. agent/quality Filed or owned by the quality agent. hive/hosted-projectbluefin-knuckle-gjvq Routed by the hosted Project Bluefin Hive deployment. labels Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent/quality Filed or owned by the quality agent. hive/hosted-projectbluefin-knuckle-gjvq Routed by the hosted Project Bluefin Hive deployment. hold Work is intentionally paused. quality Code quality or test-coverage work. testing Test authoring or test infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[quality] coverage-gap: scripts/fetch-portal-contributors.js harvestPortalContributors (95 lines, 32% line coverage)

0 participants