Files
Jordi Enric 24f8549e41 fix(studio): open edge function logs from chart clicks FE-3922 (#50364)
## Problem

Clicking an invocation bar on the Edge Function overview did not
preserve the selected chart segment, so the destination could not open a
focused investigation window.

## Fix

Forward the clicked bar timestamp and navigate to Logs or Invocations
with an encoded, focused time range. Share the existing chart range
calculation and add real Recharts interaction coverage.

## How to test

- Open an Edge Function Overview page with invocation data.
- Click a populated bar in the Total Invocations chart.
- Expected result: Logs or Invocations opens with its and ite query
parameters centered on the clicked bar.
- Repeat with unified logs enabled and disabled to verify both
destinations.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Clicking a bar in the Edge Function invocations chart now opens the
relevant logs or invocations view.
- The destination is focused on a time window surrounding the selected
invocation, making investigation faster.
- Chart bars now provide a pointer cursor to indicate they are
interactive.

- **Bug Fixes**
- Chart clicks without valid invocation data no longer trigger incorrect
navigation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-15 11:06:37 +02:00

68 lines
2.1 KiB
TypeScript

import { fireEvent, render, waitFor } from '@testing-library/react'
import { mockResizeObserver } from 'jsdom-testing-mocks'
import { expect, it, vi } from 'vitest'
import { EdgeFunctionInvocationsChart } from './EdgeFunctionInvocationsChart'
import type { InvocationChartDatum } from './EdgeFunctionOverview.utils'
const resizeObserver = mockResizeObserver()
const renderChart = async ({
chartData,
onChartClick,
}: {
chartData: InvocationChartDatum[]
onChartClick: (timestamp: string) => void
}) => {
const result = render(
<EdgeFunctionInvocationsChart
chartData={chartData}
dateTimeFormat="MMM D, h:mma"
onChartClick={onChartClick}
/>
)
const [chartContainer] = resizeObserver.getObservedElements()
if (!chartContainer) throw new Error('Expected the chart container to be observed')
resizeObserver.mockElementSize(chartContainer, {
contentBoxSize: { inlineSize: 600, blockSize: 160 },
})
resizeObserver.resize(chartContainer)
await waitFor(() => expect(result.container.querySelector('.recharts-surface')).not.toBeNull())
return result
}
it('passes the clicked bar timestamp to the chart click handler', async () => {
const timestamp = '2026-03-20T10:30:00.000Z'
const onChartClick = vi.fn()
const { container } = await renderChart({
chartData: [{ timestamp, ok_count: 3, warning_count: 1, error_count: 2 }],
onChartClick,
})
await waitFor(() => expect(container.querySelector('.recharts-rectangle')).not.toBeNull())
const bar = container.querySelector('.recharts-rectangle')
if (!bar) throw new Error('Expected a chart bar to render')
fireEvent.mouseEnter(bar)
fireEvent.click(bar)
expect(onChartClick).toHaveBeenCalledOnce()
expect(onChartClick).toHaveBeenCalledWith(timestamp)
})
it('ignores a chart click without an active payload', async () => {
const onChartClick = vi.fn()
const { container } = await renderChart({ chartData: [], onChartClick })
const chart = container.querySelector('.recharts-surface')
if (!chart) throw new Error('Expected the chart surface to render')
fireEvent.click(chart)
expect(onChartClick).not.toHaveBeenCalled()
})