Skip to content

test(ui): cover the client-side openapi spec parser and code-sample generators#8428

Closed
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:test/critical-issue-openapi-lib-coverage
Closed

test(ui): cover the client-side openapi spec parser and code-sample generators#8428
kai392 wants to merge 1 commit into
JSONbored:mainfrom
kai392:test/critical-issue-openapi-lib-coverage

Conversation

@kai392

@kai392 kai392 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

apps/loopover-ui/src/lib/openapi.ts had zero tests despite being the module every /api/* docs page runs at request time — it derives the id each /api/$op URL is keyed on, merges declared vs. path-inferred parameters, extracts response examples, groups tags, rewrites the server origin, and generates the curl/fetch/Python samples. Same class of gap already fixed once for the server-side spec writer in #7770; this is the client-side reader.

Adds apps/loopover-ui/src/lib/openapi.test.ts (14 tests, no production changes).

Fixture, not the committed spec. build() isn't exported and runs at module-import time against public/openapi.json, whose contents drift with every API change. So the spec module is mocked with a small hand-built RawOpenApiSpec and openapi.ts is imported dynamically per test (vi.resetModules()); getApiOrigin is mocked too so normalizeServers' rewrite is asserted against a fixed origin. Nothing here depends on the real spec's current shape.

Covered, per the issue's list:

  • slugify (via op.id): GET /v1/repos/{owner}/{repo}get-v1-repos-owner-repo, with braces stripped, runs collapsed, and no leading/trailing/doubled -
  • extractPathParams: an undeclared {param} is auto-added as required: true / in: "path"; a declared one is not duplicated and the author's description wins
  • extractExample: prefers example; falls back to the first examples entry — asserted on the real unwrapping (first?.value, i.e. 1, not the { value: 1 } envelope); undefined with no application/json content, and no response entries at all for an empty responses
  • tag grouping: declared tags keep their description; build()'s fallback loop still surfaces a tag never declared in raw.tags
  • normalizeServers: the first server's url is overwritten with the live origin while later servers are untouched
  • generateCurl / generateFetch / generatePython: both the auth and no-auth arms, both the body and body-less arms (with DELETE asserted body-less alongside GET), the trailing-slash strip, and the inline-token vs $LOOPOVER_TOKEN branch

Closes #8389

Test plan

  • npx vitest run --root apps/loopover-ui src/lib/openapi.test.ts — 14/14 green
  • npm run ui:typecheck clean; prettier --check clean on the new file
  • Test-only addition — no production file changed, so no behavior risk. apps/** is outside Codecov's coverage.include, so this owes no codecov/patch percentage; it exists to close a real assertion gap, not to move a number
  • CI validate

@kai392
kai392 requested a review from JSONbored as a code owner July 24, 2026 12:48
@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 24, 2026
@loopover-orb

loopover-orb Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-24 12:59:59 UTC

1 file · no blockers · CI green · clean

⏸️ Suggested Action - Manual Review

  • AI review already in progress for this PR head: Another LoopOver pass is already running the AI review for this exact PR head. This pass is skipping to avoid a duplicate LLM call.

Review summary
AI review is already running for this PR head in another LoopOver pass. LoopOver is holding this PR for manual review until that pass completes.

Nits — 1 non-blocking
  • AI review already in progress for this PR head — The gate is held for a human reviewer rather than passed automatically; it re-evaluates once the in-flight review completes or on the next update.

Decision drivers

  • ✅ Code review — No blockers (No AI review summary)
  • ⚠️ Gate result — Not blocking (Advisory; not blocking this PR.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #8389
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: 117 registered-repo PR(s), 62 merged, 4 issue(s).
Contributor context ✅ Confirmed Gittensor contributor kai392; Gittensor profile; 117 PR(s), 4 issue(s).
Improvement ℹ️ Insufficient signal risk: clean · value: insufficient-signal
Linked issue satisfaction

Addressed
The PR adds apps/loopover-ui/src/lib/openapi.test.ts with a hand-built fixture (not the committed public/openapi.json) covering slugify via op.id, extractPathParams' declared-vs-undeclared branch, extractExample's example/examples/undefined branches, declared and fallback tag grouping, normalizeServers' first-vs-later-server rewrite, findOperation, and auth/body branching in generateCurl/generateF

Review context
  • Author: kai392
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 117 PR(s), 4 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.

🟩 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 24, 2026

Copy link
Copy Markdown
Contributor

LoopOver closed this because @kai392 has 3 open pull requests, above this repository's configured limit of 2. Close or merge an existing one to open a new one. This is an automated maintenance action.

@loopover-orb loopover-orb Bot closed this Jul 24, 2026
@loopover-orb loopover-orb Bot added the mod:warning Gittensor contributor context label Jul 24, 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. mod:warning Gittensor contributor context

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lib/openapi.ts's client-side spec parsing/transform logic has zero test coverage

2 participants