Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove user from team #5797

Merged
merged 12 commits into from
Sep 10, 2024
64 changes: 64 additions & 0 deletions e2e/portalicious/pages/ProjectTeam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,29 @@ import BasePage from './BasePage';
class ProjectTeam extends BasePage {
readonly page: Page;
readonly tableRows: Locator;
readonly addUserFormUsersDropdown: Locator;
readonly addUserFormChooseUserDropdown: Locator;
readonly addUserFormChooseRoleDropdown: Locator;
readonly addUserFormSubmitButton: Locator;
readonly removeUserButton: Locator;

constructor(page: Page) {
super(page);
this.page = page;
this.tableRows = this.page.locator('table tbody tr');
this.addUserFormUsersDropdown = this.page.getByRole('option');
this.addUserFormChooseUserDropdown = this.page.locator(
`[formControlName="userValue"]`,
);
this.addUserFormChooseRoleDropdown = this.page.locator(
`[formControlName="rolesValue"]`,
);
this.addUserFormSubmitButton = this.page.getByRole('button', {
name: 'Submit',
});
this.removeUserButton = this.page.getByRole('button', {
name: 'Remove user',
});
}

async validateAssignedTeamMembers(expectedAssignedUsers: string[]) {
Expand All @@ -28,6 +46,52 @@ class ProjectTeam extends BasePage {

expect(sortedActualUsers).toEqual(sortedExpectedUsers);
}

async openAddUserForm() {
await this.page.getByRole('button', { name: 'Add team member' }).click();
}

async addUserToTeam({
userSearchPhrase,
userEmail,
role,
}: {
userSearchPhrase: string;
userEmail: string;
role: string;
}) {
await this.addUserFormChooseUserDropdown.click();
await this.addUserFormChooseUserDropdown.fill(userSearchPhrase);
await this.page.getByText(userEmail).click();
await this.addUserFormChooseRoleDropdown.click();
await this.page.getByText(role).click();
await this.addUserFormSubmitButton.click();
}

async validateAvailableSystemUsers(expectedAssignedUsers: string[]) {
await this.addUserFormChooseUserDropdown.click();
const actualAssignedUsers = await this.addUserFormUsersDropdown.evaluateAll(
(options) => options.map((option) => option.textContent.trim()),
);

const sortedActualUsers = [...actualAssignedUsers].sort((a, b) =>
a.localeCompare(b),
);
const sortedExpectedUsers = [...expectedAssignedUsers].sort((a, b) =>
a.localeCompare(b),
);

expect(sortedActualUsers).toEqual(sortedExpectedUsers);
}

async removeUserFromTeam({ userEmail }: { userEmail: string }) {
await this.page
.getByRole('row', { name: userEmail })
.getByRole('button')
.click();
await this.page.getByLabel('Remove user').click();
await this.removeUserButton.click();
}
}

export default ProjectTeam;
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import BasePage from '@121-e2e/portalicious/pages/BasePage';
import LoginPage from '@121-e2e/portalicious/pages/LoginPage';
import ProjectTeam from '@121-e2e/portalicious/pages/ProjectTeam';
import { SeedScript } from '@121-service/src/scripts/seed-script.enum';
import { resetDB } from '@121-service/test/helpers/utility.helper';
import { test } from '@playwright/test';

const expectedAssignedUsers = ['admin@example.org'];
const expectedAvailablesystemUsers = [
'program-admin@example.org',
'view-user@example.org',
'kobo-user@example.org',
'cva-manager@example.org',
'cva-officer@example.org',
'finance-manager@example.org',
'finance-officer@example.org',
'view-no-pii@example.org',
];

test.beforeEach(async ({ page }) => {
await resetDB(SeedScript.oneAdmin);

// Login
const loginPage = new LoginPage(page);
await page.goto('/');
await loginPage.login(
process.env.USERCONFIG_121_SERVICE_EMAIL_ADMIN,
process.env.USERCONFIG_121_SERVICE_PASSWORD_ADMIN,
);
});

test('[29758] All system-users are available to be added to a "project team"', async ({
page,
}) => {
const basePage = new BasePage(page);
const manageTeam = new ProjectTeam(page);
const projectTitle = 'Cash program Warsaw';

await test.step('Select program and navigate to Manage team', async () => {
await basePage.selectProgram(projectTitle);
await basePage.navigateToProgramPage('Team');
});

await test.step('Validate assigned users are visible', async () => {
await manageTeam.validateAssignedTeamMembers(expectedAssignedUsers);
});

await test.step('Validate available system users are visible', async () => {
await manageTeam.openAddUserForm();
await manageTeam.validateAvailableSystemUsers(expectedAvailablesystemUsers);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import BasePage from '@121-e2e/portalicious/pages/BasePage';
import LoginPage from '@121-e2e/portalicious/pages/LoginPage';
import ProjectTeam from '@121-e2e/portalicious/pages/ProjectTeam';
import { SeedScript } from '@121-service/src/scripts/seed-script.enum';
import { resetDB } from '@121-service/test/helpers/utility.helper';
import { test } from '@playwright/test';

const expectedAssignedUsers = ['admin@example.org', 'cva-officer@example.org'];
const userSearchPhrase = 'cva-officer';
const userFullEmail = 'cva-officer@example.org';
const userRole = 'Only CREATE registrations';

test.beforeEach(async ({ page }) => {
await resetDB(SeedScript.oneAdmin);

// Login
const loginPage = new LoginPage(page);
await page.goto('/');
await loginPage.login(
process.env.USERCONFIG_121_SERVICE_EMAIL_ADMIN,
process.env.USERCONFIG_121_SERVICE_PASSWORD_ADMIN,
);
});

test('[29759] Assign successfully roles to a user ', async ({ page }) => {
const basePage = new BasePage(page);
const manageTeam = new ProjectTeam(page);
const projectTitle = 'Cash program Warsaw';

await test.step('Select program and navigate to Manage team', async () => {
await basePage.selectProgram(projectTitle);
await basePage.navigateToProgramPage('Team');
});

await test.step('Validate available system users are visible', async () => {
await manageTeam.openAddUserForm();
await manageTeam.addUserToTeam({
userSearchPhrase: userSearchPhrase,
userEmail: userFullEmail,
role: userRole,
});
await manageTeam.validateToastMessage('User added');
await manageTeam.validateAssignedTeamMembers(expectedAssignedUsers);
});
});
59 changes: 59 additions & 0 deletions e2e/portalicious/tests/ManageTeam/RemoveUserFromTeam.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import BasePage from '@121-e2e/portalicious/pages/BasePage';
import LoginPage from '@121-e2e/portalicious/pages/LoginPage';
import ProjectTeam from '@121-e2e/portalicious/pages/ProjectTeam';
import { SeedScript } from '@121-service/src/scripts/seed-script.enum';
import { resetDB } from '@121-service/test/helpers/utility.helper';
import { test } from '@playwright/test';

const expectedInitialAssignedUsers = [
'admin@example.org',
'program-admin@example.org',
'view-user@example.org',
'kobo-user@example.org',
'cva-manager@example.org',
'cva-officer@example.org',
'finance-manager@example.org',
'finance-officer@example.org',
'view-no-pii@example.org',
];
const userToRemove = 'view-no-pii@example.org';
const expectedFinalAssignedUsers = expectedInitialAssignedUsers.filter(
(email) => email !== userToRemove,
);

test.beforeEach(async ({ page }) => {
await resetDB(SeedScript.test);

// Login
const loginPage = new LoginPage(page);
await page.goto('/');
await loginPage.login(
process.env.USERCONFIG_121_SERVICE_EMAIL_ADMIN,
process.env.USERCONFIG_121_SERVICE_PASSWORD_ADMIN,
);
});

test('[29760] Users should be removable from "project team"', async ({
page,
}) => {
const basePage = new BasePage(page);
const manageTeam = new ProjectTeam(page);
const projectTitle = 'Cash program Westeros';

await test.step('Select program and navigate to Manage team', async () => {
await basePage.selectProgram(projectTitle);
await basePage.navigateToProgramPage('Team');
});

await test.step('Validate assigned users are visible', async () => {
await manageTeam.validateAssignedTeamMembers(expectedInitialAssignedUsers);
});

await test.step('Validate available system users are visible', async () => {
await manageTeam.removeUserFromTeam({
userEmail: userToRemove,
});
await manageTeam.validateToastMessage('User removed');
await manageTeam.validateAssignedTeamMembers(expectedFinalAssignedUsers);
});
});
4 changes: 4 additions & 0 deletions services/121-service/src/scripts/scripts.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SeedProgramDrc } from '@121-service/src/scripts/seed-program-drc';
import { SeedNLProgramPV } from '@121-service/src/scripts/seed-program-nlrc-pv';
import { SeedTestProgram } from '@121-service/src/scripts/seed-program-test';
import { SeedTestMultipleProgram } from '@121-service/src/scripts/seed-program-test-multiple';
import { SeedTestOneAdmin } from '@121-service/src/scripts/seed-program-test-one-admin';
import { SeedProgramValidation } from '@121-service/src/scripts/seed-program-validation';
import { SeedScript } from '@121-service/src/scripts/seed-script.enum';
import { WrapperType } from '@121-service/src/wrapper.type';
Expand Down Expand Up @@ -36,6 +37,7 @@ export class ScriptsController {
private readonly seedProgramNlrcPv: SeedNLProgramPV,
private readonly seedProgramTestMultiple: SeedTestMultipleProgram,
private readonly seedProgramTest: SeedTestProgram,
private readonly seedProgramOneAdmin: SeedTestOneAdmin,
private readonly seedProgramValidation: SeedProgramValidation,
private readonly seedInit: SeedInit,
private readonly scriptsService: ScriptsService,
Expand Down Expand Up @@ -110,6 +112,8 @@ export class ScriptsController {
await this.seedDemoProgram.run(isApiTests);
} else if (script == SeedScript.test) {
await this.seedProgramTest.run(isApiTests);
} else if (script == SeedScript.oneAdmin) {
await this.seedProgramOneAdmin.run(isApiTests);
} else if (script == SeedScript.testMultiple) {
await this.seedProgramTestMultiple.run(isApiTests);
} else if (script == SeedScript.nlrcMultiple) {
Expand Down
2 changes: 2 additions & 0 deletions services/121-service/src/scripts/scripts.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SeedProgramDrc } from '@121-service/src/scripts/seed-program-drc';
import { SeedNLProgramPV } from '@121-service/src/scripts/seed-program-nlrc-pv';
import { SeedTestProgram } from '@121-service/src/scripts/seed-program-test';
import { SeedTestMultipleProgram } from '@121-service/src/scripts/seed-program-test-multiple';
import { SeedTestOneAdmin } from '@121-service/src/scripts/seed-program-test-one-admin';
import { SeedProgramValidation } from '@121-service/src/scripts/seed-program-validation';
import { CustomHttpService } from '@121-service/src/shared/services/custom-http.service';
import { AxiosCallsService } from '@121-service/src/utils/axios/axios-calls.service';
Expand Down Expand Up @@ -44,6 +45,7 @@ import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
SeedMultipleNLRCMockData,
SeedProgramDrc,
SeedTestProgram,
SeedTestOneAdmin,
SeedTestMultipleProgram,
SeedMockHelper,
AxiosCallsService,
Expand Down
80 changes: 80 additions & 0 deletions services/121-service/src/scripts/seed-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,86 @@ export class SeedHelper {
await this.assignAdminUserToProgram(program.id);
}

public async addOneDefaultAdminUser(
program: ProgramEntity,
debugScopeUsers: string[] = [],
): Promise<void> {
const users = [
{
type: 'programAdminUser',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_PROGRAM_ADMIN,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_PROGRAM_ADMIN,
roles: [DefaultUserRole.ProgramAdmin],
},
{
type: 'viewOnlyUser',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_USER_VIEW,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_USER_VIEW,
roles: [DefaultUserRole.View],
},
{
type: 'koboUser',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_USER_KOBO,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_USER_KOBO,
roles: [DefaultUserRole.KoboUser],
},
{
type: 'cvaManager',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_CVA_MANAGER,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_CVA_MANAGER,
roles: [DefaultUserRole.CvaManager],
},
{
type: 'cvaOfficer',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_CVA_OFFICER,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_CVA_OFFICER,
roles: [DefaultUserRole.CvaOfficer],
},
{
type: 'financeManager',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_FINANCE_MANAGER,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_FINANCE_MANAGER,
roles: [DefaultUserRole.FinanceManager],
},
{
type: 'financeOfficer',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_FINANCE_OFFICER,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_FINANCE_OFFICER,
roles: [DefaultUserRole.FinanceOfficer],
},
{
type: 'ViewWithoutPII',
username: process.env.USERCONFIG_121_SERVICE_EMAIL_VIEW_WITHOUT_PII,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_VIEW_WITHOUT_PII,
roles: [DefaultUserRole.ViewWithoutPII],
},
];

for (const user of users) {
await this.getOrSaveUser(user);
}

if (debugScopeUsers && DEBUG) {
for (const debugScopeUser of debugScopeUsers) {
const scopedUser = await this.getOrSaveUser({
type: 'debugScopedUser',
username: `${debugScopeUser}@example.org`,
password: process.env.USERCONFIG_121_SERVICE_PASSWORD_PROGRAM_ADMIN,
});
if (scopedUser) {
await this.assignAidworker(
scopedUser.id,
program.id,
[DefaultUserRole.Admin],
debugScopeUser,
);
}
}
}

await this.assignAdminUserToProgram(program.id);
}

public async getOrSaveUser(userInput: {
type: string;
username?: string;
Expand Down
24 changes: 24 additions & 0 deletions services/121-service/src/scripts/seed-program-test-one-admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { InterfaceScript } from '@121-service/src/scripts/scripts.module';
import { SeedHelper } from '@121-service/src/scripts/seed-helper';
import messageTemplateTest from '@121-service/src/seed-data/message-template/message-template-test.json';
import organizationAdmin from '@121-service/src/seed-data/organization/organization-one-admin.json';
import programTest from '@121-service/src/seed-data/program/program-test-one-admin.json';
import { Injectable } from '@nestjs/common';

@Injectable()
export class SeedTestOneAdmin implements InterfaceScript {
public constructor(private readonly seedHelper: SeedHelper) {}

public async run(isApiTests = false): Promise<void> {
// ***** CREATE PROGRAM *****
const program = await this.seedHelper.addProgram(programTest, isApiTests);

// ***** CREATE MESSAGE TEMPLATES *****
await this.seedHelper.addMessageTemplates(messageTemplateTest, program);

await this.seedHelper.addOneDefaultAdminUser(program);

// ***** CREATE ORGANIZATION *****
await this.seedHelper.addOrganization(organizationAdmin);
}
}
Loading
Loading