import { Test, TestingModule } from '@nestjs/testing' import { datatype, random } from 'faker' import { ChallengeWeek, Patient, ChallengePatient, ChallengeDay } from '../../models' import { PatientRepository, ChallengeWeekRepository, ChallengePatientRepository, ChallengeDayPatientRepository, } from '../../repositories' import { MockedModule } from '../../../test/types' import { UnauthorizedError } from '../../errors' import { ChallengeService } from './challenge.service' describe('ChallengeService', () => { let subject: ChallengeService let patientRepository: MockedModule let challengeWeekRepository: MockedModule let challengePatientRepository: MockedModule let challengeDayPatientRepository: MockedModule beforeAll(async () => { patientRepository = { get: jest.fn(), } challengeWeekRepository = { getChallengeWeekDays: jest.fn(), getChallengeWithRelationships: jest.fn(), } challengePatientRepository = { getOpenChallenge: jest.fn(), createChallengePatient: jest.fn(), } challengeDayPatientRepository = { createChallengeDayPatient: jest.fn(), } const app: TestingModule = await Test.createTestingModule({ providers: [ { provide: PatientRepository, useValue: patientRepository, }, { provide: ChallengeWeekRepository, useValue: challengeWeekRepository, }, { provide: ChallengePatientRepository, useValue: challengePatientRepository, }, { provide: ChallengeDayPatientRepository, useValue: challengeDayPatientRepository, }, ChallengeService, ], }).compile() subject = app.get(ChallengeService) }) afterEach(() => { jest.clearAllMocks() }) afterAll(() => { jest.restoreAllMocks() }) describe('calls creation service', () => { const patient_id = datatype.uuid() const challenge_week_id = datatype.uuid() const challenge_week_id_2 = datatype.uuid() const country_code = 'pt_BR' const challengePatient = ChallengePatient.toInstance({ id: datatype.uuid(), patient_id }) beforeEach(() => { patientRepository.get.mockResolvedValue( Patient.toInstance({ id: patient_id, country_code, }), ) }) describe('when patient is already in a challenge', () => { beforeEach(() => { challengePatientRepository.getOpenChallenge.mockResolvedValue(challengePatient) }) it('throws an error', async () => { await expect(subject.create({ patientId: patient_id })).rejects.toThrowError(UnauthorizedError) }) }) describe('when patient is not yet in a challenge', () => { beforeEach(() => { challengePatientRepository.createChallengePatient.mockResolvedValue(challengePatient.id) challengePatientRepository.getOpenChallenge.mockResolvedValue(null) challengeWeekRepository.getChallengeWithRelationships.mockResolvedValue(null) challengeWeekRepository.getChallengeWeekDays.mockResolvedValue([ ChallengeWeek.toInstance({ id: challenge_week_id, country_code, bonus_description: random.words(), bonus_ebook: random.word(), challenge_days: [ ChallengeDay.toInstance({ id: datatype.uuid(), challenge_week_id, day: 1, }), ChallengeDay.toInstance({ id: datatype.uuid(), challenge_week_id, day: 2, }), ], }), ChallengeWeek.toInstance({ id: challenge_week_id_2, country_code, bonus_description: random.words(), bonus_ebook: random.word(), challenge_days: [ ChallengeDay.toInstance({ id: datatype.uuid(), challenge_week_id: challenge_week_id_2, day: 3, }), ChallengeDay.toInstance({ id: datatype.uuid(), challenge_week_id: challenge_week_id_2, day: 4, }), ], }), ]) challengeDayPatientRepository.createChallengeDayPatient.mockResolvedValue(1) }) it('return challenge days', async () => { await subject.create({ patientId: patient_id }) expect(challengeWeekRepository.getChallengeWeekDays).toBeCalledWith(country_code) expect(challengeDayPatientRepository.createChallengeDayPatient).toBeCalledTimes(2) expect(challengeDayPatientRepository.createChallengeDayPatient).lastCalledWith( expect.arrayContaining([ expect.objectContaining({ challenge_patient_id: expect.stringContaining(challengePatient.id), available_at: expect.any(Date), }), ]), ) expect(challengeWeekRepository.getChallengeWithRelationships).toBeCalledWith(patient_id, country_code) }) }) }) })