import { uuid } from 'uuidv4'; import FakeAppointmentsRepository from '@domains/appointments/fakes/repositories/FakeAppointmentsRepository'; import FakeNotificationsRepository from '@domains/notifications/fakes/repositories/FakeNotificationsRepository'; import FakeCacheProvider from '@shared/container/providers/CacheProvider/fakes/FakeCacheProvider'; import Appointment from '@domains/appointments/infra/typeorm/entities/Appointment'; import CreateAppointmentService from '@domains/appointments/services/CreateAppointmentService'; import AppError from '@shared/errors/AppError'; import { BUSINESS_LIMIT_HOUR, BUSINESS_START_HOUR, } from '@domains/users/constants/appointments'; import APPOINTMENT_TYPES from '@domains/appointments/enums/appointmentTypes'; let appointmentsRepository: FakeAppointmentsRepository; let notificationsRepository: FakeNotificationsRepository; let createAppointment: CreateAppointmentService; let cacheProvider: FakeCacheProvider; describe('Create Appointment', () => { beforeEach(() => { cacheProvider = new FakeCacheProvider(); appointmentsRepository = new FakeAppointmentsRepository(); notificationsRepository = new FakeNotificationsRepository(); createAppointment = new CreateAppointmentService( appointmentsRepository, notificationsRepository, cacheProvider, ); }); it('should create an appointment', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 1, 1, 14, 0, 0).getTime()); const appointment = await createAppointment.execute({ provider_id: 'meanless provider id', customer_id: 'meanless customer id', type: APPOINTMENT_TYPES[2], date: new Date(2020, 1, 1, 15, 0, 0), }); expect(appointment).toHaveProperty('id'); }); it('should not create two appointments with the same date', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 1, 1, 14, 0, 0).getTime()); const appointmentData = Object.assign(new Appointment(), { provider_id: 'meanless provider id', customer_id: 'meanless customer id', type: APPOINTMENT_TYPES[1], date: new Date(2020, 1, 1, 15, 0, 0), }); await createAppointment.execute(appointmentData); await expect( createAppointment.execute(appointmentData), ).rejects.toBeInstanceOf(AppError); }); it('should not allow a provider to book an appointment with himself', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 1, 1, 14, 0, 0).getTime()); const providerId = uuid(); await expect( createAppointment.execute({ provider_id: providerId, customer_id: providerId, date: new Date(2020, 1, 1, 15, 0, 0), type: APPOINTMENT_TYPES[1], }), ).rejects.toBeInstanceOf(AppError); }); it('should not allow to book an appointment in past dates', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 1, 1, 14, 0, 0).getTime()); await expect( createAppointment.execute({ provider_id: 'meanless provider id', customer_id: 'meanless customer id', date: new Date(2020, 1, 1, 13, 0, 0), type: APPOINTMENT_TYPES[2], }), ).rejects.toBeInstanceOf(AppError); }); it('should not allow to book an appointment before or after the business hours range', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 0, 1, 14, 0, 0).getTime()); await expect( createAppointment.execute({ customer_id: 'meanless customer id', provider_id: 'meanless provider id', date: new Date(2020, 1, 1, BUSINESS_START_HOUR - 1, 0, 0), type: APPOINTMENT_TYPES[1], }), ).rejects.toBeInstanceOf(AppError); await expect( createAppointment.execute({ customer_id: 'meanless customer id', provider_id: 'meanless provider id', date: new Date(2020, 1, 1, BUSINESS_LIMIT_HOUR + 1, 0, 0), type: APPOINTMENT_TYPES[0], }), ).rejects.toBeInstanceOf(AppError); }); it('should send a notification to the provider after creating an appointment', async () => { jest .spyOn(Date, 'now') .mockImplementationOnce(() => new Date(2020, 0, 1, 14, 0, 0).getTime()); const createNotification = jest.spyOn(notificationsRepository, 'create'); await createAppointment.execute({ customer_id: 'meanless customer id', provider_id: 'meanless provider id', date: new Date(2020, 1, 1, BUSINESS_LIMIT_HOUR, 0, 0), type: APPOINTMENT_TYPES[2], }); expect(createNotification).toHaveBeenCalled(); }); });