the-tip-top-backend/test/unit/helpers.test.js
soufiane 614abeb196 test: add comprehensive unit and integration tests
Backend Tests Added:
- Unit tests for helpers.js (tokens, validation, pagination)
- Unit tests for middleware (auth, errorHandler, validate)
- Integration tests for auth endpoints
- Integration tests for game endpoints
- Integration tests for admin endpoints
- Integration tests for employee endpoints
- Integration tests for draw endpoints
- Integration tests for newsletter/contact endpoints

Also added:
- cross-env for Windows compatibility
- Test scripts update

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-27 11:23:43 +01:00

214 lines
6.3 KiB
JavaScript

/**
* Tests unitaires pour src/utils/helpers.js
*/
import {
generateToken,
generateJWT,
verifyJWT,
generateTicketCode,
isValidEmail,
isValidPhone,
cleanPhone,
formatDate,
maskEmail,
getTokenExpiry,
isExpired,
generateRandomPassword,
getPagination,
formatPaginatedResponse,
} from '../../src/utils/helpers.js';
describe('Helpers - Token Generation', () => {
describe('generateToken', () => {
it('should generate a token of default length 32', () => {
const token = generateToken();
expect(token).toHaveLength(64); // hex string is 2x the byte length
});
it('should generate a token of specified length', () => {
const token = generateToken(16);
expect(token).toHaveLength(32);
});
it('should generate unique tokens', () => {
const token1 = generateToken();
const token2 = generateToken();
expect(token1).not.toBe(token2);
});
});
describe('generateJWT', () => {
it('should generate a valid JWT token', () => {
const token = generateJWT(1, 'test@example.com', 'CLIENT');
expect(token).toBeDefined();
expect(typeof token).toBe('string');
expect(token.split('.')).toHaveLength(3);
});
});
describe('verifyJWT', () => {
it('should verify a valid JWT token', () => {
const token = generateJWT(1, 'test@example.com', 'CLIENT');
const decoded = verifyJWT(token);
expect(decoded).toBeDefined();
expect(decoded.userId).toBe(1);
expect(decoded.email).toBe('test@example.com');
expect(decoded.role).toBe('CLIENT');
});
it('should return null for invalid token', () => {
const decoded = verifyJWT('invalid-token');
expect(decoded).toBeNull();
});
});
});
describe('Helpers - Ticket Code Generation', () => {
describe('generateTicketCode', () => {
it('should generate a ticket code starting with TTP', () => {
const code = generateTicketCode();
expect(code).toMatch(/^TTP/);
});
it('should generate a 10-character code', () => {
const code = generateTicketCode();
expect(code).toHaveLength(10);
});
it('should include current year', () => {
const code = generateTicketCode();
const year = new Date().getFullYear().toString();
expect(code).toContain(year);
});
it('should generate unique codes', () => {
const codes = new Set();
for (let i = 0; i < 100; i++) {
codes.add(generateTicketCode());
}
expect(codes.size).toBe(100);
});
});
});
describe('Helpers - Validation', () => {
describe('isValidEmail', () => {
it('should return true for valid emails', () => {
expect(isValidEmail('test@example.com')).toBe(true);
expect(isValidEmail('user.name@domain.fr')).toBe(true);
expect(isValidEmail('user+tag@example.org')).toBe(true);
});
it('should return false for invalid emails', () => {
expect(isValidEmail('invalid')).toBe(false);
expect(isValidEmail('invalid@')).toBe(false);
expect(isValidEmail('@domain.com')).toBe(false);
expect(isValidEmail('')).toBe(false);
});
});
describe('isValidPhone', () => {
it('should return true for valid French phone numbers', () => {
expect(isValidPhone('0612345678')).toBe(true);
expect(isValidPhone('06 12 34 56 78')).toBe(true);
expect(isValidPhone('+33612345678')).toBe(true);
});
it('should return false for invalid phone numbers', () => {
expect(isValidPhone('123')).toBe(false);
expect(isValidPhone('')).toBe(false);
});
});
describe('cleanPhone', () => {
it('should remove spaces from phone number', () => {
expect(cleanPhone('06 12 34 56 78')).toBe('0612345678');
});
it('should handle already clean numbers', () => {
expect(cleanPhone('0612345678')).toBe('0612345678');
});
});
});
describe('Helpers - Date Functions', () => {
describe('formatDate', () => {
it('should format date to French locale', () => {
const date = new Date('2025-01-15');
const formatted = formatDate(date);
expect(formatted).toContain('2025');
});
});
describe('getTokenExpiry', () => {
it('should return a future date', () => {
const expiry = getTokenExpiry(24);
expect(new Date(expiry).getTime()).toBeGreaterThan(Date.now());
});
});
describe('isExpired', () => {
it('should return true for past dates', () => {
const pastDate = new Date('2020-01-01');
expect(isExpired(pastDate)).toBe(true);
});
it('should return false for future dates', () => {
const futureDate = new Date('2030-01-01');
expect(isExpired(futureDate)).toBe(false);
});
});
});
describe('Helpers - Security', () => {
describe('maskEmail', () => {
it('should mask the middle of email', () => {
const masked = maskEmail('john.doe@example.com');
expect(masked).toContain('***');
expect(masked).not.toBe('john.doe@example.com');
});
});
describe('generateRandomPassword', () => {
it('should generate password of specified length', () => {
const password = generateRandomPassword(12);
expect(password).toHaveLength(12);
});
it('should generate unique passwords', () => {
const p1 = generateRandomPassword(16);
const p2 = generateRandomPassword(16);
expect(p1).not.toBe(p2);
});
});
});
describe('Helpers - Pagination', () => {
describe('getPagination', () => {
it('should calculate correct offset', () => {
expect(getPagination(1, 10)).toEqual({ offset: 0, limit: 10 });
expect(getPagination(2, 10)).toEqual({ offset: 10, limit: 10 });
expect(getPagination(3, 20)).toEqual({ offset: 40, limit: 20 });
});
it('should handle default values', () => {
const result = getPagination();
expect(result.offset).toBeDefined();
expect(result.limit).toBeDefined();
});
});
describe('formatPaginatedResponse', () => {
it('should format paginated response correctly', () => {
const data = [{ id: 1 }, { id: 2 }];
const response = formatPaginatedResponse(data, 100, 1, 10);
expect(response.data).toEqual(data);
expect(response.pagination.total).toBe(100);
expect(response.pagination.page).toBe(1);
expect(response.pagination.limit).toBe(10);
expect(response.pagination.totalPages).toBe(10);
});
});
});