feat: reconcile application vertical slices

Backfill the completed acquisitions, sales, dashboard, pricing, search, public detail, worker, migration, contracts, validation, tests, and implementation-status changes into one verified application slice.
This commit is contained in:
2026-09-09 22:12:53 -04:00
parent b9ff7445a6
commit b8f089a5d9
78 changed files with 4561 additions and 2057 deletions
+23 -19
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
function createTestApp({ authenticateAdmin, authorizeUnsafeRequest } = {}) {
return buildApp({
@@ -9,7 +9,7 @@ function createTestApp({ authenticateAdmin, authorizeUnsafeRequest } = {}) {
authorizeUnsafeRequest,
acquisitionService: {
async create(input) {
return { id: 'acquisition-1', ...input, costBasisMinor: 1075 };
return { id: "acquisition-1", ...input, costBasisMinor: 1075 };
},
async list() {
return [];
@@ -18,21 +18,23 @@ function createTestApp({ authenticateAdmin, authorizeUnsafeRequest } = {}) {
});
}
test('creates an acquisition for the authenticated seller', async (testContext) => {
test("creates an acquisition for the authenticated seller", async (testContext) => {
let csrfChecked = false;
const app = createTestApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authorizeUnsafeRequest: async () => { csrfChecked = true; },
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {
csrfChecked = true;
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/acquisitions',
headers: { 'x-csrf-token': 'csrf-token' },
method: "POST",
url: "/api/v1/admin/acquisitions",
headers: { "x-csrf-token": "csrf-token" },
payload: {
inventoryItemId: 'd2f67d74-9647-48d5-b3a4-74d3b16ea9f8',
method: 'PURCHASE',
inventoryItemId: "d2f67d74-9647-48d5-b3a4-74d3b16ea9f8",
method: "PURCHASE",
costMinor: 1000,
},
});
@@ -42,16 +44,18 @@ test('creates an acquisition for the authenticated seller', async (testContext)
assert.equal(csrfChecked, true);
});
test('rejects invalid acquisition requests', async (testContext) => {
const app = createTestApp({ authenticateAdmin: async () => ({ sellerId: 'seller-1' }) });
test("rejects invalid acquisition requests", async (testContext) => {
const app = createTestApp({
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/acquisitions',
payload: { inventoryItemId: 'not-a-uuid', method: '', costMinor: -1 },
method: "POST",
url: "/api/v1/admin/acquisitions",
payload: { inventoryItemId: "not-a-uuid", method: "", costMinor: -1 },
});
assert.equal(response.statusCode, 400);
assert.equal(response.json().error.code, 'VALIDATION_ERROR');
});
assert.equal(response.json().error.code, "VALIDATION_ERROR");
});
+27 -9
View File
@@ -1,16 +1,34 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
test('returns a seller-scoped dashboard', async (testContext) => {
test("returns a seller-scoped dashboard", async (testContext) => {
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
dashboardService: { async get({ sellerId }) { assert.equal(sellerId, 'seller-1'); return { counts: {}, financials: {}, recentSales: [], recentAcquisitions: [] }; } },
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
dashboardService: {
async get({ sellerId }) {
assert.equal(sellerId, "seller-1");
return {
counts: {},
financials: {},
recentSales: [],
recentAcquisitions: [],
};
},
},
});
testContext.after(() => app.close());
const response = await app.inject({ method: 'GET', url: '/api/v1/admin/dashboard' });
const response = await app.inject({
method: "GET",
url: "/api/v1/admin/dashboard",
});
assert.equal(response.statusCode, 200);
assert.deepEqual(response.json().data, { counts: {}, financials: {}, recentSales: [], recentAcquisitions: [] });
});
assert.deepEqual(response.json().data, {
counts: {},
financials: {},
recentSales: [],
recentAcquisitions: [],
});
});
+114 -47
View File
@@ -1,25 +1,54 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
test('accepts a protected pricing observation and valuation request', async (testContext) => {
test("accepts a protected pricing observation and valuation request", async (testContext) => {
let csrfChecks = 0;
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authorizeUnsafeRequest: async () => { csrfChecks += 1; },
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {
csrfChecks += 1;
},
pricingService: {
async addObservation(input) { return { id: 'observation-1', ...input }; },
async calculate() { return { valuation: { id: 'valuation-1', inventoryItemId: 'inventory-1', valueMinor: 2500, currency: 'USD', strategy: 'MEDIAN', confidence: 'LOW', sourceCount: 1 }, observations: [] }; },
async addObservation(input) {
return { id: "observation-1", ...input };
},
async calculate() {
return {
valuation: {
id: "valuation-1",
inventoryItemId: "inventory-1",
valueMinor: 2500,
currency: "USD",
strategy: "MEDIAN",
confidence: "LOW",
sourceCount: 1,
},
observations: [],
};
},
},
});
testContext.after(() => app.close());
const observationResponse = await app.inject({
method: 'POST', url: '/api/v1/admin/pricing/observations', headers: { 'x-csrf-token': 'csrf' },
payload: { productId: 'd2f67d74-9647-48d5-b3a4-74d3b16ea9f8', inventoryItemId: '21eb218b-7a95-4f80-a9e3-e306f7ca1f2e', providerId: 'manual', priceMinor: 2500, sourceIdentifier: 'source-1', conditionId: 'ab8150c7-96c1-4b55-8d69-7d0b77d48958' },
method: "POST",
url: "/api/v1/admin/pricing/observations",
headers: { "x-csrf-token": "csrf" },
payload: {
productId: "d2f67d74-9647-48d5-b3a4-74d3b16ea9f8",
inventoryItemId: "21eb218b-7a95-4f80-a9e3-e306f7ca1f2e",
providerId: "manual",
priceMinor: 2500,
sourceIdentifier: "source-1",
conditionId: "ab8150c7-96c1-4b55-8d69-7d0b77d48958",
},
});
const valuationResponse = await app.inject({
method: "POST",
url: "/api/v1/admin/inventory/21eb218b-7a95-4f80-a9e3-e306f7ca1f2e/valuation",
});
const valuationResponse = await app.inject({ method: 'POST', url: '/api/v1/admin/inventory/21eb218b-7a95-4f80-a9e3-e306f7ca1f2e/valuation' });
assert.equal(observationResponse.statusCode, 201);
assert.equal(valuationResponse.statusCode, 200);
@@ -27,59 +56,74 @@ test('accepts a protected pricing observation and valuation request', async (tes
assert.equal(csrfChecks, 2);
});
test('accepts a CSRF-protected market-value override', async (testContext) => {
test("accepts a CSRF-protected market-value override", async (testContext) => {
let received;
const app = buildApp({
authenticateAdmin: async () => ({ userId: 'user-1', sellerId: 'seller-1' }),
authenticateAdmin: async () => ({ userId: "user-1", sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {},
pricingService: { async override(input) { received = input; return { id: 'override-1', ...input }; } },
pricingService: {
async override(input) {
received = input;
return { id: "override-1", ...input };
},
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/inventory/21eb218b-7a95-4f80-a9e3-e306f7ca1f2e/valuation/override',
headers: { 'x-csrf-token': 'csrf' },
payload: { valueMinor: 2600, reason: 'Verified recent sale' },
method: "POST",
url: "/api/v1/admin/inventory/21eb218b-7a95-4f80-a9e3-e306f7ca1f2e/valuation/override",
headers: { "x-csrf-token": "csrf" },
payload: { valueMinor: 2600, reason: "Verified recent sale" },
});
assert.equal(response.statusCode, 201);
assert.equal(received.actorUserId, 'user-1');
assert.equal(received.actorUserId, "user-1");
assert.equal(response.json().data.valueMinor, 2600);
});
test('enqueues a pricing refresh and exposes seller-scoped job status', async (testContext) => {
test("enqueues a pricing refresh and exposes seller-scoped job status", async (testContext) => {
const app = buildApp({
authenticateAdmin: async () => ({ userId: 'user-1', sellerId: 'seller-1' }),
authenticateAdmin: async () => ({ userId: "user-1", sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {},
pricingService: {
async enqueueRefresh(input) { return { id: 'job-1', status: 'PENDING', createdAt: input.sellerId }; },
async getJob(input) { assert.equal(input.sellerId, 'seller-1'); return { id: input.jobId, status: 'COMPLETED', error: null }; },
async enqueueRefresh(input) {
return { id: "job-1", status: "PENDING", createdAt: input.sellerId };
},
async getJob(input) {
assert.equal(input.sellerId, "seller-1");
return { id: input.jobId, status: "COMPLETED", error: null };
},
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/inventory/inventory-1/pricing/refresh',
headers: { 'x-csrf-token': 'csrf' },
payload: { providerId: 'missing' },
method: "POST",
url: "/api/v1/admin/inventory/inventory-1/pricing/refresh",
headers: { "x-csrf-token": "csrf" },
payload: { providerId: "missing" },
});
assert.equal(response.statusCode, 202);
assert.equal(response.json().data.status, 'PENDING');
assert.equal(response.json().data.status, "PENDING");
const jobResponse = await app.inject({ method: 'GET', url: '/api/v1/admin/jobs/job-1' });
const jobResponse = await app.inject({
method: "GET",
url: "/api/v1/admin/jobs/job-1",
});
assert.equal(jobResponse.statusCode, 200);
assert.equal(jobResponse.json().data.status, 'COMPLETED');
assert.equal(jobResponse.json().data.status, "COMPLETED");
});
test('returns a conflict when refresh has no active product mapping', async (testContext) => {
test("returns a conflict when refresh has no active product mapping", async (testContext) => {
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {},
pricingService: {
async enqueueRefresh() {
const error = new Error('No active pricing provider mapping exists for this product.');
error.code = 'PRICING_PROVIDER_MAPPING_NOT_FOUND';
const error = new Error(
"No active pricing provider mapping exists for this product.",
);
error.code = "PRICING_PROVIDER_MAPPING_NOT_FOUND";
error.statusCode = 409;
throw error;
},
@@ -88,30 +132,53 @@ test('returns a conflict when refresh has no active product mapping', async (tes
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/inventory/item-1/pricing/refresh',
headers: { 'x-csrf-token': 'csrf' },
payload: { productId: 'product-1', conditionId: 'condition-1' },
method: "POST",
url: "/api/v1/admin/inventory/item-1/pricing/refresh",
headers: { "x-csrf-token": "csrf" },
payload: { productId: "product-1", conditionId: "condition-1" },
});
assert.equal(response.statusCode, 409);
assert.equal(response.json().error.code, 'PRICING_PROVIDER_MAPPING_NOT_FOUND');
assert.equal(
response.json().error.code,
"PRICING_PROVIDER_MAPPING_NOT_FOUND",
);
});
test('lists jobs and retries a failed job with CSRF protection', async (testContext) => {
test("lists jobs and retries a failed job with CSRF protection", async (testContext) => {
let csrfChecks = 0;
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authorizeUnsafeRequest: async () => { csrfChecks += 1; },
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {
csrfChecks += 1;
},
pricingService: {
async listJobs() { return [{ id: 'job-1', status: 'FAILED', providerId: 'fixture', inventoryItemId: 'item-1' }]; },
async retryJob() { return { id: 'job-1', status: 'PENDING' }; },
async listJobs() {
return [
{
id: "job-1",
status: "FAILED",
providerId: "fixture",
inventoryItemId: "item-1",
},
];
},
async retryJob() {
return { id: "job-1", status: "PENDING" };
},
},
});
testContext.after(() => app.close());
const listResponse = await app.inject({ method: 'GET', url: '/api/v1/admin/jobs' });
const retryResponse = await app.inject({ method: 'POST', url: '/api/v1/admin/jobs/job-1/retry', headers: { 'x-csrf-token': 'csrf' } });
const listResponse = await app.inject({
method: "GET",
url: "/api/v1/admin/jobs",
});
const retryResponse = await app.inject({
method: "POST",
url: "/api/v1/admin/jobs/job-1/retry",
headers: { "x-csrf-token": "csrf" },
});
assert.equal(listResponse.statusCode, 200);
assert.equal(retryResponse.statusCode, 202);
assert.equal(csrfChecks, 1);
});
});
@@ -1,29 +1,40 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
test('protects provider mapping writes and scopes mappings to the seller', async (testContext) => {
test("protects provider mapping writes and scopes mappings to the seller", async (testContext) => {
let received;
const app = buildApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {},
providerMappingService: {
async create(input) { received = input; return { id: 'mapping-1', ...input, status: 'ACTIVE' }; },
async list() { return []; },
async disable() { return { id: 'mapping-1', status: 'DISABLED' }; },
async create(input) {
received = input;
return { id: "mapping-1", ...input, status: "ACTIVE" };
},
async list() {
return [];
},
async disable() {
return { id: "mapping-1", status: "DISABLED" };
},
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/products/product-1/provider-mappings',
headers: { 'x-csrf-token': 'csrf' },
payload: { providerId: 'fixture', mappingType: 'PRODUCT', externalIdentifier: 'ext-1' },
method: "POST",
url: "/api/v1/admin/products/product-1/provider-mappings",
headers: { "x-csrf-token": "csrf" },
payload: {
providerId: "fixture",
mappingType: "PRODUCT",
externalIdentifier: "ext-1",
},
});
assert.equal(response.statusCode, 201);
assert.equal(received.sellerId, 'seller-1');
assert.equal(response.json().data.providerId, 'fixture');
assert.equal(received.sellerId, "seller-1");
assert.equal(response.json().data.providerId, "fixture");
});
@@ -1,19 +1,19 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
test('returns public search results with pagination metadata', async (testContext) => {
test("returns public search results with pagination metadata", async (testContext) => {
const app = buildApp({
searchService: {
async searchPublic(filters) {
assert.equal(filters.page, 2);
assert.equal(filters.limit, 5);
assert.equal(filters.includeSold, true);
assert.equal(filters.sort, 'price_low');
assert.equal(filters.conditionId, 'condition-1');
assert.equal(filters.sort, "price_low");
assert.equal(filters.conditionId, "condition-1");
return {
items: [{ id: 'listing-1', status: 'CLOSED' }],
items: [{ id: "listing-1", status: "CLOSED" }],
pagination: { page: 2, limit: 5, total: 6, totalPages: 2 },
};
},
@@ -22,8 +22,8 @@ test('returns public search results with pagination metadata', async (testContex
testContext.after(() => app.close());
const response = await app.inject({
method: 'GET',
url: '/api/v1/public/search?query=charizard&page=2&limit=5&includeSold=true&sort=price_low&conditionId=condition-1',
method: "GET",
url: "/api/v1/public/search?query=charizard&page=2&limit=5&includeSold=true&sort=price_low&conditionId=condition-1",
});
assert.equal(response.statusCode, 200);
@@ -33,44 +33,71 @@ test('returns public search results with pagination metadata', async (testContex
total: 6,
totalPages: 2,
});
assert.equal(response.json().data.items[0].id, 'listing-1');
assert.equal(response.json().data.items[0].id, "listing-1");
});
test('rejects malformed numeric search filters', async (testContext) => {
const app = buildApp({ searchService: { async searchPublic() { throw new Error('should not run'); } } });
test("rejects malformed numeric search filters", async (testContext) => {
const app = buildApp({
searchService: {
async searchPublic() {
throw new Error("should not run");
},
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'GET',
url: '/api/v1/public/search?minPriceMinor=12.5',
method: "GET",
url: "/api/v1/public/search?minPriceMinor=12.5",
});
assert.equal(response.statusCode, 400);
assert.equal(response.json().error.code, 'INVALID_SEARCH_FILTER');
assert.equal(response.json().error.code, "INVALID_SEARCH_FILTER");
});
test('returns active public category options', async (testContext) => {
test("returns active public category options", async (testContext) => {
const app = buildApp({
catalogLookupRepository: {
async listCategories() { return [{ id: 'category-1', name: 'Trading Cards' }]; },
async listCategories() {
return [{ id: "category-1", name: "Trading Cards" }];
},
},
});
testContext.after(() => app.close());
const response = await app.inject({ method: 'GET', url: '/api/v1/public/lookups/categories' });
const response = await app.inject({
method: "GET",
url: "/api/v1/public/lookups/categories",
});
assert.equal(response.statusCode, 200);
assert.deepEqual(response.json().data, [{ id: 'category-1', name: 'Trading Cards' }]);
assert.deepEqual(response.json().data, [
{ id: "category-1", name: "Trading Cards" },
]);
});
test('returns public condition options without category internals', async (testContext) => {
test("returns public condition options without category internals", async (testContext) => {
const app = buildApp({
catalogLookupRepository: {
async listConditions() { return [{ id: 'condition-1', name: 'Near Mint', code: 'NM', categoryId: 'private-category' }]; },
async listConditions() {
return [
{
id: "condition-1",
name: "Near Mint",
code: "NM",
categoryId: "private-category",
},
];
},
},
});
testContext.after(() => app.close());
const response = await app.inject({ method: 'GET', url: '/api/v1/public/lookups/conditions' });
const response = await app.inject({
method: "GET",
url: "/api/v1/public/lookups/conditions",
});
assert.equal(response.statusCode, 200);
assert.deepEqual(response.json().data, [{ id: 'condition-1', name: 'Near Mint', code: 'NM' }]);
});
assert.deepEqual(response.json().data, [
{ id: "condition-1", name: "Near Mint", code: "NM" },
]);
});
+43 -39
View File
@@ -1,15 +1,15 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import assert from "node:assert/strict";
import test from "node:test";
import { buildApp } from '../../src/app/build-app.js';
import { buildApp } from "../../src/app/build-app.js";
const saleResult = {
sale: {
id: 'sale-1',
sellerId: 'seller-1',
saleDate: '2026-09-09',
id: "sale-1",
sellerId: "seller-1",
saleDate: "2026-09-09",
soldPriceMinor: 2499,
currency: 'USD',
currency: "USD",
platformFeesMinor: 0,
paymentProcessingFeesMinor: 0,
shippingCostMinor: 0,
@@ -17,12 +17,12 @@ const saleResult = {
otherFeesMinor: 0,
},
saleItem: {
id: 'sale-item-1',
inventoryItemId: 'inventory-1',
id: "sale-item-1",
inventoryItemId: "inventory-1",
soldPriceMinor: 2499,
costBasisMinor: 1200,
},
inventoryItem: { id: 'inventory-1', status: 'SOLD' },
inventoryItem: { id: "inventory-1", status: "SOLD" },
};
function createTestApp({ authenticateAdmin, authorizeUnsafeRequest } = {}) {
@@ -31,70 +31,74 @@ function createTestApp({ authenticateAdmin, authorizeUnsafeRequest } = {}) {
authorizeUnsafeRequest,
saleService: {
async create(input) {
assert.equal(input.sellerId, 'seller-1');
assert.equal(input.sellerId, "seller-1");
return saleResult;
},
},
});
}
test('creates a sale for the authenticated seller with CSRF protection', async (testContext) => {
test("creates a sale for the authenticated seller with CSRF protection", async (testContext) => {
let csrfChecks = 0;
const app = createTestApp({
authenticateAdmin: async () => ({ sellerId: 'seller-1' }),
authorizeUnsafeRequest: async () => { csrfChecks += 1; },
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {
csrfChecks += 1;
},
});
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/sales',
headers: { 'x-csrf-token': 'csrf-token' },
method: "POST",
url: "/api/v1/admin/sales",
headers: { "x-csrf-token": "csrf-token" },
payload: {
inventoryItemId: 'd2f67d74-9647-48d5-b3a4-74d3b16ea9f8',
inventoryItemId: "d2f67d74-9647-48d5-b3a4-74d3b16ea9f8",
costBasisMinor: 1200,
saleDate: '2026-09-09',
saleDate: "2026-09-09",
soldPriceMinor: 2499,
},
});
assert.equal(response.statusCode, 201);
assert.equal(response.json().data.inventoryItem.status, 'SOLD');
assert.equal(response.json().data.inventoryItem.status, "SOLD");
assert.equal(csrfChecks, 1);
});
test('rejects invalid sale requests and unauthenticated requests', async (testContext) => {
const app = createTestApp({ authenticateAdmin: async () => ({ sellerId: 'seller-1' }) });
test("rejects invalid sale requests and unauthenticated requests", async (testContext) => {
const app = createTestApp({
authenticateAdmin: async () => ({ sellerId: "seller-1" }),
});
testContext.after(() => app.close());
const invalidResponse = await app.inject({
method: 'POST',
url: '/api/v1/admin/sales',
method: "POST",
url: "/api/v1/admin/sales",
payload: {
inventoryItemId: 'not-a-uuid',
inventoryItemId: "not-a-uuid",
costBasisMinor: -1,
saleDate: 'tomorrow',
saleDate: "tomorrow",
soldPriceMinor: 0,
},
});
assert.equal(invalidResponse.statusCode, 400);
assert.equal(invalidResponse.json().error.code, 'VALIDATION_ERROR');
assert.equal(invalidResponse.json().error.code, "VALIDATION_ERROR");
const unauthenticatedApp = createTestApp();
testContext.after(() => unauthenticatedApp.close());
const unauthenticatedResponse = await unauthenticatedApp.inject({
method: 'POST',
url: '/api/v1/admin/sales',
method: "POST",
url: "/api/v1/admin/sales",
payload: {},
});
assert.equal(unauthenticatedResponse.statusCode, 401);
assert.equal(unauthenticatedResponse.json().error.code, 'UNAUTHORIZED');
assert.equal(unauthenticatedResponse.json().error.code, "UNAUTHORIZED");
});
test('voids a sale with CSRF protection and actor identity', async (testContext) => {
test("voids a sale with CSRF protection and actor identity", async (testContext) => {
let voidInput;
const app = buildApp({
authenticateAdmin: async () => ({ userId: 'user-1', sellerId: 'seller-1' }),
authenticateAdmin: async () => ({ userId: "user-1", sellerId: "seller-1" }),
authorizeUnsafeRequest: async () => {},
saleService: {
async void(input) {
@@ -106,13 +110,13 @@ test('voids a sale with CSRF protection and actor identity', async (testContext)
testContext.after(() => app.close());
const response = await app.inject({
method: 'POST',
url: '/api/v1/admin/sales/sale-1/void',
headers: { 'x-csrf-token': 'csrf-token' },
payload: { reason: 'Duplicate entry' },
method: "POST",
url: "/api/v1/admin/sales/sale-1/void",
headers: { "x-csrf-token": "csrf-token" },
payload: { reason: "Duplicate entry" },
});
assert.equal(response.statusCode, 200);
assert.equal(voidInput.actorUserId, 'user-1');
assert.equal(response.json().data.inventoryItem.status, 'SOLD');
});
assert.equal(voidInput.actorUserId, "user-1");
assert.equal(response.json().data.inventoryItem.status, "SOLD");
});