/// import { convexTest } from "convex-test"; import { describe, expect, test } from "vitest"; import { api } from "./_generated/api"; import type { Id } from "./_generated/dataModel"; import schema from "./schema"; const modules = import.meta.glob("./**/*.ts"); delete modules["./transactions.test.ts"]; describe("transactions.list", () => { test("combines search, date range, account, category, and type filters", async () => { const t = convexTest(schema, modules); const seeded = await t.run(async (ctx) => { const userId = await ctx.db.insert("users", { name: "Filter User", email: "filter@example.com", }); const giroAccountId = await ctx.db.insert("accounts", { userId, name: "Girokonto", type: "checking", openingBalance: 0, currency: "EUR", isArchived: false, }); const otherAccountId = await ctx.db.insert("accounts", { userId, name: "Depot", type: "investment", openingBalance: 0, currency: "EUR", isArchived: false, }); const groceryCategoryId = await ctx.db.insert("categories", { userId, name: "Lebensmittel & Supermarkt", kind: "ausgabe", block: "variabel", color: "#ef4444", sortOrder: 1, isSystem: false, }); const restaurantCategoryId = await ctx.db.insert("categories", { userId, name: "Restaurant", kind: "ausgabe", block: "variabel", color: "#f97316", sortOrder: 2, isSystem: false, }); const matchingId = await ctx.db.insert("transactions", { userId, accountId: giroAccountId, categoryId: groceryCategoryId, bookingDate: "2026-06-15", description: "LIDL SAGT DANKE", amount: -18.37, isPending: false, effectiveMonth: "2026-06", }); await ctx.db.insert("transactions", { userId, accountId: giroAccountId, categoryId: groceryCategoryId, bookingDate: "2026-05-29", description: "LIDL OLD MONTH", amount: -21.92, isPending: false, effectiveMonth: "2026-05", }); await ctx.db.insert("transactions", { userId, accountId: otherAccountId, categoryId: groceryCategoryId, bookingDate: "2026-06-16", description: "LIDL OTHER ACCOUNT", amount: -99, isPending: false, effectiveMonth: "2026-06", }); await ctx.db.insert("transactions", { userId, accountId: giroAccountId, categoryId: restaurantCategoryId, bookingDate: "2026-06-17", description: "LIDL RESTAURANT", amount: -12, isPending: false, effectiveMonth: "2026-06", }); await ctx.db.insert("transactions", { userId, accountId: giroAccountId, categoryId: groceryCategoryId, bookingDate: "2026-06-18", description: "LIDL REFUND", amount: 5, isPending: false, effectiveMonth: "2026-06", }); return { userId, giroAccountId, groceryCategoryId, matchingId }; }); const asUser = t.withIdentity({ subject: `${seeded.userId}|test-session`, tokenIdentifier: `test:${seeded.userId}`, }); const result = await asUser.query(api.transactions.list, { paginationOpts: { cursor: null, numItems: 20 }, search: "LIDL", from: "2026-06-01", to: "2026-06-30", accountId: seeded.giroAccountId as Id<"accounts">, categoryIds: [seeded.groceryCategoryId as Id<"categories">], type: "ausgabe", basis: "booking", }); expect(result.page.map((tx) => tx._id)).toEqual([seeded.matchingId]); }); test("filters by effective month when the global basis is assignment month", async () => { const t = convexTest(schema, modules); const seeded = await t.run(async (ctx) => { const userId = await ctx.db.insert("users", { name: "Basis User", email: "basis@example.com", }); const accountId = await ctx.db.insert("accounts", { userId, name: "Girokonto", type: "checking", openingBalance: 0, currency: "EUR", isArchived: false, }); const shiftedId = await ctx.db.insert("transactions", { userId, accountId, bookingDate: "2026-05-29", description: "Salary shifted into June", amount: 2500, isPending: false, assignedMonth: "2026-06", effectiveMonth: "2026-06", }); await ctx.db.insert("transactions", { userId, accountId, bookingDate: "2026-05-20", description: "May only", amount: -15, isPending: false, effectiveMonth: "2026-05", }); return { userId, shiftedId }; }); const asUser = t.withIdentity({ subject: `${seeded.userId}|test-session`, tokenIdentifier: `test:${seeded.userId}`, }); const effectiveResult = await asUser.query(api.transactions.list, { paginationOpts: { cursor: null, numItems: 20 }, from: "2026-06-01", to: "2026-06-30", basis: "effective", }); const bookingResult = await asUser.query(api.transactions.list, { paginationOpts: { cursor: null, numItems: 20 }, from: "2026-06-01", to: "2026-06-30", basis: "booking", }); expect(effectiveResult.page.map((tx) => tx._id)).toEqual([seeded.shiftedId]); expect(bookingResult.page).toEqual([]); }); });