AI Implementation feature(916): Admin Area System: Database Backup/Restore and Danger Zone 1.00 (#62)
This commit was merged in pull request #62.
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
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;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user