process.env.DATABASE_PATH = ':memory:'; process.env.THEMES_DIR = './themes'; process.env.FRONTEND_DIST = './frontend/dist'; import { coerceSystemError, destructiveCopy, deriveBackupFilename, friendlySystemErrorMessage, } from '../../frontend/src/app/features/admin/system/system.pure'; describe('Job 871: friendlySystemErrorMessage mapping', () => { it('returns the friendly token-expired message for SYSTEM_TOKEN_EXPIRED', () => { const err = { status: 400, code: 'SYSTEM_TOKEN_EXPIRED', message: 'expired' }; expect(friendlySystemErrorMessage('restore-backup', err)).toContain('expired'); expect(friendlySystemErrorMessage('restore-backup', err)).toMatch(/Re-authenticate/i); }); it('returns a specific message for SYSTEM_RESTORE_ROLLED_BACK', () => { expect(friendlySystemErrorMessage('restore-backup', { status: 500, code: 'SYSTEM_RESTORE_ROLLED_BACK', message: 'rb' })) .toContain('rolled back'); }); it('falls back to operation message when code is unknown', () => { expect(friendlySystemErrorMessage('wipe-challenges', { status: 500, code: 'WEIRD', message: 'broken' })) .toBe('broken'); }); it('falls back to the operation default when message is empty', () => { expect(friendlySystemErrorMessage('reset-scores', { status: 500, code: 'WEIRD', message: '' })) .toContain('Reset scores failed'); }); }); describe('Job 871: destructiveCopy', () => { it('reset-scores confirms with RESET SCORES', () => { expect(destructiveCopy('reset-scores').confirmation).toBe('RESET SCORES'); }); it('wipe-challenges confirms with WIPE CHALLENGES', () => { expect(destructiveCopy('wipe-challenges').confirmation).toBe('WIPE CHALLENGES'); }); it('restore-backup confirms with RESTORE BACKUP', () => { expect(destructiveCopy('restore-backup').confirmation).toBe('RESTORE BACKUP'); }); }); describe('Job 871: deriveBackupFilename', () => { it('contains today date and .json', () => { const name = deriveBackupFilename(); expect(name).toMatch(/^hipctf-backup-\d{4}-\d{2}-\d{2}\.json$/); }); }); describe('Job 871: coerceSystemError', () => { it('reads body from HttpErrorResponse shape', () => { const out = coerceSystemError( { status: 400, error: { code: 'X', message: 'Y' } }, 'fallback', ); expect(out.code).toBe('X'); expect(out.message).toBe('Y'); expect(out.status).toBe(400); }); it('falls back when no envelope is present', () => { const out = coerceSystemError(new Error('boom'), 'fallback'); expect(out.code).toBe('INTERNAL'); expect(out.message).toBe('boom'); }); it('falls back for null', () => { const out = coerceSystemError(null, 'fallback'); expect(out.code).toBe('INTERNAL'); expect(out.message).toBe('fallback'); }); });