debuts de tests unitaires
This commit is contained in:
10
src/__tests__/basic.test.ts
Normal file
10
src/__tests__/basic.test.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
describe('Basic Test', () => {
|
||||
it('should work', () => {
|
||||
expect(1 + 1).toBe(2);
|
||||
});
|
||||
|
||||
it('should handle async operations', async () => {
|
||||
const result = await Promise.resolve('test');
|
||||
expect(result).toBe('test');
|
||||
});
|
||||
});
|
||||
120
src/__tests__/lib/utils-simple.test.ts
Normal file
120
src/__tests__/lib/utils-simple.test.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
// Tests simples pour les utilitaires de base
|
||||
describe('Basic Utils', () => {
|
||||
describe('String utilities', () => {
|
||||
it('should validate email correctly', () => {
|
||||
const validateEmail = (email: string): boolean => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
expect(validateEmail('test@example.com')).toBe(true);
|
||||
expect(validateEmail('invalid-email')).toBe(false);
|
||||
expect(validateEmail('')).toBe(false);
|
||||
});
|
||||
|
||||
it('should validate required fields', () => {
|
||||
const validateRequired = (value: any): boolean => {
|
||||
return value !== null && value !== undefined && value !== '';
|
||||
};
|
||||
|
||||
expect(validateRequired('test')).toBe(true);
|
||||
expect(validateRequired('')).toBe(false);
|
||||
expect(validateRequired(null)).toBe(false);
|
||||
expect(validateRequired(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it('should format currency', () => {
|
||||
const formatCurrency = (amount: number, currency = '€'): string => {
|
||||
return `${amount} ${currency}`;
|
||||
};
|
||||
|
||||
expect(formatCurrency(100)).toBe('100 €');
|
||||
expect(formatCurrency(0)).toBe('0 €');
|
||||
expect(formatCurrency(1234.56)).toBe('1234.56 €');
|
||||
});
|
||||
|
||||
it('should generate slug from title', () => {
|
||||
const generateSlug = (title: string): string => {
|
||||
return title
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\s-]/g, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.trim();
|
||||
};
|
||||
|
||||
expect(generateSlug('Test Campaign')).toBe('test-campaign');
|
||||
expect(generateSlug('Campagne avec des accents')).toBe('campagne-avec-des-accents');
|
||||
expect(generateSlug('Campaign with UPPERCASE')).toBe('campaign-with-uppercase');
|
||||
});
|
||||
|
||||
it('should parse spending tiers', () => {
|
||||
const parseSpendingTiers = (tiers: string): number[] => {
|
||||
if (!tiers) return [];
|
||||
return tiers.split(',').map(tier => parseInt(tier.trim())).filter(tier => !isNaN(tier));
|
||||
};
|
||||
|
||||
expect(parseSpendingTiers('10,25,50,100')).toEqual([10, 25, 50, 100]);
|
||||
expect(parseSpendingTiers('5,10,20')).toEqual([5, 10, 20]);
|
||||
expect(parseSpendingTiers('100')).toEqual([100]);
|
||||
expect(parseSpendingTiers('')).toEqual([]);
|
||||
});
|
||||
|
||||
it('should validate spending tiers', () => {
|
||||
const validateSpendingTiers = (tiers: string): boolean => {
|
||||
const parsed = tiers.split(',').map(tier => parseInt(tier.trim()));
|
||||
if (parsed.some(tier => isNaN(tier) || tier <= 0)) return false;
|
||||
for (let i = 1; i < parsed.length; i++) {
|
||||
if (parsed[i] <= parsed[i - 1]) return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
expect(validateSpendingTiers('10,25,50,100')).toBe(true);
|
||||
expect(validateSpendingTiers('5,10,20')).toBe(true);
|
||||
expect(validateSpendingTiers('50,25,100')).toBe(false); // Not ascending
|
||||
expect(validateSpendingTiers('10,invalid,50')).toBe(false); // Invalid number
|
||||
});
|
||||
|
||||
it('should sanitize HTML content', () => {
|
||||
const sanitizeHtml = (html: string): string => {
|
||||
// Simple sanitization - remove script tags
|
||||
return html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
||||
};
|
||||
|
||||
const dirtyHtml = '<script>alert("xss")</script><p>Hello <strong>World</strong></p>';
|
||||
const cleanHtml = sanitizeHtml(dirtyHtml);
|
||||
|
||||
expect(cleanHtml).not.toContain('<script>');
|
||||
expect(cleanHtml).toContain('<p>');
|
||||
expect(cleanHtml).toContain('<strong>');
|
||||
});
|
||||
|
||||
it('should debounce function calls', () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
const debounce = (func: Function, delay: number) => {
|
||||
let timeoutId: NodeJS.Timeout;
|
||||
return (...args: any[]) => {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => func.apply(null, args), delay);
|
||||
};
|
||||
};
|
||||
|
||||
const mockFn = jest.fn();
|
||||
const debouncedFn = debounce(mockFn, 300);
|
||||
|
||||
debouncedFn();
|
||||
debouncedFn();
|
||||
debouncedFn();
|
||||
|
||||
expect(mockFn).not.toHaveBeenCalled();
|
||||
|
||||
jest.advanceTimersByTime(300);
|
||||
|
||||
expect(mockFn).toHaveBeenCalledTimes(1);
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
});
|
||||
61
src/__tests__/utils/test-utils.tsx
Normal file
61
src/__tests__/utils/test-utils.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React, { ReactElement } from 'react';
|
||||
import { render, RenderOptions } from '@testing-library/react';
|
||||
|
||||
// Mock data pour les tests
|
||||
export const mockCampaign = {
|
||||
id: 'test-campaign-id',
|
||||
title: 'Test Campaign',
|
||||
description: 'Test campaign description',
|
||||
status: 'deposit' as const,
|
||||
budget_per_user: 100,
|
||||
spending_tiers: '10,25,50,100',
|
||||
slug: 'test-campaign',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
};
|
||||
|
||||
export const mockParticipant = {
|
||||
id: 'test-participant-id',
|
||||
campaign_id: 'test-campaign-id',
|
||||
first_name: 'John',
|
||||
last_name: 'Doe',
|
||||
email: 'john.doe@example.com',
|
||||
short_id: 'abc123',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
};
|
||||
|
||||
export const mockProposition = {
|
||||
id: 'test-proposition-id',
|
||||
campaign_id: 'test-campaign-id',
|
||||
title: 'Test Proposition',
|
||||
description: 'Test proposition description',
|
||||
author_first_name: 'Jane',
|
||||
author_last_name: 'Smith',
|
||||
author_email: 'jane.smith@example.com',
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
};
|
||||
|
||||
export const mockVote = {
|
||||
id: 'test-vote-id',
|
||||
campaign_id: 'test-campaign-id',
|
||||
participant_id: 'test-participant-id',
|
||||
proposition_id: 'test-proposition-id',
|
||||
amount: 50,
|
||||
created_at: '2024-01-01T00:00:00Z',
|
||||
updated_at: '2024-01-01T00:00:00Z',
|
||||
};
|
||||
|
||||
// Wrapper pour les tests avec providers
|
||||
const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
// Custom render function avec providers
|
||||
const customRender = (
|
||||
ui: ReactElement,
|
||||
options?: Omit<RenderOptions, 'wrapper'>
|
||||
) => render(ui, { wrapper: AllTheProviders, ...options });
|
||||
|
||||
// Re-export everything
|
||||
export * from '@testing-library/react';
|
||||
export { customRender as render };
|
||||
Reference in New Issue
Block a user