car_mms/app/lib/__tests__/expense-management.test.ts
2025-09-11 14:22:27 +03:00

278 lines
9.4 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import {
createExpense,
getExpenses,
getExpenseById,
updateExpense,
deleteExpense,
getExpenseCategories,
getExpensesByCategory,
getTotalExpenses
} from '../expense-management.server';
import { prisma } from '../db.server';
describe('Expense Management', () => {
beforeEach(async () => {
// Clean up test data
await prisma.expense.deleteMany();
});
afterEach(async () => {
// Clean up test data
await prisma.expense.deleteMany();
});
describe('createExpense', () => {
it('should create a new expense', async () => {
const expenseData = {
description: 'قطع غيار للمحرك',
category: 'قطع غيار',
amount: 500.00,
expenseDate: new Date('2024-01-15'),
};
const expense = await createExpense(expenseData);
expect(expense).toBeDefined();
expect(expense.description).toBe(expenseData.description);
expect(expense.category).toBe(expenseData.category);
expect(expense.amount).toBe(expenseData.amount);
expect(expense.expenseDate).toEqual(expenseData.expenseDate);
});
it('should create expense with current date if no date provided', async () => {
const expenseData = {
description: 'مصروف عام',
category: 'أخرى',
amount: 100.00,
};
const expense = await createExpense(expenseData);
expect(expense).toBeDefined();
expect(expense.expenseDate).toBeInstanceOf(Date);
});
});
describe('getExpenses', () => {
beforeEach(async () => {
// Create test expenses
await prisma.expense.createMany({
data: [
{
description: 'قطع غيار',
category: 'قطع غيار',
amount: 500.00,
expenseDate: new Date('2024-01-15'),
},
{
description: 'أدوات صيانة',
category: 'أدوات',
amount: 200.00,
expenseDate: new Date('2024-01-10'),
},
{
description: 'إيجار المحل',
category: 'إيجار',
amount: 3000.00,
expenseDate: new Date('2024-01-01'),
},
],
});
});
it('should get all expenses with pagination', async () => {
const result = await getExpenses();
expect(result.expenses).toHaveLength(3);
expect(result.total).toBe(3);
expect(result.totalPages).toBe(1);
});
it('should filter expenses by search query', async () => {
const result = await getExpenses('قطع غيار');
expect(result.expenses).toHaveLength(1);
expect(result.expenses[0].description).toBe('قطع غيار');
});
it('should filter expenses by category', async () => {
const result = await getExpenses(undefined, 1, 10, 'أدوات');
expect(result.expenses).toHaveLength(1);
expect(result.expenses[0].category).toBe('أدوات');
});
it('should filter expenses by date range', async () => {
const dateFrom = new Date('2024-01-10');
const dateTo = new Date('2024-01-20');
const result = await getExpenses(undefined, 1, 10, undefined, dateFrom, dateTo);
expect(result.expenses).toHaveLength(2);
});
it('should handle pagination correctly', async () => {
const result = await getExpenses(undefined, 1, 2);
expect(result.expenses).toHaveLength(2);
expect(result.totalPages).toBe(2);
});
});
describe('getExpenseById', () => {
it('should get expense by ID', async () => {
const createdExpense = await prisma.expense.create({
data: {
description: 'تست مصروف',
category: 'أخرى',
amount: 100.00,
},
});
const expense = await getExpenseById(createdExpense.id);
expect(expense).toBeDefined();
expect(expense?.id).toBe(createdExpense.id);
expect(expense?.description).toBe('تست مصروف');
});
it('should return null for non-existent expense', async () => {
const expense = await getExpenseById(999);
expect(expense).toBeNull();
});
});
describe('updateExpense', () => {
it('should update expense successfully', async () => {
const createdExpense = await prisma.expense.create({
data: {
description: 'مصروف قديم',
category: 'أخرى',
amount: 100.00,
},
});
const updateData = {
description: 'مصروف محدث',
category: 'قطع غيار',
amount: 200.00,
};
const updatedExpense = await updateExpense(createdExpense.id, updateData);
expect(updatedExpense.description).toBe(updateData.description);
expect(updatedExpense.category).toBe(updateData.category);
expect(updatedExpense.amount).toBe(updateData.amount);
});
});
describe('deleteExpense', () => {
it('should delete expense successfully', async () => {
const createdExpense = await prisma.expense.create({
data: {
description: 'مصروف للحذف',
category: 'أخرى',
amount: 100.00,
},
});
await deleteExpense(createdExpense.id);
const deletedExpense = await prisma.expense.findUnique({
where: { id: createdExpense.id },
});
expect(deletedExpense).toBeNull();
});
});
describe('getExpenseCategories', () => {
beforeEach(async () => {
await prisma.expense.createMany({
data: [
{ description: 'مصروف 1', category: 'قطع غيار', amount: 100 },
{ description: 'مصروف 2', category: 'أدوات', amount: 200 },
{ description: 'مصروف 3', category: 'قطع غيار', amount: 150 },
],
});
});
it('should get unique expense categories', async () => {
const categories = await getExpenseCategories();
expect(categories).toHaveLength(2);
expect(categories).toContain('قطع غيار');
expect(categories).toContain('أدوات');
});
});
describe('getExpensesByCategory', () => {
beforeEach(async () => {
await prisma.expense.createMany({
data: [
{ description: 'مصروف 1', category: 'قطع غيار', amount: 100 },
{ description: 'مصروف 2', category: 'أدوات', amount: 200 },
{ description: 'مصروف 3', category: 'قطع غيار', amount: 150 },
],
});
});
it('should group expenses by category', async () => {
const result = await getExpensesByCategory();
expect(result).toHaveLength(2);
const spareParts = result.find(r => r.category === 'قطع غيار');
expect(spareParts?.total).toBe(250);
expect(spareParts?.count).toBe(2);
const tools = result.find(r => r.category === 'أدوات');
expect(tools?.total).toBe(200);
expect(tools?.count).toBe(1);
});
});
describe('getTotalExpenses', () => {
beforeEach(async () => {
await prisma.expense.createMany({
data: [
{
description: 'مصروف 1',
category: 'قطع غيار',
amount: 100,
expenseDate: new Date('2024-01-15'),
},
{
description: 'مصروف 2',
category: 'أدوات',
amount: 200,
expenseDate: new Date('2024-01-10'),
},
{
description: 'مصروف 3',
category: 'إيجار',
amount: 3000,
expenseDate: new Date('2023-12-15'),
},
],
});
});
it('should calculate total expenses', async () => {
const total = await getTotalExpenses();
expect(total).toBe(3300);
});
it('should calculate total expenses for date range', async () => {
const dateFrom = new Date('2024-01-01');
const dateTo = new Date('2024-01-31');
const total = await getTotalExpenses(dateFrom, dateTo);
expect(total).toBe(300); // Only expenses from January 2024
});
});
});