- Add AllocationController with CRUD + bulk endpoints - Add AllocationValidationService for capacity/estimate validation - Add AllocationMatrixService for optimized matrix queries - Add AllocationPolicy for authorization - Add AllocationResource for API responses - Add frontend allocationService and matrix UI - Add E2E tests for allocation matrix (20 tests) - Add unit tests for validation service and policies - Fix month format conversion (YYYY-MM to YYYY-MM-01)
117 lines
2.9 KiB
TypeScript
117 lines
2.9 KiB
TypeScript
import { fireEvent, render, screen } from '@testing-library/svelte';
|
|
import { describe, expect, it } from 'vitest';
|
|
import CapacityCalendar from '$lib/components/capacity/CapacityCalendar.svelte';
|
|
import CapacitySummary from '$lib/components/capacity/CapacitySummary.svelte';
|
|
import type { Capacity, Revenue, TeamCapacity } from '$lib/types/capacity';
|
|
|
|
describe('capacity components', () => {
|
|
it('4.1.25 CapacityCalendar displays selected month', () => {
|
|
const capacity: Capacity = {
|
|
team_member_id: 'member-1',
|
|
month: '2026-02',
|
|
working_days: 20,
|
|
person_days: 20,
|
|
hours: 160,
|
|
details: [
|
|
{
|
|
date: '2026-02-02',
|
|
day_of_week: 1,
|
|
is_weekend: false,
|
|
is_holiday: false,
|
|
is_pto: false,
|
|
availability: 1,
|
|
effective_hours: 8
|
|
}
|
|
]
|
|
};
|
|
|
|
render(CapacityCalendar, {
|
|
props: {
|
|
month: '2026-02',
|
|
capacity,
|
|
holidays: [],
|
|
ptos: []
|
|
}
|
|
});
|
|
|
|
expect(screen.getByTestId('capacity-calendar')).toBeTruthy();
|
|
expect(screen.getByText('2026-02')).toBeTruthy();
|
|
expect(screen.getByText('Working days: 20')).toBeTruthy();
|
|
});
|
|
|
|
it('4.1.26 Availability editor toggles values', async () => {
|
|
const capacity: Capacity = {
|
|
team_member_id: 'member-1',
|
|
month: '2026-02',
|
|
working_days: 20,
|
|
person_days: 20,
|
|
hours: 160,
|
|
details: [
|
|
{
|
|
date: '2026-02-10',
|
|
day_of_week: 2,
|
|
is_weekend: false,
|
|
is_holiday: false,
|
|
is_pto: false,
|
|
availability: 1,
|
|
effective_hours: 8
|
|
}
|
|
]
|
|
};
|
|
|
|
render(CapacityCalendar, {
|
|
props: {
|
|
month: '2026-02',
|
|
capacity,
|
|
holidays: [],
|
|
ptos: []
|
|
}
|
|
});
|
|
|
|
const select = screen.getByLabelText('Availability for 2026-02-10') as HTMLSelectElement;
|
|
expect(select.value).toBe('1');
|
|
|
|
await fireEvent.change(select, { target: { value: '0.5' } });
|
|
|
|
expect(select.value).toBe('0.5');
|
|
});
|
|
|
|
it('4.1.27 CapacitySummary shows totals', () => {
|
|
const teamCapacity: TeamCapacity = {
|
|
month: '2026-02',
|
|
total_person_days: 57,
|
|
total_hours: 456,
|
|
member_capacities: [
|
|
{
|
|
team_member_id: 'm1',
|
|
team_member_name: 'VJ',
|
|
role: 'Frontend Dev',
|
|
person_days: 19,
|
|
hours: 152,
|
|
hourly_rate: 80
|
|
}
|
|
]
|
|
};
|
|
|
|
const revenue: Revenue = {
|
|
month: '2026-02',
|
|
total_revenue: 45600,
|
|
member_revenues: []
|
|
};
|
|
|
|
render(CapacitySummary, {
|
|
props: {
|
|
teamCapacity,
|
|
revenue,
|
|
teamMembers: []
|
|
}
|
|
});
|
|
|
|
expect(screen.getByTestId('team-capacity-card')).toBeTruthy();
|
|
expect(screen.getByTestId('possible-revenue-card')).toBeTruthy();
|
|
expect(screen.getByText('57.0d')).toBeTruthy();
|
|
expect(screen.getByText('456 hrs')).toBeTruthy();
|
|
expect(screen.getByText('$45,600.00')).toBeTruthy();
|
|
});
|
|
});
|