feat(listings): add source field to PriceHistory + unit tests
- Add `source` column to PriceHistory Prisma model (manual_update, admin_override, market_adjustment) - Add migration for the new column with default 'manual_update' - Update ListingPriceChangedEvent domain event with optional source parameter - Update RecordPriceHistoryHandler to persist source - Update GetPriceHistoryHandler to return source in query results - Add unit tests for RecordPriceHistoryHandler (5 cases) - Add unit tests for GetPriceHistoryHandler (3 cases) - Add ListingPriceChangedEvent tests to domain events spec (4 cases) - Add getPriceHistory controller tests (2 cases) All 1805 tests pass, typecheck clean. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { ListingApprovedEvent } from '../events/listing-approved.event';
|
||||
import { ListingCreatedEvent } from '../events/listing-created.event';
|
||||
import { ListingPriceChangedEvent } from '../events/listing-price-changed.event';
|
||||
import { ListingSoldEvent } from '../events/listing-sold.event';
|
||||
import { ListingStatusChangedEvent } from '../events/listing-status-changed.event';
|
||||
|
||||
@@ -51,6 +52,34 @@ describe('Listings Domain Events', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ListingPriceChangedEvent', () => {
|
||||
it('creates event with correct properties', () => {
|
||||
const event = new ListingPriceChangedEvent('listing-1', 5_000_000_000n, 6_000_000_000n, 'manual_update');
|
||||
|
||||
expect(event.eventName).toBe('listing.price_changed');
|
||||
expect(event.aggregateId).toBe('listing-1');
|
||||
expect(event.oldPrice).toBe(5_000_000_000n);
|
||||
expect(event.newPrice).toBe(6_000_000_000n);
|
||||
expect(event.source).toBe('manual_update');
|
||||
expect(event.occurredAt).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
it('defaults source to manual_update', () => {
|
||||
const event = new ListingPriceChangedEvent('listing-2', 1_000_000n, 2_000_000n);
|
||||
expect(event.source).toBe('manual_update');
|
||||
});
|
||||
|
||||
it('accepts admin_override source', () => {
|
||||
const event = new ListingPriceChangedEvent('listing-3', 1n, 2n, 'admin_override');
|
||||
expect(event.source).toBe('admin_override');
|
||||
});
|
||||
|
||||
it('accepts market_adjustment source', () => {
|
||||
const event = new ListingPriceChangedEvent('listing-4', 1n, 2n, 'market_adjustment');
|
||||
expect(event.source).toBe('market_adjustment');
|
||||
});
|
||||
});
|
||||
|
||||
describe('ListingStatusChangedEvent', () => {
|
||||
it('creates event with correct properties', () => {
|
||||
const event = new ListingStatusChangedEvent('listing-1', 'prop-1', 'DRAFT', 'PENDING_REVIEW');
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { DomainEvent } from '@modules/shared';
|
||||
|
||||
export type PriceChangeSource = 'manual_update' | 'admin_override' | 'market_adjustment';
|
||||
|
||||
export class ListingPriceChangedEvent implements DomainEvent {
|
||||
readonly eventName = 'listing.price_changed';
|
||||
readonly occurredAt = new Date();
|
||||
@@ -8,5 +10,6 @@ export class ListingPriceChangedEvent implements DomainEvent {
|
||||
public readonly aggregateId: string,
|
||||
public readonly oldPrice: bigint,
|
||||
public readonly newPrice: bigint,
|
||||
public readonly source: PriceChangeSource = 'manual_update',
|
||||
) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user