import assert from 'node:assert/strict'; import { test } from 'node:test'; import * as qiniu from 'qiniu'; import { imageInput } from '../src/assets/image-input'; import { bufferEtag, QiniuGateway } from '../src/assets/qiniu.gateway'; import { testConfig } from './test-config'; import { ApiException } from '../src/common/api-exception'; test('图片上传按内容头校验格式/完整性/像素限制,拒绝 SVG 与超限文件', () => { const png = Buffer.from( 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+kWQAAAABJRU5ErkJggg==', 'base64', ); assert.equal(imageInput(png).mimeType, 'image/png'); assert.throws(() => imageInput(Buffer.from('')), ); assert.throws(() => imageInput(png.subarray(0, 30))); assert.throws(() => imageInput(Buffer.alloc(2 * 1024 * 1024 + 1))); const huge = Buffer.from(png); huge.writeUInt32BE(100000, 16); assert.throws(() => imageInput(huge)); assert.equal( bufferEtag(Buffer.from('hello')), 'Fqr0xh3cxeii2r7eDztILNmuqUNN', ); }); test('七牛 SDK 接口适配:正确处理 wrapper 612、新增和同内容恢复,不覆盖冲突', async (context) => { const prototype = qiniu.rs.BucketManager.prototype; const uploader = qiniu.form_up.FormUploader.prototype; const originals = { info: prototype.getBucketInfo, stat: prototype.stat, remove: prototype.delete, put: uploader.put, }; context.after(() => { prototype.getBucketInfo = originals.info; prototype.stat = originals.stat; prototype.delete = originals.remove; uploader.put = originals.put; }); const bytes = Buffer.from('hello'); let stored: { hash: string; fsize: number } | null = null; let putCount = 0; prototype.getBucketInfo = (async () => ({ resp: { statusCode: 200 }, data: { private: 0 }, })) as unknown as typeof prototype.getBucketInfo; prototype.stat = (async () => stored ? { resp: { statusCode: 200 }, data: stored } : { resp: { statusCode: 612 }, data: { error: 'missing' }, }) as unknown as typeof prototype.stat; prototype.delete = (async () => ({ resp: { statusCode: 612 }, data: { error: 'missing' }, })) as unknown as typeof prototype.delete; uploader.put = (async () => { putCount++; stored = { hash: bufferEtag(bytes), fsize: bytes.length }; return { resp: { statusCode: 200 }, data: stored }; }) as unknown as typeof uploader.put; const gateway = new QiniuGateway({ ...testConfig, qiniuAk: 'test-ak', qiniuSk: 'test-sk', qiniuBucket: 'test-public', qiniuPublicDomain: 'https://cdn.test', }); await gateway.put('test/a.png', bytes, 'image/png'); await gateway.put('test/a.png', bytes, 'image/png'); assert.equal(putCount, 1); await assert.rejects( gateway.put('test/a.png', Buffer.from('different'), 'image/png'), (error: unknown) => error instanceof ApiException && error.reason === 'ASSET_UPSTREAM_UNAVAILABLE', ); assert.equal(putCount, 1); await gateway.remove('test-public', 'test/missing.png'); prototype.getBucketInfo = (async () => ({ resp: { statusCode: 403 }, data: { error: 'private-message' }, })) as unknown as typeof prototype.getBucketInfo; await assert.rejects( gateway.put('new.png', bytes, 'image/png'), (error: unknown) => error instanceof ApiException && error.getStatus() === 503, ); });