Skip to content

Commit

Permalink
fix: apply delay to cached responses
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinechalifour committed Aug 14, 2019
1 parent cc54a94 commit 593ddd8
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 13 deletions.
15 changes: 14 additions & 1 deletion src/domain/usecase/RespondToRequest.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ResponseRepository } from '../repository';
import { NetworkService } from '../service';

import { RespondToRequest } from './RespondToRequest';
import { Response, Request } from '../entity';
import { RespondToRequest } from './RespondToRequest';
import { wait } from '../../util/timers';

jest.mock('../../util/timers');

let responseRepository: ResponseRepository;
let networkService: NetworkService;

beforeEach(() => {
(wait as jest.Mock).mockReset();
responseRepository = {
getResponseForRequest: jest.fn().mockResolvedValue(null),
persistResponseForRequest: jest.fn().mockResolvedValue(null),
Expand All @@ -26,9 +30,11 @@ describe('when the response is in the cache', () => {

it('should return the response from the cache, without using the network', async () => {
// Given
const delay = 1000;
const useCase = new RespondToRequest({
responseRepository,
networkService,
delay,
});
const method = 'GET';
const url = '/beers/1';
Expand All @@ -47,6 +53,8 @@ describe('when the response is in the cache', () => {
expect(responseRepository.getResponseForRequest).toHaveBeenCalledWith(
new Request(method, url, headers, body)
);
expect(wait).toHaveBeenCalledTimes(1);
expect(wait).toHaveBeenCalledWith(1000);

expect(networkService.executeRequest).not.toHaveBeenCalled();
});
Expand All @@ -63,9 +71,11 @@ describe('when no response is in the cache', () => {
});

it('should fetch the reponse from the network and store it in the cache', async () => {
const delay = 1000;
const useCase = new RespondToRequest({
responseRepository,
networkService,
delay,
});
const method = 'GET';
const url = '/beers/1';
Expand All @@ -92,5 +102,8 @@ describe('when no response is in the cache', () => {
new Request(method, url, headers, body),
new Response(200, { 'cache-control': 'something' }, 'some body')
);

expect(wait).toHaveBeenCalledTimes(1);
expect(wait).toHaveBeenCalledWith(1000);
});
});
26 changes: 20 additions & 6 deletions src/domain/usecase/RespondToRequest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { logger } from '../../util/logger';
import { wait } from '../../util/timers';

import { Method, Response, Request } from '../entity';
import { ResponseRepository } from '../repository';
Expand All @@ -7,6 +8,7 @@ import { NetworkService } from '../service';
interface Dependencies {
responseRepository: ResponseRepository;
networkService: NetworkService;
delay: number;
}

export interface Headers {
Expand All @@ -16,10 +18,16 @@ export interface Headers {
export class RespondToRequest {
private responseRepository: ResponseRepository;
private networkService: NetworkService;
private delay: number;

public constructor({ responseRepository, networkService }: Dependencies) {
public constructor({
responseRepository,
networkService,
delay,
}: Dependencies) {
this.responseRepository = responseRepository;
this.networkService = networkService;
this.delay = delay;
}

public async execute(
Expand All @@ -33,16 +41,22 @@ export class RespondToRequest {
const cachedResponse = await this.responseRepository.getResponseForRequest(
request
);
let response: Response;

if (cachedResponse) {
response = cachedResponse;
logger.debug('Using response from the cache');
return cachedResponse;
} else {
logger.debug('Fetching response from the network');
response = await this.networkService.executeRequest(request);

await this.responseRepository.persistResponseForRequest(
request,
response
);
}

logger.debug('Fetching response from the network');
const response = await this.networkService.executeRequest(request);

await this.responseRepository.persistResponseForRequest(request, response);
await wait(this.delay);

return response;
}
Expand Down
7 changes: 1 addition & 6 deletions src/infrastructure/service/NetworkServiceAxios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@ import { Request, Response } from '../../domain/entity';

interface Dependencies {
targetUrl: string;
delay: number;
}

export class NetworkServiceAxios implements NetworkService {
private targetUrl: string;
private delay: number;

public constructor({ targetUrl, delay }: Dependencies) {
public constructor({ targetUrl }: Dependencies) {
this.targetUrl = targetUrl;
this.delay = delay;
}

public async executeRequest(request: Request): Promise<Response> {
Expand All @@ -27,8 +24,6 @@ export class NetworkServiceAxios implements NetworkService {
// For now we do not support gzip
delete headers['accept-encoding'];

await new Promise(resolve => setTimeout(resolve, this.delay));

const axiosResponse = await axios({
data: request.body,
url: `${this.targetUrl}${request.url}`,
Expand Down
1 change: 1 addition & 0 deletions src/util/__mocks__/timers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const wait = jest.fn();
2 changes: 2 additions & 0 deletions src/util/timers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const wait = (time: number) =>
new Promise(resolve => setTimeout(resolve, time));

0 comments on commit 593ddd8

Please sign in to comment.