35e479a005
Three changes to calendar editing, too interleaved in the same files to land separately. Giving the same days to the second parent rewrote the first parent's days instead of adding their own. The save looked the existing day up against whoever was logged in rather than the parent being saved for, so parent A's leave turned into parent B's vacation. The parent choice now lives with the lookup, and two parents on the same dates produce two rows and two bands. Drawing a period by hand meant naming a day type up front. It now asks who is off and lets the planner fund it, as a one-off period the sync places, with double days offered when both parents are off and priced honestly in the hint. Pinning an exact day type is still there, moved behind Advanced, and editing a pinned day goes straight back to it. Removing a period offered only the two extremes. There are now three choices: this day, this year's period, or every year. Taking one year out of a repeating period narrows it, or splits it in two when the year is in the middle; where a scope cannot be expressed it is disabled with a reason rather than doing something surprising. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ei7gCZzdd751uZtPzb1Pep
211 lines
5.7 KiB
TypeScript
211 lines
5.7 KiB
TypeScript
/**
|
|
* Shared test fixtures — domain entities.
|
|
*
|
|
* Prefer the `make*` factories over the `MOCK_*` constants in new tests: a
|
|
* factory returns a complete, correctly-typed object, so overriding one field
|
|
* can't silently leave the rest `undefined`/wrong the way a hand-rolled
|
|
* partial object cast with `as any` can. See `frontend/tests/fixtures/index.ts`
|
|
* for the full barrel of factories (plan, analytics, calendar, scraper, hooks).
|
|
*/
|
|
|
|
import type {
|
|
Child,
|
|
DayOverride,
|
|
LeaveWish,
|
|
ParentalLeaveFetch,
|
|
PersonalData,
|
|
PlannedLeaveDay,
|
|
TierData,
|
|
Tip,
|
|
VacationDays,
|
|
Workspace,
|
|
} from '@/types'
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Workspace
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeWorkspace(overrides: Partial<Workspace> = {}): Workspace {
|
|
return {
|
|
id: 'ws-1',
|
|
name: 'Familjen Testsson',
|
|
createdAt: '2026-01-01T00:00:00',
|
|
takePlOnRedDays: false,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Personal data (parents)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makePersonalData(overrides: Partial<PersonalData> = {}): PersonalData {
|
|
return {
|
|
uuid: 'pd-a',
|
|
workspaceId: 'ws-1',
|
|
name: 'Förälder A',
|
|
salaryType: 'monthly',
|
|
employmentStatus: 'employed',
|
|
createdAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Child
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeChild(overrides: Partial<Child> = {}): Child {
|
|
return {
|
|
id: 'child-1',
|
|
workspaceId: 'ws-1',
|
|
name: 'Barnet',
|
|
birthDate: '2025-06-01',
|
|
preschoolStartDate: null,
|
|
preschoolPlanningDaysPerYear: 6,
|
|
createdAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Vacation days
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeVacationDays(overrides: Partial<VacationDays> = {}): VacationDays {
|
|
return {
|
|
id: 'vd-1',
|
|
personalDataUuid: 'pd-a',
|
|
workspaceId: 'ws-1',
|
|
year: 2026,
|
|
totalDays: 25,
|
|
savedDaysIn: 0,
|
|
createdAt: '2026-01-01T00:00:00',
|
|
updatedAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Parental leave fetch (+ tier data)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeTierData(overrides: Partial<TierData> = {}): TierData {
|
|
return {
|
|
sjukpenningTotal: 390,
|
|
sjukpenningUsed: 80,
|
|
sjukpenningLeft: 310,
|
|
lagstaNivaTotal: 90,
|
|
lagstaNivaUsed: 0,
|
|
lagstaNivaLeft: 90,
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
export function makeParentalLeaveFetch(overrides: Partial<ParentalLeaveFetch> = {}): ParentalLeaveFetch {
|
|
return {
|
|
id: 'plf-1',
|
|
personalDataUuid: 'pd-a',
|
|
workspaceId: 'ws-1',
|
|
childId: 'child-1',
|
|
source: 'manual',
|
|
fetchedAt: '2026-05-01T10:00:00',
|
|
totalDays: 240,
|
|
daysUsed: 80,
|
|
daysLeft: 160,
|
|
reservedDaysTotal: 90,
|
|
reservedDaysLeft: 70,
|
|
transferableDaysLeft: 50,
|
|
dubbeldagarLeft: 55,
|
|
tierData: makeTierData(),
|
|
createdAt: '2026-05-01T10:00:00',
|
|
updatedAt: '2026-05-01T10:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Leave wishes
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeLeaveWish(overrides: Partial<LeaveWish> = {}): LeaveWish {
|
|
return {
|
|
id: 'lw-1',
|
|
workspaceId: 'ws-1',
|
|
childId: null,
|
|
name: 'Sommar',
|
|
nameMessageKey: null,
|
|
windowStartMonth: 6,
|
|
windowStartDay: 15,
|
|
windowEndMonth: 7,
|
|
windowEndDay: 26,
|
|
targetWeeks: 6,
|
|
targetDays: null,
|
|
recurrence: 'yearly',
|
|
firstYear: 2026,
|
|
lastYear: null,
|
|
priority: 1,
|
|
parentMode: 'either',
|
|
parentPersonalDataUuid: null,
|
|
windowMode: 'fixed',
|
|
wantsDubbeldag: false,
|
|
createdAt: '2026-01-01T00:00:00',
|
|
updatedAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Planned leave days
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makePlannedLeaveDay(overrides: Partial<PlannedLeaveDay> = {}): PlannedLeaveDay {
|
|
return {
|
|
id: 'pld-1',
|
|
workspaceId: 'ws-1',
|
|
childId: 'child-1',
|
|
parentPersonalDataUuid: 'pd-a',
|
|
date: '2026-06-15',
|
|
dayType: 'vacation',
|
|
isDubbeldag: false,
|
|
wishId: null,
|
|
isPinned: false,
|
|
createdAt: '2026-01-01T00:00:00',
|
|
updatedAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Day overrides (calendar exceptions)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeDayOverride(overrides: Partial<DayOverride> = {}): DayOverride {
|
|
return {
|
|
id: 'do-1',
|
|
workspaceId: 'ws-1',
|
|
date: '2026-12-24',
|
|
isWorkingDay: false,
|
|
note: null,
|
|
createdAt: '2026-01-01T00:00:00',
|
|
updatedAt: '2026-01-01T00:00:00',
|
|
...overrides,
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Tips
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export function makeTip(overrides: Partial<Tip> = {}): Tip {
|
|
return {
|
|
id: 'tip-1',
|
|
severity: 'info',
|
|
messageKey: 'tips.example',
|
|
data: {},
|
|
anchorDate: null,
|
|
anchorRange: null,
|
|
...overrides,
|
|
}
|
|
}
|