diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts b/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts index 0c14ace06e992c49e1b96c5a6b92fc5d79437eea..e6c95427e7397272adfa1918fc560591f441d3d2 100644 --- a/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts +++ b/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts @@ -3,8 +3,10 @@ import KcAdminClient, { NetworkError } from '@keycloak/keycloak-admin-client'; import { TokenProvider } from '@keycloak/keycloak-admin-client/lib/client'; import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation'; import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation'; +import RoleRepresentation from '@keycloak/keycloak-admin-client/lib/defs/roleRepresentation'; import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; import { OAuthService } from 'angular-oauth2-oidc'; +import { isNil } from 'lodash-es'; import { Observable, OperatorFunction, @@ -111,11 +113,8 @@ export class UserRepository { } private addInformationToUser(user: UserRepresentation) { - return forkJoin({ - groups: this.getUserGroups(user), - roles: this.getAlfaClientRoles(user), - }).pipe( - map(({ groups, roles }) => ({ + return forkJoin([this.getUserGroups(user), this.getAlfaClientRoles(user)]).pipe( + map(([groups, roles]) => ({ ...user, groups, roles, @@ -131,16 +130,19 @@ export class UserRepository { private getAlfaClientRoles(user: UserRepresentation): Observable<string[]> { return from(this.kcAdminClient.users.listRoleMappings({ id: user.id })).pipe( - map((clientMappings) => this.mapToAlfaClientRoleNames(clientMappings)), + map((clientMappings: MappingsRepresentation) => + this.mapToAlfaClientRoleNames(clientMappings), + ), ); } private mapToAlfaClientRoleNames(roleMappings: MappingsRepresentation): string[] { - const clientMappings = - roleMappings.clientMappings ? roleMappings.clientMappings['alfa'] : undefined; - if (clientMappings && clientMappings.mappings) { - return clientMappings.mappings.map((role: any) => role.name); + if (isNil(roleMappings?.clientMappings?.['alfa'])) { + return []; } - return []; + + return roleMappings.clientMappings['alfa'].mappings.map( + (role: RoleRepresentation) => role.name, + ); } } diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts b/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts index 23d0951d8bcc60689206e83320a407e93e118ea7..d24b2af59e6118b9faca6e56ca81e994f5af5a2f 100644 --- a/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts +++ b/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts @@ -4,6 +4,7 @@ import { faker } from '@faker-js/faker'; import KcAdminClient, { NetworkError } from '@keycloak/keycloak-admin-client'; import { TokenProvider } from '@keycloak/keycloak-admin-client/lib/client'; import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation'; +import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation'; import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation'; import { Groups } from '@keycloak/keycloak-admin-client/lib/resources/groups'; import { OAuthService } from 'angular-oauth2-oidc'; @@ -37,9 +38,6 @@ describe('UserRepository', () => { }; }; - const userRep: UserRepresentation = { id: '1234' }; - const groupRep: GroupRepresentation = { name: 'groupName' }; - beforeEach(() => { kcAdminClient = mock(KcAdminClient); oAuthService = mock(OAuthService); @@ -336,35 +334,59 @@ describe('UserRepository', () => { }); describe('getUsers', () => { - let findMock: jest.Mock; - let listGroupsMock: jest.Mock; + const userRep: UserRepresentation = { id: faker.random.word(), firstName: faker.random.word() }; + const userRepArray: UserRepresentation[] = [userRep, userRep, userRep]; + const group = faker.random.word(); + const role = faker.random.word(); + const groupRep: GroupRepresentation[] = [{ name: group }]; + const roleRep: MappingsRepresentation = { + clientMappings: { alfa: { mappings: [{ name: role }] } }, + }; beforeEach(() => { - findMock = jest.fn().mockReturnValue(Promise.resolve([userRep])); - listGroupsMock = jest.fn().mockReturnValue(Promise.resolve([groupRep])); - + jest.clearAllMocks(); kcAdminClient.users = <any>{ - find: findMock, - listGroups: listGroupsMock, + find: jest.fn().mockReturnValue(Promise.resolve(userRepArray)), + listGroups: jest.fn().mockReturnValue(Promise.resolve(groupRep)), + listRoleMappings: jest.fn().mockReturnValue(Promise.resolve(roleRep)), }; }); it('should call kcAdminClient users find', () => { repository.getUsers(); - expect(findMock).toHaveBeenCalled(); + expect(kcAdminClient.users['find']).toHaveBeenCalled(); }); - it('should call kcAdminClient users listGroups', fakeAsync(() => { + it('should call kcadminClient listGroups for every user', fakeAsync(() => { repository.getUsers().subscribe(); tick(); - expect(listGroupsMock).toHaveBeenCalledWith({ id: userRep.id }); + expect(kcAdminClient.users['listGroups']).toBeCalledTimes(userRepArray.length); })); - it('should return users with groups', (done) => { - repository.getUsers().subscribe((result) => { - expect(result).toEqual([{ ...userRep, groupReps: [groupRep] }]); + it('should call kcadminClient listRoleMappings for every user', fakeAsync(() => { + repository.getUsers().subscribe(); + tick(); + + expect(kcAdminClient.users['listRoleMappings']).toBeCalledTimes(userRepArray.length); + })); + + it('should return users with groups and roles', (done) => { + repository.getUsers().subscribe((users: UserRepresentation[]) => { + users.forEach((user) => + expect(user).toEqual({ ...userRep, groups: [group], roles: [role] }), + ); + done(); + }); + }); + + it('should return users with empty groups and roles if they have none', (done) => { + kcAdminClient.users['listGroups'] = jest.fn().mockReturnValue(Promise.resolve([])); + kcAdminClient.users['listRoleMappings'] = jest.fn().mockReturnValue(Promise.resolve({})); + + repository.getUsers().subscribe((users: UserRepresentation[]) => { + users.forEach((user) => expect(user).toEqual({ ...userRep, groups: [], roles: [] })); done(); }); });