Files
HIPCTF2/tests/backend/admin-system-restore-commit.spec.ts
T

123 lines
4.6 KiB
TypeScript

process.env.DATABASE_PATH = ':memory:';
process.env.THEMES_DIR = './themes';
process.env.FRONTEND_DIST = './frontend/dist';
process.env.UPLOAD_SIZE_LIMIT = '5mb';
process.env.NODE_ENV = 'test';
import { ApiError } from '../../backend/src/common/errors/api-error';
import { ERROR_CODES } from '../../backend/src/common/errors/error-codes';
import type { ArgumentMetadata } from '@nestjs/common';
import { AdminSystemController } from '../../backend/src/modules/admin/system/admin-system.controller';
import { ZodValidationPipe } from '../../backend/src/common/pipes/zod-validation.pipe';
import { AdminRestoreCommitBodySchema } from '../../backend/src/modules/admin/system/dto/admin-system.dto';
describe('Job 916: Admin restore commit body passes stagingId through', () => {
function makeController(opts: {
commitRestore: jest.Mock;
consume?: jest.Mock;
}) {
const consume = opts.consume ?? jest.fn().mockResolvedValue({ id: 'tok' });
const reauthenticateAdmin = jest.fn().mockResolvedValue({ id: 'admin-1' });
const revokeAllRefreshSessions = jest.fn().mockResolvedValue(undefined);
const issue = jest.fn().mockResolvedValue({ token: 't', expiresAt: 'x', id: 'i' });
const resetScores = jest.fn();
const wipeChallenges = jest.fn();
return {
controller: new AdminSystemController(
{ build: jest.fn() } as any,
{ stageArchive: jest.fn(), commitRestore: opts.commitRestore } as any,
{ resetScores, wipeChallenges } as any,
{ consume, issue } as any,
{ reauthenticateAdmin, revokeAllRefreshSessions } as any,
),
consume,
commitRestore: opts.commitRestore,
issue,
reauthenticateAdmin,
revokeAllRefreshSessions,
};
}
function adminReq(): any {
return { user: { sub: 'admin-1', role: 'admin' } };
}
it('forwards stagingId to RestoreService.commitRestore and returns ok', async () => {
const commitRestore = jest.fn().mockResolvedValue({ restoresPerformed: true, revokeUserId: 'admin-1' });
const { controller, consume, revokeAllRefreshSessions } = makeController({ commitRestore });
const result = await controller.commitRestore(
adminReq(),
{ operation: 'restore-backup', token: 'raw-token', stagingId: 'stage-xyz' },
);
expect(result).toEqual({ ok: true, operation: 'restore-backup' });
expect(consume).toHaveBeenCalledWith({
userId: 'admin-1',
operation: 'restore-backup',
token: 'raw-token',
stagingId: 'stage-xyz',
});
expect(commitRestore).toHaveBeenCalledWith('stage-xyz');
expect(revokeAllRefreshSessions).toHaveBeenCalledWith('admin-1');
});
it('returns SYSTEM_RESTORE_STAGE_EXPIRED when stagingId is missing', async () => {
const commitRestore = jest.fn();
const consume = jest.fn();
const { controller } = makeController({ commitRestore, consume });
await expect(
controller.commitRestore(
adminReq(),
{ operation: 'restore-backup', token: 'raw-token' },
),
).rejects.toMatchObject({
code: ERROR_CODES.SYSTEM_RESTORE_STAGE_EXPIRED,
});
expect(consume).not.toHaveBeenCalled();
expect(commitRestore).not.toHaveBeenCalled();
});
it('returns SYSTEM_TOKEN_MISMATCH when operation is not restore-backup', async () => {
const commitRestore = jest.fn();
const consume = jest.fn();
const { controller } = makeController({ commitRestore, consume });
await expect(
controller.commitRestore(
adminReq(),
{ operation: 'reset-scores' as any, token: 'raw-token', stagingId: 'stage-xyz' },
),
).rejects.toMatchObject({
code: ERROR_CODES.SYSTEM_TOKEN_MISMATCH,
});
expect(consume).not.toHaveBeenCalled();
expect(commitRestore).not.toHaveBeenCalled();
});
it('AdminRestoreCommitBodySchema preserves the stagingId field', () => {
const pipe = new ZodValidationPipe(AdminRestoreCommitBodySchema);
const meta: ArgumentMetadata = { type: 'body' };
const value = pipe.transform({
operation: 'restore-backup',
token: 'raw-token',
stagingId: 'stage-xyz',
}, meta);
expect(value).toEqual({
operation: 'restore-backup',
token: 'raw-token',
stagingId: 'stage-xyz',
});
});
it('AdminRestoreCommitBodySchema keeps optional stagingId absent (not empty-stringed)', () => {
const pipe = new ZodValidationPipe(AdminRestoreCommitBodySchema);
const meta: ArgumentMetadata = { type: 'body' };
const value = pipe.transform({ operation: 'restore-backup', token: 'raw-token' }, meta);
expect(value).toEqual({ operation: 'restore-backup', token: 'raw-token' });
expect((value as any).stagingId).toBeUndefined();
void ApiError;
});
});