ledgerone_frontend/tests/transactions.spec.ts
2026-02-24 21:47:18 +00:00

125 lines
3.7 KiB
TypeScript

import { test, expect } from "@playwright/test";
const apiOk = (data: unknown) => ({
data,
meta: { timestamp: new Date().toISOString(), version: "v1" },
error: null
});
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
localStorage.setItem("ledgerone_user_id", "test_user");
});
});
test("transactions page supports filters, manual add, and edit", async ({ page }) => {
let listResponse = apiOk([
{
id: "tx_1",
name: "Coffee Bar",
amount: "12.50",
category: "Dining",
note: "",
status: "raw",
hidden: false,
date: "2025-01-10"
}
]);
await page.route("**/api/transactions/summary**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ total: "12.50", count: 1, income: "0.00", expense: "12.50", net: "-12.50" }))
});
});
await page.route("**/api/transactions/merchants**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk([]))
});
});
await page.route("**/api/transactions/cashflow**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk([]))
});
});
await page.route("**/api/transactions?*", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(listResponse)
});
});
await page.route("**/api/transactions", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(listResponse)
});
});
await page.route("**/api/transactions/sync", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ created: 1 }))
});
});
await page.route("**/api/transactions/manual", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({ id: "tx_2" }))
});
});
await page.route("**/api/transactions/*/derived", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(apiOk({}))
});
});
await page.route("**/api/accounts**", async (route) => {
await route.fulfill({
contentType: "application/json",
body: JSON.stringify(
apiOk([
{ id: "acct_1", institutionName: "Chase", accountType: "checking", mask: "1234" }
])
)
});
});
await page.goto("/transactions");
await expect(page.getByText("Sync transactions")).toBeVisible();
await expect(page.getByText("Export CSV")).toBeVisible();
await page.getByRole("button", { name: "Show filters" }).click();
await expect(page.getByPlaceholder("Search description")).toBeVisible();
await page.getByRole("button", { name: "Add manual" }).click();
await expect(page.getByText("Manual transaction")).toBeVisible();
await page.getByPlaceholder("Description").fill("Manual payment");
await page.getByPlaceholder("0.00").fill("40.25");
await page.getByRole("button", { name: "Save manual transaction" }).click();
await expect(page.getByText("Manual transaction saved.")).toBeVisible();
await page.getByRole("button", { name: "Edit" }).click();
await page.getByPlaceholder("Category").fill("Coffee");
await page.getByPlaceholder("Note").fill("Edited note");
listResponse = apiOk([
{
id: "tx_1",
name: "Coffee Bar",
amount: "12.50",
category: "Coffee",
note: "Edited note",
status: "user",
hidden: false,
date: "2025-01-10"
}
]);
await page.getByRole("button", { name: "Save edits" }).click();
await expect(page.getByText("Transaction updated.")).toBeVisible();
});