From 7c45f2ce0703cd21727f4b51a0dd435bced31c98 Mon Sep 17 00:00:00 2001 From: mkreuzkam-cap <144103168+mkreuzkam-cap@users.noreply.github.com> Date: Tue, 17 Oct 2023 08:07:35 +0200 Subject: [PATCH] EW-621: Add GET endpoint for personenkontexte. (#40) * EW-621: Add Get personenkontext endpoint to person controller. * EW-621: Add personenkontexte to personendatensatz. --- ...z-dto.ts => find-personendatensatz.dto.ts} | 6 +- .../person/api/find-personenkontext.dto.ts | 20 ++++ .../api/person-api.mapper.profile.spec.ts | 36 +++++- .../person/api/person-api.mapper.profile.ts | 93 ++++++++++----- .../person/api/person.controller.spec.ts | 112 +++++++++++++----- src/modules/person/api/person.controller.ts | 42 +++++-- src/modules/person/api/person.uc.spec.ts | 48 +++++++- src/modules/person/api/person.uc.ts | 67 +++++++++-- .../person/api/personen-query.param.spec.ts | 25 ++++ .../person/api/personen-query.param.ts | 7 +- ...nsatz.ts => personendatensatz.response.ts} | 5 +- .../api/personenkontext-query.params.spec.ts | 30 +++++ .../api/personenkontext-query.params.ts | 49 ++++++++ .../person/api/personenkontext.uc.spec.ts | 49 ++++++++ src/modules/person/api/personenkontext.uc.ts | 24 ++++ .../domain/personenkontext.service.spec.ts | 38 ++++++ .../person/domain/personenkontext.service.ts | 8 ++ .../persistence/personenkontext.repo.spec.ts | 50 ++++++++ .../persistence/personenkontext.repo.ts | 28 +++++ 19 files changed, 643 insertions(+), 94 deletions(-) rename src/modules/person/api/{finde-persondatensatz-dto.ts => find-personendatensatz.dto.ts} (53%) create mode 100644 src/modules/person/api/find-personenkontext.dto.ts create mode 100644 src/modules/person/api/personen-query.param.spec.ts rename src/modules/person/api/{personendatensatz.ts => personendatensatz.response.ts} (72%) create mode 100644 src/modules/person/api/personenkontext-query.params.spec.ts create mode 100644 src/modules/person/api/personenkontext-query.params.ts diff --git a/src/modules/person/api/finde-persondatensatz-dto.ts b/src/modules/person/api/find-personendatensatz.dto.ts similarity index 53% rename from src/modules/person/api/finde-persondatensatz-dto.ts rename to src/modules/person/api/find-personendatensatz.dto.ts index 43733a557..e43b664e9 100644 --- a/src/modules/person/api/finde-persondatensatz-dto.ts +++ b/src/modules/person/api/find-personendatensatz.dto.ts @@ -1,6 +1,7 @@ import { AutoMap } from '@automapper/classes'; +import { SichtfreigabeType } from './personen-query.param.js'; -export class FindPersonDatensatzDTO { +export class FindPersonendatensatzDto { @AutoMap() public referrer?: string; @@ -9,4 +10,7 @@ export class FindPersonDatensatzDTO { @AutoMap() public vorname?: string; + + @AutoMap() + public sichtfreigabe!: SichtfreigabeType; } diff --git a/src/modules/person/api/find-personenkontext.dto.ts b/src/modules/person/api/find-personenkontext.dto.ts new file mode 100644 index 000000000..7590e647e --- /dev/null +++ b/src/modules/person/api/find-personenkontext.dto.ts @@ -0,0 +1,20 @@ +import { AutoMap } from '@automapper/classes'; +import { Rolle, Personenstatus } from '../domain/personenkontext.enums.js'; +import { SichtfreigabeType } from './personen-query.param.js'; + +export class FindPersonenkontextDto { + @AutoMap() + public personId!: string; + + @AutoMap() + public readonly referrer?: string; + + @AutoMap() + public readonly rolle?: Rolle; + + @AutoMap() + public readonly personenstatus?: Personenstatus; + + @AutoMap() + public readonly sichtfreigabe: SichtfreigabeType = SichtfreigabeType.NEIN; +} diff --git a/src/modules/person/api/person-api.mapper.profile.spec.ts b/src/modules/person/api/person-api.mapper.profile.spec.ts index eb598005c..bb1e25cee 100644 --- a/src/modules/person/api/person-api.mapper.profile.spec.ts +++ b/src/modules/person/api/person-api.mapper.profile.spec.ts @@ -22,6 +22,8 @@ import { Jahrgangsstufe, Personenstatus, Rolle } from '../domain/personenkontext import { PersonenkontextDo } from '../domain/personenkontext.do.js'; import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; import { PersonenkontextResponse } from './personenkontext.response.js'; +import { PersonenkontextQueryParams } from './personenkontext-query.params.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; describe('PersonApiMapperProfile', () => { let module: TestingModule; @@ -166,8 +168,8 @@ describe('PersonApiMapperProfile', () => { }); it('should map PersonenkontextDo to CreatedPersonenkontextDto', () => { - const personDo: PersonenkontextDo = DoFactory.createPersonenkontext(true); - expect(() => sut.map(personDo, PersonenkontextDo, CreatedPersonenkontextDto)).not.toThrowError( + const personenkontextDo: PersonenkontextDo = DoFactory.createPersonenkontext(true); + expect(() => sut.map(personenkontextDo, PersonenkontextDo, CreatedPersonenkontextDto)).not.toThrowError( MappingError, ); }); @@ -189,5 +191,35 @@ describe('PersonApiMapperProfile', () => { MappingError, ); }); + + it('should map PersonenkontextQueryParams to FindePersonenkontextDto', () => { + const params: PersonenkontextQueryParams = { + sichtfreigabe: SichtfreigabeType.JA, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + rolle: Rolle.LERNENDER, + }; + expect(() => sut.map(params, PersonenkontextQueryParams, FindPersonenkontextDto)).not.toThrowError( + MappingError, + ); + }); + + it('should map FindePersonenkontextDto to PersonenkontextDo', () => { + const dto: FindPersonenkontextDto = { + personId: faker.string.uuid(), + sichtfreigabe: SichtfreigabeType.JA, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + rolle: Rolle.LERNENDER, + }; + expect(() => sut.map(dto, FindPersonenkontextDto, PersonenkontextDo)).not.toThrowError(MappingError); + }); + + it('should map PersonenkontextDo to PersonenkontextResponse', () => { + const personenkontextDo: PersonenkontextDo = DoFactory.createPersonenkontext(true); + expect(() => sut.map(personenkontextDo, PersonenkontextDo, PersonenkontextResponse)).not.toThrowError( + MappingError, + ); + }); }); }); diff --git a/src/modules/person/api/person-api.mapper.profile.ts b/src/modules/person/api/person-api.mapper.profile.ts index 5e2ed6e90..d002e2973 100644 --- a/src/modules/person/api/person-api.mapper.profile.ts +++ b/src/modules/person/api/person-api.mapper.profile.ts @@ -15,10 +15,10 @@ import { CreatePersonDto } from '../domain/create-person.dto.js'; import { PersonDo } from '../domain/person.do.js'; import { Gender, TrustLevel } from '../domain/person.enums.js'; import { CreatePersonBodyParams } from './create-person.body.params.js'; -import { FindPersonDatensatzDTO } from './finde-persondatensatz-dto.js'; +import { FindPersonendatensatzDto } from './find-personendatensatz.dto.js'; import { PersonGender, PersonTrustLevel } from './person.enums.js'; import { PersonenQueryParam, SichtfreigabeType } from './personen-query.param.js'; -import { PersonenDatensatz } from './personendatensatz.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; import { CreatePersonenkontextBodyParams } from './create-personenkontext.body.params.js'; import { CreatePersonenkontextDto } from './create-personenkontext.dto.js'; import { PersonenkontextDo } from '../domain/personenkontext.do.js'; @@ -26,6 +26,8 @@ import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; import { PersonenkontextResponse } from './personenkontext.response.js'; import { OrganisationDo } from '../../organisation/domain/organisation.do.js'; import { CreatedPersonenkontextOrganisationDto } from './created-personenkontext-organisation.dto.js'; +import { PersonenkontextQueryParams } from './personenkontext-query.params.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; export const personGenderToGenderConverter: Converter = { convert(source: PersonGender): Gender { @@ -146,112 +148,112 @@ export class PersonApiMapperProfile extends AutomapperProfile { createMap( mapper, PersonDo, - PersonenDatensatz, + PersonendatensatzResponse, forMember( - (dest: PersonenDatensatz) => dest.person.id, + (dest: PersonendatensatzResponse) => dest.person.id, mapFrom((src: PersonDo) => src.id), ), forMember( - (dest: PersonenDatensatz) => dest.person.mandant, + (dest: PersonendatensatzResponse) => dest.person.mandant, mapFrom((src: PersonDo) => src.client), ), forMember( - (dest: PersonenDatensatz) => dest.person.referrer, + (dest: PersonendatensatzResponse) => dest.person.referrer, mapFrom((src: PersonDo) => src.referrer), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.vorname, + (dest: PersonendatensatzResponse) => dest.person.name.vorname, mapFrom((src: PersonDo) => src.firstName), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.rufname, + (dest: PersonendatensatzResponse) => dest.person.name.rufname, mapFrom((src: PersonDo) => src.nickName), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.familienname, + (dest: PersonendatensatzResponse) => dest.person.name.familienname, mapFrom((src: PersonDo) => src.lastName), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.initialenvorname, + (dest: PersonendatensatzResponse) => dest.person.name.initialenvorname, mapFrom((src: PersonDo) => src.initialsFirstName), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.initialenfamilienname, + (dest: PersonendatensatzResponse) => dest.person.name.initialenfamilienname, mapFrom((src: PersonDo) => src.initialsLastName), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.sortierindex, + (dest: PersonendatensatzResponse) => dest.person.name.sortierindex, mapFrom((src: PersonDo) => src.nameSortIndex), ), forMember( - (dest: PersonenDatensatz) => dest.person.geburt.datum, + (dest: PersonendatensatzResponse) => dest.person.geburt.datum, mapFrom((src: PersonDo) => src.birthDate), ), forMember( - (dest: PersonenDatensatz) => dest.person.geburt.geburtsort, + (dest: PersonendatensatzResponse) => dest.person.geburt.geburtsort, mapFrom((src: PersonDo) => src.birthPlace), ), forMember( - (dest: PersonenDatensatz) => dest.person.vertrauensstufe, + (dest: PersonendatensatzResponse) => dest.person.vertrauensstufe, mapFrom((src: PersonDo) => src.trustLevel), ), forMember( - (dest: PersonenDatensatz) => dest.person.geschlecht, + (dest: PersonendatensatzResponse) => dest.person.geschlecht, mapFrom((src: PersonDo) => src.gender), ), forMember( - (dest: PersonenDatensatz) => dest.person.lokalisierung, + (dest: PersonendatensatzResponse) => dest.person.lokalisierung, mapFrom((src: PersonDo) => src.localization), ), forMember( - (dest: PersonenDatensatz) => dest.person.stammorganisation, + (dest: PersonendatensatzResponse) => dest.person.stammorganisation, mapFrom((src: PersonDo) => src.mainOrganization), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.anrede, + (dest: PersonendatensatzResponse) => dest.person.name.anrede, mapFrom((src: PersonDo) => src.nameSalutation), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.namenssuffix, + (dest: PersonendatensatzResponse) => dest.person.name.namenssuffix, mapFrom((src: PersonDo) => src.nameSuffix), ), forMember( - (dest: PersonenDatensatz) => dest.person.name.namenspraefix, + (dest: PersonendatensatzResponse) => dest.person.name.namenspraefix, mapFrom((src: PersonDo) => src.namePrefix), ), ); createMap( mapper, PersonenQueryParam, - FindPersonDatensatzDTO, + FindPersonendatensatzDto, forMember( - (dest: FindPersonDatensatzDTO) => dest.vorname, + (dest: FindPersonendatensatzDto) => dest.vorname, mapFrom((src: PersonenQueryParam) => src.vorname), ), forMember( - (dest: FindPersonDatensatzDTO) => dest.familienname, + (dest: FindPersonendatensatzDto) => dest.familienname, mapFrom((src: PersonenQueryParam) => src.familienname), ), forMember( - (dest: FindPersonDatensatzDTO) => dest.referrer, + (dest: FindPersonendatensatzDto) => dest.referrer, mapFrom((src: PersonenQueryParam) => src.referrer), ), ); createMap( mapper, - FindPersonDatensatzDTO, + FindPersonendatensatzDto, PersonDo, forMember( (dest: PersonDo) => dest.lastName, - mapFrom((src: FindPersonDatensatzDTO) => src.familienname), + mapFrom((src: FindPersonendatensatzDto) => src.familienname), ), forMember( (dest: PersonDo) => dest.firstName, - mapFrom((src: FindPersonDatensatzDTO) => src.vorname), + mapFrom((src: FindPersonendatensatzDto) => src.vorname), ), forMember( (dest: PersonDo) => dest.referrer, - mapFrom((src: FindPersonDatensatzDTO) => src.referrer), + mapFrom((src: FindPersonendatensatzDto) => src.referrer), ), forMember((dest: PersonDo) => dest.id, ignore()), forMember((dest: PersonDo) => dest.createdAt, ignore()), @@ -303,6 +305,39 @@ export class PersonApiMapperProfile extends AutomapperProfile { ); createMap(mapper, OrganisationDo, CreatedPersonenkontextOrganisationDto); createMap(mapper, CreatedPersonenkontextDto, PersonenkontextResponse); + + createMap( + mapper, + PersonenkontextQueryParams, + FindPersonenkontextDto, + forMember((dest: FindPersonenkontextDto) => dest.personId, ignore()), + ); + createMap( + mapper, + FindPersonenkontextDto, + PersonenkontextDo, + forMember((dest: PersonenkontextDo) => dest.mandant, ignore()), + forMember((dest: PersonenkontextDo) => dest.organisation, ignore()), + forMember((dest: PersonenkontextDo) => dest.jahrgangsstufe, ignore()), + forMember((dest: PersonenkontextDo) => dest.loeschungZeitpunkt, ignore()), + forMember((dest: PersonenkontextDo) => dest.revision, ignore()), + forMember( + (dest: PersonenkontextDo) => dest.sichtfreigabe, + convertUsing( + personVisibilityToBooleanConverter, + (src: FindPersonenkontextDto) => src.sichtfreigabe, + ), + ), + ); + createMap( + mapper, + PersonenkontextDo, + PersonenkontextResponse, + forMember( + (dest: PersonenkontextResponse) => dest.id, + mapFrom((src: PersonenkontextDo) => src.id), + ), + ); }; } } diff --git a/src/modules/person/api/person.controller.spec.ts b/src/modules/person/api/person.controller.spec.ts index 86263f52c..09de11d23 100644 --- a/src/modules/person/api/person.controller.spec.ts +++ b/src/modules/person/api/person.controller.spec.ts @@ -9,14 +9,16 @@ import { PersonUc } from './person.uc.js'; import { PersonByIdParams } from './person-by-id.param.js'; import { PersonResponse } from './person.response.js'; import { HttpException } from '@nestjs/common'; -import { PersonenQueryParam } from './personen-query.param.js'; +import { PersonenQueryParam, SichtfreigabeType } from './personen-query.param.js'; import { PersonBirthParams } from './person-birth.params.js'; import { TrustLevel } from '../domain/person.enums.js'; -import { PersonenDatensatz } from './personendatensatz.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; import { PersonenkontextUc } from './personenkontext.uc.js'; import { CreatePersonenkontextBodyParams } from './create-personenkontext.body.params.js'; import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; import { Jahrgangsstufe, Personenstatus, Rolle } from '../domain/personenkontext.enums.js'; +import { PersonenkontextResponse } from './personenkontext.response.js'; +import { PersonenkontextQueryParams } from './personenkontext-query.params.js'; describe('PersonController', () => { let module: TestingModule; @@ -107,8 +109,9 @@ describe('PersonController', () => { lokalisierung: faker.location.country(), vertrauensstufe: TrustLevel.TRUSTED, }; - const persondatensatz: PersonenDatensatz = { + const persondatensatz: PersonendatensatzResponse = { person: personResponse, + personenkontexte: [], }; personUcMock.findPersonById.mockResolvedValue(persondatensatz); await expect(personController.findPersonById(params)).resolves.not.toThrow(); @@ -137,6 +140,7 @@ describe('PersonController', () => { referrer: options.referrer, familienname: options.lastName, vorname: options.firstName, + sichtfreigabe: SichtfreigabeType.NEIN, }; it('should get all persons', async () => { @@ -168,15 +172,17 @@ describe('PersonController', () => { vertrauensstufe: TrustLevel.TRUSTED, }; - const mockPersondatensatz1: PersonenDatensatz = { + const mockPersondatensatz1: PersonendatensatzResponse = { person: person1, + personenkontexte: [], }; - const mockPersondatensatz2: PersonenDatensatz = { + const mockPersondatensatz2: PersonendatensatzResponse = { person: person2, + personenkontexte: [], }; - const mockPersondatensatz: PersonenDatensatz[] = [mockPersondatensatz1, mockPersondatensatz2]; + const mockPersondatensatz: PersonendatensatzResponse[] = [mockPersondatensatz1, mockPersondatensatz2]; personUcMock.findAll.mockResolvedValue(mockPersondatensatz); - const result: PersonenDatensatz[] = await personController.findPersons(queryParams); + const result: PersonendatensatzResponse[] = await personController.findPersons(queryParams); expect(personUcMock.findAll).toHaveBeenCalledTimes(1); expect(result.at(0)?.person.referrer).toEqual(queryParams.referrer); expect(result.at(0)?.person.name.vorname).toEqual(queryParams.vorname); @@ -185,33 +191,75 @@ describe('PersonController', () => { }); }); - describe('when creating a personenkontext', () => { - it('should not throw', async () => { - const pathParams: PersonByIdParams = { - personId: faker.string.uuid(), - }; - const body: CreatePersonenkontextBodyParams = { - rolle: Rolle.LEHRENDER, - jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1, - personenstatus: Personenstatus.AKTIV, - referrer: 'referrer', - }; - const ucResult: CreatedPersonenkontextDto = { - id: faker.string.uuid(), - mandant: faker.string.uuid(), - organisation: { + describe('createPersonenkontext', () => { + describe('when creating a personenkontext', () => { + it('should not throw', async () => { + const pathParams: PersonByIdParams = { + personId: faker.string.uuid(), + }; + const body: CreatePersonenkontextBodyParams = { + rolle: Rolle.LEHRENDER, + jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + }; + const ucResult: CreatedPersonenkontextDto = { id: faker.string.uuid(), - }, - revision: '1', - rolle: Rolle.LEHRENDER, - jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1, - personenstatus: Personenstatus.AKTIV, - referrer: 'referrer', - }; - personenkontextUcMock.createPersonenkontext.mockResolvedValue(ucResult); + mandant: faker.string.uuid(), + organisation: { + id: faker.string.uuid(), + }, + revision: '1', + rolle: Rolle.LEHRENDER, + jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + }; + personenkontextUcMock.createPersonenkontext.mockResolvedValue(ucResult); + + await expect(personController.createPersonenkontext(pathParams, body)).resolves.not.toThrow(); + expect(personenkontextUcMock.createPersonenkontext).toHaveBeenCalledTimes(1); + }); + }); + }); + + describe('findPersonenkontexte', () => { + describe('When fetching personenkontexte is successful', () => { + it('should get all personenkontexte', async () => { + const pathParams: PersonByIdParams = { + personId: faker.string.uuid(), + }; + const queryParams: PersonenkontextQueryParams = { + referrer: 'referrer', + sichtfreigabe: SichtfreigabeType.NEIN, + personenstatus: Personenstatus.AKTIV, + rolle: Rolle.LERNENDER, + }; + + const personenkontextResponse: PersonenkontextResponse = { + id: faker.string.uuid(), + organisation: { + id: faker.string.uuid(), + }, + revision: '1', + mandant: faker.string.uuid(), + rolle: Rolle.LERNENDER, + referrer: 'referrer', + jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1, + personenstatus: Personenstatus.AKTIV, + }; + const personenkontextResponseArray: PersonenkontextResponse[] = [personenkontextResponse]; + personenkontextUcMock.findAll.mockResolvedValue(personenkontextResponseArray); + + const result: PersonenkontextResponse[] = await personController.findPersonenkontexte( + pathParams, + queryParams, + ); - await expect(personController.createPersonenkontext(pathParams, body)).resolves.not.toThrow(); - expect(personenkontextUcMock.createPersonenkontext).toHaveBeenCalledTimes(1); + expect(personenkontextUcMock.findAll).toHaveBeenCalledTimes(1); + expect(result.length).toBe(1); + expect(result[0]?.id).toBe(personenkontextResponseArray[0]?.id); + }); }); }); }); diff --git a/src/modules/person/api/person.controller.ts b/src/modules/person/api/person.controller.ts index 82df5fabe..ae3edf016 100644 --- a/src/modules/person/api/person.controller.ts +++ b/src/modules/person/api/person.controller.ts @@ -16,13 +16,15 @@ import { CreatePersonBodyParams } from './create-person.body.params.js'; import { CreatePersonDto } from '../domain/create-person.dto.js'; import { PersonByIdParams } from './person-by-id.param.js'; import { PersonenQueryParam } from './personen-query.param.js'; -import { FindPersonDatensatzDTO } from './finde-persondatensatz-dto.js'; -import { PersonenDatensatz } from './personendatensatz.js'; +import { FindPersonendatensatzDto } from './find-personendatensatz.dto.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; import { CreatePersonenkontextBodyParams } from './create-personenkontext.body.params.js'; import { CreatePersonenkontextDto } from './create-personenkontext.dto.js'; import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; import { PersonenkontextResponse } from './personenkontext.response.js'; import { PersonenkontextUc } from './personenkontext.uc.js'; +import { PersonenkontextQueryParams } from './personenkontext-query.params.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; @ApiTags('person') @Controller({ path: 'person' }) @@ -51,9 +53,9 @@ export class PersonController { @ApiNotFoundResponse({ description: 'The person does not exist.' }) @ApiForbiddenResponse({ description: 'Insufficient permissions to get the person.' }) @ApiInternalServerErrorResponse({ description: 'Internal server error while getting the person.' }) - public async findPersonById(@Param() params: PersonByIdParams): Promise { + public async findPersonById(@Param() params: PersonByIdParams): Promise { try { - const person: PersonenDatensatz = await this.personUc.findPersonById(params.personId); + const person: PersonendatensatzResponse = await this.personUc.findPersonById(params.personId); return person; } catch (error) { throw new HttpException('Requested entity does not exist', HttpStatus.NOT_FOUND); @@ -84,18 +86,42 @@ export class PersonController { return this.mapper.map(createdPersonenkontext, CreatedPersonenkontextDto, PersonenkontextResponse); } + @Get(':personId/personenkontexte') + @ApiOkResponse({ description: 'The personenkontexte were successfully pulled.' }) + @ApiUnauthorizedResponse({ description: 'Not authorized to get personenkontexte.' }) + @ApiForbiddenResponse({ description: 'Insufficient permissions to get personenkontexte.' }) + @ApiNotFoundResponse({ description: 'No personenkontexte were found.' }) + @ApiInternalServerErrorResponse({ description: 'Internal server error while getting all personenkontexte.' }) + public async findPersonenkontexte( + @Param() pathParams: PersonByIdParams, + @Query() queryParams: PersonenkontextQueryParams, + ): Promise { + const findePersonenkontextDto: FindPersonenkontextDto = this.mapper.map( + queryParams, + PersonenkontextQueryParams, + FindPersonenkontextDto, + ); + findePersonenkontextDto.personId = pathParams.personId; + + const personenkontexte: PersonenkontextResponse[] = await this.personenkontextUc.findAll( + findePersonenkontextDto, + ); + + return personenkontexte; + } + @Get() @ApiCreatedResponse({ description: 'The persons were successfully pulled.' }) @ApiUnauthorizedResponse({ description: 'Not authorized to get persons.' }) @ApiForbiddenResponse({ description: 'Insufficient permissions to get persons.' }) @ApiInternalServerErrorResponse({ description: 'Internal server error while getting all persons.' }) - public async findPersons(@Query() queryParams: PersonenQueryParam): Promise { - const persondatensatzDTO: FindPersonDatensatzDTO = this.mapper.map( + public async findPersons(@Query() queryParams: PersonenQueryParam): Promise { + const personendatensatzDto: FindPersonendatensatzDto = this.mapper.map( queryParams, PersonenQueryParam, - FindPersonDatensatzDTO, + FindPersonendatensatzDto, ); - const persons: PersonenDatensatz[] = await this.personUc.findAll(persondatensatzDTO); + const persons: PersonendatensatzResponse[] = await this.personUc.findAll(personendatensatzDto); return persons; } } diff --git a/src/modules/person/api/person.uc.spec.ts b/src/modules/person/api/person.uc.spec.ts index dda267ad6..18063f3ee 100644 --- a/src/modules/person/api/person.uc.spec.ts +++ b/src/modules/person/api/person.uc.spec.ts @@ -6,16 +6,19 @@ import { CreatePersonDto } from '../domain/create-person.dto.js'; import { PersonService } from '../domain/person.service.js'; import { PersonApiMapperProfile } from './person-api.mapper.profile.js'; import { PersonUc } from './person.uc.js'; -import { FindPersonDatensatzDTO } from './finde-persondatensatz-dto.js'; +import { FindPersonendatensatzDto } from './find-personendatensatz.dto.js'; import { faker } from '@faker-js/faker'; import { PersonDo } from '../domain/person.do.js'; -import { PersonenDatensatz } from './personendatensatz.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; import { KeycloakUserService } from '../../keycloak-administration/index.js'; +import { SichtfreigabeType } from './personen-query.param.js'; +import { PersonenkontextService } from '../domain/personenkontext.service.js'; describe('PersonUc', () => { let module: TestingModule; let personUc: PersonUc; let personServiceMock: DeepMocked; + let personenkontextServiceMock: DeepMocked; let userServiceMock: DeepMocked; beforeAll(async () => { @@ -28,6 +31,10 @@ describe('PersonUc', () => { provide: PersonService, useValue: createMock(), }, + { + provide: PersonenkontextService, + useValue: createMock(), + }, { provide: KeycloakUserService, useValue: createMock(), @@ -36,6 +43,7 @@ describe('PersonUc', () => { }).compile(); personUc = module.get(PersonUc); personServiceMock = module.get(PersonService); + personenkontextServiceMock = module.get(PersonenkontextService); userServiceMock = module.get(KeycloakUserService); }); @@ -120,7 +128,13 @@ describe('PersonUc', () => { ok: true, value: DoFactory.createPerson(true), }); + + personenkontextServiceMock.findAllPersonenkontexte.mockResolvedValue({ + ok: true, + value: [DoFactory.createPersonenkontext(true)], + }); await expect(personUc.findPersonById(id)).resolves.not.toThrow(); + expect(personenkontextServiceMock.findAllPersonenkontexte).toHaveBeenCalledTimes(1); }); }); @@ -133,13 +147,30 @@ describe('PersonUc', () => { await expect(personUc.findPersonById(id)).rejects.toThrowError(EntityNotFoundError); }); }); + + describe('When no personenkontexte are found', () => { + it('should not throw', async () => { + personServiceMock.findPersonById.mockResolvedValue({ + ok: true, + value: DoFactory.createPerson(true), + }); + + personenkontextServiceMock.findAllPersonenkontexte.mockResolvedValue({ + ok: false, + error: new EntityNotFoundError('Personenkontext'), + }); + await expect(personUc.findPersonById(id)).resolves.not.toThrow(); + expect(personenkontextServiceMock.findAllPersonenkontexte).toHaveBeenCalledTimes(1); + }); + }); }); describe('findAll', () => { - const personDTO: FindPersonDatensatzDTO = { + const personDTO: FindPersonendatensatzDto = { referrer: '', familienname: '', vorname: '', + sichtfreigabe: SichtfreigabeType.NEIN, }; it('should find all persons that match with query param', async () => { @@ -147,7 +178,14 @@ describe('PersonUc', () => { const secondPerson: PersonDo = DoFactory.createPerson(true); const persons: PersonDo[] = [firstPerson, secondPerson]; personServiceMock.findAllPersons.mockResolvedValue(persons); - const result: PersonenDatensatz[] = await personUc.findAll(personDTO); + personenkontextServiceMock.findAllPersonenkontexte.mockResolvedValue({ + ok: true, + value: [DoFactory.createPersonenkontext(true)], + }); + const result: PersonendatensatzResponse[] = await personUc.findAll(personDTO); + + expect(personenkontextServiceMock.findAllPersonenkontexte).toHaveBeenCalledTimes(2); + expect(result).toHaveLength(2); expect(result.at(0)?.person.name.vorname).toEqual(firstPerson.firstName); expect(result.at(0)?.person.name.familienname).toEqual(firstPerson.lastName); @@ -158,7 +196,7 @@ describe('PersonUc', () => { it('should return an empty array when no matching persons are found', async () => { const emptyResult: PersonDo[] = []; personServiceMock.findAllPersons.mockResolvedValue(emptyResult); - const result: PersonenDatensatz[] = await personUc.findAll(personDTO); + const result: PersonendatensatzResponse[] = await personUc.findAll(personDTO); expect(result).toEqual([]); }); }); diff --git a/src/modules/person/api/person.uc.ts b/src/modules/person/api/person.uc.ts index cc914b862..cd54c3cd5 100644 --- a/src/modules/person/api/person.uc.ts +++ b/src/modules/person/api/person.uc.ts @@ -5,13 +5,20 @@ import { KeycloakUserService, UserDo } from '../../keycloak-administration/index import { CreatePersonDto } from '../domain/create-person.dto.js'; import { PersonService } from '../domain/person.service.js'; import { PersonDo } from '../domain/person.do.js'; -import { FindPersonDatensatzDTO } from './finde-persondatensatz-dto.js'; -import { PersonenDatensatz } from './personendatensatz.js'; +import { FindPersonendatensatzDto } from './find-personendatensatz.dto.js'; +import { PersonendatensatzResponse } from './personendatensatz.response.js'; +import { PersonenkontextService } from '../domain/personenkontext.service.js'; +import { SichtfreigabeType } from './personen-query.param.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; +import { PersonenkontextDo } from '../domain/personenkontext.do.js'; +import { PersonenkontextResponse } from './personenkontext.response.js'; +import { DomainError } from '../../../shared/error/domain.error.js'; @Injectable() export class PersonUc { public constructor( private readonly personService: PersonService, + private readonly personenkontextService: PersonenkontextService, private readonly userService: KeycloakUserService, @Inject(getMapperToken()) private readonly mapper: Mapper, ) {} @@ -42,24 +49,62 @@ export class PersonUc { } } - public async findPersonById(id: string): Promise { + public async findPersonById(id: string): Promise { const result: Result> = await this.personService.findPersonById(id); if (result.ok) { - const person: PersonenDatensatz = this.mapper.map(result.value, PersonDo, PersonenDatensatz); + const person: PersonendatensatzResponse = this.mapper.map( + result.value, + PersonDo, + PersonendatensatzResponse, + ); + person.personenkontexte = await this.findPersonenkontexteForPerson(id, SichtfreigabeType.NEIN); + return person; } throw result.error; } - public async findAll(personDto: FindPersonDatensatzDTO): Promise { - const personDo: PersonDo = this.mapper.map(personDto, FindPersonDatensatzDTO, PersonDo); + public async findAll(personDto: FindPersonendatensatzDto): Promise { + const personDo: PersonDo = this.mapper.map(personDto, FindPersonendatensatzDto, PersonDo); const result: PersonDo[] = await this.personService.findAllPersons(personDo); - if (result.length !== 0) { - const persons: PersonenDatensatz[] = result.map((person: PersonDo) => - this.mapper.map(person, PersonDo, PersonenDatensatz), + if (result.length === 0) { + return []; + } + const persons: PersonendatensatzResponse[] = result.map((person: PersonDo) => + this.mapper.map(person, PersonDo, PersonendatensatzResponse), + ); + + for (const person of persons) { + person.personenkontexte = await this.findPersonenkontexteForPerson( + person.person.id, + personDto.sichtfreigabe, ); - return persons; } - return []; + return persons; + } + + private async findPersonenkontexteForPerson( + personId: string, + sichtfreigabe: SichtfreigabeType, + ): Promise { + const personenkontextFilter: FindPersonenkontextDto = { + personId: personId, + sichtfreigabe: sichtfreigabe, + }; + + const result: Result[], DomainError> = + await this.personenkontextService.findAllPersonenkontexte( + this.mapper.map(personenkontextFilter, FindPersonenkontextDto, PersonenkontextDo), + ); + + if (!result.ok) { + return []; + } + + const personenkontextResponses: PersonenkontextResponse[] = result.value.map( + (personenkontext: PersonenkontextDo) => + this.mapper.map(personenkontext, PersonenkontextDo, PersonenkontextResponse), + ); + return personenkontextResponses; } } diff --git a/src/modules/person/api/personen-query.param.spec.ts b/src/modules/person/api/personen-query.param.spec.ts new file mode 100644 index 000000000..65659e4d5 --- /dev/null +++ b/src/modules/person/api/personen-query.param.spec.ts @@ -0,0 +1,25 @@ +import { plainToInstance } from 'class-transformer'; +import 'reflect-metadata'; +import { PersonenQueryParam, SichtfreigabeType } from './personen-query.param.js'; +import { faker } from '@faker-js/faker'; + +describe('PersonenQueryParam', () => { + const referenceParams: PersonenQueryParam = { + sichtfreigabe: SichtfreigabeType.JA, + familienname: faker.person.lastName(), + referrer: 'referrer', + vorname: faker.person.firstName(), + }; + + it('should convert a plain object to a class of PersonenQueryParam', () => { + const incomingParams: object = { + sichtfreigabe: referenceParams.sichtfreigabe, + familienname: referenceParams.familienname, + referrer: referenceParams.referrer, + vorname: referenceParams.vorname, + }; + const mappedParams: PersonenQueryParam = plainToInstance(PersonenQueryParam, incomingParams, {}); + expect(mappedParams).toBeInstanceOf(PersonenQueryParam); + expect(mappedParams).toEqual(referenceParams); + }); +}); diff --git a/src/modules/person/api/personen-query.param.ts b/src/modules/person/api/personen-query.param.ts index 7071025c9..203e44473 100644 --- a/src/modules/person/api/personen-query.param.ts +++ b/src/modules/person/api/personen-query.param.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { Expose } from 'class-transformer'; -import { IsOptional, IsString } from 'class-validator'; +import { IsEnum, IsOptional, IsString } from 'class-validator'; import { AutoMap } from '@automapper/classes'; export enum SichtfreigabeType { @@ -40,8 +40,7 @@ export class PersonenQueryParam { }) public readonly vorname?: string; - // this property would be needed for person context. - /* @AutoMap() + @AutoMap() @IsOptional() @IsEnum(SichtfreigabeType) @Expose({ name: 'sichtfreigabe' }) @@ -52,5 +51,5 @@ export class PersonenQueryParam { required: false, nullable: true, }) - public readonly sichtfreigabe: SichtfreigabeType = SichtfreigabeType.NEIN;*/ + public readonly sichtfreigabe: SichtfreigabeType = SichtfreigabeType.NEIN; } diff --git a/src/modules/person/api/personendatensatz.ts b/src/modules/person/api/personendatensatz.response.ts similarity index 72% rename from src/modules/person/api/personendatensatz.ts rename to src/modules/person/api/personendatensatz.response.ts index fccf386f0..6e671bada 100644 --- a/src/modules/person/api/personendatensatz.ts +++ b/src/modules/person/api/personendatensatz.response.ts @@ -3,13 +3,14 @@ import { Type } from 'class-transformer'; import { ApiProperty } from '@nestjs/swagger'; import { ValidateNested } from 'class-validator'; import { PersonResponse } from './person.response.js'; +import { PersonenkontextResponse } from './personenkontext.response.js'; -export class PersonenDatensatz { +export class PersonendatensatzResponse { @AutoMap(() => PersonResponse) @ValidateNested() @Type(() => PersonResponse) @ApiProperty({ name: 'person', type: PersonResponse, required: true }) public person!: PersonResponse; - // personKontext wird spaeter hier hinzugefuegt. + public personenkontexte!: PersonenkontextResponse[]; } diff --git a/src/modules/person/api/personenkontext-query.params.spec.ts b/src/modules/person/api/personenkontext-query.params.spec.ts new file mode 100644 index 000000000..14ca3b8c5 --- /dev/null +++ b/src/modules/person/api/personenkontext-query.params.spec.ts @@ -0,0 +1,30 @@ +import { plainToInstance } from 'class-transformer'; +import 'reflect-metadata'; +import { PersonenkontextQueryParams } from './personenkontext-query.params.js'; +import { SichtfreigabeType } from './personen-query.param.js'; +import { Personenstatus, Rolle } from '../domain/personenkontext.enums.js'; + +describe('PersonenkontextQueryParams', () => { + const referenceParams: PersonenkontextQueryParams = { + sichtfreigabe: SichtfreigabeType.JA, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + rolle: Rolle.LERNENDER, + }; + + it('should convert a plain object to a class of PersonenkontextQueryParams', () => { + const incomingParams: object = { + sichtfreigabe: SichtfreigabeType.JA, + personenstatus: Personenstatus.AKTIV, + referrer: 'referrer', + rolle: Rolle.LERNENDER, + }; + const mappedParams: PersonenkontextQueryParams = plainToInstance( + PersonenkontextQueryParams, + incomingParams, + {}, + ); + expect(mappedParams).toBeInstanceOf(PersonenkontextQueryParams); + expect(mappedParams).toEqual(referenceParams); + }); +}); diff --git a/src/modules/person/api/personenkontext-query.params.ts b/src/modules/person/api/personenkontext-query.params.ts new file mode 100644 index 000000000..59c256526 --- /dev/null +++ b/src/modules/person/api/personenkontext-query.params.ts @@ -0,0 +1,49 @@ +import { AutoMap } from '@automapper/classes'; +import { ApiProperty } from '@nestjs/swagger'; +import { IsEnum, IsOptional, IsString } from 'class-validator'; +import { Personenstatus, Rolle } from '../domain/personenkontext.enums.js'; +import { SichtfreigabeType } from './personen-query.param.js'; + +export class PersonenkontextQueryParams { + @AutoMap() + @IsOptional() + @IsString() + @ApiProperty({ + name: 'referrer', + required: false, + nullable: true, + }) + public readonly referrer?: string; + + @AutoMap() + @IsOptional() + @IsEnum(Rolle) + @ApiProperty({ + name: 'rolle', + required: false, + nullable: true, + }) + public readonly rolle?: Rolle; + + @AutoMap() + @IsOptional() + @IsEnum(Personenstatus) + @ApiProperty({ + name: 'personenstatus', + required: false, + nullable: true, + }) + public readonly personenstatus?: Personenstatus; + + @AutoMap() + @IsOptional() + @IsEnum(SichtfreigabeType) + @ApiProperty({ + name: 'sichtfreigabe', + enum: SichtfreigabeType, + default: SichtfreigabeType.NEIN, + required: false, + nullable: true, + }) + public readonly sichtfreigabe: SichtfreigabeType = SichtfreigabeType.NEIN; +} diff --git a/src/modules/person/api/personenkontext.uc.spec.ts b/src/modules/person/api/personenkontext.uc.spec.ts index 8fa40b7f8..b6d42fcda 100644 --- a/src/modules/person/api/personenkontext.uc.spec.ts +++ b/src/modules/person/api/personenkontext.uc.spec.ts @@ -8,6 +8,13 @@ import { PersonApiMapperProfile } from './person-api.mapper.profile.js'; import { PersonenkontextUc } from './personenkontext.uc.js'; import { EntityCouldNotBeCreated } from '../../../shared/error/entity-could-not-be-created.error.js'; import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; +import { SichtfreigabeType } from './personen-query.param.js'; +import { Personenstatus, Rolle } from '../domain/personenkontext.enums.js'; +import { PersonenkontextResponse } from './personenkontext.response.js'; +import { faker } from '@faker-js/faker'; +import { DomainError } from '../../../shared/error/domain.error.js'; +import { EntityNotFoundError } from '../../../shared/error/entity-not-found.error.js'; describe('PersonenkontextUc', () => { let module: TestingModule; @@ -75,4 +82,46 @@ describe('PersonenkontextUc', () => { }); }); }); + + describe('findAll', () => { + describe('When searching for personenkontexte', () => { + it('should find all persons that match with query param', async () => { + const findPersonenkontextDto: FindPersonenkontextDto = { + personId: faker.string.uuid(), + referrer: 'referrer', + sichtfreigabe: SichtfreigabeType.NEIN, + personenstatus: Personenstatus.AKTIV, + rolle: Rolle.LERNENDER, + }; + + const firstPersonenkontext: PersonenkontextDo = DoFactory.createPersonenkontext(true); + const secondPersonenkontext: PersonenkontextDo = DoFactory.createPersonenkontext(true); + const personenkontexte: PersonenkontextDo[] = [firstPersonenkontext, secondPersonenkontext]; + personenkontextServiceMock.findAllPersonenkontexte.mockResolvedValue({ + ok: true, + value: personenkontexte, + }); + + const result: PersonenkontextResponse[] = await personenkontextUc.findAll(findPersonenkontextDto); + expect(result).toHaveLength(2); + }); + + it('should throw EntityNotFoundError when no matching persons are found', async () => { + const findPersonenkontextDto: FindPersonenkontextDto = { + personId: faker.string.uuid(), + referrer: 'referrer', + sichtfreigabe: SichtfreigabeType.NEIN, + personenstatus: Personenstatus.AKTIV, + rolle: Rolle.LERNENDER, + }; + + const emptyResult: Result[], DomainError> = { + ok: false, + error: new EntityNotFoundError('Personenkontext'), + }; + personenkontextServiceMock.findAllPersonenkontexte.mockResolvedValue(emptyResult); + await expect(personenkontextUc.findAll(findPersonenkontextDto)).rejects.toThrow(EntityNotFoundError); + }); + }); + }); }); diff --git a/src/modules/person/api/personenkontext.uc.ts b/src/modules/person/api/personenkontext.uc.ts index 5c3da4460..f49e03cc5 100644 --- a/src/modules/person/api/personenkontext.uc.ts +++ b/src/modules/person/api/personenkontext.uc.ts @@ -1,10 +1,13 @@ import { Mapper } from '@automapper/core'; import { getMapperToken } from '@automapper/nestjs'; import { Inject, Injectable } from '@nestjs/common'; +import { DomainError } from '../../../shared/error/domain.error.js'; import { PersonenkontextDo } from '../domain/personenkontext.do.js'; import { PersonenkontextService } from '../domain/personenkontext.service.js'; import { CreatePersonenkontextDto } from './create-personenkontext.dto.js'; import { CreatedPersonenkontextDto } from './created-personenkontext.dto.js'; +import { FindPersonenkontextDto } from './find-personenkontext.dto.js'; +import { PersonenkontextResponse } from './personenkontext.response.js'; @Injectable() export class PersonenkontextUc { @@ -29,4 +32,25 @@ export class PersonenkontextUc { } throw result.error; } + + // TODO refactor after EW-561 is done + public async findAll(findePersonenkontextDto: FindPersonenkontextDto): Promise { + const personenkontextDo: PersonenkontextDo = this.mapper.map( + findePersonenkontextDto, + FindPersonenkontextDto, + PersonenkontextDo, + ); + const result: Result[], DomainError> = + await this.personenkontextService.findAllPersonenkontexte(personenkontextDo); + + if (!result.ok) { + throw result.error; + } + + const personenkontexte: PersonenkontextResponse[] = result.value.map( + (personenkontext: PersonenkontextDo) => + this.mapper.map(personenkontext, PersonenkontextDo, PersonenkontextResponse), + ); + return personenkontexte; + } } diff --git a/src/modules/person/domain/personenkontext.service.spec.ts b/src/modules/person/domain/personenkontext.service.spec.ts index 5e8a8d115..48452e1c7 100644 --- a/src/modules/person/domain/personenkontext.service.spec.ts +++ b/src/modules/person/domain/personenkontext.service.spec.ts @@ -109,4 +109,42 @@ describe('PersonenkontextService', () => { }); }); }); + + describe('findAllPersonenkontexte', () => { + describe('When personenkontexte are found', () => { + it('should get all personenkontexte that match', async () => { + const personenkontext1: PersonenkontextDo = DoFactory.createPersonenkontext(false); + const personenkontext2: PersonenkontextDo = DoFactory.createPersonenkontext(false); + const personenkontexte: PersonenkontextDo[] = [ + personenkontext1 as unknown as PersonenkontextDo, + personenkontext2 as unknown as PersonenkontextDo, + ]; + personenkontextRepoMock.findAll.mockResolvedValue(personenkontexte); + mapperMock.map.mockReturnValue(personenkontexte as unknown as Dictionary); + const personenkontextDoWithQueryParam: PersonenkontextDo = + DoFactory.createPersonenkontext(false); + + const result: Result[], DomainError> = + await personenkontextService.findAllPersonenkontexte(personenkontextDoWithQueryParam); + expect(result).toEqual[], DomainError>>({ + ok: true, + value: personenkontexte, + }); + }); + }); + + describe('When no personenkontexte are found', () => { + it('should return a result with an empty array', async () => { + const personenkontext: PersonenkontextDo = DoFactory.createPersonenkontext(false); + personenkontextRepoMock.findAll.mockResolvedValue([]); + mapperMock.map.mockReturnValue(personenkontext as unknown as Dictionary); + const result: Result[], DomainError> = + await personenkontextService.findAllPersonenkontexte(personenkontext); + expect(result).toEqual[], DomainError>>({ + ok: true, + value: [], + }); + }); + }); + }); }); diff --git a/src/modules/person/domain/personenkontext.service.ts b/src/modules/person/domain/personenkontext.service.ts index 1bbab51f1..af868d73c 100644 --- a/src/modules/person/domain/personenkontext.service.ts +++ b/src/modules/person/domain/personenkontext.service.ts @@ -27,4 +27,12 @@ export class PersonenkontextService { } return { ok: false, error: new EntityCouldNotBeCreated(`Personenkontext`) }; } + + public async findAllPersonenkontexte( + personenkontextDo: PersonenkontextDo, + ): Promise[], DomainError>> { + const personenkontexte: PersonenkontextDo[] = await this.personenkontextRepo.findAll(personenkontextDo); + + return { ok: true, value: personenkontexte }; + } } diff --git a/src/modules/person/persistence/personenkontext.repo.spec.ts b/src/modules/person/persistence/personenkontext.repo.spec.ts index ba734fff2..3a469bf1d 100644 --- a/src/modules/person/persistence/personenkontext.repo.spec.ts +++ b/src/modules/person/persistence/personenkontext.repo.spec.ts @@ -9,6 +9,8 @@ import { PersonPersistenceMapperProfile } from './person-persistence.mapper.prof import { PersonEntity } from './person.entity.js'; import { PersonenkontextEntity } from './personenkontext.entity.js'; import { PersonenkontextRepo } from './personenkontext.repo.js'; +import { Personenstatus, Rolle } from '../domain/personenkontext.enums.js'; +import { faker } from '@faker-js/faker'; describe('PersonenkontextRepo', () => { let module: TestingModule; @@ -102,4 +104,52 @@ describe('PersonenkontextRepo', () => { }); }); }); + + describe('findAll', () => { + describe('When personenkontext for person exists', () => { + it('should find all personenkontexte for this person', async () => { + const props: Partial> = { + referrer: 'referrer', + personenstatus: Personenstatus.AKTIV, + rolle: Rolle.LERNENDER, + sichtfreigabe: false, + }; + const person1Id: string = faker.string.uuid(); + const personenkontextDo1: PersonenkontextDo = DoFactory.createPersonenkontext(false, { + ...props, + personId: person1Id, + }); + const personenkontextDo2: PersonenkontextDo = DoFactory.createPersonenkontext(false, props); + await em.persistAndFlush(mapper.map(personenkontextDo1, PersonenkontextDo, PersonenkontextEntity)); + await em.persistAndFlush(mapper.map(personenkontextDo2, PersonenkontextDo, PersonenkontextEntity)); + + const personenkontextDoFromQueryParam: PersonenkontextDo = DoFactory.createPersonenkontext( + false, + { + ...props, + personId: person1Id, + }, + ); + + const result: PersonenkontextDo[] = await sut.findAll(personenkontextDoFromQueryParam); + expect(result).not.toBeNull(); + expect(result).toHaveLength(1); + await expect(em.find(PersonenkontextEntity, {})).resolves.toHaveLength(2); + }); + }); + + describe('When no personenkontext matches', () => { + it('should return an empty list', async () => { + const props: Partial> = {}; + const personenkontextDoFromQueryParam: PersonenkontextDo = DoFactory.createPersonenkontext( + false, + props, + ); + const result: PersonenkontextDo[] = await sut.findAll(personenkontextDoFromQueryParam); + expect(result).not.toBeNull(); + expect(result).toHaveLength(0); + await expect(em.find(PersonenkontextEntity, {})).resolves.toHaveLength(0); + }); + }); + }); }); diff --git a/src/modules/person/persistence/personenkontext.repo.ts b/src/modules/person/persistence/personenkontext.repo.ts index 002dacf04..4d1aa5ea1 100644 --- a/src/modules/person/persistence/personenkontext.repo.ts +++ b/src/modules/person/persistence/personenkontext.repo.ts @@ -17,6 +17,34 @@ export class PersonenkontextRepo { return this.create(personenkontextDo); } + // TODO refactor after EW-561 is done, use Scope + public async findAll(personenkontextDo: PersonenkontextDo): Promise[]> { + const query: Record = {}; + + query['personId'] = personenkontextDo.personId; + + if (personenkontextDo.referrer) { + query['referrer'] = personenkontextDo.referrer; + } + + if (personenkontextDo.rolle) { + query['rolle'] = personenkontextDo.rolle; + } + + if (personenkontextDo.personenstatus) { + query['personenstatus'] = personenkontextDo.personenstatus; + } + + if (personenkontextDo.sichtfreigabe !== undefined) { + query['sichtfreigabe'] = personenkontextDo.sichtfreigabe; + } + + const result: PersonenkontextEntity[] = await this.em.find(PersonenkontextEntity, query); + return result.map((person: PersonenkontextEntity) => + this.mapper.map(person, PersonenkontextEntity, PersonenkontextDo), + ); + } + private async create(personenkontextDo: PersonenkontextDo): Promise>> { const personenkontext: PersonenkontextEntity = this.mapper.map( personenkontextDo,