diff --git a/jest.browser.js b/jest.browser.js index ea3be24f8..ff8bd2a6b 100644 --- a/jest.browser.js +++ b/jest.browser.js @@ -10,6 +10,9 @@ module.exports = { 'moduleNameMapper': { '^@okta/okta-auth-js$': OktaAuth }, + 'setupFiles': [ + '/test/support/nodeExceptions.js' + ], 'testMatch': [ '**/test/spec/*.{js,ts}' ], diff --git a/lib/TokenManager.ts b/lib/TokenManager.ts index d4b368553..2b55cc72e 100644 --- a/lib/TokenManager.ts +++ b/lib/TokenManager.ts @@ -289,7 +289,7 @@ export class TokenManager { const onTokenExpiredHandler = (key) => { if (options.autoRenew) { - this.renew(key); + this.renew(key).catch(() => {}); // Renew errors will emit an "error" event } else { this.remove(key); } diff --git a/test/spec/tokenManager.js b/test/spec/tokenManager.js index e08628e02..129ffb2e7 100644 --- a/test/spec/tokenManager.js +++ b/test/spec/tokenManager.js @@ -607,6 +607,7 @@ describe('TokenManager', function() { }); afterEach(function() { jest.useRealTimers(); + client.tokenManager.clear(); // clear all timeouts }); it('should register listener for "expired" event', function() { jest.spyOn(Emitter.prototype, 'on'); @@ -752,7 +753,6 @@ describe('TokenManager', function() { }); }); - it('does not return the token after tokens were cleared before renew promise was resolved', function() { var expiresAt = tokens.standardIdTokenParsed.expiresAt; return oauthUtil.setupFrame({ @@ -800,7 +800,7 @@ describe('TokenManager', function() { }); }); - it('Emits an "error" event on OAuth failure', function() { + it('Emits an "error" event on OAuth failure', function(done) { setupSync({ tokenManager: { autoRenew: true @@ -815,11 +815,15 @@ describe('TokenManager', function() { accessToken: false }; var errorEventCallback = jest.fn().mockImplementation(function(err) { - util.expectErrorToEqual(err, error); + try { + util.expectErrorToEqual(err, error); + } catch (e) { + done.fail(e); + } }); client.tokenManager.on('error', errorEventCallback); - return oauthUtil.setupFrame({ + oauthUtil.setupFrame({ authClient: client, autoRenew: true, willFail: true, @@ -839,31 +843,41 @@ describe('TokenManager', function() { util.expectErrorToEqual(err, error); oauthUtil.expectTokenStorageToEqual(localStorage, {}); expect(errorEventCallback).toHaveBeenCalled(); + }) + .then(function() { + done(); + }) + .catch(function(err) { + done.fail(err); }); }); - it('Emits an "error" event on AuthSdkError', function() { + it('Emits an "error" event on AuthSdkError', function(done) { setupSync({ tokenManager: { autoRenew: true } }); var errorEventCallback = jest.fn().mockImplementation(function(err) { - util.expectErrorToEqual(err, { - name: 'AuthSdkError', - message: 'The request does not match client configuration', - errorCode: 'INTERNAL', - errorSummary: 'The request does not match client configuration', - errorLink: 'INTERNAL', - errorId: 'INTERNAL', - errorCauses: [], - tokenKey: 'test-idToken', - accessToken: false - }); + try { + util.expectErrorToEqual(err, { + name: 'AuthSdkError', + message: 'The request does not match client configuration', + errorCode: 'INTERNAL', + errorSummary: 'The request does not match client configuration', + errorLink: 'INTERNAL', + errorId: 'INTERNAL', + errorCauses: [], + tokenKey: 'test-idToken', + accessToken: false + }); + } catch (e) { + done.fail(e); + } }); client.tokenManager.on('error', errorEventCallback); - return oauthUtil.setupFrame({ + oauthUtil.setupFrame({ authClient: client, autoRenew: true, willFail: true, @@ -895,6 +909,12 @@ describe('TokenManager', function() { oauthUtil.expectTokenStorageToEqual(localStorage, {}); expect(errorEventCallback).toHaveBeenCalled(); + }) + .then(function() { + done(); + }) + .catch(function(err) { + done.fail(err); }); }); diff --git a/test/support/nodeExceptions.js b/test/support/nodeExceptions.js new file mode 100644 index 000000000..1f4dac28b --- /dev/null +++ b/test/support/nodeExceptions.js @@ -0,0 +1,5 @@ +// Catch unhandled promise rejections. These should never happen. +// If you see one of these, debug the test and set a breakpoint below. +process.on('unhandledRejection', error => { + console.log('FLAKEY TEST or CODE! unhandledRejection', error); +}); \ No newline at end of file diff --git a/test/support/oauthUtil.js b/test/support/oauthUtil.js index 0fba7b623..042007e79 100644 --- a/test/support/oauthUtil.js +++ b/test/support/oauthUtil.js @@ -173,6 +173,9 @@ oauthUtil.setup = function(opts) { authClient = opts.authClient; } else { authClient = new OktaAuth({ + tokenManager: { + autoRenew: false, + }, pkce: false, issuer: 'https://auth-js-test.okta.com' }); @@ -248,6 +251,11 @@ oauthUtil.setup = function(opts) { console.error(err); // eslint-disable-line expect('not to be hit').toBe(true); } + }) + .finally(function() { + if (authClient && authClient._tokenQueue) { + expect(authClient._tokenQueue.queue.length).toBe(0); + } }); }; diff --git a/test/support/util.js b/test/support/util.js index 8633963f1..3317bd485 100644 --- a/test/support/util.js +++ b/test/support/util.js @@ -195,7 +195,10 @@ function setup(options) { issuer: options.issuer, transformErrorXHR: options.transformErrorXHR, headers: options.headers, - ignoreSignature: options.bypassCrypto === true + ignoreSignature: options.bypassCrypto === true, + tokenManager: { + autoRenew: false + } }); // 3. Initialize status if passed in