Skip to content

Commit

Permalink
BC-8213 - validate room dates (#5347)
Browse files Browse the repository at this point in the history
* fixing room date validation on create and update
  • Loading branch information
MartinSchuhmacher authored Nov 29, 2024
1 parent 6b59148 commit 6c1cf2e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 66 deletions.
52 changes: 0 additions & 52 deletions apps/server/src/modules/room/domain/do/room.do.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ValidationError } from '@shared/common';
import { EntityId } from '@shared/domain/types';
import { roomFactory } from '../../testing';
import { RoomColor } from '../type';
Expand Down Expand Up @@ -71,55 +70,4 @@ describe('Room', () => {
const expectedUpdatedAt = new Date('2024-01-01');
expect(room.updatedAt).toEqual(expectedUpdatedAt);
});

describe('time frame validation', () => {
const setup = () => {
const props: RoomProps = {
id: roomId,
name: 'Conference Room',
color: RoomColor.BLUE,
startDate: new Date('2024-01-01'),
endDate: new Date('2024-12-31'),
createdAt: new Date('2024-01-01'),
updatedAt: new Date('2024-01-01'),
};

return { props };
};

describe('when costructor is called with invalid time frame', () => {
it('should throw validation error', () => {
const buildInvalid = () => {
const { props } = setup();
props.startDate = new Date('2024-12-31');
props.endDate = new Date('2024-01-01');
// eslint-disable-next-line no-new
new Room(props);
};
expect(buildInvalid).toThrowError(ValidationError);
});
});

describe('when setting start date after end date', () => {
it('should throw validation error', () => {
const setInvalidStartDate = () => {
const { props } = setup();
const inValidRoom = new Room(props);
inValidRoom.startDate = new Date('2025-01-01');
};
expect(setInvalidStartDate).toThrowError(ValidationError);
});
});

describe('when setting end date before start date', () => {
it('should throw validation error', () => {
const setInvalidEndDate = () => {
const { props } = setup();
const inValidRoom = new Room(props);
inValidRoom.endDate = new Date('2023-12-31');
};
expect(setInvalidEndDate).toThrowError(ValidationError);
});
});
});
});
14 changes: 0 additions & 14 deletions apps/server/src/modules/room/domain/do/room.do.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ValidationError } from '@shared/common';
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { EntityId } from '@shared/domain/types';
import { RoomColor } from '../type';
Expand All @@ -19,7 +18,6 @@ export type RoomUpdateProps = RoomCreateProps; // will probably change in the fu
export class Room extends DomainObject<RoomProps> {
public constructor(props: RoomProps) {
super(props);
this.validateTimeSpan();
}

public getProps(): RoomProps {
Expand Down Expand Up @@ -54,7 +52,6 @@ export class Room extends DomainObject<RoomProps> {

public set startDate(value: Date) {
this.props.startDate = value;
this.validateTimeSpan();
}

public get endDate(): Date | undefined {
Expand All @@ -63,7 +60,6 @@ export class Room extends DomainObject<RoomProps> {

public set endDate(value: Date) {
this.props.endDate = value;
this.validateTimeSpan();
}

public get createdAt(): Date {
Expand All @@ -73,14 +69,4 @@ export class Room extends DomainObject<RoomProps> {
public get updatedAt(): Date {
return this.props.updatedAt;
}

private validateTimeSpan() {
if (this.props.startDate != null && this.props.endDate != null && this.props.startDate > this.props.endDate) {
throw new ValidationError(
`Invalid room timespan. Start date '${this.props.startDate.toISOString()}' has to be before end date: '${this.props.endDate.toISOString()}'. Room id='${
this.id
}'`
);
}
}
}
17 changes: 17 additions & 0 deletions apps/server/src/modules/room/domain/service/room.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createMock, DeepMocked } from '@golevelup/ts-jest';
import { Test, TestingModule } from '@nestjs/testing';
import { Page } from '@shared/domain/domainobject';
import { EntityId } from '@shared/domain/types';
import { ValidationError } from '@shared/common';
import { RoomRepo } from '../../repo';
import { roomFactory } from '../../testing';
import { Room, RoomCreateProps, RoomUpdateProps } from '../do';
Expand Down Expand Up @@ -80,6 +81,14 @@ describe('RoomService', () => {

expect(roomRepo.save).toHaveBeenCalledWith(expect.objectContaining(props));
});

it('should throw validation error if start date is after end date', async () => {
const { props } = setup();
props.startDate = new Date('2024-12-31');
props.endDate = new Date('2024-01-01');

await expect(service.createRoom(props)).rejects.toThrowError(ValidationError);
});
});

describe('getSingleRoom', () => {
Expand Down Expand Up @@ -137,6 +146,14 @@ describe('RoomService', () => {

expect(roomRepo.save).toHaveBeenCalledWith(room);
});

it('should throw validation error if start date is after end date', async () => {
const { props, room } = setup();
props.startDate = new Date('2024-12-31');
props.endDate = new Date('2024-01-01');

await expect(service.updateRoom(room, props)).rejects.toThrowError(ValidationError);
});
});

describe('deleteRoom', () => {
Expand Down
11 changes: 11 additions & 0 deletions apps/server/src/modules/room/domain/service/room.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common';
import { Page } from '@shared/domain/domainobject';
import { IFindOptions } from '@shared/domain/interface';
import { EntityId } from '@shared/domain/types';
import { ValidationError } from '@shared/common';
import { RoomRepo } from '../../repo';
import { Room, RoomCreateProps, RoomProps, RoomUpdateProps } from '../do';

Expand All @@ -29,6 +30,7 @@ export class RoomService {
createdAt: new Date(),
updatedAt: new Date(),
};
this.validateTimeSpan(props, roomProps.id);
const room = new Room(roomProps);

await this.roomRepo.save(room);
Expand All @@ -43,6 +45,7 @@ export class RoomService {
}

public async updateRoom(room: Room, props: RoomUpdateProps): Promise<void> {
this.validateTimeSpan(props, room.id);
Object.assign(room, props);

await this.roomRepo.save(room);
Expand All @@ -51,4 +54,12 @@ export class RoomService {
public async deleteRoom(room: Room): Promise<void> {
await this.roomRepo.delete(room);
}

private validateTimeSpan(props: RoomCreateProps | RoomUpdateProps, roomId: string): void {
if (props.startDate != null && props.endDate != null && props.startDate > props.endDate) {
throw new ValidationError(
`Invalid room timespan. Start date '${props.startDate.toISOString()}' has to be before end date: '${props.endDate.toISOString()}'. Room id='${roomId}'`
);
}
}
}

0 comments on commit 6c1cf2e

Please sign in to comment.