mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
test(vacay): catch the suites up with the comp/flex column
The kind column changed four things the tests still asserted the old way: toggleEntry gained a parameter, the toolbar gained the comp modifier, shared calendar rows carry kind, and a multi-person cell is now segment overlays instead of one split gradient. splitBackground went with it — nothing but the test still referenced it. The toolbar tests picked the half-day button by index, which the new button shifted; they select by name now so the next modifier does not break them.
This commit is contained in:
@@ -7,8 +7,8 @@ import { useVacayStore } from '../../store/vacayStore'
|
||||
import VacayCalendar from './VacayCalendar'
|
||||
|
||||
vi.mock('./VacayMonthCard', () => ({
|
||||
default: ({ month, onCellClick }: any) => (
|
||||
<div data-testid={`month-card-${month}`}>
|
||||
default: ({ year, month, onCellClick }: any) => (
|
||||
<div data-testid={`month-card-${month}`} data-year={year}>
|
||||
<button onClick={() => onCellClick(`2025-01-${String(month + 1).padStart(2, '0')}`)}>
|
||||
click-{month}
|
||||
</button>
|
||||
@@ -16,6 +16,8 @@ vi.mock('./VacayMonthCard', () => ({
|
||||
),
|
||||
}))
|
||||
|
||||
const fiscalJuly = { year_type: 'fiscal' as const, year_start_month: 7, year_start_day: 1, hire_date: null }
|
||||
|
||||
const basePlan = {
|
||||
id: 1,
|
||||
holidays_enabled: false,
|
||||
@@ -47,6 +49,51 @@ describe('VacayCalendar', () => {
|
||||
expect(screen.getAllByTestId(/^month-card-/)).toHaveLength(12)
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-001a: renders January to December of the selected year by default', () => {
|
||||
seedStore(useVacayStore, {
|
||||
selectedYear: 2025,
|
||||
entries: [],
|
||||
companyHolidays: [],
|
||||
holidays: {},
|
||||
plan: basePlan,
|
||||
users: [],
|
||||
selectedUserId: null,
|
||||
})
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
const cards = screen.getAllByTestId(/^month-card-/)
|
||||
expect(cards[0]).toHaveAttribute('data-testid', 'month-card-0')
|
||||
expect(cards[0]).toHaveAttribute('data-year', '2025')
|
||||
expect(cards[11]).toHaveAttribute('data-testid', 'month-card-11')
|
||||
expect(cards[11]).toHaveAttribute('data-year', '2025')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-001b: rolls the grid over the calendar year for a fiscal window (#737)', () => {
|
||||
seedStore(useVacayStore, {
|
||||
selectedYear: 2026,
|
||||
entries: [],
|
||||
companyHolidays: [],
|
||||
holidays: {},
|
||||
plan: basePlan,
|
||||
users: [],
|
||||
selectedUserId: null,
|
||||
yearSettings: fiscalJuly,
|
||||
})
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
const cards = screen.getAllByTestId(/^month-card-/)
|
||||
expect(cards).toHaveLength(12)
|
||||
// Jul 2026 first, Jan 2027 in the middle, Jun 2027 last.
|
||||
expect(cards[0]).toHaveAttribute('data-testid', 'month-card-6')
|
||||
expect(cards[0]).toHaveAttribute('data-year', '2026')
|
||||
expect(cards[6]).toHaveAttribute('data-testid', 'month-card-0')
|
||||
expect(cards[6]).toHaveAttribute('data-year', '2027')
|
||||
expect(cards[11]).toHaveAttribute('data-testid', 'month-card-5')
|
||||
expect(cards[11]).toHaveAttribute('data-year', '2027')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-002: shows vacation mode button by default with username', () => {
|
||||
seedStore(useVacayStore, {
|
||||
selectedYear: 2025,
|
||||
@@ -97,10 +144,10 @@ describe('VacayCalendar', () => {
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
// Vacation + half-day buttons stay; only the company button is hidden.
|
||||
// Vacation + the comp and half-day modifiers stay; only the company button is hidden.
|
||||
const buttons = screen.getAllByRole('button')
|
||||
const toolbarButtons = buttons.filter(b => !b.textContent?.startsWith('click-'))
|
||||
expect(toolbarButtons).toHaveLength(2)
|
||||
expect(toolbarButtons).toHaveLength(3)
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-005: switching to company mode highlights company button', async () => {
|
||||
@@ -149,7 +196,7 @@ describe('VacayCalendar', () => {
|
||||
// Click the first month card cell button (month 0 → date '2025-01-01')
|
||||
await user.click(screen.getByText('click-0'))
|
||||
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 1)
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 1, 'vacation')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-006b: half-day mode logs the day as 0.5', async () => {
|
||||
@@ -169,13 +216,58 @@ describe('VacayCalendar', () => {
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
// toolbarButtons[0] = vacation, [1] = half day
|
||||
const buttons = screen.getAllByRole('button')
|
||||
const toolbarButtons = buttons.filter(b => !b.textContent?.startsWith('click-'))
|
||||
await user.click(toolbarButtons[1])
|
||||
// Comp and half-day are both modifiers in the toolbar — pick by name, not position.
|
||||
await user.click(screen.getByRole('button', { name: 'Half day' }))
|
||||
await user.click(screen.getByText('click-0'))
|
||||
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 0.5)
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 0.5, 'vacation')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-006c: the comp modifier logs the day as a comp/flex day (#1074)', async () => {
|
||||
const user = userEvent.setup()
|
||||
const toggleEntry = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
seedStore(useVacayStore, {
|
||||
selectedYear: 2025,
|
||||
entries: [],
|
||||
companyHolidays: [],
|
||||
holidays: {},
|
||||
plan: { ...basePlan, block_weekends: false, company_holidays_enabled: false },
|
||||
users: [],
|
||||
selectedUserId: 42,
|
||||
toggleEntry,
|
||||
})
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'Comp / Flex' }))
|
||||
await user.click(screen.getByText('click-0'))
|
||||
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 1, 'comp')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-006d: comp and half-day stack into a half comp day (#1074)', async () => {
|
||||
const user = userEvent.setup()
|
||||
const toggleEntry = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
seedStore(useVacayStore, {
|
||||
selectedYear: 2025,
|
||||
entries: [],
|
||||
companyHolidays: [],
|
||||
holidays: {},
|
||||
plan: { ...basePlan, block_weekends: false, company_holidays_enabled: false },
|
||||
users: [],
|
||||
selectedUserId: 42,
|
||||
toggleEntry,
|
||||
})
|
||||
|
||||
render(<VacayCalendar />)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'Comp / Flex' }))
|
||||
await user.click(screen.getByRole('button', { name: 'Half day' }))
|
||||
await user.click(screen.getByText('click-0'))
|
||||
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', 42, 0.5, 'comp')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-007: cell click on public holiday toggles vacation entry', async () => {
|
||||
@@ -198,7 +290,7 @@ describe('VacayCalendar', () => {
|
||||
// Month 0, button emits '2025-01-01' which is a holiday — should still toggle vacation
|
||||
await user.click(screen.getByText('click-0'))
|
||||
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', undefined, 1)
|
||||
expect(toggleEntry).toHaveBeenCalledWith('2025-01-01', undefined, 1, 'vacation')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYCALENDAR-008: cell click in company mode calls toggleCompanyHoliday', async () => {
|
||||
|
||||
@@ -150,18 +150,87 @@ describe('VacayMonthCard', () => {
|
||||
expect(getFirstWeekLabels()).toEqual(['', '', '', '1', '2', '3', '4'])
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-011: Two vacation entries fill the cell with a split gradient', () => {
|
||||
it('FE-COMP-VACAYMONTHCARD-011: Two vacation entries split the cell into two clipped halves', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
entryMap: {
|
||||
'2025-01-15': [{ date: '2025-01-15', user_id: 1, person_color: '#6366f1' }, { date: '2025-01-15', user_id: 1, person_color: '#f43f5e' }],
|
||||
'2025-01-15': [{ date: '2025-01-15', user_id: 1, person_color: '#6366f1' }, { date: '2025-01-15', user_id: 2, person_color: '#f43f5e' }],
|
||||
},
|
||||
}
|
||||
render(<VacayMonthCard {...props} />)
|
||||
const daySpan = screen.getByText('15')
|
||||
const cell = daySpan.closest('div') as HTMLElement
|
||||
// The split gradient is the cell background itself (glass facelift).
|
||||
expect(cell.style.background).toContain('linear-gradient')
|
||||
// Each half is its own clipped overlay so it can be solid or hatched on its
|
||||
// own (#1074) — the diagonal is no longer one gradient on the cell itself.
|
||||
// jsdom normalises the hex inside color-mix() to rgb().
|
||||
const halves = [...cell.querySelectorAll<HTMLElement>('div')].filter(d => d.style.clipPath)
|
||||
expect(halves).toHaveLength(2)
|
||||
expect(halves[0].style.background).toContain('rgb(99, 102, 241)')
|
||||
expect(halves[1].style.background).toContain('rgb(244, 63, 94)')
|
||||
expect(halves.map(h => h.style.background).join()).not.toContain('repeating-linear-gradient')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-011a: a comp day hatches only its own half of the split (#1074)', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
entryMap: {
|
||||
'2025-01-15': [
|
||||
{ date: '2025-01-15', user_id: 1, person_color: '#6366f1', kind: 'comp' as const },
|
||||
{ date: '2025-01-15', user_id: 2, person_color: '#f43f5e' },
|
||||
],
|
||||
},
|
||||
}
|
||||
render(<VacayMonthCard {...props} />)
|
||||
const cell = screen.getByText('15').closest('div') as HTMLElement
|
||||
const halves = [...cell.querySelectorAll<HTMLElement>('div')].filter(d => d.style.clipPath)
|
||||
expect(halves[0].style.background).toContain('repeating-linear-gradient')
|
||||
expect(halves[1].style.background).not.toContain('repeating-linear-gradient')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-011b: a single comp day hatches the whole cell (#1074)', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
entryMap: {
|
||||
'2025-01-15': [{ date: '2025-01-15', user_id: 1, person_color: '#6366f1', kind: 'comp' as const }],
|
||||
},
|
||||
}
|
||||
render(<VacayMonthCard {...props} />)
|
||||
const cell = screen.getByText('15').closest('div') as HTMLElement
|
||||
expect(cell.style.background).toContain('repeating-linear-gradient')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-011c: an all-comp day keeps the white digit and gains a shadow to carry it (#1074)', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
entryMap: {
|
||||
'2025-01-15': [{ date: '2025-01-15', user_id: 1, person_color: '#6366f1', kind: 'comp' as const }],
|
||||
// A solid vacation fill needs no shadow — the fill itself is the contrast.
|
||||
'2025-01-16': [{ date: '2025-01-16', user_id: 1, person_color: '#6366f1' }],
|
||||
},
|
||||
}
|
||||
render(<VacayMonthCard {...props} />)
|
||||
const comp = screen.getByText('15')
|
||||
const vacation = screen.getByText('16')
|
||||
expect(comp).toHaveStyle({ color: '#fff' })
|
||||
// Only that the shadow is there — its exact strength is a design value.
|
||||
expect(comp.style.textShadow).not.toBe('')
|
||||
expect(vacation).toHaveStyle({ color: '#fff' })
|
||||
expect(vacation.style.textShadow).toBe('')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-011d: a mixed comp/vacation day needs no shadow — a solid half sits under the digit (#1074)', () => {
|
||||
const props = {
|
||||
...baseProps,
|
||||
entryMap: {
|
||||
'2025-01-15': [
|
||||
{ date: '2025-01-15', user_id: 1, person_color: '#6366f1', kind: 'comp' as const },
|
||||
{ date: '2025-01-15', user_id: 2, person_color: '#f43f5e' },
|
||||
],
|
||||
},
|
||||
}
|
||||
render(<VacayMonthCard {...props} />)
|
||||
expect(screen.getByText('15')).toHaveStyle({ color: '#fff' })
|
||||
expect(screen.getByText('15').style.textShadow).toBe('')
|
||||
})
|
||||
|
||||
it('FE-COMP-VACAYMONTHCARD-012: Four vacation entries render quadrant overlay', () => {
|
||||
|
||||
@@ -8,6 +8,9 @@ export const FALLBACK_PERSON_COLOR = '#6366f1'
|
||||
export interface DayVisual {
|
||||
background: string
|
||||
numColor: string
|
||||
// Set on hatched (comp/flex) cells, where the screen shows through between the
|
||||
// stripes and the digit needs its own contrast (#1074).
|
||||
textShadow?: string
|
||||
boxShadow?: string
|
||||
// At least one person logged this day as a half day (#552) — the cell shows a ½ badge.
|
||||
half?: boolean
|
||||
@@ -81,15 +84,6 @@ export function hatchTint(color: string): string {
|
||||
return `repeating-linear-gradient(45deg, ${color} 0 2.5px, transparent 2.5px 5px)`
|
||||
}
|
||||
|
||||
/** Hard split background when several persons logged the same day. */
|
||||
export function splitBackground(colors: string[]): string {
|
||||
const n = colors.length
|
||||
const stops = colors
|
||||
.map((c, i) => `${c} ${Math.round((i * 100) / n)}% ${Math.round(((i + 1) * 100) / n)}%`)
|
||||
.join(',')
|
||||
return `linear-gradient(105deg,${stops})`
|
||||
}
|
||||
|
||||
/**
|
||||
* Day-cell color matrix, priority top-down: today ring > company holiday >
|
||||
* logged persons (pastel, split for several) > public holiday > weekend >
|
||||
@@ -120,7 +114,13 @@ function baseDayVisual(dateStr: string, dayOfWeek: number, ctx: DayVisualContext
|
||||
const segments = entries.map(e => ({ color: personTint(e.person_color || FALLBACK_PERSON_COLOR), comp: e.kind === 'comp' }))
|
||||
const single = segments.length === 1
|
||||
const background = single ? (segments[0].comp ? hatchTint(segments[0].color) : segments[0].color) : 'transparent'
|
||||
// The pastel fills are theme-independent surfaces, so every logged day keeps
|
||||
// the same hard dark digit. An all-comp day is hatched, and the screen shows
|
||||
// through between its stripes — a light shadow carries the contrast there so
|
||||
// the digit survives dark mode without changing colour (#1074).
|
||||
const allComp = segments.every(s => s.comp)
|
||||
const visual: DayVisual = { background, numColor: '#101013', segments }
|
||||
if (allComp) visual.textShadow = '0 1px 2px rgba(255,255,255,0.9), 0 0 3px rgba(255,255,255,0.6)'
|
||||
if (entries.some(e => (e.fraction ?? 1) === 0.5)) visual.half = true
|
||||
return withSchool(visual)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { dayVisual, monthLead, personTint, splitBackground, type DayVisualContext } from '../../../../src/mobile/screens/vacay/vacayDayModel';
|
||||
import { dayVisual, hatchTint, monthLead, personTint, type DayVisualContext } from '../../../../src/mobile/screens/vacay/vacayDayModel';
|
||||
|
||||
// FE-MOB-VACAY-001 onwards
|
||||
|
||||
@@ -44,11 +44,13 @@ describe('vacayDayModel', () => {
|
||||
// ...but not when company holidays are disabled.
|
||||
expect(dayVisual('2026-07-15', 3, { ...notToday, companyHolidaysEnabled: false }).numColor).toBe('#101013');
|
||||
|
||||
// Logged person: pastel tint of the person color, hard dark digit.
|
||||
// Logged person: pastel tint of the person color, hard dark digit. One person
|
||||
// fills the cell directly and still reports the segment (#1074).
|
||||
const logged = ctx({ todayStr: '2026-01-01', entryMap: { '2026-07-15': [entry] } });
|
||||
expect(dayVisual('2026-07-15', 3, logged)).toEqual({
|
||||
background: personTint('#EC4899'),
|
||||
numColor: '#101013',
|
||||
segments: [{ color: personTint('#EC4899'), comp: false }],
|
||||
});
|
||||
|
||||
// Public holiday: calendar color fill.
|
||||
@@ -66,7 +68,7 @@ describe('vacayDayModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('FE-MOB-VACAY-002: splits logged days evenly and offsets month starts by week start', () => {
|
||||
it('FE-MOB-VACAY-002: splits logged days into segments and offsets month starts by week start', () => {
|
||||
const two = ctx({
|
||||
todayStr: '2026-01-01',
|
||||
entryMap: {
|
||||
@@ -76,10 +78,42 @@ describe('vacayDayModel', () => {
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(dayVisual('2026-07-15', 3, two).background).toBe(
|
||||
splitBackground([personTint('#EC4899'), personTint('#2FA9A0')]),
|
||||
);
|
||||
expect(splitBackground(['a', 'b'])).toBe('linear-gradient(105deg,a 0% 50%,b 50% 100%)');
|
||||
// Several persons render as segment overlays (#1074), so the cell itself stays
|
||||
// transparent underneath them and the split lives in `segments`.
|
||||
const shared = dayVisual('2026-07-15', 3, two);
|
||||
expect(shared.background).toBe('transparent');
|
||||
expect(shared.segments).toEqual([
|
||||
{ color: personTint('#EC4899'), comp: false },
|
||||
{ color: personTint('#2FA9A0'), comp: false },
|
||||
]);
|
||||
|
||||
// A comp/flex day marks its own segment without touching the other one.
|
||||
const mixed = ctx({
|
||||
todayStr: '2026-01-01',
|
||||
entryMap: {
|
||||
'2026-07-15': [
|
||||
{ date: '2026-07-15', user_id: 1, person_color: '#EC4899', kind: 'comp' as const },
|
||||
{ date: '2026-07-15', user_id: 2, person_color: '#2FA9A0' },
|
||||
],
|
||||
},
|
||||
});
|
||||
expect(dayVisual('2026-07-15', 3, mixed).segments).toEqual([
|
||||
{ color: personTint('#EC4899'), comp: true },
|
||||
{ color: personTint('#2FA9A0'), comp: false },
|
||||
]);
|
||||
|
||||
// A single comp day hatches the whole cell instead.
|
||||
const soloComp = ctx({
|
||||
todayStr: '2026-01-01',
|
||||
entryMap: { '2026-07-15': [{ date: '2026-07-15', user_id: 1, person_color: '#EC4899', kind: 'comp' as const }] },
|
||||
});
|
||||
expect(dayVisual('2026-07-15', 3, soloComp).background).toBe(hatchTint(personTint('#EC4899')));
|
||||
// The hatch lets the screen through, so the digit keeps its colour and gains a
|
||||
// light shadow to stay readable; a day with a solid segment needs none.
|
||||
expect(dayVisual('2026-07-15', 3, soloComp).numColor).toBe('#101013');
|
||||
expect(dayVisual('2026-07-15', 3, soloComp).textShadow).toBeTruthy();
|
||||
expect(dayVisual('2026-07-15', 3, mixed).numColor).toBe('#101013');
|
||||
expect(dayVisual('2026-07-15', 3, mixed).textShadow).toBeUndefined();
|
||||
|
||||
// July 2026 starts on a Wednesday: 2 leading cells Monday-first, 3 Sunday-first.
|
||||
expect(monthLead(2026, 6, 1)).toBe(2);
|
||||
|
||||
@@ -83,7 +83,7 @@ describe('Vacay e2e (real auth guard + temp SQLite)', () => {
|
||||
.set('Cookie', sessionCookie(1)).set('X-Socket-Id', 'sock-7').send({ date: '2026-07-01' });
|
||||
expect(res.status).toBe(200);
|
||||
expect(res.body).toEqual({ action: 'added' });
|
||||
expect(svc.toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', undefined, 'sock-7');
|
||||
expect(svc.toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', undefined, undefined, 'sock-7');
|
||||
});
|
||||
|
||||
it('400 on entries/toggle without a date', async () => {
|
||||
|
||||
@@ -137,13 +137,42 @@ describe('VacayController (parity with the legacy /api/addons/vacay route)', ()
|
||||
it('toggles for the caller', () => {
|
||||
const toggleEntry = vi.fn().mockReturnValue({ action: 'added' });
|
||||
expect(makeController({ ...planBase, toggleEntry }).toggleEntry(user, { date: '2026-07-01' }, 'sock')).toEqual({ action: 'added' });
|
||||
expect(toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', undefined, 'sock');
|
||||
expect(toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', undefined, undefined, 'sock');
|
||||
});
|
||||
|
||||
it('forwards the half-day fraction (#552)', () => {
|
||||
const toggleEntry = vi.fn().mockReturnValue({ action: 'added', fraction: 0.5 });
|
||||
makeController({ ...planBase, toggleEntry }).toggleEntry(user, { date: '2026-07-01', fraction: 0.5 }, 'sock');
|
||||
expect(toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', 0.5, 'sock');
|
||||
expect(toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', 0.5, undefined, 'sock');
|
||||
});
|
||||
|
||||
it('forwards the comp/flex leave type (#1074)', () => {
|
||||
const toggleEntry = vi.fn().mockReturnValue({ action: 'added', kind: 'comp' });
|
||||
makeController({ ...planBase, toggleEntry }).toggleEntry(user, { date: '2026-07-01', kind: 'comp' }, 'sock');
|
||||
expect(toggleEntry).toHaveBeenCalledWith(1, 10, '2026-07-01', undefined, 'comp', 'sock');
|
||||
});
|
||||
|
||||
it('GET reads entries over the caller window (#737)', () => {
|
||||
const getEntries = vi.fn().mockReturnValue({ entries: [], companyHolidays: [] });
|
||||
makeController({ ...planBase, getEntries }).entries(user, '2026');
|
||||
expect(getEntries).toHaveBeenCalledWith(10, '2026', 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('year settings (#737)', () => {
|
||||
it('GET wraps the caller settings', () => {
|
||||
const getYearSettings = vi.fn().mockReturnValue({ year_type: 'calendar' });
|
||||
expect(makeController({ getYearSettings }).yearSettings(user)).toEqual({ settings: { year_type: 'calendar' } });
|
||||
expect(getYearSettings).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it('PUT saves for the caller and returns the stored settings', () => {
|
||||
const updateYearSettings = vi.fn().mockReturnValue({ year_type: 'fiscal', year_start_month: 7, year_start_day: 1 });
|
||||
const body = { year_type: 'fiscal' as const, year_start_month: 7, year_start_day: 1 };
|
||||
expect(makeController({ updateYearSettings }).updateYearSettings(user, body)).toEqual({
|
||||
settings: { year_type: 'fiscal', year_start_month: 7, year_start_day: 1 },
|
||||
});
|
||||
expect(updateYearSettings).toHaveBeenCalledWith(1, body);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user