From 9e83eb4a53de8939d4c80bb7afbd246913725fa3 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Thu, 13 Aug 2026 08:46:45 +0000 Subject: [PATCH] =?UTF-8?q?fix(tradein/ui):=20=D1=8D=D1=82=D0=B0=D0=B6=20?= =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8=20=D1=81=D0=BA=D1=80=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=D1=81=D1=8F=20=D1=83=20=D0=B2=D1=81=D0=B5?= =?UTF-8?q?=D1=85=2096=20974=20=E2=80=94=20=D1=82=D1=80=D0=B5=D0=B1=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=D0=BE=D1=81=D1=8C=20=D0=B2=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=B5=20(#2674)=20(#2861)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/trade-in/DealsCard.tsx | 11 +++- .../__tests__/DealsCardFloor.test.tsx | 57 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 tradein-mvp/frontend/src/components/trade-in/__tests__/DealsCardFloor.test.tsx diff --git a/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx b/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx index 9438f2e3..682e923c 100644 --- a/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx +++ b/tradein-mvp/frontend/src/components/trade-in/DealsCard.tsx @@ -156,8 +156,15 @@ function DealRow({ deal }: { deal: AnalogLot }) { {deal.address} {deal.area_m2.toFixed(1)} м² · {deal.rooms === 0 ? "студия" : `${deal.rooms}-к`} - {deal.floor !== null && deal.total_floors !== null - ? ` · этаж ${deal.floor}/${deal.total_floors}` + {/* #2674: этажность у сделок Росреестра пуста ВСЕГДА (0 из 96 974 — + открытый набор её не содержит), а этаж заполнен у 96 974 из 96 974. + Прежнее условие требовало оба поля, поэтому этаж был скрыт у ВСЕХ + сделок. Печатаем «этаж N», когда этажности нет, — ровно так уже + делает BuildingListingsDrawer для объявлений. */} + {deal.floor !== null + ? deal.total_floors !== null + ? ` · этаж ${deal.floor}/${deal.total_floors}` + : ` · этаж ${deal.floor}` : ""} diff --git a/tradein-mvp/frontend/src/components/trade-in/__tests__/DealsCardFloor.test.tsx b/tradein-mvp/frontend/src/components/trade-in/__tests__/DealsCardFloor.test.tsx new file mode 100644 index 00000000..77dfffd3 --- /dev/null +++ b/tradein-mvp/frontend/src/components/trade-in/__tests__/DealsCardFloor.test.tsx @@ -0,0 +1,57 @@ +/** + * #2674 — этаж сделки скрывался у ВСЕХ сделок из-за требования второго поля. + * + * Замер на проде 13.08.2026: `deals.floor` заполнен у 96 974 из 96 974, + * `deals.total_floors` — у 0 из 96 974. Открытый набор Росреестра этажности не + * содержит в принципе, то есть это не «данные не доехали», а свойство источника. + * + * Прежнее условие печатало «этаж X/Y» только когда непусты ОБА поля, поэтому + * этаж не показывался никогда. Соседний компонент (BuildingListingsDrawer) уже + * делал правильно — печатал «этаж N», когда этажность неизвестна. + */ +import { render, screen } from "@testing-library/react"; +import { describe, expect, it } from "vitest"; + +import { DealsCard } from "../DealsCard"; +import type { AggregatedEstimate, AnalogLot } from "@/types/trade-in"; + +function makeDeal(overrides: Partial = {}): AnalogLot { + return { + address: "Екатеринбург, Ленина 5", + area_m2: 55.4, + rooms: 2, + floor: 7, + total_floors: null, + price_rub: 6_500_000, + price_per_m2: 117_328, + source: "rosreestr", + deal_date: "2026-01-01", + ...overrides, + } as AnalogLot; +} + +function makeEstimate(deals: AnalogLot[]): AggregatedEstimate { + return { + actual_deals: deals, + period_months: 12, + } as unknown as AggregatedEstimate; +} + +describe("DealsCard — этаж сделки", () => { + it("печатает этаж, когда этажность неизвестна (боевой случай: 100% сделок)", () => { + render(); + // Именно «этаж 7» без дроби — этажности у сделок Росреестра нет никогда. + expect(screen.getByText(/этаж 7/)).toBeTruthy(); + expect(screen.queryByText(/этаж 7\//)).toBeNull(); + }); + + it("печатает дробь, когда этажность известна — прежнее поведение цело", () => { + render(); + expect(screen.getByText(/этаж 7\/9/)).toBeTruthy(); + }); + + it("не печатает ничего, когда неизвестен сам этаж", () => { + render(); + expect(screen.queryByText(/этаж/)).toBeNull(); + }); +});