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

test(console): assign permissions to organization role #5729

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import ExpectApiResources from '#src/ui-helpers/expect-api-resources.js';
import ExpectConsole from '#src/ui-helpers/expect-console.js';
import ExpectOrganizations from '#src/ui-helpers/expect-organizations.js';
import {
generateResourceIndicator,
generateResourceName,
generateRoleName,
generateScopeName,
} from '#src/utils.js';

const expectConsole = new ExpectConsole();
const expectApiResources = new ExpectApiResources();
const expectOrganizations = new ExpectOrganizations();

const apiResourceName = generateResourceName();
const apiResourceIndicator = generateResourceIndicator();
const apiPermissionName = generateScopeName();

const organizationPermissionName = generateScopeName();
const organizationRoleName = generateRoleName();

const dummyPermissionDescription = 'Dummy permission description';

describe('Organization RBAC', () => {
beforeAll(async () => {
await expectConsole.start();
});

it('navigates to API resources page', async () => {
await expectApiResources.gotoPage('/api-resources', 'API resources');
await expectApiResources.toExpectTableHeaders('API name', 'API Identifier');
});

it('creates an API resource', async () => {
await expectApiResources.toCreateApiResource({
name: apiResourceName,
indicator: apiResourceIndicator,
});
});

it('creates an API permission for organization role', async () => {
await expectApiResources.toCreateApiResourcePermission(
{ name: apiPermissionName, description: dummyPermissionDescription },
apiResourceName
);
});

it('navigates to the organization template', async () => {
await expectConsole.gotoPage('/organization-template', 'Organization template');
await expectConsole.toExpectTabs('Organization roles', 'Organization permissions');
await expectConsole.toExpectTableHeaders('Organization Role', 'Permissions');
});

it('creates an organization permission', async () => {
await expectOrganizations.toCreateOrganizationPermission({
name: organizationPermissionName,
description: dummyPermissionDescription,
});
});

it('creates an organization role', async () => {
await expectOrganizations.toCreateOrganizationRole({
name: organizationRoleName,
description: dummyPermissionDescription,
});
});

it('assigns organization permissions and API permissions for organization role', async () => {
await expectOrganizations.toAssignPermissionsForOrganizationRole({
organizationPermission: organizationPermissionName,
apiPermission: {
resource: apiResourceName,
permission: apiPermissionName,
},
forOrganizationRole: organizationRoleName,
});
});

// Clean up
it('deletes created resources', async () => {
// Delete created organization role
await expectOrganizations.toDeleteOrganizationRole(organizationRoleName);

// Delete created organization permissions
await expectOrganizations.toDeleteOrganizationPermission(organizationPermissionName);

// Delete created API resource
await expectApiResources.toDeleteApiResource(apiResourceName);
});
});
105 changes: 105 additions & 0 deletions packages/integration-tests/src/ui-helpers/expect-api-resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { cls } from '#src/utils.js';

import ExpectConsole from './expect-console.js';
import { expectToClickDetailsPageOption, expectToClickModalAction } from './index.js';

export default class ExpectApiResources extends ExpectConsole {
/**
* Go to the api resources page and create a new API resource, then assert that the URL matches
* the API resource detail page.
*
* @param {Object} params The parameters for creating the API resource.
* @param {string} params.name The name of the API resource to create.
* @param {string} params.indicator The indicator of the API resource to create.
*/
async toCreateApiResource({ name, indicator }: { name: string; indicator: string }) {
await this.gotoPage('/api-resources', 'API resources');
await this.toClickButton('Create API resource');

await this.toExpectModal('Start with tutorials');

// Click bottom button to skip tutorials
await this.toClickButton('Continue without tutorial', false);

await this.toExpectModal('Create API resource');

await this.toFillForm({
name,
indicator,
});

await this.toClick(
['.ReactModalPortal', `button${cls('primary')}`].join(' '),
'Create API resource',
false
);

this.toMatchUrl(/\/api-resources\/.+$/);
}

/**
* Go to the api resource details page by given resource name and create a new API permission, then assert the permission is created.
*
* @param {Object} params The parameters for creating the API permission.
* @param {string} params.name The name of the API permission to create.
* @param {string} params.description The description of the API permission to create.
* @param {string} forResourceName The name of the API resource for which the permission is created.
*/
async toCreateApiResourcePermission(
{
name,
description,
}: {
name: string;
description: string;
},
forResourceName: string
) {
await this.gotoPage('/api-resources', 'API resources');
await this.toExpectTableHeaders('API name', 'API Identifier');

await expect(this.page).toClick(['table', 'tbody', 'tr', 'td', `a${cls('title')}`].join(' '), {
text: forResourceName,
});

// Expect the API resource details page
await expect(this.page).toMatchElement([cls('header'), cls('metadata'), 'div'].join(' '), {
text: forResourceName,
});

await this.toClickButton('Create permission', false);

await this.toExpectModal('Create permission');

await this.toFillForm({ name, description });

await this.toClick(
['.ReactModalPortal', `button${cls('primary')}`].join(' '),
'Create permission',
false
);

await this.waitForToast(`The permission ${name} has been successfully created`);

await this.toExpectTableCell(name);
}

/**
* Go to the api resource details page by given resource name and delete the API resource.
*
* @param {string} name The name of the API resource to delete.
*/
async toDeleteApiResource(name: string) {
await this.gotoPage('/api-resources', 'API resources');
await this.toExpectTableCell(name);
await this.toClickTableCell(name);

await expectToClickDetailsPageOption(this.page, 'Delete');

await this.toExpectModal('Reminder');
await this.toFill('.ReactModalPortal input', name);

await expectToClickModalAction(this.page, 'Delete');
await this.waitForToast(`The API resource ${name} has been successfully deleted`);
}
}
27 changes: 25 additions & 2 deletions packages/integration-tests/src/ui-helpers/expect-console.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ type ExpectConsoleOptions = {
tenantId?: string;
};

export type ConsoleTitle = 'Sign-in experience' | 'Organizations';
export type ConsoleTitle =
| 'Sign-in experience'
| 'Organizations'
| 'API resources'
| 'Organization template';

export default class ExpectConsole extends ExpectPage {
readonly options: Required<ExpectConsoleOptions>;
Expand Down Expand Up @@ -59,9 +63,15 @@ export default class ExpectConsole extends ExpectPage {

/**
* Navigate to a specific page in the Console.
* If the current page is the target page, it will not navigate.
*/
async gotoPage(pathname: string, title: ConsoleTitle) {
await this.navigateTo(this.buildUrl(path.join(this.options.tenantId, pathname)));
const target = this.buildUrl(path.join(this.options.tenantId, pathname));
if (this.page.url() === target.href) {
return;
}

await this.navigateTo(target);
await expect(this.page).toMatchElement(
[dcls('main'), dcls('container'), dcls('title')].join(' '),
{ text: title }
Expand Down Expand Up @@ -112,6 +122,19 @@ export default class ExpectConsole extends ExpectPage {
});
}

/**
* To click a table cell with the given text.
* @param text The text to expect, case-insensitive.
* @param shouldNavigate Whether to navigate to the page after clicking the cell.
*/
async toClickTableCell(text: string, shouldNavigate = true) {
await this.toClick(
['table', 'tbody', 'tr', 'td'].join(' '),
new RegExp(text, 'i'),
shouldNavigate
);
}

/**
* Expect a modal to appear with the given title.
*
Expand Down
Loading
Loading