Give a new account a first run, and drop to three tabs
Registering used to land you on a bare form asking for a child, with no hint what came next. A short wizard now walks through the child, whether you are planning alone or together, and where the day balances come from: fetched from Försäkringskassan, entered by hand, or skipped — and if skipped, the figures carry a badge saying they are estimates until real ones arrive. Fetching is the first option rather than a hidden one, so the scraper is on by default and the script that used to force it on no longer needs to. Planning and Tips lose their tabs. Authoring moved to the calendar and the figures moved to the overview, so both pages were only a second way to reach what is already on screen; their routes now redirect rather than dead-end. The dead translations went with them. Dates also follow the chosen language now instead of always formatting as Swedish.
This commit is contained in:
@@ -38,6 +38,13 @@ vi.mock('@/components/layout/Layout', () => ({
|
||||
Layout: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
|
||||
}))
|
||||
|
||||
// Dashboard hands off to Onboarding entirely when there are no children yet —
|
||||
// stub it out so this file only asserts the hand-off happens, not
|
||||
// Onboarding's own behaviour (covered by Onboarding.test.tsx).
|
||||
vi.mock('@/pages/Onboarding', () => ({
|
||||
Onboarding: () => <div data-testid="onboarding-page">Onboarding</div>,
|
||||
}))
|
||||
|
||||
const renderWithRouter = (component: React.ReactElement) => {
|
||||
return render(<BrowserRouter>{component}</BrowserRouter>)
|
||||
}
|
||||
@@ -136,7 +143,7 @@ describe('Dashboard', () => {
|
||||
expect(screen.getByText(/Laddar/)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows add child form when no children', () => {
|
||||
it('hands off to Onboarding when there are no children yet', () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(
|
||||
makeWorkspaceContextValue({
|
||||
workspace: { id: 'ws-1', name: 'Test Workspace', planningMode: 'solo', createdAt: '2026-01-01' },
|
||||
@@ -148,8 +155,21 @@ describe('Dashboard', () => {
|
||||
})
|
||||
)
|
||||
renderWithRouter(<Dashboard />)
|
||||
expect(screen.getByText(/Du har inga barn registrerade ännu/)).toBeInTheDocument()
|
||||
expect(screen.getByLabelText(/Barnets namn/)).toBeInTheDocument()
|
||||
expect(screen.getByTestId('onboarding-page')).toBeInTheDocument()
|
||||
expect(screen.queryByTestId('dashboard')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
describe('estimated-figures badge', () => {
|
||||
it('is hidden once real parental-leave balances have been fetched (the default mock)', () => {
|
||||
renderWithRouter(<Dashboard />)
|
||||
expect(screen.queryByTestId('dashboard-estimate-badge')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('is shown when no parental-leave balance has ever been fetched, labelling the figures as estimates', () => {
|
||||
vi.mocked(hooks.useParentalLeave).mockReturnValue(makeParentalLeaveResult({ data: null }))
|
||||
renderWithRouter(<Dashboard />)
|
||||
expect(screen.getByTestId('dashboard-estimate-badge')).toHaveTextContent('Uppskattat')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Hero', () => {
|
||||
@@ -396,133 +416,6 @@ describe('Dashboard', () => {
|
||||
expect(button).not.toBeDisabled()
|
||||
})
|
||||
|
||||
it('submits add child form with valid data', async () => {
|
||||
const user = userEvent.setup()
|
||||
const mockCreateChild = vi.fn().mockResolvedValue({ id: 'c-2', name: 'New Child', birth_date: '2024-01-15' })
|
||||
const mockRefreshContext = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
vi.mocked(useWorkspace).mockReturnValue(
|
||||
makeWorkspaceContextValue({
|
||||
workspace: { id: 'ws-1', name: 'Test Workspace', planningMode: 'solo', createdAt: '2026-01-01' },
|
||||
workspaceId: 'ws-1',
|
||||
children: [],
|
||||
selectedChildId: null,
|
||||
personalDataUuid: 'pd-1',
|
||||
parentName: 'Test Parent',
|
||||
refreshContext: mockRefreshContext,
|
||||
})
|
||||
)
|
||||
|
||||
const mockApi = await import('@/services/api')
|
||||
vi.mocked(mockApi.createChild).mockImplementation(mockCreateChild)
|
||||
|
||||
renderWithRouter(<Dashboard />)
|
||||
|
||||
const nameInput = screen.getByLabelText(/Barnets namn/)
|
||||
const birthDateInput = screen.getByTestId('birth-date-input')
|
||||
const submitButton = screen.getByRole('button', { name: /Lägg till barn/ })
|
||||
|
||||
await user.type(nameInput, 'Test Child')
|
||||
await user.type(birthDateInput, '2024-01-15')
|
||||
await user.click(submitButton)
|
||||
|
||||
expect(mockCreateChild).toHaveBeenCalledWith({
|
||||
workspace_id: 'ws-1',
|
||||
name: 'Test Child',
|
||||
birth_date: '2024-01-15',
|
||||
})
|
||||
expect(mockRefreshContext).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('shows error when add child form submission fails', async () => {
|
||||
const user = userEvent.setup()
|
||||
const mockCreateChild = vi.fn().mockRejectedValue(new Error('API error'))
|
||||
|
||||
vi.mocked(useWorkspace).mockReturnValue(
|
||||
makeWorkspaceContextValue({
|
||||
workspace: { id: 'ws-1', name: 'Test Workspace', planningMode: 'solo', createdAt: '2026-01-01' },
|
||||
workspaceId: 'ws-1',
|
||||
children: [],
|
||||
selectedChildId: null,
|
||||
personalDataUuid: 'pd-1',
|
||||
parentName: 'Test Parent',
|
||||
})
|
||||
)
|
||||
|
||||
const mockApi = await import('@/services/api')
|
||||
vi.mocked(mockApi.createChild).mockImplementation(mockCreateChild)
|
||||
|
||||
renderWithRouter(<Dashboard />)
|
||||
|
||||
const nameInput = screen.getByLabelText(/Barnets namn/)
|
||||
const birthDateInput = screen.getByTestId('birth-date-input')
|
||||
const submitButton = screen.getByRole('button', { name: /Lägg till barn/ })
|
||||
|
||||
await user.type(nameInput, 'Test Child')
|
||||
await user.type(birthDateInput, '2024-01-15')
|
||||
await user.click(submitButton)
|
||||
|
||||
expect(screen.getByText(/API error/)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('disables submit button during form submission', async () => {
|
||||
const user = userEvent.setup()
|
||||
const mockCreateChild = vi.fn().mockImplementation(
|
||||
() => new Promise(resolve => setTimeout(() => resolve({ id: 'c-2' }), 100))
|
||||
)
|
||||
|
||||
vi.mocked(useWorkspace).mockReturnValue(
|
||||
makeWorkspaceContextValue({
|
||||
workspace: { id: 'ws-1', name: 'Test Workspace', planningMode: 'solo', createdAt: '2026-01-01' },
|
||||
workspaceId: 'ws-1',
|
||||
children: [],
|
||||
selectedChildId: null,
|
||||
personalDataUuid: 'pd-1',
|
||||
parentName: 'Test Parent',
|
||||
refreshContext: vi.fn().mockResolvedValue(undefined),
|
||||
})
|
||||
)
|
||||
|
||||
const mockApi = await import('@/services/api')
|
||||
vi.mocked(mockApi.createChild).mockImplementation(mockCreateChild)
|
||||
|
||||
renderWithRouter(<Dashboard />)
|
||||
|
||||
const nameInput = screen.getByLabelText(/Barnets namn/)
|
||||
const birthDateInput = screen.getByTestId('birth-date-input')
|
||||
const submitButton = screen.getByRole('button', { name: /Lägg till barn/ })
|
||||
|
||||
await user.type(nameInput, 'Test Child')
|
||||
await user.type(birthDateInput, '2024-01-15')
|
||||
await user.click(submitButton)
|
||||
|
||||
expect(submitButton).toBeDisabled()
|
||||
})
|
||||
|
||||
it('validates add child form with workspace check', async () => {
|
||||
vi.mocked(useWorkspace).mockReturnValue(
|
||||
makeWorkspaceContextValue({
|
||||
workspace: null,
|
||||
children: [],
|
||||
selectedChildId: null,
|
||||
})
|
||||
)
|
||||
|
||||
renderWithRouter(<Dashboard />)
|
||||
|
||||
const nameInput = screen.getByLabelText(/Barnets namn/)
|
||||
const birthDateInput = screen.getByTestId('birth-date-input')
|
||||
|
||||
const user = userEvent.setup()
|
||||
await user.type(nameInput, 'Test Child')
|
||||
await user.type(birthDateInput, '2024-01-15')
|
||||
|
||||
const submitButton = screen.getByRole('button', { name: /Lägg till barn/ })
|
||||
await user.click(submitButton)
|
||||
|
||||
expect(screen.getByText(/Fyll i alla fält/)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('has manual fetch button enabled when child selected', () => {
|
||||
renderWithRouter(<Dashboard />)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user