import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { beforeAll, afterAll, describe, expect, it } from 'vitest'; import { buildApp } from '../../src/app/app'; import { makeToken, setupTestJwks } from '../support/token'; const dir = mkdtempSync(join(tmpdir(), 'bpos-store-')); describe('upload', () => { let token = ''; beforeAll(async () => { process.env.OBJECT_STORE_DIR = dir; await setupTestJwks(); token = await makeToken({ roles: ['user'], aud: 'api-gateway' }); }); afterAll(() => rmSync(dir, { recursive: true, force: true })); it('上传→取回一致;越权 401;超 8MB 413', async () => { const app = buildApp(); const payload = new TextEncoder().encode('原件字节'); const up = await app.request('/api/upload', { method: 'POST', headers: { authorization: `Bearer ${token}`, 'content-type': 'text/plain', 'x-filename': 'a.txt' }, body: payload, }); expect(up.status).toBe(201); const { ref } = (await up.json()) as { ref: string }; const back = await app.request(`/api/upload/${ref}`, { headers: { authorization: `Bearer ${token}` } }); expect(back.status).toBe(200); expect(back.headers.get('content-type')).toContain('text/plain'); expect(new Uint8Array(await back.arrayBuffer())).toEqual(payload); expect((await app.request('/api/upload', { method: 'POST' })).status).toBe(401); const big = new Uint8Array(8 * 1024 * 1024 + 1); const tooBig = await app.request('/api/upload', { method: 'POST', headers: { authorization: `Bearer ${token}` }, body: big, }); expect(tooBig.status).toBe(413); }); });