import { Test, TestingModule } from '@nestjs/testing' import { datatype } from 'faker' import { PatientRepository, PlanRepository, SubscriptionInstallmentRepository, SubscriptionTransactionRepository, } from '../../../repositories' import { factory } from '../../../../test/factories' import { ContractService, MailService, MessagingService, SMSService } from '../../../services' import { MockedModule } from '../../../../test/types' import { Patient, Plan, Subscription, SubscriptionTransaction } from '../../../models' import { NotFoundError } from '../../../errors' import { TranslateNotificationsHelper } from '../i18n' import { Subscriptions } from './subscriptions' describe('Subscriptions', () => { let subject: Subscriptions let patientRepository: MockedModule let mailService: MockedModule let contractService: MockedModule let planRepository: MockedModule let subscriptionTransactionRepository: MockedModule let subscriptionInstallmentRepository: MockedModule let messagingService: MockedModule let smsService: MockedModule let translateNotificationsHelper: MockedModule beforeAll(async () => { patientRepository = { get: jest.fn(), } mailService = { send: jest.fn(), } contractService = { generateSubscriptionContract: jest.fn(), } planRepository = { getWithFeatures: jest.fn(), } subscriptionTransactionRepository = { findLastBySubscription: jest.fn(), } subscriptionInstallmentRepository = { getTotalBySubscription: jest.fn(), } messagingService = { sendPushNotification: jest.fn(), } smsService = { send: jest.fn(), } translateNotificationsHelper = { get: jest.fn(), } const app: TestingModule = await Test.createTestingModule({ controllers: [], providers: [ { provide: PatientRepository, useValue: patientRepository, }, { provide: MailService, useValue: mailService, }, { provide: ContractService, useValue: contractService, }, { provide: PlanRepository, useValue: planRepository, }, { provide: SubscriptionTransactionRepository, useValue: subscriptionTransactionRepository, }, { provide: SubscriptionInstallmentRepository, useValue: subscriptionInstallmentRepository, }, { provide: MessagingService, useValue: messagingService, }, { provide: SMSService, useValue: smsService, }, { provide: TranslateNotificationsHelper, useValue: translateNotificationsHelper, }, Subscriptions, ], }).compile() subject = app.get(Subscriptions) }) afterEach(() => { jest.resetAllMocks() }) describe('#notifyNew', () => { let patient: Patient let plan: Plan let transaction: SubscriptionTransaction let subscription: Subscription let totalInstallments = datatype.number({ min: 1 }) beforeAll(async () => { patient = await factory.build('patient') subscription = await factory.build('subscription', { patientId: patient.id }) plan = await factory.build('plan') transaction = await factory.build('subscription', { patientId: patient.id }) }) beforeEach(() => { patientRepository.get.mockResolvedValue(patient) planRepository.getWithFeatures.mockResolvedValue(plan) subscriptionTransactionRepository.findLastBySubscription.mockResolvedValue(transaction) subscriptionInstallmentRepository.getTotalBySubscription.mockResolvedValue(totalInstallments) }) describe('when patient not exists', () => { beforeAll(() => { patient = null }) afterAll(async () => { patient = await factory.build('patient') }) it('throws an error', async () => { await expect(subject.notifyNew(subscription)).rejects.toThrowError(NotFoundError) }) }) describe('when plan not exists', () => { beforeAll(() => { plan = null }) afterAll(async () => { const planFeature = await factory.build('plan_feature', { feature: 'teleconsultation' }) plan = await factory.build('plan', { features: [planFeature] }) }) it('throws an error', async () => { await expect(subject.notifyNew(subscription)).rejects.toThrowError(NotFoundError) }) }) describe('when subscription transaction not exists', () => { beforeAll(() => { transaction = null }) afterAll(async () => { transaction = await factory.build('subscription_transaction', { subscription: subscription.id, patientId: patient.id, }) }) it('throws an error', async () => { await expect(subject.notifyNew(subscription)).rejects.toThrowError(NotFoundError) }) }) describe('when subscription does not have installments', () => { beforeAll(() => { totalInstallments = 0 }) afterAll(async () => { totalInstallments = datatype.number({ min: 1 }) }) it('throws an error', async () => { await expect(subject.notifyNew(subscription)).rejects.toThrowError(NotFoundError) }) }) it('calls to generate contract', async () => { await subject.notifyNew(subscription) expect(contractService.generateSubscriptionContract).toBeCalled() }) }) })