diff --git a/static/app/views/investigations/detail/cell.tsx b/static/app/views/investigations/detail/cell.tsx index b74e089dfdf3..1ee53769630e 100644 --- a/static/app/views/investigations/detail/cell.tsx +++ b/static/app/views/investigations/detail/cell.tsx @@ -104,11 +104,6 @@ export function InvestigationCell({ block.title || chartTitle || (block.kind === 'query' ? t('Untitled query') : t('Untitled cell')); - const rerunMutation = useRunInvestigationBlockMutation( - organizationSlug, - investigation.id, - {onError: () => addErrorMessage(t('Unable to rerun this cell.'))} - ); const deleteMutation = useDeleteInvestigationBlockMutation( organizationSlug, investigation.id, @@ -136,36 +131,7 @@ export function InvestigationCell({ setPrompt(block.outputStatus === 'notRun' ? block.generationPrompt : ''); } - async function rerun() { - try { - const execution = await rerunMutation.mutateAsync({ - block, - investigationVersion: investigation.version, - }); - setPanelOpen(true); - setTraceExecutionId(execution.id); - setShowPrompt(false); - autoOpenedExecutionId.current = execution.id; - } catch { - // The mutation owns user-facing error handling. - } - } - - const actionItems: MenuItemProps[] = []; - if (block.kind === 'query') { - // oxlint-disable-next-line react/refs - actionItems.push({ - key: 'rerun', - label: t('Rerun'), - disabled: - !canRun || - rerunMutation.isPending || - isExecutionActive(block.currentExecution?.status) || - !(block.generationPrompt || block.content).trim(), - onAction: () => void rerun(), - }); - } - actionItems.push( + const actionItems: MenuItemProps[] = [ { key: 'refine', label: t('Refine'), @@ -191,8 +157,8 @@ export function InvestigationCell({ investigationVersion: investigation.version, }), }), - } - ); + }, + ]; const cellActions = ( @@ -307,7 +273,7 @@ function QueryResult({ block: InvestigationBlock; progressState: CellProgressState; }) { - const [expanded, setExpanded] = useState(block.config.autoRun !== true); + const [expanded, setExpanded] = useState(true); const output = getQueryOutput(block.output); const chart = output?.preferredView === 'chart' ? getRenderableChart(output.chart) : null; @@ -466,13 +432,18 @@ function getCellProgressState( return 'waiting'; } -export function shouldDisplayInvestigationBlock( - block: InvestigationBlock, - blocks: InvestigationBlock[] -) { - // Waiting cells have no useful content yet. Dependency failures and cancellations - // remain visible so users can understand why downstream work stopped. - return getCellProgressState(block, blocks) !== 'waiting'; +export function shouldDisplayInvestigationBlock(block: InvestigationBlock) { + if (block.kind === 'text') { + return Boolean((getTextOutput(block.output) ?? block.content).trim()); + } + const output = getQueryOutput(block.output); + if (!output || output.isEmpty) { + return false; + } + return Boolean( + output.tableMarkdown.trim() || + (output.preferredView === 'chart' && getRenderableChart(output.chart)) + ); } export function shouldPollInvestigationBlocks(blocks: InvestigationBlock[]) { @@ -1090,7 +1061,7 @@ function getTextOutput(output: unknown): string | null { type RenderableQueryOutput = Pick< InvestigationQueryOutput, - 'chart' | 'preferredView' | 'tableMarkdown' + 'chart' | 'preferredView' | 'tableMarkdown' | 'isEmpty' >; function getQueryOutput(output: unknown): RenderableQueryOutput | null { @@ -1110,6 +1081,7 @@ function getQueryOutput(output: unknown): RenderableQueryOutput | null { : null; return { chart, + isEmpty: 'isEmpty' in output && output.isEmpty === true, preferredView: output.preferredView, tableMarkdown: output.tableMarkdown, }; diff --git a/static/app/views/investigations/detail/index.spec.tsx b/static/app/views/investigations/detail/index.spec.tsx index c8694507fc50..54b5a3120a14 100644 --- a/static/app/views/investigations/detail/index.spec.tsx +++ b/static/app/views/investigations/detail/index.spec.tsx @@ -32,6 +32,7 @@ import { InvestigationAgenticDetailFixture, InvestigationDetailFixture, InvestigationOrchestrationFixture, + InvestigationQueryOutputFixture, } from 'sentry/views/investigations/fixtures'; jest.unmock('@tanstack/react-pacer'); @@ -99,10 +100,17 @@ function renderView( return {...result, queryClient}; } -async function chooseCellAction( - cellTitle: string, - action: 'Delete' | 'Refine' | 'Rerun' -) { +function investigationWithQueryResult() { + const investigation = InvestigationDetailFixture(); + investigation.blocks[1] = { + ...investigation.blocks[1]!, + outputStatus: 'available', + output: InvestigationQueryOutputFixture(), + }; + return investigation; +} + +async function chooseCellAction(cellTitle: string, action: 'Delete' | 'Refine') { await userEvent.click( await screen.findByRole('button', {name: `Cell actions for ${cellTitle}`}) ); @@ -120,7 +128,7 @@ describe('Investigation detail', () => { it('loads and renders the complete investigation response', async () => { const request = MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView(); @@ -145,7 +153,7 @@ describe('Investigation detail', () => { await userEvent.keyboard('{Escape}'); await userEvent.click(screen.getByLabelText('Cell actions for Latency query')); - expect(screen.getByRole('menuitemradio', {name: 'Rerun'})).toBeInTheDocument(); + expect(screen.queryByRole('menuitemradio', {name: 'Rerun'})).not.toBeInTheDocument(); expect(screen.getByRole('menuitemradio', {name: 'Refine'})).toBeInTheDocument(); expect(screen.getByRole('menuitemradio', {name: 'Delete'})).toBeInTheDocument(); }); @@ -204,7 +212,7 @@ describe('Investigation detail', () => { }); it('renders partial text while an agent-written text cell is running', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks[0] = { ...investigation.blocks[0]!, outputStatus: 'running', @@ -239,7 +247,7 @@ describe('Investigation detail', () => { it('does not render stale streamed text after a text cell completes', async () => { const queryClient = makeTestQueryClient(); - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks[0] = { ...investigation.blocks[0]!, outputStatus: 'available', @@ -415,86 +423,63 @@ describe('Investigation detail', () => { ); }); - it('shows active auto-run cells, hides waiting cells, and opens agent steps', async () => { - const investigation = InvestigationDetailFixture({ - template: {key: 'breached_metric', version: 1}, - }); - const textBlock = investigation.blocks[0]!; - const queryBlock = investigation.blocks[1]!; - investigation.blocks = [ - { - ...textBlock, - content: '', - config: {autoRun: true}, - outputStatus: 'running', - currentExecution: { - id: 'execution-1', - status: 'running', - startedAt: '2026-08-17T10:00:00Z', - completedAt: null, - error: null, - }, - }, - { - ...queryBlock, - config: {autoRun: true}, - outputStatus: 'pending', - currentExecution: { - id: 'execution-2', - status: 'pending', - startedAt: null, - completedAt: null, - error: null, - }, - }, - { - ...textBlock, - id: 'block-3', - position: 2, - title: 'Synthesis', - content: '', - config: {autoRun: true}, - dependencies: ['block-1', 'block-2'], - }, - ]; - MockApiClient.addMockResponse({url: detailUrl, body: investigation}); - MockApiClient.addMockResponse({ - url: `${detailUrl}blocks/block-1/executions/execution-1/`, - body: { + it('reveals cells as results arrive without showing pending placeholders', async () => { + const investigation = InvestigationDetailFixture(); + investigation.blocks[0] = { + ...investigation.blocks[0]!, + content: '', + config: {autoRun: true}, + outputStatus: 'running', + currentExecution: { id: 'execution-1', status: 'running', - blocks: [], - transcriptTruncated: false, - pendingUserInput: null, - partialMarkdown: null, - error: null, - }, - }); - MockApiClient.addMockResponse({ - url: `${detailUrl}blocks/block-2/executions/execution-2/`, - body: { - id: 'execution-2', - status: 'pending', - blocks: [], - transcriptTruncated: false, - pendingUserInput: null, - partialMarkdown: null, + startedAt: '2026-08-17T10:00:00Z', + completedAt: null, error: null, }, - }); - - renderView(); + }; + investigation.blocks[1] = { + ...investigation.blocks[1]!, + config: {autoRun: true}, + dependencies: ['block-1'], + }; + MockApiClient.addMockResponse({url: detailUrl, body: investigation}); + const {queryClient} = renderView(); - expect(await screen.findAllByRole('button', {name: 'Close Seer panel'})).toHaveLength( - 2 - ); - expect(screen.getByTestId('investigation-cell-block-1')).toBeInTheDocument(); - expect(screen.getByTestId('investigation-cell-block-2')).toBeInTheDocument(); - expect(screen.queryByTestId('investigation-cell-block-3')).not.toBeInTheDocument(); + await screen.findByText('Investigate database latency'); + expect(screen.queryByLabelText('Cell actions for Summary')).not.toBeInTheDocument(); + expect( + screen.queryByLabelText('Cell actions for Latency query') + ).not.toBeInTheDocument(); expect(screen.queryByText('Waiting for previous cells…')).not.toBeInTheDocument(); + expect(screen.queryByText('This cell has no output yet.')).not.toBeInTheDocument(); + expect( + screen.queryByRole('button', {name: 'Close Seer panel'}) + ).not.toBeInTheDocument(); + + const completed = { + ...investigation, + blocks: investigation.blocks.map(block => ({ + ...block, + outputStatus: 'completed' as const, + currentExecution: null, + output: + block.kind === 'text' + ? {schemaVersion: 1, markdown: 'Timeouts began after the deployment.'} + : InvestigationQueryOutputFixture(), + })), + }; + MockApiClient.addMockResponse({url: detailUrl, body: completed}); + await queryClient.invalidateQueries({ + queryKey: getInvestigationDetailQueryOptions(organization.slug, investigation.id) + .queryKey, + }); + + expect(await screen.findByText('Timeouts began after the deployment.')).toBeVisible(); + expect(await screen.findByText('1.84s')).toBeVisible(); expect(screen.getByRole('button', {name: 'Toggle Latency query'})).toHaveAttribute( 'aria-expanded', - 'false' + 'true' ); }); @@ -529,31 +514,46 @@ describe('Investigation detail', () => { await waitFor(() => expect(request).toHaveBeenCalledTimes(2), {timeout: 3000}); }); - it('shows a failed state when a cell has no output', async () => { - const investigation = InvestigationDetailFixture(); - investigation.blocks = [ - { - ...investigation.blocks[1]!, - outputStatus: 'failed', - currentExecution: { - id: 'execution-failed', - status: 'failed', - startedAt: '2026-08-17T10:00:00Z', - completedAt: '2026-08-17T10:00:10Z', - error: {message: 'Query failed'}, + it.each(['notRun', 'pending', 'running', 'failed', 'cancelled', 'completed'] as const)( + 'hides query cells with no usable output when %s', + async status => { + const investigation = InvestigationDetailFixture(); + investigation.blocks = [ + { + ...investigation.blocks[1]!, + outputStatus: status, + currentExecution: null, + output: null, }, - }, - ]; - MockApiClient.addMockResponse({url: detailUrl, body: investigation}); + ]; + MockApiClient.addMockResponse({url: detailUrl, body: investigation}); + renderView(); + + await screen.findByText('Investigate database latency'); + expect( + screen.queryByLabelText('Cell actions for Latency query') + ).not.toBeInTheDocument(); + expect(screen.queryByText('This cell has no output yet.')).not.toBeInTheDocument(); + } + ); + it('omits completed empty results from the report', async () => { + const investigation = investigationWithQueryResult(); + investigation.blocks[1]!.output = InvestigationQueryOutputFixture({ + isEmpty: true, + tableMarkdown: '| Events |\n| --- |', + chartUnavailableReason: 'No events in this window.', + }); + MockApiClient.addMockResponse({url: detailUrl, body: investigation}); renderView(); - expect(await screen.findByTestId('cell-execution-failed')).toHaveTextContent( - 'Query failed' - ); + await screen.findByText('Initial notes'); + expect( + screen.queryByLabelText('Cell actions for Latency query') + ).not.toBeInTheDocument(); }); - it('only blocks cells that depend on a failed branch', async () => { + it('shows available results and hides cells blocked by a failed branch', async () => { const investigation = InvestigationDetailFixture(); const textBlock = investigation.blocks[0]!; const queryBlock = investigation.blocks[1]!; @@ -601,11 +601,10 @@ describe('Investigation detail', () => { renderView(); - expect(await screen.findByTestId('investigation-cell-block-2')).toBeInTheDocument(); - expect(screen.getByRole('button', {name: 'Toggle Latency query'})).toHaveAttribute( - 'aria-expanded', - 'false' - ); + expect( + await screen.findByLabelText('Cell actions for Independent analysis') + ).toBeInTheDocument(); + expect(screen.queryByTestId('investigation-cell-block-2')).not.toBeInTheDocument(); expect(screen.queryByTestId('investigation-cell-block-4')).not.toBeInTheDocument(); expect(screen.queryByText('Waiting for previous cells…')).not.toBeInTheDocument(); expect( @@ -616,7 +615,7 @@ describe('Investigation detail', () => { it('keeps the refinement composer expanded while editing', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView(); @@ -624,7 +623,7 @@ describe('Investigation detail', () => { const prompt = screen.getByLabelText('Instructions for Seer'); expect(screen.getByText('Ask Seer to refine')).toBeInTheDocument(); - expect(prompt).toHaveValue('Find slow spans'); + expect(prompt).toHaveValue(''); expect(prompt).toBeVisible(); expect(screen.queryByRole('button', {name: 'Ask Seer'})).not.toBeInTheDocument(); @@ -633,7 +632,7 @@ describe('Investigation detail', () => { }); it('renders block output instead of block content', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); const firstBlock = investigation.blocks[0]; if (!firstBlock) { throw new Error('Expected an investigation block fixture.'); @@ -658,7 +657,7 @@ describe('Investigation detail', () => { }); it('uses compact breadcrumbs and renders text and table results without prompt data', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks = [ { ...investigation.blocks[0]!, @@ -723,8 +722,8 @@ describe('Investigation detail', () => { expect(screen.getByText('820ms')).toBeVisible(); }); - it('starts generated query evidence collapsed', async () => { - const investigation = InvestigationDetailFixture(); + it('shows generated query evidence expanded when ready', async () => { + const investigation = investigationWithQueryResult(); investigation.blocks = [ { ...investigation.blocks[1]!, @@ -753,21 +752,21 @@ describe('Investigation detail', () => { renderView(); const toggle = await screen.findByRole('button', {name: 'Toggle Latency query'}); - expect(toggle).toHaveAttribute('aria-expanded', 'false'); - expect(screen.queryByText('820ms')).not.toBeInTheDocument(); + expect(toggle).toHaveAttribute('aria-expanded', 'true'); + expect(screen.getByText('820ms')).toBeVisible(); expect(screen.getByTestId('query-cell-toolbar')).toContainElement( screen.getByRole('button', {name: 'Cell actions for Latency query'}) ); await userEvent.click(toggle); - expect(screen.getByText('820ms')).toBeVisible(); + expect(screen.queryByText('820ms')).not.toBeInTheDocument(); }); it('renders the outer query title as non-editable text', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView(); expect(await screen.findByTestId('query-cell-title')).toHaveTextContent( @@ -779,7 +778,7 @@ describe('Investigation detail', () => { }); it('renders a preferred chart and falls back to its table when unavailable', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks = [ { ...investigation.blocks[1]!, @@ -840,8 +839,8 @@ describe('Investigation detail', () => { expect(screen.getByText('shown')).toBeInTheDocument(); }); - it('renders chart metadata and reruns the query from the header', async () => { - const investigation = InvestigationDetailFixture(); + it('renders chart metadata and offers Refine without Rerun', async () => { + const investigation = investigationWithQueryResult(); const block = { ...investigation.blocks[1]!, outputStatus: 'completed' as const, @@ -872,24 +871,6 @@ describe('Investigation detail', () => { }; investigation.blocks = [block]; MockApiClient.addMockResponse({url: detailUrl, body: investigation}); - const runUrl = `${detailUrl}blocks/${block.id}/executions/`; - const rerunRequest = MockApiClient.addMockResponse({ - url: runUrl, - method: 'POST', - body: {id: 'rerun-1', status: 'running'}, - }); - MockApiClient.addMockResponse({ - url: `${runUrl}rerun-1/`, - body: { - id: 'rerun-1', - status: 'running', - blocks: [], - transcriptTruncated: false, - pendingUserInput: null, - partialMarkdown: null, - error: null, - }, - }); renderView(); const chartHeader = await screen.findByTestId('query-cell-header'); @@ -909,19 +890,14 @@ describe('Investigation detail', () => { screen.queryByRole('button', {name: 'Rerun Latency query'}) ).not.toBeInTheDocument(); - await chooseCellAction('Latency query', 'Rerun'); - await waitFor(() => - expect(rerunRequest).toHaveBeenCalledWith( - runUrl, - expect.objectContaining({ - data: {investigationVersion: 1, version: 1}, - }) - ) - ); + await userEvent.click(screen.getByLabelText('Cell actions for Latency query')); + expect(screen.queryByRole('menuitemradio', {name: 'Rerun'})).not.toBeInTheDocument(); + await userEvent.click(screen.getByRole('menuitemradio', {name: 'Refine'})); + expect(screen.getByLabelText('Instructions for Seer')).toHaveValue(''); }); it('deletes a query cell when it is no longer present in the cache', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); const block = investigation.blocks[1]!; const queryClient = makeTestQueryClient(); const options = getInvestigationDetailQueryOptions('org-slug', 'investigation-1'); @@ -959,7 +935,7 @@ describe('Investigation detail', () => { }); it('deletes a text cell from its actions menu', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); const block = investigation.blocks[0]!; MockApiClient.addMockResponse({url: detailUrl, body: investigation}); const deleteRequest = MockApiClient.addMockResponse({ @@ -986,15 +962,13 @@ describe('Investigation detail', () => { ).not.toBeInTheDocument(); }); - it('starts a never-run cell from its stored prompt', async () => { - // `Latency query` arrives from the fixture never run, carrying the prompt - // it was created with — which is the state Refine is meant to pick up. - MockApiClient.addMockResponse({url: detailUrl, body: InvestigationDetailFixture()}); + it('refines an existing result with new instructions', async () => { + MockApiClient.addMockResponse({url: detailUrl, body: investigationWithQueryResult()}); const updateUrl = `${detailUrl}blocks/block-2/`; const updateRequest = MockApiClient.addMockResponse({ url: updateUrl, method: 'PUT', - body: InvestigationDetailFixture().blocks[1], + body: investigationWithQueryResult().blocks[1], }); const runUrl = `${updateUrl}executions/`; const runRequest = MockApiClient.addMockResponse({ @@ -1019,7 +993,11 @@ describe('Investigation detail', () => { expect(await screen.findByText('Investigate database latency')).toBeInTheDocument(); await chooseCellAction('Latency query', 'Refine'); - expect(screen.getByLabelText('Instructions for Seer')).toHaveValue('Find slow spans'); + expect(screen.getByLabelText('Instructions for Seer')).toHaveValue(''); + await userEvent.type( + screen.getByLabelText('Instructions for Seer'), + 'Show a bar chart instead' + ); await userEvent.click(screen.getByRole('button', {name: 'Submit'})); await waitFor(() => @@ -1029,7 +1007,7 @@ describe('Investigation detail', () => { data: { investigationVersion: 1, version: 1, - generationPrompt: 'Find slow spans', + generationPrompt: 'Show a bar chart instead', }, }) ) @@ -1203,7 +1181,7 @@ describe('Investigation detail', () => { }); it('shows "Building chart…" for a query block\'s in-progress structured result instead of raw JSON', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); MockApiClient.addMockResponse({url: detailUrl, body: investigation}); const blockUrl = `${detailUrl}blocks/block-2/`; MockApiClient.addMockResponse({ @@ -1256,7 +1234,7 @@ describe('Investigation detail', () => { }); it("hides a query block's completed structured result from the transcript, not just while streaming", async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); MockApiClient.addMockResponse({url: detailUrl, body: investigation}); const blockUrl = `${detailUrl}blocks/block-2/`; MockApiClient.addMockResponse({ @@ -1313,7 +1291,7 @@ describe('Investigation detail', () => { }); it('stops an active refinement and leaves the rendered result visible', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks = [ { ...investigation.blocks[0]!, @@ -1365,7 +1343,7 @@ describe('Investigation detail', () => { }); it('answers a question while an execution is awaiting input', async () => { - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); investigation.blocks = [ { ...investigation.blocks[0]!, @@ -1434,7 +1412,7 @@ describe('Investigation detail', () => { it('reuses an investigation prefetched before the detail page mounts', async () => { const request = MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); const queryClient = makeTestQueryClient(); @@ -1450,7 +1428,7 @@ describe('Investigation detail', () => { it('optimistically renames and debounces persistence', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); const renameRequest = MockApiClient.addMockResponse({ url: detailUrl, @@ -1487,7 +1465,7 @@ describe('Investigation detail', () => { it('preserves newer block state when a rename completes', async () => { const queryClient = makeTestQueryClient(); const options = getInvestigationDetailQueryOptions('org-slug', 'investigation-1'); - const investigation = InvestigationDetailFixture(); + const investigation = investigationWithQueryResult(); MockApiClient.addMockResponse({url: detailUrl, body: investigation}); MockApiClient.addMockResponse({ url: `${detailUrl}blocks/block-1/executions/execution-running/`, @@ -1555,7 +1533,7 @@ describe('Investigation detail', () => { it('flushes a pending title change when the page unmounts', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); const renameRequest = MockApiClient.addMockResponse({ url: detailUrl, @@ -1617,7 +1595,7 @@ describe('Investigation detail', () => { it('duplicates and opens the duplicate from the title menu', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); MockApiClient.addMockResponse({ url: `${detailUrl}duplicate/`, @@ -1653,7 +1631,7 @@ describe('Investigation detail', () => { }); MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView(); @@ -1670,7 +1648,7 @@ describe('Investigation detail', () => { it('deletes after confirmation and returns to the list', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); const deleteRequest = MockApiClient.addMockResponse({ url: detailUrl, @@ -1719,7 +1697,7 @@ describe('Investigation detail', () => { const options = getInvestigationDetailQueryOptions('org-slug', 'investigation-1'); queryClient.setQueryData(options.queryKey, { headers: {}, - json: InvestigationDetailFixture(), + json: investigationWithQueryResult(), }); const request = MockApiClient.addMockResponse({ url: detailUrl, @@ -1738,7 +1716,7 @@ describe('Investigation detail', () => { it('does not bootstrap when the feature is disabled', () => { const request = MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView(OrganizationFixture({features: [], openMembership: true})); @@ -1752,7 +1730,7 @@ describe('Investigation detail', () => { it('does not bootstrap for a closed-membership organization', () => { const request = MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); renderView( @@ -1797,7 +1775,7 @@ describe('Investigation detail', () => { it('does not reach for orchestration on a manual investigation', async () => { MockApiClient.addMockResponse({ url: detailUrl, - body: InvestigationDetailFixture(), + body: investigationWithQueryResult(), }); const orchestrationRequest = MockApiClient.addMockResponse({ url: orchestrationUrl, diff --git a/static/app/views/investigations/detail/index.tsx b/static/app/views/investigations/detail/index.tsx index 635d6d7253e8..15fcc1351868 100644 --- a/static/app/views/investigations/detail/index.tsx +++ b/static/app/views/investigations/detail/index.tsx @@ -263,11 +263,11 @@ function InvestigationPageContent({investigation}: {investigation: Investigation const summaryBlock = investigation.template ? blocks[0] : undefined; const notebookCells = summaryBlock ? blocks.slice(1) : blocks; const visibleSummaryBlock = - summaryBlock && shouldDisplayInvestigationBlock(summaryBlock, blocks) + summaryBlock && shouldDisplayInvestigationBlock(summaryBlock) ? summaryBlock : undefined; const visibleNotebookCells = notebookCells.filter(block => - shouldDisplayInvestigationBlock(block, blocks) + shouldDisplayInvestigationBlock(block) ); return (