From 803ea2217b4a2fdb6bb66c1c85aa25cbf4b075e0 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 17 Sep 2026 13:44:36 +0500 Subject: [PATCH] =?UTF-8?q?test(tradein-front):=20=D0=BF=D0=BE=D0=B4=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D1=8C=20=D0=BA=D0=BE=D1=80=D0=B8=D0=B4=D0=BE=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B2=20v1=20HeroSummary=20=D1=81=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B5=D0=B6=D1=91=D1=82=D1=81=D1=8F=20=D1=80=D0=B5=D0=BD=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=D0=BE=D0=BC=20(#3466)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ревью #3554: вызов corridorAdvisoryNote в HeroSummary (корневая /trade-in) тестом не покрывался — мутация F2 убирала аргумент estimate.analog_tier, vitest оставался зелёным (305 passed). Покрыт был только v2 mappers. Рендер HeroSummary по образцу thinMarketBadge.test.tsx: n=20, advisory_only=false; same_building → подпись про дом в тексте hero, micro_radius → подписи нет. Мутант F2 краснеет: «expected 'Секция 1 · Сводка…' to contain 'справочно: цена посчитана по аналогам…'». Co-Authored-By: Claude Opus 5 --- .../HeroSummaryCorridorNote.test.tsx | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tradein-mvp/frontend/src/components/trade-in/__tests__/HeroSummaryCorridorNote.test.tsx diff --git a/tradein-mvp/frontend/src/components/trade-in/__tests__/HeroSummaryCorridorNote.test.tsx b/tradein-mvp/frontend/src/components/trade-in/__tests__/HeroSummaryCorridorNote.test.tsx new file mode 100644 index 00000000..54009c31 --- /dev/null +++ b/tradein-mvp/frontend/src/components/trade-in/__tests__/HeroSummaryCorridorNote.test.tsx @@ -0,0 +1,53 @@ +/** + * #3466 — подпись «цена по дому, коридор её не ограничивает» на корневой /trade-in. + * + * corridorAdvisoryNote проверена сама по себе и через v2 mapResultPanel + * (v2/__tests__/corridorAdvisoryNote.test.ts). Вызов в v1 HeroSummary — отдельный: + * без аргумента estimate.analog_tier функция молча вернёт null при n ≥ порога, + * и vitest этого не видел (ревью #3554, мутация F2). Здесь проверяется то, что + * реально стоит на экране hero. + */ +import { render } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; + +import { HeroSummary } from "../HeroSummary"; +import { FIXTURE_ESTIMATE, FIXTURE_INPUT } from "@/app/ui-preview/estimate/fixture"; +import type { AggregatedEstimate, AnalogTier } from "@/types/trade-in"; + +// Как в thinMarketBadge.test.tsx: бренд и блок прозрачности ходят в сеть. +vi.mock("@/lib/useBrand", () => ({ + useActiveBrandSlug: () => null, + useBrand: () => ({ data: null }), +})); +vi.mock("../HeroTransparency", () => ({ HeroTransparency: () => null })); + +const SAME_BUILDING = + "справочно: цена посчитана по аналогам в этом же доме — коридор её не ограничивает"; + +function heroText(analog_tier: AnalogTier | null): string { + const estimate: AggregatedEstimate = { + ...FIXTURE_ESTIMATE, + analog_tier, + // n=20 ≥ порога: advisory_only=false, подпись может дать только тир. + dkp_corridor: { ...FIXTURE_ESTIMATE.dkp_corridor!, count: 20, advisory_only: false }, + }; + const { container } = render( + {}} />, + ); + return container.textContent ?? ""; +} + +describe("#3466 подпись коридора в v1 HeroSummary", () => { + it("same_building + n=20 → подпись про дом стоит в hero", () => { + const text = heroText("same_building"); + // Коридор отрисован (20 ДКП) и рядом — подпись, а не просто число. + expect(text).toContain("20 сд."); + expect(text).toContain(SAME_BUILDING); + }); + + it("micro_radius + n=20 → подписи нет: коридор цену держит", () => { + const text = heroText("micro_radius"); + expect(text).toContain("20 сд."); + expect(text).not.toContain("коридор её не ограничивает"); + }); +});