import path from 'path'; import * as harUtils from '../har'; import * as render from '../render'; import * as models from '../../models'; import { AUTH_BASIC } from '../constants'; import { globalBeforeEach } from '../../__jest__/before-each'; describe('exportHar()', () => { beforeEach(globalBeforeEach); it('exports single requests', async () => { const wrk = await models.workspace.create({ _id: 'wrk_1', name: 'Workspace' }); const req1 = await models.request.create({ _id: 'req_1', name: 'Request 1', parentId: wrk._id, url: 'https://httpstat.us/200', method: 'POST', body: { mimeType: 'application/json', text: '{}' }, headers: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Accept', value: 'application/json', disabled: false }, { name: 'X-Disabled', value: 'X-Disabled', disabled: true } ] }); await models.response.create({ parentId: req1._id, statusCode: 200, statusMessage: 'OK', elapsedTime: 999, headers: [{ name: 'Content-Type', value: 'application/json' }], contentType: 'application/json', bodyPath: path.join(__dirname, '../__fixtures__/har/test-response.json'), bodyCompression: null }); const exportRequests = [{ requestId: req1._id, environmentId: 'n/a' }]; const harExport = await harUtils.exportHar(exportRequests); expect(harExport).toMatchObject({ log: { version: '1.2', creator: { name: 'Insomnia REST Client' }, entries: [ { startedDateTime: expect.any(String), time: 999, request: { method: 'POST', url: 'https://httpstat.us/200', httpVersion: 'HTTP/1.1', cookies: [], headers: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Accept', value: 'application/json' } ], queryString: [], postData: { mimeType: 'application/json', params: [], text: '{}' }, headersSize: -1, bodySize: -1 }, response: { status: 200, statusText: 'OK', httpVersion: 'HTTP/1.1', cookies: [], headers: [{ name: 'Content-Type', value: 'application/json' }], content: { size: 15, mimeType: 'application/json', text: '{"key":"value"}' }, redirectURL: '', headersSize: -1, bodySize: -1 }, cache: {}, timings: { blocked: -1, dns: -1, connect: -1, send: 0, wait: 999, receive: 0, ssl: -1 }, comment: req1.name } ] } }); }); it('exports multiple requests', async () => { const workspace = await models.workspace.create({ _id: 'wrk_1', name: 'Workspace' }); const baseReq = await models.request.create({ _id: 'req_0', type: models.request.type, name: 'Request', parentId: workspace._id, url: 'http://localhost', method: 'GET', body: {}, headers: [{ name: 'X-Environment', value: '{{ envvalue }}' }] }); const req1 = await models.request.duplicate(baseReq); req1._id = 'req_1'; req1.name = 'Request 1'; req1.headers.push({ name: 'X-Request', value: '1' }); await models.request.create(req1); const req2 = await models.request.duplicate(baseReq); req2._id = 'req_2'; req2.name = 'Request 2'; req2.headers.push({ name: 'X-Request', value: '2' }); await models.request.create(req2); const req3 = await models.request.duplicate(baseReq); req3._id = 'req_3'; req3.name = 'Request 3'; req3.headers.push({ name: 'X-Request', value: '3' }); await models.request.create(req3); await models.response.create({ _id: 'res_1', parentId: req1._id, statusCode: 204 }); await models.response.create({ _id: 'res_2', parentId: req2._id, statusCode: 404 }); await models.response.create({ _id: 'res_3', parentId: req3._id, statusCode: 500 }); const envBase = await models.environment.getOrCreateForWorkspace(workspace); await models.environment.update(envBase, { data: { envvalue: '' } }); const envPublic = await models.environment.create({ _id: 'env_1', name: 'Public', parentId: envBase._id }); await models.environment.update(envPublic, { data: { envvalue: 'public' } }); const envPrivate = await models.environment.create({ _id: 'env_2', name: 'Private', isPrivate: true, parentId: envBase._id }); await models.environment.update(envPrivate, { data: { envvalue: 'private' } }); const exportRequests = [ { requestId: req1._id, environmentId: 'n/a' }, { requestId: req2._id, environmentId: envPublic._id }, { requestId: req3._id, environmentId: envPrivate._id } ]; const harExport = await harUtils.exportHar(exportRequests); expect(harExport).toMatchObject({ log: { version: '1.2', creator: { name: 'Insomnia REST Client' }, entries: [ { request: { headers: [ { name: 'X-Environment', value: '' }, { name: 'X-Request', value: '1' } ] }, response: { status: 204 }, comment: req1.name }, { request: { headers: [ { name: 'X-Environment', value: 'public' }, { name: 'X-Request', value: '2' } ] }, response: { status: 404 }, comment: req2.name }, { request: { headers: [ { name: 'X-Environment', value: 'private' }, { name: 'X-Request', value: '3' } ] }, response: { status: 500 }, comment: req3.name } ] } }); }); }); describe('exportHarResponse()', () => { beforeEach(globalBeforeEach); it('exports a default har response for an empty response', async () => { const notFoundResponse = null; const harResponse = await harUtils.exportHarResponse(notFoundResponse); expect(harResponse).toMatchObject({ status: 0, statusText: '', httpVersion: 'HTTP/1.1', content: { size: 0, mimeType: '' } }); }); it('exports a valid har response for a non empty response', async () => { const response = Object.assign(models.response.init(), { _id: 'res_123', type: models.response.type, parentId: 'req_123', modified: 0, created: 0, statusCode: 200, statusMessage: 'OK', headers: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Content-Length', value: '2' }, { name: 'Set-Cookie', value: 'sessionid=12345; HttpOnly; Path=/' } ], contentType: 'application/json', bodyPath: path.join(__dirname, '../__fixtures__/har/test-response.json') }); const harResponse = await harUtils.exportHarResponse(response); expect(harResponse).toMatchObject({ status: 200, statusText: 'OK', httpVersion: 'HTTP/1.1', cookies: [ { name: 'sessionid', value: '12345', path: '/', httpOnly: true } ], headers: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Content-Length', value: '2' }, { name: 'Set-Cookie', value: 'sessionid=12345; HttpOnly; Path=/' } ], content: { size: 15, mimeType: 'application/json', text: '{"key":"value"}' }, redirectURL: '', headersSize: -1, bodySize: -1 }); }); }); describe('exportHarWithRequest()', () => { beforeEach(globalBeforeEach); it('renders does it correctly', async () => { const workspace = await models.workspace.create(); const cookies = [ { creation: new Date('2016-10-05T04:40:49.505Z'), key: 'foo', value: 'barrrrr', expires: new Date('2096-10-12T04:40:49.000Z'), domain: 'google.com', path: '/', hostOnly: true, lastAccessed: new Date('2096-10-05T04:40:49.505Z') } ]; const cookieJar = await models.cookieJar.getOrCreateForParentId( workspace._id ); await models.cookieJar.update(cookieJar, { parentId: workspace._id, cookies }); const request = Object.assign(models.request.init(), { _id: 'req_123', parentId: workspace._id, headers: [{ name: 'Content-Type', value: 'application/json' }], parameters: [{ name: 'foo bar', value: 'hello&world' }], method: 'POST', body: { text: 'foo bar' }, url: 'http://google.com', authentication: { type: AUTH_BASIC, username: 'user', password: 'pass' } }); const renderedRequest = await render.getRenderedRequest(request); const har = await harUtils.exportHarWithRequest(renderedRequest); expect(har.cookies.length).toBe(1); expect(har).toEqual({ bodySize: -1, cookies: [ { domain: 'google.com', expires: '2096-10-12T04:40:49.000Z', name: 'foo', path: '/', value: 'barrrrr' } ], headers: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Authorization', value: 'Basic dXNlcjpwYXNz' } ], headersSize: -1, httpVersion: 'HTTP/1.1', method: 'POST', postData: { mimeType: '', params: [], text: 'foo bar' }, queryString: [{ name: 'foo bar', value: 'hello&world' }], url: 'http://google.com/', settingEncodeUrl: true }); }); });