Skip to content

test(miner-extension): cover options.js pure helpers without a jsdom harness - #7069

Closed
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/extension-options-pure-fn-tests-7008
Closed

test(miner-extension): cover options.js pure helpers without a jsdom harness#7069
luciferlive112116 wants to merge 1 commit into
JSONbored:mainfrom
luciferlive112116:fix/extension-options-pure-fn-tests-7008

Conversation

@luciferlive112116

@luciferlive112116 luciferlive112116 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes #7008

Summary

Scope

  • The PR title follows type(scope): short summary Conventional Commit format.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes — it is a test-only + README-note change scoped to apps/loopover-miner-extension/.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves — Closes #7008.

Validation

  • git diff --check — clean.
  • npm run typecheck — 0 errors (the root tsc config type-checks the new test/options.test.ts).
  • Extension suite: npm --workspace @loopover/miner-extension test — 31 tests pass (24 prior + 7 new) with vitest.config.ts coverage thresholds still met (options.js is not in coverage.include, so the new test adds behavior coverage without moving the gated numbers, mirroring content.js).
  • npm run miner-extension:lint (node --check on all scripts) and npm run miner-extension:typecheck pass; ESLint on the new test file is clean.

If any required check was skipped, explain why:

  • test:coverage, test:workers, build:mcp/test:mcp-pack, ui:openapi:check, ui:lint/ui:typecheck/ui:build, and npm audit are not applicable: this PR touches only apps/loopover-miner-extension/** (a test file plus a README note) — no src/**, no MCP/API/OpenAPI surface, no @loopover/ui files, and no dependency changes. apps/** is outside the Codecov codecov/patch scope, so there is no changed backend line/branch to cover; the extension's own vitest thresholds (verified above) are the relevant coverage signal.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests — N/A (none in this PR).
  • API/OpenAPI/MCP behavior is updated and tested where needed — N/A (none in this PR).
  • UI changes use live API data or real empty/error/loading states — N/A (no UI behavior change).
  • Visible UI changes include a UI Evidence section — N/A: this is a test-only + README-note change; options.js's runtime behavior and the extension UI are unchanged, so there is nothing visual to screenshot.
  • Public docs are updated where needed (the README deferred-coverage note); no changelog edited.

UI Evidence

Not applicable — no visible UI, frontend, or behavioral change. This PR adds a unit-test file and updates a README note only; options.js itself is unchanged, so there is no rendered state to capture.

Notes

  • The extension's vitest suite is not currently a CI-gated step (CI runs miner-extension:lint/:typecheck/:build); the new test file is nonetheless type-checked by the root typecheck job and passes locally with thresholds met, matching how content.test.ts already lives in this package.

…harness (JSONbored#7008)

options.js's pure, DOM-independent helpers had no test file. Add
test/options.test.ts using the same __LOOPOVER_MINER_EXTENSION_TEST__ import
hook that content.test.ts (JSONbored#6189) already proved out: importing options.js on a
non-mounted path (a null-returning document) exposes its internals without any
jsdom mount harness.

Covers parseWatchedRepos, parseRankedCandidatesJson (empty short-circuit, array
parse, non-array rejection, and the UTF-8 byte-size quota that guards
chrome.storage.local against silent over-quota failures), normalizeMinerUiUrl,
and the legacy discoveryIndexUrl purge. Update the README's deferred-coverage
note: content.js and options.js pure logic are now tested this way; only the
mounted options-page/content-script UI event handlers still need a real DOM
harness.

Closes JSONbored#7008
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 17, 2026
@loopover-orb

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-17 20:53:28 UTC

2 files · 1 AI reviewer · no blockers · CI failing · blocked

🛑 Suggested Action - Fix Blockers

Review summary
This is a test-only PR that adds apps/loopover-miner-extension/test/options.test.ts to cover options.js's pure helpers (parseWatchedRepos, parseRankedCandidatesJson, normalizeMinerUiUrl, removeLegacyDiscoveryIndexUrl) via the same non-mounted-document import trick already established for content.js in #6189, plus a matching README update that retires the stale deferred-coverage note. The technique is sound: stubbing document.querySelector to return null forces options.js down its unmounted branch so the pure logic runs without a jsdom harness, and each assertion (newline/comma split, empty-string short-circuit, non-array rejection, UTF-8 byte-size quota, trim/default fallback, legacy key purge) maps to a specific, named behavior. Since validate-tests and validate-tests-merge both show PASSED in CI, the exported __loopoverMinerOptionsInternals surface matches what this test expects.

Nits — 3 non-blocking
  • The test relies on options.js exporting exactly MAX_RANKED_CANDIDATES_JSON_BYTES, DEFAULT_MINER_UI_URL, and SYNC_RANKED_CANDIDATES_MESSAGE off __loopoverMinerOptionsInternals — worth double-checking those names stay in sync if options.js is ever refactored, since a rename here would silently produce `undefined` comparisons rather than a type error given the `unknown`-typed OptionsInternals fields.
  • The oversized-payload test (test/options.test.ts) repeats the string "a" MAX_RANKED_CANDIDATES_JSON_BYTES+1 times — fine functionally, but for a large quota this could be a non-trivial allocation on every test run; consider whether MAX_RANKED_CANDIDATES_JSON_BYTES is small enough that this is a non-issue (likely is, given it's guarding chrome.storage.local).
  • Consider adding one assertion that parseRankedCandidatesJson at exactly MAX_RANKED_CANDIDATES_JSON_BYTES (not +1) does not throw, to pin down the boundary as inclusive rather than exclusive.

CI checks failing

  • validate
  • validate-code

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #7008
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 177 registered-repo PR(s), 110 merged, 27 issue(s).
Contributor context ✅ Confirmed Gittensor contributor luciferlive112116; Gittensor profile; 177 PR(s), 27 issue(s).
Improvement ℹ️ Insufficient signal risk: clean · value: insufficient-signal · LLM: minor
Linked issue satisfaction

Addressed
The PR adds test/options.test.ts using the same import-hook technique as content.test.ts, covering the byte-size quota validator, JSON parsing/validation helpers, watched-repos parsing, URL normalization, and legacy key purge, and updates README.md's deferred-coverage note to cite #6189/#7008 and narrow the remaining gap to the mounted UI event handlers, matching the issue's requirements without a

Review context
  • Author: luciferlive112116
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, JavaScript, MDX, Rust, TypeScript
  • Official Gittensor activity: 177 PR(s), 27 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Triage stale or unlinked PRs.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb

loopover-orb Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (CI is failing (validate, validate-code)). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

@loopover-orb loopover-orb Bot closed this Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extension README's test-coverage deferral note is stale; options.js pure functions can use content.js's proven technique

1 participant