import { Test, TestingModule } from '@nestjs/testing' import { datatype } from 'faker' import { AppointmentRepository, PatientRepository, UserRepository } from '../../../repositories' import { factory } from '../../../../test/factories' import { MailService, MessagingService } from '../../../services' import { MockedModule } from '../../../../test/types' import { Anthropometry, Appointment, BioimpedanceAnalysis, Patient, User } from '../../../models' import { UserNotFoundError } from '../../../errors/user_not_found.error' import { TranslateNotificationsHelper } from '../i18n' import { Patients } from './patients' describe('Patients', () => { let subject: Patients let messagingService: MockedModule let userRepository: MockedModule let patientRepository: MockedModule let appointmentRepository: MockedModule let mailService: MockedModule const translateNotificationsHelper = new TranslateNotificationsHelper() beforeAll(async () => { messagingService = { sendPushNotificationByTemplate: jest.fn(), } userRepository = { get: jest.fn(), } appointmentRepository = { getLastAppointment: jest.fn(), existsScheduledAppointmentBy: jest.fn(), } patientRepository = { get: jest.fn(), } mailService = { send: jest.fn(), } const app: TestingModule = await Test.createTestingModule({ controllers: [], providers: [ { provide: MessagingService, useValue: messagingService, }, { provide: UserRepository, useValue: userRepository, }, { provide: AppointmentRepository, useValue: appointmentRepository, }, { provide: PatientRepository, useValue: patientRepository, }, { provide: MailService, useValue: mailService, }, { provide: TranslateNotificationsHelper, useValue: translateNotificationsHelper, }, Patients, ], }).compile() subject = app.get(Patients) }) afterEach(() => { jest.resetAllMocks() }) describe('#notifyNutriUnavailableChange()', () => { let patient: Patient let oldNutri: User let newNutri: User beforeAll(async () => { patient = await factory.build('patient') oldNutri = await factory.build('user') newNutri = await factory.build('user') }) it('sends push notification', async () => { await subject['notifyNutriUnavailableChange'](patient, oldNutri, newNutri) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_unavailable_change' as any), patient.device_id, ) }) }) describe('#notifyAppointmentUnavailableBlocked()', () => { let patient: Patient let nutri: User beforeAll(async () => { patient = await factory.build('patient') nutri = await factory.build('user') }) it('sends push notification', async () => { await subject['notifyAppointmentUnavailableBlocked'](patient, nutri) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_unavailable_cancel' as any), patient.device_id, ) }) }) describe('#notifyAppointmentBlocked()', () => { let patient: Patient beforeAll(async () => { patient = await factory.build('patient') }) it('sends push notification', async () => { await subject['notifyAppointmentBlocked'](patient) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_cancel' as any), patient.device_id, ) }) }) describe('#nutriChanged()', () => { let patient: Patient let oldNutriId: string let hasScheduledAppointments: boolean beforeAll(async () => { patient = await factory.build('patient') oldNutriId = datatype.uuid() }) beforeEach(() => { appointmentRepository.existsScheduledAppointmentBy.mockResolvedValue(hasScheduledAppointments) }) describe('when patient did not have nutri previously', () => { beforeAll(async () => { patient = await factory.build('patient') oldNutriId = null }) afterAll(async () => { oldNutriId = datatype.uuid() }) it('does not execute the function', async () => { await subject.nutriChanged(patient, oldNutriId, patient.user_id) expect(patientRepository.get).not.toBeCalled() }) }) describe('when not found any nutri', () => { it('throws an error', async () => { await expect(subject.nutriChanged(patient, oldNutriId, patient.user_id)).rejects.toThrowError(UserNotFoundError) }) }) describe('when the old nutri is inactivated', () => { beforeEach(async () => { userRepository.get.mockResolvedValueOnce(await factory.build('user', { inactivated_at: new Date() })) userRepository.get.mockResolvedValueOnce(await factory.build('user')) }) describe('when patient has scheduled appointments', () => { beforeAll(() => { hasScheduledAppointments = true }) it('sends nutri unavailable and was changed', async () => { await subject.nutriChanged(patient, oldNutriId, patient.user_id) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_unavailable_change' as any), patient.device_id, ) }) }) describe(`when patient hasn't scheduled appointments`, () => { beforeAll(() => { hasScheduledAppointments = false }) it('sends nutri unavailable and was changed', async () => { await subject.nutriChanged(patient, oldNutriId, patient.user_id) expect(messagingService.sendPushNotificationByTemplate).not.toBeCalled() }) }) }) }) describe('#appointmentBlocked()', () => { let appointment: Appointment let patient: Patient let nutri: User beforeAll(async () => { appointment = await factory.build('appointment', { state: 'blocked' }) patient = await factory.build('patient') }) describe('when not found the nutri', () => { it('throws an error', async () => { await expect(subject.appointmentBlocked(appointment)).rejects.toThrowError(UserNotFoundError) }) }) describe('when not found the patient', () => { beforeEach(async () => { userRepository.get.mockResolvedValue({}) }) it('throws an error', async () => { await expect(subject.appointmentBlocked(appointment)).rejects.toThrowError(UserNotFoundError) }) }) describe('when the nutri is inactivated', () => { beforeAll(async () => { nutri = await factory.build('user', { inactivated_at: new Date() }) }) beforeEach(async () => { userRepository.get.mockResolvedValue(nutri) patientRepository.get.mockResolvedValue(patient) }) it('sends nutri unavailable notify', async () => { await subject.appointmentBlocked(appointment) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_unavailable_cancel' as any), patient.device_id, ) }) }) describe('when the nutri is active', () => { beforeAll(async () => { nutri = await factory.build('user') }) beforeEach(async () => { userRepository.get.mockResolvedValue(nutri) patientRepository.get.mockResolvedValue(patient) }) it('sends nutri available notify', async () => { await subject.appointmentBlocked(appointment) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.nutri_cancel' as any), patient.device_id, ) }) }) }) describe('#bioimpedanceAnalysisFinished()', () => { let anthropometry: Anthropometry let bioimpedanceAnalysis: BioimpedanceAnalysis let patient: Patient beforeAll(async () => { bioimpedanceAnalysis = await factory.build('bioimpedance_analysis') anthropometry = await factory.build('anthropometry', { id: bioimpedanceAnalysis.anthropometry_id }) patient = await factory.build('patient', { id: anthropometry.patient_id }) }) beforeEach(() => { patientRepository.get.mockResolvedValue(patient) }) it('sends push notification', async () => { await subject.bioimpedanceAnalysisFinished(bioimpedanceAnalysis) expect(messagingService.sendPushNotificationByTemplate).toBeCalledWith( translateNotificationsHelper.get(patient.country_code, 'pushes.bioimpedance_analysis_finished' as any), patient.device_id, ) }) }) })