From f7f2ec368c228f9e98e0e9fd15b4adff58a6b9fb Mon Sep 17 00:00:00 2001 From: pamapa Date: Wed, 15 Sep 2021 15:01:23 +0200 Subject: [PATCH] fix: #45 switch to oidc-client-ts --- README.md | 8 +- docs/react-oidc-context.api.md | 26 +-- package-lock.json | 149 +++++------------- package.json | 8 +- src/AuthContext.ts | 19 ++- src/AuthProvider.tsx | 9 +- src/AuthState.ts | 2 +- src/reducer.ts | 2 +- test/AuthProvider.test.tsx | 21 +-- .../{oidc-client.ts => oidc-client-ts.ts} | 2 +- test/helpers.tsx | 3 +- test/useAuth.test.tsx | 4 +- test/withAuth.test.tsx | 4 +- 13 files changed, 101 insertions(+), 156 deletions(-) rename test/__mocks__/{oidc-client.ts => oidc-client-ts.ts} (99%) diff --git a/README.md b/README.md index d31e507f..b2e3fded 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![Pipeline](https://github.com/authts/react-oidc-context/workflows/Release/badge.svg) -Lightweight auth library using the [oidc-client](https://github.com/IdentityModel/oidc-client-js) library for React single page applications (SPA). +Lightweight auth library using the [oidc-client-ts](https://github.com/authts/oidc-client-ts) library for React single page applications (SPA). Support for [hooks](https://reactjs.org/docs/hooks-intro.html) and [higher-order components (HOC)](https://reactjs.org/docs/higher-order-components.html). @@ -18,10 +18,10 @@ Support for [hooks](https://reactjs.org/docs/hooks-intro.html) and [higher-order ## Documentation -This library implements an auth context provider by making use of the `oidc-client` library. Its configuration is +This library implements an auth context provider by making use of the `oidc-client-ts` library. Its configuration is tight coupled to that library. -- [oidc-client](https://github.com/IdentityModel/oidc-client-js/wiki) +- [oidc-client-ts](https://github.com/authts/oidc-client-ts) The User and UserManager is hold in this context, which is accessible from the React application. Additionally it intercepts the auth redirects by looking at the query/fragment parameters and acts accordingly. You still need to setup a redirect uri, @@ -170,7 +170,7 @@ As **not** a child of `AuthProvider` (e.g. redux slice) when using local storage containing an access token: ```jsx // src/slice.js -import { User } from "oidc-client" +import { User } from "oidc-client-ts" function getUser() { const oidcStorage = localStorage.getItem(`oidc.user::`) diff --git a/docs/react-oidc-context.api.md b/docs/react-oidc-context.api.md index 6f03c7e2..7944e184 100644 --- a/docs/react-oidc-context.api.md +++ b/docs/react-oidc-context.api.md @@ -4,11 +4,17 @@ ```ts +import type { QuerySessionStatusArgs } from 'oidc-client-ts'; import { default as React_2 } from 'react'; -import type { SessionStatus } from 'oidc-client'; -import { User } from 'oidc-client'; -import { UserManager } from 'oidc-client'; -import { UserManagerSettings } from 'oidc-client'; +import type { SessionStatus } from 'oidc-client-ts'; +import type { SigninPopupArgs } from 'oidc-client-ts'; +import type { SigninRedirectArgs } from 'oidc-client-ts'; +import type { SigninSilentArgs } from 'oidc-client-ts'; +import type { SignoutPopupArgs } from 'oidc-client-ts'; +import type { SignoutRedirectArgs } from 'oidc-client-ts'; +import { User } from 'oidc-client-ts'; +import { UserManager } from 'oidc-client-ts'; +import { UserManagerSettings } from 'oidc-client-ts'; // @public (undocumented) export const AuthContext: React_2.Context; @@ -20,22 +26,22 @@ export interface AuthContextProps extends AuthState { // (undocumented) clearStaleState(): Promise; // (undocumented) - querySessionStatus(args?: any): Promise; + querySessionStatus(args?: QuerySessionStatusArgs): Promise; // (undocumented) removeUser(): Promise; // (undocumented) revokeAccessToken(): Promise; readonly settings: UserManagerSettings; // (undocumented) - signinPopup(args?: any): Promise; + signinPopup(args?: SigninPopupArgs): Promise; // (undocumented) - signinRedirect(args?: any): Promise; + signinRedirect(args?: SigninRedirectArgs): Promise; // (undocumented) - signinSilent(args?: any): Promise; + signinSilent(args?: SigninSilentArgs): Promise; // (undocumented) - signoutPopup(args?: any): Promise; + signoutPopup(args?: SignoutPopupArgs): Promise; // (undocumented) - signoutRedirect(args?: any): Promise; + signoutRedirect(args?: SignoutRedirectArgs): Promise; // (undocumented) startSilentRenew(): void; // (undocumented) diff --git a/package-lock.json b/package-lock.json index fd9d1cf0..3a40180a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "react-oidc-context", "version": "1.1.0", "license": "MIT", - "dependencies": { - "oidc-client": "^1.11.5" - }, "devDependencies": { "@microsoft/api-extractor": "^7.18.10", "@testing-library/jest-dom": "^5.5.0", @@ -26,6 +23,7 @@ "husky": "^7.0.2", "jest": "^27.2.0", "lint-staged": "^11.1.2", + "oidc-client-ts": "^2.0.0-beta.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-test-renderer": "^17.0.2", @@ -34,11 +32,11 @@ "typescript": "^4.2.4" }, "engines": { - "node": ">=10" + "node": ">=12.13.0" }, "peerDependencies": { - "oidc-client": "^1.11.5", - "react": ">=16" + "oidc-client-ts": "^2.0.0-beta.2", + "react": ">=16.8.0" } }, "node_modules/@babel/code-frame": { @@ -2894,6 +2892,7 @@ "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -3209,25 +3208,6 @@ "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3614,16 +3594,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/core-js": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.11.3.tgz", - "integrity": "sha1-KDWx9NEPbQQAv4IM/m/mStBn3T8=", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, "node_modules/core-js-pure": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.11.3.tgz", @@ -3649,11 +3619,6 @@ "node": ">= 8" } }, - "node_modules/crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", - "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" - }, "node_modules/css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -8259,6 +8224,15 @@ "node": ">=6" } }, + "node_modules/jsrsasign": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.4.1.tgz", + "integrity": "sha512-g2CP2nb8xKdmfZhuHaJEz1zVYTsZc+lUjLFvgbMX35/cUALK0G15sQfCbCpDg/UivkjCNlq0lV6FxCfPhv0shw==", + "dev": true, + "funding": { + "url": "https://github.com/kjur/jsrsasign#donations" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -8777,16 +8751,16 @@ "node": ">=0.10.0" } }, - "node_modules/oidc-client": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/oidc-client/-/oidc-client-1.11.5.tgz", - "integrity": "sha1-Agqhk9aKPh+Hok/L9QBztzjekrs=", + "node_modules/oidc-client-ts": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.0.0-beta.2.tgz", + "integrity": "sha512-Jo4WBvurxAnfnkJynDDrX3hkag3MsF0wwzVNqrxFd7sXJwPIBrWjQ6FjpZRhnDJN8Lo/SJxvjn0PSE3Kxbwmmg==", + "dev": true, "dependencies": { - "acorn": "^7.4.1", - "base64-js": "^1.5.1", - "core-js": "^3.8.3", - "crypto-js": "^4.0.0", - "serialize-javascript": "^4.0.0" + "jsrsasign": "^10.3.0" + }, + "engines": { + "node": ">=12.13.0" } }, "node_modules/once": { @@ -9061,14 +9035,6 @@ } ] }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -9326,7 +9292,8 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true }, "node_modules/safer-buffer": { "version": "2.1.2", @@ -9377,14 +9344,6 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, - "node_modules/serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha1-tSXhI4SJpez8Qq+sw/6Z5mb0sao=", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12642,7 +12601,8 @@ "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=" + "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=", + "dev": true }, "acorn-globals": { "version": "6.0.0", @@ -12885,11 +12845,6 @@ "integrity": "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4=", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo=" - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -13193,11 +13148,6 @@ "safe-buffer": "~5.1.1" } }, - "core-js": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.11.3.tgz", - "integrity": "sha1-KDWx9NEPbQQAv4IM/m/mStBn3T8=" - }, "core-js-pure": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.11.3.tgz", @@ -13215,11 +13165,6 @@ "which": "^2.0.1" } }, - "crypto-js": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz", - "integrity": "sha1-KQSrJnep0EKFai6i74DekuSjbcw=" - }, "css": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", @@ -16843,6 +16788,12 @@ "minimist": "^1.2.5" } }, + "jsrsasign": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.4.1.tgz", + "integrity": "sha512-g2CP2nb8xKdmfZhuHaJEz1zVYTsZc+lUjLFvgbMX35/cUALK0G15sQfCbCpDg/UivkjCNlq0lV6FxCfPhv0shw==", + "dev": true + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -17246,16 +17197,13 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, - "oidc-client": { - "version": "1.11.5", - "resolved": "https://registry.npmjs.org/oidc-client/-/oidc-client-1.11.5.tgz", - "integrity": "sha1-Agqhk9aKPh+Hok/L9QBztzjekrs=", + "oidc-client-ts": { + "version": "2.0.0-beta.2", + "resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-2.0.0-beta.2.tgz", + "integrity": "sha512-Jo4WBvurxAnfnkJynDDrX3hkag3MsF0wwzVNqrxFd7sXJwPIBrWjQ6FjpZRhnDJN8Lo/SJxvjn0PSE3Kxbwmmg==", + "dev": true, "requires": { - "acorn": "^7.4.1", - "base64-js": "^1.5.1", - "core-js": "^3.8.3", - "crypto-js": "^4.0.0", - "serialize-javascript": "^4.0.0" + "jsrsasign": "^10.3.0" } }, "once": { @@ -17452,14 +17400,6 @@ "integrity": "sha1-SSkii7xyTfrEPg77BYyve2z7YkM=", "dev": true }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha1-32+ENy8CcNxlzfYpE0mrekc9Tyo=", - "requires": { - "safe-buffer": "^5.1.0" - } - }, "react": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", @@ -17647,7 +17587,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -17689,14 +17630,6 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha1-tSXhI4SJpez8Qq+sw/6Z5mb0sao=", - "requires": { - "randombytes": "^2.1.0" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/package.json b/package.json index 706a60e1..b7bd2c10 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,8 @@ "prepare": "husky install" }, "peerDependencies": { - "react": ">=16", - "oidc-client": "^1.11.5" - }, - "dependencies": { - "oidc-client": "^1.11.5" + "react": ">=16.8.0", + "oidc-client-ts": "^2.0.0-beta.2" }, "devDependencies": { "@microsoft/api-extractor": "^7.18.10", @@ -50,6 +47,7 @@ "esbuild": "^0.13.2", "eslint": "^7.32.0", "eslint-plugin-testing-library": "^4.10.1", + "oidc-client-ts": "^2.0.0-beta.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-test-renderer": "^17.0.2", diff --git a/src/AuthContext.ts b/src/AuthContext.ts index 3739d562..a98dacd9 100644 --- a/src/AuthContext.ts +++ b/src/AuthContext.ts @@ -1,5 +1,8 @@ import React from "react"; -import type { UserManagerSettings, User, SessionStatus } from "oidc-client"; +import type { + UserManagerSettings, User, SessionStatus, + SigninPopupArgs, SigninSilentArgs, SigninRedirectArgs, + SignoutRedirectArgs, SignoutPopupArgs, QuerySessionStatusArgs } from "oidc-client-ts"; import type { AuthState } from "./AuthState"; @@ -8,17 +11,17 @@ import type { AuthState } from "./AuthState"; */ export interface AuthContextProps extends AuthState { /** - * UserManager functions. See [UserManager](https://github.com/IdentityModel/oidc-client-js/wiki#usermanager) for more details. + * UserManager functions. See [UserManager](https://github.com/authts/oidc-client-ts) for more details. */ readonly settings: UserManagerSettings; clearStaleState(): Promise; removeUser(): Promise; - signinPopup(args?: any): Promise; - signinSilent(args?: any): Promise; - signinRedirect(args?: any): Promise; - signoutRedirect(args?: any): Promise; - signoutPopup(args?: any): Promise; - querySessionStatus(args?: any): Promise; + signinPopup(args?: SigninPopupArgs): Promise; + signinSilent(args?: SigninSilentArgs): Promise; + signinRedirect(args?: SigninRedirectArgs): Promise; + signoutRedirect(args?: SignoutRedirectArgs): Promise; + signoutPopup(args?: SignoutPopupArgs): Promise; + querySessionStatus(args?: QuerySessionStatusArgs): Promise; revokeAccessToken(): Promise; startSilentRenew(): void; stopSilentRenew(): void; diff --git a/src/AuthProvider.tsx b/src/AuthProvider.tsx index 016dc9f7..45463bd2 100644 --- a/src/AuthProvider.tsx +++ b/src/AuthProvider.tsx @@ -1,5 +1,6 @@ import React from "react"; -import { UserManager, UserManagerSettings, User } from "oidc-client"; +import { UserManager, UserManagerSettings, User } from "oidc-client-ts"; +import type { SignoutRedirectArgs, SignoutPopupArgs } from "oidc-client-ts"; import { AuthContext } from "./AuthContext"; import { initialAuthState } from "./AuthState"; @@ -110,7 +111,7 @@ export const AuthProvider = (props: AuthProviderProps): JSX.Element => { const [state, dispatch] = React.useReducer(reducer, initialAuthState); const userManagerContext = React.useMemo( () => ({ - settings: userManager?.settings ?? {}, + settings: userManager?.settings ?? { ...userManagerProps }, ...(Object.fromEntries( userManagerContextKeys.map((key) => [ key, @@ -177,14 +178,14 @@ export const AuthProvider = (props: AuthProviderProps): JSX.Element => { const signoutRedirect = React.useMemo( () => userManager - ? (args?: any) => userManager.signoutRedirect(args).then(onSignoutRedirect) + ? (args?: SignoutRedirectArgs) => userManager.signoutRedirect(args).then(onSignoutRedirect) : unsupportedEnvironment("signoutRedirect"), [userManager, onSignoutRedirect] ); const signoutPopup = React.useMemo( () => userManager - ? (args?: any) => userManager.signoutPopup(args).then(onSignoutPopup) + ? (args?: SignoutPopupArgs) => userManager.signoutPopup(args).then(onSignoutPopup) : unsupportedEnvironment("signoutPopup"), [userManager, onSignoutPopup] ); diff --git a/src/AuthState.ts b/src/AuthState.ts index b9c321e6..bdaee6f9 100644 --- a/src/AuthState.ts +++ b/src/AuthState.ts @@ -1,4 +1,4 @@ -import type { User } from "oidc-client"; +import type { User } from "oidc-client-ts"; /** * The auth state which, when combined with the auth methods, make up the return object of the `useAuth` hook. diff --git a/src/reducer.ts b/src/reducer.ts index c22e00fe..4766c505 100644 --- a/src/reducer.ts +++ b/src/reducer.ts @@ -1,4 +1,4 @@ -import type { User } from "oidc-client"; +import type { User } from "oidc-client-ts"; import type { AuthState } from "./AuthState"; diff --git a/test/AuthProvider.test.tsx b/test/AuthProvider.test.tsx index 30ace8be..9e9fc3fe 100644 --- a/test/AuthProvider.test.tsx +++ b/test/AuthProvider.test.tsx @@ -1,17 +1,18 @@ /* eslint-disable @typescript-eslint/unbound-method */ -import { UserManager, User } from "oidc-client"; +import { UserManager, User } from "oidc-client-ts"; import { renderHook } from "@testing-library/react-hooks"; import { mocked } from "ts-jest/utils"; import { useAuth } from "../src/useAuth"; import { createWrapper } from "./helpers"; +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" }; const user = { id_token: "__test_user__" } as User; describe("AuthProvider", () => { it("should signinRedirect when asked", async () => { // arrange - const wrapper = createWrapper(); + const wrapper = createWrapper({ ...settingsStub }); const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }); @@ -38,7 +39,7 @@ describe("AuthProvider", () => { "https://www.example.com/?code=__test_code__&state=__test_state__" ); - const wrapper = createWrapper({ onSigninCallback }); + const wrapper = createWrapper({ ...settingsStub, onSigninCallback }); // act const { waitForNextUpdate } = renderHook(() => useAuth(), { @@ -63,7 +64,7 @@ describe("AuthProvider", () => { "https://www.example.com/?error=__test_error__&state=__test_state__" ); - const wrapper = createWrapper({ onSigninCallback }); + const wrapper = createWrapper({ ...settingsStub, onSigninCallback }); // act const { waitForNextUpdate } = renderHook(() => useAuth(), { @@ -80,7 +81,7 @@ describe("AuthProvider", () => { // arrange const onRemoveUser = jest.fn(); - const wrapper = createWrapper({ onRemoveUser }); + const wrapper = createWrapper({ ...settingsStub, onRemoveUser }); const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }); @@ -97,7 +98,7 @@ describe("AuthProvider", () => { it("should handle signoutRedirect and call onSignoutRedirect", async () => { // arrange const onSignoutRedirect = jest.fn(); - const wrapper = createWrapper({ onSignoutRedirect }); + const wrapper = createWrapper({ ...settingsStub, onSignoutRedirect }); const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }); @@ -114,7 +115,7 @@ describe("AuthProvider", () => { it("should handle signoutPopup and call onSignoutPopup", async () => { // arrange const onSignoutPopup = jest.fn(); - const wrapper = createWrapper({ onSignoutPopup }); + const wrapper = createWrapper({ ...settingsStub, onSignoutPopup }); const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }); @@ -131,7 +132,7 @@ describe("AuthProvider", () => { it("should get the user", async () => { // arrange mocked(UserManager.prototype).getUser.mockResolvedValueOnce(user); - const wrapper = createWrapper(); + const wrapper = createWrapper({ ...settingsStub }); // act const { waitForNextUpdate, result } = renderHook(() => useAuth(), { @@ -148,7 +149,7 @@ describe("AuthProvider", () => { class CustomUserManager extends UserManager { } mocked(CustomUserManager.prototype).signinRedirect = jest.fn(); - const wrapper = createWrapper({ implementation: CustomUserManager }); + const wrapper = createWrapper({ ...settingsStub, implementation: CustomUserManager }); const { waitForNextUpdate, result } = renderHook(() => useAuth(), { wrapper, }); @@ -165,7 +166,7 @@ describe("AuthProvider", () => { it("should should throw when no UserManager implementation exists", async () => { // arrange - const wrapper = createWrapper({ implementation: null }); + const wrapper = createWrapper({ ...settingsStub, implementation: null }); const { result } = renderHook(() => useAuth(), { wrapper, }); diff --git a/test/__mocks__/oidc-client.ts b/test/__mocks__/oidc-client-ts.ts similarity index 99% rename from test/__mocks__/oidc-client.ts rename to test/__mocks__/oidc-client-ts.ts index dae659a6..464faa12 100644 --- a/test/__mocks__/oidc-client.ts +++ b/test/__mocks__/oidc-client-ts.ts @@ -1,4 +1,4 @@ -import type { UserManager, UserManagerEvents } from "oidc-client"; +import type { UserManager, UserManagerEvents } from "oidc-client-ts"; const MockUserManager: typeof UserManager = jest.fn(function (this: { events: Partial }) { this.events = { diff --git a/test/helpers.tsx b/test/helpers.tsx index 237d8565..bf0b6890 100644 --- a/test/helpers.tsx +++ b/test/helpers.tsx @@ -2,11 +2,10 @@ import React from "react"; import { AuthProvider, AuthProviderProps } from "../src/AuthProvider"; -export const createWrapper = (opts?: AuthProviderProps) => ({ +export const createWrapper = (opts: AuthProviderProps) => ({ children, }: React.PropsWithChildren): JSX.Element => ( {children} diff --git a/test/useAuth.test.tsx b/test/useAuth.test.tsx index bc2732df..bcd2a519 100644 --- a/test/useAuth.test.tsx +++ b/test/useAuth.test.tsx @@ -3,10 +3,12 @@ import { renderHook } from "@testing-library/react-hooks"; import { useAuth } from "../src/useAuth"; import { createWrapper } from "./helpers"; +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" }; + describe("useAuth", () => { it("should provide the auth context", async () => { // arrange - const wrapper = createWrapper(); + const wrapper = createWrapper({ ...settingsStub }); const { result, waitForNextUpdate } = renderHook(useAuth, { wrapper }); await waitForNextUpdate(); diff --git a/test/withAuth.test.tsx b/test/withAuth.test.tsx index fb9018f9..c8f9a928 100644 --- a/test/withAuth.test.tsx +++ b/test/withAuth.test.tsx @@ -4,6 +4,8 @@ import "@testing-library/jest-dom/extend-expect"; import { AuthContextProps, AuthProvider, withAuth } from "../src"; +const settingsStub = { authority: "authority", client_id: "client", redirect_uri: "redirect" }; + describe("withAuth", () => { it("should wrap a class component", async () => { // arrange @@ -17,7 +19,7 @@ describe("withAuth", () => { // act const WrappedComponent = withAuth(MyComponent); render( - + );