Skip to content

Commit

Permalink
added user management
Browse files Browse the repository at this point in the history
  • Loading branch information
pnaik1 committed Apr 19, 2024
1 parent 14f6605 commit cfae327
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 5 deletions.
28 changes: 28 additions & 0 deletions frontend/src/__mocks__/mockGroupConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { GroupsConfig } from '~/pages/groupSettings/groupTypes';

export const mockGroupSettings = (): GroupsConfig => ({
adminGroups: [
{
id: 0,
name: 'odh-admins',
enabled: true,
},
{
id: 1,
name: 'odh-admins-1',
enabled: false,
},
],
allowedGroups: [
{
id: 0,
name: 'odh-admins',
enabled: false,
},
{
id: 1,
name: 'system:authenticated',
enabled: false,
},
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,11 @@ describe('Project Details', () => {
});
projectDetails.visitSection('test-project', 'workbenches');
const notebookRow = projectDetails.getNotebookRow('test-notebook');
notebookRow.findOutdatedElyraInfo().should('not.exist');
projectDetails.findElyraInvalidVersionAlert().should('not.exist');
notebookRow.findOutdatedElyraInfo().should('be.visible');
projectDetails.findElyraInvalidVersionAlert().should('be.visible');
projectDetails.findUnsupportedPipelineVersionAlert().should('not.exist');
});

it('Notebook with updated Elyra image and no pipeline server', () => {
initIntercepts({
imageStreamPythonDependencies: '[{"name":"odh-elyra","version":"3.16"}]',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { mockGroupSettings } from '~/__mocks__/mockGroupConfig';
import { userManagement } from '~/__tests__/cypress/cypress/pages/userManagement';

describe('User Management', () => {
beforeEach(() => {
cy.interceptOdh('GET /api/groups-config', mockGroupSettings());
cy.interceptOdh('PUT /api/groups-config', mockGroupSettings()).as('saveGroupSetting');
userManagement.visit();
});

it('Administrator group setting', () => {
const administratorGroupSection = userManagement.getAdministratorGroupSection();
administratorGroupSection.shouldHaveAdministratorGroupInfo();
administratorGroupSection.clearMultiChipItem();
administratorGroupSection.selectMultiGroup('odh-admins');
administratorGroupSection.findMultiSelectGroupInput().type('odh-admin');
administratorGroupSection.findMultiGroupOptions('odh-admins-1').click();
administratorGroupSection.findChipItem().should('contain', 'odh-admins');
administratorGroupSection.removeChipItem('odh-admins');
administratorGroupSection.findChipItem().should('not.contain', /^odh-admins$/);
administratorGroupSection.removeChipItem('odh-admins-1');
administratorGroupSection.findErrorText().should('exist');
administratorGroupSection.findMultiGroupOptions('odh-admins').click();
administratorGroupSection.findErrorText().should('not.exist');
userManagement.findSubmitButton().should('be.disabled');
});

it('User group setting', () => {
const userGroupSection = userManagement.getUserGroupSection();
userManagement.findSubmitButton().should('be.disabled');
userGroupSection.findErrorText().should('exist');
userGroupSection.selectMultiGroup('odh-admins');
userGroupSection.findMultiGroupOptions('system:authenticated').click();
userGroupSection.findChipItem().should('contain', 'odh-admins');
userGroupSection.removeChipItem('odh-admins');
userManagement.findSubmitButton().should('be.enabled');
userManagement.findSubmitButton().click();
cy.wait('@saveGroupSetting').then((interception) => {
expect(interception.request.body).to.eql({
adminGroups: [
{ id: 0, name: 'odh-admins', enabled: true },
{ id: 1, name: 'odh-admins-1', enabled: false },
],
allowedGroups: [
{ id: 0, name: 'odh-admins', enabled: false },
{ id: 1, name: 'system:authenticated', enabled: true },
],
});
});
});
});
68 changes: 68 additions & 0 deletions frontend/src/__tests__/cypress/cypress/pages/userManagement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Contextual } from './components/Contextual';

class GroupSettingSection extends Contextual<HTMLElement> {
shouldHaveAdministratorGroupInfo() {
this.find().findByTestId('data-science-administrator-info');
return this;
}

clearMultiChipItem() {
this.find().findByRole('button', { name: 'Clear all' }).click();
}

findMultiSelectGroupInput() {
return this.find().find('input');
}

findMultiGroupOptions(name: string) {
return this.find().findByTestId('multi-group-selection').findByRole('option', { name });
}

private findChipGroup() {
return this.find().findByRole('list', { name: 'Chip group category' });
}

findChipItem() {
return this.findChipGroup().find('li');
}

removeChipItem(name: string) {
this.findChipGroup()
.findByRole('button', { name: `Remove ${name}` })
.click();
}

findErrorText() {
return this.find().findByTestId('group-selection-error-text');
}

selectMultiGroup(name: string) {
this.find().findByRole('button', { name: 'Options menu' }).click();
this.findMultiGroupOptions(name).click();
}
}
class UserManagement {
visit() {
cy.visit('/groupSettings');
this.wait();
}

private wait() {
cy.findByTestId('app-page-title').should('have.text', 'User management');
cy.testA11y();
}

findSubmitButton() {
return cy.findByTestId('save-button');
}

getAdministratorGroupSection() {
return new GroupSettingSection(() => cy.findByTestId('data-science-administrator-groups'));
}

getUserGroupSection() {
return new GroupSettingSection(() => cy.findByTestId('data-science-user-groups'));
}
}

export const userManagement = new UserManagement();
11 changes: 11 additions & 0 deletions frontend/src/__tests__/cypress/cypress/support/commands/odh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
ServingRuntimeKind,
TemplateKind,
} from '~/k8sTypes';
import { GroupsConfig } from '~/pages/groupSettings/groupTypes';
import type { StatusResponse } from '~/redux/types';
import type {
BYONImage,
Expand Down Expand Up @@ -57,6 +58,16 @@ declare global {
response?: OdhResponse,
): Cypress.Chainable<null>;

interceptOdh(
type: 'GET /api/groups-config',
response?: OdhResponse<GroupsConfig>,
): Cypress.Chainable<null>;

interceptOdh(
type: 'PUT /api/groups-config',
response?: OdhResponse<GroupsConfig>,
): Cypress.Chainable<null>;

interceptOdh(
type: 'GET /api/components',
options: {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/MultiSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const MultiSelection: React.FC<MultiSelectionProps> = ({ value, setValue,
return (
<>
<Select
data-testid="multi-group-selection"
variant={SelectVariant.typeaheadMulti}
onToggle={(e, isOpen: React.SetStateAction<boolean>) => toggleMenu(isOpen)}
onSelect={(e, newValue) => {
Expand All @@ -51,7 +52,7 @@ export const MultiSelection: React.FC<MultiSelectionProps> = ({ value, setValue,
</Select>
{noSelectedItems && (
<HelperText>
<HelperTextItem variant="error" hasIcon>
<HelperTextItem variant="error" hasIcon data-testid="group-selection-error-text">
One or more group must be selected
</HelperTextItem>
</HelperText>
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/components/SettingSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Card, CardBody, CardFooter, CardTitle, Stack, StackItem } from '@patter
type SettingSectionProps = {
children: React.ReactNode;
title: string;
testId?: string;
description?: React.ReactNode;
footer?: React.ReactNode;
};
Expand All @@ -12,9 +13,10 @@ const SettingSection: React.FC<SettingSectionProps> = ({
title,
children,
footer,
testId,
description,
}) => (
<Card isFlat>
<Card data-testid={testId} isFlat>
<CardTitle>{title}</CardTitle>
<CardBody>
<Stack hasGutter>
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/pages/groupSettings/GroupSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ const GroupSettings: React.FC = () => {
<StackItem>
<SettingSection
title="Data Science administrator groups"
testId="data-science-administrator-groups"
description={adminDesc}
footer={
<Alert
data-testid="data-science-administrator-info"
variant="info"
isInline
isPlain
Expand Down Expand Up @@ -102,7 +104,11 @@ const GroupSettings: React.FC = () => {
</SettingSection>
</StackItem>
<StackItem>
<SettingSection title="Data Science user groups" description={userDesc}>
<SettingSection
title="Data Science user groups"
description={userDesc}
testId="data-science-user-groups"
>
<MultiSelection
ariaLabel={userDesc}
value={groupSettings.allowedGroups}
Expand Down Expand Up @@ -133,6 +139,7 @@ const GroupSettings: React.FC = () => {
<StackItem>
<Button
data-id="save-button"
data-testid="save-button"
isDisabled={
isLoading ||
!isGroupSettingsChanged ||
Expand Down

0 comments on commit cfae327

Please sign in to comment.