import { test, expect } from '@playwright/experimental-ct-react' import { DegreeCourseTableWrapper } from './DegreeCourseTableWrapper' test.describe('DegreeCourseTable', () => { let criteriaRequests: unknown[] let exclusionRequests: { method: string; body: unknown }[] test.beforeEach(async ({ router }) => { criteriaRequests = [] exclusionRequests = [] await router.route('**/api/login', route => route.fulfill({ json: { user: { roles: [] } } })) await router.route('**/api/banners', route => route.fulfill({ json: [] })) await router.route('**/api/programme-criteria/courses', route => { criteriaRequests.push(route.request().postDataJSON()) return route.fulfill({ json: {} }) }) await router.route('**/api/course-exclusions/', route => { exclusionRequests.push({ method: route.request().method(), body: route.request().postDataJSON() }) return route.fulfill({ json: [] }) }) }) test('shows year columns and required course counts instead of criterion labels', async ({ mount }) => { const component = await mount() await expect(component.getByRole('columnheader')).toHaveText([ 'Name', 'Code', 'Visibility', 'Required for year criteria', 'Year 1', 'Year 2', 'Year 3', ]) await expect(component.getByText('1 / 2')).toBeVisible() await expect(component.locator('[data-cy^="programme-row-"]')).toHaveCount(0) }) test('combined programme shows both curriculums in one table, first programme first', async ({ mount, page }) => { const component = await mount() await expect(page.locator('[data-cy="degree-course-table"]')).toHaveCount(1) await expect(component.getByRole('columnheader', { name: 'Year 6' })).toBeVisible() await expect(component.locator('tbody tr')).toHaveText([ 'First programme (KH90_001)', /^Basic studies/, 'Second programme (MH90_001)', /^Clinical studies/, ]) }) test('hiding a course of the second programme only hides it there', async ({ mount }) => { const component = await mount() await component.getByText('Clinical studies').click() await component.getByRole('checkbox', { name: 'Show Calculus I' }).uncheck() await component.getByText('Basic studies').click() const calculusSwitches = component.getByRole('checkbox', { name: 'Show Calculus I' }) await expect(calculusSwitches.first()).toBeChecked() await expect(calculusSwitches.last()).not.toBeChecked() await expect .poll(() => exclusionRequests) .toEqual([ { method: 'POST', body: { courseGroupIds: ['group-MAT101'], curriculumVersion: 'period-1', programmeCode: 'MH90_001' }, }, ]) }) test('shows six years for medicine', async ({ mount }) => { const component = await mount() await expect(component.getByRole('columnheader', { name: 'Year 6' })).toBeVisible() }) test('checking a year saves the criteria once', async ({ mount }) => { const component = await mount() await component.getByText('Basic studies').click() const checkbox = component.getByRole('checkbox', { name: 'Linear algebra required for year 1' }) await checkbox.check() await expect(checkbox).toBeChecked() await expect(component.getByText('2 / 2')).toBeVisible() expect(criteriaRequests).toEqual([{ code: 'KH50_001', courseGroupIds: ['group-MAT101', 'group-MAT102'], year: 1 }]) }) test('unchecking a year saves the criteria once', async ({ mount }) => { const component = await mount() await component.getByText('Basic studies').click() await component.getByRole('checkbox', { name: 'Calculus I required for year 1' }).uncheck() await expect.poll(() => criteriaRequests).toEqual([{ code: 'KH50_001', courseGroupIds: [], year: 1 }]) }) test('visibility-only table hides criteria columns and toggles course visibility', async ({ mount }) => { const component = await mount() await expect(component.getByRole('columnheader')).toHaveText(['Name', 'Code', 'Visibility']) await component.getByText('Basic studies').click() await component.getByRole('checkbox', { name: 'Show Calculus I' }).uncheck() await expect(component.getByText('Partly shown')).toBeVisible() await expect .poll(() => exclusionRequests) .toEqual([ { method: 'POST', body: { courseGroupIds: ['group-MAT101'], curriculumVersion: 'period-1', programmeCode: 'KH50_001' }, }, ]) }) test('hiding a partly hidden module asks for confirmation', async ({ mount, page }) => { const component = await mount() // The switch stays on until the user confirms await component.getByRole('checkbox', { name: 'Show all courses of Basic studies' }).click() await expect(page.getByRole('dialog')).toContainText('remaining 1 course for all') expect(exclusionRequests).toEqual([]) await page.getByRole('button', { name: 'Hide module' }).click() await expect(component.getByText('Hidden', { exact: true })).toBeVisible() await expect .poll(() => exclusionRequests) .toEqual([ { method: 'POST', body: { courseGroupIds: ['group-MAT101'], curriculumVersion: 'period-1', programmeCode: 'KH50_001' }, }, ]) }) })