refactor: simplify calendar and form state
This commit is contained in:
@@ -30,10 +30,9 @@ import { createTestQueryClient } from "@/test/query";
|
||||
import { resource } from "@/test/resource";
|
||||
import { server } from "@/test/server";
|
||||
|
||||
import { isDate } from "../../model/period";
|
||||
import { toIncomeDisplayModel } from "../../model/display";
|
||||
import { AccountIncomePage } from "./AccountIncomePage";
|
||||
import {
|
||||
toIncomeDisplayModel,
|
||||
useAccountIncomePageViewModel,
|
||||
} from "./AccountIncomePage.vm";
|
||||
import { IncomePayments } from "./components/IncomePayments.view";
|
||||
@@ -469,12 +468,6 @@ describe("AccountIncomePage", () => {
|
||||
expect(within(panel).getByText("−2 ₽")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("rejects malformed calendar dates without throwing", () => {
|
||||
expect(isDate("2026-99-99")).toBe(false);
|
||||
expect(isDate("2026-02-29")).toBe(false);
|
||||
expect(isDate("2024-02-29")).toBe(true);
|
||||
});
|
||||
|
||||
it("renders realized text and comparisons without subscribing to events", async () => {
|
||||
const eventsRequest = vi.fn(() => new HttpResponse(null, { status: 503 }));
|
||||
server.use(
|
||||
@@ -584,92 +577,6 @@ describe("AccountIncomePage", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("income comparison display", () => {
|
||||
it.each([
|
||||
["25", "100", "+25 %"],
|
||||
["-25", "100", "-25 %"],
|
||||
["0", "100", "0 %"],
|
||||
["-0.000", "100", "0 %"],
|
||||
["0.0001", "100", "0 %"],
|
||||
["1", "3", "+33,3 %"],
|
||||
["0.01", "0.04", "+25 %"],
|
||||
["123456789012345678.123456789", "123456789012345678.123456789", "+100 %"],
|
||||
[
|
||||
"10",
|
||||
"0",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"0",
|
||||
"0",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"10",
|
||||
"-0.00",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"10",
|
||||
"-100",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"9".repeat(400),
|
||||
"1",
|
||||
null,
|
||||
],
|
||||
[
|
||||
"1",
|
||||
"9".repeat(400),
|
||||
null,
|
||||
],
|
||||
])("formats change %s against base %s", (difference, base, expected) => {
|
||||
const value = comparison("RUB");
|
||||
value.difference.coupon = money("RUB", difference);
|
||||
value.compared.coupon = money("RUB", base);
|
||||
|
||||
const display = toIncomeDisplayModel({
|
||||
...analytics,
|
||||
yearComparison: {
|
||||
period: { from: "2025-08-01", to: "2025-08-27" },
|
||||
totalsByCurrency: [value],
|
||||
},
|
||||
});
|
||||
|
||||
const result = display?.comparison?.values[0];
|
||||
expect(
|
||||
result?.percentages.coupon?.replaceAll("\u{A0}", " ")
|
||||
|
||||
?? null,
|
||||
).toBe(expected);
|
||||
expect(result?.difference.coupon.value).toBe(difference);
|
||||
expect(result?.compared.coupon.value).toBe(base);
|
||||
});
|
||||
|
||||
it("formats calendar ranges across years and preserves separate currencies", () => {
|
||||
const display = toIncomeDisplayModel({
|
||||
...analytics,
|
||||
period: { from: "2025-12-01", to: "2026-01-09" },
|
||||
yearComparison: {
|
||||
period: { from: "2024-12-01", to: "2025-01-09" },
|
||||
totalsByCurrency: [comparison("RUB"), comparison("USD")],
|
||||
},
|
||||
});
|
||||
|
||||
expect(display?.comparison?.selectedPeriod.replaceAll(/\s/g, " ")).toBe(
|
||||
"01.12.2025 – 09.01.2026",
|
||||
);
|
||||
expect(display?.comparison?.comparedPeriod.replaceAll(/\s/g, " ")).toBe(
|
||||
"01.12.2024 – 09.01.2025",
|
||||
);
|
||||
expect(display?.comparison?.values.map(value => value.currency)).toEqual([
|
||||
"RUB",
|
||||
"USD",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
const LocationProbe: FC = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
@@ -978,43 +885,6 @@ describe("income period and snapshot boundary", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("maps comparison notices by role regardless of dependency order or resource key", () => {
|
||||
const selected = { ...resource(analytics).meta, role: "selected" as const };
|
||||
|
||||
const previous
|
||||
= {
|
||||
...resource(null).meta,
|
||||
resourceKey: "opaque/year-looking-key",
|
||||
role: "previous" as const,
|
||||
sync: {
|
||||
errorCode: "TBANK_UNAVAILABLE",
|
||||
id: null,
|
||||
state: "failed" as const,
|
||||
},
|
||||
};
|
||||
|
||||
const year = {
|
||||
...resource(null).meta,
|
||||
resourceKey: "opaque/previous-looking-key",
|
||||
role: "year" as const,
|
||||
unavailableReason: "CALENDAR_OR_ACCOUNT_HISTORY",
|
||||
};
|
||||
|
||||
for (const dependencies of [
|
||||
[selected, previous, year],
|
||||
[year, selected, previous],
|
||||
]) {
|
||||
const display = toIncomeDisplayModel(analytics, {
|
||||
...resource(analytics).meta,
|
||||
dependencies,
|
||||
});
|
||||
|
||||
expect(display?.previousNotice).toBe("comparisonFailed");
|
||||
expect(display?.yearNotice).toBe("yearUnavailable");
|
||||
expect(display?.previousComparison).not.toBeNull();
|
||||
}
|
||||
});
|
||||
|
||||
it.each([false, true])(
|
||||
"shows unavailable comparisons for absent roles without positional fallback (legacy=%s)",
|
||||
async (legacy) => {
|
||||
|
||||
Reference in New Issue
Block a user