feat(web): 完善选股详情图表与案例图
This commit is contained in:
@@ -16,6 +16,7 @@ import { SelectionResultsPage } from "./selection-results-page"
|
||||
|
||||
const routerNavigate = vi.hoisted(() => vi.fn())
|
||||
const useSelectionResults = vi.fn()
|
||||
const useSelectionChart = vi.fn()
|
||||
const useSelectionRun = vi.fn()
|
||||
const useTriggerSelectionRun = vi.fn()
|
||||
const mutate = vi.fn()
|
||||
@@ -23,6 +24,7 @@ const reset = vi.fn()
|
||||
|
||||
vi.mock("@/features/selection/api/selection.query", () => ({
|
||||
useSelectionResults: (...args: unknown[]) => useSelectionResults(...args),
|
||||
useSelectionChart: (...args: unknown[]) => useSelectionChart(...args),
|
||||
useSelectionRun: (...args: unknown[]) => useSelectionRun(...args),
|
||||
useTriggerSelectionRun: () => useTriggerSelectionRun(),
|
||||
}))
|
||||
@@ -110,6 +112,11 @@ const selectedResult: SelectionResults = {
|
||||
|
||||
describe("SelectionResultsPage", () => {
|
||||
beforeEach(() => {
|
||||
useSelectionChart.mockReturnValue({
|
||||
data: undefined,
|
||||
isError: false,
|
||||
isPending: false,
|
||||
})
|
||||
useSelectionResults.mockReturnValue({
|
||||
data: selectedResult,
|
||||
isError: false,
|
||||
@@ -167,12 +174,23 @@ describe("SelectionResultsPage", () => {
|
||||
})
|
||||
expect(within(detailPanel).getByText("关键指标")).toBeInTheDocument()
|
||||
expect(within(detailPanel).getByText("图形相似度评分")).toBeInTheDocument()
|
||||
expect(
|
||||
within(detailPanel).getByText("暂无可用行情数据。"),
|
||||
).toBeInTheDocument()
|
||||
expect(
|
||||
within(detailPanel).getByText("最佳案例:华纳药厂"),
|
||||
).toBeInTheDocument()
|
||||
expect(within(detailPanel).getByText("价格形态")).toBeInTheDocument()
|
||||
expect(within(detailPanel).getAllByText("J 值")).toHaveLength(2)
|
||||
expect(within(detailPanel).getByText("RSI")).toBeInTheDocument()
|
||||
const caseImages = within(detailPanel).getAllByRole("img", {
|
||||
name: "华纳药厂 B1 参考案例图",
|
||||
})
|
||||
expect(caseImages).toHaveLength(1)
|
||||
expect(caseImages[0]).toHaveAttribute(
|
||||
"src",
|
||||
"/patterns/b1-cases/case_001_688799_华纳药厂_2025-05-12.jpg",
|
||||
)
|
||||
})
|
||||
|
||||
it.each<{
|
||||
@@ -184,14 +202,23 @@ describe("SelectionResultsPage", () => {
|
||||
score: null,
|
||||
},
|
||||
{
|
||||
expected: "未匹配到 60.00 分以上案例。",
|
||||
expected: "低于匹配阈值",
|
||||
score: {
|
||||
breakdown: null,
|
||||
case: null,
|
||||
reason: "未匹配到评分阈值以上案例",
|
||||
breakdown: {
|
||||
kdj_state: 42,
|
||||
price_shape: 44,
|
||||
trend_structure: 40,
|
||||
volume_pattern: 43,
|
||||
},
|
||||
case: {
|
||||
breakout_date: "2025-07-23",
|
||||
id: "case_004",
|
||||
name: "方正科技",
|
||||
},
|
||||
reason: null,
|
||||
status: "below_threshold",
|
||||
threshold: 60,
|
||||
value: null,
|
||||
value: 42.5,
|
||||
version: "zhixing_b1_pattern_fastdtw_v1",
|
||||
},
|
||||
},
|
||||
@@ -225,9 +252,51 @@ describe("SelectionResultsPage", () => {
|
||||
const table = screen.getByRole("table")
|
||||
expect(within(table).getByText("原始 B1")).toBeInTheDocument()
|
||||
expect(within(table).getByText("12")).toBeInTheDocument()
|
||||
if (score?.status === "below_threshold") {
|
||||
const detailPanel = screen.getByRole("complementary", {
|
||||
name: "当前股票详情",
|
||||
})
|
||||
const images = within(detailPanel).getAllByRole("img", {
|
||||
name: "方正科技 B1 参考案例图",
|
||||
})
|
||||
expect(images).toHaveLength(1)
|
||||
expect(images[0]).toHaveAttribute(
|
||||
"src",
|
||||
"/patterns/b1-cases/case_004_600601_方正科技_2025-07-23.jpg",
|
||||
)
|
||||
expect(within(detailPanel).getAllByText("42.50 分")).toHaveLength(2)
|
||||
} else {
|
||||
const detailPanel = screen.getByRole("complementary", {
|
||||
name: "当前股票详情",
|
||||
})
|
||||
expect(within(detailPanel).queryByRole("img")).not.toBeInTheDocument()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
it("shows chart loading and error states for the selected stock", () => {
|
||||
useSelectionChart.mockReturnValue({
|
||||
data: undefined,
|
||||
isError: false,
|
||||
isPending: true,
|
||||
})
|
||||
const view = render(<SelectionResultsPage />)
|
||||
|
||||
expect(screen.getByText("正在加载行情图表…")).toBeInTheDocument()
|
||||
expect(useSelectionChart).toHaveBeenLastCalledWith(
|
||||
"000001.SZ",
|
||||
"2026-08-08",
|
||||
)
|
||||
|
||||
useSelectionChart.mockReturnValue({
|
||||
data: undefined,
|
||||
isError: true,
|
||||
isPending: false,
|
||||
})
|
||||
view.rerender(<SelectionResultsPage />)
|
||||
expect(screen.getByText("行情图表暂时不可用。")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it("opens execution status details in a drawer and restores trigger focus", async () => {
|
||||
useSelectionResults.mockReturnValue({
|
||||
data: {
|
||||
|
||||
Reference in New Issue
Block a user