/** * The two authoring gestures the calendar rework is actually about: * dragging a range to create a period, and deleting one again through its * popover. Neither was covered end-to-end before — the existing specs only * check rendering (bands, red days, age-4 figures) of state the API seeded * directly. * * Uses a brand-new, empty account (see `support/onboarding.ts`) rather than * the shared demo workspace: `Calendar.tsx`'s drag-to-create always pins the * new period to the CURRENTLY LOGGED-IN parent * (`parentMode: 'specific', parentPersonalDataUuid: personalDataUuid`), and * the demo user (Alex) is deliberately seeded with a fully drained * sjukpenning/lägstanivå pool (see `backend/scripts/seed_demo.py`'s "near- * drained FP pool") so that its one low-priority wish always shows a real * shortfall — a 3-day drag by Alex would fail to fund for the same reason, * which isn't what this test is about. A fresh account with no manual fetch * gets the full statutory-assumption pool instead (see * `AllocationInputLoader.load`'s "No FK snapshot yet" fallback), which is * always enough for a 3-day period. * * The target month is derived from "today" (never a hardcoded year). */ import { test, expect } from '@playwright/test' import { goToCalendarMonth, calendarDayCell, dragSelectDates } from '../support/calendarNav' import { toIsoDate } from '../support/dates' import { uniqueEmail, registerAndReachOnboarding, fillChildStep, continueSoloAndSkipBalances } from '../support/onboarding' test.use({ storageState: { cookies: [], origins: [] } }) function targetRange(): { month: Date; dates: [string, string, string] } { const now = new Date() // Two months out and mid-month (the 10th–12th), so the range can never // land on a leading/trailing day of an adjacent month — `CalendarWeek.tsx` // only wires pointer handlers for cells belonging to the currently // displayed month. const month = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 2, 1)) const dates = [10, 11, 12].map((day) => toIsoDate(new Date(Date.UTC(month.getUTCFullYear(), month.getUTCMonth(), day))), ) as [string, string, string] return { month, dates } } test('dragging a range creates a period, and deleting it removes the days for good', async ({ page }) => { await registerAndReachOnboarding(page, uniqueEmail('drag-delete'), 'Robin Testsson') await fillChildStep(page, 'Nova') await continueSoloAndSkipBalances(page) const { month, dates } = targetRange() const [startDate, , endDate] = dates await goToCalendarMonth(page, month) const wishBand = page.locator('[data-testid^="calendar-band-wish:"]') await expect(wishBand).toHaveCount(0) // a brand-new account — nothing here yet await dragSelectDates(page, dates) // A toast reports the change (Calendar.tsx's `buildSyncToastMessage`), // and the dragged range now renders as one band. await expect(page.getByTestId('calendar-toast')).toBeVisible() await expect(wishBand).toHaveCount(1) // Open the new period through its band and delete it — via the in-app // confirmation from PeriodPopover.tsx, not a native `window.confirm`. await wishBand.click() await expect(page.getByTestId('period-popover__content')).toBeVisible() await expect(page.getByTestId('period-start-input')).toHaveValue(startDate) await expect(page.getByTestId('period-end-input')).toHaveValue(endDate) await page.getByTestId('period-delete-button').click() await expect(page.getByTestId('period-delete-confirm')).toBeVisible() await page.getByTestId('period-delete-confirm-button').click() await expect(page.getByTestId('period-popover__overlay')).not.toBeVisible() // The regression this guards ("Remove a period's days along with the // period"): the underlying planned days must actually be gone // server-side, not merely dropped from client state. A reload refetches // from the API, so this is the assertion a surviving-days bug would fail. await page.reload() await goToCalendarMonth(page, month) await expect(page.locator('[data-testid^="calendar-band-wish:"]')).toHaveCount(0) // And the day itself is empty again — clicking it opens the "plan a new // day" modal, not an edit of a day that supposedly no longer exists. await calendarDayCell(page, dates[1]).click() await expect(page.getByTestId('modal-title')).toHaveText('Planera en dag') })