back(test): specs validation env + DTO upload (48 -> 59 tests)
- env.validation.spec : config valide/coercion/défauts + rejets (var manquante, port hors plage, NODE_ENV inconnu) - create-api-upload.dto.spec : name requis, emails @ValidateIf (vides OK, invalides rejetés), énum convention, MaxLength - vitest-setup charge reflect-metadata (décorateurs class-validator en test) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
33
back/src/config/env.validation.spec.ts
Normal file
33
back/src/config/env.validation.spec.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { validateEnv } from './env.validation';
|
||||||
|
|
||||||
|
const base = {
|
||||||
|
DATABASE_HOST: 'localhost',
|
||||||
|
DATABASE_PORT: '5432',
|
||||||
|
DATABASE_USER: 'datacat',
|
||||||
|
DATABASE_PASSWORD: 'datacat',
|
||||||
|
DATABASE_NAME: 'datacat',
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('validateEnv', () => {
|
||||||
|
it('accepte une config valide, coerce le port et applique les défauts', () => {
|
||||||
|
const cfg = validateEnv({ ...base });
|
||||||
|
expect(cfg.DATABASE_PORT).toBe(5432);
|
||||||
|
expect(typeof cfg.DATABASE_PORT).toBe('number');
|
||||||
|
expect(cfg.NODE_ENV).toBe('development');
|
||||||
|
expect(cfg.PORT).toBe(3000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette une variable requise manquante (message explicite)', () => {
|
||||||
|
const { DATABASE_HOST: _omit, ...rest } = base;
|
||||||
|
expect(() => validateEnv(rest)).toThrow(/DATABASE_HOST/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette un port hors plage', () => {
|
||||||
|
expect(() => validateEnv({ ...base, DATABASE_PORT: '70000' })).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette un NODE_ENV inconnu', () => {
|
||||||
|
expect(() => validateEnv({ ...base, NODE_ENV: 'staging' })).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
49
back/src/modules/uploads/dto/create-api-upload.dto.spec.ts
Normal file
49
back/src/modules/uploads/dto/create-api-upload.dto.spec.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
import { plainToInstance } from 'class-transformer';
|
||||||
|
import { validateSync } from 'class-validator';
|
||||||
|
import { CreateApiUploadDto } from './create-api-upload.dto';
|
||||||
|
|
||||||
|
function validate(payload: Record<string, unknown>) {
|
||||||
|
const dto = plainToInstance(CreateApiUploadDto, payload, { enableImplicitConversion: true });
|
||||||
|
return validateSync(dto, { whitelist: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('CreateApiUploadDto', () => {
|
||||||
|
it('accepte un payload minimal (name seul requis)', () => {
|
||||||
|
expect(validate({ name: 'Mon API' })).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette un name manquant', () => {
|
||||||
|
expect(validate({}).some((e) => e.property === 'name')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepte des emails de contact vides (@ValidateIf)', () => {
|
||||||
|
expect(
|
||||||
|
validate({ name: 'X', contactFunctionalEmail: '', contactTechnicalEmail: '' }),
|
||||||
|
).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette un email renseigné mais invalide', () => {
|
||||||
|
expect(
|
||||||
|
validate({ name: 'X', contactFunctionalEmail: 'pas-un-email' }).some(
|
||||||
|
(e) => e.property === 'contactFunctionalEmail',
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepte un email valide', () => {
|
||||||
|
expect(validate({ name: 'X', contactFunctionalEmail: 'a@b.fr' })).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette une convention hors énumération', () => {
|
||||||
|
expect(
|
||||||
|
validate({ name: 'X', convention: 'FOO' }).some((e) => e.property === 'convention'),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejette un name trop long (>255)', () => {
|
||||||
|
expect(
|
||||||
|
validate({ name: 'a'.repeat(256) }).some((e) => e.property === 'name'),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
3
back/vitest-setup.ts
Normal file
3
back/vitest-setup.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// Requis pour que les décorateurs class-validator / class-transformer
|
||||||
|
// (Reflect.getMetadata) fonctionnent dans les tests, comme dans l'app (main.ts).
|
||||||
|
import 'reflect-metadata';
|
||||||
@@ -4,6 +4,7 @@ export default defineConfig({
|
|||||||
test: {
|
test: {
|
||||||
globals: true,
|
globals: true,
|
||||||
environment: 'node',
|
environment: 'node',
|
||||||
|
setupFiles: ['./vitest-setup.ts'],
|
||||||
include: ['src/**/*.spec.ts'],
|
include: ['src/**/*.spec.ts'],
|
||||||
coverage: {
|
coverage: {
|
||||||
provider: 'v8',
|
provider: 'v8',
|
||||||
|
|||||||
Reference in New Issue
Block a user