From 08d4359df9d0b4b31c5c7ccdb06fbdc8dc7660ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20L=C3=BCthi?= Date: Fri, 22 Dec 2023 11:28:07 +0100 Subject: [PATCH] Implement OIDC lifecycle in cypress tests Remove some UI navigations --- .../cypress/e2e/admin/aboutSettings.cy.js | 11 +- .../cypress/e2e/admin/loginScreen.cy.js | 5 +- .../e2e/admin/userAdministration.cy.js | 3 +- src/client/cypress/e2e/app.cy.js | 3 + src/client/cypress/e2e/boreholeList.cy.js | 5 +- src/client/cypress/e2e/codeList.cy.js | 23 +- .../e2e/editor/boreholeEditorTable.cy.js | 5 +- src/client/cypress/e2e/editor/bulkedit.cy.js | 77 ++---- .../e2e/editor/chronostratigraphy.cy.js | 45 ++-- .../cypress/e2e/editor/copyBorehole.cy.js | 5 +- .../cypress/e2e/editor/fieldMeasurement.cy.js | 13 +- .../editor/groundwaterLevelMeasurement.cy.js | 13 +- src/client/cypress/e2e/editor/hydrotest.cy.js | 13 +- src/client/cypress/e2e/editor/import.cy.js | 99 +++---- .../cypress/e2e/editor/instrumentation.cy.js | 5 +- .../e2e/editor/lithostratigraphy.cy.js | 47 ++-- .../cypress/e2e/editor/waterIngress.cy.js | 13 +- src/client/cypress/e2e/filter.cy.js | 26 +- .../cypress/e2e/hierarchicalDataFilter.cy.js | 11 +- src/client/cypress/e2e/srsFilter.cy.js | 8 +- src/client/cypress/e2e/testHelpers.js | 249 ++++++++++-------- .../cypress/e2e/viewer/displayLayer.cy.js | 8 +- src/client/src/pages/settings/dataLoader.js | 2 +- 23 files changed, 380 insertions(+), 309 deletions(-) diff --git a/src/client/cypress/e2e/admin/aboutSettings.cy.js b/src/client/cypress/e2e/admin/aboutSettings.cy.js index b24df7783..c390ef11b 100644 --- a/src/client/cypress/e2e/admin/aboutSettings.cy.js +++ b/src/client/cypress/e2e/admin/aboutSettings.cy.js @@ -1,9 +1,10 @@ -import { login } from "../testHelpers"; +import { loginAsAdmin } from "../testHelpers"; import license from "../../fixtures/license.json"; describe("Admin about page tests", () => { it("shows version information linking the corresponding release on GitHub.", () => { - login("/setting/about"); + loginAsAdmin(); + cy.visit("/setting/about"); cy.get('[data-cy="version"]') .should("contain", "0.0.99+dev") @@ -16,7 +17,8 @@ describe("Admin about page tests", () => { it("shows license information (with fixtures)", () => { cy.intercept("/license.json", license); - login("/setting/about"); + loginAsAdmin(); + cy.visit("/setting/about"); cy.get('[data-cy^="credits-"]').should("have.length", 2); cy.get('[data-cy="credits-example-js@0.0.999"]').should( @@ -30,7 +32,8 @@ describe("Admin about page tests", () => { }); it("shows license information (without fixtures)", () => { - login("/setting/about"); + loginAsAdmin(); + cy.visit("/setting/about"); cy.get('[data-cy^="credits-"]').should("have.length.above", 0); }); }); diff --git a/src/client/cypress/e2e/admin/loginScreen.cy.js b/src/client/cypress/e2e/admin/loginScreen.cy.js index 4af52443b..2720da6ce 100644 --- a/src/client/cypress/e2e/admin/loginScreen.cy.js +++ b/src/client/cypress/e2e/admin/loginScreen.cy.js @@ -1,8 +1,9 @@ -import { login } from "../testHelpers"; +import { loginAsAdmin } from "../testHelpers"; describe("Admin login preview tests", () => { it("displays correct message when publishing a new welcome message.", () => { - login("/setting/login"); + loginAsAdmin(); + cy.visit("/setting/login"); // Initial button state cy.get('[data-cy="save-welcome-message-button"]').should("not.be.visible"); diff --git a/src/client/cypress/e2e/admin/userAdministration.cy.js b/src/client/cypress/e2e/admin/userAdministration.cy.js index cde07f54c..2b73b877b 100644 --- a/src/client/cypress/e2e/admin/userAdministration.cy.js +++ b/src/client/cypress/e2e/admin/userAdministration.cy.js @@ -2,7 +2,8 @@ import { loginAsAdmin } from "../testHelpers"; describe("Admin settings test", () => { beforeEach(() => { - loginAsAdmin("/setting/admin"); + loginAsAdmin(); + cy.visit("/setting/admin"); cy.get('[data-cy="user-list-table-body"]') .children() diff --git a/src/client/cypress/e2e/app.cy.js b/src/client/cypress/e2e/app.cy.js index 1ca6ed332..c32cffb51 100644 --- a/src/client/cypress/e2e/app.cy.js +++ b/src/client/cypress/e2e/app.cy.js @@ -3,6 +3,7 @@ import { loginAsAdmin, loginAsEditorInViewerMode } from "./testHelpers"; describe("General app tests", () => { it("Displays the login page in the correct language", () => { // default is english + cy.session("logged out", () => cy.visit("/")); cy.visit("/"); cy.contains("Sign in"); cy.contains("Welcome to"); @@ -25,12 +26,14 @@ describe("General app tests", () => { it("Displays the current host as app title", () => { loginAsEditorInViewerMode(); + cy.visit("/"); cy.get('[data-cy="app-title"]').contains("localhost"); }); it("Correctly navigates back and forth from settings", () => { // correctly navigate back to viewer mode loginAsAdmin(); + cy.visit("/"); cy.get('[data-cy="menu"]').click(); cy.get('[data-cy="settings-list-item"]').click(); cy.contains("h3", "Done").click(); diff --git a/src/client/cypress/e2e/boreholeList.cy.js b/src/client/cypress/e2e/boreholeList.cy.js index b1e204ee1..34581c272 100644 --- a/src/client/cypress/e2e/boreholeList.cy.js +++ b/src/client/cypress/e2e/boreholeList.cy.js @@ -4,6 +4,7 @@ describe("Borehole list tests", () => { it("Boreholes are displayed in correct order with editor login", () => { cy.intercept("/api/v1/borehole").as("borehole"); loginAsEditorInViewerMode(); + cy.visit("/"); cy.get("div[id=map]").should("be.visible"); @@ -80,7 +81,8 @@ describe("Borehole list tests", () => { it("Boreholes are displayed in correct order with admin login", () => { cy.intercept("/api/v1/borehole").as("borehole"); cy.intercept("/api/v1/borehole/edit").as("editorBorehole"); - loginAsAdmin("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.wait("@editorBorehole"); cy.get("div[id=map]").should("be.visible"); @@ -173,6 +175,7 @@ describe("Borehole list tests", () => { it("preserves column sorting and active page when navigating", () => { loginAsEditorInViewerMode(); + cy.visit("/"); // sort by name ascending cy.contains("div", "Original name") diff --git a/src/client/cypress/e2e/codeList.cy.js b/src/client/cypress/e2e/codeList.cy.js index 56969e358..485c80333 100644 --- a/src/client/cypress/e2e/codeList.cy.js +++ b/src/client/cypress/e2e/codeList.cy.js @@ -4,11 +4,8 @@ describe("Codelist translations tests", () => { it("Admin can open codelist translation section", () => { // Login and navigate to editor settings loginAsAdmin(); - cy.get("div[id=map]").should("be.visible"); + cy.visit("/setting/editor"); - cy.get("i[class='th big icon']").click(); - cy.contains("h4", "Settings").click(); - cy.contains("h3", "Editor").click(); cy.get("button").should("not.contain", "Collapse"); cy.contains("div", "Codelist translations") @@ -22,11 +19,7 @@ describe("Codelist translations tests", () => { it("Admin can edit translations", () => { loginAsAdmin(); - cy.get("div[id=map]").should("be.visible"); - - cy.get("i[class='th big icon']").click(); - cy.contains("h4", "Settings").click(); - cy.contains("h3", "Editor").click(); + cy.visit("/setting/editor"); cy.contains("div", "Codelist translations") .parent("div") .children("div") @@ -88,22 +81,14 @@ describe("Codelist translations tests", () => { it("Editor cannot open codelist translation section", () => { loginAsEditorInViewerMode(); - cy.get("div[id=map]").should("be.visible"); - - cy.get("i[class='th big icon']").click(); - cy.contains("h4", "Settings").click(); - cy.contains("h3", "Editor").click(); + cy.visit("/setting/editor"); // Codelist translation section is not available cy.get("div").should("not.contain", "Codelist translations"); }); it("Admin can edit order", () => { loginAsAdmin(); - cy.get("div[id=map]").should("be.visible"); - - cy.get("i[class='th big icon']").click(); - cy.contains("h4", "Settings").click(); - cy.contains("h3", "Editor").click(); + cy.visit("/setting/editor"); cy.contains("div", "Codelist translations") .parent("div") .children("div") diff --git a/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js b/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js index 1f53ae29e..99deb31dd 100644 --- a/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js +++ b/src/client/cypress/e2e/editor/boreholeEditorTable.cy.js @@ -1,8 +1,9 @@ -import { login } from "../../e2e/testHelpers"; +import { loginAsAdmin } from "../../e2e/testHelpers"; describe("Borehole editor table tests", () => { it("preserves column sorting and active page when navigating", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); // sort by name ascending cy.contains("th", "Original name").click(); diff --git a/src/client/cypress/e2e/editor/bulkedit.cy.js b/src/client/cypress/e2e/editor/bulkedit.cy.js index 58db6243e..f910fd036 100644 --- a/src/client/cypress/e2e/editor/bulkedit.cy.js +++ b/src/client/cypress/e2e/editor/bulkedit.cy.js @@ -1,55 +1,18 @@ -import { createBorehole, login, adminUserAuth } from "../testHelpers"; - -export const changeWorkgroupRoleForUser = ( - workgroupId, - userId, - role, - action, -) => { - return cy - .request({ - method: "POST", - url: "/api/v1/user/workgroup/edit", - body: { - action: action, - id: workgroupId, - }, - auth: adminUserAuth, - }) - .then(res => { - expect(res.body).to.have.property("success", true); - cy.request({ - method: "POST", - url: "/api/v1/user/workgroup/edit", - body: { - action: "SET", - user_id: userId, - workgroup_id: workgroupId, - role_name: role, - active: action === "ENABLE" ? true : false, - }, - auth: adminUserAuth, - }).then(res => { - expect(res.body).to.have.property("success", true); - cy.request({ - method: "GET", - url: "/api/v2/user", - auth: adminUserAuth, - }); - }); - }); -}; +import { createBorehole, loginAsAdmin } from "../testHelpers"; +import adminUser from "../../fixtures/adminUser.json"; describe("Test the borehole bulk edit feature.", () => { it("opens the bulk edit dialog with all boreholes selected", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.get('[data-cy="borehole-table"] thead .checkbox').click({ force: true }); cy.contains("button", "Bulk editing").click({ force: true }); cy.wait("@edit_ids"); }); it("checks if all toggle buttons do something", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.get('[data-cy="borehole-table"] thead .checkbox').click({ force: true }); cy.contains("button", "Bulk editing").click({ force: true }); @@ -64,13 +27,26 @@ describe("Test the borehole bulk edit feature.", () => { }); it("displays workgroup toggle only if user has permission for more than one workgroup", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.get('[data-cy="borehole-table"] thead .checkbox').click({ force: true }); cy.contains("button", "Bulk editing").click({ force: true }); - cy.get(".modal .toggle").should("have.length", 30); - changeWorkgroupRoleForUser(6, 1, "EDIT", "ENABLE"); - login("/editor"); + + loginAsAdmin("admin"); + const adminUser2Workgroups = Object.assign({}, adminUser); + adminUser2Workgroups.data.workgroups.push({ + id: 6, + workgroup: "Blue", + roles: ["EDIT"], + disabled: null, + supplier: false, + }); + cy.intercept("/api/v1/user", { + statusCode: 200, + body: JSON.stringify(adminUser2Workgroups), + }).as("adminUser2Workgroups"); + cy.visit("/editor"); cy.get('[data-cy="borehole-table"] thead .checkbox').click({ force: true }); cy.contains("button", "Bulk editing").click({ force: true }); @@ -83,16 +59,15 @@ describe("Test the borehole bulk edit feature.", () => { cy.wrap(el).scrollIntoView().click(); cy.get('.modal [role="option"]').eq(0).click({ force: true }); }); - changeWorkgroupRoleForUser(6, 1, "EDIT", "DISABLE"); }); it("fills all bulkedit fields and saves.", () => { - login("/editor"); - // create boreholes createBorehole({ "extended.original_name": "NINTIC" }).as("borehole_id_1"); createBorehole({ "extended.original_name": "LOMONE" }).as("borehole_id_2"); - cy.contains("a", "Refresh").click(); + + loginAsAdmin(); + cy.visit("/editor"); cy.wait("@borehole"); // select the boreholes for bulk edit diff --git a/src/client/cypress/e2e/editor/chronostratigraphy.cy.js b/src/client/cypress/e2e/editor/chronostratigraphy.cy.js index 8e6ca5649..486e3276d 100644 --- a/src/client/cypress/e2e/editor/chronostratigraphy.cy.js +++ b/src/client/cypress/e2e/editor/chronostratigraphy.cy.js @@ -1,8 +1,8 @@ import { createBorehole, createStratigraphy, - adminUserAuth, - login, + loginAsAdmin, + bearerAuth, } from "../testHelpers"; describe("Tests for the chronostratigraphy editor.", () => { @@ -49,31 +49,34 @@ describe("Tests for the chronostratigraphy editor.", () => { ], }; Object.entries(layers).forEach(([key, value]) => { - value.forEach(layer => { - cy.request({ - method: "POST", - url: "/api/v2/" + key, - cache: "no-cache", - credentials: "same-origin", - headers: { - "Content-Type": "application/json", - }, - body: { - stratigraphyId: response.body.id, - ...layer, - }, - auth: adminUserAuth, - }).then(response => { - expect(response).to.have.property("status", 200); + cy.get("@id_token").then(token => { + value.forEach(layer => { + cy.request({ + method: "POST", + url: "/api/v2/" + key, + cache: "no-cache", + credentials: "same-origin", + headers: { + "Content-Type": "application/json", + }, + body: { + stratigraphyId: response.body.id, + ...layer, + }, + auth: bearerAuth(token), + }).then(response => { + expect(response).to.have.property("status", 200); + }); }); }); }); }); // open chronostratigraphy editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/stratigraphy/chronostratigraphy`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/stratigraphy/chronostratigraphy`); + }); cy.wait("@layer-by-profileId"); // start editing session diff --git a/src/client/cypress/e2e/editor/copyBorehole.cy.js b/src/client/cypress/e2e/editor/copyBorehole.cy.js index 9d6c315d2..d4323badb 100644 --- a/src/client/cypress/e2e/editor/copyBorehole.cy.js +++ b/src/client/cypress/e2e/editor/copyBorehole.cy.js @@ -1,10 +1,11 @@ -import { createBorehole, login } from "../testHelpers"; +import { createBorehole, loginAsAdmin } from "../testHelpers"; describe("Test copying of boreholes", () => { it("copies a borehole", () => { - login("/editor"); createBorehole({ "extended.original_name": "NINTIC" }).as("borehole_id_1"); + loginAsAdmin(); + cy.visit("/editor"); cy.get('[data-cy="borehole-table"] tbody') .children() .eq(1) diff --git a/src/client/cypress/e2e/editor/fieldMeasurement.cy.js b/src/client/cypress/e2e/editor/fieldMeasurement.cy.js index 2a298a6d5..d2b01995a 100644 --- a/src/client/cypress/e2e/editor/fieldMeasurement.cy.js +++ b/src/client/cypress/e2e/editor/fieldMeasurement.cy.js @@ -1,4 +1,8 @@ -import { createBorehole, createStratigraphy, login } from "../testHelpers"; +import { + createBorehole, + createStratigraphy, + loginAsAdmin, +} from "../testHelpers"; describe("Tests for the field measurement editor.", () => { beforeEach(function () { @@ -11,9 +15,10 @@ describe("Tests for the field measurement editor.", () => { }); // open field measurement editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/hydrogeology/fieldmeasurement`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/hydrogeology/fieldmeasurement`); + }); // start editing session cy.contains("a", "Start editing").click(); diff --git a/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js b/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js index c212ac3f6..d04619812 100644 --- a/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js +++ b/src/client/cypress/e2e/editor/groundwaterLevelMeasurement.cy.js @@ -1,4 +1,8 @@ -import { createBorehole, createStratigraphy, login } from "../testHelpers"; +import { + createBorehole, + createStratigraphy, + loginAsAdmin, +} from "../testHelpers"; describe("Tests for the groundwater level measurement editor.", () => { beforeEach(function () { @@ -11,9 +15,10 @@ describe("Tests for the groundwater level measurement editor.", () => { }); // open groundwater level measurement editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/hydrogeology/groundwaterlevelmeasurement`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/hydrogeology/groundwaterlevelmeasurement`); + }); // start editing session cy.contains("a", "Start editing").click(); diff --git a/src/client/cypress/e2e/editor/hydrotest.cy.js b/src/client/cypress/e2e/editor/hydrotest.cy.js index c4f1a3f70..53a4c05b5 100644 --- a/src/client/cypress/e2e/editor/hydrotest.cy.js +++ b/src/client/cypress/e2e/editor/hydrotest.cy.js @@ -1,4 +1,8 @@ -import { createBorehole, createStratigraphy, login } from "../testHelpers"; +import { + createBorehole, + createStratigraphy, + loginAsAdmin, +} from "../testHelpers"; const openDropdown = dataCy => { cy.get(`[data-cy="${dataCy}"]`) @@ -34,9 +38,10 @@ describe("Tests for the hydrotest editor.", () => { }); // open hydrotest editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/hydrogeology/hydrotest`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/hydrogeology/hydrotest`); + }); // start editing session cy.contains("a", "Start editing").click(); diff --git a/src/client/cypress/e2e/editor/import.cy.js b/src/client/cypress/e2e/editor/import.cy.js index 60512de58..be0b42e00 100644 --- a/src/client/cypress/e2e/editor/import.cy.js +++ b/src/client/cypress/e2e/editor/import.cy.js @@ -1,8 +1,9 @@ -import { login, getImportFileFromFixtures } from "../../e2e/testHelpers"; +import { loginAsAdmin, getImportFileFromFixtures } from "../../e2e/testHelpers"; describe("Test for importing boreholes.", () => { it("Successfully imports multiple boreholes.", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("a", "Import").click(); // Select borehole csv file @@ -77,31 +78,35 @@ describe("Test for importing boreholes.", () => { }); it("Displays borehole validation errors.", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("a", "Import").click(); // Select borehole csv file - let boreholeFile = new DataTransfer(); getImportFileFromFixtures( "boreholes-missing-fields-and-duplicates.csv", null, - ).then(fileContent => { - const file = new File( - [fileContent], - "boreholes-missing-fields-and-duplicates.csv", - { - type: "text/csv", - }, - ); - boreholeFile.items.add(file); - }); - - cy.get('[data-cy="import-boreholeFile-input"]').within(() => { - cy.get("input[type=file]", { force: true }).then(input => { - input[0].files = boreholeFile.files; - input[0].dispatchEvent(new Event("change", { bubbles: true })); + ) + .then(fileContent => { + const file = new File( + [fileContent], + "boreholes-missing-fields-and-duplicates.csv", + { + type: "text/csv", + }, + ); + let boreholeFile = new DataTransfer(); + boreholeFile.items.add(file); + return boreholeFile; + }) + .then(boreholeFile => { + cy.get('[data-cy="import-boreholeFile-input"]').within(() => { + cy.get("input[type=file]", { force: true }).then(input => { + input[0].files = boreholeFile.files; + input[0].dispatchEvent(new Event("change", { bubbles: true })); + }); + }); }); - }); cy.intercept("/api/v2/upload?workgroupId=1").as("borehole-upload"); @@ -123,45 +128,51 @@ describe("Test for importing boreholes.", () => { }); it("Displays lithology validation errors.", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("a", "Import").click(); // Select borehole csv file - let boreholeFile = new DataTransfer(); - getImportFileFromFixtures("boreholes-multiple-valid.csv", null).then( - fileContent => { + getImportFileFromFixtures("boreholes-multiple-valid.csv", null) + .then(fileContent => { const file = new File([fileContent], "boreholes-multiple-valid.csv", { type: "text/csv", }); + let boreholeFile = new DataTransfer(); boreholeFile.items.add(file); - }, - ); - - cy.get('[data-cy="import-boreholeFile-input"]').within(() => { - cy.get("input[type=file]", { force: true }).then(input => { - input[0].files = boreholeFile.files; - input[0].dispatchEvent(new Event("change", { bubbles: true })); + return boreholeFile; + }) + .then(boreholeFile => { + cy.get('[data-cy="import-boreholeFile-input"]').within(() => { + cy.get("input[type=file]", { force: true }).then(input => { + input[0].files = boreholeFile.files; + input[0].dispatchEvent(new Event("change", { bubbles: true })); + }); + }); }); - }); // Select lithology csv file - let lithologyFile = new DataTransfer(); getImportFileFromFixtures( "lithology-single-not-valid.csv", null, "invalid-lithology", - ).then(fileContent => { - const file = new File([fileContent], "lithology-single-not-valid.csv", { - type: "text/csv", - }); - lithologyFile.items.add(file); - }); - cy.get('[data-cy="import-lithologyFile-input"]').within(() => { - cy.get("input[type=file]", { force: true }).then(input => { - input[0].files = lithologyFile.files; - input[0].dispatchEvent(new Event("change", { bubbles: true })); + ) + .then(fileContent => { + const file = new File([fileContent], "lithology-single-not-valid.csv", { + type: "text/csv", + }); + let lithologyFile = new DataTransfer(); + lithologyFile.items.add(file); + return lithologyFile; + }) + .then(lithologyFile => { + cy.get('[data-cy="import-lithologyFile-input"]').within(() => { + cy.get("input[type=file]", { force: true }).then(input => { + input[0].files = lithologyFile.files; + input[0].dispatchEvent(new Event("change", { bubbles: true })); + }); + }); }); - }); cy.intercept("/api/v2/upload?workgroupId=1").as("borehole-upload"); diff --git a/src/client/cypress/e2e/editor/instrumentation.cy.js b/src/client/cypress/e2e/editor/instrumentation.cy.js index 6fbc2c040..a9e768bdc 100644 --- a/src/client/cypress/e2e/editor/instrumentation.cy.js +++ b/src/client/cypress/e2e/editor/instrumentation.cy.js @@ -1,5 +1,5 @@ import { - loginAsViewer, + loginAsEditorInViewerMode, createBorehole, createAndEditBoreholeAsAdmin, } from "../testHelpers"; @@ -7,7 +7,8 @@ import { describe("Instrumentation tests", () => { it("Displays correct 'No Instumentation' message when logged in as viewer and no stratigraphies are defined", () => { createBorehole({ "extended.original_name": "A1_Borehole" }); - loginAsViewer("/editor"); + loginAsEditorInViewerMode(); + cy.visit("/editor"); // Select borehole A1_Borehole cy.get("tbody").children().first().click(); diff --git a/src/client/cypress/e2e/editor/lithostratigraphy.cy.js b/src/client/cypress/e2e/editor/lithostratigraphy.cy.js index 5bffebf40..855cf559e 100644 --- a/src/client/cypress/e2e/editor/lithostratigraphy.cy.js +++ b/src/client/cypress/e2e/editor/lithostratigraphy.cy.js @@ -1,8 +1,8 @@ import { createBorehole, createStratigraphy, - adminUserAuth, - login, + bearerAuth, + loginAsAdmin, } from "../testHelpers"; describe("Tests for the lithostratigraphy editor.", () => { @@ -34,29 +34,34 @@ describe("Tests for the lithostratigraphy editor.", () => { toDepth: 43, }, ].forEach(layer => { - cy.request({ - method: "POST", - url: "/api/v2/layer", - cache: "no-cache", - credentials: "same-origin", - headers: { - "Content-Type": "application/json", - }, - body: { - stratigraphyId: response.body.id, - ...layer, - }, - auth: adminUserAuth, - }).then(response => { - expect(response).to.have.property("status", 200); - }); + cy.get("@id_token").then(token => + cy + .request({ + method: "POST", + url: "/api/v2/layer", + cache: "no-cache", + credentials: "same-origin", + headers: { + "Content-Type": "application/json", + }, + body: { + stratigraphyId: response.body.id, + ...layer, + }, + auth: bearerAuth(token), + }) + .then(response => { + expect(response).to.have.property("status", 200); + }), + ); }); }); // open lithostratigraphy editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/stratigraphy/lithostratigraphy`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/stratigraphy/lithostratigraphy`); + }); cy.wait("@layer-by-profileId"); // start editing session diff --git a/src/client/cypress/e2e/editor/waterIngress.cy.js b/src/client/cypress/e2e/editor/waterIngress.cy.js index 455f1be61..c2ee54dfa 100644 --- a/src/client/cypress/e2e/editor/waterIngress.cy.js +++ b/src/client/cypress/e2e/editor/waterIngress.cy.js @@ -1,4 +1,8 @@ -import { createBorehole, createStratigraphy, login } from "../testHelpers"; +import { + createBorehole, + createStratigraphy, + loginAsAdmin, +} from "../testHelpers"; describe("Tests for the wateringress editor.", () => { beforeEach(function () { @@ -11,9 +15,10 @@ describe("Tests for the wateringress editor.", () => { }); // open wateringress editor - cy.get("@borehole_id").then(id => - login(`editor/${id}/hydrogeology/wateringress`), - ); + cy.get("@borehole_id").then(id => { + loginAsAdmin(); + cy.visit(`editor/${id}/hydrogeology/wateringress`); + }); // start editing session cy.contains("a", "Start editing").click(); diff --git a/src/client/cypress/e2e/filter.cy.js b/src/client/cypress/e2e/filter.cy.js index 2e787dbdf..844e5bd04 100644 --- a/src/client/cypress/e2e/filter.cy.js +++ b/src/client/cypress/e2e/filter.cy.js @@ -1,13 +1,15 @@ -import { login, loginAsViewer } from "../e2e/testHelpers"; +import { loginAsAdmin, loginAsEditorInViewerMode } from "../e2e/testHelpers"; describe("Search filter tests", () => { it("has search filters", () => { - login(); + loginAsAdmin(); + cy.visit("/"); cy.contains("Search filters:"); }); it("shows the correct dropdowns", () => { - login(); + loginAsAdmin(); + cy.visit("/"); cy.contains("span", "Location").click(); cy.contains("Show all fields").children().eq(0).click(); let indentifierDropdown = cy.contains("label", "ID type").next(); @@ -40,7 +42,8 @@ describe("Search filter tests", () => { }); it("shows 'fiter by map' in editor on 'Large Map' appearance", () => { - loginAsViewer("/setting/editor"); + loginAsEditorInViewerMode(); + cy.visit("/setting/editor"); // Check if Editor mode settings are apparant cy.contains("Location filters"); @@ -67,7 +70,8 @@ describe("Search filter tests", () => { it("checks that the registration filter settings control the filter visibility.", () => { // precondition filters not visible - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("Registration").click(); cy.contains("Show all fields") .next() @@ -101,7 +105,8 @@ describe("Search filter tests", () => { }); it("filters boreholes by creator name", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("Registration").click(); cy.contains("Show all fields").children(".checkbox").click(); @@ -119,7 +124,8 @@ describe("Search filter tests", () => { }); it("filters boreholes by original lithology", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("Lithology").click(); cy.contains("Show all fields").children(".checkbox").click(); @@ -134,7 +140,8 @@ describe("Search filter tests", () => { }); it("filters boreholes by creation date", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("Registration").click(); cy.contains("Show all fields").children(".checkbox").click(); @@ -172,7 +179,8 @@ describe("Search filter tests", () => { }); it("filters boreholes by workgroup in viewer", () => { - login(); + loginAsAdmin(); + cy.visit("/"); cy.contains("Workgroup").click(); cy.contains("Default").click(); cy.wait("@borehole"); diff --git a/src/client/cypress/e2e/hierarchicalDataFilter.cy.js b/src/client/cypress/e2e/hierarchicalDataFilter.cy.js index 8e979cc3d..4c40d3a1e 100644 --- a/src/client/cypress/e2e/hierarchicalDataFilter.cy.js +++ b/src/client/cypress/e2e/hierarchicalDataFilter.cy.js @@ -1,8 +1,9 @@ -import { login } from "./testHelpers"; +import { loginAsAdmin } from "./testHelpers"; describe("Hierachical data filter tests", () => { it("check visible filters", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("span", "Chronostratigraphy").click(); cy.get("Show all fields").should("not.exist"); cy.get('[data-cy="hierarchical-data-search"]').should("have.length", 7); @@ -12,7 +13,8 @@ describe("Hierachical data filter tests", () => { }); it("check sorting of filter values", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("span", "Chronostratigraphy").click(); let periodsDropdown = cy.contains("label", "Period").next(); periodsDropdown.click(); @@ -46,7 +48,8 @@ describe("Hierachical data filter tests", () => { "Burdigalian", "late Burdigalian", ]; - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("span", "Chronostratigraphy").click(); cy.get('[data-cy="hierarchical-data-search"]') .eq(filterValues.length - 1) diff --git a/src/client/cypress/e2e/srsFilter.cy.js b/src/client/cypress/e2e/srsFilter.cy.js index 2a577b50c..b446fca59 100644 --- a/src/client/cypress/e2e/srsFilter.cy.js +++ b/src/client/cypress/e2e/srsFilter.cy.js @@ -1,4 +1,4 @@ -import { newEditableBorehole, login } from "./testHelpers"; +import { newEditableBorehole, loginAsAdmin } from "./testHelpers"; describe("Tests for filtering data by reference system.", () => { function goToEditorLocationFilter() { @@ -16,7 +16,8 @@ describe("Tests for filtering data by reference system.", () => { } it("can set filters as viewer", () => { - login(); + loginAsAdmin(); + cy.visit("/"); goToViewerLocationFilter(); cy.contains("div", "Spatial reference system") @@ -44,7 +45,8 @@ describe("Tests for filtering data by reference system.", () => { }); it("can set filters as editor", () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); goToEditorLocationFilter(); cy.contains("div", "Spatial reference system") diff --git a/src/client/cypress/e2e/testHelpers.js b/src/client/cypress/e2e/testHelpers.js index 05e622794..7d715e869 100644 --- a/src/client/cypress/e2e/testHelpers.js +++ b/src/client/cypress/e2e/testHelpers.js @@ -2,10 +2,7 @@ import adminUser from "../fixtures/adminUser.json"; import editorUser from "../fixtures/editorUser.json"; import viewerUser from "../fixtures/viewerUser.json"; -export const adminUserAuth = { - user: "admin", - password: "swissforages", -}; +export const bearerAuth = token => ({ bearer: token }); export const interceptApiCalls = () => { // Api V1 @@ -70,43 +67,76 @@ export const interceptApiCalls = () => { }; /** - * Login into the application with the pre-filled user for the development environment. - * @param {string} visitUrl The url to visit after logging in. Default is the root path. + * Login into the application with the user for the development environment. */ -export const login = (visitUrl = "/") => { - cy.intercept("api/v1/content").as("content"); - cy.intercept("/api/v1/borehole/codes").as("code"); - cy.visit(visitUrl); - cy.wait("@content"); - cy.contains("button", "Login").click({ force: true }); - cy.wait("@code"); +export const login = user => { + cy.session( + ["login", user], + () => { + cy.intercept("http://localhost:4011/connect/token").as("token"); + cy.visit("/"); + cy.get('[data-cy="login-button"]').click({ force: true }); + cy.origin("http://localhost:4011", { args: { user } }, ({ user }) => { + cy.get("#Username").type(user); + cy.get("#Password").type("swissforages"); + cy.contains("button", "Login").click({ force: true }); + }); + cy.wait("@token") + .then(interception => interception.response.body.id_token) + .then(token => window.localStorage.setItem("id_token", token)); + }, + { + validate() { + cy.window() + .then(win => win.localStorage.getItem("id_token")) + .as("id_token"); + cy.get("@id_token").then(token => + cy.request({ + method: "POST", + url: "/api/v1/user", + body: { + action: "GET", + }, + auth: bearerAuth(token), + }), + ); + }, + cacheAcrossSpecs: true, + }, + ); }; /** * Login into the application as admin. - * @param {string} visitUrl The url to visit after logging in. Default is the root path. */ -export const loginAsAdmin = (visitUrl = "/") => { - cy.intercept("/api/v1/user", adminUser); - login(visitUrl); +export const loginAsAdmin = () => { + login(adminUser.data.username); + cy.intercept("/api/v1/user", { + statusCode: 200, + body: JSON.stringify(adminUser), + }).as("stubAdminUser"); }; /** * Login into the application as editor. - * @param {string} visitUrl The url to visit after logging in. Default is the root path. */ -export const loginAsEditorInViewerMode = (visitUrl = "/") => { - cy.intercept("/api/v1/user", editorUser); - login(visitUrl); +export const loginAsEditor = () => { + login(editorUser.data.username); + cy.intercept("/api/v1/user", { + statusCode: 200, + body: JSON.stringify(editorUser), + }).as("stubEditorUser"); }; /** * Login into the application as viewer. - * @param {string} visitUrl The url to visit after logging in. Default is the root path. */ -export const loginAsViewer = (visitUrl = "/") => { - cy.intercept("/api/v1/user", viewerUser); - login(visitUrl); +export const loginAsEditorInViewerMode = () => { + login(editorUser.data.username); + cy.intercept("/api/v1/user", { + statusCode: 200, + body: JSON.stringify(viewerUser), + }).as("stubViewerUser"); }; export const newEditableBorehole = () => { @@ -117,7 +147,8 @@ export const newEditableBorehole = () => { }; export const newUneditableBorehole = () => { - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.contains("a", "New").click(); cy.contains("button", "Create").click(); const id = waitForCreation(); @@ -136,83 +167,93 @@ const waitForCreation = () => { }; export const createBorehole = values => { - return cy - .request({ - method: "POST", - url: "/api/v1/borehole/edit", - body: { - action: "CREATE", - id: 1, - }, - auth: adminUserAuth, - }) - .then(res => { - expect(res.body).to.have.property("success", true); - let boreholeId = res.body.id; - let fields = Object.entries(values).map(([key, value]) => [key, value]); - if (fields.length > 0) { - cy.request({ - method: "POST", - url: "/api/v1/borehole/edit", - body: { - action: "MULTIPATCH", - fields: fields, - ids: [boreholeId], - }, - auth: adminUserAuth, - }).then(res => expect(res.body).to.have.property("success", true)); - } - return cy.wrap(boreholeId); - }); + loginAsAdmin(); + return cy.get("@id_token").then(token => + cy + .request({ + method: "POST", + url: "/api/v1/borehole/edit", + body: { + action: "CREATE", + id: 1, + }, + auth: bearerAuth(token), + }) + .then(res => { + expect(res.body).to.have.property("success", true); + let boreholeId = res.body.id; + let fields = Object.entries(values).map(([key, value]) => [key, value]); + if (fields.length > 0) { + cy.request({ + method: "POST", + url: "/api/v1/borehole/edit", + body: { + action: "MULTIPATCH", + fields: fields, + ids: [boreholeId], + }, + auth: bearerAuth(token), + }).then(res => expect(res.body).to.have.property("success", true)); + } + return cy.wrap(boreholeId); + }), + ); }; export const createAndEditBoreholeAsAdmin = values => { - return createBorehole(values).then(value => loginAsAdmin(`/editor/${value}`)); + return createBorehole(values).then(value => { + loginAsAdmin(); + cy.visit(`/editor/${value}`); + }); }; export const deleteBorehole = id => { - cy.request({ - method: "POST", - url: "/api/v1/borehole/edit", - body: { - action: "DELETE", - id: id, - }, - auth: adminUserAuth, - }) - .its("body.success") - .should("eq", true); + loginAsAdmin(); + cy.get("@id_token").then(token => { + cy.request({ + method: "POST", + url: "/api/v1/borehole/edit", + body: { + action: "DELETE", + id: id, + }, + auth: bearerAuth(token), + }) + .its("body.success") + .should("eq", true); + }); }; export const loginAndResetState = () => { - // Reset boreholes - cy.request({ - method: "POST", - url: "/api/v1/borehole/edit", - body: { - action: "IDS", - }, - auth: adminUserAuth, - }).then(response => { - response.body.data - .filter(id => id > 1009999) // max id in seed data. - .forEach(id => { - deleteBorehole(id); - }); - }); + loginAsAdmin(); + cy.get("@id_token").then(token => { + // Reset boreholes + cy.request({ + method: "POST", + url: "/api/v1/borehole/edit", + body: { + action: "IDS", + }, + auth: bearerAuth(token), + }).then(response => { + response.body.data + .filter(id => id > 1009999) // max id in seed data. + .forEach(id => { + deleteBorehole(id); + }); + }); - // Reset user settings (i.e. table ordering) - cy.request({ - method: "POST", - url: "/api/v2/user/resetAllSettings", - cache: "no-cache", - credentials: "same-origin", - headers: { - "Content-Type": "application/json", - Authorization: `Basic ${btoa( - `${adminUserAuth.user}:${adminUserAuth.password}`, - )}`, - }, + // Reset user settings (i.e. table ordering) + cy.request({ + method: "POST", + url: "/api/v2/user/resetAllSettings", + cache: "no-cache", + credentials: "same-origin", + auth: bearerAuth(token), + headers: { + "Content-Type": "application/json", + }, + }); }); }; @@ -291,15 +332,17 @@ export const getImportFileFromFixtures = (fileName, encoding, dataSet) => { }; export const createStratigraphy = (boreholeId, kindId) => { - return cy.request({ - method: "POST", - url: "/api/v2/stratigraphy", - body: { - boreholeId: boreholeId, - kindId: kindId, - }, - cache: "no-cache", - credentials: "same-origin", - auth: adminUserAuth, + cy.get("@id_token").then(token => { + return cy.request({ + method: "POST", + url: "/api/v2/stratigraphy", + body: { + boreholeId: boreholeId, + kindId: kindId, + }, + cache: "no-cache", + credentials: "same-origin", + auth: bearerAuth(token), + }); }); }; diff --git a/src/client/cypress/e2e/viewer/displayLayer.cy.js b/src/client/cypress/e2e/viewer/displayLayer.cy.js index ee545ef8b..61ad6ba7a 100644 --- a/src/client/cypress/e2e/viewer/displayLayer.cy.js +++ b/src/client/cypress/e2e/viewer/displayLayer.cy.js @@ -1,6 +1,6 @@ import { newEditableBorehole, - login, + loginAsAdmin, createBorehole, setValueOfInputElement, } from "../testHelpers"; @@ -8,7 +8,8 @@ import { describe("Test for the borehole form.", () => { it("Adds complete layer and displays it in viewer mode, checks if fields can be optionally hidden.", () => { // Assert map number of boreholes - login("/editor"); + loginAsAdmin(); + cy.visit("/editor"); cy.get("div[id=map]").should("be.visible"); cy.get("tbody").children().should("have.length", 100); @@ -155,7 +156,8 @@ describe("Test for the borehole form.", () => { it("Checks if null values are displayed as dash.", () => { createBorehole({ "extended.original_name": "A1_Borehole" }); - login(); + loginAsAdmin(); + cy.visit("/"); // Select borehole A1_Borehole cy.get("tbody").children().contains("td", "A1_Borehole").click(); diff --git a/src/client/src/pages/settings/dataLoader.js b/src/client/src/pages/settings/dataLoader.js index 3335a223f..9c561f3d7 100644 --- a/src/client/src/pages/settings/dataLoader.js +++ b/src/client/src/pages/settings/dataLoader.js @@ -175,6 +175,7 @@ class DataLoader extends React.Component { style={{ marginTop: "1.5em", }} + data-cy="login-button" /> )} @@ -200,7 +201,6 @@ DataLoader.propTypes = { loadBoreholeCount: PropTypes.func, loadSettings: PropTypes.func, loadUser: PropTypes.func, - setUser: PropTypes.func, user: PropTypes.object, };