view models
This commit is contained in:
123
apps/website/lib/view-models/SponsorshipViewModel.test.ts
Normal file
123
apps/website/lib/view-models/SponsorshipViewModel.test.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user