// @ts-nocheck import { expect } from 'chai'; import fetch from 'node-fetch'; import * as nock from 'nock'; import { makeRequest } from '../../../src/request/make-request'; import * as errors from '../../../src/errors'; describe('Make request', () => { const domain = 'https://example.com'; let options; before(() => { options = {}; nock(domain) .get('/success') .reply(200, { result: 'success!' }); nock(domain) .head('/head') .reply(204); nock(domain) .post('/201-empty') .reply(201, '', { 'content-length': '0' }); nock(domain) .get('/pdf-data') .reply(200, 'some pdf binary data'); nock(domain) .get('/non-json') .reply(200, 'This is not valid JSON!'); nock(domain) .get('/json-string') .reply(200, '"testEmail@ft.com"'); nock(domain) .get('/http-code-400') .reply(400, {}); nock(domain) .get('/http-code-401') .reply(401, {}); nock(domain) .get('/http-code-403') .reply(403, {}); nock(domain) .get('/http-code-404') .reply(404, {}); nock(domain) .get('/http-code-418') .reply(418, { message: 'I\'m a teapot' }); nock(domain) .get('/http-code-500') .reply(500, {}); nock(domain) .get('/http-code-503') .reply(503, {}); nock(domain) .get('/string-response') .reply(200, 'some plain text'); nock(domain) .get('/empty-body') .reply(200, 'some text', { 'content-length': 0 }); }); it('resolves with a json response when the status code is 200', async () => { const response = await makeRequest(`${domain}/success`, options, fetch); expect(response).to.eql({ result: 'success!', status: 200 }); }); it('resolves with a buffered response when the status code is 200 and the accept header is application/pdf', async () => { let fetchOptions = { method: 'GET', headers: { 'Content-Type': 'application/pdf', 'X-api-key': '', 'Accept': 'application/pdf' } }; const response = await makeRequest(`${domain}/pdf-data`, fetchOptions, fetch); expect(response).to.instanceof(Buffer); }); it('resolves with a string response when the status code is 200 and the accept header is text/plain', async () => { let fetchOptions = { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-api-key': '', 'Accept': 'text/plain' } }; const response = await makeRequest(`${domain}/string-response`, fetchOptions, fetch); expect(response).to.be.a('string'); }); it('resolves with a string response when the status code is 200 and content length is 0', async () => { let fetchOptions = { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-api-key': '', } }; const response = await makeRequest(`${domain}/empty-body`, fetchOptions, fetch); expect(response).to.eql('some text'); }); it('returns key response data for a 204 status code', async () => { const response = await makeRequest(`${domain}/head`, { method: 'HEAD', headers: undefined }, fetch); expect(response).to.have.property('status', 204); expect(response).to.have.property('ok', true); expect(response).to.have.property('headers'); }); it('returns key response data for a 201 status code with empty body', async () => { const response = await makeRequest(`${domain}/201-empty`, { ...options, method: 'POST' }, fetch); expect(response).to.have.property('status', 201); expect(response).to.have.property('ok', true); expect(response).to.have.property('headers'); }); it("throws an InvalidResponseError when the response isn't JSON", async () => { let erroredResponse; try { await makeRequest(`${domain}/non-json`, options, fetch); } catch (error) { erroredResponse = error; } expect(erroredResponse).to.be.instanceof(errors.InvalidResponseError); expect(erroredResponse.data).to.exist; expect(erroredResponse.data).to.have.property('raw'); }); it('resolves with a string when the response is valid JSON string', async () => { const response = await makeRequest(`${domain}/json-string`, options, fetch); expect(response).to.eql('testEmail@ft.com'); }); it('throws a BadRequestError when the response status is 400', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-400`, options, fetch); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'BadRequestError'); }); it('throws a UnauthorizedError when the response status is 401', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-401`, options, fetch); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'UnauthorizedError'); }); it('throws a ForbiddenError when the response status is 403', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-403`, options, fetch); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'ForbiddenError'); }); it('throws a NotFoundError when the response status is 404', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-404`, options, fetch); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'NotFoundError'); }); it('throws a ServerError when the response status is 418', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-418`, options, fetch); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'ServerError'); }); it('throws a UpstreamServiceError when the response status is 500, with relatesToSystem value', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-500`, options, fetch, 'api-system-code'); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'UpstreamServiceError'); expect(erroredResponse.relatesToSystems).to.exist; expect(erroredResponse.relatesToSystems).to.eql(['api-system-code']); }); it('throws a UpstreamServiceError when the response status is 503, with relatesToSystems value', async () => { let erroredResponse; try { await makeRequest(`${domain}/http-code-503`, options, fetch, 'api-system-code'); } catch (error) { erroredResponse = error; } expectError(erroredResponse, 'UpstreamServiceError'); expect(erroredResponse.relatesToSystems).to.exist; expect(erroredResponse.relatesToSystems).to.eql(['api-system-code']); }); function expectError(error, name) { expect(error).to.be.instanceof(errors[name]); expect(error.data).to.exist; expect(error.data).to.have.property('url'); expect(error.data).to.have.property('status'); expect(error.data).to.have.property('method'); expect(error.data).to.have.property('responseBody'); } });