From a3cbf82de56ca566a9e3dc7953061677dccbff3f Mon Sep 17 00:00:00 2001 From: Pyry Koivisto Date: Wed, 8 Jan 2025 15:07:47 +0200 Subject: [PATCH] VKT(Frontend): PublicGoodAndSatisfactoryLevelPage cypress tests --- ...c_good_and_satisfactory_level_page.spec.ts | 46 ++++++++++ .../vkt/src/tests/cypress/support/commands.ts | 7 ++ .../publicGoodAndSatisfactoryLevelPage.ts | 48 ++++++++++ .../tests/cypress/support/types/index.d.ts | 1 + .../src/tests/msw/fixtures/publicExaminer.ts | 87 +++++++++++++++++++ .../packages/vkt/src/tests/msw/handlers.ts | 14 ++- 6 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 frontend/packages/vkt/src/tests/cypress/integration/public_good_and_satisfactory_level_page.spec.ts create mode 100644 frontend/packages/vkt/src/tests/msw/fixtures/publicExaminer.ts diff --git a/frontend/packages/vkt/src/tests/cypress/integration/public_good_and_satisfactory_level_page.spec.ts b/frontend/packages/vkt/src/tests/cypress/integration/public_good_and_satisfactory_level_page.spec.ts new file mode 100644 index 000000000..47bd275f6 --- /dev/null +++ b/frontend/packages/vkt/src/tests/cypress/integration/public_good_and_satisfactory_level_page.spec.ts @@ -0,0 +1,46 @@ +import { onCookieBanner } from 'tests/cypress/support/page-objects/cookieBanner'; +import { onPublicGoodAndSatisfactoryLevelPage } from 'tests/cypress/support/page-objects/publicGoodAndSatisfactoryLevelPage'; +import { AppRoutes, ExamLanguage } from 'enums/app'; +import { publicExaminers } from 'tests/msw/fixtures/publicExaminer'; + +describe('PublicGoodAndSatisfactoryLevelPage', () => { + beforeEach(() => { + cy.openPublicGoodAndSatisfactoryLevelPage(); + onCookieBanner.closeBanner(); + }); + + it('should allow filtering examiners by exam language', () => { + onPublicGoodAndSatisfactoryLevelPage.filterExaminersByExamLanguage( + ExamLanguage.FI, + ); + onPublicGoodAndSatisfactoryLevelPage.expectFilteredExaminersCount(2); + + onPublicGoodAndSatisfactoryLevelPage.filterExaminersByExamLanguage( + ExamLanguage.SV, + ); + onPublicGoodAndSatisfactoryLevelPage.expectFilteredExaminersCount(3); + + onPublicGoodAndSatisfactoryLevelPage.filterExaminersByExamLanguage( + ExamLanguage.ALL, + ); + onPublicGoodAndSatisfactoryLevelPage.expectFilteredExaminersCount(4); + }); + + it('should redirect user to contact request form when clicking on examiner', () => { + const lastName = 'Alanen'; + const firstName = 'Anneli'; + const examiner = publicExaminers.filter( + (v) => v.lastName === lastName && v.firstName === firstName, + )[0]; + onPublicGoodAndSatisfactoryLevelPage.contactExaminer( + `${firstName} ${lastName}`, + ); + cy.url().should( + 'include', + AppRoutes.PublicEnrollmentContactContactDetails.replace( + /:examinerId/, + `${examiner.id}`, + ), + ); + }); +}); diff --git a/frontend/packages/vkt/src/tests/cypress/support/commands.ts b/frontend/packages/vkt/src/tests/cypress/support/commands.ts index 7a4636d7e..d78263578 100644 --- a/frontend/packages/vkt/src/tests/cypress/support/commands.ts +++ b/frontend/packages/vkt/src/tests/cypress/support/commands.ts @@ -32,6 +32,13 @@ Cypress.Commands.add( }, ); +Cypress.Commands.add('openPublicGoodAndSatisfactoryLevelPage', () => { + cy.window().then((win) => { + win.sessionStorage.setItem('persist:root', '{}'); + }); + cy.visit(AppRoutes.PublicGoodAndSatisfactoryLevelLanding); +}); + Cypress.Commands.add('openClerkExcellentLevelPage', () => { cy.window().then((win) => win.sessionStorage.setItem('persist:root', '{}')); cy.visit(AppRoutes.ClerkExcellentLevelPage); diff --git a/frontend/packages/vkt/src/tests/cypress/support/page-objects/publicGoodAndSatisfactoryLevelPage.ts b/frontend/packages/vkt/src/tests/cypress/support/page-objects/publicGoodAndSatisfactoryLevelPage.ts index e69de29bb..8b511cb06 100644 --- a/frontend/packages/vkt/src/tests/cypress/support/page-objects/publicGoodAndSatisfactoryLevelPage.ts +++ b/frontend/packages/vkt/src/tests/cypress/support/page-objects/publicGoodAndSatisfactoryLevelPage.ts @@ -0,0 +1,48 @@ +import { ExamLanguage } from 'enums/app'; + +class PublicGoodAndSatisfactoryLevelPage { + elements = { + examinersTable: () => + cy + .findByRole('heading', { + name: 'Ota yhteyttä tutkintosuorituksen vastaanottajiin', + }) + .siblings('table') + .first(), + examinerRow: (examinerName: string) => + this.elements + .examinersTable() + .findAllByRole('cell', { name: examinerName }) + .parent(), + languageFilter: () => + cy.findByRole('group', { name: 'Näytä seuraavien kielten tutkinnot:' }), + }; + + filterExaminersByExamLanguage(language: ExamLanguage) { + const label = + language === ExamLanguage.FI + ? 'Suomi' + : language === ExamLanguage.SV + ? 'Ruotsi' + : 'Molemmat kielet'; + this.elements.languageFilter().findByRole('radio', { name: label }).click(); + } + + expectFilteredExaminersCount(count: number) { + // Expect number of table rows to be count + 1, as the table header is also considered a row. + this.elements + .examinersTable() + .findAllByRole('row') + .should('have.length', count + 1); + } + + contactExaminer(examinerName: string) { + this.elements + .examinerRow(examinerName) + .findByRole('button', { name: /Ota yhteyttä/i }) + .click(); + } +} + +export const onPublicGoodAndSatisfactoryLevelPage = + new PublicGoodAndSatisfactoryLevelPage(); diff --git a/frontend/packages/vkt/src/tests/cypress/support/types/index.d.ts b/frontend/packages/vkt/src/tests/cypress/support/types/index.d.ts index 687cbb6d8..ca3093193 100644 --- a/frontend/packages/vkt/src/tests/cypress/support/types/index.d.ts +++ b/frontend/packages/vkt/src/tests/cypress/support/types/index.d.ts @@ -11,6 +11,7 @@ declare global { examEventId: number, persistedState?: string, ): void; + openPublicGoodAndSatisfactoryLevelPage(): void; openClerkExcellentLevelPage(): void; openClerkExamEventPage(examEventId: number): void; openClerkCreateExamEventPage(): void; diff --git a/frontend/packages/vkt/src/tests/msw/fixtures/publicExaminer.ts b/frontend/packages/vkt/src/tests/msw/fixtures/publicExaminer.ts new file mode 100644 index 000000000..5e80be057 --- /dev/null +++ b/frontend/packages/vkt/src/tests/msw/fixtures/publicExaminer.ts @@ -0,0 +1,87 @@ +import { ExamLanguage } from 'enums/app'; +import { PublicExaminerResponse } from 'interfaces/publicExaminer'; + +export const publicExaminers: Array = [ + { + id: 3, + lastName: 'Aaltonen', + firstName: 'Antti', + languages: [ExamLanguage.SV], + municipalities: [ + { + fi: 'Enonkoski', + sv: 'Enonkoski', + }, + ], + examDates: [], + }, + { + id: 2, + lastName: 'Alanen', + firstName: 'Anneli', + languages: [ExamLanguage.FI, ExamLanguage.SV], + municipalities: [ + { + fi: 'Alavieska', + sv: 'Alavieska', + }, + { + fi: 'Alavus', + sv: 'Alavo', + }, + { + fi: 'Hyvinkää', + sv: 'Hyvinge', + }, + { + fi: 'Ii', + sv: 'Ii', + }, + { + fi: 'Kihniö', + sv: 'Kihniö', + }, + ], + examDates: [ + { + examDate: '2026-01-10', + isFull: false, + }, + { + examDate: '2026-01-22', + isFull: false, + }, + ], + }, + { + id: 1, + lastName: 'Eskola', + firstName: 'Eero', + languages: [ExamLanguage.FI], + municipalities: [ + { + fi: 'Oulu', + sv: 'Uleåborg', + }, + ], + examDates: [], + }, + { + id: 4, + lastName: 'Hakala', + firstName: 'Ella', + languages: [ExamLanguage.SV], + municipalities: [ + { + fi: 'Aura', + sv: 'Aura', + }, + ], + examDates: [ + { + examDate: '2025-06-15', + isFull: false, + }, + ], + }, +]; diff --git a/frontend/packages/vkt/src/tests/msw/handlers.ts b/frontend/packages/vkt/src/tests/msw/handlers.ts index af7ab5e3b..59aca630f 100644 --- a/frontend/packages/vkt/src/tests/msw/handlers.ts +++ b/frontend/packages/vkt/src/tests/msw/handlers.ts @@ -17,7 +17,7 @@ import { publicEnrollmentInitialisationWithFreeEnrollments, } from 'tests/msw/fixtures/publicEnrollmentInitialisation'; import { publicExamEvents11 } from 'tests/msw/fixtures/publicExamEvents11'; -import { publicExaminer } from 'tests/msw/fixtures/publicExaminer'; +import { publicExaminers } from 'tests/msw/fixtures/publicExaminer'; export const handlers = [ http.get(APIEndpoints.ClerkUser, ({ cookies }) => { @@ -158,6 +158,16 @@ export const handlers = [ }); }), http.get(APIEndpoints.PublicExaminer, () => { - return new Response(JSON.stringify(publicExaminer), { status: 200 }); + return new Response(JSON.stringify(publicExaminers), { status: 200 }); + }), + http.get(`${APIEndpoints.PublicExaminer}/:id`, ({ params }) => { + const { id } = params; + // TODO Are the details from the listing response sufficient? Do we need more details? + const examiner = publicExaminers.findLast((v) => v.id === Number(id)); + if (examiner) { + return new Response(JSON.stringify(examiner), { status: 200 }); + } else { + return new Response(null, { status: 404 }); + } }), ];