Backfill the completed acquisitions, sales, dashboard, pricing, search, public detail, worker, migration, contracts, validation, tests, and implementation-status changes into one verified application slice.
138 lines
3.7 KiB
JavaScript
138 lines
3.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { createPricingService } from "../../src/modules/pricing/services/pricing-service.js";
|
|
|
|
test("records an owned pricing observation and calculates a valuation", async () => {
|
|
const service = createPricingService({
|
|
pricingRepository: {
|
|
async addObservationForSeller({ observation, sellerId }) {
|
|
assert.equal(sellerId, "seller-1");
|
|
return { status: "CREATED", observation };
|
|
},
|
|
async markOutliersForSeller() {
|
|
return { status: "UPDATED" };
|
|
},
|
|
async calculateForSeller() {
|
|
return {
|
|
status: "CALCULATED",
|
|
valuation: { valueMinor: 2500 },
|
|
observations: [],
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
const observation = await service.addObservation({
|
|
sellerId: "seller-1",
|
|
productId: "product-1",
|
|
inventoryItemId: "inventory-1",
|
|
providerId: "manual",
|
|
priceMinor: 2500,
|
|
sourceIdentifier: "source-1",
|
|
conditionId: "condition-1",
|
|
});
|
|
assert.equal(observation.priceMinor, 2500);
|
|
const valuation = await service.calculate({
|
|
sellerId: "seller-1",
|
|
inventoryItemId: "inventory-1",
|
|
});
|
|
assert.equal(valuation.valuation.valueMinor, 2500);
|
|
});
|
|
|
|
test("requires a reason for an audited market-value override", async () => {
|
|
const service = createPricingService({
|
|
pricingRepository: {
|
|
async createOverride() {
|
|
throw new Error("should not run");
|
|
},
|
|
},
|
|
});
|
|
await assert.rejects(
|
|
() =>
|
|
service.override({
|
|
sellerId: "seller-1",
|
|
actorUserId: "user-1",
|
|
inventoryItemId: "inventory-1",
|
|
valueMinor: 2000,
|
|
reason: "x",
|
|
}),
|
|
(error) =>
|
|
error.code === "OVERRIDE_REASON_REQUIRED" && error.statusCode === 400,
|
|
);
|
|
});
|
|
|
|
test("fails clearly when a requested pricing provider is unavailable", async () => {
|
|
const service = createPricingService({
|
|
pricingRepository: {},
|
|
pricingProviderRegistry: {
|
|
get() {
|
|
return null;
|
|
},
|
|
},
|
|
});
|
|
|
|
await assert.rejects(
|
|
() =>
|
|
service.refresh({
|
|
sellerId: "seller-1",
|
|
inventoryItemId: "inventory-1",
|
|
providerId: "missing",
|
|
}),
|
|
(error) =>
|
|
error.code === "PRICING_PROVIDER_UNAVAILABLE" && error.statusCode === 503,
|
|
);
|
|
});
|
|
|
|
test("enqueues a seller-scoped pricing refresh and reads its status", async () => {
|
|
const service = createPricingService({
|
|
pricingRepository: {},
|
|
pricingRefreshJobRepository: {
|
|
async create(input) {
|
|
return { id: "job-1", status: "PENDING", ...input };
|
|
},
|
|
async findByIdForSeller(id, sellerId) {
|
|
return { id, sellerId, status: "COMPLETED" };
|
|
},
|
|
},
|
|
providerMappingRepository: {
|
|
async findActiveForSeller() {
|
|
return { providerId: "mapped-provider" };
|
|
},
|
|
},
|
|
});
|
|
|
|
const job = await service.enqueueRefresh({
|
|
sellerId: "seller-1",
|
|
inventoryItemId: "item-1",
|
|
providerId: "provider-1",
|
|
productId: "product-1",
|
|
conditionId: "condition-1",
|
|
});
|
|
assert.equal(job.status, "PENDING");
|
|
assert.equal(job.providerId, "mapped-provider");
|
|
assert.equal(
|
|
(await service.getJob({ sellerId: "seller-1", jobId: job.id })).status,
|
|
"COMPLETED",
|
|
);
|
|
});
|
|
|
|
test("lists and retries seller-scoped failed pricing jobs", async () => {
|
|
const service = createPricingService({
|
|
pricingRepository: {},
|
|
pricingRefreshJobRepository: {
|
|
async listForSeller() {
|
|
return [{ id: "job-1", status: "FAILED" }];
|
|
},
|
|
async retryForSeller() {
|
|
return { id: "job-1", status: "PENDING" };
|
|
},
|
|
},
|
|
});
|
|
assert.equal((await service.listJobs({ sellerId: "seller-1" })).length, 1);
|
|
assert.equal(
|
|
(await service.retryJob({ sellerId: "seller-1", jobId: "job-1" })).status,
|
|
"PENDING",
|
|
);
|
|
});
|