From f6e366c2d90b613b73a6d8b719aaa6dfe53c39fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=C4=9Fuz=20Bilgener?= Date: Wed, 10 Jun 2020 10:45:16 -0400 Subject: [PATCH] fix(cubejs-client-core): Remove Content-Type header from requests in HttpTransport (#709) * fix(cubejs-client-core): Remove Content-Type header from requests in HttpTransport --- .../cubejs-client-core/src/HttpTransport.js | 3 +- .../src/HttpTransport.test.js | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 packages/cubejs-client-core/src/HttpTransport.test.js diff --git a/packages/cubejs-client-core/src/HttpTransport.js b/packages/cubejs-client-core/src/HttpTransport.js index 3dec1ea7be6e1..39e7b1a75e5e4 100644 --- a/packages/cubejs-client-core/src/HttpTransport.js +++ b/packages/cubejs-client-core/src/HttpTransport.js @@ -30,11 +30,12 @@ class HttpTransport { let spanCounter = 1; + // Currently, all methods make GET requests. If a method makes a request with a body payload, + // remember to add a 'Content-Type' header. const runRequest = () => fetch( `${this.apiUrl}/${method}${searchParams.toString().length ? `?${searchParams}` : ''}`, { headers: { Authorization: this.authorization, - 'Content-Type': 'application/json', 'x-request-id': baseRequestId && `${baseRequestId}-span-${spanCounter++}`, ...this.headers } diff --git a/packages/cubejs-client-core/src/HttpTransport.test.js b/packages/cubejs-client-core/src/HttpTransport.test.js new file mode 100644 index 0000000000000..fd68162ce4a33 --- /dev/null +++ b/packages/cubejs-client-core/src/HttpTransport.test.js @@ -0,0 +1,56 @@ +/* eslint-disable import/first */ +/* eslint-disable import/newline-after-import */ +/* globals describe,test,expect,jest,afterEach */ +import '@babel/runtime/regenerator'; +jest.mock('cross-fetch'); +import fetch from 'cross-fetch'; +import HttpTransport from './HttpTransport'; + +describe('HttpTransport', () => { + const apiUrl = 'http://localhost:3000/cubejs-api/v1'; + const query = { + measures: ['Orders.count'], + dimensions: ['Users.country'] + }; + const queryUrlEncoded = '%7B%22measures%22%3A%5B%22Orders.count%22%5D%2C%22dimensions%22%3A%5B%22Users.country%22%5D%7D'; + + afterEach(() => { + fetch.mockClear(); + }); + + test('it serializes the query object and sends it in the query string', async () => { + const transport = new HttpTransport({ + authorization: 'token', + apiUrl, + }); + const req = transport.request('load', { query }); + await req.subscribe(() => { }); + expect(fetch).toHaveBeenCalledTimes(1); + expect(fetch).toHaveBeenCalledWith(`${apiUrl}/load?query=${queryUrlEncoded}`, { + headers: { + Authorization: 'token', + } + }); + }); + + test('it passes extra headers and serializes extra params', async () => { + const extraParams = { foo: 'bar' }; + const serializedExtraParams = encodeURIComponent(JSON.stringify(extraParams)); + const transport = new HttpTransport({ + authorization: 'token', + apiUrl, + headers: { + 'X-Extra-Header': '42' + } + }); + const req = transport.request('meta', { extraParams }); + await req.subscribe(() => { }); + expect(fetch).toHaveBeenCalledTimes(1); + expect(fetch).toHaveBeenCalledWith(`${apiUrl}/meta?extraParams=${serializedExtraParams}`, { + headers: { + Authorization: 'token', + 'X-Extra-Header': '42' + } + }); + }); +});