import { INestApplication } from '@nestjs/common'; import * as bcrypt from 'bcryptjs'; import request from 'supertest'; import { App } from 'supertest/types'; import { PrismaService } from '../src/prisma/prisma.service'; import { createTestApp } from './utils/create-test-app'; import { login } from './utils/api'; interface ScheduleBody { importLimitBytes: number; lastBackupExceedsImportLimit: boolean; } const IMPORT_LIMIT_BYTES = 2048; /** * BACKUP_MAX_IMPORT_BYTES is the one limit for both sides: the upload of * POST /backup/import is cut off at it, and GET /backup/schedule reports it * so the UI can tell when a backup has outgrown it. */ describe('Backup import limit (e2e)', () => { let app: INestApplication; const originalLimit = process.env.BACKUP_MAX_IMPORT_BYTES; const suffix = `${Date.now()}-${Math.round(Math.random() * 1e6)}`; const password = 'SuperSecret123!'; let token: string; beforeAll(async () => { process.env.BACKUP_MAX_IMPORT_BYTES = String(IMPORT_LIMIT_BYTES); app = await createTestApp(); await app.get(PrismaService).user.create({ data: { email: `backup-limit-${suffix}@example.com`, passwordHash: await bcrypt.hash(password, 12), name: 'Backup Admin', role: { connect: { key: 'ADMIN' } }, }, }); token = (await login(app, `backup-limit-${suffix}@example.com`, password)) .accessToken; }); afterAll(async () => { await app.close(); if (originalLimit === undefined) { delete process.env.BACKUP_MAX_IMPORT_BYTES; } else { process.env.BACKUP_MAX_IMPORT_BYTES = originalLimit; } }); it('reports the configured import limit in the schedule status', async () => { const response = await request(app.getHttpServer()) .get('/api/v1/backup/schedule') .set('Authorization', `Bearer ${token}`) .expect(200); expect((response.body as ScheduleBody).importLimitBytes).toBe( IMPORT_LIMIT_BYTES, ); }); it('refuses an upload larger than the import limit before reading it in', async () => { const tooLarge = Buffer.from( JSON.stringify({ padding: 'x'.repeat(IMPORT_LIMIT_BYTES) }), ); await request(app.getHttpServer()) .post('/api/v1/backup/import') .set('Authorization', `Bearer ${token}`) .field('password', password) .attach('file', tooLarge, 'apicore-backup.json') .expect(413); }); });