Files
PANEL_BASES_ANEXO24/src/lib/server/mssql-nodes.test.ts
AlexeerCT 7f9d502cb1
Some checks failed
Aduanasoft/PANEL_BASES_ANEXO24/pipeline/head There was a failure building this commit
feat(env): update environment configuration and add SQL Server password handling (#15)
- Added new environment variables for deduplication and SQL Server password encryption.
- Updated docker-compose files to include SECRET_KEY and ENCRYPTION_KEY for compatibility with a24c.
- Enhanced the navigation structure to reflect changes in admin-only views and report access.
- Introduced new functions for handling SQL Server connections and database management, including parsing server addresses and listing user databases.

This update improves security and functionality related to database management and user access control.

Reviewed-on: #15
Co-authored-by: AlexeerCT <acazares@aduanasoft.com.mx>
Co-committed-by: AlexeerCT <acazares@aduanasoft.com.mx>
2026-07-06 17:00:49 +00:00

87 lines
3.4 KiB
TypeScript

/**
* Pruebas de resolveNodeSqlPassword: la columna database_nodes.sql_password se autorrellena
* al asignar un restaurador copiando su sobre cifrado (gcm:), así que al resolverla hay que
* descifrarla. Cubre: sin valor → global, texto plano legado, sobre gcm: descifrado, y
* descifrado que falla → global (no debe tumbar el dashboard).
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { env } from '$env/dynamic/private';
// Se conserva el isEncrypted real (trivial: prefijo gcm:) y solo se controla el descifrado.
vi.mock('./crypto', async (importOriginal) => {
const actual = await importOriginal<typeof import('./crypto')>();
return { ...actual, decryptSecret: vi.fn() };
});
import { decryptSecret } from './crypto';
import { resolveNodeSqlPassword, parseMssqlServer } from './mssql-nodes';
const decryptMock = vi.mocked(decryptSecret);
beforeEach(() => {
vi.clearAllMocks();
env.PANEL_MSSQL_PASSWORD = 'GLOBAL_PWD';
});
describe('resolveNodeSqlPassword', () => {
it('sin valor (null/undefined/vacío/espacios) usa la contraseña global', () => {
expect(resolveNodeSqlPassword(null)).toBe('GLOBAL_PWD');
expect(resolveNodeSqlPassword(undefined)).toBe('GLOBAL_PWD');
expect(resolveNodeSqlPassword('')).toBe('GLOBAL_PWD');
expect(resolveNodeSqlPassword(' ')).toBe('GLOBAL_PWD');
expect(decryptMock).not.toHaveBeenCalled();
});
it('texto plano legado (sin prefijo gcm:) se usa tal cual y se recorta, sin descifrar', () => {
expect(resolveNodeSqlPassword(' MiPassPlano ')).toBe('MiPassPlano');
expect(decryptMock).not.toHaveBeenCalled();
});
it('sobre cifrado gcm: se descifra y devuelve el texto plano', () => {
decryptMock.mockReturnValue('SecretoDescifrado');
const envelope = 'gcm:aXY=:dGFn:Y2lwaGVy';
expect(resolveNodeSqlPassword(envelope)).toBe('SecretoDescifrado');
expect(decryptMock).toHaveBeenCalledWith(envelope);
});
it('si el descifrado falla (sobre corrupto o clave equivocada) cae a la global sin propagar el error', () => {
decryptMock.mockImplementation(() => {
throw new Error('autenticación GCM inválida');
});
expect(resolveNodeSqlPassword('gcm:corrupto')).toBe('GLOBAL_PWD');
expect(decryptMock).toHaveBeenCalledOnce();
});
});
describe('parseMssqlServer', () => {
it('host,puerto → server y port separados (evita el bug host,puerto:1433)', () => {
expect(parseMssqlServer('192.168.1.20,1433')).toEqual({
server: '192.168.1.20',
port: 1433
});
});
it('solo host → sin puerto (tedious usa 1433 por defecto)', () => {
expect(parseMssqlServer('SQLSERVER01')).toEqual({ server: 'SQLSERVER01' });
});
it('host\\instancia → instanceName', () => {
expect(parseMssqlServer('HOST\\SQLEXPRESS')).toEqual({
server: 'HOST',
instanceName: 'SQLEXPRESS'
});
});
it('host\\instancia,puerto → server, instanceName y port', () => {
expect(parseMssqlServer('HOST\\SQLEXPRESS,1450')).toEqual({
server: 'HOST',
port: 1450,
instanceName: 'SQLEXPRESS'
});
});
it('recorta espacios e ignora puerto no numérico', () => {
expect(parseMssqlServer(' 10.0.0.5 , abc ')).toEqual({ server: '10.0.0.5' });
});
});