import { Test, TestingModule } from '@nestjs/testing' import { datatype } from 'faker' import { Patient } from '../../../models' import { AccountService, RedisService, SMSTokenOptions, TokenService, TokenValidatorService } from '../../../services' import { MockedModule } from '../../../../test/types' import { factory } from '../../../../test/factories' import { PatientRepository } from '../../../repositories' import { OS } from '../../../params' import { Accounts } from './accounts' describe('Accounts', () => { let accounts: Accounts let tokenService: MockedModule let accountService: MockedModule let tokenValidatorService: MockedModule let patientRepository: MockedModule let redisService: MockedModule const authToken = { code: datatype.uuid(), encryptedCode: datatype.uuid(), } let smsOptions: SMSTokenOptions beforeAll(async () => { tokenService = { sendAuthToken: jest.fn(), } accountService = { createPatientAndAuth: jest.fn(), createPatientIfStudentOrCollaborator: jest.fn(), checkAndUpdatePatient: jest.fn(), } tokenValidatorService = { validatePatientToken: jest.fn(), } patientRepository = { findByLogin: jest.fn(), } redisService = { set: jest.fn(), } const app: TestingModule = await Test.createTestingModule({ controllers: [], providers: [ { provide: PatientRepository, useValue: patientRepository, }, { provide: TokenService, useValue: tokenService, }, { provide: AccountService, useValue: accountService, }, { provide: TokenValidatorService, useValue: tokenValidatorService, }, { provide: RedisService, useValue: redisService, }, Accounts, ], }).compile() accounts = app.get(Accounts) }) beforeEach(() => { smsOptions = { appSignature: datatype.uuid(), os: OS.ANDROID } }) afterEach(() => { jest.clearAllMocks() }) afterAll(() => { jest.restoreAllMocks() }) describe('#createPatientAndSendToken', () => { const id = datatype.uuid() let patient: Patient beforeAll(async () => { patient = await factory.build('patient') accountService.createPatientAndAuth.mockResolvedValue({ ...patient, id }) tokenService.sendAuthToken.mockResolvedValue(authToken) }) it('creates the patient with the provided data', async () => { await accounts.createPatientAndSendToken(patient, smsOptions) expect(accountService.createPatientAndAuth).toHaveBeenCalledWith(patient) }) it('creates and send the auth token', async () => { await accounts.createPatientAndSendToken(patient, smsOptions) expect(tokenService.sendAuthToken).toHaveBeenCalledWith( { ...patient, id }, { sms: true, email: true }, smsOptions, ) }) it('returns the validation', async () => { expect(await accounts.createPatientAndSendToken(patient, smsOptions)).toEqual(authToken) }) }) describe('#sendTokenToPatient', () => { const login = datatype.uuid() let patient: Patient beforeEach(() => { patientRepository.findByLogin.mockResolvedValue(patient) tokenService.sendAuthToken.mockResolvedValue(authToken) }) describe('when patient already exists', () => { beforeAll(async () => { patient = await factory.build('patient') accountService.checkAndUpdatePatient.mockResolvedValue(patient) }) it('updates the patient with the provided data', async () => { await accounts.sendTokenToPatient(login) expect(accountService.checkAndUpdatePatient).toHaveBeenCalledWith(patient) }) it('creates and send the auth token', async () => { await accounts.sendTokenToPatient(login, smsOptions) expect(tokenService.sendAuthToken).toHaveBeenCalledWith(patient, { sms: true, email: true }, smsOptions) }) it('returns the validation', async () => { expect(await accounts.sendTokenToPatient(login)).toEqual({ ...authToken, exists: true }) }) }) describe('when patient don`t previously exists', () => { let createdPatient: Patient beforeAll(async () => { patient = null createdPatient = await factory.build('patient') accountService.createPatientIfStudentOrCollaborator.mockResolvedValue(createdPatient) }) it('creates the patient with the provided data', async () => { await accounts.sendTokenToPatient(login) expect(accountService.createPatientIfStudentOrCollaborator).toHaveBeenCalledWith(login) }) it('creates and send the auth token', async () => { await accounts.sendTokenToPatient(login, smsOptions) expect(tokenService.sendAuthToken).toHaveBeenCalledWith(createdPatient, { sms: true, email: true }, smsOptions) }) it('returns the validation', async () => { expect(await accounts.sendTokenToPatient(login)).toEqual({ ...authToken, exists: false }) }) }) }) describe('#validatePatientToken', () => { const login = datatype.uuid() const token = datatype.uuid() const authTokenValue = datatype.uuid() beforeAll(() => { tokenValidatorService.validatePatientToken.mockResolvedValue(authTokenValue) }) it('validates the patient token', async () => { await accounts.validatePatientToken(login, token) expect(tokenValidatorService.validatePatientToken).toHaveBeenCalledWith(login, token) }) it('returns the validation', async () => { expect(await accounts.validatePatientToken(login, token)).toEqual(authTokenValue) }) }) })