/** * Integration Test: Sponsor League Detail Use Case Orchestration * * Tests the orchestration logic of sponsor league detail-related Use Cases: * - GetEntitySponsorshipPricingUseCase: Retrieves sponsorship pricing for leagues * - Validates that Use Cases correctly interact with their Ports (Repositories) * - Uses In-Memory adapters for fast, deterministic testing * * Focus: Business logic orchestration, NOT UI rendering */ import { describe, it, expect, beforeAll, beforeEach } from 'vitest'; import { InMemorySponsorshipPricingRepository } from '../../../adapters/racing/persistence/inmemory/InMemorySponsorshipPricingRepository'; import { GetEntitySponsorshipPricingUseCase } from '../../../core/racing/application/use-cases/GetEntitySponsorshipPricingUseCase'; import { Logger } from '../../../core/shared/domain/Logger'; describe('Sponsor League Detail Use Case Orchestration', () => { let sponsorshipPricingRepository: InMemorySponsorshipPricingRepository; let getEntitySponsorshipPricingUseCase: GetEntitySponsorshipPricingUseCase; let mockLogger: Logger; beforeAll(() => { mockLogger = { info: () => {}, debug: () => {}, warn: () => {}, error: () => {}, } as unknown as Logger; sponsorshipPricingRepository = new InMemorySponsorshipPricingRepository(mockLogger); getEntitySponsorshipPricingUseCase = new GetEntitySponsorshipPricingUseCase( sponsorshipPricingRepository, mockLogger, ); }); beforeEach(() => { sponsorshipPricingRepository.clear(); }); describe('GetEntitySponsorshipPricingUseCase - Success Path', () => { it('should retrieve sponsorship pricing for a league', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured const pricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: true, mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: ['Primary logo placement', 'League page header banner'], }, secondarySlots: { price: { amount: 2000, currency: 'USD' }, benefits: ['Secondary logo on liveries', 'League page sidebar placement'], }, }; await sponsorshipPricingRepository.create(pricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The result should contain sponsorship pricing expect(result.isOk()).toBe(true); const pricingResult = result.unwrap(); // And: The entity type should be correct expect(pricingResult.entityType).toBe('league'); // And: The entity ID should be correct expect(pricingResult.entityId).toBe(leagueId); // And: The league should be accepting applications expect(pricingResult.acceptingApplications).toBe(true); // And: The tiers should contain main slot expect(pricingResult.tiers).toHaveLength(2); expect(pricingResult.tiers[0].name).toBe('main'); expect(pricingResult.tiers[0].price.amount).toBe(10000); expect(pricingResult.tiers[0].price.currency).toBe('USD'); expect(pricingResult.tiers[0].benefits).toContain('Primary logo placement'); // And: The tiers should contain secondary slot expect(pricingResult.tiers[1].name).toBe('secondary'); expect(pricingResult.tiers[1].price.amount).toBe(2000); expect(pricingResult.tiers[1].price.currency).toBe('USD'); expect(pricingResult.tiers[1].benefits).toContain('Secondary logo on liveries'); }); it('should retrieve sponsorship pricing with only main slot', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured with only main slot const pricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: true, mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: ['Primary logo placement', 'League page header banner'], }, }; await sponsorshipPricingRepository.create(pricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The result should contain sponsorship pricing expect(result.isOk()).toBe(true); const pricingResult = result.unwrap(); // And: The tiers should contain only main slot expect(pricingResult.tiers).toHaveLength(1); expect(pricingResult.tiers[0].name).toBe('main'); expect(pricingResult.tiers[0].price.amount).toBe(10000); }); it('should retrieve sponsorship pricing with custom requirements', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured with custom requirements const pricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: true, customRequirements: 'Must have racing experience', mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: ['Primary logo placement'], }, }; await sponsorshipPricingRepository.create(pricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The result should contain sponsorship pricing expect(result.isOk()).toBe(true); const pricingResult = result.unwrap(); // And: The custom requirements should be included expect(pricingResult.customRequirements).toBe('Must have racing experience'); }); it('should retrieve sponsorship pricing with not accepting applications', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured but not accepting applications const pricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: false, mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: ['Primary logo placement'], }, }; await sponsorshipPricingRepository.create(pricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The result should contain sponsorship pricing expect(result.isOk()).toBe(true); const pricingResult = result.unwrap(); // And: The league should not be accepting applications expect(pricingResult.acceptingApplications).toBe(false); }); }); describe('GetEntitySponsorshipPricingUseCase - Error Handling', () => { it('should return error when pricing is not configured', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has no sponsorship pricing configured // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: Should return an error expect(result.isErr()).toBe(true); const error = result.unwrapErr(); expect(error.code).toBe('PRICING_NOT_CONFIGURED'); }); }); describe('Sponsor League Detail Data Orchestration', () => { it('should correctly retrieve sponsorship pricing with all tiers', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured with both main and secondary slots const pricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: true, customRequirements: 'Must have racing experience', mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: [ 'Primary logo placement on all liveries', 'League page header banner', 'Race results page branding', 'Social media feature posts', 'Newsletter sponsor spot', ], }, secondarySlots: { price: { amount: 2000, currency: 'USD' }, benefits: [ 'Secondary logo on liveries', 'League page sidebar placement', 'Race results mention', 'Social media mentions', ], }, }; await sponsorshipPricingRepository.create(pricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called const result = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The sponsorship pricing should be correctly retrieved expect(result.isOk()).toBe(true); const pricingResult = result.unwrap(); // And: The entity type should be correct expect(pricingResult.entityType).toBe('league'); // And: The entity ID should be correct expect(pricingResult.entityId).toBe(leagueId); // And: The league should be accepting applications expect(pricingResult.acceptingApplications).toBe(true); // And: The custom requirements should be included expect(pricingResult.customRequirements).toBe('Must have racing experience'); // And: The tiers should contain both main and secondary slots expect(pricingResult.tiers).toHaveLength(2); // And: The main slot should have correct price and benefits expect(pricingResult.tiers[0].name).toBe('main'); expect(pricingResult.tiers[0].price.amount).toBe(10000); expect(pricingResult.tiers[0].price.currency).toBe('USD'); expect(pricingResult.tiers[0].benefits).toHaveLength(5); expect(pricingResult.tiers[0].benefits).toContain('Primary logo placement on all liveries'); // And: The secondary slot should have correct price and benefits expect(pricingResult.tiers[1].name).toBe('secondary'); expect(pricingResult.tiers[1].price.amount).toBe(2000); expect(pricingResult.tiers[1].price.currency).toBe('USD'); expect(pricingResult.tiers[1].benefits).toHaveLength(4); expect(pricingResult.tiers[1].benefits).toContain('Secondary logo on liveries'); }); it('should correctly retrieve sponsorship pricing for different entity types', async () => { // Given: A league exists with ID "league-123" const leagueId = 'league-123'; // And: The league has sponsorship pricing configured const leaguePricing = { entityType: 'league' as const, entityId: leagueId, acceptingApplications: true, mainSlot: { price: { amount: 10000, currency: 'USD' }, benefits: ['Primary logo placement'], }, }; await sponsorshipPricingRepository.create(leaguePricing); // And: A team exists with ID "team-456" const teamId = 'team-456'; // And: The team has sponsorship pricing configured const teamPricing = { entityType: 'team' as const, entityId: teamId, acceptingApplications: true, mainSlot: { price: { amount: 5000, currency: 'USD' }, benefits: ['Team logo placement'], }, }; await sponsorshipPricingRepository.create(teamPricing); // When: GetEntitySponsorshipPricingUseCase.execute() is called for league const leagueResult = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'league', entityId: leagueId, }); // Then: The league pricing should be retrieved expect(leagueResult.isOk()).toBe(true); const leaguePricingResult = leagueResult.unwrap(); expect(leaguePricingResult.entityType).toBe('league'); expect(leaguePricingResult.entityId).toBe(leagueId); expect(leaguePricingResult.tiers[0].price.amount).toBe(10000); // When: GetEntitySponsorshipPricingUseCase.execute() is called for team const teamResult = await getEntitySponsorshipPricingUseCase.execute({ entityType: 'team', entityId: teamId, }); // Then: The team pricing should be retrieved expect(teamResult.isOk()).toBe(true); const teamPricingResult = teamResult.unwrap(); expect(teamPricingResult.entityType).toBe('team'); expect(teamPricingResult.entityId).toBe(teamId); expect(teamPricingResult.tiers[0].price.amount).toBe(5000); }); }); });