import { describe, it, expect, vi } from 'vitest'; import { SponsorshipViewModel } from './SponsorshipViewModel'; describe('SponsorshipViewModel', () => { const baseData = { id: 'sp-1', type: 'leagues' as const, entityId: 'league-1', entityName: 'Pro League', tier: 'main' as const, status: 'active' as const, applicationDate: '2025-01-01T00:00:00Z', approvalDate: '2025-01-02T00:00:00Z', startDate: '2025-01-10T00:00:00Z', endDate: '2025-02-10T00:00:00Z', price: 5_000, impressions: 50_000, impressionsChange: 10, engagement: 3.5, details: 'Full season branding', entityOwner: 'League Owner', applicationMessage: 'Excited to sponsor', }; it('maps core fields and converts dates', () => { const vm = new SponsorshipViewModel(baseData); expect(vm.id).toBe(baseData.id); expect(vm.type).toBe(baseData.type); expect(vm.entityId).toBe(baseData.entityId); expect(vm.entityName).toBe(baseData.entityName); expect(vm.tier).toBe(baseData.tier); expect(vm.status).toBe(baseData.status); expect(vm.applicationDate).toBeInstanceOf(Date); expect(vm.approvalDate).toBeInstanceOf(Date); expect(vm.startDate).toBeInstanceOf(Date); expect(vm.endDate).toBeInstanceOf(Date); expect(vm.price).toBe(baseData.price); expect(vm.impressions).toBe(baseData.impressions); expect(vm.impressionsChange).toBe(baseData.impressionsChange); expect(vm.engagement).toBe(baseData.engagement); expect(vm.details).toBe(baseData.details); expect(vm.entityOwner).toBe(baseData.entityOwner); expect(vm.applicationMessage).toBe(baseData.applicationMessage); }); it('exposes formatted impressions and price', () => { const vm = new SponsorshipViewModel(baseData); expect(vm.formattedImpressions).toBe(baseData.impressions.toLocaleString()); expect(vm.formattedPrice).toBe(`$${baseData.price}`); }); it('computes daysRemaining and expiringSoon based on endDate', () => { const now = new Date('2025-01-01T00:00:00Z'); vi.setSystemTime(now); const vm = new SponsorshipViewModel({ ...baseData, endDate: '2025-01-15T00:00:00Z', }); expect(vm.daysRemaining).toBeGreaterThan(0); expect(vm.isExpiringSoon).toBe(true); const farFuture = new SponsorshipViewModel({ ...baseData, endDate: '2025-12-31T00:00:00Z', }); expect(farFuture.isExpiringSoon).toBe(false); const past = new SponsorshipViewModel({ ...baseData, endDate: '2024-12-31T00:00:00Z', }); expect(past.daysRemaining).toBeLessThanOrEqual(0); expect(past.isExpiringSoon).toBe(false); vi.useRealTimers(); }); it('derives human-readable status and type labels', () => { const active = new SponsorshipViewModel({ ...baseData, status: 'active' }); const pending = new SponsorshipViewModel({ ...baseData, status: 'pending_approval' }); const approved = new SponsorshipViewModel({ ...baseData, status: 'approved' }); const rejected = new SponsorshipViewModel({ ...baseData, status: 'rejected' }); const expired = new SponsorshipViewModel({ ...baseData, status: 'expired' }); expect(active.statusLabel).toBe('Active'); expect(pending.statusLabel).toBe('Awaiting Approval'); expect(approved.statusLabel).toBe('Approved'); expect(rejected.statusLabel).toBe('Declined'); expect(expired.statusLabel).toBe('Expired'); const league = new SponsorshipViewModel({ ...baseData, type: 'leagues' }); const team = new SponsorshipViewModel({ ...baseData, type: 'teams' }); const driver = new SponsorshipViewModel({ ...baseData, type: 'drivers' }); const race = new SponsorshipViewModel({ ...baseData, type: 'races' }); const platform = new SponsorshipViewModel({ ...baseData, type: 'platform' }); expect(league.typeLabel).toBe('League'); expect(team.typeLabel).toBe('Team'); expect(driver.typeLabel).toBe('Driver'); expect(race.typeLabel).toBe('Race'); expect(platform.typeLabel).toBe('Platform'); }); it('formats sponsorship period as month-year range', () => { const vm = new SponsorshipViewModel({ ...baseData, startDate: '2025-01-10T00:00:00Z', endDate: '2025-03-10T00:00:00Z', }); const [start, end] = vm.periodDisplay.split(' - '); expect(typeof start).toBe('string'); expect(typeof end).toBe('string'); expect(start.length).toBeGreaterThan(0); expect(end.length).toBeGreaterThan(0); }); });