diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index f2907a9e..59484c6b 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -107,7 +107,7 @@ jobs:
strategy:
fail-fast: false
matrix:
- specs: ['actions_tasks', 'actions_tasks2', 'actions_tasks3', 'actions_objects', 'actions_objects2', 'actions_users', 'actions_projects_models', 'canvas3d_functionality', 'canvas3d_functionality_2', 'issues_prs', 'issues_prs2']
+ specs: ['actions_tasks', 'actions_tasks2', 'actions_tasks3', 'actions_objects', 'actions_objects2', 'actions_users', 'actions_projects_models', 'actions_organizations', 'canvas3d_functionality', 'canvas3d_functionality_2', 'issues_prs', 'issues_prs2']
steps:
- uses: actions/checkout@v2
- name: Getting SHA from the default branch
@@ -193,16 +193,16 @@ jobs:
npm ci
if [[ ${{ github.ref }} == 'refs/heads/develop' ]]; then
if [ ${{ matrix.specs }} == 'canvas3d_functionality' ] || [ ${{ matrix.specs }} == 'canvas3d_functionality_2' ]; then
- npx cypress run --headed --browser chrome --config-file cypress_canvas3d.json --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects.js'
+ npx cypress run --headed --browser chrome --config-file cypress_canvas3d.json --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects_organizations.js'
else
- npx cypress run --browser chrome --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects.js'
+ npx cypress run --browser chrome --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects_organizations.js'
fi
mv ./.nyc_output/out.json ./.nyc_output/out_${{ matrix.specs }}.json
else
if [ ${{ matrix.specs }} == 'canvas3d_functionality' ] || [ ${{ matrix.specs }} == 'canvas3d_functionality_2' ]; then
- npx cypress run --headed --browser chrome --env coverage=false --config-file cypress_canvas3d.json --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects.js'
+ npx cypress run --headed --browser chrome --env coverage=false --config-file cypress_canvas3d.json --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects_organizations.js'
else
- npx cypress run --browser chrome --env coverage=false --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects.js'
+ npx cypress run --browser chrome --env coverage=false --spec 'cypress/integration/${{ matrix.specs }}/**/*.js,cypress/integration/remove_users_tasks_projects_organizations.js'
fi
fi
- name: Creating a log file from "cvat" container logs
diff --git a/cvat-ui/src/components/header/header.tsx b/cvat-ui/src/components/header/header.tsx
index c54732af..6b9722e2 100644
--- a/cvat-ui/src/components/header/header.tsx
+++ b/cvat-ui/src/components/header/header.tsx
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -266,11 +266,11 @@ function HeaderContainer(props: Props): JSX.Element {
icon={organizationsFetching ? : }
>
{currentOrganization ? (
-
} key='open_organization' onClick={() => history.push('/organization')}>
+ } key='open_organization' onClick={() => history.push('/organization')} className='cvat-header-menu-open-organization'>
Settings
) : null}
- } key='create_organization' onClick={() => history.push('/organizations/create')}>Create
+ } key='create_organization' onClick={() => history.push('/organizations/create')} className='cvat-header-menu-create-organization'>Create
{ organizationsList.length > 5 ? (
@@ -324,7 +325,7 @@ function HeaderContainer(props: Props): JSX.Element {
{organizationsList.map((organization: any): JSX.Element => (
setNewOrganization(organization)}
>
@@ -475,13 +476,15 @@ function HeaderContainer(props: Props): JSX.Element {
-
+
{user.username.length > 14 ? `${user.username.slice(0, 10)} ...` : user.username}
{ currentOrganization ? (
- {currentOrganization.slug}
+
+ {currentOrganization.slug}
+
) : null }
diff --git a/cvat-ui/src/components/organization-page/member-item.tsx b/cvat-ui/src/components/organization-page/member-item.tsx
index 1fcc3178..ff00d83c 100644
--- a/cvat-ui/src/components/organization-page/member-item.tsx
+++ b/cvat-ui/src/components/organization-page/member-item.tsx
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Intel Corporation
+// Copyright (C) 2021-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -65,6 +65,7 @@ function MemberItem(props: Props): JSX.Element {
{
Modal.confirm({
+ className: 'cvat-modal-organization-member-remove',
title: `You are removing "${username}" from this organization`,
content: 'The person will not have access to the organization data anymore. Continue?',
okText: 'Yes, remove',
diff --git a/cvat-ui/src/components/organization-page/top-bar.tsx b/cvat-ui/src/components/organization-page/top-bar.tsx
index 8b050426..ab40483f 100644
--- a/cvat-ui/src/components/organization-page/top-bar.tsx
+++ b/cvat-ui/src/components/organization-page/top-bar.tsx
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Intel Corporation
+// Copyright (C) 2021-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -194,6 +194,7 @@ function OrganizationTopBar(props: Props): JSX.Element {
onOk: () => {
dispatch(leaveOrganizationAsync(organizationInstance));
},
+ className: 'cvat-modal-organization-leave-confirm',
content: (
<>
Please, confirm leaving the organization
@@ -260,6 +261,7 @@ function OrganizationTopBar(props: Props): JSX.Element {
{
setVisibleInviteModal(false);
@@ -294,6 +296,7 @@ function OrganizationTopBar(props: Props): JSX.Element {
+
+context('New organization pipeline.', () => {
+ const caseId = '113';
+ const firstUserName = 'Firstuser';
+ const secondUserName = 'Seconduser';
+ const thirdUserName = 'Thirduser';
+
+ const firstUser = {
+ firstName: `${firstUserName} fitstname`,
+ lastName: `${firstUserName} lastname`,
+ emailAddr: `${firstUserName.toLowerCase()}@local.local`,
+ password: 'UfdU21!dds',
+ };
+ const secondUser = {
+ firstName: `${secondUserName} fitstname`,
+ lastName: `${secondUserName} lastname`,
+ emailAddr: `${secondUserName.toLowerCase()}@local.local`,
+ password: 'UfdU21!dds',
+ };
+ const thirdUser = {
+ firstName: `${thirdUserName} fitstname`,
+ lastName: `${thirdUserName} lastname`,
+ emailAddr: `${thirdUserName.toLowerCase()}@local.local`,
+ password: 'Fv5Df3#f55g',
+ };
+ const organizationParams = {
+ shortName: 'TestOrganization',
+ fullName: 'Organization full name. Only for test.',
+ description: 'This organization was created to test the functionality.',
+ email: 'testorganization@local.local',
+ phoneNumber: '+70000000000',
+ location: 'Country, State, Address, 000000',
+ };
+ const project = {
+ name: `Project case ${caseId}`,
+ label: 'car',
+ attrName: 'color',
+ attrVaue: 'red',
+ multiAttrParams: false,
+ };
+
+ const labelName = `Case ${caseId}`;
+ const taskName = `New annotation task for ${labelName}`;
+ const newTaskName = labelName;
+ const attrName = `Attr for ${labelName}`;
+ const textDefaultValue = 'Some default value for type Text';
+ const imagesCount = 1;
+ const imageFileName = `image_${labelName.replace(' ', '_').toLowerCase()}`;
+ const width = 800;
+ const height = 800;
+ const posX = 10;
+ const posY = 10;
+ const color = 'gray';
+ const archiveName = `${imageFileName}.zip`;
+ const archivePath = `cypress/fixtures/${archiveName}`;
+ const imagesFolder = `cypress/fixtures/${imageFileName}`;
+ const directoryToArchive = imagesFolder;
+ let taskID;
+ let jobID;
+
+ const createCuboidShape2Points = {
+ points: 'From rectangle',
+ type: 'Shape',
+ labelName,
+ firstX: 250,
+ firstY: 350,
+ secondX: 350,
+ secondY: 450,
+ };
+
+ function capitalizeEmail(email) {
+ return email.split('@').map((part) => `${part.toUpperCase()[0]}${part.slice(1)}`).join('@');
+ }
+
+ before(() => {
+ cy.imageGenerator(
+ imagesFolder,
+ imageFileName,
+ width,
+ height,
+ color,
+ posX,
+ posY,
+ project.label,
+ imagesCount,
+ );
+ cy.createZipArchive(directoryToArchive, archivePath);
+
+ cy.visit('/');
+ cy.goToRegisterPage();
+ cy.userRegistration(
+ secondUser.firstName,
+ secondUser.lastName,
+ secondUserName,
+ secondUser.emailAddr,
+ secondUser.password,
+ );
+ cy.logout(secondUserName);
+
+ cy.goToRegisterPage();
+ cy.userRegistration(
+ thirdUser.firstName,
+ thirdUser.lastName,
+ thirdUserName,
+ thirdUser.emailAddr,
+ thirdUser.password,
+ );
+ cy.logout(thirdUserName);
+
+ cy.goToRegisterPage();
+ cy.userRegistration(
+ firstUser.firstName,
+ firstUser.lastName,
+ firstUserName,
+ firstUser.emailAddr,
+ firstUser.password,
+ );
+ });
+
+ beforeEach(() => {
+ Cypress.Cookies.preserveOnce('sessionid', 'csrftoken');
+ });
+
+ after(() => {
+ cy.logout(thirdUserName);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [thirdUserName]);
+ cy.deleteTasks(authKey, [newTaskName]);
+ cy.deleteProjects(authKey, [project.name]);
+ cy.deleteOrganizations(authKey, [organizationParams.shortName]);
+ });
+ });
+
+ describe(`Testing case "${caseId}"`, () => {
+ it('The first user creates an organization and activates it.', () => {
+ cy.createOrganization(organizationParams);
+ cy.activateOrganization(organizationParams.shortName);
+ });
+
+ it('Open the organization settings. Invite members.', () => {
+ cy.openOrganization(organizationParams.shortName);
+ cy.checkOrganizationParams(organizationParams);
+ cy.checkOrganizationMembers(1, [firstUserName]);
+ const membersToInvite = [
+ {
+ email: capitalizeEmail(secondUser.emailAddr),
+ role: 'Worker',
+ },
+ {
+ email: thirdUser.emailAddr,
+ role: 'Worker',
+ },
+ ];
+ cy.inviteMembersToOrganization(membersToInvite);
+ cy.checkOrganizationMembers(3, [firstUserName, secondUserName, thirdUserName]);
+ });
+
+ it('Create a project, create a task. Deactivate organization.', () => {
+ cy.goToProjectsList();
+ cy.createProjects(
+ project.name,
+ project.label,
+ project.attrName,
+ project.attrVaue,
+ project.multiAttrParams,
+ );
+ cy.goToTaskList();
+ cy.createAnnotationTask(taskName, labelName, attrName, textDefaultValue, archiveName);
+ cy.openTask(taskName);
+ cy.assignTaskToUser(secondUserName);
+ cy.deactivateOrganization();
+ });
+
+ it('The project, the task are invisible now.', () => {
+ cy.contains('.cvat-item-task-name', taskName).should('not.exist');
+ cy.goToProjectsList();
+ cy.contains('.cvat-projects-project-item-title', project.name).should('not.exist');
+ });
+
+ it('Admin tries to leave from organization (not successfully because he is not a member of it).', () => {
+ cy.logout(firstUserName);
+ cy.login();
+ cy.activateOrganization(organizationParams.shortName);
+ cy.openOrganization(organizationParams.shortName);
+ cy.contains('button', 'Leave organization').should('be.visible').click();
+ cy.get('.cvat-modal-organization-leave-confirm')
+ .should('be.visible')
+ .within(() => {
+ cy.contains('button', 'Leave').click();
+ });
+ cy.get('.cvat-notification-notice-leave-organization-failed').should('exist');
+ cy.closeNotification('.cvat-notification-notice-leave-organization-failed');
+ });
+
+ it('The second user login. The user is able to see the organization, can\'t see the task.', () => {
+ cy.logout();
+ cy.login(secondUserName, secondUser.password);
+ cy.checkOrganizationExists(organizationParams.shortName);
+ cy.contains('.cvat-item-task-name', taskName).should('not.exist');
+ });
+
+ it('The second user activates the organization, can\'t see the project because it is not assigned to him.', () => {
+ cy.activateOrganization(organizationParams.shortName);
+ cy.goToProjectsList();
+ cy.contains('.cvat-projects-project-item-title', project.name).should('not.exist');
+ });
+
+ it('The first user login. Assigne the project to the second user.', () => {
+ cy.logout(secondUserName);
+ cy.login(firstUserName, firstUser.password);
+ cy.activateOrganization(organizationParams.shortName);
+ cy.goToProjectsList();
+ cy.openProject(project.name);
+ cy.assignProjectToUser(secondUserName);
+ });
+
+ it('The second user login. Now he sees the project and can open it.', () => {
+ cy.logout(firstUserName);
+ cy.login(secondUserName, secondUser.password);
+ cy.activateOrganization(organizationParams.shortName);
+ cy.goToProjectsList();
+ cy.openProject(project.name);
+ });
+
+ it('Open the task, assign one of jobs to the third user. Rename the task.', () => {
+ cy.goToTaskList();
+ cy.openTask(taskName);
+ cy.assignJobToUser(0, thirdUserName);
+ cy.renameTask(taskName, newTaskName);
+ cy.url().then((url) => {
+ taskID = Number(url.split('/').slice(-1)[0]);
+ });
+ cy.getJobNum(0).then(($jobID) => {
+ jobID = $jobID;
+ });
+ });
+
+ it('Logout, the third user login. The user does not see the project, the task. The user can\'t open the job using direct link.', () => {
+ cy.logout(secondUserName);
+ cy.login(thirdUserName, thirdUser.password);
+ cy.contains('.cvat-item-task-name', taskName).should('not.exist');
+ cy.goToProjectsList();
+ cy.contains('.cvat-projects-project-item-title', project.name).should('not.exist');
+ cy.visit(`/tasks/${taskID}/jobs/${jobID}`);
+ cy.get('.cvat-canvas-container').should('not.exist');
+ cy.get('.cvat-notification-notice-fetch-job-failed').should('be.visible');
+ cy.closeNotification('.cvat-notification-notice-fetch-job-failed');
+ });
+
+ it('The third user activates the organization. Now can open the job using direct link. Create an object, save annotations.', () => {
+ cy.activateOrganization(organizationParams.shortName);
+ cy.visit(`/tasks/${taskID}/jobs/${jobID}`);
+ cy.get('.cvat-canvas-container').should('exist');
+ cy.createCuboid(createCuboidShape2Points);
+ cy.saveJob();
+ });
+
+ it('The owner of the organization removes the second user from it.', () => {
+ cy.logout(thirdUserName);
+ cy.login(firstUserName, firstUser.password);
+ cy.activateOrganization(organizationParams.shortName);
+ cy.openOrganization(organizationParams.shortName);
+ cy.removeMemberFromOrganization(secondUserName);
+ cy.checkOrganizationMembers(2, [firstUserName, thirdUserName]);
+ });
+
+ it('The organization, project, task is no longer available to the second user.', () => {
+ cy.logout(firstUserName);
+ cy.login(secondUserName, secondUser.password);
+ cy.checkOrganizationExists(organizationParams.shortName, false);
+ cy.contains('.cvat-item-task-name', taskName).should('not.exist');
+ cy.goToProjectsList();
+ cy.contains('.cvat-projects-project-item-title', project.name).should('not.exist');
+ });
+
+ it('Logout. Remove the first, the second user (deletion occurs from user admin).', () => {
+ cy.logout(secondUserName);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [firstUserName, secondUserName]);
+ });
+ });
+
+ it('Login as the third user. The organization page can be opened. The job can be opened.', () => {
+ cy.login(thirdUserName, thirdUser.password);
+ cy.activateOrganization(organizationParams.shortName);
+ cy.visit('/organization');
+ cy.checkOrganizationParams(organizationParams);
+ cy.checkOrganizationMembers(1, [thirdUserName]);
+ cy.visit(`/tasks/${taskID}/jobs/${jobID}`);
+ cy.get('.cvat-canvas-container').should('exist');
+ cy.get('.cvat_canvas_shape_cuboid').should('be.visible');
+ });
+ });
+});
diff --git a/tests/cypress/integration/actions_projects_models/registration_involved/base_actions_project_task_user.js b/tests/cypress/integration/actions_projects_models/registration_involved/base_actions_project_task_user.js
index d669b395..9b46a40b 100644
--- a/tests/cypress/integration/actions_projects_models/registration_involved/base_actions_project_task_user.js
+++ b/tests/cypress/integration/actions_projects_models/registration_involved/base_actions_project_task_user.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -58,7 +58,9 @@ context('Base actions on the project', () => {
});
after(() => {
- cy.deletingRegisteredUsers([userName]);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [userName]);
+ });
});
describe('Testing "Base actions on the project"', () => {
diff --git a/tests/cypress/integration/actions_tasks/registration_involved/case_39_issue_2572_rename_task.js b/tests/cypress/integration/actions_tasks/registration_involved/case_39_issue_2572_rename_task.js
index b9fd4dee..6a52c1e2 100644
--- a/tests/cypress/integration/actions_tasks/registration_involved/case_39_issue_2572_rename_task.js
+++ b/tests/cypress/integration/actions_tasks/registration_involved/case_39_issue_2572_rename_task.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Intel Corporation
+// Copyright (C) 2021-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -56,9 +56,11 @@ context('Rename a task.', () => {
});
after(() => {
- cy.deletingRegisteredUsers([secondUserName]);
- cy.login();
- cy.deleteTask(newTaskNameSecondUser);
+ cy.logout(secondUserName);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [secondUserName]);
+ cy.deleteTasks(authKey, [newTaskNameSecondUser]);
+ });
});
describe(`Testing "${labelName}". Issue 2572.`, () => {
@@ -72,9 +74,7 @@ context('Rename a task.', () => {
it('The second user tries to rename the task. Success.', () => {
cy.login(secondUserName, secondUser.password);
cy.openTask(newTaskName);
- renameTask(newTaskName, '{leftarrow}{leftarrow}3{Enter}');
- cy.contains('.cvat-task-details-task-name', newTaskNameSecondUser).should('exist');
- cy.logout(secondUserName);
+ cy.renameTask(newTaskName, newTaskNameSecondUser);
});
});
});
diff --git a/tests/cypress/integration/actions_tasks/registration_involved/case_69_filters_sorting_jobs.js b/tests/cypress/integration/actions_tasks/registration_involved/case_69_filters_sorting_jobs.js
index 2424f13c..ee8e2fdb 100644
--- a/tests/cypress/integration/actions_tasks/registration_involved/case_69_filters_sorting_jobs.js
+++ b/tests/cypress/integration/actions_tasks/registration_involved/case_69_filters_sorting_jobs.js
@@ -121,9 +121,10 @@ context('Filtering, sorting jobs.', () => {
after(() => {
cy.logout();
- cy.deletingRegisteredUsers([secondUserName]);
- cy.login();
- cy.deleteTask(taskName);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [secondUserName]);
+ cy.deleteTasks(authKey, [taskName]);
+ });
});
describe(`Testing "${labelName}".`, () => {
diff --git a/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js b/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js
index d53f7917..ca134e26 100644
--- a/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js
+++ b/tests/cypress/integration/actions_users/registration_involved/case_28_review_pipeline_feature.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -137,11 +137,11 @@ context('Review pipeline feature', () => {
});
after(() => {
- cy.login();
- cy.goToTaskList();
- cy.deleteTask(taskName);
cy.logout();
- cy.deletingRegisteredUsers([secondUserName, thirdUserName]);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [secondUserName, thirdUserName]);
+ cy.deleteTasks(authKey, [taskName]);
+ });
});
describe(`Testing "${labelName}"`, () => {
@@ -193,7 +193,6 @@ context('Review pipeline feature', () => {
cy.login();
cy.openTask(taskName);
cy.assignJobToUser(0, secondUserName);
- cy.logout();
});
/* FIXME: Second user has access to a job inside the task. Need to redesign openTaskJob.
diff --git a/tests/cypress/integration/actions_users/registration_involved/case_2_register_user_change_pass.js b/tests/cypress/integration/actions_users/registration_involved/case_2_register_user_change_pass.js
index 75b1f2c5..c78d5baf 100644
--- a/tests/cypress/integration/actions_users/registration_involved/case_2_register_user_change_pass.js
+++ b/tests/cypress/integration/actions_users/registration_involved/case_2_register_user_change_pass.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -37,7 +37,9 @@ context('Register user, change password, login with new password', () => {
after(() => {
cy.get('.cvat-modal-change-password').find('[aria-label="Close"]').click();
cy.logout(userName);
- cy.deletingRegisteredUsers([userName]);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [userName]);
+ });
});
describe(`Testing "Case ${caseId}"`, () => {
diff --git a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js
index 4c1a48a2..82d9e7ae 100644
--- a/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js
+++ b/tests/cypress/integration/actions_users/registration_involved/case_4_assign_taks_job_users.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -61,11 +61,11 @@ context('Multiple users. Assign task, job. Deactivating users.', () => {
});
after(() => {
- cy.goToTaskList();
- cy.deleteTask(taskName);
- cy.deleteTask(secondTaskName);
cy.logout();
- cy.deletingRegisteredUsers([secondUserName, thirdUserName]);
+ cy.getAuthKey().then(($authKey) => {
+ cy.deleteUsers($authKey, [secondUserName, thirdUserName]);
+ cy.deleteTasks($authKey, [taskName, secondTaskName]);
+ });
});
describe(`Testing case "${caseId}"`, () => {
diff --git a/tests/cypress/integration/actions_users/registration_involved/issue_1599_ch_user_registration.js b/tests/cypress/integration/actions_users/registration_involved/issue_1599_ch_user_registration.js
index 37842cee..4cf06d98 100644
--- a/tests/cypress/integration/actions_users/registration_involved/issue_1599_ch_user_registration.js
+++ b/tests/cypress/integration/actions_users/registration_involved/issue_1599_ch_user_registration.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -18,7 +18,9 @@ context('Issue 1599 (Chinese alphabet).', () => {
after(() => {
cy.logout(userName);
- cy.deletingRegisteredUsers([userName]);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [userName]);
+ });
});
describe('User registration using the Chinese alphabet.', () => {
diff --git a/tests/cypress/integration/actions_users/registration_involved/issue_1599_pl_user_registration.js b/tests/cypress/integration/actions_users/registration_involved/issue_1599_pl_user_registration.js
index e0605bf9..3abbdfb7 100644
--- a/tests/cypress/integration/actions_users/registration_involved/issue_1599_pl_user_registration.js
+++ b/tests/cypress/integration/actions_users/registration_involved/issue_1599_pl_user_registration.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -18,7 +18,9 @@ context('Issue 1599 (Polish alphabet).', () => {
after(() => {
cy.logout(userName);
- cy.deletingRegisteredUsers([userName]);
+ cy.getAuthKey().then((authKey) => {
+ cy.deleteUsers(authKey, [userName]);
+ });
});
describe('User registration using the Polish alphabet.', () => {
diff --git a/tests/cypress/integration/remove_users_tasks_projects.js b/tests/cypress/integration/remove_users_tasks_projects_organizations.js
similarity index 52%
rename from tests/cypress/integration/remove_users_tasks_projects.js
rename to tests/cypress/integration/remove_users_tasks_projects_organizations.js
index 87c47092..913b0e53 100644
--- a/tests/cypress/integration/remove_users_tasks_projects.js
+++ b/tests/cypress/integration/remove_users_tasks_projects_organizations.js
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2021 Intel Corporation
+// Copyright (C) 2020-2022 Intel Corporation
//
// SPDX-License-Identifier: MIT
@@ -6,7 +6,7 @@
let authKey = '';
-describe('Delete users and tasks created during the test run.', () => {
+describe('Delete users, tasks, projects, organizations created during the tests run.', () => {
it('Get token', () => {
cy.request({
method: 'POST',
@@ -16,45 +16,45 @@ describe('Delete users and tasks created during the test run.', () => {
email: Cypress.env('email'),
password: Cypress.env('password'),
},
- }).then(async (response) => {
- authKey = await response['body']['key'];
+ }).then((response) => {
+ authKey = response.body.key;
});
});
- it('Get a list of users and delete all except id:1', () => {
+
+ it('Get a list of tasks and delete them all', () => {
cy.request({
- url: '/api/v1/users',
+ url: '/api/v1/tasks?page_size=1000',
headers: {
Authorization: `Token ${authKey}`,
},
- }).then(async (response) => {
- const responceResult = await response['body']['results'];
- for (let user of responceResult) {
- let userId = user['id'];
- if (userId !== 1) {
- cy.request({
- method: 'DELETE',
- url: `/api/v1/users/${userId}`,
- headers: {
- Authorization: `Token ${authKey}`,
- },
- });
- }
+ }).then((response) => {
+ const responseResult = response.body.results;
+ for (const task of responseResult) {
+ const { id } = task;
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/tasks/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
}
});
});
- it('Get a list of tasks and delete them all', () => {
+
+ it('Get a list of projects and delete them all', () => {
cy.request({
- url: '/api/v1/tasks?page_size=1000',
+ url: '/api/v1/projects?page_size=all',
headers: {
Authorization: `Token ${authKey}`,
},
- }).then(async (response) => {
- const responceResult = await response['body']['results'];
- for (let tasks of responceResult) {
- let taskId = tasks['id'];
+ }).then((response) => {
+ const responseResult = response.body.results;
+ for (const project of responseResult) {
+ const { id } = project;
cy.request({
method: 'DELETE',
- url: `/api/v1/tasks/${taskId}`,
+ url: `/api/v1/projects/${id}`,
headers: {
Authorization: `Token ${authKey}`,
},
@@ -62,19 +62,20 @@ describe('Delete users and tasks created during the test run.', () => {
}
});
});
- it('Get a list of projects and delete them all', () => {
+
+ it('Get a list of organizations and delete them all', () => {
cy.request({
- url: '/api/v1/projects?page_size=all',
+ url: '/api/v1/organizations?page_size=all',
headers: {
Authorization: `Token ${authKey}`,
},
- }).then(async (response) => {
- const responceResult = await response['body']['results'];
- for (let tasks of responceResult) {
- let taskId = tasks['id'];
+ }).then((response) => {
+ const responseResult = response.body;
+ for (const org of responseResult) {
+ const { id } = org;
cy.request({
method: 'DELETE',
- url: `/api/v1/projects/${taskId}`,
+ url: `/api/v1/organizations/${id}`,
headers: {
Authorization: `Token ${authKey}`,
},
@@ -82,4 +83,27 @@ describe('Delete users and tasks created during the test run.', () => {
}
});
});
+
+ it('Get a list of users and delete all except id:1', () => {
+ cy.request({
+ url: '/api/v1/users',
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ }).then((response) => {
+ const responseResult = response.body.results;
+ for (const user of responseResult) {
+ const { id } = user;
+ if (id !== 1) {
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/users/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
+ }
+ }
+ });
+ });
});
diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js
index c701d198..82ce94ce 100644
--- a/tests/cypress/support/commands.js
+++ b/tests/cypress/support/commands.js
@@ -16,11 +16,11 @@ require('cy-verify-downloads').addCustomCommand();
let selectedValueGlobal = '';
-Cypress.Commands.add('login', (username = Cypress.env('user'), password = Cypress.env('password')) => {
+Cypress.Commands.add('login', (username = Cypress.env('user'), password = Cypress.env('password'), page = 'tasks') => {
cy.get('[placeholder="Username"]').type(username);
cy.get('[placeholder="Password"]').type(password);
cy.get('[type="submit"]').click();
- cy.url().should('match', /\/tasks$/);
+ cy.url().should('contain', `/${page}`);
cy.document().then((doc) => {
const loadSettingFailNotice = Array.from(doc.querySelectorAll('.cvat-notification-notice-load-settings-fail'));
if (loadSettingFailNotice.length > 0) {
@@ -31,7 +31,7 @@ Cypress.Commands.add('login', (username = Cypress.env('user'), password = Cypres
Cypress.Commands.add('logout', (username = Cypress.env('user')) => {
cy.get('.cvat-right-header').within(() => {
- cy.get('.cvat-header-menu-user-dropdown').should('have.text', username).trigger('mouseover', { which: 1 });
+ cy.get('.cvat-header-menu-user-dropdown-user').should('have.text', username).trigger('mouseover');
});
cy.get('span[aria-label="logout"]').click();
cy.url().should('include', '/auth/login');
@@ -52,7 +52,7 @@ Cypress.Commands.add('userRegistration', (firstName, lastName, userName, emailAd
}
});
-Cypress.Commands.add('deletingRegisteredUsers', (accountToDelete) => {
+Cypress.Commands.add('getAuthKey', () => {
cy.request({
method: 'POST',
url: '/api/v1/auth/login',
@@ -61,31 +61,32 @@ Cypress.Commands.add('deletingRegisteredUsers', (accountToDelete) => {
email: Cypress.env('email'),
password: Cypress.env('password'),
},
- }).then((response) => {
- const authKey = response.body.key;
- cy.request({
- url: '/api/v1/users?page_size=all',
- headers: {
- Authorization: `Token ${authKey}`,
- },
- }).then((_response) => {
- const responceResult = _response.body.results;
- for (const user of responceResult) {
- const userId = user.id;
- const userName = user.username;
- for (const account of accountToDelete) {
- if (userName === account) {
- cy.request({
- method: 'DELETE',
- url: `/api/v1/users/${userId}`,
- headers: {
- Authorization: `Token ${authKey}`,
- },
- });
- }
+ });
+});
+
+Cypress.Commands.add('deleteUsers', (authResponse, accountsToDelete) => {
+ const authKey = authResponse.body.key;
+ cy.request({
+ url: '/api/v1/users?page_size=all',
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ }).then((_response) => {
+ const responseResult = _response.body.results;
+ for (const user of responseResult) {
+ const { id, username } = user;
+ for (const account of accountsToDelete) {
+ if (username === account) {
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/users/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
}
}
- });
+ }
});
});
@@ -134,6 +135,32 @@ Cypress.Commands.add('checkUserStatuses', (authKey, userName, staffStatus, super
});
});
+Cypress.Commands.add('deleteTasks', (authResponse, tasksToDelete) => {
+ const authKey = authResponse.body.key;
+ cy.request({
+ url: '/api/v1/tasks?page_size=all',
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ }).then((_response) => {
+ const responceResult = _response.body.results;
+ for (const task of responceResult) {
+ const { id, name } = task;
+ for (const taskToDelete of tasksToDelete) {
+ if (name === taskToDelete) {
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/tasks/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
+ }
+ }
+ }
+ });
+});
+
Cypress.Commands.add(
'createAnnotationTask',
(
@@ -802,6 +829,14 @@ Cypress.Commands.add('exportTask', ({
cy.closeNotification('.cvat-notification-notice-export-task-start');
});
+Cypress.Commands.add('renameTask', (oldName, newName) => {
+ cy.get('.cvat-task-details-task-name').within(() => {
+ cy.get('[aria-label="edit"]').click();
+ });
+ cy.contains('.cvat-text-color', oldName).clear().type(`${newName}{Enter}`);
+ cy.contains('.cvat-task-details-task-name', newName).should('exist');
+});
+
Cypress.Commands.add('shapeRotate', (shape, x, y, expectedRotateDeg, pressShift = false) => {
cy.get(shape)
.trigger('mousemove')
diff --git a/tests/cypress/support/commands_organizations.js b/tests/cypress/support/commands_organizations.js
new file mode 100644
index 00000000..e3df85c4
--- /dev/null
+++ b/tests/cypress/support/commands_organizations.js
@@ -0,0 +1,183 @@
+// Copyright (C) 2022 Intel Corporation
+//
+// SPDX-License-Identifier: MIT
+
+///
+
+Cypress.Commands.add('createOrganization', (organizationParams) => {
+ cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover');
+ cy.get('.cvat-header-menu')
+ .should('be.visible')
+ .find('[role="menuitem"]')
+ .filter(':contains("Organization")')
+ .trigger('mouseover');
+ cy.get('.cvat-header-menu-create-organization')
+ .should('be.visible')
+ .click();
+ cy.url().should('contain', '/organizations/create');
+ cy.get('.cvat-create-organization-form').should('be.visible').within(() => {
+ cy.get('#slug').type(organizationParams.shortName);
+ cy.get('#name').type(organizationParams.fullName);
+ cy.get('#description').type(organizationParams.description);
+ cy.get('#email').type(organizationParams.email);
+ cy.get('#phoneNumber').type(organizationParams.phoneNumber);
+ cy.get('#location').type(organizationParams.location);
+ cy.intercept('POST', '/api/v1/organizations**').as('createOrganizations');
+ cy.get('[type="submit"]').click();
+ cy.wait('@createOrganizations').its('response.statusCode').should('equal', 201);
+ });
+});
+
+Cypress.Commands.add('deleteOrganizations', (authResponse, otrganizationsToDelete) => {
+ const authKey = authResponse.body.key;
+ cy.request({
+ url: '/api/v1/organizations?page_size=all',
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ }).then((_response) => {
+ const responceResult = _response.body;
+ for (const organization of responceResult) {
+ const { id, slug } = organization;
+ for (const organizationToDelete of otrganizationsToDelete) {
+ if (slug === organizationToDelete) {
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/organizations/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
+ }
+ }
+ }
+ });
+});
+
+Cypress.Commands.add('activateOrganization', (organizationShortName) => {
+ cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover');
+ cy.get('.ant-dropdown')
+ .should('be.visible')
+ .not('ant-dropdown-hidden')
+ .find('[role="menuitem"]')
+ .filter(':contains("Organization")')
+ .trigger('mouseover');
+ cy.contains('.cvat-header-menu-organization-item', organizationShortName).click();
+ cy.get('.cvat-header-menu-user-dropdown').should('be.visible');
+ cy.get('.cvat-header-menu-user-dropdown-organization')
+ .should('exist')
+ .and('have.text', organizationShortName);
+});
+
+Cypress.Commands.add('deactivateOrganization', () => {
+ cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover');
+ cy.get('.ant-dropdown')
+ .should('be.visible')
+ .not('ant-dropdown-hidden')
+ .find('[role="menuitem"]')
+ .filter(':contains("Organization")')
+ .trigger('mouseover');
+ cy.contains('.cvat-header-menu-organization-item', 'Personal workspace').click();
+ cy.get('.cvat-header-menu-user-dropdown').should('be.visible');
+ cy.get('.cvat-header-menu-user-dropdown-organization').should('not.exist');
+});
+
+Cypress.Commands.add('openOrganization', (organizationShortName) => {
+ cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover');
+ cy.get('.ant-dropdown')
+ .should('be.visible')
+ .not('ant-dropdown-hidden')
+ .find('[role="menuitem"]')
+ .filter(':contains("Organization")')
+ .trigger('mouseover');
+ cy.get('.cvat-header-menu-active-organization-item')
+ .should('have.text', organizationShortName);
+ cy.get('.cvat-header-menu-open-organization')
+ .should('be.visible')
+ .click();
+ cy.get('.cvat-organization-page').should('exist').and('be.visible');
+});
+
+Cypress.Commands.add('checkOrganizationExists', (organizationShortName, shouldExist = true) => {
+ cy.get('.cvat-header-menu-user-dropdown').trigger('mouseover');
+ cy.get('.ant-dropdown')
+ .should('be.visible')
+ .not('ant-dropdown-hidden')
+ .find('[role="menuitem"]')
+ .filter(':contains("Organization")')
+ .trigger('mouseover');
+ if (shouldExist) {
+ cy.contains('.cvat-header-menu-organization-item', organizationShortName)
+ .should('exist')
+ .trigger('mouseout')
+ .should('be.hidden');
+ } else {
+ cy.contains('.cvat-header-menu-organization-item', organizationShortName).should('not.exist');
+ cy.get('.cvat-header-menu-active-organization-item').trigger('mouseout').should('be.hidden');
+ }
+});
+
+Cypress.Commands.add('checkOrganizationParams', (organizationParams) => {
+ cy.get('.cvat-organization-top-bar-descriptions').then((orgDescriptions) => {
+ const orgDescText = orgDescriptions.text();
+ expect(orgDescText).contain(organizationParams.shortName);
+ expect(orgDescText).contain(organizationParams.fullName);
+ expect(orgDescText).contain(organizationParams.description);
+ });
+ cy.get('.cvat-organization-top-bar-contacts').then((orgContacts) => {
+ const orgContactsText = orgContacts.text();
+ expect(orgContactsText).contain(organizationParams.email);
+ expect(orgContactsText).contain(organizationParams.phoneNumber);
+ expect(orgContactsText).contain(organizationParams.location);
+ });
+});
+
+Cypress.Commands.add('checkOrganizationMembers', (expectedMembersCount, expectedOrganizationMembers) => {
+ const orgMembersUserameText = [];
+ cy.get('.cvat-organization-member-item').should('have.length', expectedMembersCount);
+ cy.get('.cvat-organization-member-item-username').each((el) => {
+ orgMembersUserameText.push(el.text());
+ }).then(() => {
+ expect(orgMembersUserameText).to.include.members(expectedOrganizationMembers);
+ });
+});
+
+Cypress.Commands.add('inviteMembersToOrganization', (members) => {
+ cy.get('.cvat-organization-top-bar-buttons-block').should('exist');
+ cy.contains('button', 'Invite members').click();
+ cy.get('.cvat-organization-invitation-modal').should('be.visible');
+ let addedMembers = 0;
+ for (const el of members) {
+ cy.get('.cvat-organization-invitation-field-email')
+ .last()
+ .find('input')
+ .type(el.email)
+ .should('have.value', el.email);
+ cy.get('.cvat-organization-invitation-field-email')
+ .find('[aria-label="check-circle"]')
+ .should('exist');
+ cy.get('.cvat-organization-invitation-field-role').last().click();
+ cy.get('.ant-select-dropdown')
+ .should('be.visible')
+ .not('.ant-select-dropdown-hidden')
+ .find(`[title=${el.role}]`)
+ .click();
+ addedMembers++;
+ if (addedMembers !== Object.keys(members).length) {
+ cy.contains('button', 'Invite more').click();
+ }
+ }
+ cy.get('.cvat-organization-invitation-modal')
+ .contains('button', 'OK')
+ .click();
+});
+
+Cypress.Commands.add('removeMemberFromOrganization', (username) => {
+ cy.contains('.cvat-organization-member-item-username', username)
+ .parents('.cvat-organization-member-item')
+ .find('.cvat-organization-member-item-remove')
+ .click();
+ cy.get('.cvat-modal-organization-member-remove')
+ .contains('button', 'Yes, remove')
+ .click();
+});
diff --git a/tests/cypress/support/commands_projects.js b/tests/cypress/support/commands_projects.js
index 55bae092..e0544c38 100644
--- a/tests/cypress/support/commands_projects.js
+++ b/tests/cypress/support/commands_projects.js
@@ -7,6 +7,7 @@
Cypress.Commands.add('goToProjectsList', () => {
cy.get('[value="projects"]').click();
cy.url().should('include', '/projects');
+ cy.get('.cvat-spinner').should('not.exist');
});
Cypress.Commands.add(
@@ -37,6 +38,32 @@ Cypress.Commands.add(
},
);
+Cypress.Commands.add('deleteProjects', (authResponse, projectsToDelete) => {
+ const authKey = authResponse.body.key;
+ cy.request({
+ url: '/api/v1/projects?page_size=all',
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ }).then((_response) => {
+ const responceResult = _response.body.results;
+ for (const project of responceResult) {
+ const { id, name } = project;
+ for (const projectToDelete of projectsToDelete) {
+ if (name === projectToDelete) {
+ cy.request({
+ method: 'DELETE',
+ url: `/api/v1/projects/${id}`,
+ headers: {
+ Authorization: `Token ${authKey}`,
+ },
+ });
+ }
+ }
+ }
+ });
+});
+
Cypress.Commands.add('openProject', (projectName) => {
cy.contains(projectName).click({ force: true });
cy.get('.cvat-project-details').should('exist');
diff --git a/tests/cypress/support/index.js b/tests/cypress/support/index.js
index dd649730..62aaa768 100644
--- a/tests/cypress/support/index.js
+++ b/tests/cypress/support/index.js
@@ -9,6 +9,7 @@ require('./commands_canvas3d');
require('./commands_filters_feature');
require('./commands_models');
require('./commands_opencv');
+require('./commands_organizations');
require('@cypress/code-coverage/support');
before(() => {
diff --git a/tests/cypress_canvas3d.json b/tests/cypress_canvas3d.json
index d965f768..b6a0bfc1 100644
--- a/tests/cypress_canvas3d.json
+++ b/tests/cypress_canvas3d.json
@@ -14,6 +14,6 @@
"auth_page.js",
"canvas3d_functionality/*.js",
"canvas3d_functionality_2/*.js",
- "remove_users_tasks_projects.js"
+ "remove_users_tasks_projects_organizations.js"
]
}
diff --git a/tests/cypress_cron_type.json b/tests/cypress_cron_type.json
index c8d01f82..6565c36e 100644
--- a/tests/cypress_cron_type.json
+++ b/tests/cypress_cron_type.json
@@ -21,6 +21,6 @@
"actions_projects_models/*.js",
"actions_users/*.js",
"email_system/*.js",
- "remove_users_tasks_projects.js"
+ "remove_users_tasks_projects_organizations.js"
]
}