Skip to content

test: cover DirectoryFreshness's unparseable-timestamp arms end to end - #1104

Merged
mrbobbytables merged 3 commits into
mainfrom
quality/test-directory-freshness-variant
Oct 7, 2026
Merged

mrbobbytables merged 3 commits into
mainfrom
quality/test-directory-freshness-variant

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Covers formatDate's Number.isNaN guard
(src/components/MemberDirectory/utils.js line 16) and the two operands that
DirectoryFreshness short-circuits past while every provenance timestamp
parses (src/components/MemberDirectory/DirectoryFreshness.js lines 19 and
49).

17   const landscapeDate = formatDate(landscape?.collectedAt);
19   if (!landscapeDate && !architecturesDate && !awardsDate) return null;
49       {(landscapeDate || architecturesDate) && awardsDate && ' '}

data/members.json always carries a parseable
sources.landscape.collectedAt, so landscapeDate is always truthy, the
operands beside it are never evaluated, and formatDate never sees a value
Date rejects. That guard is what stops a malformed timestamp from a
scheduled refresh rendering the literal string Invalid Date into the
directory's provenance note, and a browser had never taken it.

Why the variant build

tests/e2e/fixtures/data/** overlays are additive. Making the timestamp
unparseable there would not add a case — it would trade the membership
sentence for these arms, taking the lines tests/e2e/member-directory-freshness.spec.js
(#1075) asserts with it. The overlay goes in
tests/e2e/fixtures/data-variants/members.json instead, the mechanism
tests/e2e/data-variants.spec.js already documents for this class of branch,
so one Playwright run visits /community/members and
/e2e-coverage-variant/community/members and the report unions what each build
reached.

What this adds

  • tests/e2e/fixtures/data-variants/members.json — sets
    sources.landscape.collectedAt to an unparseable string. The path must
    already exist in the real file, so a regenerated data/members.json that
    drops it fails the build rather than silently losing the coverage.
  • tests/e2e/member-directory-freshness-variant.spec.js — two cases, skipped
    outside E2E_COVERAGE=1. The first asserts the real route renders the
    membership sentence and the variant route omits it while still rendering the
    note and the architectures sentence, and that Invalid Date appears nowhere;
    the second asserts the directory's member cards still render on the variant
    route, so the first is evidence about the sentence and not about a build that
    lost the page. Both read the timestamps through loadSiteData() rather than
    hard-coding them, so an edited overlay fails here instead of leaving a test
    that asserts nothing.

Verification

Run locally at 8afaa67 (npm run build:e2e:coverage, then the coverage
Playwright run with E2E_COVERAGE_DIR/E2E_COVERAGE_RUN_ID set, chromium,
node v26.10.0): 300 passed. npm run test:unit: 1941 passed, 0 failed.

Rendered against that run, compared with CI artifact e2e-coverage id
11348560988 from run
37317061554 at the
same revision:

file before after
src/components/MemberDirectory/utils.js 17/18 regions (94.44%) 21/21 (100.00%)
src/components/MemberDirectory/DirectoryFreshness.js 4/9 (44.44%) 7/14 (50.00%)
src files 377/429 (87.88%) 385/438 (87.90%)

The region totals rise too: the variant build compiles a second copy of these
files and the reporter's union does not fold every one of its regions onto its
real-build twin — the drift already tracked by #1066 and #1079. One visible
consequence is that DirectoryFreshness.js line 35 joins the uncovered-region
list; it is an unfolded twin of a region the real build covers, not a case that
stopped running. The gate is on src files
(--check-source 100 --check-source-regions 80) and is unaffected.

Out of scope

DirectoryFreshness.js lines 30 and 44 — the no-URL fallbacks for
cncf/landscape and cncf/architecture — need sourceUrl / repository to
be null while the dates still parse, which contradicts this overlay, and line
44's half would belong in tests/e2e/fixtures/data-variants/metrics.json,
which #1093 is editing.

Coordination

Touches only two new files. Disjoint from #1075
(tests/e2e/member-directory-freshness.spec.js, real route only), #1093
(data-variants/metrics.json), #1098 (data-variants/radar-reports.json) and
#1034/#1078 (tests/e2e-data-fixtures.test.mjs, deliberately not edited here —
once #1100 lands, its directory-wide integrity check covers this overlay
without a per-file list).

Related Issue

Closes #1103


Human review required.

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

src/components/MemberDirectory/utils.js line 16 -- formatDate's
Number.isNaN guard -- and the short-circuited operands at
src/components/MemberDirectory/DirectoryFreshness.js lines 19 and 49 only
run when one of the three provenance timestamps does not parse.
data/members.json always carries a parseable
sources.landscape.collectedAt, so no build the end-to-end suite visits
takes them.

Clearing the field in the ordinary coverage build would trade the
membership sentence for these arms rather than add a case, so the
timestamp is made unparseable in a variant overlay instead and one
Playwright run visits both /community/members and its variant.

utils.js reaches 100% of e2e regions and DirectoryFreshness rises from
4/9 to 7/14 regions.

Closes #1103

Signed-off-by: quality <quality@hive.kubestellar.io>
@hivecommons-hive hivecommons-hive Bot added the hold label Oct 5, 2026
@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.

@castrojo castrojo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Holding: in tests/e2e/member-directory-freshness-variant.spec.js:47-72 the "other two sentences must survive" preconditions read metrics.json and awards.json with COVERAGE_ENV, but the page under test is the variant build, which also applies data-variants/metrics.json (generatedAt: null) and data-variants/awards.json (verifiedAt: null). formatDate(null) yields the Unix epoch (new Date(null) is 0, not NaN), so on /e2e-coverage-variant/community/members the architectures and awards sentences render "January 1, 1970", and the assertions at lines 79-86 pass only because of that. Load the preconditions with VARIANT_ENV, then either make formatDate treat null as missing or choose a variant shape that keeps real architectures/awards dates. #1075 (the real-page freshness spec this one references) is queued ahead of this.

quality added 2 commits October 6, 2026 09:52
Review on #1104: the "other two sentences must survive" preconditions in
tests/e2e/member-directory-freshness-variant.spec.js read metrics.json and
awards.json through COVERAGE_ENV, but the assertions that follow run against
/e2e-coverage-variant/community/members, which is built from the VARIANT_ENV
overlay. That overlay sets metrics.generatedAt and awards.verifiedAt to null,
so the preconditions described a document the page under test was never built
from, and the architectures/awards sentences rendered only because
formatDate(null) is the Unix epoch rather than an Invalid Date.

Load both documents with VARIANT_ENV, assert the null they actually carry, and
pin the epoch text the page renders because of it, so the behaviour the test
depends on is stated rather than relied on by accident. If formatDate is later
changed to treat null as missing, DirectoryFreshness returns null for this
page and the test fails loudly instead of asserting an empty note.

Signed-off-by: quality <quality@hive.kubestellar.io>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Thanks — confirmed, and fixed in 07ab851 (the branch is also merged up to current main).

The review is right about the mechanism. new Date(null) is 0, not NaN, so formatDate(null) returns a formatted epoch date rather than null. Verified against the built variant page rather than inferred — build/e2e-coverage-variant/community/members/index.html renders:

Architecture-derived profiles last synced from cncf/architecture on December 31, 1969. Award data last verified on December 31, 1969.

(December 31, 1969 rather than January 1, 1970 because nothing pins TZ for the build or the Playwright run, and 0ms lands in 1969 west of UTC.) The old assertions at lines 79-86 did pass only because of that.

What changed. Only tests/e2e/member-directory-freshness-variant.spec.js:

  • metrics.json and awards.json are now loaded with VARIANT_ENV, so the preconditions describe the document the page under test was actually built from.
  • The preconditions assert what the variant overlay really carries — generatedAt === null, verifiedAt === null — and then, separately, that those values still format to a date. The parses() helper (which had a Boolean(value) guard formatDate does not have) is replaced by formatsToADate(), which mirrors formatDate's Number.isNaN(new Date(v).getTime()) exactly.
  • A new assertion pins the epoch text the page renders because of it, matched TZ-robustly as /December 31, 1969|January 1, 1970/.

The behaviour the test depends on is now stated instead of relied on by accident: if formatDate is later changed to treat null as missing, all three dates go null, DirectoryFreshness returns null, and this test fails loudly rather than quietly asserting an empty note.

On the two options offered. I took the third one deliberately. Changing formatDate is production code, which this lane does not PR. Changing the metrics.json/awards.json variant overlays to keep real dates is not available either: those overlays exist to hold open ReferenceArchitectures' and AwardsTimeline' s : null arms, so giving them real timestamps would drop the coverage they were written for. Making the epoch explicit is what is left, and it is also the honest description of what the shipped code does today.

That said, formatDate(null) rendering a 1969/1970 date into a user-facing provenance sentence is a real latent defect in src/components/MemberDirectory/utils.js — it is only unreachable in production because data/metrics.json and data/awards.json always carry their timestamps, and those files are regenerated by scheduled collectors. I have not filed it separately to avoid duplicating an existing issue I cannot see from here; flagging it here so it is on the record.

Verification. The browser could not be launched in this environment (chrome-headless-shell fails on a missing libglib-2.0.so.0, and there is no root to install it), so the spec's assertions were checked against the real artifacts instead: both overlays through loadSiteData, and the rendered text of build/community/members/index.html and build/e2e-coverage-variant/community/members/index.html from a full local npm run build:e2e:coverage. All twelve checks — the four preconditions, the real page's membership sentence, and the variant page's note count, architectures sentence, epoch date, absent membership sentence, absent Invalid Date, and intact member cards — pass. npm run test:unit is green at 1966/1966. CI runs the spec in a real browser.

The hold label stays on.


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: 07ab851

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

mrbobbytables pushed a commit that referenced this pull request Oct 7, 2026
src/components/GroupLinkStatus/index.js is the lowest-covered file in the
end-to-end report at 60% of regions. Three of its four uncovered regions
are reachable, and all three need a second build:

  * line 7, formatDate's Number.isNaN guard, needs a checkedAt that does
    not parse, which the real file never carries;
  * lines 32-33, the plural arms of the drift warning, need two groups
    drifting at once, while the ordinary coverage overlay appends exactly
    one archived group.

Clearing checkedAt or emptying the list in the ordinary coverage build
would swap which arm renders rather than add a case, so the overlay goes
in tests/e2e/fixtures/data-variants/ and the variant site is asserted
beside the real one. The appended group drifts through reachable:false
rather than archived:true so the filter's second operand decides it, as a
link-check run that cannot reach a repository produces.

tests/e2e-data-fixtures.test.mjs used community-groups.json as the
contrast case for a file with no variant overlay, which this makes false.
case-studies.json takes that role: members.json is the other base-only
overlay, but open PR #1104 adds a members.json variant, so it would stop
being a contrast as soon as that lands.

Verified by building both sites locally with npm run build:e2e:coverage
and reading the rendered HTML. build/community: verification line dated
"September 23, 2026", singular "has an archived or unreachable upstream
repository", one group named, no plural. build/e2e-coverage-variant/
community: no verification line and no "Invalid Date", plural "have
archived or unreachable upstream repositories", both groups named. The
Playwright run itself was not executed here -- this sandbox has no
browser (chrome-headless-shell cannot load libglib-2.0.so.0 and there is
no root to install it), so CI is the first place the spec runs.

Line 23's `|| []` is deliberately left uncovered: reaching it means
clearing `groups` entirely, which stops the warning rendering at all.

Signed-off-by: quality <quality@hive.kubestellar.io>
mrbobbytables added a commit that referenced this pull request Oct 7, 2026
case-studies.json gained a variant overlay in #1133, and members.json
gains one in #1104; the architectures catalog is the remaining data file
the ordinary coverage build overlays and the variant build does not.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
@mrbobbytables
mrbobbytables disabled auto-merge October 7, 2026 13:07
@mrbobbytables
mrbobbytables dismissed castrojo’s stale review October 7, 2026 13:09

Addressed by 07ab851: the preconditions now load metrics.json and awards.json through VARIANT_ENV, assert the nulls the variant overlay actually carries, and pin the epoch-rendering behavior with a comment pointing at the formatDate(null) semantics, so a future change to treat null as missing fails this test loudly. Dismissing to unblock the queue; re-review welcome.

@mrbobbytables
mrbobbytables added this pull request to the merge queue Oct 7, 2026
Merged via the queue into main with commit fc2f000 Oct 7, 2026
7 checks passed
@mrbobbytables
mrbobbytables deleted the quality/test-directory-freshness-variant branch October 7, 2026 15:19
mrbobbytables added a commit to mrbobbytables/endusers that referenced this pull request Oct 8, 2026
…cncf#1113)

* test: cover GroupLinkStatus's plural arms and invalid-checkedAt guard

src/components/GroupLinkStatus/index.js is the lowest-covered file in the
end-to-end report at 60% of regions. Three of its four uncovered regions
are reachable, and all three need a second build:

  * line 7, formatDate's Number.isNaN guard, needs a checkedAt that does
    not parse, which the real file never carries;
  * lines 32-33, the plural arms of the drift warning, need two groups
    drifting at once, while the ordinary coverage overlay appends exactly
    one archived group.

Clearing checkedAt or emptying the list in the ordinary coverage build
would swap which arm renders rather than add a case, so the overlay goes
in tests/e2e/fixtures/data-variants/ and the variant site is asserted
beside the real one. The appended group drifts through reachable:false
rather than archived:true so the filter's second operand decides it, as a
link-check run that cannot reach a repository produces.

tests/e2e-data-fixtures.test.mjs used community-groups.json as the
contrast case for a file with no variant overlay, which this makes false.
case-studies.json takes that role: members.json is the other base-only
overlay, but open PR cncf#1104 adds a members.json variant, so it would stop
being a contrast as soon as that lands.

Verified by building both sites locally with npm run build:e2e:coverage
and reading the rendered HTML. build/community: verification line dated
"September 23, 2026", singular "has an archived or unreachable upstream
repository", one group named, no plural. build/e2e-coverage-variant/
community: no verification line and no "Invalid Date", plural "have
archived or unreachable upstream repositories", both groups named. The
Playwright run itself was not executed here -- this sandbox has no
browser (chrome-headless-shell cannot load libglib-2.0.so.0 and there is
no root to install it), so CI is the first place the spec runs.

Line 23's `|| []` is deliberately left uncovered: reaching it means
clearing `groups` entirely, which stops the warning rendering at all.

Signed-off-by: quality <quality@hive.kubestellar.io>

* test: move the no-variant contrast case to architectures/catalog.json

case-studies.json gained a variant overlay in cncf#1133, and members.json
gains one in cncf#1104; the architectures catalog is the remaining data file
the ordinary coverage build overlays and the variant build does not.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>

---------

Signed-off-by: quality <quality@hive.kubestellar.io>
Signed-off-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
Co-authored-by: quality <quality@hive.kubestellar.io>
Co-authored-by: mrbobbytables <mrbobbytables@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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] DirectoryFreshness's unparseable-timestamp arms and formatDate's NaN guard have no end-to-end coverage

2 participants