Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BC-8213 - validate room dates #5347

Merged
merged 4 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}'`
);
}
}
}
Loading