From 6c4650785cd63977a4bf0dff402563a04f5ad128 Mon Sep 17 00:00:00 2001 From: tomgny <49343696+tomgny@users.noreply.github.com> Date: Thu, 28 Oct 2021 15:07:22 +0200 Subject: [PATCH] [AAE-5961] Storybook stories for GroupCloud component (#7326) * [AAE-5961] added stories and mock files * [AAE-5961] added interface for identity group service * [AAE-5961] added few stories * [AAE-5961] added mock for roles, syntax improvements * [AAE-5961] improved syntax, removed redundant storybook config files * [AAE-5961] renamed service interface * [AAE-5961] removed unused declarations * [AAE-5961] exported interface from core * [AAE-5961] restored config files for process cloud lib * [AAE-5961] improved syntax --- lib/core/services/identity-group.interface.ts | 48 ++++++ lib/core/services/identity-group.service.ts | 3 +- lib/core/services/public-api.ts | 1 + .../group-cloud.component.stories.ts | 105 +++++++++++++ .../group/mock/identity-group.service.mock.ts | 146 ++++++++++++++++++ 5 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 lib/core/services/identity-group.interface.ts create mode 100644 lib/process-services-cloud/src/lib/group/components/group-cloud.component.stories.ts create mode 100644 lib/process-services-cloud/src/lib/group/mock/identity-group.service.mock.ts diff --git a/lib/core/services/identity-group.interface.ts b/lib/core/services/identity-group.interface.ts new file mode 100644 index 0000000000..d2aa7737ce --- /dev/null +++ b/lib/core/services/identity-group.interface.ts @@ -0,0 +1,48 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { Observable } from 'rxjs'; +import { + IdentityGroupModel, + IdentityGroupQueryResponse, + IdentityGroupCountModel, + IdentityGroupQueryCloudRequestModel, + IdentityGroupSearchParam +} from '../models/identity-group.model'; +import { IdentityRoleModel } from '../models/identity-role.model'; + +export interface IdentityGroupServiceInterface { + + getGroups(): Observable; + getAvailableRoles(groupId: string): Observable; + getAssignedRoles(groupId: string): Observable; + assignRoles(groupId: string, roles: IdentityRoleModel[]): Observable; + removeRoles(groupId: string, roles: IdentityRoleModel[]): Observable; + getEffectiveRoles(groupId: string): Observable; + queryGroups(requestQuery: IdentityGroupQueryCloudRequestModel): Observable; + getTotalGroupsCount(): Observable; + createGroup(newGroup: IdentityGroupModel): Observable; + updateGroup(groupId: string, updatedGroup: IdentityGroupModel); + deleteGroup(groupId: string): Observable; + findGroupsByName(searchParams: IdentityGroupSearchParam): Observable; + getGroupRoles(groupId: string): Observable; + checkGroupHasRole(groupId: string, roleNames: string[]): Observable; + getClientIdByApplicationName(applicationName: string): Observable; + getClientRoles(groupId: string, clientId: string): Observable; + checkGroupHasClientApp(groupId: string, clientId: string): Observable; + checkGroupHasAnyClientAppRole(groupId: string, clientId: string, roleNames: string[]): Observable; +} diff --git a/lib/core/services/identity-group.service.ts b/lib/core/services/identity-group.service.ts index 9bf90a04f1..2b02340216 100644 --- a/lib/core/services/identity-group.service.ts +++ b/lib/core/services/identity-group.service.ts @@ -27,10 +27,11 @@ import { IdentityGroupCountModel } from '../models/identity-group.model'; import { IdentityRoleModel } from '../models/identity-role.model'; +import { IdentityGroupServiceInterface } from './identity-group.interface'; import { OAuth2Service } from './oauth2.service'; @Injectable({ providedIn: 'root' }) -export class IdentityGroupService { +export class IdentityGroupService implements IdentityGroupServiceInterface { constructor( private oAuth2Service: OAuth2Service, diff --git a/lib/core/services/public-api.ts b/lib/core/services/public-api.ts index fb2f7be879..7dd2f25e8a 100644 --- a/lib/core/services/public-api.ts +++ b/lib/core/services/public-api.ts @@ -66,3 +66,4 @@ export * from './auth-bearer.interceptor'; export * from './oauth2.service'; export * from './language.service'; export * from './identity-user.service.interface'; +export * from './identity-group.interface'; diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.stories.ts b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.stories.ts new file mode 100644 index 0000000000..9c415f70de --- /dev/null +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.stories.ts @@ -0,0 +1,105 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { Meta, moduleMetadata, Story } from '@storybook/angular'; +import { IdentityGroupService, mockIdentityGroups } from '@alfresco/adf-core'; +import { GroupCloudModule } from '../group-cloud.module'; +import { GroupCloudComponent } from './group-cloud.component'; +import { IdentityGroupServiceMock } from '../mock/identity-group.service.mock'; +import { ProcessServicesCloudStoryModule } from '../../testing/process-services-cloud-story.module'; + +export default { + component: GroupCloudComponent, + title: 'Process Services Cloud/Components/Group', + decorators: [ + moduleMetadata({ + imports: [ProcessServicesCloudStoryModule, GroupCloudModule], + providers: [ + { provide: IdentityGroupService, useClass: IdentityGroupServiceMock } + ] + }) + ], + argTypes: { + appName: { table: { disable: true } }, + mode: { + options: ['single', 'multiple'], + control: 'radio' + }, + roles: { + options: ['empty', 'user', 'admin'], + control: 'radio', + mapping: { + empty: [], + user: ['MOCK-USER-ROLE'], + admin: ['MOCK-ADMIN-ROLE'] + } + } + } +} as Meta; + +const template: Story = (args: GroupCloudComponent) => ({ + props: args +}); + +export const primary = template.bind({}); +primary.args = { + appName: 'app', + mode: 'single', + preSelectGroups: [], + readOnly: false, + roles: [], + title: 'Groups', + validate: false +}; + +export const validPreselectedGroups = template.bind({}); +validPreselectedGroups.args = { + ...primary.args, + validate: true, + mode: 'multiple', + preSelectGroups: mockIdentityGroups +}; + +export const mandatoryPreselectedGroups = template.bind({}); +mandatoryPreselectedGroups.args = { + ...primary.args, + validate: true, + mode: 'multiple', + preSelectGroups: [{ id: 'mock-group-id-1', name: 'Mock Group 1', path: '/mock', subGroups: [], readonly: true }, + { id: 'mock-group-id-2', name: 'Mock Group 2', path: '', subGroups: [] }, + { id: 'mock-group-id-3', name: 'Mock Group 3', path: '', subGroups: [], readonly: true }] +}; + +export const invalidPreselectedGroups = template.bind({}); +invalidPreselectedGroups.args = { + ...primary.args, + validate: true, + mode: 'multiple', + preSelectGroups: [{ id: 'invalid-group', name: 'invalid groups' }] +}; + +export const adminRoleGroups = template.bind({}); +adminRoleGroups.args = { + ...primary.args, + roles: 'admin' +}; + +export const invalidOrEmptyAppName = template.bind({}); +invalidOrEmptyAppName.args = { + ...primary.args, + appName: undefined +}; diff --git a/lib/process-services-cloud/src/lib/group/mock/identity-group.service.mock.ts b/lib/process-services-cloud/src/lib/group/mock/identity-group.service.mock.ts new file mode 100644 index 0000000000..adeff8329d --- /dev/null +++ b/lib/process-services-cloud/src/lib/group/mock/identity-group.service.mock.ts @@ -0,0 +1,146 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { Injectable } from '@angular/core'; +import { + IdentityGroupCountModel, + IdentityGroupModel, + IdentityGroupQueryCloudRequestModel, + IdentityGroupQueryResponse, + IdentityGroupSearchParam, + IdentityRoleModel, + mockIdentityGroups, + mockIdentityRoles, + IdentityGroupServiceInterface +} from '@alfresco/adf-core'; +import { Observable, of } from 'rxjs'; +import { map } from 'rxjs/operators'; + +Injectable({ providedIn: 'root' }); +export class IdentityGroupServiceMock implements IdentityGroupServiceInterface { + + getGroups(): Observable { + return of(mockIdentityGroups); + } + + getAvailableRoles(_groupId: string): Observable { + return of(mockIdentityRoles); + } + + getAssignedRoles(_groupId: string): Observable { + return of(mockIdentityRoles); + } + + assignRoles(_groupId: string, _roles: IdentityRoleModel[]): Observable { + return of(); + } + + removeRoles(_groupId: string, _roles: IdentityRoleModel[]): Observable { + return of(); + } + + getEffectiveRoles(_groupId: string): Observable { + return of(mockIdentityRoles); + } + + queryGroups(_requestQuery: IdentityGroupQueryCloudRequestModel): Observable { + return of(); + } + + getTotalGroupsCount(): Observable { + return of({ count: mockIdentityGroups.length }); + } + + createGroup(_newGroup: IdentityGroupModel): Observable { + return of(); + } + + updateGroup(_groupId: string, _updatedGroup: IdentityGroupModel): Observable { + return of(); + } + + deleteGroup(_groupId: string): Observable { + return of(); + } + + findGroupsByName(searchParams: IdentityGroupSearchParam): Observable { + if (searchParams.name === '') { + return of([]); + } + + return of(mockIdentityGroups.filter(group => + group.name.toUpperCase().includes(searchParams.name.toUpperCase()) + )); + } + + getGroupRoles(_groupId: string): Observable { + return of(mockIdentityRoles); + } + + checkGroupHasRole(groupId: string, roleNames: string[]): Observable { + return this.getGroupRoles(groupId).pipe(map((groupRoles) => { + let hasRole = false; + if (groupRoles && groupRoles.length > 0) { + roleNames.forEach((roleName: string) => { + const role = groupRoles.find(({ name }) => roleName === name); + if (role) { + hasRole = true; + return; + } + }); + } + return hasRole; + })); + } + + getClientIdByApplicationName(_applicationName: string): Observable { + return of('fake-client-id'); + } + + getClientRoles(groupId: string, _clientId: string): Observable { + if (['mock-group-id-1', 'mock-group-id-2'].includes(groupId)) { + return of([{ id: 'mock-role-id', name: 'MOCK-ADMIN-ROLE' }]); + } + + return of([{ id: 'mock-role-id', name: 'MOCK-USER-ROLE' }]); + } + + checkGroupHasClientApp(groupId: string, clientId: string): Observable { + return this.getClientRoles(groupId, clientId).pipe( + map((response) => response && response.length > 0) + ); + } + + checkGroupHasAnyClientAppRole(groupId: string, clientId: string, roleNames: string[]): Observable { + return this.getClientRoles(groupId, clientId).pipe( + map((clientRoles: any[]) => { + let hasRole = false; + if (clientRoles.length > 0) { + roleNames.forEach((roleName) => { + const role = clientRoles.find(({ name }) => name === roleName); + + if (role) { + hasRole = true; + return; + } + }); + } + return hasRole; + }) + ); + } +}