From d81910d72184d5dbe028aa3271793ad7f32a1077 Mon Sep 17 00:00:00 2001 From: Angel Mendez Date: Mon, 19 Feb 2024 05:09:17 -0600 Subject: [PATCH] Migration: typescript/okta commands.js (#25730) * refactor: migrate okta _commands.js to typescript - convert okta _commands.js file to typescript - add types to function arguments - declare types for functions into same file * docs: add docs for okta_commands.ts - add documentation - improve type definitions - add return types * refactor: create interface for okta response on okta_commands.ts - create interface OktaResponse - replace any with OktaResponse --------- Co-authored-by: Mattermost Build --- .../{okta_commands.js => okta_commands.ts} | 210 ++++++++++++++---- 1 file changed, 170 insertions(+), 40 deletions(-) rename e2e-tests/cypress/tests/support/{okta_commands.js => okta_commands.ts} (54%) diff --git a/e2e-tests/cypress/tests/support/okta_commands.js b/e2e-tests/cypress/tests/support/okta_commands.ts similarity index 54% rename from e2e-tests/cypress/tests/support/okta_commands.js rename to e2e-tests/cypress/tests/support/okta_commands.ts index bf471aec63..19de9c8100 100644 --- a/e2e-tests/cypress/tests/support/okta_commands.js +++ b/e2e-tests/cypress/tests/support/okta_commands.ts @@ -1,12 +1,52 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {ChainableT} from 'tests/types'; import * as TIMEOUTS from '../fixtures/timeouts'; const token = 'SSWS ' + Cypress.env('oktaMMAppToken'); -function buildProfile(user) { - const profile = { +type UserId = string | null; + +interface Profile { + firstName: string; + lastName: string; + email: string; + login: string; + userType: string; + isAdmin: string; + isGuest: string; +} + +interface User { + firstname: string; + lastname: string; + email: string; + login: string; + userType: string; + isAdmin: string; + isGuest: string; + password: string; +} + +interface UserCollection { + admins: User[]; + guests: User[]; + regulars: User[]; +} + +interface OktaResponse { + status: number; + data: T; +} + +/** + * Builds a user profile object + * @param {Object} user - the user data + * @returns {Object} profile: the user profile + */ +function buildProfile(user: User): Profile { + const profile: Profile = { firstName: user.firstname, lastName: user.lastname, email: user.email, @@ -18,7 +58,12 @@ function buildProfile(user) { return profile; } -Cypress.Commands.add('oktaCreateUser', (user = {}) => { +/** + * creates a user + * @param {Object} user - the user to create + * @returns {String} userId: the user id + */ +function oktaCreateUser(user: any = {}): ChainableT { const profile = buildProfile(user); return cy.task('oktaRequest', { baseUrl: Cypress.env('oktaApiUrl'), @@ -35,29 +80,44 @@ Cypress.Commands.add('oktaCreateUser', (user = {}) => { }, }, }, - }).then((response) => { + }).then((response: OktaResponse<{id: UserId}>) => { expect(response.status).to.equal(200); const userId = response.data.id; return cy.wrap(userId); }); -}); +} -Cypress.Commands.add('oktaGetUser', (userId = '') => { +Cypress.Commands.add('oktaCreateUser', oktaCreateUser); + +/** + * gets a user by user id + * @param {String} userId - the user id + * @returns {String} userId: the user id or null if not found + */ +function oktaGetUser(userId: string = ''): ChainableT { return cy.task('oktaRequest', { baseUrl: Cypress.env('oktaApiUrl'), urlSuffix: '/users?q=' + userId, method: 'get', token, - }).then((response) => { + }).then((response: OktaResponse>) => { expect(response.status).to.be.equal(200); if (response.data.length > 0) { return cy.wrap(response.data[0].id); } - return cy.wrap(null); + return cy.wrap(null as UserId); }); -}); +} -Cypress.Commands.add('oktaUpdateUser', (userId = '', user = {}) => { +Cypress.Commands.add('oktaGetUser', oktaGetUser); + +/** + * Updates the user data + * @param {String} userId - the user id + * @param {Object} user - the user data + * @returns {Object} data: the user data as a response + */ +function oktaUpdateUser(userId: string = '', user: any = {}): ChainableT { const profile = buildProfile(user); return cy.task('oktaRequest', { @@ -68,20 +128,25 @@ Cypress.Commands.add('oktaUpdateUser', (userId = '', user = {}) => { data: { profile, }, - }).then((response) => { + }).then((response: OktaResponse) => { expect(response.status).to.equal(201); return cy.wrap(response.data); }); -}); +} -//first we deactivate the user, then we actually delete it -Cypress.Commands.add('oktaDeleteUser', (userId = '') => { +Cypress.Commands.add('oktaUpdateUser', oktaUpdateUser); + +/** + * deletes a user by user id + * @param {String} userId - the user id + */ +function oktaDeleteUser(userId: string = '') { cy.task('oktaRequest', { baseUrl: Cypress.env('oktaApiUrl'), urlSuffix: '/users/' + userId, method: 'delete', token, - }).then((response) => { + }).then((response: OktaResponse) => { expect(response.status).to.equal(204); expect(response.data).is.empty; cy.task('oktaRequest', { @@ -89,20 +154,27 @@ Cypress.Commands.add('oktaDeleteUser', (userId = '') => { urlSuffix: '/users/' + userId, method: 'delete', token, - }).then((_response) => { + }).then((_response: OktaResponse) => { expect(_response.status).to.equal(204); expect(_response.data).is.empty; }); }); -}); +} -Cypress.Commands.add('oktaDeleteSession', (userId = '') => { +//first we deactivate the user, then we actually delete it +Cypress.Commands.add('oktaDeleteUser', oktaDeleteUser); + +/** + * deletes a user's session + * @param {String} userId - the user id + */ +function oktaDeleteSession(userId: string = '') { cy.task('oktaRequest', { baseUrl: Cypress.env('oktaApiUrl'), urlSuffix: '/users/' + userId + '/sessions', method: 'delete', token, - }).then((response) => { + }).then((response: OktaResponse) => { expect(response.status).to.equal(204); expect(response.data).is.empty; @@ -111,9 +183,17 @@ Cypress.Commands.add('oktaDeleteSession', (userId = '') => { cy.clearCookie(cookie); }); }); -}); +} -Cypress.Commands.add('oktaAssignUserToApplication', (userId = '', user = {}) => { +Cypress.Commands.add('oktaDeleteSession', oktaDeleteSession); + +/** + * Assigns a user to an application + * @param {String} userId - the user id + * @param {Object} user - the user data + * @returns {Object} data: the user data as response + */ +function oktaAssignUserToApplication(userId: string = '', user: any = {}): ChainableT { return cy.task('oktaRequest', { baseUrl: Cypress.env('oktaApiUrl'), urlSuffix: '/apps/' + Cypress.env('oktaMMAppId') + '/users', @@ -128,13 +208,20 @@ Cypress.Commands.add('oktaAssignUserToApplication', (userId = '', user = {}) => email: user.email, }, }, - }).then((response) => { + }).then((response: OktaResponse) => { expect(response.status).to.be.equal(200); return cy.wrap(response.data); }); -}); +} -Cypress.Commands.add('oktaGetOrCreateUser', (user) => { +Cypress.Commands.add('oktaAssignUserToApplication', oktaAssignUserToApplication); + +/** + * Gets the user data if exists or create one if does not exists + * @param {Object} user - the user data + * @returns {String} userId: the user id + */ +function oktaGetOrCreateUser(user: User): ChainableT { let userId; return cy.oktaGetUser(user.email).then((uId) => { userId = uId; @@ -146,13 +233,19 @@ Cypress.Commands.add('oktaGetOrCreateUser', (user) => { } else { cy.oktaAssignUserToApplication(userId, user); } - return cy.wrap(userId); + return cy.wrap(userId as UserId); }); -}); +} -Cypress.Commands.add('oktaAddUsers', (users) => { +Cypress.Commands.add('oktaGetOrCreateUser', oktaGetOrCreateUser); + +/** + * Add users given a collection of users + * @param {Object} users - a collection of users + */ +function oktaAddUsers(users: UserCollection) { let userId; - Object.values(users.regulars).forEach((_user) => { + Object.values(users.regulars).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((uId) => { userId = uId; if (userId == null) { @@ -165,7 +258,7 @@ Cypress.Commands.add('oktaAddUsers', (users) => { }); }); - Object.values(users.guests).forEach((_user) => { + Object.values(users.guests).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((uId) => { userId = uId; if (userId == null) { @@ -178,7 +271,7 @@ Cypress.Commands.add('oktaAddUsers', (users) => { }); }); - Object.values(users.admins).forEach((_user) => { + Object.values(users.admins).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((uId) => { userId = uId; if (userId == null) { @@ -190,11 +283,17 @@ Cypress.Commands.add('oktaAddUsers', (users) => { } }); }); -}); +} -Cypress.Commands.add('oktaRemoveUsers', (users) => { +Cypress.Commands.add('oktaAddUsers', oktaAddUsers); + +/** + * Remove users given a collection of users + * @param {Object} users - a collection of users + */ +function oktaRemoveUsers(users: UserCollection) { let userId; - Object.values(users.regulars).forEach((_user) => { + Object.values(users.regulars).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((_uId) => { userId = _uId; if (userId != null) { @@ -203,7 +302,7 @@ Cypress.Commands.add('oktaRemoveUsers', (users) => { }); }); - Object.values(users.guests).forEach((_user) => { + Object.values(users.guests).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((_uId) => { userId = _uId; if (userId != null) { @@ -212,7 +311,7 @@ Cypress.Commands.add('oktaRemoveUsers', (users) => { }); }); - Object.values(users.admins).forEach((_user) => { + Object.values(users.admins).forEach((_user: User) => { cy.oktaGetUser(_user.email).then((_uId) => { userId = _uId; if (userId != null) { @@ -220,19 +319,50 @@ Cypress.Commands.add('oktaRemoveUsers', (users) => { } }); }); -}); +} -Cypress.Commands.add('checkOktaLoginPage', () => { +Cypress.Commands.add('oktaRemoveUsers', oktaRemoveUsers); + +/** + * check if okta login page is visible + */ +function checkOktaLoginPage() { cy.findByText('Powered by').should('be.visible'); cy.findAllByText('Sign In').should('be.visible'); cy.get('#okta-signin-password').should('be.visible'); cy.get('#okta-signin-submit').should('be.visible'); -}); +} -Cypress.Commands.add('doOktaLogin', (user) => { +Cypress.Commands.add('checkOktaLoginPage', checkOktaLoginPage); + +/** + * performs an okta login + */ +function doOktaLogin(user: User) { cy.checkOktaLoginPage(); cy.get('#okta-signin-username').type(user.email); cy.get('#okta-signin-password').type(user.password); cy.findAllByText('Sign In').last().click().wait(TIMEOUTS.FIVE_SEC); -}); +} + +Cypress.Commands.add('doOktaLogin', doOktaLogin); + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + interface Chainable { + oktaCreateUser: typeof oktaCreateUser; + oktaGetUser: typeof oktaGetUser; + oktaUpdateUser: typeof oktaUpdateUser; + oktaDeleteUser: typeof oktaDeleteUser; + oktaDeleteSession: typeof oktaDeleteSession; + oktaAssignUserToApplication: typeof oktaAssignUserToApplication; + oktaGetOrCreateUser: typeof oktaGetOrCreateUser; + oktaAddUsers: typeof oktaAddUsers; + oktaRemoveUsers: typeof oktaRemoveUsers; + checkOktaLoginPage: typeof checkOktaLoginPage; + doOktaLogin: typeof doOktaLogin; + } + } +}