diff --git a/packages/core/src/__tests__/httpClient/basicHttpClient.unit.spec.ts b/packages/core/src/__tests__/httpClient/basicHttpClient.unit.spec.ts new file mode 100644 index 0000000000..d98f24632e --- /dev/null +++ b/packages/core/src/__tests__/httpClient/basicHttpClient.unit.spec.ts @@ -0,0 +1,58 @@ +// Copyright 2020 Cognite AS + +// @ts-ignore +import { + headersWithDefaultField, + HttpHeaders, +} from '../../httpClient/basicHttpClient'; + +function lengthOfHttpHeaders(headers?: HttpHeaders): number { + let counter = 0; + for (const _ in headers) { + counter += 1; + } + return counter; +} + +describe('basicHttpClient', () => { + describe('headersWithDefaultField', () => { + test('add missing', () => { + const emptyHeaders: HttpHeaders = {}; + const alteredEmptyHeaders = headersWithDefaultField( + emptyHeaders, + 'Accept', + 'application/json' + ); + expect(lengthOfHttpHeaders(alteredEmptyHeaders)).toEqual(1); + expect('Accept' in alteredEmptyHeaders).toBeTruthy(); + }); + test('not overwrite existing', () => { + const mediaType = 'image/png'; + const emptyHeaders: HttpHeaders = { + Accept: mediaType, + }; + const alteredEmptyHeaders = headersWithDefaultField( + emptyHeaders, + 'Accept', + 'application/json' + ); + expect(lengthOfHttpHeaders(alteredEmptyHeaders)).toEqual(1); + expect('Accept' in alteredEmptyHeaders).toBeTruthy(); + expect(alteredEmptyHeaders['Accept']).toEqual(mediaType); + }); + test('to be case insensitive', () => { + const mediaType = 'image/png'; + const emptyHeaders: HttpHeaders = { + accept: mediaType, + }; + const alteredEmptyHeaders = headersWithDefaultField( + emptyHeaders, + 'Accept', + 'application/json' + ); + expect(lengthOfHttpHeaders(alteredEmptyHeaders)).toEqual(1); + expect('accept' in alteredEmptyHeaders).toBeTruthy(); + expect(alteredEmptyHeaders['accept']).toEqual(mediaType); + }); + }); +}); diff --git a/packages/core/src/httpClient/basicHttpClient.ts b/packages/core/src/httpClient/basicHttpClient.ts index cf60a17d1d..3e2f16c4f6 100644 --- a/packages/core/src/httpClient/basicHttpClient.ts +++ b/packages/core/src/httpClient/basicHttpClient.ts @@ -179,10 +179,11 @@ export class BasicHttpClient { request: HttpRequest ): Promise> { const url = this.constructUrl(request.path, request.params); - const headers: HttpHeaders = { - Accept: 'application/json', - ...request.headers, - }; + const headers = headersWithDefaultField( + request.headers, + 'Accept', + 'application/json' + ); let body = request.data; if (isJson(body)) { body = BasicHttpClient.transformRequestBody(body); @@ -224,6 +225,27 @@ export class BasicHttpClient { } } +function lowercaseHeadersKeys(headers: HttpHeaders): string[] { + const keys: string[] = []; + for (const key in headers) { + keys.push(key.toLowerCase()); + } + return keys; +} + +export function headersWithDefaultField( + headers: HttpHeaders = {}, + fieldName: string, + fieldValue: string +): HttpHeaders { + const lowercaseHeaders = lowercaseHeadersKeys(headers); + const lowercaseKey = fieldName.toLowerCase(); + if (!lowercaseHeaders.includes(lowercaseKey)) { + headers[fieldName] = fieldValue; + } + return headers; +} + export interface HttpRequest extends HttpRequestOptions { path: string; method: HttpMethod; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 39a1e13a8c..83c9f926be 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,6 +2,7 @@ import * as Constants from './constants'; import * as GraphUtils from './graphUtils'; import * as TestUtils from './testUtils'; + export * from './types'; export { MetadataMap } from './metadata';