Files
pokemon-inventory/apps/api/tests/http/image-move-routes.test.js
2026-09-11 00:13:44 -04:00

34 lines
1.8 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { buildApp } from '../../src/app/build-app.js';
test('validates and authorizes image moves and exposes only the image DTO', async (context) => {
const calls = [];
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authorizeUnsafeRequest: async () => { calls.push('csrf'); },
inventoryImageService: { async move(input) { calls.push(input); return { id: input.imageId, sortOrder: 1, privateData: 'hidden' }; } },
});
context.after(() => app.close());
const response = await app.inject({ method: 'POST', url: '/api/v1/admin/images/image-1/move', payload: { direction: 'down' } });
assert.equal(response.statusCode, 200);
assert.deepEqual(calls, ['csrf', { imageId: 'image-1', direction: 'down', sellerId: 'seller-1' }]);
assert.equal(response.json().data.sortOrder, 1);
assert.equal(response.json().data.privateData, undefined);
for (const payload of [{}, { direction: 'left' }, { direction: 'up', sellerId: 'other' }]) {
assert.equal((await app.inject({ method: 'POST', url: '/api/v1/admin/images/image-1/move', payload })).statusCode, 400);
}
});
test('rejects unauthenticated and CSRF-blocked moves without calling the service', async (context) => {
for (const csrf of [false, true]) {
const app = buildApp({
authenticateAdmin: async () => csrf ? { sellerId: 'seller-1' } : null,
authorizeUnsafeRequest: async () => { throw Object.assign(new Error('Forbidden'), { statusCode: 403 }); },
inventoryImageService: { async move() { assert.fail('unauthorized move'); } },
});
context.after(() => app.close());
assert.equal((await app.inject({ method: 'POST', url: '/api/v1/admin/images/image-1/move', payload: { direction: 'up' } })).statusCode, csrf ? 403 : 401);
}
});