Skip to content

Commit

Permalink
Get users from request in the book use case
Browse files Browse the repository at this point in the history
  • Loading branch information
simonecarriero committed Mar 12, 2024
1 parent d17db98 commit caa7b9f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 15 deletions.
54 changes: 49 additions & 5 deletions src/application/book.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,29 @@ import { justDate } from '../domain/JustDate';
import { justTime } from '../domain/JustTime';
import { BookingRequestRepositoryInMemory } from '../infrastructure/in-memory/BookingRequestRepositoryInMemory';
import { FreeSpotRepositoryInMemory } from '../infrastructure/in-memory/FreeSpotRepositoryInMemory';
import { UserRepositoryInMemory } from '../infrastructure/in-memory/UserRepositoryInMemory';
import { book } from './book';
import * as E from 'fp-ts/Either';
import * as TE from 'fp-ts/TaskEither';
import { pipe } from 'fp-ts/lib/function';

describe(`book`, () => {
const jane = {
firstname: 'Jane',
lastname: 'Doe',
email: '[email protected]',
phone: '0123456789',
};

const jon = {
firstname: 'Jon',
lastname: 'Doe',
email: '[email protected]',
phone: '0123456789',
};

const userRepository = new UserRepositoryInMemory([jane, jon]);

it(`books the first available spot for each booking request`, async () => {
let freeSpots = [
{ id: 1, date: justDate(2020, 1, 1), time: justTime(18, 30) },
Expand All @@ -19,19 +38,19 @@ describe(`book`, () => {

const freeSpotRepository = new FreeSpotRepositoryInMemory(freeSpots);
const bookingRequestRepository = new BookingRequestRepositoryInMemory(bookingRequests);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository, userRepository);

const booked = await bookUseCase();

expect(booked).toEqual(
E.right([
[
{ date: justDate(2020, 1, 1), from: justTime(18), to: justTime(20), chat: 123 },
{ id: 1, date: justDate(2020, 1, 1), time: justTime(18, 30) },
{ id: 1, date: justDate(2020, 1, 1), time: justTime(18, 30), user: jane },
],
[
{ date: justDate(2020, 1, 1), from: justTime(18), to: justTime(21), chat: 123 },
{ id: 1, date: justDate(2020, 1, 1), time: justTime(19, 30) },
{ id: 1, date: justDate(2020, 1, 1), time: justTime(19, 30), user: jane },
],
]),
);
Expand All @@ -54,7 +73,7 @@ describe(`book`, () => {

const freeSpotRepository = new FreeSpotRepositoryInMemory(freeSpots);
const bookingRequestRepository = new BookingRequestRepositoryInMemory(bookingRequests);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository, userRepository);

await bookUseCase();

Expand All @@ -71,7 +90,7 @@ describe(`book`, () => {

const freeSpotRepository = new FreeSpotRepositoryInMemory(freeSpots);
const bookingRequestRepository = new BookingRequestRepositoryInMemory(bookingRequests);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository, userRepository);
await bookUseCase();

const spots = freeSpotRepository.get({
Expand All @@ -83,4 +102,29 @@ describe(`book`, () => {

expect(spots()).resolves.toEqual(E.right([]));
});

it(`gets user`, async () => {
let freeSpots = [{ id: 1, date: justDate(2020, 1, 1), time: justTime(18, 30) }];
let bookingRequests = [
{ date: justDate(2020, 1, 1), from: justTime(18), to: justTime(20), chat: 123, user: 'Jon' },
];

const freeSpotRepository = new FreeSpotRepositoryInMemory(freeSpots);
const bookingRequestRepository = new BookingRequestRepositoryInMemory(bookingRequests);
const bookUseCase = book(bookingRequestRepository, freeSpotRepository, userRepository);

const booked = await pipe(
bookUseCase,
TE.map(([[_, freeSpot]]) => freeSpot),
)();

expect(booked).toEqual(
E.right({
id: 1,
date: justDate(2020, 1, 1),
time: justTime(18, 30),
user: jon,
}),
);
});
});
16 changes: 6 additions & 10 deletions src/application/book.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { BookingRequest, BookingRequestRepository } from '../domain/BookingRequest';
import { FreeSpot, FreeSpotRepository } from '../domain/FreeSpot';
import { UserRepository } from '../domain/User';
import * as O from 'fp-ts/Option';
import * as A from 'fp-ts/ReadonlyArray';
import * as TE from 'fp-ts/TaskEither';
import { sequenceT } from 'fp-ts/lib/Apply';
import { pipe } from 'fp-ts/lib/function';

export const book = (
bookingRequestRepository: BookingRequestRepository,
freeSpotRepository: FreeSpotRepository,
userRepository: UserRepository,
): TE.TaskEither<Error, readonly [BookingRequest, FreeSpot][]> => {
const tryBooking = (request: BookingRequest): TE.TaskEither<Error, O.Option<[BookingRequest, FreeSpot]>> => {
const user = {
firstname: 'Jane',
lastname: 'Doe',
email: '[email protected]',
phone: '0123456789',
};

return pipe(
freeSpotRepository.get(request),
TE.flatMap((spots) => {
sequenceT(TE.ApplyPar)(userRepository.get(request.user || 'Jane'), freeSpotRepository.get(request)),
TE.flatMap(([user, spots]) => {
if (spots.length === 0) {
return TE.right(O.none);
}
return pipe(
freeSpotRepository.book(spots[0], user),
TE.flatMap((_) => bookingRequestRepository.delete(request)),
TE.map((_) => O.some([request, spots[0]])),
TE.map((_) => O.some([request, { ...spots[0], user }])),
);
}),
);
Expand Down
1 change: 1 addition & 0 deletions src/domain/FreeSpot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type FreeSpot = {
id: number;
date: JustDate;
time: JustTime;
user?: User;
};

export type User = {
Expand Down
6 changes: 6 additions & 0 deletions src/domain/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { User } from './FreeSpot';
import * as TE from 'fp-ts/lib/TaskEither';

export interface UserRepository {
get(name: string): TE.TaskEither<Error, User>;
}
9 changes: 9 additions & 0 deletions src/infrastructure/in-memory/UserRepositoryInMemory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { User } from '../../domain/FreeSpot';
import { UserRepository } from '../../domain/User';
import * as TE from 'fp-ts/TaskEither';

export class UserRepositoryInMemory implements UserRepository {
constructor(private state: User[] = []) {}

get = (name: string): TE.TaskEither<Error, User> => TE.of(this.state.find((s) => s.firstname === name)!);
}

0 comments on commit caa7b9f

Please sign in to comment.