test(api): add domain layer unit tests across all modules

Cover admin events, notifications, reviews, search VOs, listings (property,
media, events, price/geo/address VOs), auth events, payment events,
subscription events, and analytics events. Raises domain test coverage
from ~24% to ~75%.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-09 00:36:39 +07:00
parent 801e29e65c
commit 62f4f001b6
14 changed files with 973 additions and 1 deletions

View File

@@ -0,0 +1,130 @@
import { describe, it, expect } from 'vitest';
import { ReviewEntity } from '../entities/review.entity';
import { ReviewCreatedEvent } from '../events/review-created.event';
import { ReviewDeletedEvent } from '../events/review-deleted.event';
import { Rating } from '../value-objects/rating.vo';
describe('Reviews Domain', () => {
describe('Rating', () => {
it('creates valid rating', () => {
const result = Rating.create(5);
expect(result.isOk).toBe(true);
expect(result.unwrap().value).toBe(5);
});
it('creates rating with minimum value', () => {
const result = Rating.create(1);
expect(result.isOk).toBe(true);
expect(result.unwrap().value).toBe(1);
});
it('rejects rating below 1', () => {
const result = Rating.create(0);
expect(result.isErr).toBe(true);
});
it('rejects rating above 5', () => {
const result = Rating.create(6);
expect(result.isErr).toBe(true);
});
it('rejects non-integer rating', () => {
const result = Rating.create(3.5);
expect(result.isErr).toBe(true);
});
it('rejects negative rating', () => {
const result = Rating.create(-1);
expect(result.isErr).toBe(true);
});
});
describe('ReviewCreatedEvent', () => {
it('creates event with correct properties', () => {
const event = new ReviewCreatedEvent('review-1', 'user-1', 'agent', 'agent-1', 5);
expect(event.eventName).toBe('review.created');
expect(event.aggregateId).toBe('review-1');
expect(event.userId).toBe('user-1');
expect(event.targetType).toBe('agent');
expect(event.targetId).toBe('agent-1');
expect(event.rating).toBe(5);
expect(event.occurredAt).toBeInstanceOf(Date);
});
});
describe('ReviewDeletedEvent', () => {
it('creates event with correct properties', () => {
const event = new ReviewDeletedEvent('review-1', 'user-1', 'agent', 'agent-1');
expect(event.eventName).toBe('review.deleted');
expect(event.aggregateId).toBe('review-1');
expect(event.userId).toBe('user-1');
expect(event.targetType).toBe('agent');
expect(event.targetId).toBe('agent-1');
expect(event.occurredAt).toBeInstanceOf(Date);
});
});
describe('ReviewEntity', () => {
it('creates new review with domain event', () => {
const rating = Rating.create(4).unwrap();
const review = ReviewEntity.createNew(
'review-1',
'user-1',
'agent',
'agent-1',
rating,
'Môi giới rất nhiệt tình',
);
expect(review.id).toBe('review-1');
expect(review.userId).toBe('user-1');
expect(review.targetType).toBe('agent');
expect(review.targetId).toBe('agent-1');
expect(review.rating.value).toBe(4);
expect(review.comment).toBe('Môi giới rất nhiệt tình');
const events = review.domainEvents;
expect(events).toHaveLength(1);
expect(events[0]).toBeInstanceOf(ReviewCreatedEvent);
});
it('creates review without comment', () => {
const rating = Rating.create(3).unwrap();
const review = ReviewEntity.createNew(
'review-2',
'user-2',
'property',
'prop-1',
rating,
null,
);
expect(review.comment).toBeNull();
});
it('emits ReviewDeletedEvent on markDeleted', () => {
const rating = Rating.create(5).unwrap();
const review = ReviewEntity.createNew(
'review-3',
'user-3',
'agent',
'agent-2',
rating,
null,
);
review.clearDomainEvents();
review.markDeleted();
const events = review.domainEvents;
expect(events).toHaveLength(1);
expect(events[0]).toBeInstanceOf(ReviewDeletedEvent);
const deleteEvent = events[0] as ReviewDeletedEvent;
expect(deleteEvent.userId).toBe('user-3');
expect(deleteEvent.targetType).toBe('agent');
expect(deleteEvent.targetId).toBe('agent-2');
});
});
});