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:
+30
-28
@@ -7,11 +7,13 @@ import {
|
||||
waitFor,
|
||||
within,
|
||||
} from "@testing-library/react";
|
||||
import { HttpResponse, http } from "msw";
|
||||
import { http, HttpResponse } from "msw";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { apiQueryClient, configureAuthClient } from "@/shared/api";
|
||||
import { createTestQueryClient } from "@/test/query";
|
||||
import { server } from "@/test/server";
|
||||
|
||||
import { tbankConnectionQueryOptions } from "../../model/connection-boundary";
|
||||
import { TbankConnectionSection } from "./TbankConnectionSection";
|
||||
|
||||
@@ -54,8 +56,8 @@ const unrelatedQueryKey = apiQueryClient.queryOptions(
|
||||
function renderSection(client: QueryClient) {
|
||||
configureAuthClient({
|
||||
accessToken: () => "test-token",
|
||||
refresh: async () => true,
|
||||
clear: vi.fn(),
|
||||
refresh: () => Promise.resolve(true),
|
||||
});
|
||||
return render(
|
||||
<MantineProvider>
|
||||
@@ -69,12 +71,14 @@ function renderSection(client: QueryClient) {
|
||||
function seededClient() {
|
||||
const client = createTestQueryClient();
|
||||
client.setQueryData(brokerageAccountsQueryKey, [
|
||||
{
|
||||
id: "account-1",
|
||||
name: "Основной счет",
|
||||
type: "BROKERAGE",
|
||||
openedOn: null,
|
||||
},
|
||||
(/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{
|
||||
id: "account-1",
|
||||
name: "Основной счет",
|
||||
openedOn: null,
|
||||
type: "BROKERAGE",
|
||||
}
|
||||
/* eslint-enable unicorn/no-null */),
|
||||
]);
|
||||
client.setQueryData(portfolioQueryKey, { source: "previous-connection" });
|
||||
client.setQueryData(stockQueryKey, { source: "previous-connection" });
|
||||
@@ -87,10 +91,8 @@ function seededClient() {
|
||||
describe("TbankConnectionSection", () => {
|
||||
it("preserves cached status and a draft entered during a delayed failed refetch", async () => {
|
||||
const status = { connected: true, connectedAt: "2026-08-14T00:00:00Z" };
|
||||
let finishRefetch: (() => void) | undefined;
|
||||
const response = new Promise<void>((resolve) => {
|
||||
finishRefetch = resolve;
|
||||
});
|
||||
|
||||
const { promise: response, resolve: finishRefetch } = Promise.withResolvers<void>();
|
||||
let reads = 0;
|
||||
server.use(
|
||||
http.get("*/api/v1/tbank-connection", async () => {
|
||||
@@ -141,7 +143,9 @@ describe("TbankConnectionSection", () => {
|
||||
reads += 1;
|
||||
return reads === 1
|
||||
? HttpResponse.json({ code: "TBANK_UNAVAILABLE" }, { status: 503 })
|
||||
: HttpResponse.json({ connected: false, connectedAt: null });
|
||||
: HttpResponse.json((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
|
||||
{ connected: false, connectedAt: null }
|
||||
/* eslint-enable unicorn/no-null */));
|
||||
}),
|
||||
);
|
||||
renderSection(createTestQueryClient());
|
||||
@@ -238,22 +242,21 @@ describe("TbankConnectionSection", () => {
|
||||
|
||||
it("cancels an in-flight previous-boundary query and ignores its late response", async () => {
|
||||
const client = seededClient();
|
||||
let finishPrevious: ((value: { source: string }) => void) | undefined;
|
||||
let aborted = false;
|
||||
const previousResponse = new Promise<{ source: string }>((resolve) => {
|
||||
finishPrevious = resolve;
|
||||
});
|
||||
|
||||
let isAborted = false;
|
||||
const { promise: previousResponse, resolve: finishPrevious } = Promise.withResolvers<{ source: string }>();
|
||||
const previousRequest = client
|
||||
.fetchQuery({
|
||||
queryKey: operationsQueryKey,
|
||||
.query({
|
||||
queryFn: ({ signal }) => {
|
||||
signal.addEventListener("abort", () => {
|
||||
aborted = true;
|
||||
isAborted = true;
|
||||
});
|
||||
return previousResponse;
|
||||
},
|
||||
queryKey: operationsQueryKey,
|
||||
})
|
||||
.catch(() => undefined);
|
||||
// eslint-disable-next-line unicorn/prefer-await -- Attach the handler immediately and retain the pending promise for queue/race ordering.
|
||||
.catch(() => {});
|
||||
renderSection(client);
|
||||
|
||||
await screen.findByText("Не подключено");
|
||||
@@ -262,7 +265,7 @@ describe("TbankConnectionSection", () => {
|
||||
});
|
||||
fireEvent.click(screen.getByRole("button", { name: "Подключить" }));
|
||||
|
||||
await waitFor(() => expect(aborted).toBe(true));
|
||||
await waitFor(() => expect(isAborted).toBe(true));
|
||||
await previousRequest;
|
||||
finishPrevious?.({ source: "previous-connection" });
|
||||
await Promise.resolve();
|
||||
@@ -298,10 +301,8 @@ describe("TbankConnectionSection", () => {
|
||||
|
||||
it("keeps DELETE recovery inside the dialog and preserves cache until successful retry", async () => {
|
||||
let deletes = 0;
|
||||
let finishDelete: (() => void) | undefined;
|
||||
const response = new Promise<void>((resolve) => {
|
||||
finishDelete = resolve;
|
||||
});
|
||||
|
||||
const { promise: response, resolve: finishDelete } = Promise.withResolvers<void>();
|
||||
server.use(
|
||||
http.get("*/api/v1/tbank-connection", () =>
|
||||
HttpResponse.json({
|
||||
@@ -327,6 +328,7 @@ describe("TbankConnectionSection", () => {
|
||||
name: "Удалить подключение?",
|
||||
});
|
||||
await waitFor(() =>
|
||||
// eslint-disable-next-line testing-library/no-node-access -- This assertion checks DOM structure, decoration or focus behavior that semantic queries cannot establish.
|
||||
expect(dialog.contains(document.activeElement)).toBe(true),
|
||||
);
|
||||
const confirm = within(dialog).getByRole("button", { name: /^Удалить$/ });
|
||||
@@ -340,7 +342,7 @@ describe("TbankConnectionSection", () => {
|
||||
document.body.tabIndex = -1;
|
||||
document.body.focus();
|
||||
document.body.removeAttribute("tabindex");
|
||||
expect(document.activeElement).toBe(document.body);
|
||||
expect(document.body).toHaveFocus();
|
||||
finishDelete?.();
|
||||
|
||||
expect(await within(dialog).findByRole("alert")).toHaveTextContent(
|
||||
|
||||
Reference in New Issue
Block a user