import assert from 'node:assert/strict'; import test from 'node:test'; import { LISTING_STATUS, canPublishListing, createListing, transitionListingStatus, } from '../../src/modules/listings/domain/listing.js'; test('creates a draft listing with the required public offer fields', () => { const listing = createListing({ inventoryItemId: 'inventory-item-id', productName: ' Charizard ex ', categoryId: 'category-id', conditionId: 'condition-id', askingPriceMinor: 2499, imageCount: 2, notes: ' Near mint ', }); assert.deepEqual(listing, { inventoryItemId: 'inventory-item-id', productName: 'Charizard ex', categoryId: 'category-id', conditionId: 'condition-id', askingPriceMinor: 2499, imageCount: 2, status: LISTING_STATUS.DRAFT, notes: 'Near mint', }); }); test('requires the publication prerequisites before a listing can be made available', () => { const valid = { productName: 'Charizard ex', categoryId: 'category-id', conditionId: 'condition-id', inventoryItemId: 'inventory-item-id', askingPriceMinor: 2499, imageCount: 2, }; assert.doesNotThrow(() => canPublishListing(valid)); assert.throws( () => canPublishListing({ ...valid, askingPriceMinor: 0 }), (error) => error.code === 'LISTING_REQUIREMENTS_NOT_MET', ); assert.throws( () => canPublishListing({ ...valid, imageCount: 0 }), (error) => error.code === 'LISTING_REQUIREMENTS_NOT_MET', ); assert.throws( () => canPublishListing({ ...valid, inventoryStatus: 'SOLD' }), (error) => error.code === 'LISTING_INVENTORY_UNAVAILABLE' && error.statusCode === 409, ); assert.throws( () => canPublishListing({ ...valid, inventoryStatus: 'ARCHIVED' }), (error) => error.code === 'LISTING_INVENTORY_UNAVAILABLE', ); }); test('allows only status transitions permitted by the listing lifecycle', () => { assert.equal(transitionListingStatus(LISTING_STATUS.DRAFT, LISTING_STATUS.AVAILABLE), LISTING_STATUS.AVAILABLE); assert.throws( () => transitionListingStatus(LISTING_STATUS.DRAFT, LISTING_STATUS.ARCHIVED), /Listing status cannot transition from DRAFT to ARCHIVED/, ); assert.equal(transitionListingStatus(LISTING_STATUS.CLOSED, LISTING_STATUS.ARCHIVED), LISTING_STATUS.ARCHIVED); });