diff --git a/src/cli.ts b/src/cli.ts index edff2f5..95b5032 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,6 +10,7 @@ import { ClearRequest, RefreshRequest, ListRequest, + GetRequestDetails, } from './domain/usecase'; interface CreateCliOptions { @@ -32,6 +33,9 @@ export function createCli({ container }: CreateCliOptions) { const listRequestsUseCase = container.resolve( 'listRequestsUseCase' ); + const getRequestDetailsUseCase = container.resolve( + 'getRequestDetailsUseCase' + ); const vorpal = new Vorpal(); @@ -90,6 +94,48 @@ export function createCli({ container }: CreateCliOptions) { this.log('Done.'); }); + vorpal + .command( + 'info ', + '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 __ __ _______ __ __ _______ __ _ _______ _______ | |_| || || |_| || || | | || || | diff --git a/src/domain/usecase/GetRequestDetails.test.ts b/src/domain/usecase/GetRequestDetails.test.ts new file mode 100644 index 0000000..9a76f8d --- /dev/null +++ b/src/domain/usecase/GetRequestDetails.test.ts @@ -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')); + } +}); diff --git a/src/domain/usecase/GetRequestDetails.ts b/src/domain/usecase/GetRequestDetails.ts new file mode 100644 index 0000000..3cd2855 --- /dev/null +++ b/src/domain/usecase/GetRequestDetails.ts @@ -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]; + } +} diff --git a/src/domain/usecase/ListRequests.test.ts b/src/domain/usecase/ListRequests.test.ts index 98c2f58..967cef9 100644 --- a/src/domain/usecase/ListRequests.test.ts +++ b/src/domain/usecase/ListRequests.test.ts @@ -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; diff --git a/src/domain/usecase/ListRequest.ts b/src/domain/usecase/ListRequests.ts similarity index 100% rename from src/domain/usecase/ListRequest.ts rename to src/domain/usecase/ListRequests.ts diff --git a/src/domain/usecase/index.ts b/src/domain/usecase/index.ts index 3a48c59..8680c01 100644 --- a/src/domain/usecase/index.ts +++ b/src/domain/usecase/index.ts @@ -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'; diff --git a/src/index.ts b/src/index.ts index ef47059..7b94d2e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { ClearRequest, RefreshRequest, ListRequest, + GetRequestDetails, } from './domain/usecase'; import { NetworkServiceAxios } from './infrastructure/service'; import { RequestRepositoryFile } from './infrastructure/repository'; @@ -29,6 +30,7 @@ container.register({ clearRequestUseCase: asClass(ClearRequest), refreshRequestUseCase: asClass(RefreshRequest), listRequestsUseCase: asClass(ListRequest), + getRequestDetailsUseCase: asClass(GetRequestDetails), // Repositories requestRepository: asClass(RequestRepositoryFile).singleton(),