Skip to content

fix(admin): prevent no-op tenant saves and cover settings states - #436

Merged
seonghobae merged 6 commits into
worktree-fix-frontend-build-breakfrom
worktree-fix-adminpanel-coverage
Aug 23, 2026
Merged

fix(admin): prevent no-op tenant saves and cover settings states#436
seonghobae merged 6 commits into
worktree-fix-frontend-build-breakfrom
worktree-fix-adminpanel-coverage

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Buyer-visible gap

Tenant settings could be submitted through the form even when the trimmed brand name was empty or unchanged. That created a needless write outside the disabled-button path, while success and failure feedback was not announced to assistive technology.

Change

  • Guard the shared form-submit path against empty and unchanged names and send only the trimmed value.
  • Announce saved and failed states with native live-region roles.
  • Cover unchanged, whitespace-only, success auto-clear, failure, and empty-error fallback paths at exact 100% production statement/branch/function/line coverage.
  • Keep the default and long-name Storybook states and register the component in the Storybook inventory.

The prior App/OIDC changes are removed from this PR's effective diff and inherited from parent PR #426.

Stack boundary

Verification

  • Focused AdminPanel: 4 passed; 20 statements, 15 branches, 4 functions, and 18 lines at 100%.
  • Full frontend: 167 passed.
  • pnpm run lint: passed.
  • pnpm run build: passed.
  • pnpm run build-storybook: passed.
  • git diff --check: passed.

Only synthetic names are used; no real records, identifiers, or provider credentials are included.

Found via a systematic component-vs-story-vs-test cross-reference of
frontend/src/components/*.tsx -- AdminPanel had neither a .test.tsx
nor a .stories.tsx, unlike every other component in the directory.

Tests cover: save disabled until the brand name actually changes,
a successful save calling updateTenantConfig (backend/app/main.py's
PATCH /api/settings, now covered separately in #435) with the right
arguments and reporting the new name back to the caller, and a failed
save showing the error while leaving the form editable (not stuck
disabled). Storybook stories cover the default state and a long
brand-name layout edge case.

pnpm run test: 143 passed (was 140). pnpm run lint: no new warnings.
pnpm run build: the two pre-existing App.tsx errors are the unrelated
main break already fixed in #426, not something this PR touches.
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 750b479f-9fee-46fa-8ab8-0a3a6520b695

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

devin-ai-integration[bot]

This comment was marked as resolved.

Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434: the
login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth). This PR's own AdminPanel.test.tsx/.stories.tsx
render the component directly, so this doesn't affect its coverage.
seonghobae added a commit that referenced this pull request Aug 22, 2026
Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#436:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth).
devin-ai-integration[bot]

This comment was marked as resolved.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Acknowledged — vitest's ESM-mutable-export spying does work here, but passing a mocked dependency would be more robust if this pattern gets reused elsewhere. Not blocking this PR's own scope (adding AdminPanel coverage); worth keeping in mind for the next component test that needs to mock ../api.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Acknowledged — the raw English-key assertions work because jsdom defaults navigator.language to en-US, matching this repo's other component tests' existing convention. Not blocking; a locale-agnostic assertion helper would be a nice future improvement across the whole test suite, not specific to this PR.

@seonghobae
seonghobae enabled auto-merge (squash) August 22, 2026 12:26
seonghobae added a commit that referenced this pull request Aug 22, 2026
Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth). This PR's own diff doesn't touch AdminPanel.
seonghobae added a commit that referenced this pull request Aug 22, 2026
Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436/#437:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth). This PR's own diff doesn't touch AdminPanel.
@seonghobae

Copy link
Copy Markdown
Contributor Author

Confirmed, thanks — no action needed.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Confirmed — the removed login-screen AdminPanel render was unreachable through normal navigation, matching #426's approach.

seonghobae added a commit that referenced this pull request Aug 22, 2026
Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436/#437/#438:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render.
seonghobae added a commit that referenced this pull request Aug 22, 2026
Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436/#437/#438/#439:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render.
seonghobae added a commit that referenced this pull request Aug 23, 2026
* test(frontend): add Storybook coverage for BuyerNav

BuyerNav had a test file but no story, the last remaining gap in
frontend/src/components/*.tsx test+story coverage. Adds stories for
each destination plus an edge case with an extra tools slot.

* fix(frontend): use OIDC return-url helpers on the login button

Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436/#437:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth). This PR's own diff doesn't touch AdminPanel.

* test(frontend): cover WorkspaceNav in Storybook
seonghobae added a commit that referenced this pull request Aug 23, 2026
* test(frontend): cover LineageDag with tests and stories

LineageDag renders the git-branch-style multi-thread lineage graph
used by both the post-detail popup and the Ask Agent's multi-lineage
answer view (ADR 0120), and had zero test or story coverage despite
being a core, non-trivial component. Adds tests for the empty state,
multi-group branch rendering, group-heading fallback for missing/UUID
groups, click and keyboard node selection, the current-post marker,
and label truncation with an accessible full-label fallback. Adds
stories for empty, single-branch, multi-branch (with an actual fork),
ungrouped, and long-label scenarios.

* fix(frontend): use OIDC return-url helpers on the login button

Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436/#437/#438:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render.

* Revert "fix(frontend): use OIDC return-url helpers on the login button"

This reverts commit 590c6c3.

* fix(frontend): keep lineage edge evidence visible-only

* fix(frontend): terminate rooted lineage cycles

* chore(frontend): keep shared OIDC repair on #426

* refactor(frontend): remove unreachable cycle guard

* test(frontend): cover converging lineage DAGs

* fix(frontend): position converging DAG nodes once
seonghobae added a commit that referenced this pull request Aug 23, 2026
* test(frontend): cover FiveW1H component with tests and stories

Adds Vitest coverage for loading state, empty-evidence messaging,
raw-source-to-label mapping (including the unmapped fallback), and
optional evidence-text/ontology-badge rendering, plus a Storybook
inventory covering the loading, all-empty, grounded-answer, and
unmapped-source scenarios.

* fix(frontend): use OIDC return-url helpers on the login button

Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#435/#436:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth). This PR's own diff doesn't touch AdminPanel.

* chore(frontend): keep FiveW1H coverage dependency-correct

Remove the duplicated OIDC/login changes owned by #426 so this PR carries only its FiveW1H tests and Storybook inventory.
seonghobae added a commit that referenced this pull request Aug 23, 2026
* test(api): cover POST /api/ask, GET /api/rankings, PATCH /api/me/preferences

Found via a systematic route-vs-test cross-reference (every @app.get/
post/patch/put/delete path in backend/app/main.py checked against
every test file, not just backend/tests/test_api.py) -- same technique
that found the /healthz routing bug earlier this session. All three
endpoints had zero test coverage anywhere in the repo:

- POST /api/ask: the Ask Agent endpoint itself was never exercised at
  the HTTP layer, despite its underlying functions
  (gather_global_chat_sources, cited_post_evidence, ...) being
  unit-tested. New tests cover the empty-question 422, the
  no-orchestrator-configured 503 (Null client, matching the existing
  derive-commitment 503 test's monkeypatch pattern), and the
  unauthenticated 401/403 case.
- GET /api/rankings: covers the real response contract
  (RankWeave's own "never invent a fused score" fail-closed shape --
  status is either "accepted" or "unavailable", never a guessed
  ranking) plus the unauthenticated case.
- PATCH /api/me/preferences: covers persisting a supported locale
  (round-tripped through GET /api/me) and rejecting an unsupported one
  (Pydantic's own Literal validation, previously untested).

uv run --frozen python -m pytest -q: 760 passed, 17 skipped.

* fix(frontend): use OIDC return-url helpers on the login button

Same shared-ancestor bug as #418/#415/#426/#427/#429/#431/#434/#436:
the login button built an unsanitized returnUrl inline instead of
returnUrlFromLocation()/rememberOidcReturnUrl(), and removed the
unreachable login-screen AdminPanel render (accessToken is always
undefined pre-auth).

* Revert "fix(frontend): use OIDC return-url helpers on the login button"

This reverts commit b80628b.

* test(api): verify buyer route trust boundaries

* fix: remove unused httpx2 dependency

* docs: keep API test transport provenance accurate

Remove stale httpx2 claims after the look-alike dependency was deleted; the harness uses Starlette TestClient with the official httpx dev dependency.

* fix(frontend): repair the inherited login/admin-panel build break

Two TypeScript build errors on main (blocking every open PR's
"Frontend lint, test, build" check, including this repo's own review
bot's ability to approve them):

- App.tsx imported rememberOidcReturnUrl/returnUrlFromLocation from
  oidcReturnUrl.ts but never called them -- the login button built its
  own unsanitized returnUrl inline instead of using the safe helper
  (oidcReturnUrl.ts's isSafeReturnUrl guard against an open-redirect-
  shaped value) or persisting it as the sessionStorage/localStorage
  fallback restoreOidcReturnUrl (already wired up on the callback side
  in main.tsx) reads when the OIDC state round-trip drops it.
- The unauthenticated login screen unconditionally rendered
  <AdminPanel accessToken={accessToken} /> when destination === "admin"
  -- accessToken is string | undefined here (always undefined while
  unauthenticated), a real type error, and the render was unreachable
  through normal navigation (destination only changes via the
  authenticated nav) -- dead code, removed.

uv run --frozen python -m pytest -q: 753 passed, 17 skipped.
pnpm run test: 140 passed. pnpm run lint / build: clean.

* Revert "fix(frontend): repair the inherited login/admin-panel build break"

This reverts commit 36164fb.
@seonghobae
seonghobae disabled auto-merge August 23, 2026 16:40
@seonghobae
seonghobae changed the base branch from main to worktree-fix-frontend-build-break August 23, 2026 16:42
devin-ai-integration[bot]

This comment was marked as resolved.

@seonghobae seonghobae changed the title test(admin): cover AdminPanel (previously zero coverage) fix(admin): prevent no-op tenant saves and cover settings states Aug 23, 2026
@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please review the exact current head. The PR is stacked on #426; do not transfer parent checks or approvals.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

Open in Devin Review

Comment thread frontend/src/components/AdminPanel.tsx
Comment thread frontend/src/components/AdminPanel.tsx
@seonghobae
seonghobae merged commit 4988fb7 into worktree-fix-frontend-build-break Aug 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant