diff --git a/fetch/fetchRequest.js b/fetch/fetchRequest.js index 78a5b0dcd..3f2d16369 100644 --- a/fetch/fetchRequest.js +++ b/fetch/fetchRequest.js @@ -33,8 +33,8 @@ function fetchRequest(method, url, args) { } return result; }; - if (response.headers.get('Accept') && - response.headers.get('Accept').toLowerCase().indexOf('application/json') >= 0) { + if (response.headers.get('Content-Type') && + response.headers.get('Content-Type').toLowerCase().indexOf('application/json') >= 0) { return response.json().then(respHandler); } else { return response.text().then(respHandler); diff --git a/fetch/index.js b/fetch/index.js deleted file mode 100644 index 7961689d2..000000000 --- a/fetch/index.js +++ /dev/null @@ -1,17 +0,0 @@ -/*! - * Copyright (c) 2018-present, Okta, Inc. and/or its affiliates. All rights reserved. - * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") - * - * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - * See the License for the specific language governing permissions and limitations under the License. - * - */ - -var fetchRequest = require('./fetchRequest'); -var storageUtil = require('../lib/server/serverStorage'); - -module.exports = require('../lib/server/server')(storageUtil, fetchRequest); diff --git a/jest.browser.js b/jest.browser.js new file mode 100644 index 000000000..25c768466 --- /dev/null +++ b/jest.browser.js @@ -0,0 +1,20 @@ +var packageJson = require('./package.json'); +var OktaAuth = '/' + packageJson.browser; + +module.exports = { + 'coverageDirectory': './build2/reports/coverage', + 'restoreMocks': true, + 'moduleNameMapper': { + '^OktaAuth(.*)$': OktaAuth + }, + 'testMatch': [ + '**/test/spec/*.js' + ], + 'testPathIgnorePatterns': [ + './test/spec/serverStorage.js' + ], + 'reporters': [ + 'default', + 'jest-junit' + ] +}; diff --git a/jest.browser.json b/jest.browser.json deleted file mode 100644 index af27b09df..000000000 --- a/jest.browser.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "browser": true, - "coverageDirectory": "./build2/reports/coverage", - "restoreMocks": true, - "moduleNameMapper": { - "^OktaAuth(.*)$": "/jquery/$1" - }, - "testMatch": [ - "**/test/spec/*.js" - ], - "testPathIgnorePatterns": [ - "./test/spec/serverStorage.js" - ], - "reporters": [ - "default", - "jest-junit" - ] -} diff --git a/jest.server.js b/jest.server.js new file mode 100644 index 000000000..28a378e81 --- /dev/null +++ b/jest.server.js @@ -0,0 +1,25 @@ +var packageJson = require('./package.json'); +var OktaAuth = '/' + packageJson.main; + +module.exports = { + 'coverageDirectory': './build2/reports/coverage', + 'restoreMocks': true, + 'moduleNameMapper': { + '^OktaAuth(.*)$': OktaAuth + }, + 'testMatch': [ + '**/test/spec/*.js' + ], + 'testPathIgnorePatterns': [ + './test/spec/fingerprint.js', + './test/spec/general.js', + './test/spec/oauthUtil.js', + './test/spec/token.js', + './test/spec/tokenManager.js', + './test/spec/webfinger.js' + ], + 'reporters': [ + 'default', + 'jest-junit' + ] +}; diff --git a/jest.server.json b/jest.server.json deleted file mode 100644 index b677696cb..000000000 --- a/jest.server.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "coverageDirectory": "./build2/reports/coverage", - "restoreMocks": true, - "moduleNameMapper": { - "^OktaAuth(.*)$": "/jquery/$1" - }, - "testMatch": [ - "**/test/spec/*.js" - ], - "testPathIgnorePatterns": [ - "./test/spec/oauthUtil.js" - ], - "reporters": [ - "default", - "jest-junit" - ] -} diff --git a/lib/browser/browserIndex.js b/lib/browser/browserIndex.js index b100651c9..91822a4a8 100644 --- a/lib/browser/browserIndex.js +++ b/lib/browser/browserIndex.js @@ -11,5 +11,7 @@ * */ -// This exists to use reqwest for http requests by default when library used on browser -module.exports = require('../../reqwest'); +var fetchRequest = require('../../fetch/fetchRequest'); +var storageUtil = require('./browserStorage'); + +module.exports = require('./browser')(storageUtil, fetchRequest); diff --git a/lib/server/serverIndex.js b/lib/server/serverIndex.js index f2d24ccfa..e1019bec8 100644 --- a/lib/server/serverIndex.js +++ b/lib/server/serverIndex.js @@ -11,5 +11,7 @@ * */ -// This exists to use fetch for http requests by default when library used on server side -module.exports = require('../../fetch'); +var fetchRequest = require('../../fetch/fetchRequest'); +var storageUtil = require('./serverStorage'); + +module.exports = require('./server')(storageUtil, fetchRequest); diff --git a/lib/token.js b/lib/token.js index 7b342e0bd..a722e4c0e 100644 --- a/lib/token.js +++ b/lib/token.js @@ -594,7 +594,12 @@ function getUserInfo(sdk, accessTokenObject) { }) .fail(function(err) { if (err.xhr && (err.xhr.status === 401 || err.xhr.status === 403)) { - var authenticateHeader = err.xhr.getResponseHeader('WWW-Authenticate'); + var authenticateHeader; + if (err.xhr.headers && util.isFunction(err.xhr.headers.get) && err.xhr.headers.get('WWW-Authenticate')) { + authenticateHeader = err.xhr.headers.get('WWW-Authenticate'); + } else if (util.isFunction(err.xhr.getResponseHeader)) { + authenticateHeader = err.xhr.getResponseHeader('WWW-Authenticate'); + } if (authenticateHeader) { var errorMatches = authenticateHeader.match(/error="(.*?)"/) || []; var errorDescriptionMatches = authenticateHeader.match(/error_description="(.*?)"/) || []; diff --git a/lib/util.js b/lib/util.js index d720525ff..2029bac8a 100644 --- a/lib/util.js +++ b/lib/util.js @@ -252,3 +252,7 @@ util.removeTrailingSlash = function(path) { util.isIE11OrLess = function() { return !!document.documentMode && document.documentMode <= 11; }; + +util.isFunction = function(fn) { + return !!fn && {}.toString.call(fn) === '[object Function]'; +}; diff --git a/package.json b/package.json index e3e3799a5..86cbceceb 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "lint": "eslint .", "lint:report": "eslint -f checkstyle -o build2/reports/lint/eslint-checkstyle-result.xml .", "test": "yarn test:browser && yarn test:server", - "test:browser": "jest --config ./jest.browser.json", - "test:server": "jest --config ./jest.server.json", + "test:browser": "jest --config ./jest.browser.js", + "test:server": "jest --config ./jest.server.js", "test:report": "yarn test --ci --silent || true", "build": "node ./writeConfig.js && webpack --config webpack.config.js", "prepublish": "yarn build" diff --git a/test/spec/fingerprint.js b/test/spec/fingerprint.js index c3ce542e7..0b61bf610 100644 --- a/test/spec/fingerprint.js +++ b/test/spec/fingerprint.js @@ -2,6 +2,8 @@ var OktaAuth = require('OktaAuth'); var util = require('../util/util'); var packageJson = require('../../package.json'); +jest.mock('cross-fetch'); + describe('fingerprint', function() { function setup(options) { options = options || {}; diff --git a/test/spec/oauthUtil.js b/test/spec/oauthUtil.js index 89e9ec8c4..4a317a099 100644 --- a/test/spec/oauthUtil.js +++ b/test/spec/oauthUtil.js @@ -7,6 +7,8 @@ var wellKnown = require('../xhr/well-known'); var keys = require('../xhr/keys'); var tokens = require('../util/tokens'); +jest.mock('cross-fetch'); + describe('getWellKnown', function() { util.itMakesCorrectRequestResponse({ title: 'caches response and uses cache on subsequent requests', diff --git a/test/spec/token.js b/test/spec/token.js index 4eb089a09..ec89221ca 100644 --- a/test/spec/token.js +++ b/test/spec/token.js @@ -6,6 +6,8 @@ var packageJson = require('../../package.json'); var _ = require('lodash'); var Q = require('q'); +jest.mock('cross-fetch'); + function setupSync() { return new OktaAuth({ issuer: 'http://example.okta.com' }); } diff --git a/test/spec/util.js b/test/spec/util.js index f0a7c1e98..9a4600e42 100644 --- a/test/spec/util.js +++ b/test/spec/util.js @@ -122,4 +122,50 @@ describe('util', function() { }); }); + describe('isFunction', function() { + it('returns false if argument is undefined', function() { + var fn; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is null', function() { + var fn = null; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is a boolean', function() { + var fn = true; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is a number', function() { + var fn = 3; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument a string', function() { + var fn = 'I am not a function!'; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is an Object', function() { + var fn = { name: 'Not a function!' }; + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is a Date', function() { + var fn = new Date('December 17, 1995 03:24:00'); + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns false if argument is a RegExp', function() { + var fn = new RegExp('\\w+'); + expect(util.isFunction(fn)).toBe(false); + }); + + it('returns true if argument is a function', function() { + var fn = function() { return 'I am a function!'; }; + expect(util.isFunction(fn)).toBe(true); + }); + }); }); diff --git a/test/util/util.js b/test/util/util.js index 0f02bb0dc..b7b860e4f 100644 --- a/test/util/util.js +++ b/test/util/util.js @@ -1,10 +1,12 @@ /* globals expect, JSON */ /* eslint-disable max-statements, complexity */ var Q = require('q'), - $ = require('jquery'), _ = require('lodash'), OktaAuth = require('OktaAuth'), - cookies = require('../../lib/browser/browserStorage').storage; + cookies = require('../../lib/browser/browserStorage').storage, + fetch = require('cross-fetch'); + +jest.mock('cross-fetch'); var util = {}; @@ -80,44 +82,46 @@ function mockAjax(pairs) { setNextPair(pairs); } - jest.spyOn($, 'ajax').mockImplementation(function(args) { - + fetch.mockImplementation(function (url, args) { var pair = allPairs.shift(); if (!pair) { throw new Error('We are making a request that we have not anticipated.'); } // Make sure every request is attaching cookies - expect(args.xhrFields).toEqual({ - withCredentials: true - }); + expect(args.credentials).toEqual('include'); if (pair.request) { - expect(pair.request.uri).toEqual(args.url); - if (pair.request.data || args.data) { - expect(pair.request.data).toEqual(JSON.parse(args.data)); + expect(pair.request.uri).toEqual(url); + if (pair.request.data || args.body) { + expect(pair.request.data).toEqual(JSON.parse(args.body)); } if (pair.request.headers) { expect(pair.request.headers).toEqual(args.headers); } } - var deferred = $.Deferred(); + var deferred = Q.defer(); var xhr = pair.response; - - xhr.getResponseHeader = function(name) { - return xhr.headers && xhr.headers[name]; - }; + xhr.headers = xhr.headers || {}; + xhr.headers['Content-Type'] = 'application/json'; + xhr.headers.get = function(attr) { + return xhr.headers[attr]; + } + xhr.ok = xhr.status >= 200 && xhr.status < 300; + xhr.json = function() { + return Q.Promise(function(resolve) { + resolve(xhr.responseText); + }); + } if (xhr.status > 0 && xhr.status < 300) { - // $.ajax send (data, textStatus, jqXHR) on success - _.defer(function () { deferred.resolve(xhr.response, null, xhr); }); + _.defer(function () { deferred.resolve(xhr); }); } else { - // $.ajax send (jqXHR, textStatus, errorThrown) on failure xhr.responseJSON = xhr.response; - deferred.reject(xhr, null, xhr.response); + deferred.reject(xhr); } - return deferred; + return deferred.promise; }); return {