chore: finish frontend ESLint migration #18
Enable every plugin recommended preset and replace Biome with ESLint formatting. Preserve API contracts and JSX whitespace; verify source, tests, builds and tooling.
This commit is contained in:
@@ -1,21 +1,23 @@
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { fireEvent, render, screen, within } from "@testing-library/react";
|
||||
import { MemoryRouter, Route, Routes } from "react-router";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { useBrokerageEvents } from "@/entities/brokerage-event";
|
||||
|
||||
import { AccountEventsPage } from "./AccountEventsPage";
|
||||
|
||||
const { refresh } = vi.hoisted(() => ({ refresh: vi.fn() }));
|
||||
vi.mock("@/features/tbank-connection", () => ({
|
||||
useScreenSync: () => ({
|
||||
refresh,
|
||||
retry: refresh,
|
||||
refreshing: false,
|
||||
retry: refresh,
|
||||
sourceError: false,
|
||||
transportError: false,
|
||||
}),
|
||||
}));
|
||||
vi.mock("@/entities/brokerage-event", async (importOriginal) => ({
|
||||
vi.mock("@/entities/brokerage-event", async importOriginal => ({
|
||||
...(await importOriginal<typeof import("@/entities/brokerage-event")>()),
|
||||
useBrokerageEvents: vi.fn(),
|
||||
}));
|
||||
@@ -35,20 +37,22 @@ function renderPage() {
|
||||
describe("AccountEventsPage", () => {
|
||||
beforeEach(() => {
|
||||
refresh.mockClear();
|
||||
query.mockReturnValue({
|
||||
data: {
|
||||
accountId: "account",
|
||||
calculatedAt: "2026-08-14T00:00:00Z",
|
||||
events: [],
|
||||
},
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { state: "idle", id: null, errorCode: null },
|
||||
},
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
refetch: vi.fn(),
|
||||
} as never);
|
||||
query.mockReturnValue((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{
|
||||
data: {
|
||||
accountId: "account",
|
||||
calculatedAt: "2026-08-14T00:00:00Z",
|
||||
events: [],
|
||||
},
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { errorCode: null, id: null, state: "idle" },
|
||||
},
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
/* eslint-enable unicorn/no-null */) as never);
|
||||
});
|
||||
|
||||
it("passes the selected route account to the query", () => {
|
||||
@@ -57,8 +61,8 @@ describe("AccountEventsPage", () => {
|
||||
<MemoryRouter initialEntries={["/accounts/selected-account/events"]}>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/accounts/:accountId/events"
|
||||
element={<AccountEventsPage />}
|
||||
path="/accounts/:accountId/events"
|
||||
/>
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
@@ -68,16 +72,18 @@ describe("AccountEventsPage", () => {
|
||||
});
|
||||
|
||||
it("keeps the loading fallback when no result or account is available", () => {
|
||||
query.mockReturnValue({
|
||||
data: undefined,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { state: "idle", id: null, errorCode: null },
|
||||
},
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
refetch: vi.fn(),
|
||||
} as never);
|
||||
query.mockReturnValue((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{
|
||||
data: undefined,
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { errorCode: null, id: null, state: "idle" },
|
||||
},
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
/* eslint-enable unicorn/no-null */) as never);
|
||||
renderPage();
|
||||
expect(query).toHaveBeenCalledWith("", {});
|
||||
expect(screen.getByRole("status", { name: "Загрузка" })).toHaveAttribute(
|
||||
@@ -87,46 +93,48 @@ describe("AccountEventsPage", () => {
|
||||
});
|
||||
|
||||
it("renders events and marks an offer without an amount", () => {
|
||||
query.mockReturnValue({
|
||||
data: {
|
||||
accountId: "account",
|
||||
calculatedAt: "2026-08-14T00:00:00Z",
|
||||
events: [
|
||||
{
|
||||
date: "2026-08-20",
|
||||
dateKind: "event",
|
||||
displayName: "ОФЗ 26238",
|
||||
figi: "FIGI",
|
||||
instrumentUid: "UID",
|
||||
projectedAmount: { currency: "RUB", value: "1250" },
|
||||
ticker: "OFZ",
|
||||
type: "coupon",
|
||||
logoName: "ofz.png",
|
||||
isin: "RU000A0JX0J2",
|
||||
},
|
||||
{
|
||||
date: "2026-08-25",
|
||||
dateKind: "event",
|
||||
displayName: "ОФЗ 26238",
|
||||
figi: "FIGI",
|
||||
instrumentUid: "UID",
|
||||
projectedAmount: null,
|
||||
ticker: "OFZ",
|
||||
type: "offer",
|
||||
logoName: null,
|
||||
isin: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { state: "idle", id: null, errorCode: null },
|
||||
},
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
refetch: vi.fn(),
|
||||
} as never);
|
||||
const { container } = renderPage();
|
||||
query.mockReturnValue((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{
|
||||
data: {
|
||||
accountId: "account",
|
||||
calculatedAt: "2026-08-14T00:00:00Z",
|
||||
events: [
|
||||
{
|
||||
date: "2026-08-20",
|
||||
dateKind: "event",
|
||||
displayName: "ОФЗ 26238",
|
||||
figi: "FIGI",
|
||||
instrumentUid: "UID",
|
||||
isin: "RU000A0JX0J2",
|
||||
logoName: "ofz.png",
|
||||
projectedAmount: { currency: "RUB", value: "1250" },
|
||||
ticker: "OFZ",
|
||||
type: "coupon",
|
||||
},
|
||||
{
|
||||
date: "2026-08-25",
|
||||
dateKind: "event",
|
||||
displayName: "ОФЗ 26238",
|
||||
figi: "FIGI",
|
||||
instrumentUid: "UID",
|
||||
isin: null,
|
||||
logoName: null,
|
||||
projectedAmount: null,
|
||||
ticker: "OFZ",
|
||||
type: "offer",
|
||||
},
|
||||
],
|
||||
},
|
||||
isError: false,
|
||||
isLoading: false,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { errorCode: null, id: null, state: "idle" },
|
||||
},
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
/* eslint-enable unicorn/no-null */) as never);
|
||||
renderPage();
|
||||
expect(screen.getByText("1 250 ₽")).toBeInTheDocument();
|
||||
expect(screen.getByText("Сумма неизвестна")).toBeInTheDocument();
|
||||
expect(screen.getByText("Купон · ОФЗ 26238")).toBeVisible();
|
||||
@@ -136,7 +144,7 @@ describe("AccountEventsPage", () => {
|
||||
expect(screen.getByText("25.08.2026")).toBeVisible();
|
||||
expect(screen.queryByText(/Дата события/)).not.toBeInTheDocument();
|
||||
expect(screen.getAllByText("Ожидаемая сумма")).toHaveLength(2);
|
||||
const logo = container.querySelector("img");
|
||||
const logo = screen.queryByAltText("");
|
||||
expect(logo).toHaveAttribute(
|
||||
"src",
|
||||
"https://invest-brands.cdn-tinkoff.ru/ofzx160.png",
|
||||
@@ -144,7 +152,7 @@ describe("AccountEventsPage", () => {
|
||||
expect(screen.getAllByText("O")).toHaveLength(1);
|
||||
if (!logo) throw new Error("Expected the event logo");
|
||||
fireEvent.error(logo);
|
||||
expect(container.querySelector("img")).toBeNull();
|
||||
expect(screen.queryByAltText("")).not.toBeInTheDocument();
|
||||
expect(screen.getAllByText("O")).toHaveLength(2);
|
||||
});
|
||||
|
||||
@@ -167,26 +175,28 @@ describe("AccountEventsPage", () => {
|
||||
</MemoryRouter>
|
||||
</MantineProvider>,
|
||||
);
|
||||
screen.getByRole("button", { name: "Повторить" }).click();
|
||||
fireEvent.click(screen.getByRole("button", { name: "Повторить" }));
|
||||
expect(refresh).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("shows a structural busy state before events are available", () => {
|
||||
query.mockReturnValue({
|
||||
data: undefined,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { state: "idle", id: null, errorCode: null },
|
||||
},
|
||||
isError: false,
|
||||
isLoading: true,
|
||||
refetch: vi.fn(),
|
||||
} as never);
|
||||
query.mockReturnValue((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{
|
||||
data: undefined,
|
||||
isError: false,
|
||||
isLoading: true,
|
||||
meta: {
|
||||
availability: "complete",
|
||||
sync: { errorCode: null, id: null, state: "idle" },
|
||||
},
|
||||
refetch: vi.fn(),
|
||||
}
|
||||
/* eslint-enable unicorn/no-null */) as never);
|
||||
|
||||
renderPage();
|
||||
|
||||
const status = screen.getByRole("status", { name: "Загрузка" });
|
||||
expect(status).toHaveAttribute("aria-busy", "true");
|
||||
expect(status.querySelector("button")).toBeNull();
|
||||
expect(within(status).queryByRole("button")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user