fix: a signed-out tab no longer asks for saved views

The providers mount for the public landing too, and the saved-views query had no
enabled gate, so every signed-out load logged a 401 for /api/saved-views. The query
now waits for a signed-in account in BootGate's me cache, like WizardProvider.
This commit is contained in:
2026-09-15 23:45:13 +02:00
parent 595490cb98
commit 4e52bdd4ca
2 changed files with 37 additions and 2 deletions
@@ -67,12 +67,19 @@ function Probe() {
);
}
// The views query waits for a signed-in account in the cache (BootGate's `me`).
function signedInClient() {
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
qc.setQueryData(qk.me(), { id: ID, preferences: {} });
return qc;
}
async function mountResolved(views: SavedView[]) {
// Fresh array + object copies per call, like a real fetch — so a refetch changes viewsQuery.data's
// identity and re-runs the seed effect (which is what makes the per-source guard actually load-bearing
// in the re-seed test; a shared reference would skip the effect and hide a missing guard).
vi.spyOn(api, "savedViews").mockImplementation(async () => views.map((v) => ({ ...v })));
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
const qc = signedInClient();
render(
<QueryClientProvider client={qc}>
<SavedViewsProvider>
@@ -141,7 +148,7 @@ describe("SavedViewsProvider — default-view seeding on first resolve", () => {
calls += 1;
return calls === 1 ? [def] : [def, view({ id: 9, name: "added-later" })];
});
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
const qc = signedInClient();
render(
<QueryClientProvider client={qc}>
<SavedViewsProvider>
@@ -174,3 +181,26 @@ describe("SavedViewsProvider — default-view seeding on first resolve", () => {
expect(h.setPlexFilters).not.toHaveBeenCalled();
});
});
describe("SavedViewsProvider — signed-out tab", () => {
it("does NOT ask for saved views while no account is signed in (the landing logged a 401)", async () => {
const spy = vi.spyOn(api, "savedViews").mockResolvedValue([]);
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
qc.setQueryData(qk.me(), null); // BootGate's "nobody"
render(
<QueryClientProvider client={qc}>
<SavedViewsProvider>
<Probe />
</SavedViewsProvider>
</QueryClientProvider>,
);
// Let any fetch the mount would start get going before asserting it never happened.
await act(async () => {
await new Promise((r) => setTimeout(r, 20));
});
expect(spy).not.toHaveBeenCalled();
// …and it asks as soon as an account signs in.
act(() => qc.setQueryData(qk.me(), { id: ID, preferences: {} }));
await waitFor(() => expect(spy).toHaveBeenCalledWith("feed"));
});
});