fix(lens): preserve investigations during activity refresh errors

This commit is contained in:
moe-berri 2026-10-03 20:06:16 -07:00
parent acae4640ab
commit 4ec311e95b
3 changed files with 28 additions and 3 deletions

View file

@ -1,4 +1,4 @@
import { fireEvent, screen, within, waitFor } from "@testing-library/react";
import { act, fireEvent, screen, within, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { renderWithProviders, testQueryClient } from "@/../tests/test-utils";
@ -187,6 +187,29 @@ describe("Lens setup journey", () => {
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
});
it("keeps request-only users in investigations when an activity refresh fails", async () => {
serve({ requests: true, connected: true });
const user = userEvent.setup();
renderWithProviders(<LensWorkspace accessToken="setup-token" userRole="Admin" readOnly={false} />, {
searchParams: "?tab=investigations",
});
expect(await screen.findByText("Request logs received")).toBeVisible();
const normal = network.getMockImplementation()!;
network.mockImplementation((input, init) =>
new URL(String(input), "http://localhost").pathname === "/lens/activity/available"
? Promise.resolve(Response.json({ detail: "Activity unavailable" }, { status: 503 }))
: normal(input, init),
);
await act(() => testQueryClient.refetchQueries());
expect(await screen.findByRole("alert")).toHaveTextContent("Could not check recorded activity");
expect(screen.queryByRole("heading", { name: "Get Lens running" })).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: "New investigation" })).toBeDisabled();
network.mockImplementation(normal);
await user.click(screen.getByRole("button", { name: "Retry" }));
expect(await screen.findByText("Request logs received")).toBeVisible();
expect(screen.getByRole("button", { name: "New investigation" })).toBeEnabled();
});
it("keeps administrator-only setup unavailable to trace viewers", async () => {
serve({ enabled: true, traces: true });
const user = userEvent.setup();

View file

@ -275,6 +275,6 @@ function needsSetup(
if (requested) return true;
if (!state.missingTraces) return false;
if (tab === "traces") return true;
const hasActivity = state.hasInvestigations || state.requestsReady || selected;
const hasActivity = state.hasInvestigations || state.hasRequests || selected;
return canInvestigate && !hasActivity;
}

View file

@ -23,7 +23,8 @@ export function useLensSetup(accessToken: string, enabled: boolean, canInvestiga
const activity = useQuery(lensQueries.activity(api, enabled && canInvestigate && list.isSuccess));
const data = list.data ?? { lenses: [], workers: [], tracing_enabled: false };
const traceState = traceSetupState(traces, data.tracing_enabled);
const requestsReady = activity.data?.requests === true && !activity.error;
const hasRequests = activity.data?.requests === true;
const requestsReady = hasRequests && !activity.error;
const connected = data.workers.some((worker) => workerConnected(worker, now));
const hasInvestigations = data.lenses.length > 0;
const activityReady = traceState.tracesReady || requestsReady;
@ -42,6 +43,7 @@ export function useLensSetup(accessToken: string, enabled: boolean, canInvestiga
tracingEnabled: traceState.tracingEnabled,
tracesReady: traceState.tracesReady,
requestsReady,
hasRequests,
connected,
hasInvestigations,
missingTraces: traceState.missingTraces,