test(tradein-front): подпись коридора в v1 HeroSummary стережётся рендером (#3466)

Ревью #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 <noreply@anthropic.com>
This commit is contained in:
bot-backend 2026-09-17 13:44:36 +05:00
parent 49bcfdacd6
commit 803ea2217b

View file

@ -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(
<HeroSummary estimate={estimate} input={FIXTURE_INPUT} onResubmit={() => {}} />,
);
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("коридор её не ограничивает");
});
});