uup
This commit is contained in:
278
app/lib/__tests__/expense-management.test.ts
Normal file
278
app/lib/__tests__/expense-management.test.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
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
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user