/* Copyright 2026 Marimo. All rights reserved. */ import { act, render, waitFor } from "@testing-library/react"; import { Suspense } from "react"; import { describe, expect, it, vi } from "vitest"; import { SetupMocks } from "@/__mocks__/common"; import type { Setter } from "@/plugins/types"; import { PlotlyComponent } from "../PlotlyPlugin"; SetupMocks.resizeObserver(); type CapturedPlotProps = { onClick?: (event: { points: { data?: { type?: string }; x?: string | number; y?: string | number; pointIndex?: number; pointNumber?: number; curveNumber?: number; }[]; }) => void; } | null; let capturedPlotProps: CapturedPlotProps = null; vi.mock("../Plot", () => ({ Plot: (props: CapturedPlotProps) => { capturedPlotProps = props; return
; }, })); vi.mock("../usePlotlyLayout", () => ({ usePlotlyLayout: ({ originalFigure, }: { originalFigure: { data: unknown[]; layout: Record; frames: unknown[] | null; }; }) => ({ figure: originalFigure, layout: originalFigure.layout, handleReset: vi.fn(), }), })); vi.mock("@/hooks/useScript", () => ({ useScript: () => "ready", })); vi.mock("react-use-event-hook", () => ({ default: (callback: T) => callback, })); describe("PlotlyPlugin", () => { it("clicking a bar selects that bar", async () => { const setValue = vi.fn>(); render( , ); await waitFor(() => { expect(capturedPlotProps).not.toBeNull(); }); act(() => { capturedPlotProps?.onClick?.({ points: [ { data: { type: "bar" }, x: "Feb", y: 18, pointIndex: 1, pointNumber: 1, curveNumber: 0, }, ], }); }); expect(setValue).toHaveBeenCalledTimes(1); const updater = setValue.mock.calls[0][0] as (value: unknown) => unknown; expect(updater({})).toEqual({ selections: [], points: [ { x: "Feb", y: 18, curveNumber: 0, pointNumber: 1, pointIndex: 1, }, ], indices: [1], range: undefined, }); }); it("clicking a box element triggers onClick", async () => { const setValue = vi.fn>(); render( , ); await waitFor(() => { expect(capturedPlotProps).not.toBeNull(); }); act(() => { capturedPlotProps?.onClick?.({ points: [ { data: { type: "box" }, x: "Group A", y: 3, pointIndex: 0, pointNumber: 0, curveNumber: 0, }, ], }); }); expect(setValue).toHaveBeenCalledTimes(1); const updater = setValue.mock.calls[0][0] as (value: unknown) => unknown; expect(updater({})).toEqual({ selections: [], points: [ { x: "Group A", y: 3, curveNumber: 0, pointNumber: 0, pointIndex: 0 }, ], indices: [0], range: undefined, }); }); it("clicking a violin element triggers onClick", async () => { const setValue = vi.fn>(); render( , ); await waitFor(() => { expect(capturedPlotProps).not.toBeNull(); }); act(() => { capturedPlotProps?.onClick?.({ points: [ { data: { type: "violin" }, x: "Group A", y: 3, pointIndex: 0, pointNumber: 0, curveNumber: 0, }, ], }); }); expect(setValue).toHaveBeenCalledTimes(1); const updater = setValue.mock.calls[0][0] as (value: unknown) => unknown; expect(updater({})).toEqual({ selections: [], points: [ { x: "Group A", y: 3, curveNumber: 0, pointNumber: 0, pointIndex: 0 }, ], indices: [0], range: undefined, }); }); });