Skip to content

Commit

Permalink
feat: add info command
Browse files Browse the repository at this point in the history
  • Loading branch information
antoinechalifour committed Aug 18, 2019
1 parent d4906b2 commit 46c2e17
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 2 deletions.
46 changes: 46 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ClearRequest,
RefreshRequest,
ListRequest,
GetRequestDetails,
} from './domain/usecase';

interface CreateCliOptions {
Expand All @@ -32,6 +33,9 @@ export function createCli({ container }: CreateCliOptions) {
const listRequestsUseCase = container.resolve<ListRequest>(
'listRequestsUseCase'
);
const getRequestDetailsUseCase = container.resolve<GetRequestDetails>(
'getRequestDetailsUseCase'
);

const vorpal = new Vorpal();

Expand Down Expand Up @@ -90,6 +94,48 @@ export function createCli({ container }: CreateCliOptions) {
this.log('Done.');
});

vorpal
.command(
'info <requestId>',
'Displays information about the request and its response'
)
.option('-b, --body', 'Include the response body')
.action(async function(
this: Vorpal.CommandInstance,
{ requestId, options }
) {
const [request, response] = await getRequestDetailsUseCase.execute(
requestId
);

this.log(chalk`{green Request information}`);
this.log(
table([
[chalk.yellow('Method'), chalk.white(request.method)],
[chalk.yellow('URL'), chalk.white(request.url)],
...Object.keys(request.headers).map(headerName => [
chalk.yellow(headerName),
chalk.white(request.headers[headerName]),
]),
])
);

this.log(chalk`\n\n{green Response information}`);
this.log(
table([
...Object.keys(response.headers).map(headerName => [
chalk.yellow(headerName),
chalk.white(response.headers[headerName]),
]),
])
);

if (options.body) {
this.log(chalk`\n\n{green Response body}`);
this.log(response.body);
}
});

console.log(chalk`{green
__ __ _______ __ __ _______ __ _ _______ _______
| |_| || || |_| || || | | || || |
Expand Down
71 changes: 71 additions & 0 deletions src/domain/usecase/GetRequestDetails.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { getTestRequestRepository } from '../../test-utils/infrastructure';
import { RequestRepository } from '../repository';
import { Request, Response } from '../entity';
import { GetRequestDetails } from './GetRequestDetails';

let useCase: GetRequestDetails;
let requestRepository: RequestRepository;

beforeEach(() => {
requestRepository = getTestRequestRepository();

useCase = new GetRequestDetails({ requestRepository });
});

it('should return a tuple with the request and the response', async () => {
// Given
const requestId = 'request-id';
const request = new Request('GET', '/test', {}, '');
const response = new Response(201, {}, 'Hello world');

(requestRepository.getRequestById as jest.Mock).mockResolvedValue(request);
(requestRepository.getResponseByRequestId as jest.Mock).mockResolvedValue(
response
);

// When
const result = await useCase.execute(requestId);

//Then
expect(result).toEqual([request, response]);
expect(requestRepository.getRequestById).toHaveBeenCalledTimes(1);
expect(requestRepository.getRequestById).toHaveBeenCalledWith(requestId);
expect(requestRepository.getResponseByRequestId).toHaveBeenCalledTimes(1);
expect(requestRepository.getResponseByRequestId).toHaveBeenCalledWith(
requestId
);
});

it('should throw when the request is not found', async () => {
expect.assertions(1);

// Given
(requestRepository.getRequestById as jest.Mock).mockResolvedValue(null);

// When
try {
await useCase.execute('');
} catch (err) {
// Then
expect(err).toEqual(new Error('Request not found'));
}
});

it('should throw when the response is not found', async () => {
expect.assertions(1);

// Given
const request = new Request('GET', '/test', {}, '');
(requestRepository.getRequestById as jest.Mock).mockResolvedValue(request);
(requestRepository.getResponseByRequestId as jest.Mock).mockResolvedValue(
null
);

// When
try {
await useCase.execute('');
} catch (err) {
// Then
expect(err).toEqual(new Error('Response not found'));
}
});
31 changes: 31 additions & 0 deletions src/domain/usecase/GetRequestDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { RequestRepository } from '../repository';
import { Request, Response } from '../entity';

interface Dependencies {
requestRepository: RequestRepository;
}

export class GetRequestDetails {
private requestRepository: RequestRepository;

public constructor({ requestRepository }: Dependencies) {
this.requestRepository = requestRepository;
}

public async execute(requestId: string): Promise<[Request, Response]> {
const [request, response] = await Promise.all([
this.requestRepository.getRequestById(requestId),
this.requestRepository.getResponseByRequestId(requestId),
]);

if (!request) {
throw new Error('Request not found');
}

if (!response) {
throw new Error('Response not found');
}

return [request, response];
}
}
2 changes: 1 addition & 1 deletion src/domain/usecase/ListRequests.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getTestRequestRepository } from '../../test-utils/infrastructure';
import { RequestRepository } from '../repository';
import { Request } from '../entity';
import { ListRequest } from './ListRequest';
import { ListRequest } from './ListRequests';

let useCase: ListRequest;
let requestRepository: RequestRepository;
Expand Down
File renamed without changes.
3 changes: 2 additions & 1 deletion src/domain/usecase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export * from './RespondToRequest';
export * from './ClearAllRequests';
export * from './ClearRequest';
export * from './RefreshRequest';
export * from './ListRequest';
export * from './ListRequests';
export * from './GetRequestDetails';
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ClearRequest,
RefreshRequest,
ListRequest,
GetRequestDetails,
} from './domain/usecase';
import { NetworkServiceAxios } from './infrastructure/service';
import { RequestRepositoryFile } from './infrastructure/repository';
Expand All @@ -29,6 +30,7 @@ container.register({
clearRequestUseCase: asClass(ClearRequest),
refreshRequestUseCase: asClass(RefreshRequest),
listRequestsUseCase: asClass(ListRequest),
getRequestDetailsUseCase: asClass(GetRequestDetails),

// Repositories
requestRepository: asClass(RequestRepositoryFile).singleton(),
Expand Down

0 comments on commit 46c2e17

Please sign in to comment.