From 3a5d62b639fabcbd829ae7ba8ba67700b776afe2 Mon Sep 17 00:00:00 2001 From: Arne Hassel Date: Mon, 12 Nov 2018 11:30:49 +0100 Subject: [PATCH 1/4] Handling case where options.headers is of type window.Headers --- src/__test__/fetch-util.spec.js | 25 +++++++++++++++++++++++++ src/fetch-util.js | 17 +++++++++++++++++ src/webid-oidc.js | 11 +++++++---- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 src/__test__/fetch-util.spec.js create mode 100644 src/fetch-util.js diff --git a/src/__test__/fetch-util.spec.js b/src/__test__/fetch-util.spec.js new file mode 100644 index 0000000..996f790 --- /dev/null +++ b/src/__test__/fetch-util.spec.js @@ -0,0 +1,25 @@ +// @flow +/* eslint-env jest */ +/* global Headers */ + +import { copyHeaders } from '../fetch-util' + +describe('copyHeaders', () => { + it('returns an object', () => expect(copyHeaders({})).toEqual({})) + it('returns a copy of whatever is passed in as first param', () => + expect(copyHeaders({ foo: 42 })).toEqual({ foo: 42 })) + it('handles option.headers as object', () => + expect(copyHeaders({ foo: 42 }, { headers: { bar: 1337 } })).toEqual({ + foo: 42, + bar: 1337 + })) + xit('handles options.headers as Headers', () => { + // Enable this when there is support for window.Headers + const headers = new Headers() + headers.append('bar', '1337') + expect(copyHeaders({ foo: '42' }, { headers })).toEqual({ + foo: '42', + bar: '1337' + }) + }) +}) diff --git a/src/fetch-util.js b/src/fetch-util.js new file mode 100644 index 0000000..43983e8 --- /dev/null +++ b/src/fetch-util.js @@ -0,0 +1,17 @@ +export function copyHeaders(newHeaders, oldOptions = {}) { + return { + ...normalizeHeaders(oldOptions.headers), + ...normalizeHeaders(newHeaders) + } +} + +function normalizeHeaders(headers = {}) { + if (!headers.forEach) { + return headers + } + const newHeaders = {} + headers.forEach((value, key) => { + newHeaders[key] = value + }) + return newHeaders +} diff --git a/src/webid-oidc.js b/src/webid-oidc.js index a23d25c..75b3a97 100644 --- a/src/webid-oidc.js +++ b/src/webid-oidc.js @@ -9,6 +9,7 @@ import { currentUrl, navigateTo, toUrlString } from './url-util' import type { webIdOidcSession } from './session' import type { AsyncStorage } from './storage' import { defaultStorage, getData, updateStorage } from './storage' +import { copyHeaders } from './fetch-util' export async function login( idp: string, @@ -191,10 +192,12 @@ export async function fetchWithCredentials( const authenticatedOptions = { ...options, credentials: 'include', - headers: { - ...(options && options.headers ? options.headers : {}), - authorization: `Bearer ${popToken}` - } + headers: copyHeaders( + { + authorization: `Bearer ${popToken}` + }, + options + ) } return fetch(input, authenticatedOptions) } From 1b660ced134ca3381c5ddf2b7c16caf0852902ec Mon Sep 17 00:00:00 2001 From: Arne Hassel Date: Mon, 12 Nov 2018 11:32:58 +0100 Subject: [PATCH 2/4] Test should work --- src/__test__/fetch-util.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/__test__/fetch-util.spec.js b/src/__test__/fetch-util.spec.js index 996f790..b2ab33f 100644 --- a/src/__test__/fetch-util.spec.js +++ b/src/__test__/fetch-util.spec.js @@ -13,8 +13,7 @@ describe('copyHeaders', () => { foo: 42, bar: 1337 })) - xit('handles options.headers as Headers', () => { - // Enable this when there is support for window.Headers + it('handles options.headers as Headers', () => { const headers = new Headers() headers.append('bar', '1337') expect(copyHeaders({ foo: '42' }, { headers })).toEqual({ From 0783941640a018c9371178d5326b94331894e17b Mon Sep 17 00:00:00 2001 From: Arne Hassel Date: Mon, 12 Nov 2018 12:04:36 +0100 Subject: [PATCH 3/4] Fixed a minimal polyfill for Headers --- src/__test__/fetch-util.spec.js | 7 +++++-- src/__test__/spec-helpers.js | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/__test__/fetch-util.spec.js b/src/__test__/fetch-util.spec.js index b2ab33f..19a4ab1 100644 --- a/src/__test__/fetch-util.spec.js +++ b/src/__test__/fetch-util.spec.js @@ -1,10 +1,13 @@ // @flow /* eslint-env jest */ -/* global Headers */ import { copyHeaders } from '../fetch-util' +import { polyfillWindow, polyunfillWindow } from './spec-helpers' describe('copyHeaders', () => { + beforeEach(() => polyfillWindow()) + afterEach(() => polyunfillWindow()) + it('returns an object', () => expect(copyHeaders({})).toEqual({})) it('returns a copy of whatever is passed in as first param', () => expect(copyHeaders({ foo: 42 })).toEqual({ foo: 42 })) @@ -14,7 +17,7 @@ describe('copyHeaders', () => { bar: 1337 })) it('handles options.headers as Headers', () => { - const headers = new Headers() + const headers = new window.Headers() headers.append('bar', '1337') expect(copyHeaders({ foo: '42' }, { headers })).toEqual({ foo: '42', diff --git a/src/__test__/spec-helpers.js b/src/__test__/spec-helpers.js index e1c4527..c9b01a4 100644 --- a/src/__test__/spec-helpers.js +++ b/src/__test__/spec-helpers.js @@ -31,6 +31,23 @@ export const polyfillWindow = () => { value: window.origin }) MessageEvent.prototype.origin = window.location.origin + + // in case Headers is not available + Object.defineProperty(window, 'Headers', { + value: class Headers { + constructor() { + this.map = {} + } + + append(key, value) { + this.map[key] = value + } + + forEach(callback) { + Object.keys(this.map).forEach(key => callback(this.map[key], key)) + } + } + }) } export const polyunfillWindow = () => { From cff14a19d6cb3ec8c5c24c1ffaa6bc049127c751 Mon Sep 17 00:00:00 2001 From: Arne Hassel Date: Mon, 12 Nov 2018 12:14:33 +0100 Subject: [PATCH 4/4] Do not know how to handle testing with Headers... --- src/__test__/fetch-util.spec.js | 3 ++- src/__test__/spec-helpers.js | 30 +++++++++++++++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/__test__/fetch-util.spec.js b/src/__test__/fetch-util.spec.js index 19a4ab1..509f72f 100644 --- a/src/__test__/fetch-util.spec.js +++ b/src/__test__/fetch-util.spec.js @@ -16,7 +16,8 @@ describe('copyHeaders', () => { foo: 42, bar: 1337 })) - it('handles options.headers as Headers', () => { + xit('handles options.headers as Headers', () => { + // TODO: Need to have Headers working const headers = new window.Headers() headers.append('bar', '1337') expect(copyHeaders({ foo: '42' }, { headers })).toEqual({ diff --git a/src/__test__/spec-helpers.js b/src/__test__/spec-helpers.js index c9b01a4..b1a17d5 100644 --- a/src/__test__/spec-helpers.js +++ b/src/__test__/spec-helpers.js @@ -33,21 +33,21 @@ export const polyfillWindow = () => { MessageEvent.prototype.origin = window.location.origin // in case Headers is not available - Object.defineProperty(window, 'Headers', { - value: class Headers { - constructor() { - this.map = {} - } - - append(key, value) { - this.map[key] = value - } - - forEach(callback) { - Object.keys(this.map).forEach(key => callback(this.map[key], key)) - } - } - }) + // Object.defineProperty(window, 'Headers', { + // value: class Headers { + // constructor() { + // this.map = {} + // } + // + // append(key, value) { + // this.map[key] = value + // } + // + // forEach(callback) { + // Object.keys(this.map).forEach(key => callback(this.map[key], key)) + // } + // } + // }) } export const polyunfillWindow = () => {