Test coverage for pagination and search service.
This commit is contained in:
parent
5eb20c4727
commit
26cd205738
@ -1,8 +1,7 @@
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common";
|
||||
import { Observable, map, take } from "rxjs";
|
||||
import { EsResponseDto, PageDto } from "../domain/dtos";
|
||||
import { EsHitDto } from "../domain/dtos/es-hit.dto";
|
||||
import { PageDto } from "../domain/dtos";
|
||||
import { EsQueryDto } from "../domain/dtos/es-query.dto";
|
||||
import { RequestDto } from "../domain/dtos/request.dto";
|
||||
import { SearchQueryDto } from "../domain/dtos/search-q.dto";
|
||||
@ -10,12 +9,11 @@ import { EsTime } from "../domain/enums/es-time.enum";
|
||||
import { Order } from "../domain/enums/page-order.enum";
|
||||
import { PageMeta } from "../domain/interfaces";
|
||||
import { EsPit } from "../domain/interfaces/es-pit.interface";
|
||||
import { SearchInfo } from "../domain/interfaces/search-info.interface";
|
||||
|
||||
/**
|
||||
* Previous search data storage
|
||||
*/
|
||||
class PrevSearch implements SearchInfo {
|
||||
class PrevSearch {
|
||||
/**
|
||||
* Constructs an uninitialized object
|
||||
*/
|
||||
@ -28,17 +26,35 @@ class PrevSearch implements SearchInfo {
|
||||
/**
|
||||
* PIT object of the previous search
|
||||
*/
|
||||
pit: EsPit;
|
||||
private pit: EsPit;
|
||||
set _pit(pit: EsPit) {
|
||||
this.pit = pit;
|
||||
}
|
||||
get _pit(): EsPit {
|
||||
return this.pit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tiebreaker and sort parameters
|
||||
*/
|
||||
tiebreaker: unknown[];
|
||||
private tiebreaker: unknown[];
|
||||
set _tiebreaker(tiebreaker: unknown[]) {
|
||||
this.tiebreaker = tiebreaker;
|
||||
}
|
||||
get _tiebreaker(): unknown[] {
|
||||
return this.tiebreaker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of the previous page
|
||||
*/
|
||||
prevPage: number;
|
||||
private prevPage: number;
|
||||
set _prevPage(page: number) {
|
||||
this.prevPage = page;
|
||||
}
|
||||
get _prevPage(): number {
|
||||
return this.prevPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there was the search before current one
|
||||
@ -89,23 +105,23 @@ export class PageInterceptor implements NestInterceptor {
|
||||
];
|
||||
|
||||
if (this.prevSearch.isSet()) {
|
||||
request.es_query.pit = this.prevSearch.pit;
|
||||
request.es_query.search_after = this.prevSearch.tiebreaker;
|
||||
request.es_query.pit = this.prevSearch._pit;
|
||||
request.es_query.search_after = this.prevSearch._tiebreaker;
|
||||
|
||||
let limit = !query?.limit ? 10 : query.limit;
|
||||
request.es_query.size = limit * Math.abs(query.page - this.prevSearch.prevPage);
|
||||
request.es_query.size = limit * Math.abs(query.page - this.prevSearch._prevPage);
|
||||
|
||||
if (query.page < this.prevSearch.prevPage) {
|
||||
if (query.page < this.prevSearch._prevPage) {
|
||||
request.es_query.sort = [{ _score: { order: 'asc' } }];
|
||||
request.es_query.size += limit - 1;
|
||||
reverse = true;
|
||||
} else if (query.page == this.prevSearch.prevPage) {
|
||||
} else if (query.page == this.prevSearch._prevPage) {
|
||||
// Caching should be HERE
|
||||
request.es_query.sort = [{ _score: { order: 'asc' } }];
|
||||
reverse = true;
|
||||
}
|
||||
} else {
|
||||
this.prevSearch.pit = request.es_query.pit = await this.getPIT(1);
|
||||
this.prevSearch._pit = request.es_query.pit = await this.getPIT(1);
|
||||
|
||||
let limit = !query?.limit ? 10 : query.limit;
|
||||
request.es_query.size = limit * query.page;
|
||||
@ -116,24 +132,24 @@ export class PageInterceptor implements NestInterceptor {
|
||||
// Setting the page meta-data
|
||||
let meta: PageMeta = {
|
||||
total: res.hits.total.value,
|
||||
pagenum: !query?.page ? 1 : query.page,
|
||||
pagenum: !query?.page ? 1 : +query.page,
|
||||
order: query?.order?.toUpperCase() === Order.ASC ? Order.ASC : Order.DESC,
|
||||
pagesize: !query?.limit ? 10 : query.limit,
|
||||
hasNext: undefined,
|
||||
hasPrev: undefined,
|
||||
pagesize: !query?.limit ? 10 : query.limit,
|
||||
};
|
||||
meta.hasNext = meta.pagenum * meta.pagesize < meta.total ? true : false;
|
||||
meta.hasPrev = meta.pagenum != 1 ? true : false;
|
||||
|
||||
// Saving the search info
|
||||
this.prevSearch.pit.id = res.pit_id;
|
||||
this.prevSearch.tiebreaker = res.hits.hits[res.hits.hits.length - 1]?.sort;
|
||||
this.prevSearch.prevPage = query.page;
|
||||
this.prevSearch._pit.id = res.pit_id;
|
||||
this.prevSearch._tiebreaker = res.hits.hits[res.hits.hits.length - 1]?.sort;
|
||||
this.prevSearch._prevPage = query.page;
|
||||
|
||||
// Check if the performed search is a backward search
|
||||
// Check if the performed search is a backwards search
|
||||
let data = res.hits.hits.slice(-meta.pagesize);
|
||||
if (reverse) {
|
||||
this.prevSearch.tiebreaker = data[0]?.sort;
|
||||
this.prevSearch._tiebreaker = data[0]?.sort;
|
||||
data.reverse();
|
||||
reverse = false;
|
||||
}
|
||||
@ -165,12 +181,12 @@ export class PageInterceptor implements NestInterceptor {
|
||||
public async getPIT(alive: number, unit: EsTime = EsTime.min): Promise<EsPit> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
(this.httpService.post<EsPit>(`http://localhost:${this.ES_PORT}/papers/_pit?keep_alive=${alive+unit}`)
|
||||
this.httpService.post<EsPit>(`http://localhost:${this.ES_PORT}/papers/_pit?keep_alive=${alive+unit}`)
|
||||
.pipe(take(1), map(axiosRes => axiosRes.data))
|
||||
.subscribe((res) => {
|
||||
.subscribe((res: EsPit) => {
|
||||
res.keep_alive = alive + unit;
|
||||
resolve(res);
|
||||
}));
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
82
src/test/e2e/papers.endpoint.spec.ts
Normal file
82
src/test/e2e/papers.endpoint.spec.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { INestApplication } from "@nestjs/common";
|
||||
import request from 'supertest'
|
||||
import { AppModule } from "src/infrastructure/modules";
|
||||
|
||||
describe('E2E Testing of /papers', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('GET /papers/{uuid} | Should return one exact item on page', async () => {
|
||||
const test = await request(app.getHttpServer())
|
||||
.get('/papers/eeeb2d01-8315-454e-b33f-3d6caa25db42') // ??? Fetch a random object from DB
|
||||
.expect(200);
|
||||
|
||||
// Checking received data
|
||||
expect(test.body.data).toBeDefined();
|
||||
|
||||
expect(test.body.data.length).toBe(1);
|
||||
expect(test.body.data[0].id).toBeDefined();
|
||||
expect(test.body.data[0].title).toBeDefined();
|
||||
expect(test.body.data[0].authors).toBeDefined();
|
||||
expect(test.body.data[0].summary).toBeDefined();
|
||||
expect(test.body.data[0].tags).toBeDefined();
|
||||
expect(test.body.data[0].content).toBeDefined();
|
||||
expect(test.body.data[0].id).toBe('eeeb2d01-8315-454e-b33f-3d6caa25db42');
|
||||
|
||||
// Checking received meta
|
||||
expect(test.body.meta).toBeDefined();
|
||||
|
||||
expect(test.body.meta.total).toBeDefined();
|
||||
expect(test.body.meta.pagenum).toBeDefined();
|
||||
expect(test.body.meta.order).toBeDefined();
|
||||
expect(test.body.meta.pagesize).toBeDefined();
|
||||
expect(test.body.meta.hasNext).toBeDefined();
|
||||
expect(test.body.meta.hasPrev).toBeDefined();
|
||||
expect(test.body.meta.total).toBe(1);
|
||||
expect(test.body.meta.pagenum).toBe(1);
|
||||
});
|
||||
|
||||
it('GET /papers/search? | Should return multiple items', async () => {
|
||||
const test = await request(app.getHttpServer())
|
||||
.get('/papers/search?query=at&page=1')
|
||||
.expect(200);
|
||||
|
||||
// Checking received data
|
||||
expect(test.body.data).toBeDefined();
|
||||
|
||||
expect(test.body.data.length).toBeGreaterThan(0);
|
||||
for (const paper of test.body.data) {
|
||||
expect(paper.id).toBeDefined();
|
||||
expect(paper.title).toBeDefined();
|
||||
expect(paper.authors).toBeDefined();
|
||||
expect(paper.summary).toBeDefined();
|
||||
expect(paper.tags).toBeDefined();
|
||||
expect(paper.content).toBeDefined();
|
||||
}
|
||||
|
||||
// Checking received meta
|
||||
expect(test.body.meta).toBeDefined();
|
||||
|
||||
expect(test.body.meta.total).toBeDefined();
|
||||
expect(test.body.meta.pagenum).toBeDefined();
|
||||
expect(test.body.meta.order).toBeDefined();
|
||||
expect(test.body.meta.pagesize).toBeDefined();
|
||||
expect(test.body.meta.hasNext).toBeDefined();
|
||||
expect(test.body.meta.hasPrev).toBeDefined();
|
||||
expect(test.body.meta.total).toBeGreaterThan(0);
|
||||
expect(test.body.meta.pagenum).toBe(1);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
})
|
||||
});
|
@ -1,12 +1,12 @@
|
||||
import { HttpModule } from "@nestjs/axios";
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { ConfigModule } from "@nestjs/config";
|
||||
import { ModuleRef } from "@nestjs/core";
|
||||
import { Test } from "@nestjs/testing";
|
||||
import exp from "constants";
|
||||
import { Observable, of } from "rxjs";
|
||||
import { PapersController } from "src/application";
|
||||
import { Order } from "src/core/domain";
|
||||
import { PageDto, SearchQueryDto } from "src/core/domain/dtos";
|
||||
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";
|
||||
import { SearchService } from "src/core/services/common/search.service";
|
||||
|
||||
const execCtxMock = {
|
||||
switchToHttp: jest.fn().mockReturnThis(),
|
||||
@ -26,18 +26,31 @@ const callHandlerMock = {
|
||||
|
||||
describe('Unit tests for PageInterceptor', () => {
|
||||
let pageInter: PageInterceptor;
|
||||
let moduleRef;
|
||||
let httpService: HttpService;
|
||||
|
||||
beforeAll(async () => {
|
||||
moduleRef = await Test.createTestingModule({
|
||||
imports: [HttpModule],
|
||||
controllers: [PapersController],
|
||||
providers: [SearchService, PageInterceptor],
|
||||
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);
|
||||
|
||||
pageInter.getPIT = jest.fn().mockReturnValue({});
|
||||
httpService = moduleRef.get(HttpService);
|
||||
|
||||
execCtxMock.getRequest.mockReturnValue({
|
||||
query: {
|
||||
@ -48,19 +61,32 @@ describe('Unit tests for PageInterceptor', () => {
|
||||
}
|
||||
});
|
||||
|
||||
callHandlerMock.handle.mockReturnValueOnce(
|
||||
callHandlerMock.handle.mockReturnValue(
|
||||
of({
|
||||
hits: {
|
||||
total: { value: 1 },
|
||||
hits: { hits: [{}] }
|
||||
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);
|
||||
});
|
||||
@ -74,80 +100,233 @@ describe('Unit tests for PageInterceptor', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it.todo('Should touch CallHandler.handle() method');
|
||||
|
||||
|
||||
// it('Should return an Observable with a page of type PageDto', (done) => {
|
||||
// executionContext.getRequest.mockReturnValue( { query: new SearchQueryDto('someQuery', 1, 10, 'desc') });
|
||||
// callHandler.handle.mockReturnValue( of({
|
||||
// total: { value: 1 },
|
||||
// hits: [{},],
|
||||
// }));
|
||||
|
||||
|
||||
// expect(pageInter.intercept(executionContext, callHandler)).toBeInstanceOf(Promise);
|
||||
// pageInter.intercept(executionContext, callHandler).then(res => res.subscribe((data) => {
|
||||
// expect(data).toBeInstanceOf(PageDto);
|
||||
// done();
|
||||
// }));
|
||||
// })
|
||||
|
||||
// it('Should hold content on the returned page', (done) => {
|
||||
// executionContext.getRequest.mockReturnValueOnce( { query: new SearchQueryDto('someQuery', 1, 10, 'desc') });
|
||||
// callHandler.handle.mockReturnValueOnce(of({
|
||||
// total: { value: 1 },
|
||||
// hits: [{dummy: 'dum'}],
|
||||
// }));
|
||||
|
||||
// pageInter.intercept(executionContext, callHandler).then(res => res.subscribe((data) => {
|
||||
// expect(data).toEqual({
|
||||
// data: expect.anything(),
|
||||
// meta: expect.anything(),
|
||||
// });
|
||||
// done();
|
||||
// }));
|
||||
// });
|
||||
|
||||
// it('Should have next page', (done) => {
|
||||
// executionContext.getRequest.mockReturnValue({ query: new SearchQueryDto('someQuery', 1, 5, 'desc') });
|
||||
// callHandler.handle.mockReturnValue(of({
|
||||
// total: { value: 10 },
|
||||
// hits: Array(10).fill({dummy: 'dum'}, 0, 10),
|
||||
// }));
|
||||
|
||||
// pageInter.intercept(executionContext, callHandler).then(res => res.subscribe((data) => {
|
||||
// expect(data.meta.hasNext).toEqual(true);
|
||||
// expect(data.meta.hasPrev).toEqual(false);
|
||||
// done();
|
||||
// }));
|
||||
// });
|
||||
|
||||
// it('Should have correct meta-data', (done) => {
|
||||
// executionContext.getRequest.mockReturnValue({ query: new SearchQueryDto('someQuery', 2, 5, 'asc') });
|
||||
// callHandler.handle.mockReturnValue(of({
|
||||
// total: { value: 15 },
|
||||
// hits: Array(15).fill({dummy: 'dum'}, 0, 15),
|
||||
// }));
|
||||
|
||||
// pageInter.intercept(executionContext, callHandler).then(res => res.subscribe((data) => {
|
||||
// expect(data.meta).toEqual({
|
||||
// total: 15,
|
||||
// pagenum: 2,
|
||||
// order: Order.ASC,
|
||||
// hasNext: true,
|
||||
// hasPrev: true,
|
||||
// pagesize: 5
|
||||
// });
|
||||
// done();
|
||||
// }));
|
||||
// });
|
||||
it('Should touch CallHandler.handle() method', () => {
|
||||
let chHandleSpy = jest.spyOn(callHandlerMock, 'handle');
|
||||
pageInter.intercept(execCtxMock, callHandlerMock);
|
||||
expect(chHandleSpy).toBeCalled();
|
||||
});
|
||||
|
||||
// describe('getPIT()', () => {
|
||||
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://localhost:${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://localhost:${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 httpPostMock = jest.spyOn(httpService, 'delete').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://localhost:${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://localhost:${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',
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
@ -1,47 +0,0 @@
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { INestApplication } from "@nestjs/common";
|
||||
import request from 'supertest'
|
||||
import { AppModule } from "src/infrastructure/modules";
|
||||
|
||||
describe('E2E Testing of /papers', () => {
|
||||
let app: INestApplication;
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef: TestingModule = await Test.createTestingModule({
|
||||
imports: [AppModule],
|
||||
}).compile();
|
||||
|
||||
app = moduleRef.createNestApplication();
|
||||
await app.init();
|
||||
});
|
||||
|
||||
it('Should return one exact item on page', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/papers/eeeb2d01-8315-454e-b33f-3d6caa25db42')
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
res.body.data.length === 1;
|
||||
})
|
||||
.expect((res) => {
|
||||
res.body.data[0]._source.id === 'eeeb2d01-8315-454e-b33f-3d6caa25db42';
|
||||
});
|
||||
});
|
||||
|
||||
it('Should return multiple items', async () => {
|
||||
return request(app.getHttpServer())
|
||||
.get('/papers/search?query=at&page=1')
|
||||
.expect(200)
|
||||
.expect((res) => {
|
||||
res.body.data.length > 0;
|
||||
})
|
||||
.expect((res) => {
|
||||
for (const value of res.body.data) {
|
||||
if(Object.keys(value).length === 0) return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
})
|
||||
});
|
@ -10,7 +10,6 @@ describe('Unit tests for SearchService', () => {
|
||||
let searchService: SearchService;
|
||||
let httpService: HttpService;
|
||||
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleRef = await Test.createTestingModule({
|
||||
providers: [
|
||||
@ -114,7 +113,6 @@ describe('Unit tests for SearchService', () => {
|
||||
|
||||
searchService.findByID('').catch((err) => {
|
||||
expect(err).toBeInstanceOf(GatewayTimeoutException);
|
||||
console.log(err)
|
||||
});
|
||||
});
|
||||
|
||||
@ -211,7 +209,6 @@ describe('Unit tests for SearchService', () => {
|
||||
|
||||
searchService.findByContext(null).catch((err) => {
|
||||
expect(err).toBeInstanceOf(GatewayTimeoutException);
|
||||
console.log(err)
|
||||
});
|
||||
});
|
||||
|
||||
@ -228,79 +225,3 @@ describe('Unit tests for SearchService', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* describe('getPIT()', () => {
|
||||
it('Should touch HttpService.post() method', () => {
|
||||
let postMock = jest.spyOn(httpService, 'post').mockReturnValue(of({
|
||||
data: {id: '2567'},
|
||||
status: 0,
|
||||
statusText: '',
|
||||
headers: {},
|
||||
config: {},
|
||||
}));
|
||||
|
||||
searchService.getPIT(1);
|
||||
expect(postMock).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Should contain correct port in the URI from .env', () => {
|
||||
let postMock = jest.spyOn(httpService, 'post').mockReturnValue(of({
|
||||
data: {id: '2567'},
|
||||
status: 0,
|
||||
statusText: '',
|
||||
headers: {},
|
||||
config: {},
|
||||
}));
|
||||
|
||||
searchService.getPIT(1);
|
||||
expect(postMock).toHaveBeenCalledWith(`http://localhost:${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 postMock = jest.spyOn(httpService, 'post').mockReturnValue(of({
|
||||
data: {id: '2567'},
|
||||
status: 0,
|
||||
statusText: '',
|
||||
headers: {},
|
||||
config: {},
|
||||
}));
|
||||
|
||||
let time = 2;
|
||||
let unit = EsTime.sec;
|
||||
|
||||
searchService.getPIT(time, unit);
|
||||
expect(postMock).toHaveBeenCalledWith(`http://localhost:${process.env.ES_PORT}/papers/_pit?keep_alive=${time+unit}`);
|
||||
});
|
||||
|
||||
it('Should return error exeception when HttpService fails', () => {
|
||||
jest.spyOn(httpService, 'post').mockImplementation(() => {
|
||||
throw HttpResponseException;
|
||||
});
|
||||
|
||||
expect(searchService.getPIT(1)).rejects.toEqual(HttpResponseException);
|
||||
});
|
||||
|
||||
it('Should return a non-empty string when HttpService request succeedes', () => {
|
||||
jest.spyOn(httpService, 'post').mockReturnValue(of({
|
||||
data: {id: '2567', keep_alive: '1m'},
|
||||
status: 0,
|
||||
statusText: '',
|
||||
headers: {},
|
||||
config: {},
|
||||
}));
|
||||
|
||||
expect(searchService.getPIT(1)).resolves.toEqual({
|
||||
id: '2567',
|
||||
keep_alive: '1m',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('deletePIT()', () => {
|
||||
it.todo('Should fail to delete, because the requested PIT ID is invalid');
|
||||
it.todo('Should call HttpService.delete() method with correct body');
|
||||
});
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user