import { HttpService } from "@nestjs/axios"; import { GatewayTimeoutException, HttpException } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; import { Test } from "@nestjs/testing"; import { of } from "rxjs"; import { EsQueryDto, EsResponseDto } from "src/core/domain"; import { SearchService } from "src/core/services/common/search.service"; describe('Unit tests for SearchService', () => { let searchService: SearchService; let httpService: HttpService; beforeAll(async () => { const moduleRef = await Test.createTestingModule({ providers: [ SearchService, { provide: HttpService, useValue: { get: jest.fn(), }, }, ], imports: [ ConfigModule.forRoot({ isGlobal: true, cache: true, expandVariables: true, }) ], }).compile(); searchService = moduleRef.get(SearchService); httpService = moduleRef.get(HttpService); }); describe('findByID()', () => { it('Should touch HttpService.get() method', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); searchService.findByID(''); expect(httpGetSpy).toHaveBeenCalled(); }); it('Should send correct data via HttpService.get() body parameter', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); const uuid = 'thisIsUUID_Provided'; searchService.findByID(uuid); expect(httpGetSpy).toHaveBeenCalledWith<[string, object]>(expect.anything(), { data: { size: 1, query: { query_string: { query: 'id:' + uuid } } }, headers: { 'Content-Type': 'application/json' } }); }); it('Should call HttpService.get() with correct URI and port number', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); searchService.findByID(''); expect(httpGetSpy).toHaveBeenCalledWith<[string, object]>( `http://${process.env.ES_CONTAINER_NAME}:${process.env.ES_PORT}/_search`, expect.anything() ); }); it('Should return a Promise', () => { expect(searchService.findByID('')).toBeInstanceOf(Promise); }); // it('Should return a Promise with EsResponseDto', () => { // // Axios response mock // httpService.get = jest.fn().mockReturnValueOnce( // of({ // status: undefined, // statusText: undefined, // headers: undefined, // config: undefined, // data: { // took: 1, // timed_out: false, // hits: { // total: {}, // hits: [{}] // } // }, // }) // ); // expect(searchService.findByID('')).resolves.toBeInstanceOf(EsResponseDto) // }); // Errors it('Should throw 504 | GatewayTimeoutException', () => { // Axios response mock httpService.get = jest.fn().mockReturnValueOnce( of({ status: undefined, statusText: undefined, headers: undefined, config: undefined, data: { timed_out: true, dummy: 'dum' } }) ); searchService.findByID('').catch((err) => { expect(err).toBeInstanceOf(GatewayTimeoutException); }); }); it('Should throw an HttpException when HttpService.get() fails and throws', () => { httpService.get = jest.fn().mockImplementationOnce(() => { throw new HttpException({ oops: 'sorry' }, 999); }); searchService.findByID('').catch((err) => { expect(err).toBeInstanceOf(HttpException); expect(err.response).toEqual({ oops: 'sorry' }); expect(err.status).toEqual(999); }); }); }); describe('findByContext()', () => { it('Should touch HttpService.get() method', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); searchService.findByContext(null); expect(httpGetSpy).toHaveBeenCalled(); }); it('Should send correct data via HttpService.get() body parameter', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); let es_query = new EsQueryDto(); es_query = { query: { query_string: { query: 'thisIsTheQuery!' } } } searchService.findByContext(es_query); expect(httpGetSpy).toHaveBeenCalledWith<[string, object]>(expect.anything(), { data: es_query, headers: { 'Content-Type': 'application/json' } }); }); it('Should call HttpService.get() with correct URI and port number', () => { let httpGetSpy = jest.spyOn(httpService, 'get'); searchService.findByContext(null); expect(httpGetSpy).toHaveBeenCalledWith<[string, object]>( `http://${process.env.ES_CONTAINER_NAME}:${process.env.ES_PORT}/_search`, expect.anything() ); }); it('Should return a Promise', () => { expect(searchService.findByContext(null)).toBeInstanceOf(Promise); }); // it('Should return a Promise with EsResponseDto', () => { // // Axios response mock // httpService.get = jest.fn().mockReturnValueOnce( // of({ // status: undefined, // statusText: undefined, // headers: undefined, // config: undefined, // data: { // dummy: 'dum' // } // }) // ); // expect(searchService.findByContext(null)).resolves.toMatchObject(null); // }); // Errors it('Should throw 504 | GatewayTimeoutException', () => { // Axios response mock httpService.get = jest.fn().mockReturnValueOnce( of({ status: undefined, statusText: undefined, headers: undefined, config: undefined, data: { timed_out: true, dummy: 'dum' } }) ); searchService.findByContext(null).catch((err) => { expect(err).toBeInstanceOf(GatewayTimeoutException); }); }); it('Should throw an HttpException when HttpService.get() fails and throws', () => { httpService.get = jest.fn().mockImplementationOnce(() => { throw new HttpException({ oops: 'sorry' }, 999); }); searchService.findByContext(null).catch((err) => { expect(err).toBeInstanceOf(HttpException); expect(err.response).toEqual({ oops: 'sorry' }); expect(err.status).toEqual(999); }); }); }); });