Files
supabase/apps/studio/components/ui/Charts/useChartHighlight.test.tsx
Jordi Enric 9069e8d21e fix(reports): chart click selects bucket range, fix logs datepicker crash (#48009)
## Problem

In a database report, dragging over a chart to open logs had two bugs.
Clicking a bar instead of dragging produced a zero-width selection (its
=== ite), so the logs view showed no results. Separately, the logs
datepicker crashed with "Invalid time value" because the chart put raw
epoch-ms values into the its/ite URL params, which get parsed with new
Date(string) and yield an Invalid Date that react-day-picker cannot
format.

## Fix

The chart now emits ISO timestamps in the logs URL so its/ite match the
format every other logs consumer already uses, and the datepicker guards
against unparseable values from any source (such as old bookmarked
links). A single click now expands the highlight to the clicked bucket,
from the bar's start to the next bar's start, so the selection, popover,
and logs range all cover the bar the user picked.

## How to test

1. Open a database report with a chart (for example Postgres, project
logs).
2. Drag across the chart, choose "Open in Postgres Logs", then open the
timepicker. Expected: it opens without crashing and shows the selected
range.
3. Go back and single-click one bar instead of dragging. Expected: that
bar's bucket is selected and "Open in Postgres Logs" loads logs for a
real, non-empty range.
4. Run the chart tests, expected all pass: pnpm --filter studio exec
vitest --run components/ui/Charts


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

* **Bug Fixes**
* Prevented invalid log date inputs from creating invalid date
selections.
* Improved chart “open logs” links by normalizing the selected time
bounds (now consistently sent as ISO timestamps).
* Refined chart highlight behavior for click-to-advance and more
accurate left/right range selection, supporting both numeric and string
coordinate values.
* Updated the chart highlight dropdown display for clearer formatting of
numeric vs non-numeric dates.
* **Tests**
* Added Vitest coverage for chart highlight click, drag, and left/right
ordering scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-16 17:49:18 +02:00

71 lines
2.1 KiB
TypeScript

import { act, renderHook } from '@testing-library/react'
import { describe, expect, it } from 'vitest'
import { useChartHighlight } from './useChartHighlight'
const BAR = '1784211420000'
const NEXT_BAR = '1784211480000'
const LATER_BAR = '1784211540000'
describe('useChartHighlight', () => {
it('expands a single click to cover the clicked bucket', () => {
const { result } = renderHook(() => useChartHighlight())
act(() => {
result.current.handleMouseDown({
activeLabel: BAR,
coordinates: Number(BAR),
nextLabel: NEXT_BAR,
nextCoordinate: Number(NEXT_BAR),
})
})
act(() => {
result.current.handleMouseUp({ chartX: 10, chartY: 20 })
})
expect(result.current.left).toBe(BAR)
expect(result.current.right).toBe(NEXT_BAR)
expect(result.current.coordinates.left).not.toBe(result.current.coordinates.right)
})
it('keeps the dragged range without expanding it', () => {
const { result } = renderHook(() => useChartHighlight())
act(() => {
result.current.handleMouseDown({
activeLabel: BAR,
coordinates: Number(BAR),
nextLabel: NEXT_BAR,
nextCoordinate: Number(NEXT_BAR),
})
})
act(() => {
result.current.handleMouseMove({ activeLabel: LATER_BAR, coordinates: Number(LATER_BAR) })
})
act(() => {
result.current.handleMouseUp({ chartX: 10, chartY: 20 })
})
expect(result.current.left).toBe(BAR)
expect(result.current.right).toBe(LATER_BAR)
})
it('keeps left earlier than right when dragging leftward across epoch-ms labels', () => {
const { result } = renderHook(() => useChartHighlight())
act(() => {
result.current.handleMouseDown({ activeLabel: LATER_BAR, coordinates: Number(LATER_BAR) })
})
act(() => {
result.current.handleMouseMove({ activeLabel: BAR, coordinates: Number(BAR) })
})
act(() => {
result.current.handleMouseUp({ chartX: 10, chartY: 20 })
})
expect(Number(result.current.left)).toBeLessThan(Number(result.current.right))
expect(result.current.left).toBe(BAR)
expect(result.current.right).toBe(LATER_BAR)
})
})