test(app): cover publish 429/401 error paths in e2e#382
Merged
Conversation
The Share button, Publish/Export tab labels, and the popover/tablist aria-labels were the last hardcoded English strings in the share-publish surfaces after the #372 i18n pass. Route them through t() with new shareEditor.shareMenu.* keys across all 7 locales. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The prod CSP hardcoded the spool.pro origin family in connect-src and img-src. When SPOOL_SHARE_BACKEND redirects API traffic elsewhere (staging, local mock), main-process fetches follow the override but the renderer's direct fetches — avatar <img> loads and api calls — get silently blocked by CSP, which looks like a broken image with an empty network tab. buildCsp() now appends the override origin (normalized via URL.origin, so a trailing-slash default doesn't duplicate) to both directives in both profiles. The canonical spool.pro family stays unconditionally: published-share URLs and avatar links keep pointing there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The publish-flow e2e suite covered the happy paths but not the error surfaces: rate-limit (429) and expired-session (401) rendering was only verified at the unit layer on each side of the wire, never end-to-end through IPC into the inline error element. The mock backend gains a 'failures' switch that forces a status code on selected routes, and two specs assert the exact error copy (sourced from en.json, not hand-typed), that the form survives for retry, and that a recovered backend lets the same submit button succeed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Published tab mixed live and revoked shares in one list with text
badges and two bare hover icons per row — ambiguous at a glance and
structurally unprepared for revoked history, which the backend keeps
forever (only account deletion purges it) and so grows without bound.
- Live rows mirror the share-web /me row: visibility as an icon-only
glyph with tooltip (globe = on profile, link-2 = link only), whole-row
open, expiry inline in the meta line. Hover/cursor/action behavior
mirrors SessionRow: warm-surface row hover, default cursor, actions
in a single hover-revealed ⋯ menu that stays visible while open.
- Revoked shares move to a collapsed "Unpublished · N" section at the
bottom and are display-only: revoke is permanent (R2 content deleted,
slug 410 forever), so Copy link would hand out a dead URL.
- A failed myShares refresh now raises a persistent inline banner
("showing cached data" + retry) instead of silently rendering a stale
cache that may miss remote revocations.
- Drafts tab drops its count to match the Published tab.
New e2e: stale banner raise/clear, live-row affordances via the ⋯ menu,
revoked rows collapsing into the section with no actions.
Co-authored-by: Chen <99816898+donteatfriedrice@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds failure injection to the share-publish mock backend — a
failuresswitch that forces a status code on selected routes (/api/publish,/api/me/shares) — and two specs for the publish error surfaces:Error-copy assertions are sourced from
en.jsonrather than hand-typed, so copy edits don't flake the suite while still verifying which of the three error variants rendered.Why
The e2e suite covered the publish happy paths; 429/401 handling was verified only at the unit layer on each side of the wire (backend status codes in
publish.test.ts, renderer branching in the PublishTab state machine). Nothing proved the status code actually travels through IPC into the visible error element — the exact wiring class the pre-GA audit flagged as untested.Test plan
failuresis cleared byreset()so injection can't leak across tests🤖 Generated with Claude Code