feat(expenses): enhance expenses management with filtering and search capabilities

This commit is contained in:
Jose Selesan
2026-05-29 14:56:35 -03:00
parent e99e97aa14
commit d3cf386be5
9 changed files with 379 additions and 17 deletions

View File

@@ -13,6 +13,7 @@ const mockPrisma = {
findFirst: mock(),
create: mock(),
update: mock(),
count: mock(),
},
};
@@ -26,6 +27,7 @@ beforeEach(() => {
fn.mockClear();
}
}
mockPrisma.expense.count.mockResolvedValue(0);
});
const {
@@ -229,7 +231,7 @@ describe("listPeriodicExpenses", () => {
expect(result).toEqual(mockItems);
expect(mockPrisma.periodicExpense.findMany).toHaveBeenCalledWith({
where: { isDeleted: false },
orderBy: { createdAt: "desc" },
orderBy: { description: "asc" },
});
});
});
@@ -289,21 +291,65 @@ describe("softDeletePeriodicExpense", () => {
describe("listExpenses", () => {
test("returns all expenses when no status filter", async () => {
mockPrisma.expense.findMany.mockResolvedValueOnce([]);
await listExpenses();
await listExpenses({});
expect(mockPrisma.expense.findMany).toHaveBeenCalledWith({
where: {},
include: { periodicExpense: true },
orderBy: { dueDate: "asc" },
orderBy: { dueDate: "desc" },
skip: 0,
take: 10,
});
});
test("filters by status when provided", async () => {
mockPrisma.expense.findMany.mockResolvedValueOnce([]);
await listExpenses("PENDING");
await listExpenses({ status: "PENDING" });
expect(mockPrisma.expense.findMany).toHaveBeenCalledWith({
where: { status: "PENDING" },
include: { periodicExpense: true },
orderBy: { dueDate: "asc" },
orderBy: { dueDate: "desc" },
skip: 0,
take: 10,
});
});
test("filters by periodicExpenseId when provided", async () => {
mockPrisma.expense.findMany.mockResolvedValueOnce([]);
await listExpenses({ periodicExpenseId: 3 });
expect(mockPrisma.expense.findMany).toHaveBeenCalledWith({
where: { periodicExpenseId: 3 },
include: { periodicExpense: true },
orderBy: { dueDate: "desc" },
skip: 0,
take: 10,
});
});
test("filters by search query with case-insensitive contains", async () => {
mockPrisma.expense.findMany.mockResolvedValueOnce([]);
await listExpenses({ search: "Gim" });
expect(mockPrisma.expense.findMany).toHaveBeenCalledWith({
where: { description: { contains: "Gim", mode: "insensitive" } },
include: { periodicExpense: true },
orderBy: { dueDate: "desc" },
skip: 0,
take: 10,
});
});
test("combines status, periodicExpenseId, and search filters", async () => {
mockPrisma.expense.findMany.mockResolvedValueOnce([]);
await listExpenses({ status: "PENDING", periodicExpenseId: 1, search: "Agua" });
expect(mockPrisma.expense.findMany).toHaveBeenCalledWith({
where: {
status: "PENDING",
periodicExpenseId: 1,
description: { contains: "Agua", mode: "insensitive" },
},
include: { periodicExpense: true },
orderBy: { dueDate: "desc" },
skip: 0,
take: 10,
});
});
});