🎓 Initial commit: Math2 Platform - Plataforma de Álgebra Lineal PRO
✨ Características: - 45 ejercicios universitarios (Basic → Advanced) - Renderizado LaTeX profesional - IA generativa (Z.ai/DashScope) - Docker 9 servicios - Tests 123/123 pasando - Seguridad enterprise (JWT, XSS, Rate limiting) 🐳 Infraestructura: - Next.js 14 + Node.js 20 - PostgreSQL 15 + Redis 7 - Docker Compose completo - Nginx + SSL ready 📚 Documentación: - 5 informes técnicos completos - README profesional - Scripts de deployment automatizados Estado: Producción lista ✅
This commit is contained in:
250
backend/tests/system-config.test.ts
Normal file
250
backend/tests/system-config.test.ts
Normal file
@@ -0,0 +1,250 @@
|
||||
/**
|
||||
* System Config Service Tests
|
||||
*
|
||||
* Unit tests for SystemConfigService
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { SystemConfigService } from '../src/modules/system-config/system-config.service';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
const service = new SystemConfigService(prisma);
|
||||
|
||||
describe('SystemConfigService', () => {
|
||||
beforeAll(async () => {
|
||||
// Clean up test configs
|
||||
await prisma.systemConfig.deleteMany({
|
||||
where: { key: { startsWith: 'test.' } },
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// Clean up after tests
|
||||
await prisma.systemConfig.deleteMany({
|
||||
where: { key: { startsWith: 'test.' } },
|
||||
});
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
|
||||
describe('upsert', () => {
|
||||
it('should create a new config', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.create',
|
||||
value: 'test-value',
|
||||
category: 'platform',
|
||||
dataType: 'string',
|
||||
});
|
||||
|
||||
const value = await service.get('test.create');
|
||||
expect(value).toBe('test-value');
|
||||
});
|
||||
|
||||
it('should update existing config', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.update',
|
||||
value: 'original',
|
||||
category: 'platform',
|
||||
});
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.update',
|
||||
value: 'updated',
|
||||
category: 'platform',
|
||||
});
|
||||
|
||||
const value = await service.get('test.update');
|
||||
expect(value).toBe('updated');
|
||||
});
|
||||
|
||||
it('should track change history', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.history',
|
||||
value: 'v1',
|
||||
category: 'platform',
|
||||
}, 'user-1');
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.history',
|
||||
value: 'v2',
|
||||
category: 'platform',
|
||||
}, 'user-2');
|
||||
|
||||
const history = await service.getChangeHistory('test.history');
|
||||
expect(history).toHaveLength(1);
|
||||
expect(history[0].value).toBe('v1');
|
||||
expect(history[0].user).toBe('user-1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getParsed', () => {
|
||||
it('should parse boolean values', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.bool.true',
|
||||
value: 'true',
|
||||
category: 'platform',
|
||||
dataType: 'boolean',
|
||||
});
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.bool.false',
|
||||
value: 'false',
|
||||
category: 'platform',
|
||||
dataType: 'boolean',
|
||||
});
|
||||
|
||||
expect(await service.getParsed('test.bool.true')).toBe(true);
|
||||
expect(await service.getParsed('test.bool.false')).toBe(false);
|
||||
});
|
||||
|
||||
it('should parse number values', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.number',
|
||||
value: '42.5',
|
||||
category: 'platform',
|
||||
dataType: 'number',
|
||||
});
|
||||
|
||||
const value = await service.getParsed('test.number');
|
||||
expect(value).toBe(42.5);
|
||||
});
|
||||
|
||||
it('should parse json values', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.json',
|
||||
value: '{"key": "value", "num": 123}',
|
||||
category: 'platform',
|
||||
dataType: 'json',
|
||||
});
|
||||
|
||||
const value = await service.getParsed('test.json');
|
||||
expect(value).toEqual({ key: 'value', num: 123 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('getByCategory', () => {
|
||||
it('should filter by category', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.cat.platform',
|
||||
value: '1',
|
||||
category: 'platform',
|
||||
isPublic: true,
|
||||
});
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.cat.ai',
|
||||
value: '2',
|
||||
category: 'ai',
|
||||
isPublic: true,
|
||||
});
|
||||
|
||||
const platformConfigs = await service.getByCategory('platform');
|
||||
expect(platformConfigs.some(c => c.key === 'test.cat.platform')).toBe(true);
|
||||
expect(platformConfigs.some(c => c.key === 'test.cat.ai')).toBe(false);
|
||||
});
|
||||
|
||||
it('should filter public/private configs', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.public',
|
||||
value: 'public',
|
||||
category: 'platform',
|
||||
isPublic: true,
|
||||
});
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.private',
|
||||
value: 'private',
|
||||
category: 'platform',
|
||||
isPublic: false,
|
||||
});
|
||||
|
||||
const publicConfigs = await service.getByCategory('platform');
|
||||
expect(publicConfigs.some(c => c.key === 'test.public')).toBe(true);
|
||||
expect(publicConfigs.some(c => c.key === 'test.private')).toBe(false);
|
||||
|
||||
const allConfigs = await service.getByCategory('platform', true);
|
||||
expect(allConfigs.some(c => c.key === 'test.private')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPublicConfigs', () => {
|
||||
it('should return only public configs', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.public.all',
|
||||
value: 'visible',
|
||||
category: 'platform',
|
||||
isPublic: true,
|
||||
});
|
||||
|
||||
await service.upsert({
|
||||
key: 'test.private.all',
|
||||
value: 'hidden',
|
||||
category: 'platform',
|
||||
isPublic: false,
|
||||
});
|
||||
|
||||
const configs = await service.getPublicConfigs();
|
||||
expect(configs.some(c => c.key === 'test.public.all')).toBe(true);
|
||||
expect(configs.some(c => c.key === 'test.private.all')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateValue', () => {
|
||||
it('should update only the value', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.update.value',
|
||||
value: 'original',
|
||||
description: 'Original description',
|
||||
category: 'platform',
|
||||
});
|
||||
|
||||
await service.updateValue('test.update.value', 'new-value', 'admin-1');
|
||||
|
||||
const config = await prisma.systemConfig.findUnique({
|
||||
where: { key: 'test.update.value' },
|
||||
});
|
||||
|
||||
expect(config?.value).toBe('new-value');
|
||||
expect(config?.description).toBe('Original description');
|
||||
expect(config?.category).toBe('platform');
|
||||
});
|
||||
|
||||
it('should throw error for non-existent key', async () => {
|
||||
await expect(
|
||||
service.updateValue('test.nonexistent', 'value')
|
||||
).rejects.toThrow("Config with key 'test.nonexistent' not found");
|
||||
});
|
||||
});
|
||||
|
||||
describe('delete', () => {
|
||||
it('should delete config', async () => {
|
||||
await service.upsert({
|
||||
key: 'test.delete',
|
||||
value: 'to-delete',
|
||||
category: 'platform',
|
||||
});
|
||||
|
||||
await service.delete('test.delete');
|
||||
|
||||
const value = await service.get('test.delete');
|
||||
expect(value).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseValue', () => {
|
||||
it('should parse different data types correctly', () => {
|
||||
expect(service.parseValue('123', 'number')).toBe(123);
|
||||
expect(service.parseValue('45.67', 'number')).toBe(45.67);
|
||||
expect(service.parseValue('true', 'boolean')).toBe(true);
|
||||
expect(service.parseValue('1', 'boolean')).toBe(true);
|
||||
expect(service.parseValue('false', 'boolean')).toBe(false);
|
||||
expect(service.parseValue('{"a":1}', 'json')).toEqual({ a: 1 });
|
||||
expect(service.parseValue('2024-01-01', 'date')).toEqual(new Date('2024-01-01'));
|
||||
expect(service.parseValue('plain string', 'string')).toBe('plain string');
|
||||
});
|
||||
|
||||
it('should handle invalid json gracefully', () => {
|
||||
expect(service.parseValue('invalid json', 'json')).toBe('invalid json');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user