import "../../../tests/web/test-utils"; import { render } from "@testing-library/react"; import { describe, expect, test, vi } from "bun:test"; import type { HistoryResponse, TargetMetricsResponse, TargetStatus } from "../../../src/shared/api"; import { TargetDetailDrawer } from "../../../src/web/components/TargetDetailDrawer"; describe("TargetDetailDrawer", () => { const target: TargetStatus = { currentStreak: null, group: "default", id: 1, interval: "30s", latestCheck: { durationMs: 100, failure: null, matched: true, statusDetail: "200 OK", timestamp: "2025-01-15T10:00:00.000Z", }, name: "test-target", recentSamples: [], stats: { availability: 100, downChecks: 0, totalChecks: 10, upChecks: 10 }, target: "https://example.com", type: "http", }; const metricsData: TargetMetricsResponse = { stats: { availability: 95, avgDurationMs: 150, currentStreak: null, downChecks: 1, incidentCount: 1, longestOutage: null, mttr: null, p95DurationMs: 200, p99DurationMs: 250, totalChecks: 20, upChecks: 19, }, targetId: 1, trend: [], window: { bucket: "1h", from: "", to: "" }, }; const historyData: HistoryResponse = { items: [], page: 1, pageSize: 20, total: 0, }; const defaultProps = { activeTab: "overview", historyData, historyLoading: false, metricsData, metricsLoading: false, onClose: vi.fn(), onPageChange: vi.fn(), onTabChange: vi.fn(), onTimeChange: vi.fn(), target, timeFrom: "2025-01-15T00:00:00.000Z", timeTo: "2025-01-15T23:59:59.999Z", }; test("target 为 null 时不崩溃", () => { const { container } = render(); // When target is null, the drawer might not render, which is expected behavior expect(container).not.toBeNull(); }); test("target 存在时不崩溃", () => { const { asFragment } = render(); // Just verify rendering doesn't throw expect(asFragment()).not.toBeNull(); }); test("关闭按钮不崩溃", () => { const onClose = vi.fn(); const { asFragment } = render(); // Just verify rendering doesn't throw expect(asFragment()).not.toBeNull(); }); test("Drawer 使用响应式默认宽度 CSS 变量", () => { render(); const wrapper = document.querySelector(".t-drawer__content-wrapper")!; expect(wrapper).not.toBeNull(); expect(wrapper.style.width).toBe("var(--target-detail-drawer-width)"); }); test("Drawer 包含业务 className", () => { render(); const drawer = document.querySelector(".target-detail-drawer"); expect(drawer).not.toBeNull(); }); test("Drawer 启用 sizeDraggable 拖拽", () => { render(); const wrapper = document.querySelector(".t-drawer__content-wrapper")!; expect(wrapper).not.toBeNull(); const dragLine = wrapper.querySelector('[style*="col-resize"]'); expect(dragLine).not.toBeNull(); }); test("Drawer 拖拽宽度不写入 localStorage", () => { const keysBefore = window.localStorage.length; render(); expect(window.localStorage.length).toBe(keysBefore); }); test("Drawer sizeDraggable 配置最小拖拽边界", () => { render(); const wrapper = document.querySelector(".t-drawer__content-wrapper")!; expect(wrapper).not.toBeNull(); const dragLine = wrapper.querySelector('[style*="col-resize"]'); expect(dragLine).not.toBeNull(); }); });