Skip to content

Commit

Permalink
Add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkreuzkam-cap committed Nov 16, 2023
1 parent d9f5be1 commit e20cc6c
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 8 deletions.
37 changes: 37 additions & 0 deletions src/modules/person/api/personenkontext.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { PersonenkontextController } from './personenkontext.controller.js';
import { PersonenkontextDto } from './personenkontext.dto.js';
import { PersonenkontextUc } from './personenkontext.uc.js';
import { PersonenkontextdatensatzResponse } from './personenkontextdatensatz.response.js';
import { UpdatePersonenkontextBodyParams } from './update-personenkontext.body.params.js';
import { PersonenkontextResponse } from './personenkontext.response.js';

describe('PersonenkontextController', () => {
let module: TestingModule;
Expand Down Expand Up @@ -138,4 +140,39 @@ describe('PersonenkontextController', () => {
});
});
});

describe('updatePersonenkontextWithId', () => {
describe('when updating a personenkontext', () => {
it('should return PersonenkontextResponse', async () => {
const idParams: FindPersonenkontextByIdParams = {
personenkontextId: faker.string.uuid(),
};
const bodyParams: UpdatePersonenkontextBodyParams = {
referrer: 'referrer',
personenstatus: Personenstatus.AKTIV,
jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1,
revision: '1',
};
const mockResonse: PersonenkontextResponse = {
id: faker.string.uuid(),
personenstatus: Personenstatus.AKTIV,
jahrgangsstufe: Jahrgangsstufe.JAHRGANGSSTUFE_1,
referrer: 'referrer',
revision: '1',
organisation: {
id: faker.string.uuid(),
},
mandant: faker.string.uuid(),
rolle: Rolle.LERNENDER,
};

personenkontextUcMock.updatePersonenkontext.mockResolvedValue(mockResonse);

const response: PersonenkontextResponse = await sut.updatePersonenkontextWithId(idParams, bodyParams);

expect(response).toBeInstanceOf(PersonenkontextResponse);
expect(personenkontextUcMock.updatePersonenkontext).toHaveBeenCalledTimes(1);
});
});
});
});
35 changes: 35 additions & 0 deletions src/modules/person/api/personenkontext.uc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,39 @@ describe('PersonenkontextUc', () => {
});
});
});

describe('updatePersonenkontext', () => {
// AI next 30 lines
describe('when updating personenkontext is successful', () => {
it('should not throw', async () => {
const personenkontextDo: PersonenkontextDo<true> = DoFactory.createPersonenkontext(true);
personenkontextServiceMock.updatePersonenkontext.mockResolvedValue({
ok: true,
value: personenkontextDo,
});

const updatePersonPromise: Promise<SavedPersonenkontextDto> = sut.updatePersonenkontext(
{} as PersonenkontextDto,
);

await expect(updatePersonPromise).resolves.not.toThrow();
});
});

describe('when updating personenkontext is not successful', () => {
it('should throw Error', async () => {
const error: EntityCouldNotBeCreated = new EntityCouldNotBeCreated('Personenkontext');
personenkontextServiceMock.updatePersonenkontext.mockResolvedValue({
ok: false,
error: error,
});

const updatePersonPromise: Promise<SavedPersonenkontextDto> = sut.updatePersonenkontext(
{} as PersonenkontextDto,
);

await expect(updatePersonPromise).rejects.toThrow(error);
});
});
});
});
91 changes: 91 additions & 0 deletions src/modules/person/domain/personenkontext.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { PersonenkontextRepo } from '../persistence/personenkontext.repo.js';
import { PersonDo } from './person.do.js';
import { PersonenkontextDo } from './personenkontext.do.js';
import { PersonenkontextService } from './personenkontext.service.js';
import { MismatchedRevisionError } from '../../../shared/error/mismatched-revision.error.js';
import { EntityCouldNotBeUpdated } from '../../../shared/error/entity-could-not-be-updated.error.js';

describe('PersonenkontextService', () => {
let module: TestingModule;
Expand Down Expand Up @@ -190,4 +192,93 @@ describe('PersonenkontextService', () => {
});
});
});

describe('updatePersonenkontext', () => {
describe('when personenkontext is updated successfully', () => {
it('should return updated personenkontext', async () => {
// AI next 19 lines
const personenkontextDo: PersonenkontextDo<true> = DoFactory.createPersonenkontext(true, {
revision: '1',
});
const personenkontextDoWithUpdatedRevision: PersonenkontextDo<true> = {
...personenkontextDo,
revision: '2',
};

personenkontextRepoMock.findById.mockResolvedValue(personenkontextDo);
personenkontextRepoMock.save.mockResolvedValue(personenkontextDoWithUpdatedRevision);

const result: Result<
PersonenkontextDo<true>,
DomainError
> = await personenkontextService.updatePersonenkontext(personenkontextDo);

expect(result).toEqual<Result<PersonenkontextDo<true>, DomainError>>({
ok: true,
value: personenkontextDoWithUpdatedRevision,
});
expect(personenkontextRepoMock.save).toHaveBeenCalledWith(personenkontextDoWithUpdatedRevision);
});
});

describe('when entity is not found', () => {
it('should return EntityNotFoundError', async () => {
const response: Result<
PersonenkontextDo<true>,
DomainError
> = await personenkontextService.updatePersonenkontext({} as PersonenkontextDo<true>);

// AI next 4 lines
expect(response).toEqual<Result<PersonenkontextDo<true>, DomainError>>({
ok: false,
error: new EntityNotFoundError('Personenkontext'),
});
});
});

describe('when revision does not match', () => {
it('should return MismatchedRevisionError', async () => {
// AI next 20 lines
const personenkontextDo: PersonenkontextDo<true> = DoFactory.createPersonenkontext(true);
const personenkontextDoWithWrongRevision: PersonenkontextDo<true> = {
...personenkontextDo,
revision: 'wrongRevision',
};

personenkontextRepoMock.findById.mockResolvedValue(personenkontextDo);

const result: Result<
PersonenkontextDo<true>,
DomainError
> = await personenkontextService.updatePersonenkontext(personenkontextDoWithWrongRevision);

expect(result).toEqual<Result<PersonenkontextDo<true>, DomainError>>({
ok: false,
error: new MismatchedRevisionError(
`Revision ${personenkontextDoWithWrongRevision.revision} does not match revision ${personenkontextDo.revision} of stored personenkontext.`,
),
});
});
});

describe('when could not be stored', () => {
it('should return EntityCouldNotBeUpdatedError', async () => {
// AI next 14 lines
const personenkontextDo: PersonenkontextDo<true> = DoFactory.createPersonenkontext(true);

personenkontextRepoMock.findById.mockResolvedValue(personenkontextDo);
personenkontextRepoMock.save.mockResolvedValue(null);

const result: Result<
PersonenkontextDo<true>,
DomainError
> = await personenkontextService.updatePersonenkontext(personenkontextDo);

expect(result).toEqual<Result<PersonenkontextDo<true>, DomainError>>({
ok: false,
error: new EntityCouldNotBeUpdated('Personenkontext', personenkontextDo.id),
});
});
});
});
});
8 changes: 4 additions & 4 deletions src/modules/person/domain/personenkontext.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { PersonenkontextRepo } from '../persistence/personenkontext.repo.js';
import { PersonenkontextScope } from '../persistence/personenkontext.scope.js';
import { PersonDo } from './person.do.js';
import { PersonenkontextDo } from './personenkontext.do.js';
import { MismatchedRevisionError } from '../../../shared/error/mismatched-revision-error.error.js';
import { MismatchedRevisionError } from '../../../shared/error/mismatched-revision.error.js';
import { EntityCouldNotBeUpdated } from '../../../shared/error/entity-could-not-be-updated.error.js';

@Injectable()
Expand Down Expand Up @@ -100,11 +100,11 @@ export class PersonenkontextService {
jahrgangsstufe: personenkontextDo.jahrgangsstufe,
revision: newRevision,
};
Object.assign(storedPersonenkontext, newData);
const updatedPersonenkontextDo: PersonenkontextDo<true> = Object.assign(storedPersonenkontext, newData);

const saved: Option<PersonenkontextDo<true>> = await this.personenkontextRepo.save(storedPersonenkontext);
const saved: Option<PersonenkontextDo<true>> = await this.personenkontextRepo.save(updatedPersonenkontextDo);
if (!saved) {
return { ok: false, error: new EntityCouldNotBeUpdated('Personenkontext', storedPersonenkontext.id) };
return { ok: false, error: new EntityCouldNotBeUpdated('Personenkontext', updatedPersonenkontextDo.id) };
}

return { ok: true, value: saved };
Expand Down
2 changes: 1 addition & 1 deletion src/shared/error/entity-could-not-be-created.error.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('EntityCouldNotBeCreated', () => {
it('should set message and code', () => {
const error: EntityCouldNotBeCreated = new EntityCouldNotBeCreated('EntityName');
expect(error.message).toBe('EntityName could not be created');
expect(error.code).toBe('ENTITY_CLOUD_NOT_BE_CREATED');
expect(error.code).toBe('ENTITY_COULD_NOT_BE_CREATED');
});
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/shared/error/entity-could-not-be-created.error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { DomainError } from './domain.error.js';

export class EntityCouldNotBeCreated extends DomainError {
public constructor(entityName: string, details?: unknown[] | Record<string, unknown>) {
super(`${entityName} could not be created`, 'ENTITY_CLOUD_NOT_BE_CREATED', details);
super(`${entityName} could not be created`, 'ENTITY_COULD_NOT_BE_CREATED', details);
}
}
13 changes: 13 additions & 0 deletions src/shared/error/entity-could-not-be-updated.error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { EntityCouldNotBeUpdated } from './entity-could-not-be-updated.error.js';

describe('EntityCouldNotBeUpdated', () => {
describe('constructor', () => {
describe('when calling the constructor', () => {
it('should set message and code', () => {
const error: EntityCouldNotBeUpdated = new EntityCouldNotBeUpdated('EntityName', '0');
expect(error.message).toBe('EntityName with ID 0 could not be updated');
expect(error.code).toBe('ENTITY_COULD_NOT_BE_UPDATED');
});
});
});
});
2 changes: 1 addition & 1 deletion src/shared/error/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export * from './entity-could-not-be-updated.error.js';
export * from './entity-not-found.error.js';
export * from './keycloak-client.error.js';
export * from './mapping.error.js';
export * from './mismatched-revision-error.error.js';
export * from './mismatched-revision.error.js';
export * from './person-already-exists.error.js';
13 changes: 13 additions & 0 deletions src/shared/error/mismatched-revision.error.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MismatchedRevisionError } from './mismatched-revision.error.js';

describe('MismatchedRevisionError', () => {
describe('constructor', () => {
describe('when calling the constructor', () => {
it('should set message and code', () => {
const error: MismatchedRevisionError = new MismatchedRevisionError('message');
expect(error.message).toBe('message');
expect(error.code).toBe('MISMATCHED_REVISION');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { DomainError } from './domain.error.js';

export class MismatchedRevisionError extends DomainError {
public constructor(message: string, details?: unknown[] | Record<string, unknown>) {
super(message, 'MISMATCHED_REVISION_ERROR', details);
super(message, 'MISMATCHED_REVISION', details);
}
}

0 comments on commit e20cc6c

Please sign in to comment.