import { fireEvent, render, screen } from "@testing-library/react" import { describe, expect, it } from "vitest" import type { SelectionPatternScore } from "../api/selection.types" import { PatternCaseImage } from "./pattern-case-image" function score( caseId = "case_004", caseName = "方正科技", ): SelectionPatternScore { return { breakdown: { kdj_state: 91, price_shape: 92, trend_structure: 86, volume_pattern: 89, }, case: { breakout_date: "2025-07-23", id: caseId, name: caseName, }, reason: null, status: "matched", threshold: 60, value: 90.17, version: "zhixing_b1_pattern_fastdtw_v1", } } describe("PatternCaseImage", () => { it("renders only the best case image and falls back after a load error", () => { const view = render() const image = screen.getByRole("img", { name: "方正科技 B1 参考案例图", }) expect(screen.getAllByRole("img")).toHaveLength(1) expect(image).toHaveAttribute( "src", "/patterns/b1-cases/case_004_600601_方正科技_2025-07-23.jpg", ) fireEvent.error(image) expect(screen.queryByRole("img")).not.toBeInTheDocument() expect(screen.getByText("案例图片暂不可用。")).toBeInTheDocument() view.rerender() expect( screen.getByRole("img", { name: "华纳药厂 B1 参考案例图" }), ).toBeInTheDocument() }) it("does not guess an asset for an unknown case id", () => { render() expect(screen.queryByRole("img")).not.toBeInTheDocument() expect(screen.getByText("案例图片暂不可用。")).toBeInTheDocument() }) it("does not render an image for uncomputed or failed scores", () => { const failed: SelectionPatternScore = { breakdown: null, case: null, reason: "scoring unavailable", status: "failed", threshold: null, value: null, version: null, } const view = render() expect(screen.queryByRole("img")).not.toBeInTheDocument() view.rerender() expect(screen.queryByRole("img")).not.toBeInTheDocument() expect(screen.queryByText("案例图片暂不可用。")).not.toBeInTheDocument() }) })