67 lines
4.0 KiB
JavaScript
67 lines
4.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
|
|
import { createInventoryImageService } from '../../src/modules/inventory/services/inventory-image-service.js';
|
|
|
|
function createService() {
|
|
const calls = [];
|
|
const service = createInventoryImageService({
|
|
inventoryImageRepository: {
|
|
async findByIdForSeller(id, sellerId) { calls.push(['find', id, sellerId]); return { id, inventoryItemId: 'item-1', storageKey: 'image.jpg' }; },
|
|
async updateOrderForSeller(id, sortOrder, sellerId) { calls.push(['order', id, sortOrder, sellerId]); return { id, sortOrder }; },
|
|
async setPrimaryForSeller(id, sellerId) { calls.push(['primary', id, sellerId]); return { id, isPrimary: true }; },
|
|
async updateAltTextForSeller(id, altText, sellerId) { calls.push(['alt', id, altText, sellerId]); return { id, altText }; },
|
|
async deleteForSeller(id, sellerId) { calls.push(['delete', id, sellerId]); return { id, storageKey: 'image.jpg' }; },
|
|
},
|
|
imageDerivativeJobRepository: {
|
|
async retryForImage(id) { calls.push(['retry', id]); return { id: 'job-1' }; },
|
|
async deleteForImage(id) { calls.push(['delete-job', id]); },
|
|
},
|
|
imageStorage: { async delete(key) { calls.push(['storage-delete', key]); } },
|
|
});
|
|
return { service, calls };
|
|
}
|
|
|
|
test('manages owned image order, primary state, alt text, retry, and deletion', async () => {
|
|
const { service, calls } = createService();
|
|
|
|
assert.deepEqual(await service.updateOrder({ imageId: 'image-1', sortOrder: 2, sellerId: 'seller-1' }), { id: 'image-1', sortOrder: 2 });
|
|
assert.deepEqual(await service.setPrimary({ imageId: 'image-1', sellerId: 'seller-1' }), { id: 'image-1', isPrimary: true });
|
|
assert.deepEqual(await service.updateAltText({ imageId: 'image-1', altText: 'Front', sellerId: 'seller-1' }), { id: 'image-1', altText: 'Front' });
|
|
assert.deepEqual(await service.retry({ imageId: 'image-1', sellerId: 'seller-1' }), { id: 'image-1', inventoryItemId: 'item-1', storageKey: 'image.jpg' });
|
|
await service.delete({ imageId: 'image-1', sellerId: 'seller-1' });
|
|
|
|
assert.ok(calls.some(([action]) => action === 'retry'));
|
|
assert.ok(calls.some(([action]) => action === 'delete-job'));
|
|
assert.ok(calls.some(([action]) => action === 'storage-delete'));
|
|
});
|
|
|
|
test('moves an image through the owned atomic repository operation', async () => {
|
|
const service = createInventoryImageService({ inventoryImageRepository: {
|
|
async moveForSeller(id, direction, sellerId) {
|
|
assert.equal(direction, 'down');
|
|
assert.equal(sellerId, 'seller-1');
|
|
return id === 'owned' ? { id, sortOrder: 1 } : null;
|
|
},
|
|
} });
|
|
assert.deepEqual(await service.move({ imageId: 'owned', direction: 'down', sellerId: 'seller-1' }), { id: 'owned', sortOrder: 1 });
|
|
await assert.rejects(() => service.move({ imageId: 'missing', direction: 'down', sellerId: 'seller-1' }), { code: 'IMAGE_NOT_FOUND' });
|
|
await assert.rejects(() => service.move({ imageId: 'owned', direction: 'left', sellerId: 'seller-1' }), { code: 'IMAGE_MOVE_INVALID' });
|
|
});
|
|
|
|
test('validates image updates before persistence and normalizes valid alt text', async () => {
|
|
const { service, calls } = createService();
|
|
for (const sortOrder of [undefined, null, -1, 0.5, '1', NaN, Infinity, 2147483648]) {
|
|
await assert.rejects(() => service.updateOrder({ imageId: 'image-1', sortOrder, sellerId: 'seller-1' }), { code: 'IMAGE_ORDER_INVALID' });
|
|
}
|
|
for (const altText of [undefined, 123, {}, [], 'x'.repeat(1001)]) {
|
|
await assert.rejects(() => service.updateAltText({ imageId: 'image-1', altText, sellerId: 'seller-1' }), { code: 'IMAGE_ALT_TEXT_INVALID' });
|
|
}
|
|
assert.deepEqual(calls, []);
|
|
await service.updateOrder({ imageId: 'image-1', sortOrder: 2147483647, sellerId: 'seller-1' });
|
|
for (const [input, expected] of [[' Front ', 'Front'], [' ', ''], [null, null], ['x'.repeat(1000), 'x'.repeat(1000)]]) {
|
|
const result = await service.updateAltText({ imageId: 'image-1', altText: input, sellerId: 'seller-1' });
|
|
assert.equal(result.altText, expected);
|
|
}
|
|
});
|