import { TestingModule, Test } from '@nestjs/testing' import { datatype } from 'faker' import { Anthropometry, Patient } from '../../models' import { factory } from '../../../test/factories' import { MockedModule } from '../../../test/types' import { RedisService } from '../redis/redis.service' import { AnthropometriesFilter, PatientRepository, AnthropometryRepository } from '../../repositories' import { BioimpedanceService } from './bioimpedance.service' describe('BioimpedanceService', () => { let subject: BioimpedanceService let anthropometryRepository: MockedModule let patientRepository: MockedModule let redisService: MockedModule let filter: AnthropometriesFilter beforeAll(async () => { anthropometryRepository = { findByPatientLogin: jest.fn(), } patientRepository = { get: jest.fn(), } redisService = { get: jest.fn(), set: jest.fn(), } filter = 'bioimpedances' const app: TestingModule = await Test.createTestingModule({ controllers: [], providers: [ { provide: AnthropometryRepository, useValue: anthropometryRepository, }, { provide: PatientRepository, useValue: patientRepository, }, { provide: RedisService, useValue: redisService, }, BioimpedanceService, ], }).compile() subject = app.get(BioimpedanceService) }) afterEach(() => { jest.resetAllMocks() }) afterAll(() => { jest.restoreAllMocks() }) describe('#getPatientAnthropometriesCache', () => { let patient: Patient beforeAll(async () => { patient = await factory.build('patient') patientRepository.get.mockResolvedValue(patient) }) describe('when cache not exists', () => { beforeAll(() => { redisService.get.mockResolvedValue(null) }) it('returns null', async () => { await expect(subject.getPatientAnthropometriesCache(patient, filter)).resolves.toBeNull() }) }) describe('when cache exists but is an empty array', () => { beforeAll(() => { redisService.get.mockResolvedValue('[]') }) it('returns an empty array', async () => { await expect(subject.getPatientAnthropometriesCache(patient, filter)).resolves.toEqual([]) }) }) describe('when cache exists with an anthropometry array', () => { const anthropometries = [{ id: datatype.uuid() }] beforeAll(() => { redisService.get.mockResolvedValue(JSON.stringify(anthropometries)) }) it('returns the array', async () => { await expect(subject.getPatientAnthropometriesCache(patient, filter)).resolves.toEqual(anthropometries) }) }) describe('when cache exists with an error object', () => { const errors = [{ error: 'not-found' }] beforeAll(() => { redisService.get.mockResolvedValue(JSON.stringify(errors)) }) it('returns null', async () => { await expect(subject.getPatientAnthropometriesCache(patient, filter)).resolves.toBeNull() }) }) describe('when cache is not an array', () => { beforeAll(() => { redisService.get.mockResolvedValue(JSON.stringify('')) }) it('returns an empty array', async () => { await expect(subject.getPatientAnthropometriesCache(patient, filter)).resolves.toEqual([]) }) }) }) describe('#createPatientAnthropometriesCache', () => { let patient: Patient let setCacheSpy: jest.SpyInstance let filter: AnthropometriesFilter beforeAll(async () => { patient = await factory.build('patient:subscriber') patientRepository.get.mockResolvedValue(patient) filter = 'bioimpedances' }) beforeEach(() => { setCacheSpy = jest.spyOn(subject, 'setCache') }) describe('when patient not exists', () => { it('writes empty array', async () => { await subject.createPatientAnthropometriesCache(patient.id, filter) expect(setCacheSpy).toBeCalledWith(patient.login + '-' + filter, []) }) }) describe('when patient exists', () => { beforeEach(() => { anthropometryRepository.findByPatientLogin.mockResolvedValue(patient) }) describe('when the patient anthropometries is empty', () => { beforeAll(() => { patient.anthropometries = [] patientRepository.get.mockResolvedValue(patient) }) it('writes empty array', async () => { await subject.createPatientAnthropometriesCache(patient.id, filter) expect(setCacheSpy).toBeCalledWith(patient.login + '-' + filter, []) }) }) describe('when the patient anthropometries is not empty', () => { beforeAll(() => { patient.anthropometries = [Anthropometry.toInstance({ id: datatype.uuid() })] patientRepository.get.mockResolvedValue(patient) }) it('writes anthropometries cache', async () => { await subject.createPatientAnthropometriesCache(patient.id, filter) expect(setCacheSpy).toBeCalledWith( patient.login + '-' + filter, subject['buildAnthropometriesToCache'](patient, patient.anthropometries), ) }) describe('when patient is not a subscriber', () => { beforeAll(() => { patient.subscription = null patientRepository.get.mockResolvedValue(patient) }) it('writes anthropometries cache with subscriber false', async () => { await subject.createPatientAnthropometriesCache(patient.id, filter) expect(setCacheSpy).toBeCalledWith( patient.login + '-' + filter, expect.arrayContaining([expect.objectContaining({ subscriber: false })]), ) }) describe('when patient has more than one', () => { beforeAll(() => { patient.anthropometries = [...Array(2)].map(() => Anthropometry.toInstance({ id: datatype.uuid() })) patientRepository.get.mockResolvedValue(patient) }) it('writes anthropometries cache with just one allowed to view', async () => { await subject.createPatientAnthropometriesCache(patient.id, filter) expect(setCacheSpy).toBeCalledWith( patient.login + '-' + filter, expect.arrayContaining([ expect.objectContaining({ id: patient.anthropometries[0].id, allow_bioimpedance: false }), expect.objectContaining({ id: patient.anthropometries[1].id, allow_bioimpedance: true }), ]), ) }) }) }) }) }) }) })