293 lines
8.8 KiB
TypeScript
293 lines
8.8 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
|
|
// Mock the auth middleware
|
|
vi.mock('../auth-middleware.server', () => ({
|
|
requireAuth: vi.fn().mockResolvedValue({
|
|
id: 1,
|
|
name: 'Test User',
|
|
username: 'testuser',
|
|
email: 'test@example.com',
|
|
authLevel: 1,
|
|
status: 'active',
|
|
}),
|
|
}));
|
|
|
|
// Mock the customer management functions
|
|
vi.mock('../customer-management.server', () => ({
|
|
getCustomers: vi.fn(),
|
|
createCustomer: vi.fn(),
|
|
updateCustomer: vi.fn(),
|
|
deleteCustomer: vi.fn(),
|
|
getCustomerById: vi.fn(),
|
|
}));
|
|
|
|
// Mock validation
|
|
vi.mock('../validation', () => ({
|
|
validateCustomer: vi.fn(),
|
|
}));
|
|
|
|
import { loader, action } from '../../routes/customers';
|
|
import { getCustomers, createCustomer, updateCustomer, deleteCustomer } from '../customer-management.server';
|
|
import { validateCustomer } from '../validation';
|
|
|
|
const mockGetCustomers = getCustomers as any;
|
|
const mockCreateCustomer = createCustomer as any;
|
|
const mockUpdateCustomer = updateCustomer as any;
|
|
const mockDeleteCustomer = deleteCustomer as any;
|
|
const mockValidateCustomer = validateCustomer as any;
|
|
|
|
describe('Customer Routes Integration', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('loader', () => {
|
|
it('should load customers with default pagination', async () => {
|
|
const mockCustomers = [
|
|
{
|
|
id: 1,
|
|
name: 'أحمد محمد',
|
|
phone: '0501234567',
|
|
email: 'ahmed@example.com',
|
|
address: 'الرياض',
|
|
createdDate: new Date(),
|
|
updateDate: new Date(),
|
|
vehicles: [],
|
|
maintenanceVisits: [],
|
|
},
|
|
];
|
|
|
|
mockGetCustomers.mockResolvedValue({
|
|
customers: mockCustomers,
|
|
total: 1,
|
|
totalPages: 1,
|
|
});
|
|
|
|
const request = new Request('http://localhost:3000/customers');
|
|
const response = await loader({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(mockGetCustomers).toHaveBeenCalledWith('', 1, 10);
|
|
expect(data.customers).toEqual(mockCustomers);
|
|
expect(data.total).toBe(1);
|
|
expect(data.totalPages).toBe(1);
|
|
expect(data.currentPage).toBe(1);
|
|
});
|
|
|
|
it('should handle search and pagination parameters', async () => {
|
|
mockGetCustomers.mockResolvedValue({
|
|
customers: [],
|
|
total: 0,
|
|
totalPages: 0,
|
|
});
|
|
|
|
const request = new Request('http://localhost:3000/customers?search=أحمد&page=2&limit=20');
|
|
await loader({ request, params: {}, context: {} });
|
|
|
|
expect(mockGetCustomers).toHaveBeenCalledWith('أحمد', 2, 20);
|
|
});
|
|
});
|
|
|
|
describe('action', () => {
|
|
it('should create customer successfully', async () => {
|
|
const mockCustomer = {
|
|
id: 1,
|
|
name: 'أحمد محمد',
|
|
phone: '0501234567',
|
|
email: 'ahmed@example.com',
|
|
address: 'الرياض',
|
|
createdDate: new Date(),
|
|
updateDate: new Date(),
|
|
};
|
|
|
|
mockValidateCustomer.mockReturnValue({
|
|
isValid: true,
|
|
errors: {},
|
|
});
|
|
|
|
mockCreateCustomer.mockResolvedValue({
|
|
success: true,
|
|
customer: mockCustomer,
|
|
});
|
|
|
|
const formData = new FormData();
|
|
formData.append('_action', 'create');
|
|
formData.append('name', 'أحمد محمد');
|
|
formData.append('phone', '0501234567');
|
|
formData.append('email', 'ahmed@example.com');
|
|
formData.append('address', 'الرياض');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(mockValidateCustomer).toHaveBeenCalledWith({
|
|
name: 'أحمد محمد',
|
|
phone: '0501234567',
|
|
email: 'ahmed@example.com',
|
|
address: 'الرياض',
|
|
});
|
|
|
|
expect(mockCreateCustomer).toHaveBeenCalledWith({
|
|
name: 'أحمد محمد',
|
|
phone: '0501234567',
|
|
email: 'ahmed@example.com',
|
|
address: 'الرياض',
|
|
});
|
|
|
|
expect(data.success).toBe(true);
|
|
expect(data.customer).toEqual(mockCustomer);
|
|
expect(data.action).toBe('create');
|
|
expect(data.message).toBe('تم إنشاء العميل بنجاح');
|
|
});
|
|
|
|
it('should return validation errors for invalid data', async () => {
|
|
mockValidateCustomer.mockReturnValue({
|
|
isValid: false,
|
|
errors: {
|
|
name: 'اسم العميل مطلوب',
|
|
email: 'البريد الإلكتروني غير صحيح',
|
|
},
|
|
});
|
|
|
|
const formData = new FormData();
|
|
formData.append('_action', 'create');
|
|
formData.append('name', '');
|
|
formData.append('email', 'invalid-email');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(data.success).toBe(false);
|
|
expect(data.errors).toEqual({
|
|
name: 'اسم العميل مطلوب',
|
|
email: 'البريد الإلكتروني غير صحيح',
|
|
});
|
|
expect(mockCreateCustomer).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('should update customer successfully', async () => {
|
|
const mockCustomer = {
|
|
id: 1,
|
|
name: 'أحمد محمد المحدث',
|
|
phone: '0509876543',
|
|
email: 'ahmed.updated@example.com',
|
|
address: 'جدة',
|
|
createdDate: new Date(),
|
|
updateDate: new Date(),
|
|
};
|
|
|
|
mockValidateCustomer.mockReturnValue({
|
|
isValid: true,
|
|
errors: {},
|
|
});
|
|
|
|
mockUpdateCustomer.mockResolvedValue({
|
|
success: true,
|
|
customer: mockCustomer,
|
|
});
|
|
|
|
const formData = new FormData();
|
|
formData.append('_action', 'update');
|
|
formData.append('id', '1');
|
|
formData.append('name', 'أحمد محمد المحدث');
|
|
formData.append('phone', '0509876543');
|
|
formData.append('email', 'ahmed.updated@example.com');
|
|
formData.append('address', 'جدة');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(mockUpdateCustomer).toHaveBeenCalledWith(1, {
|
|
name: 'أحمد محمد المحدث',
|
|
phone: '0509876543',
|
|
email: 'ahmed.updated@example.com',
|
|
address: 'جدة',
|
|
});
|
|
|
|
expect(data.success).toBe(true);
|
|
expect(data.customer).toEqual(mockCustomer);
|
|
expect(data.action).toBe('update');
|
|
expect(data.message).toBe('تم تحديث العميل بنجاح');
|
|
});
|
|
|
|
it('should delete customer successfully', async () => {
|
|
mockDeleteCustomer.mockResolvedValue({
|
|
success: true,
|
|
});
|
|
|
|
const formData = new FormData();
|
|
formData.append('_action', 'delete');
|
|
formData.append('id', '1');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(mockDeleteCustomer).toHaveBeenCalledWith(1);
|
|
expect(data.success).toBe(true);
|
|
expect(data.action).toBe('delete');
|
|
expect(data.message).toBe('تم حذف العميل بنجاح');
|
|
});
|
|
|
|
it('should handle delete errors', async () => {
|
|
mockDeleteCustomer.mockResolvedValue({
|
|
success: false,
|
|
error: 'لا يمكن حذف العميل لأنه يملك مركبات',
|
|
});
|
|
|
|
const formData = new FormData();
|
|
formData.append('_action', 'delete');
|
|
formData.append('id', '1');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(data.success).toBe(false);
|
|
expect(data.error).toBe('لا يمكن حذف العميل لأنه يملك مركبات');
|
|
});
|
|
|
|
it('should handle unknown action', async () => {
|
|
const formData = new FormData();
|
|
formData.append('_action', 'unknown');
|
|
|
|
const request = new Request('http://localhost:3000/customers', {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
|
|
const response = await action({ request, params: {}, context: {} });
|
|
const data = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(data.success).toBe(false);
|
|
expect(data.error).toBe('إجراء غير صحيح');
|
|
expect(data.action).toBe('unknown');
|
|
});
|
|
});
|
|
}); |