Reviewed-on: #20 Co-authored-by: hreyes <hreyes@aduanasoft.com.mx> Co-committed-by: hreyes <hreyes@aduanasoft.com.mx>
114 lines
4.5 KiB
TypeScript
114 lines
4.5 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
INSTALL_PHASE_STARTING,
|
|
INSTALL_STEP_LABEL,
|
|
INSTALL_STEP_SEQUENCE,
|
|
currentPhaseLabel,
|
|
expectedStepCount,
|
|
formatElapsed,
|
|
progressPercent,
|
|
type InstallStepView
|
|
} from './cras-install-progress';
|
|
|
|
function step(name: string, ok = true): InstallStepView {
|
|
return { step: name, at: '2026-07-29T20:00:00.000Z', ok };
|
|
}
|
|
|
|
describe('currentPhaseLabel', () => {
|
|
it('sin pasos anuncia la apertura de la instalación', () => {
|
|
expect(currentPhaseLabel([])).toBe(INSTALL_PHASE_STARTING);
|
|
});
|
|
|
|
it('traduce el último paso a la fase que sigue en curso, no a "terminado"', () => {
|
|
// El caso que reportó el operador: `subir-artefacto` se persiste ANTES del fastPut de
|
|
// ~270 MB, así que un ✓ en ese paso significa "empezó la subida".
|
|
expect(currentPhaseLabel([step('preparar-artefacto'), step('subir-artefacto')])).toBe(
|
|
'Subiendo el artefacto por SFTP…'
|
|
);
|
|
expect(currentPhaseLabel([step('preparar-artefacto')])).toBe(
|
|
'Descargando de Gitea y verificando sha256…'
|
|
);
|
|
expect(currentPhaseLabel([step('ejecutar-instalador')])).toBe(
|
|
'Corriendo el instalador en el servidor…'
|
|
);
|
|
});
|
|
|
|
it('un paso fallido es el desenlace, no una fase en curso', () => {
|
|
expect(currentPhaseLabel([step('precondiciones'), step('error', false)])).toBe('Error');
|
|
expect(currentPhaseLabel([step('subir-artefacto', false)])).toBe('Subir artefacto por SFTP');
|
|
});
|
|
|
|
it('un paso desconocido no rompe la fila viva', () => {
|
|
expect(currentPhaseLabel([step('paso-nuevo-del-instalador')])).toBe('Trabajando…');
|
|
});
|
|
});
|
|
|
|
describe('expectedStepCount', () => {
|
|
it('cuenta verificar-servicio solo en los modos que dejan algo arrancado', () => {
|
|
// `cras-install.ts` corta antes de ese paso cuando el modo no arranca nada.
|
|
expect(expectedStepCount('service')).toBe(11);
|
|
expect(expectedStepCount('desktop')).toBe(10);
|
|
expect(expectedStepCount('none')).toBe(10);
|
|
});
|
|
|
|
it('el servicio de usuario también verifica, aunque no use privilegios', () => {
|
|
// Si esto se quedara comparando solo con 'service', la barra de una instalación sin
|
|
// privilegios llegaría al 100 % con un paso todavía por delante.
|
|
expect(expectedStepCount('user-service')).toBe(11);
|
|
expect(progressPercent(10, 'user-service', 'running')).toBe(91);
|
|
});
|
|
});
|
|
|
|
describe('progressPercent', () => {
|
|
it('nunca llega a 100 mientras el run sigue corriendo', () => {
|
|
expect(progressPercent(11, 'service', 'running')).toBe(95);
|
|
expect(progressPercent(50, 'service', 'running')).toBe(95);
|
|
});
|
|
|
|
it('100 solo cuando el backend cerró el run como completado', () => {
|
|
expect(progressPercent(11, 'service', 'completed')).toBe(100);
|
|
expect(progressPercent(0, 'service', 'completed')).toBe(100);
|
|
});
|
|
|
|
it('escala con los pasos emitidos y el denominador del modo de arranque', () => {
|
|
expect(progressPercent(0, 'service', 'running')).toBe(0);
|
|
expect(progressPercent(5, 'none', 'running')).toBe(50);
|
|
// Mismo conteo de pasos, denominador distinto: 6/11 vs 6/10.
|
|
expect(progressPercent(6, 'service', 'running')).toBe(55);
|
|
expect(progressPercent(6, 'none', 'running')).toBe(60);
|
|
});
|
|
|
|
it('un run fallido conserva el avance parcial en lugar de saltar a 100', () => {
|
|
expect(progressPercent(3, 'service', 'failed')).toBe(27);
|
|
});
|
|
});
|
|
|
|
describe('formatElapsed', () => {
|
|
it('formatea mm:ss y h:mm:ss', () => {
|
|
expect(formatElapsed(0)).toBe('00:00');
|
|
expect(formatElapsed(65_000)).toBe('01:05');
|
|
expect(formatElapsed(599_000)).toBe('09:59');
|
|
expect(formatElapsed(3_725_000)).toBe('1:02:05');
|
|
});
|
|
|
|
it('un reloj desfasado no produce tiempos negativos', () => {
|
|
expect(formatElapsed(-5_000)).toBe('00:00');
|
|
});
|
|
});
|
|
|
|
describe('cobertura de las etiquetas', () => {
|
|
it('todo paso del camino feliz tiene etiqueta y fase siguiente', () => {
|
|
for (const name of INSTALL_STEP_SEQUENCE) {
|
|
expect(INSTALL_STEP_LABEL[name], `falta etiqueta de ${name}`).toBeTruthy();
|
|
expect(currentPhaseLabel([step(name)]), `falta fase de ${name}`).not.toBe(
|
|
'Trabajando…'
|
|
);
|
|
}
|
|
});
|
|
|
|
it('los pasos fuera del camino feliz también tienen etiqueta', () => {
|
|
expect(INSTALL_STEP_LABEL['limpiar-staging']).toBeTruthy();
|
|
expect(INSTALL_STEP_LABEL.error).toBeTruthy();
|
|
});
|
|
});
|