124 lines
4.4 KiB
TypeScript
124 lines
4.4 KiB
TypeScript
import { describe, expect, it, 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('$5,000.00');
|
|
});
|
|
|
|
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);
|
|
});
|
|
});
|