refactor: enforce frontend view model boundaries
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s

This commit is contained in:
2026-09-28 18:48:23 +03:00
parent 5b69003516
commit ca0ad4f824
287 changed files with 8558 additions and 4538 deletions
+10 -6
View File
@@ -19,9 +19,11 @@ const handlers = [
),
http.get("*/api/v1/auth/me", () => HttpResponse.json(authentication.user)),
http.get("*/api/v1/tbank-connection", () =>
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 */)),
/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
HttpResponse.json(
{ connected: false, connectedAt: null },
/* eslint-enable unicorn/no-null */
),
),
http.put("*/api/v1/tbank-connection", () =>
HttpResponse.json({ connected: true, connectedAt: "2026-08-14T00:00:00Z" }),
@@ -47,15 +49,17 @@ const handlers = [
),
http.get("*/api/v1/brokerage-accounts/:accountId/operations", () =>
HttpResponse.json(
resource((/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
resource(
{
accountId: "account-1",
hasNext: false,
items: [],
nextCursor: null,
observedAt: "2026-08-14T00:00:00Z",
}
/* eslint-enable unicorn/no-null */)),
},
/* eslint-enable unicorn/no-null */
),
),
),
http.get("*/api/v1/brokerage-accounts/:accountId/events", () =>
+5 -2
View File
@@ -2,8 +2,10 @@ import type { paths } from "@/shared/api";
type Meta
= paths["/api/v1/brokerage-accounts"]["get"]["responses"][200]["content"]["application/json"]["meta"];
function resource<T>(data: T, meta: Partial<Meta> = {}) {
return (/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
/* eslint-disable unicorn/no-null -- Fixture preserves the production contract’s explicit null values. */
return (
{
data,
meta: {
@@ -17,7 +19,8 @@ function resource<T>(data: T, meta: Partial<Meta> = {}) {
...meta,
} satisfies Meta,
}
/* eslint-enable unicorn/no-null */);
/* eslint-enable unicorn/no-null */
);
}
export { resource };
+3 -1
View File
@@ -39,7 +39,9 @@ Object.defineProperty(globalThis, "matchMedia", {
dispatchEvent: () => false,
matches: false,
media: query,
onchange: /* eslint-disable-line unicorn/no-null -- Exercise the explicit null returned by the production API/DOM contract. */ null,
onchange:
// eslint-disable-next-line unicorn/no-null -- Exercise the explicit null returned by the production API/DOM contract.
null,
removeEventListener: () => {},
removeListener: () => {},
}),
+5
View File
@@ -28,6 +28,7 @@ describe("Storybook isolated product examples", () => {
vi.spyOn(Document.prototype, "cookie", "get"),
vi.spyOn(Document.prototype, "cookie", "set"),
];
const stories = [
...Object.values(composeStories(AccountStories, preview)),
...Object.values(composeStories(LoadingStories, preview)),
@@ -39,16 +40,20 @@ describe("Storybook isolated product examples", () => {
...Object.values(composeStories(IncomePeriodStories, preview)),
...Object.values(composeStories(OperationStories, preview)),
];
for (const Story of stories) {
render(<Story />);
for (const button of screen.queryAllByRole("button"))
fireEvent.click(button);
for (const link of screen.queryAllByRole("link")) fireEvent.click(link);
for (const image of screen.queryAllByRole("img")) {
expect(image).not.toHaveAttribute("src");
}
cleanup();
}
for (const spy of spies) expect(spy).not.toHaveBeenCalled();
});