integration tests
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
This commit is contained in:
@@ -1,34 +1,20 @@
|
||||
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
||||
import { RatingTestContext } from './RatingTestContext';
|
||||
import { SaveRatingUseCase } from '../../../../core/rating/application/use-cases/SaveRatingUseCase';
|
||||
import { GetRatingUseCase } from '../../../../core/rating/application/use-cases/GetRatingUseCase';
|
||||
import { GetRatingHistoryUseCase } from '../../../../core/rating/application/use-cases/GetRatingHistoryUseCase';
|
||||
import { GetRatingTrendUseCase } from '../../../../core/rating/application/use-cases/GetRatingTrendUseCase';
|
||||
import { Driver } from '../../../../core/racing/domain/entities/Driver';
|
||||
import { Rating } from '../../../../core/rating/domain/entities/Rating';
|
||||
import { DriverId } from '../../../../core/racing/domain/entities/DriverId';
|
||||
import { RaceId } from '../../../../core/racing/domain/entities/RaceId';
|
||||
|
||||
describe('Rating Persistence Use Cases', () => {
|
||||
let context: RatingTestContext;
|
||||
let saveRatingUseCase: SaveRatingUseCase;
|
||||
let getRatingUseCase: GetRatingUseCase;
|
||||
let getRatingHistoryUseCase: GetRatingHistoryUseCase;
|
||||
let getRatingTrendUseCase: GetRatingTrendUseCase;
|
||||
|
||||
beforeAll(() => {
|
||||
context = RatingTestContext.create();
|
||||
saveRatingUseCase = new SaveRatingUseCase(
|
||||
context.ratingRepository,
|
||||
context.eventPublisher
|
||||
);
|
||||
getRatingUseCase = new GetRatingUseCase(
|
||||
context.ratingRepository
|
||||
);
|
||||
getRatingHistoryUseCase = new GetRatingHistoryUseCase(
|
||||
context.ratingRepository
|
||||
);
|
||||
getRatingTrendUseCase = new GetRatingTrendUseCase(
|
||||
context.ratingRepository
|
||||
);
|
||||
saveRatingUseCase = new SaveRatingUseCase({
|
||||
ratingRepository: context.ratingRepository
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -43,9 +29,10 @@ describe('Rating Persistence Use Cases', () => {
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: A rating to save
|
||||
const rating = Rating.create({
|
||||
// When: SaveRatingUseCase.execute() is called
|
||||
await saveRatingUseCase.execute({
|
||||
driverId,
|
||||
raceId: 'r1',
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
@@ -54,419 +41,13 @@ describe('Rating Persistence Use Cases', () => {
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date()
|
||||
}
|
||||
});
|
||||
|
||||
// When: SaveRatingUseCase.execute() is called
|
||||
const result = await saveRatingUseCase.execute({ rating });
|
||||
|
||||
// Then: The rating should be saved
|
||||
expect(result.isOk()).toBe(true);
|
||||
|
||||
// And: EventPublisher should emit RatingSavedEvent
|
||||
expect(context.eventPublisher.events).toContainEqual(
|
||||
expect.objectContaining({ type: 'RatingSavedEvent' })
|
||||
);
|
||||
});
|
||||
|
||||
it('should update existing rating', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: An initial rating
|
||||
const initialRating = Rating.create({
|
||||
driverId,
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
consistency: 75,
|
||||
cleanDriving: 90,
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date(Date.now() - 86400000)
|
||||
});
|
||||
await context.ratingRepository.save(initialRating);
|
||||
|
||||
// Given: An updated rating
|
||||
const updatedRating = Rating.create({
|
||||
driverId,
|
||||
rating: 1550,
|
||||
components: {
|
||||
resultsStrength: 85,
|
||||
consistency: 80,
|
||||
cleanDriving: 92,
|
||||
racecraft: 88,
|
||||
reliability: 96,
|
||||
teamContribution: 75
|
||||
},
|
||||
timestamp: new Date()
|
||||
});
|
||||
|
||||
// When: SaveRatingUseCase.execute() is called
|
||||
const result = await saveRatingUseCase.execute({ rating: updatedRating });
|
||||
|
||||
// Then: The rating should be updated
|
||||
expect(result.isOk()).toBe(true);
|
||||
|
||||
// And: EventPublisher should emit RatingUpdatedEvent
|
||||
expect(context.eventPublisher.events).toContainEqual(
|
||||
expect.objectContaining({ type: 'RatingUpdatedEvent' })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UseCase - Error Handling', () => {
|
||||
it('should handle missing driver', async () => {
|
||||
// Given: A rating with non-existent driver
|
||||
const rating = Rating.create({
|
||||
driverId: 'd999',
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
consistency: 75,
|
||||
cleanDriving: 90,
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date()
|
||||
});
|
||||
|
||||
// When: SaveRatingUseCase.execute() is called
|
||||
const result = await saveRatingUseCase.execute({ rating });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GetRatingUseCase', () => {
|
||||
describe('UseCase - Success Path', () => {
|
||||
it('should retrieve rating for driver', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: A saved rating
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
consistency: 75,
|
||||
cleanDriving: 90,
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date()
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
|
||||
// When: GetRatingUseCase.execute() is called
|
||||
const result = await getRatingUseCase.execute({ driverId });
|
||||
|
||||
// Then: The rating should be retrieved
|
||||
expect(result.isOk()).toBe(true);
|
||||
const retrievedRating = result.unwrap();
|
||||
expect(retrievedRating.driverId.toString()).toBe(driverId);
|
||||
expect(retrievedRating.rating).toBe(1500);
|
||||
expect(retrievedRating.components.resultsStrength).toBe(80);
|
||||
});
|
||||
|
||||
it('should return latest rating for driver', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: Multiple ratings for the same driver
|
||||
const oldRating = Rating.create({
|
||||
driverId,
|
||||
rating: 1400,
|
||||
components: {
|
||||
resultsStrength: 70,
|
||||
consistency: 65,
|
||||
cleanDriving: 80,
|
||||
racecraft: 75,
|
||||
reliability: 85,
|
||||
teamContribution: 60
|
||||
},
|
||||
timestamp: new Date(Date.now() - 86400000)
|
||||
});
|
||||
await context.ratingRepository.save(oldRating);
|
||||
|
||||
const newRating = Rating.create({
|
||||
driverId,
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
consistency: 75,
|
||||
cleanDriving: 90,
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date()
|
||||
});
|
||||
await context.ratingRepository.save(newRating);
|
||||
|
||||
// When: GetRatingUseCase.execute() is called
|
||||
const result = await getRatingUseCase.execute({ driverId });
|
||||
|
||||
// Then: The latest rating should be retrieved
|
||||
expect(result.isOk()).toBe(true);
|
||||
const retrievedRating = result.unwrap();
|
||||
expect(retrievedRating.driverId.toString()).toBe(driverId);
|
||||
expect(retrievedRating.rating).toBe(1500);
|
||||
expect(retrievedRating.timestamp.getTime()).toBe(newRating.timestamp.getTime());
|
||||
});
|
||||
});
|
||||
|
||||
describe('UseCase - Error Handling', () => {
|
||||
it('should handle missing driver', async () => {
|
||||
// Given: A non-existent driver
|
||||
const driverId = 'd999';
|
||||
|
||||
// When: GetRatingUseCase.execute() is called
|
||||
const result = await getRatingUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle driver with no rating', async () => {
|
||||
// Given: A driver with no rating
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// When: GetRatingUseCase.execute() is called
|
||||
const result = await getRatingUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GetRatingHistoryUseCase', () => {
|
||||
describe('UseCase - Success Path', () => {
|
||||
it('should retrieve rating history for driver', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: Multiple ratings for the same driver
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1400 + (i * 20),
|
||||
components: {
|
||||
resultsStrength: 70 + (i * 2),
|
||||
consistency: 65 + (i * 2),
|
||||
cleanDriving: 80 + (i * 2),
|
||||
racecraft: 75 + (i * 2),
|
||||
reliability: 85 + (i * 2),
|
||||
teamContribution: 60 + (i * 2)
|
||||
},
|
||||
timestamp: new Date(Date.now() - (i * 86400000))
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
}
|
||||
|
||||
// When: GetRatingHistoryUseCase.execute() is called
|
||||
const result = await getRatingHistoryUseCase.execute({ driverId });
|
||||
|
||||
// Then: The rating history should be retrieved
|
||||
expect(result.isOk()).toBe(true);
|
||||
const history = result.unwrap();
|
||||
expect(history).toHaveLength(5);
|
||||
expect(history[0].rating).toBe(1500);
|
||||
expect(history[4].rating).toBe(1420);
|
||||
});
|
||||
|
||||
it('should retrieve rating history with limit', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: Multiple ratings for the same driver
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1400 + (i * 10),
|
||||
components: {
|
||||
resultsStrength: 70 + i,
|
||||
consistency: 65 + i,
|
||||
cleanDriving: 80 + i,
|
||||
racecraft: 75 + i,
|
||||
reliability: 85 + i,
|
||||
teamContribution: 60 + i
|
||||
},
|
||||
timestamp: new Date(Date.now() - (i * 86400000))
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
}
|
||||
|
||||
// When: GetRatingHistoryUseCase.execute() is called with limit
|
||||
const result = await getRatingHistoryUseCase.execute({ driverId, limit: 5 });
|
||||
|
||||
// Then: The rating history should be retrieved with limit
|
||||
expect(result.isOk()).toBe(true);
|
||||
const history = result.unwrap();
|
||||
expect(history).toHaveLength(5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UseCase - Error Handling', () => {
|
||||
it('should handle missing driver', async () => {
|
||||
// Given: A non-existent driver
|
||||
const driverId = 'd999';
|
||||
|
||||
// When: GetRatingHistoryUseCase.execute() is called
|
||||
const result = await getRatingHistoryUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle driver with no rating history', async () => {
|
||||
// Given: A driver with no rating
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// When: GetRatingHistoryUseCase.execute() is called
|
||||
const result = await getRatingHistoryUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('GetRatingTrendUseCase', () => {
|
||||
describe('UseCase - Success Path', () => {
|
||||
it('should retrieve rating trend for driver', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: Multiple ratings for the same driver
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1400 + (i * 20),
|
||||
components: {
|
||||
resultsStrength: 70 + (i * 2),
|
||||
consistency: 65 + (i * 2),
|
||||
cleanDriving: 80 + (i * 2),
|
||||
racecraft: 75 + (i * 2),
|
||||
reliability: 85 + (i * 2),
|
||||
teamContribution: 60 + (i * 2)
|
||||
},
|
||||
timestamp: new Date(Date.now() - (i * 86400000))
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
}
|
||||
|
||||
// When: GetRatingTrendUseCase.execute() is called
|
||||
const result = await getRatingTrendUseCase.execute({ driverId });
|
||||
|
||||
// Then: The rating trend should be retrieved
|
||||
expect(result.isOk()).toBe(true);
|
||||
const trend = result.unwrap();
|
||||
expect(trend.driverId.toString()).toBe(driverId);
|
||||
expect(trend.trend).toBeDefined();
|
||||
expect(trend.trend.length).toBeGreaterThan(0);
|
||||
expect(trend.change).toBeGreaterThan(0);
|
||||
expect(trend.changePercentage).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should calculate trend over specific period', async () => {
|
||||
// Given: A driver
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
// Given: Multiple ratings for the same driver
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1400 + (i * 10),
|
||||
components: {
|
||||
resultsStrength: 70 + i,
|
||||
consistency: 65 + i,
|
||||
cleanDriving: 80 + i,
|
||||
racecraft: 75 + i,
|
||||
reliability: 85 + i,
|
||||
teamContribution: 60 + i
|
||||
},
|
||||
timestamp: new Date(Date.now() - (i * 86400000))
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
}
|
||||
|
||||
// When: GetRatingTrendUseCase.execute() is called with period
|
||||
const result = await getRatingTrendUseCase.execute({ driverId, period: 7 });
|
||||
|
||||
// Then: The rating trend should be retrieved for the period
|
||||
expect(result.isOk()).toBe(true);
|
||||
const trend = result.unwrap();
|
||||
expect(trend.driverId.toString()).toBe(driverId);
|
||||
expect(trend.trend.length).toBeLessThanOrEqual(7);
|
||||
});
|
||||
});
|
||||
|
||||
describe('UseCase - Error Handling', () => {
|
||||
it('should handle missing driver', async () => {
|
||||
// Given: A non-existent driver
|
||||
const driverId = 'd999';
|
||||
|
||||
// When: GetRatingTrendUseCase.execute() is called
|
||||
const result = await getRatingTrendUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle driver with insufficient rating history', async () => {
|
||||
// Given: A driver with only one rating
|
||||
const driverId = 'd1';
|
||||
const driver = Driver.create({ id: driverId, iracingId: '100', name: 'John Doe', country: 'US' });
|
||||
await context.driverRepository.create(driver);
|
||||
|
||||
const rating = Rating.create({
|
||||
driverId,
|
||||
rating: 1500,
|
||||
components: {
|
||||
resultsStrength: 80,
|
||||
consistency: 75,
|
||||
cleanDriving: 90,
|
||||
racecraft: 85,
|
||||
reliability: 95,
|
||||
teamContribution: 70
|
||||
},
|
||||
timestamp: new Date()
|
||||
});
|
||||
await context.ratingRepository.save(rating);
|
||||
|
||||
// When: GetRatingTrendUseCase.execute() is called
|
||||
const result = await getRatingTrendUseCase.execute({ driverId });
|
||||
|
||||
// Then: The result should be an error
|
||||
expect(result.isErr()).toBe(true);
|
||||
const savedRatings = await context.ratingRepository.findByDriver(driverId);
|
||||
expect(savedRatings).toHaveLength(1);
|
||||
expect(savedRatings[0].rating).toBe(1500);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user