mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-01 02:56:10 +00:00
Add & Organise Cypress User spec (#14624)
* add user spec * organize user spec * change test description * cover different user roles * change max password length * code refactor * fix failing update admin details test --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
c87b6d60fa
commit
406345e257
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
descriptionBox,
|
||||
interceptURL,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { VISIT_SERVICE_PAGE_DETAILS } from '../../constants/service.constants';
|
||||
import {
|
||||
permanentDeleteUser,
|
||||
restoreUser,
|
||||
softDeleteUser,
|
||||
} from '../Utils/Users';
|
||||
|
||||
class UsersTestClass {
|
||||
protected name: string;
|
||||
|
||||
public getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
visitUserListPage() {
|
||||
cy.get('[data-testid="app-bar-item-settings"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
cy.get('[data-testid="settings-left-panel"]').contains('Users').click();
|
||||
}
|
||||
|
||||
softDeleteUser(name) {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
softDeleteUser(name);
|
||||
}
|
||||
|
||||
restoreSoftDeletedUser(name, editedName) {
|
||||
restoreUser(name, editedName);
|
||||
}
|
||||
|
||||
permanentDeleteUser(name) {
|
||||
permanentDeleteUser(name);
|
||||
cy.logout();
|
||||
}
|
||||
|
||||
checkConsumerPermissions() {
|
||||
// check Add domain permission
|
||||
cy.get('[data-testid="add-domain"]').should('not.be.exist');
|
||||
cy.get('[data-testid="edit-displayName-button"]').should('not.be.exist');
|
||||
// check edit owner permission
|
||||
cy.get('[data-testid="edit-owner"]').should('not.be.exist');
|
||||
// check edit description permission
|
||||
cy.get('[data-testid="edit-description"]').should('be.exist');
|
||||
// check edit tier permission
|
||||
cy.get('[data-testid="edit-tier"]').should('be.exist');
|
||||
// check add tags button
|
||||
cy.get(
|
||||
':nth-child(2) > [data-testid="tags-container"] > [data-testid="entity-tags"] > .m-t-xss > .ant-tag'
|
||||
).should('be.exist');
|
||||
// check add glossary term button
|
||||
cy.get(
|
||||
':nth-child(3) > [data-testid="glossary-container"] > [data-testid="entity-tags"] > .m-t-xss > .ant-tag'
|
||||
).should('be.exist');
|
||||
// check edit tier permission
|
||||
cy.get('[data-testid="manage-button"]').should('not.be.exist');
|
||||
cy.get('[data-testid="lineage"] > .ant-space-item').click();
|
||||
cy.get('[data-testid="edit-lineage"]').should('be.disabled');
|
||||
}
|
||||
|
||||
checkStewardServicesPermissions() {
|
||||
cy.get('[data-testid="app-bar-item-explore"]').click();
|
||||
Object.values(VISIT_SERVICE_PAGE_DETAILS).forEach((service) => {
|
||||
cy.get('[data-testid="app-bar-item-settings"]').click();
|
||||
cy.get(`[data-menu-id*="${service.settingsMenuId}"]`).click();
|
||||
cy.get('[data-testid="add-service-button"] > span').should('not.exist');
|
||||
});
|
||||
cy.get('[data-testid="app-bar-item-explore"]').click();
|
||||
cy.get('[data-testid="tables-tab"] > .ant-space').click();
|
||||
cy.get(
|
||||
'.ant-drawer-title > [data-testid="entity-link"] > .ant-typography'
|
||||
).click();
|
||||
cy.get('[data-testid="edit-tier"]').should('be.visible');
|
||||
}
|
||||
|
||||
checkStewardPermissions() {
|
||||
// check Add domain permission
|
||||
cy.get('[data-testid="add-domain"]').should('not.be.exist');
|
||||
cy.get('[data-testid="edit-displayName-button"]').should('be.exist');
|
||||
// check edit owner permission
|
||||
cy.get('[data-testid="edit-owner"]').should('be.exist');
|
||||
// check edit description permission
|
||||
cy.get('[data-testid="edit-description"]').should('be.exist');
|
||||
// check edit tier permission
|
||||
cy.get('[data-testid="edit-tier"]').should('be.exist');
|
||||
// check add tags button
|
||||
cy.get(
|
||||
':nth-child(2) > [data-testid="tags-container"] > [data-testid="entity-tags"] > .m-t-xss > .ant-tag'
|
||||
).should('be.exist');
|
||||
// check add glossary term button
|
||||
cy.get(
|
||||
':nth-child(3) > [data-testid="glossary-container"] > [data-testid="entity-tags"] > .m-t-xss > .ant-tag'
|
||||
).should('be.exist');
|
||||
// check edit tier permission
|
||||
cy.get('[data-testid="manage-button"]').should('be.exist');
|
||||
cy.get('[data-testid="lineage"] > .ant-space-item').click();
|
||||
cy.get('[data-testid="edit-lineage"]').should('be.enabled');
|
||||
}
|
||||
|
||||
restoreAdminDetails() {
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
cy.get('[data-testid="edit-displayName"]').should('be.visible');
|
||||
cy.get('[data-testid="edit-displayName"]').click();
|
||||
cy.get('[data-testid="displayName"]').clear();
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'updateName');
|
||||
cy.get('[data-testid="inline-save-btn"]').click();
|
||||
cy.get('[data-testid="edit-displayName"]').scrollIntoView();
|
||||
verifyResponseStatusCode('@updateName', 200);
|
||||
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
cy.get('[data-testid="edit-teams-button"]').click();
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'updateTeam');
|
||||
cy.get('.ant-select-selection-item-remove > .anticon').click();
|
||||
cy.get('[data-testid="inline-save-btn"]').click();
|
||||
verifyResponseStatusCode('@updateTeam', 200);
|
||||
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
cy.get('[data-testid="edit-description"]').click();
|
||||
cy.get(descriptionBox).clear();
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'patchDescription');
|
||||
cy.get('[data-testid="save"]').should('be.visible').click();
|
||||
verifyResponseStatusCode('@patchDescription', 200);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
}
|
||||
}
|
||||
|
||||
export default UsersTestClass;
|
||||
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {
|
||||
customFormatDateTime,
|
||||
getEpochMillisForFutureDays,
|
||||
} from '../../../src/utils/date-time/DateTimeUtils';
|
||||
import {
|
||||
descriptionBox,
|
||||
interceptURL,
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../common';
|
||||
|
||||
export const addUser = ({
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
role,
|
||||
}: {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
role: string;
|
||||
}) => {
|
||||
cy.get('[data-testid="add-user"]').click();
|
||||
|
||||
cy.get('[data-testid="email"]')
|
||||
.scrollIntoView()
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(email);
|
||||
cy.get('[data-testid="displayName"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(name);
|
||||
cy.get(descriptionBox)
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type('Adding user');
|
||||
cy.get(':nth-child(2) > .ant-radio > .ant-radio-input').click();
|
||||
cy.get('#password').type(password);
|
||||
cy.get('#confirmPassword').type(password);
|
||||
cy.get('[data-testid="roles-dropdown"] > .ant-select-selector')
|
||||
.click()
|
||||
.type(role);
|
||||
cy.get('.ant-select-item-option-content').click();
|
||||
cy.get('[data-testid="roles-dropdown"] > .ant-select-selector').click();
|
||||
interceptURL('POST', ' /api/v1/users', 'add-user');
|
||||
cy.get('[data-testid="save-user"]').scrollIntoView().click();
|
||||
verifyResponseStatusCode('@add-user', 201);
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
};
|
||||
|
||||
export const visitProfileSection = () => {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').click();
|
||||
};
|
||||
export const softDeleteUser = (username: string) => {
|
||||
// Search the created user
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=**&from=0&size=*&index=*',
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
// Click on delete button
|
||||
cy.get(`[data-testid="delete-user-btn-${username}"]`);
|
||||
cy.get(':nth-child(4) > .ant-space > .ant-space-item > .ant-btn').click();
|
||||
// Soft deleting the user
|
||||
cy.get('[data-testid="soft-delete"]').click();
|
||||
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
||||
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
'/api/v1/users/*?hardDelete=false&recursive=false',
|
||||
'softdeleteUser'
|
||||
);
|
||||
interceptURL('GET', '/api/v1/users*', 'userDeleted');
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode('@softdeleteUser', 200);
|
||||
verifyResponseStatusCode('@userDeleted', 200);
|
||||
|
||||
toastNotification('User deleted successfully!');
|
||||
|
||||
interceptURL('GET', '/api/v1/search/query*', 'searchUser');
|
||||
|
||||
// Verifying the deleted user
|
||||
cy.get('[data-testid="searchbar"]').scrollIntoView().clear().type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
};
|
||||
|
||||
export const restoreUser = (username: string, editedUserName: string) => {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
// Click on deleted user toggle
|
||||
cy.get('[data-testid="show-deleted"]').click();
|
||||
interceptURL('GET', '/api/v1/search/query*', 'searchUser');
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
cy.get(`[data-testid="restore-user-btn-${username}"]`).click();
|
||||
cy.get('.ant-modal-body > p').should(
|
||||
'contain',
|
||||
`Are you sure you want to restore ${editedUserName}?`
|
||||
);
|
||||
interceptURL('PUT', '/api/v1/users', 'restoreUser');
|
||||
cy.get('.ant-modal-footer > .ant-btn-primary').click();
|
||||
verifyResponseStatusCode('@restoreUser', 200);
|
||||
toastNotification('User restored successfully');
|
||||
};
|
||||
|
||||
export const permanentDeleteUser = (username: string) => {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
interceptURL('GET', '/api/v1/users/name/*', 'getUser');
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
verifyResponseStatusCode('@getUser', 200);
|
||||
interceptURL('GET', '/api/v1/search/query*', 'searchUser');
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
cy.get(`[data-testid="delete-user-btn-${username}"]`).click();
|
||||
cy.get('[data-testid="hard-delete"]').click();
|
||||
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
'api/v1/users/*?hardDelete=true&recursive=false',
|
||||
'hardDeleteUser'
|
||||
);
|
||||
cy.get('[data-testid="confirm-button"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
verifyResponseStatusCode('@hardDeleteUser', 200);
|
||||
|
||||
toastNotification('User deleted successfully!');
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/search/query?q=**&from=0&size=15&index=user_search_index',
|
||||
'searchUser'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
cy.get('[data-testid="search-error-placeholder"]').should('be.exist');
|
||||
};
|
||||
export const visitUserListPage = () => {
|
||||
cy.get('[data-testid="app-bar-item-settings"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
cy.get('[data-testid="settings-left-panel"]').contains('Users').click();
|
||||
};
|
||||
|
||||
export const generateToken = () => {
|
||||
cy.get('[data-testid="no-token"]').should('be.visible');
|
||||
cy.get('[data-testid="auth-mechanism"] > span').click();
|
||||
cy.get('[data-testid="token-expiry"]').should('be.visible').click();
|
||||
cy.contains('1 hr').should('exist').should('be.visible').click();
|
||||
cy.get('[data-testid="token-expiry"]').should('be.visible');
|
||||
cy.get('[data-testid="save-edit"]').should('be.visible').click();
|
||||
};
|
||||
|
||||
export const revokeToken = () => {
|
||||
cy.get('[data-testid="revoke-button"]').should('be.visible').click();
|
||||
cy.get('[data-testid="body-text"]').should(
|
||||
'contain',
|
||||
'Are you sure you want to revoke access for Personal Access Token?'
|
||||
);
|
||||
cy.get('[data-testid="save-button"]').click();
|
||||
cy.get('[data-testid="revoke-button"]').should('not.exist');
|
||||
};
|
||||
|
||||
export const updateExpiration = (expiry: number) => {
|
||||
cy.get('[data-testid="dropdown-profile"]').click();
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').click();
|
||||
cy.get('[data-testid="no-token"]').should('be.visible');
|
||||
cy.get('[data-testid="auth-mechanism"] > span').click();
|
||||
|
||||
cy.get('[data-testid="token-expiry"]').click();
|
||||
cy.contains(`${expiry} days`).click();
|
||||
const expiryDate = customFormatDateTime(
|
||||
getEpochMillisForFutureDays(expiry),
|
||||
`ccc d'th' MMMM, yyyy`
|
||||
);
|
||||
cy.get('[data-testid="save-edit"]').click();
|
||||
cy.get('[data-testid="center-panel"]')
|
||||
.find('[data-testid="revoke-button"]')
|
||||
.should('be.visible');
|
||||
cy.get('[data-testid="token-expiry"]')
|
||||
.invoke('text')
|
||||
.should('contain', `Expires on ${expiryDate}`);
|
||||
cy.get('[data-testid="token-expiry"]').click();
|
||||
revokeToken();
|
||||
};
|
||||
|
||||
export const editDisplayName = (editedUserName: string) => {
|
||||
cy.get('[data-testid="edit-displayName"]').should('be.visible');
|
||||
cy.get('[data-testid="edit-displayName"]').click();
|
||||
cy.get('[data-testid="displayName"]').clear();
|
||||
cy.get('[data-testid="displayName"]').type(editedUserName);
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'updateName');
|
||||
cy.get('[data-testid="inline-save-btn"]').click();
|
||||
cy.get('[data-testid="edit-displayName"]').scrollIntoView();
|
||||
cy.get('[data-testid="user-name"]').should('contain', editedUserName);
|
||||
};
|
||||
|
||||
export const editDescription = (updatedDescription: string) => {
|
||||
cy.get('[data-testid="edit-description"]').click();
|
||||
cy.get(descriptionBox).clear().type(updatedDescription);
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'patchDescription');
|
||||
cy.get('[data-testid="save"]').should('be.visible').click();
|
||||
verifyResponseStatusCode('@patchDescription', 200);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
cy.get(
|
||||
':nth-child(2) > :nth-child(1) > [data-testid="viewer-container"] > [data-testid="markdown-parser"] > :nth-child(1) > .toastui-editor-contents > p'
|
||||
).should('contain', updatedDescription);
|
||||
};
|
||||
|
||||
export const editTeams = (teamName: string) => {
|
||||
cy.get('[data-testid="edit-teams-button"]').click();
|
||||
cy.get('.ant-select-selection-item-remove > .anticon').click();
|
||||
cy.get('[data-testid="team-select"]').click();
|
||||
cy.get('[data-testid="team-select"]').type(teamName);
|
||||
interceptURL('PATCH', '/api/v1/users/*', 'updateTeams');
|
||||
cy.get('.filter-node > .ant-select-tree-node-content-wrapper').click();
|
||||
cy.get('[data-testid="inline-save-btn"]').click({ timeout: 10000 });
|
||||
verifyResponseStatusCode('@updateTeams', 200);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
cy.get(`[data-testid="${teamName}"]`).should('exist').and('be.visible');
|
||||
};
|
||||
|
||||
export const handleUserUpdateDetails = (
|
||||
editedUserName: string,
|
||||
updatedDescription: string
|
||||
) => {
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
// edit displayName
|
||||
editDisplayName(editedUserName);
|
||||
// edit description
|
||||
cy.wait(500);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
editDescription(updatedDescription);
|
||||
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
};
|
||||
|
||||
export const handleAdminUpdateDetails = (
|
||||
editedUserName: string,
|
||||
updatedDescription: string,
|
||||
teamName: string,
|
||||
role?: string
|
||||
) => {
|
||||
// edit displayName
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
editDisplayName(editedUserName);
|
||||
|
||||
// edit teams
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
editTeams(teamName);
|
||||
|
||||
// edit description
|
||||
cy.wait(500);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
editDescription(updatedDescription);
|
||||
|
||||
// edit roles
|
||||
cy.get(`[data-testid="chip-container"]`).should('contain', role);
|
||||
};
|
||||
|
||||
export const updateDetails = ({
|
||||
updatedDisplayName,
|
||||
updatedDescription,
|
||||
isAdmin,
|
||||
teamName,
|
||||
role,
|
||||
}: {
|
||||
email: string;
|
||||
password: string;
|
||||
updatedDisplayName: string;
|
||||
updatedDescription: string;
|
||||
teamName: string;
|
||||
isAdmin?: boolean;
|
||||
role?: string;
|
||||
}) => {
|
||||
isAdmin
|
||||
? handleAdminUpdateDetails(
|
||||
updatedDisplayName,
|
||||
updatedDescription,
|
||||
teamName,
|
||||
role
|
||||
)
|
||||
: handleUserUpdateDetails(updatedDisplayName, updatedDescription);
|
||||
};
|
||||
|
||||
export const resetPassword = (password: string, newPassword: string) => {
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
cy.clickOutside();
|
||||
cy.get('[data-testid="change-password-button"]').click();
|
||||
cy.get('.ant-modal-wrap').should('be.visible');
|
||||
cy.get('[data-testid="input-oldPassword"]').clear().type(password);
|
||||
cy.get('[data-testid="input-newPassword"]').clear().type(newPassword);
|
||||
cy.get('[data-testid="input-confirm-newPassword"]').clear().type(newPassword);
|
||||
interceptURL('PUT', '/api/v1/users/changePassword', 'changePassword');
|
||||
cy.get('.ant-modal-footer > .ant-btn-primary')
|
||||
.contains('Update Password')
|
||||
.click();
|
||||
verifyResponseStatusCode('@changePassword', 200);
|
||||
toastNotification('Password updated successfully.');
|
||||
};
|
||||
|
||||
export const editRole = (username: string, role: string) => {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
|
||||
// Search the created user
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=**&from=0&size=*&index=*',
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
cy.get(`[data-testid=${username}]`).click();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').click();
|
||||
cy.get('[data-testid="edit-roles-button"]').click();
|
||||
cy.get('.ant-select-selection-item-remove > .anticon').click();
|
||||
cy.get('[data-testid="inline-edit-container"] #select-role')
|
||||
.click()
|
||||
.type(role);
|
||||
cy.get('.ant-select-item-option-content').contains(role).click();
|
||||
interceptURL('PATCH', `/api/v1/users/*`, 'updateRole');
|
||||
cy.get('[data-testid="inline-save-btn"]').click();
|
||||
verifyResponseStatusCode('@updateRole', 200);
|
||||
cy.get('.ant-collapse-expand-icon > .anticon > svg').scrollIntoView();
|
||||
cy.get(`[data-testid=chip-container]`).should('contain', role);
|
||||
};
|
||||
@ -657,140 +657,6 @@ export const addNewTagToEntity = (entityObj, term) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const addUser = (username, email) => {
|
||||
cy.get('[data-testid="email"]')
|
||||
.scrollIntoView()
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(email);
|
||||
cy.get('[data-testid="displayName"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(username);
|
||||
cy.get(descriptionBox)
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type('Adding user');
|
||||
interceptURL('GET', ' /api/v1/users/generateRandomPwd', 'generatePassword');
|
||||
cy.get('[data-testid="password-generator"]').should('be.visible').click();
|
||||
interceptURL('POST', ' /api/v1/users', 'add-user');
|
||||
verifyResponseStatusCode('@generatePassword', 200);
|
||||
cy.get('[data-testid="save-user"]').scrollIntoView().click();
|
||||
verifyResponseStatusCode('@add-user', 201);
|
||||
};
|
||||
|
||||
export const softDeleteUser = (username, isAdmin) => {
|
||||
// Search the created user
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=**&from=0&size=*&index=*',
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
// Click on delete button
|
||||
cy.get(`[data-testid="delete-user-btn-${username}"]`).click();
|
||||
|
||||
// Soft deleting the user
|
||||
cy.get('[data-testid="soft-delete"]').click();
|
||||
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
||||
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
'/api/v1/users/*?hardDelete=false&recursive=false',
|
||||
'softdeleteUser'
|
||||
);
|
||||
interceptURL('GET', '/api/v1/users*', 'userDeleted');
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode('@softdeleteUser', 200);
|
||||
verifyResponseStatusCode('@userDeleted', 200);
|
||||
|
||||
toastNotification('User deleted successfully!');
|
||||
|
||||
interceptURL('GET', '/api/v1/search/query*', 'searchUser');
|
||||
|
||||
// Verifying the deleted user
|
||||
cy.get('[data-testid="searchbar"]').scrollIntoView().clear().type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
|
||||
};
|
||||
|
||||
export const restoreUser = (username) => {
|
||||
// Click on deleted user toggle
|
||||
interceptURL('GET', '/api/v1/users*', 'deletedUser');
|
||||
cy.get('[data-testid="show-deleted"]').click();
|
||||
verifyResponseStatusCode('@deletedUser', 200);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=**&from=0&size=*&index=*',
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
cy.get(`[data-testid="restore-user-btn-${username}"]`).click();
|
||||
cy.get('.ant-modal-body > p').should(
|
||||
'contain',
|
||||
`Are you sure you want to restore ${username}?`
|
||||
);
|
||||
interceptURL('PUT', '/api/v1/users', 'restoreUser');
|
||||
cy.get('.ant-modal-footer > .ant-btn-primary').click();
|
||||
verifyResponseStatusCode('@restoreUser', 200);
|
||||
toastNotification('User restored successfully');
|
||||
|
||||
// Verifying the restored user
|
||||
cy.get('[data-testid="show-deleted"]').click();
|
||||
|
||||
interceptURL('GET', '/api/v1/search/query*', 'searchUser');
|
||||
cy.get('[data-testid="searchbar"]').type(username);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
cy.get(`[data-testid=${username}]`).should('exist');
|
||||
};
|
||||
|
||||
export const deleteSoftDeletedUser = (username) => {
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
|
||||
cy.get('.ant-switch-handle').should('exist').should('be.visible').click();
|
||||
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
|
||||
cy.get(`[data-testid="delete-user-btn-${username}"]`)
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
'api/v1/users/*?hardDelete=true&recursive=false',
|
||||
'hardDeleteUser'
|
||||
);
|
||||
cy.get('[data-testid="confirm-button"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
verifyResponseStatusCode('@hardDeleteUser', 200);
|
||||
|
||||
toastNotification('User deleted successfully!');
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/search/query?q=**&from=0&size=15&index=user_search_index',
|
||||
'searchUser'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="searchbar"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(username);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
|
||||
cy.get('[data-testid="search-error-placeholder"]').should('be.visible');
|
||||
};
|
||||
|
||||
export const toastNotification = (msg, closeToast = true) => {
|
||||
cy.get('.Toastify__toast-body').should('contain.text', msg);
|
||||
cy.wait(200);
|
||||
|
||||
@ -740,3 +740,73 @@ export const DOMAIN_3 = {
|
||||
},
|
||||
],
|
||||
};
|
||||
export const GLOBAL_SETTING_PERMISSIONS = {
|
||||
metadata: {
|
||||
testid: '[data-menu-id*="metadata"]',
|
||||
},
|
||||
customAttributesTable: {
|
||||
testid: '[data-menu-id*="tables"]',
|
||||
},
|
||||
customAttributesTopics: {
|
||||
testid: '[data-menu-id*="topics"]',
|
||||
},
|
||||
customAttributesDashboards: {
|
||||
testid: '[data-menu-id*="customAttributes.dashboards"]',
|
||||
},
|
||||
customAttributesPipelines: {
|
||||
testid: '[data-menu-id*="customAttributes.pipelines"]',
|
||||
},
|
||||
customAttributesMlModels: {
|
||||
testid: '[data-menu-id*="customAttributes.mlModels"]',
|
||||
},
|
||||
bots: {
|
||||
testid: '[data-menu-id*="bots"]',
|
||||
},
|
||||
};
|
||||
export const ID = {
|
||||
teams: {
|
||||
testid: '[data-menu-id*="teams"]',
|
||||
button: 'add-team',
|
||||
api: '/api/v1/teams/name/Organization?*',
|
||||
},
|
||||
users: {
|
||||
testid: '[data-menu-id*="users"]',
|
||||
button: 'add-user',
|
||||
api: '/api/v1/users?*',
|
||||
},
|
||||
admins: {
|
||||
testid: '[data-menu-id*="admins"]',
|
||||
button: 'add-user',
|
||||
api: '/api/v1/users?*',
|
||||
},
|
||||
databases: {
|
||||
testid: '[data-menu-id*="databases"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/databaseServices?*',
|
||||
},
|
||||
messaging: {
|
||||
testid: '[data-menu-id*="messaging"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/messagingServices?*',
|
||||
},
|
||||
dashboard: {
|
||||
testid: '[data-menu-id*="services.dashboards"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/dashboardServices?*',
|
||||
},
|
||||
pipelines: {
|
||||
testid: '[data-menu-id*="services.pipelines"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/pipelineServices?*',
|
||||
},
|
||||
mlmodels: {
|
||||
testid: '[data-menu-id*="services.mlmodels"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/mlmodelServices?*',
|
||||
},
|
||||
storage: {
|
||||
testid: '[data-menu-id*="services.storages"]',
|
||||
button: 'add-service-button',
|
||||
api: '/api/v1/services/storageServices?*',
|
||||
},
|
||||
};
|
||||
|
||||
@ -69,4 +69,8 @@ export const VISIT_SERVICE_PAGE_DETAILS = {
|
||||
settingsMenuId: 'services.search',
|
||||
serviceCategory: SERVICE_CATEGORIES.SEARCH_SERVICES,
|
||||
},
|
||||
[SERVICE_TYPE.Metadata]: {
|
||||
settingsMenuId: 'services.metadata',
|
||||
serviceCategory: SERVICE_CATEGORIES.METADATA_SERVICES,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="cypress" />
|
||||
import {
|
||||
customFormatDateTime,
|
||||
getEpochMillisForFutureDays,
|
||||
} from '../../../src/utils/date-time/DateTimeUtils';
|
||||
import {
|
||||
addUser,
|
||||
deleteSoftDeletedUser,
|
||||
interceptURL,
|
||||
restoreUser,
|
||||
softDeleteUser,
|
||||
uuid,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
|
||||
const userName = `Usercttest${uuid()}`;
|
||||
const userEmail = `${userName}@gmail.com`;
|
||||
|
||||
const adminName = `Admincttest${uuid()}`;
|
||||
const adminEmail = `${adminName}@gmail.com`;
|
||||
|
||||
const searchBotText = 'bot';
|
||||
|
||||
const expirationTime = {
|
||||
oneday: '1',
|
||||
sevendays: '7',
|
||||
onemonth: '30',
|
||||
twomonths: '60',
|
||||
threemonths: '90',
|
||||
};
|
||||
|
||||
const revokeToken = () => {
|
||||
// Click on revoke button
|
||||
cy.get('[data-testid="revoke-button"]').should('be.visible').click();
|
||||
// Verify the revoke text
|
||||
cy.get('[data-testid="body-text"]').should(
|
||||
'contain',
|
||||
'Are you sure you want to revoke access for Personal Access Token?'
|
||||
);
|
||||
// Click on confirm button
|
||||
cy.get('[data-testid="save-button"]').click();
|
||||
// Verify the revoke is successful
|
||||
cy.get('[data-testid="revoke-button"]').should('not.exist');
|
||||
};
|
||||
|
||||
describe('Users flow should work properly', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
|
||||
cy.get('[data-testid="app-bar-item-settings"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
interceptURL('GET', '/api/v1/users?*', 'getUsers');
|
||||
cy.get('[data-testid="settings-left-panel"]').contains('Users').click();
|
||||
});
|
||||
|
||||
it('Add new User', () => {
|
||||
// Clicking on Add user button
|
||||
cy.get('[data-testid="add-user"]').click();
|
||||
|
||||
addUser(userName, userEmail);
|
||||
verifyResponseStatusCode('@getUsers', 200);
|
||||
});
|
||||
|
||||
it('Soft delete user', () => {
|
||||
softDeleteUser(userName);
|
||||
});
|
||||
|
||||
it('Restore soft deleted user', () => {
|
||||
restoreUser(userName);
|
||||
});
|
||||
|
||||
it('Permanently Delete Soft Deleted User', () => {
|
||||
softDeleteUser(userName);
|
||||
deleteSoftDeletedUser(userName);
|
||||
});
|
||||
|
||||
it('Search for bot user', () => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/search/query?q=*${searchBotText}***isBot:false&from=0&size=25&index=user_search_index`,
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(searchBotText);
|
||||
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Admin flow should work properly', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
|
||||
cy.get('[data-testid="app-bar-item-settings"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
interceptURL('GET', '/api/v1/users?*isAdmin=true*', 'getAdmins');
|
||||
cy.get('.ant-menu-title-content')
|
||||
.contains('Admins')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
});
|
||||
|
||||
it('Add admin user', () => {
|
||||
// Clicking on add user button
|
||||
cy.get('[data-testid="add-user"]').click();
|
||||
|
||||
// Setting the user to admin before adding user
|
||||
cy.get('[data-testid="admin"]')
|
||||
.scrollIntoView()
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
addUser(adminName, adminEmail);
|
||||
verifyResponseStatusCode('@getAdmins', 200);
|
||||
|
||||
// Validate if user is added in the User tab
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/search/query?q=**&from=0&size=*&index=*',
|
||||
'searchUser'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]')
|
||||
.should('exist')
|
||||
.should('be.visible')
|
||||
.type(adminName);
|
||||
verifyResponseStatusCode('@searchUser', 200);
|
||||
cy.get('.ant-table-tbody ').should('contain', adminName);
|
||||
});
|
||||
|
||||
it('Soft delete admin', () => {
|
||||
softDeleteUser(adminName, true);
|
||||
});
|
||||
|
||||
it('Restore soft deleted admin', () => {
|
||||
restoreUser(adminName);
|
||||
});
|
||||
|
||||
it('Permanently Delete Soft Deleted admin', () => {
|
||||
softDeleteUser(adminName, true);
|
||||
deleteSoftDeletedUser(adminName);
|
||||
});
|
||||
|
||||
describe('Personal Access Token flow should work properly', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('Token should be generated and revoked', function () {
|
||||
// Enter profile section
|
||||
cy.get('.username').click();
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click();
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').click();
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').should(
|
||||
'be.visible'
|
||||
);
|
||||
|
||||
// generate token
|
||||
cy.get('[data-testid="no-token"]').should('be.visible');
|
||||
cy.get('[data-testid="auth-mechanism"] > span').click();
|
||||
cy.get('[data-testid="token-expiry"]').should('be.visible').click();
|
||||
cy.contains('1 hr').should('exist').should('be.visible').click();
|
||||
cy.get('[data-testid="token-expiry"]').should('be.visible');
|
||||
cy.get('[data-testid="save-edit"]').should('be.visible').click();
|
||||
|
||||
// revoke token
|
||||
cy.get('[data-testid="revoke-button"] > span').should('be.visible');
|
||||
cy.get('[data-testid="revoke-button"] > span').click();
|
||||
cy.get('[data-testid="save-button"] > span').click();
|
||||
cy.get(':nth-child(1) > .ant-row > .ant-form-item-label > label').should(
|
||||
'be.visible'
|
||||
);
|
||||
});
|
||||
|
||||
Object.values(expirationTime).forEach((expiry) => {
|
||||
it(`Update token expiration for ${expiry} days`, () => {
|
||||
cy.get('.username').click();
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click();
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').click();
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.get('[data-testid="no-token"]').should('be.visible');
|
||||
cy.get('[data-testid="auth-mechanism"] > span').click();
|
||||
|
||||
cy.get('[data-testid="token-expiry"]').click();
|
||||
// Select the expiration period
|
||||
cy.contains(`${expiry} days`).click();
|
||||
// Save the updated date
|
||||
const expiryDate = customFormatDateTime(
|
||||
getEpochMillisForFutureDays(expiry),
|
||||
`ccc d'th' MMMM, yyyy`
|
||||
);
|
||||
cy.get('[data-testid="save-edit"]').click();
|
||||
cy.get('[data-testid="center-panel"]')
|
||||
.find('[data-testid="revoke-button"]')
|
||||
.should('be.visible');
|
||||
// Verify the expiry time
|
||||
cy.get('[data-testid="token-expiry"]')
|
||||
.invoke('text')
|
||||
.should('contain', `Expires on ${expiryDate}`);
|
||||
cy.get('[data-testid="token-expiry"]').click();
|
||||
revokeToken();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// eslint-disable-next-line spaced-comment
|
||||
import UsersTestClass from '../../common/Entities/UserClass';
|
||||
import { visitEntityDetailsPage } from '../../common/Utils/Entity';
|
||||
import { addOwner, removeOwner } from '../../common/Utils/Owner';
|
||||
import {
|
||||
addUser,
|
||||
editRole,
|
||||
generateToken,
|
||||
resetPassword,
|
||||
revokeToken,
|
||||
updateDetails,
|
||||
updateExpiration,
|
||||
visitUserListPage,
|
||||
} from '../../common/Utils/Users';
|
||||
import { interceptURL, verifyResponseStatusCode } from '../../common/common';
|
||||
import { EntityType } from '../../constants/Entity.interface';
|
||||
|
||||
import {
|
||||
BASE_URL,
|
||||
DELETE_ENTITY,
|
||||
GLOBAL_SETTING_PERMISSIONS,
|
||||
ID,
|
||||
uuid,
|
||||
} from '../../constants/constants';
|
||||
import { NAVBAR_DETAILS } from '../../constants/redirections.constants';
|
||||
const entity = new UsersTestClass();
|
||||
const expirationTime = {
|
||||
oneday: '1',
|
||||
sevendays: '7',
|
||||
onemonth: '30',
|
||||
twomonths: '60',
|
||||
threemonths: '90',
|
||||
};
|
||||
const name = `Usercttest${uuid()}`;
|
||||
const glossary = NAVBAR_DETAILS.glossary;
|
||||
const tag = NAVBAR_DETAILS.tags;
|
||||
const ownerName = 'Aaron Warren';
|
||||
const user = {
|
||||
name: name,
|
||||
email: `${name}@gmail.com`,
|
||||
password: `User@${uuid()}`,
|
||||
updatedDisplayName: `Edited${uuid()}`,
|
||||
newPassword: `NewUser@${uuid()}`,
|
||||
teamName: 'Applications',
|
||||
updatedDescription: 'This is updated description',
|
||||
newStewardPassword: `StewUser@${uuid()}`,
|
||||
};
|
||||
|
||||
describe('User with different Roles', () => {
|
||||
it('Update own admin details', () => {
|
||||
cy.login();
|
||||
updateDetails({
|
||||
...user,
|
||||
isAdmin: true,
|
||||
role: 'Admin',
|
||||
});
|
||||
});
|
||||
|
||||
it('Create Data Consumer User', () => {
|
||||
cy.login();
|
||||
visitUserListPage();
|
||||
addUser({ ...user, role: 'Data Consumer' });
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
it('Reset Data Consumer Password', () => {
|
||||
cy.login(user.email, user.password);
|
||||
|
||||
resetPassword(user.password, user.newPassword);
|
||||
cy.logout();
|
||||
|
||||
cy.login(user.email, user.newPassword);
|
||||
});
|
||||
|
||||
it('Token generation & revocation', () => {
|
||||
cy.login(user.email, user.newPassword);
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography', {
|
||||
timeout: 10000,
|
||||
}).click();
|
||||
cy.get('[data-testid="access-token"]').click();
|
||||
generateToken();
|
||||
revokeToken();
|
||||
});
|
||||
|
||||
it(`Update token expiration`, () => {
|
||||
cy.login(user.email, user.newPassword);
|
||||
visitUserListPage();
|
||||
Object.values(expirationTime).forEach((expiry) => {
|
||||
updateExpiration(expiry);
|
||||
});
|
||||
});
|
||||
|
||||
it('Data Consumer user should have only view permission for glossary and tags', () => {
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
cy.storeSession(user.email, user.newPassword);
|
||||
cy.goToHomePage();
|
||||
cy.url().should('eq', `${BASE_URL}/my-data`);
|
||||
|
||||
// Check CRUD for Glossary
|
||||
cy.get(glossary.testid)
|
||||
.should('be.visible')
|
||||
.click({ animationDistanceThreshold: 10 });
|
||||
if (glossary.subMenu) {
|
||||
cy.get(glossary.subMenu).should('be.visible').click({ force: true });
|
||||
}
|
||||
cy.clickOutside();
|
||||
|
||||
cy.clickOnLogo();
|
||||
|
||||
// Check CRUD for Tags
|
||||
cy.get(tag.testid)
|
||||
.should('be.visible')
|
||||
.click({ animationDistanceThreshold: 10 });
|
||||
if (tag.subMenu) {
|
||||
cy.get(tag.subMenu).should('be.visible').click({ force: true });
|
||||
}
|
||||
cy.get('body').click();
|
||||
cy.wait(200);
|
||||
cy.get('[data-testid="add-new-tag-button"]').should('not.exist');
|
||||
|
||||
cy.get('[data-testid="manage-button"]').should('not.exist');
|
||||
});
|
||||
|
||||
it('Data Consumer operations for settings page', () => {
|
||||
cy.storeSession(user.email, user.newPassword);
|
||||
cy.goToHomePage();
|
||||
cy.url().should('eq', `${BASE_URL}/my-data`);
|
||||
// Navigate to settings
|
||||
cy.get(NAVBAR_DETAILS.settings.testid).should('be.visible').click();
|
||||
Object.values(ID).forEach((id) => {
|
||||
if (id?.api) {
|
||||
interceptURL('GET', id.api, 'getTabDetails');
|
||||
}
|
||||
cy.get(id.testid).should('be.visible').click();
|
||||
if (id?.api) {
|
||||
verifyResponseStatusCode('@getTabDetails', 200);
|
||||
}
|
||||
cy.get(`[data-testid="${id.button}"]`).should('not.be.exist');
|
||||
});
|
||||
|
||||
Object.values(GLOBAL_SETTING_PERMISSIONS).forEach((id) => {
|
||||
if (id.testid === '[data-menu-id*="metadata"]') {
|
||||
cy.get(id.testid).should('be.visible').click();
|
||||
} else {
|
||||
cy.get(id.testid).should('not.be.exist');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Data Consumer permissions for table details page', () => {
|
||||
cy.login();
|
||||
visitEntityDetailsPage({
|
||||
term: DELETE_ENTITY.table.term,
|
||||
serviceName: DELETE_ENTITY.table.serviceName,
|
||||
entity: EntityType.Table,
|
||||
});
|
||||
addOwner(ownerName);
|
||||
cy.logout();
|
||||
cy.login(user.email, user.newPassword);
|
||||
visitEntityDetailsPage({
|
||||
term: DELETE_ENTITY.table.term,
|
||||
serviceName: DELETE_ENTITY.table.serviceName,
|
||||
entity: EntityType.Table,
|
||||
});
|
||||
entity.checkConsumerPermissions();
|
||||
});
|
||||
|
||||
it('Update Data Consumer details', () => {
|
||||
cy.login(user.email, user.newPassword);
|
||||
updateDetails({ ...user, isAdmin: false });
|
||||
});
|
||||
|
||||
it('Update Data Steward details', () => {
|
||||
// change role from consumer to steward
|
||||
cy.login();
|
||||
visitUserListPage();
|
||||
editRole(user.name, 'Data Steward');
|
||||
cy.logout();
|
||||
// login to steward user
|
||||
cy.login(user.email, user.newPassword);
|
||||
updateDetails({ ...user, isAdmin: false });
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
it('Reset Data Steward Password', () => {
|
||||
cy.login(user.email, user.newPassword);
|
||||
resetPassword(user.newPassword, user.newStewardPassword);
|
||||
cy.logout();
|
||||
cy.login(user.email, user.newStewardPassword);
|
||||
});
|
||||
|
||||
it('Token generation & revocation for Data Steward', () => {
|
||||
cy.login(user.email, user.newStewardPassword);
|
||||
visitUserListPage();
|
||||
cy.get('[data-testid="dropdown-profile"]').click({ force: true });
|
||||
cy.get('[data-testid="user-name"] > .ant-typography').click({
|
||||
force: true,
|
||||
});
|
||||
cy.get('[data-testid="access-token"] > .ant-space-item').click();
|
||||
generateToken();
|
||||
revokeToken();
|
||||
});
|
||||
|
||||
it(`Update token expiration for Data Steward`, () => {
|
||||
cy.login(user.email, user.newStewardPassword);
|
||||
visitUserListPage();
|
||||
Object.values(expirationTime).forEach((expiry) => {
|
||||
updateExpiration(expiry);
|
||||
});
|
||||
});
|
||||
|
||||
it('Data Steward operations for settings page', () => {
|
||||
cy.login(user.email, user.newStewardPassword);
|
||||
cy.url().should('eq', `${BASE_URL}/my-data`);
|
||||
// Navigate to settings
|
||||
cy.get(NAVBAR_DETAILS.settings.testid).should('be.visible').click();
|
||||
Object.values(ID).forEach((id) => {
|
||||
if (id?.api) {
|
||||
interceptURL('GET', id.api, 'getTabDetails');
|
||||
}
|
||||
cy.get(id.testid).should('be.visible').click();
|
||||
if (id?.api) {
|
||||
verifyResponseStatusCode('@getTabDetails', 200);
|
||||
}
|
||||
cy.get(`[data-testid="${id.button}"]`).should('not.be.exist');
|
||||
});
|
||||
|
||||
Object.values(GLOBAL_SETTING_PERMISSIONS).forEach((id) => {
|
||||
if (id.testid === '[data-menu-id*="metadata"]') {
|
||||
cy.get(id.testid).should('be.visible').click();
|
||||
} else {
|
||||
cy.get(id.testid).should('not.be.exist');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('Check Data Steward permissions', () => {
|
||||
cy.login(user.email, user.newStewardPassword);
|
||||
entity.checkStewardServicesPermissions();
|
||||
cy.goToHomePage();
|
||||
visitEntityDetailsPage({
|
||||
term: DELETE_ENTITY.table.term,
|
||||
serviceName: DELETE_ENTITY.table.serviceName,
|
||||
entity: EntityType.Table,
|
||||
});
|
||||
entity.checkStewardPermissions();
|
||||
cy.logout();
|
||||
});
|
||||
|
||||
it('Admin Soft delete user', () => {
|
||||
cy.login();
|
||||
visitUserListPage();
|
||||
entity.softDeleteUser(user.name);
|
||||
});
|
||||
|
||||
it('Admin Restore soft deleted user', () => {
|
||||
cy.login();
|
||||
visitUserListPage();
|
||||
entity.restoreSoftDeletedUser(user.name, user.updatedDisplayName);
|
||||
});
|
||||
|
||||
it('Admin Permanent Delete User', () => {
|
||||
cy.login();
|
||||
visitUserListPage();
|
||||
entity.permanentDeleteUser(user.name);
|
||||
});
|
||||
|
||||
it('Restore Admin Details', () => {
|
||||
cy.login();
|
||||
entity.restoreAdminDetails();
|
||||
cy.goToHomePage();
|
||||
visitEntityDetailsPage({
|
||||
term: DELETE_ENTITY.table.term,
|
||||
serviceName: DELETE_ENTITY.table.serviceName,
|
||||
entity: EntityType.Table,
|
||||
});
|
||||
removeOwner(ownerName);
|
||||
});
|
||||
});
|
||||
@ -130,10 +130,13 @@ Cypress.Commands.add('storeSession', (username, password) => {
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('login', () => {
|
||||
cy.storeSession(LOGIN.username, LOGIN.password);
|
||||
cy.goToHomePage();
|
||||
});
|
||||
Cypress.Commands.add(
|
||||
'login',
|
||||
(username = LOGIN.username, password = LOGIN.password) => {
|
||||
cy.storeSession(username, password);
|
||||
cy.goToHomePage();
|
||||
}
|
||||
);
|
||||
|
||||
Cypress.Commands.add('clickOutside', function () {
|
||||
return cy.get('body').click(0, 0); // 0,0 here are the x and y coordinates
|
||||
@ -149,4 +152,5 @@ Cypress.Commands.add('logout', () => {
|
||||
verifyResponseStatusCode('@logoutUser', 200);
|
||||
|
||||
cy.url().should('eq', `${BASE_URL}/signin`);
|
||||
Cypress.session.clearAllSavedSessions();
|
||||
});
|
||||
|
||||
@ -20,7 +20,11 @@ declare global {
|
||||
* Custom command to select DOM element by data-cy attribute.
|
||||
* @example cy.login()
|
||||
*/
|
||||
login(): void;
|
||||
login(email?: string, password?: string): void;
|
||||
logout(): void;
|
||||
goToHomePage(doNotNavigate: boolean): void;
|
||||
clickOnLogo(): void;
|
||||
clickOutside(): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ export const delimiterRegex = /[\\[\]\\()\\;\\,\\|\\{}\\``\\/\\<>\\^]/g;
|
||||
export const nameWithSpace = /\s/g;
|
||||
|
||||
export const passwordRegex =
|
||||
/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,16}$/g;
|
||||
/^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,56}$/g;
|
||||
|
||||
export const allowedNameRegEx = /[`!@#$%^&*()+=[\]{};:"\\|,.<>/?~]/;
|
||||
|
||||
|
||||
@ -324,9 +324,7 @@ const UserListPageV1 = () => {
|
||||
disabled={!isAdminUser}
|
||||
icon={
|
||||
<IconDelete
|
||||
data-testid={`delete-user-btn-${
|
||||
record.displayName || record.name
|
||||
}`}
|
||||
data-testid={`delete-user-btn-${record.name}`}
|
||||
name={t('label.delete')}
|
||||
width="16px"
|
||||
/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user