Files
pokemon-inventory/apps/api/tests/http/image-upload-inspection.test.js
2026-09-11 00:35:07 -04:00

42 lines
2.3 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import sharp from 'sharp';
import { buildApp } from '../../src/app/build-app.js';
import { createInventoryImageService } from '../../src/modules/inventory/services/inventory-image-service.js';
import { createSharpImageInspector } from '../../src/infrastructure/images/sharp-image-inspector.js';
test('multipart uploads derive dimensions and reject malformed bytes before writes', async (context) => {
const saved = [];
let stored = 0;
let jobs = 0;
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
inventoryImageService: createInventoryImageService({
imageInspector: createSharpImageInspector(),
imageStorage: { async put() { stored += 1; }, async delete() {} },
inventoryImageRepository: { async createForSeller(input, sellerId) { assert.equal(sellerId, 'seller-1'); saved.push(input); return { id: 'image-1', ...input }; } },
imageDerivativeJobRepository: { async create() { jobs += 1; } },
}),
});
context.after(() => app.close());
const data = await sharp({ create: { width: 7, height: 5, channels: 3, background: 'white' } }).png().toBuffer();
const send = (bytes, fields = '') => app.inject({
method: 'POST', url: '/api/v1/admin/inventory/item-1/images',
headers: { 'content-type': 'multipart/form-data; boundary=image-test' },
payload: Buffer.concat([Buffer.from(`${fields}--image-test\r\nContent-Disposition: form-data; name="file"; filename="image.png"\r\nContent-Type: image/png\r\n\r\n`), bytes, Buffer.from('\r\n--image-test--\r\n')]),
});
for (const fields of ['', '--image-test\r\nContent-Disposition: form-data; name="width"\r\n\r\n1\r\n--image-test\r\nContent-Disposition: form-data; name="height"\r\n\r\n1\r\n']) {
const response = await send(data, fields);
assert.equal(response.statusCode, 201);
assert.equal(response.json().data.width, 7);
assert.equal(response.json().data.height, 5);
assert.equal(response.json().data.fileSize, data.length);
}
const response = await send(data.subarray(0, 40));
assert.equal(response.statusCode, 400);
assert.equal(response.json().error.code, 'IMAGE_DECODE_INVALID');
assert.equal(saved.length, 2);
assert.equal(stored, 2);
assert.equal(jobs, 2);
});