From f84351f265566ad127fac3042b65d3bf7a13664b Mon Sep 17 00:00:00 2001 From: Frederik Prijck Date: Wed, 14 Jun 2023 15:41:50 +0200 Subject: [PATCH] Lazily retrieve transaction from transaction storage (#1108) --- .../handleRedirectCallback.test.ts | 8 ++--- .../Auth0Client/loginWithRedirect.test.ts | 4 ++- __tests__/transaction-manager.test.ts | 32 +++++++++---------- src/transaction-manager.ts | 15 ++++----- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/__tests__/Auth0Client/handleRedirectCallback.test.ts b/__tests__/Auth0Client/handleRedirectCallback.test.ts index f78d6c53c..4ea5a5ca3 100644 --- a/__tests__/Auth0Client/handleRedirectCallback.test.ts +++ b/__tests__/Auth0Client/handleRedirectCallback.test.ts @@ -135,7 +135,7 @@ describe('Auth0Client', () => { expect(error.error).toBe('some-error'); expect(error.error_description).toBe('some-error-description'); expect(error.state).toBe('error-state'); - expect(error.appState).toBe(appState); + expect(error.appState).toEqual(appState); }); it('should clear the transaction data when the /authorize call redirects with a code param', async () => { @@ -220,7 +220,7 @@ describe('Auth0Client', () => { const result = await loginWithRedirect(auth0, { appState }); expect(result).toBeDefined(); - expect(result.appState).toBe(appState); + expect(result.appState).toEqual(appState); }); it('uses the custom http timeout value if specified', async () => { @@ -234,7 +234,7 @@ describe('Auth0Client', () => { expect((http.switchFetch as jest.Mock).mock.calls[0][6]).toEqual(40000); expect(result).toBeDefined(); - expect(result.appState).toBe(appState); + expect(result.appState).toEqual(appState); }); it('does not store the scope from token endpoint if none was returned', async () => { @@ -456,7 +456,7 @@ describe('Auth0Client', () => { expect(error.error).toBe('some-error'); expect(error.error_description).toBe('some-error-description'); expect(error.state).toBe('error-state'); - expect(error.appState).toBe(appState); + expect(error.appState).toEqual(appState); }); it('should clear the transaction data when the /authorize call redirects with a code param', async () => { diff --git a/__tests__/Auth0Client/loginWithRedirect.test.ts b/__tests__/Auth0Client/loginWithRedirect.test.ts index 45363a968..46ee9accd 100644 --- a/__tests__/Auth0Client/loginWithRedirect.test.ts +++ b/__tests__/Auth0Client/loginWithRedirect.test.ts @@ -35,7 +35,6 @@ import { } from '../constants'; import version from '../../src/version'; -jest.mock('es-cookie'); jest.mock('../../src/jwt'); jest.mock('../../src/worker/token.worker'); @@ -59,6 +58,9 @@ describe('Auth0Client', () => { const oldWindowLocation = window.location; beforeEach(() => { + jest.spyOn(mockCookies, 'get'); + jest.spyOn(mockCookies, 'set'); + jest.spyOn(mockCookies, 'remove'); // https://www.benmvp.com/blog/mocking-window-location-methods-jest-jsdom/ delete window.location; window.location = Object.defineProperties( diff --git a/__tests__/transaction-manager.test.ts b/__tests__/transaction-manager.test.ts index e0846f69f..3ec15e7cc 100644 --- a/__tests__/transaction-manager.test.ts +++ b/__tests__/transaction-manager.test.ts @@ -27,9 +27,12 @@ describe('transaction manager', () => { jest.resetAllMocks(); }); - describe('constructor', () => { + describe('get', () => { it('loads transactions from storage (per key)', () => { tm = new TransactionManager(SessionStorage, TEST_CLIENT_ID); + + tm.get(); + expect(sessionStorage.getItem).toHaveBeenCalledWith(transactionKey()); }); }); @@ -59,7 +62,7 @@ describe('transaction manager', () => { }); it('`get` with a transaction should return the transaction', () => { - tm.create(transaction); + jest.mocked(sessionStorage.getItem).mockReturnValue(transactionJson); expect(tm.get()).toMatchObject(transaction); }); @@ -81,11 +84,11 @@ describe('transaction manager', () => { expect(sessionStorage.removeItem).toHaveBeenCalledWith(transactionKey()); }); }); - - describe('CookieStorage usage', () => { - it("`create` saves the transaction in the storage with the provided domain", () => { + + describe('CookieStorage usage', () => { + it('`create` saves the transaction in the storage with the provided domain', () => { CookieStorage.save = jest.fn(); - const cookieDomain = "vanity.auth.com"; + const cookieDomain = 'vanity.auth.com'; tm = new TransactionManager(CookieStorage, TEST_CLIENT_ID, cookieDomain); tm.create(transaction); @@ -99,18 +102,15 @@ describe('transaction manager', () => { ); }); - it("`remove` deletes the transaction in the storage with the provided domain", () => { + it('`remove` deletes the transaction in the storage with the provided domain', () => { CookieStorage.remove = jest.fn(); - const cookieDomain = "vanity.auth.com"; + const cookieDomain = 'vanity.auth.com'; tm = new TransactionManager(CookieStorage, TEST_CLIENT_ID, cookieDomain); tm.remove(); - expect(CookieStorage.remove).toHaveBeenCalledWith( - transactionKey(), - { - cookieDomain: cookieDomain - } - ); - }); - }); + expect(CookieStorage.remove).toHaveBeenCalledWith(transactionKey(), { + cookieDomain: cookieDomain + }); + }); + }); }); diff --git a/src/transaction-manager.ts b/src/transaction-manager.ts index 17a22074c..40efc450c 100644 --- a/src/transaction-manager.ts +++ b/src/transaction-manager.ts @@ -14,29 +14,28 @@ interface Transaction { } export class TransactionManager { - private transaction: Transaction | undefined; private storageKey: string; - constructor(private storage: ClientStorage, private clientId: string, private cookieDomain?: string) { + constructor( + private storage: ClientStorage, + private clientId: string, + private cookieDomain?: string + ) { this.storageKey = `${TRANSACTION_STORAGE_KEY_PREFIX}.${this.clientId}`; - this.transaction = this.storage.get(this.storageKey); } public create(transaction: Transaction) { - this.transaction = transaction; - this.storage.save(this.storageKey, transaction, { daysUntilExpire: 1, - cookieDomain: this.cookieDomain, + cookieDomain: this.cookieDomain }); } public get(): Transaction | undefined { - return this.transaction; + return this.storage.get(this.storageKey); } public remove() { - delete this.transaction; this.storage.remove(this.storageKey, { cookieDomain: this.cookieDomain });