Files
gridpilot.gg/apps/website/lib/view-models/PrizeViewModel.test.ts
2026-01-24 01:25:46 +01:00

89 lines
3.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { PrizeViewModel } from './PrizeViewModel';
const createPrizeDto = (overrides: Partial<any> = {}): any => ({
id: 'prize-1',
leagueId: 'league-1',
seasonId: 'season-1',
position: 1,
name: 'Main Prize',
amount: 100,
type: 'cash',
description: 'Top prize',
awarded: false,
awardedTo: undefined,
awardedAt: undefined,
createdAt: new Date('2024-01-01T00:00:00Z'),
...overrides,
});
describe('PrizeViewModel', () => {
it('maps DTO fields via Object.assign', () => {
const dto = createPrizeDto();
const vm = new PrizeViewModel(dto);
expect(vm.id).toBe('prize-1');
expect(vm.leagueId).toBe('league-1');
expect(vm.position).toBe(1);
expect(vm.amount).toBe(100);
});
it('formats amount as EUR currency string', () => {
const vm = new PrizeViewModel(createPrizeDto({ amount: 50.25 }));
expect(vm.formattedAmount).toBe('€50.25');
});
it('formats positionDisplay based on position', () => {
const first = new PrizeViewModel(createPrizeDto({ position: 1 }));
const second = new PrizeViewModel(createPrizeDto({ position: 2 }));
const third = new PrizeViewModel(createPrizeDto({ position: 3 }));
const other = new PrizeViewModel(createPrizeDto({ position: 4 }));
expect(first.positionDisplay).toBe('1st Place');
expect(second.positionDisplay).toBe('2nd Place');
expect(third.positionDisplay).toBe('3rd Place');
expect(other.positionDisplay).toBe('4th Place');
});
it('maps type to human readable typeDisplay', () => {
const cash = new PrizeViewModel(createPrizeDto({ type: 'cash' }));
const merchandise = new PrizeViewModel(createPrizeDto({ type: 'merchandise' }));
const other = new PrizeViewModel(createPrizeDto({ type: 'other' }));
const unknown = new PrizeViewModel(createPrizeDto({ type: 'custom' }));
expect(cash.typeDisplay).toBe('Cash Prize');
expect(merchandise.typeDisplay).toBe('Merchandise');
expect(other.typeDisplay).toBe('Other');
expect(unknown.typeDisplay).toBe('custom');
});
it('derives statusDisplay and statusColor from awarded flag', () => {
const available = new PrizeViewModel(createPrizeDto({ awarded: false }));
const awarded = new PrizeViewModel(createPrizeDto({ awarded: true }));
expect(available.statusDisplay).toBe('Available');
expect(available.statusColor).toBe('blue');
expect(awarded.statusDisplay).toBe('Awarded');
expect(awarded.statusColor).toBe('green');
});
it('builds prizeDescription from name and amount', () => {
const vm = new PrizeViewModel(createPrizeDto({ name: 'Bonus', amount: 25 }));
expect(vm.prizeDescription).toBe('Bonus - €25.00');
});
it('formats awardedAt and createdAt timestamps', () => {
const awardedAt = new Date('2024-01-02T00:00:00Z');
const vm = new PrizeViewModel(createPrizeDto({ awarded: true, awardedAt }));
expect(typeof vm.formattedAwardedAt).toBe('string');
expect(typeof vm.formattedCreatedAt).toBe('string');
const notAwarded = new PrizeViewModel(createPrizeDto({ awarded: false, awardedAt: undefined }));
expect(notAwarded.formattedAwardedAt).toBe('Not awarded');
});
});