318 lines
11 KiB
TypeScript
318 lines
11 KiB
TypeScript
import { HttpService } from "@nestjs/axios";
|
|
import { ConfigModule } from "@nestjs/config";
|
|
import { Test } from "@nestjs/testing";
|
|
import { Observable, of } from "rxjs";
|
|
import { EsTime, Order } from "src/core/domain";
|
|
import { PageDto } from "src/core/domain/dtos";
|
|
import { HttpResponseException } from "src/core/exceptions";
|
|
import { PageInterceptor } from "src/core/interceptors/page.interceptor";
|
|
|
|
const execCtxMock = {
|
|
switchToHttp: jest.fn().mockReturnThis(),
|
|
getRequest: jest.fn().mockReturnThis(),
|
|
getHandler: jest.fn().mockReturnThis(),
|
|
getArgs: jest.fn().mockReturnThis(),
|
|
getArgByIndex: jest.fn().mockReturnThis(),
|
|
switchToRpc: jest.fn().mockReturnThis(),
|
|
switchToWs: jest.fn().mockReturnThis(),
|
|
getType: jest.fn().mockReturnThis(),
|
|
getClass: jest.fn().mockReturnThis(),
|
|
};
|
|
|
|
const callHandlerMock = {
|
|
handle: jest.fn(),
|
|
};
|
|
|
|
describe('Unit tests for PageInterceptor', () => {
|
|
let pageInter: PageInterceptor;
|
|
let httpService: HttpService;
|
|
|
|
beforeAll(async () => {
|
|
const moduleRef = await Test.createTestingModule({
|
|
providers: [
|
|
{
|
|
provide: HttpService,
|
|
useValue: {
|
|
post: jest.fn(),
|
|
delete: jest.fn()
|
|
},
|
|
},
|
|
PageInterceptor,
|
|
],
|
|
imports: [
|
|
ConfigModule.forRoot({
|
|
isGlobal: true,
|
|
cache: true,
|
|
expandVariables: true,
|
|
})
|
|
],
|
|
}).compile();
|
|
|
|
pageInter = moduleRef.get(PageInterceptor);
|
|
httpService = moduleRef.get(HttpService);
|
|
|
|
execCtxMock.getRequest.mockReturnValue({
|
|
query: {
|
|
query: 'thisIsMyQuery',
|
|
page: 1,
|
|
limit: 5,
|
|
order: Order.DESC
|
|
}
|
|
});
|
|
|
|
callHandlerMock.handle.mockReturnValue(
|
|
of({
|
|
hits: {
|
|
total: { value: 1 },
|
|
hits: [{}]
|
|
}
|
|
})
|
|
);
|
|
});
|
|
|
|
it('Should be defined', () => {
|
|
expect(pageInter).toBeDefined();
|
|
expect(httpService).toBeDefined();
|
|
});
|
|
|
|
describe('intercept()', () => {
|
|
let tmp;
|
|
beforeAll(() => {
|
|
tmp = pageInter.getPIT;
|
|
pageInter.getPIT = jest.fn().mockReturnValue({});
|
|
});
|
|
|
|
afterAll(() => {
|
|
pageInter.getPIT = tmp;
|
|
});
|
|
|
|
it('Should return a Promise', () => {
|
|
expect(pageInter.intercept(execCtxMock, callHandlerMock)).toBeInstanceOf(Promise);
|
|
});
|
|
|
|
it('Should return a Promise with Observable and PageDto inside', () => {
|
|
pageInter.intercept(execCtxMock, callHandlerMock).then((res) => {
|
|
expect(res).toBeInstanceOf(Observable);
|
|
res.subscribe((data) => {
|
|
expect(data).toBeInstanceOf(PageDto);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Should touch CallHandler.handle() method', () => {
|
|
let chHandleSpy = jest.spyOn(callHandlerMock, 'handle');
|
|
pageInter.intercept(execCtxMock, callHandlerMock);
|
|
expect(chHandleSpy).toBeCalled();
|
|
});
|
|
|
|
it('Should construct a page with proper data on it', () => {
|
|
callHandlerMock.handle.mockReturnValueOnce(
|
|
of({
|
|
hits: {
|
|
total: { value: 1 },
|
|
hits: [{
|
|
_source: {
|
|
dummy: 'dum'
|
|
}
|
|
}]
|
|
}
|
|
})
|
|
);
|
|
|
|
pageInter.intercept(execCtxMock, callHandlerMock).then((res) => {
|
|
res.subscribe((page) => {
|
|
expect(page.data.length).toBe(1);
|
|
expect(page.data[0]).toEqual({ dummy: 'dum' });
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Should construct correct meta-data of the page', () => {
|
|
execCtxMock.getRequest.mockReturnValueOnce({
|
|
query: {
|
|
page: 5,
|
|
order: 'desc',
|
|
limit: 100,
|
|
}
|
|
});
|
|
|
|
callHandlerMock.handle.mockReturnValueOnce(
|
|
of({
|
|
hits: {
|
|
total: { value: 921 },
|
|
hits: []
|
|
}
|
|
})
|
|
);
|
|
|
|
pageInter.intercept(execCtxMock, callHandlerMock).then((res) => {
|
|
res.subscribe((page) => {
|
|
expect(page.meta).toEqual({
|
|
total: 921,
|
|
pagenum: 5,
|
|
order: 'desc',
|
|
hasNext: true,
|
|
hasPrev: true,
|
|
pagesize: 100
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('Should reverse the search results', () => {
|
|
execCtxMock.getRequest.mockReturnValueOnce({
|
|
query: {
|
|
page: 1,
|
|
order: 'desc',
|
|
limit: 3
|
|
}
|
|
});
|
|
|
|
pageInter['prevSearch']._prevPage = 3;
|
|
pageInter['prevSearch'].isSet = jest.fn().mockImplementationOnce(() => {
|
|
return true;
|
|
})
|
|
|
|
callHandlerMock.handle.mockReturnValueOnce(
|
|
of({
|
|
hits: {
|
|
total: { value: 1 },
|
|
hits: [
|
|
{ sort: ['1', 'less relevant'], _source: '1' },
|
|
{ sort: ['2', 'average'], _source: '2' },
|
|
{ sort: ['3', 'most relevant'], _source: '3' }
|
|
]
|
|
}
|
|
})
|
|
);
|
|
|
|
pageInter.intercept(execCtxMock, callHandlerMock).then((res) => {
|
|
res.subscribe((page) => {
|
|
expect(pageInter['prevSearch']._tiebreaker).toEqual(['1', 'less relevant']);
|
|
expect(page.data).toEqual(['3', '2', '1']);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('getPIT()', () => {
|
|
it('Should touch HttpService.post() method', () => {
|
|
let httpPostMock = jest.spyOn(httpService, 'post').mockReturnValueOnce(of({
|
|
data: {id: '2567'},
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
pageInter.getPIT(1);
|
|
expect(httpPostMock).toHaveBeenCalled();
|
|
});
|
|
|
|
it('Should contain correct port in the URI from .env', () => {
|
|
let httpPostMock = jest.spyOn(httpService, 'post').mockReturnValueOnce(of({
|
|
data: {id: '2567'},
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
pageInter.getPIT(1);
|
|
expect(httpPostMock).toHaveBeenCalledWith(`http://${process.env.ES_CONTAINER_NAME}:${process.env.ES_PORT}/papers/_pit?keep_alive=1m`);
|
|
});
|
|
|
|
it('Should touch HttpService with correct URI when time alive and time-unit are set', () => {
|
|
let httpPostMock = jest.spyOn(httpService, 'post').mockReturnValueOnce(of({
|
|
data: {id: '2567'},
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
let time = 2;
|
|
let unit = EsTime.sec;
|
|
|
|
pageInter.getPIT(time, unit);
|
|
expect(httpPostMock).toHaveBeenCalledWith(`http://${process.env.ES_CONTAINER_NAME}:${process.env.ES_PORT}/papers/_pit?keep_alive=${time+unit}`);
|
|
});
|
|
|
|
it('Should return error exeception when HttpService fails', () => {
|
|
jest.spyOn(httpService, 'post').mockImplementationOnce(() => {
|
|
throw HttpResponseException;
|
|
});
|
|
|
|
expect(pageInter.getPIT(1)).rejects.toEqual(HttpResponseException);
|
|
});
|
|
|
|
it('Should return a non-empty string when HttpService request succeedes', () => {
|
|
jest.spyOn(httpService, 'post').mockReturnValueOnce(of({
|
|
data: {id: '2567', keep_alive: '1m'},
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
expect(pageInter.getPIT(1)).resolves.toEqual({
|
|
id: '2567',
|
|
keep_alive: '1m',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('deletePIT()', () => {
|
|
it('Should touch HttpService.delete() method', () => {
|
|
let httpDeleteMock = jest.spyOn(httpService, 'delete').mockReturnValueOnce(
|
|
of({
|
|
data: {succeeded: true},
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
pageInter.deletePIT('');
|
|
expect(httpDeleteMock).toHaveBeenCalled();
|
|
});
|
|
|
|
it('Should contain correct port in the URI from .env and passed PIT ID in the request body', () => {
|
|
let httpDeleteMock = jest.spyOn(httpService, 'delete').mockReturnValueOnce(
|
|
of({
|
|
data: { succeeded: true },
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
pageInter.deletePIT('thisIsIDSpecified');
|
|
expect(httpDeleteMock).toHaveBeenCalledWith(`http://${process.env.ES_CONTAINER_NAME}:${process.env.ES_PORT}/_pit`, {
|
|
data: { id: 'thisIsIDSpecified' },
|
|
headers: { 'Content-Type': 'application/json' }
|
|
});
|
|
});
|
|
|
|
it('Should return error exeception when HttpService fails', () => {
|
|
jest.spyOn(httpService, 'delete').mockImplementationOnce(() => {
|
|
throw HttpResponseException;
|
|
});
|
|
|
|
expect(pageInter.deletePIT('')).rejects.toEqual(HttpResponseException);
|
|
});
|
|
|
|
it('Should return true when Elasticsearch successfully removed PIT', () => {
|
|
jest.spyOn(httpService, 'delete').mockReturnValueOnce(
|
|
of({
|
|
data: { succeeded: true },
|
|
status: 0,
|
|
statusText: '',
|
|
headers: {},
|
|
config: {},
|
|
}));
|
|
|
|
expect(pageInter.deletePIT('')).resolves.toBe(true);
|
|
});
|
|
});
|
|
}); |