Skip to content

Commit

Permalink
feat: merging master changes with stabilizaing auth0
Browse files Browse the repository at this point in the history
  • Loading branch information
panvourtsis committed Feb 20, 2024
1 parent 9132312 commit 5d2be07
Show file tree
Hide file tree
Showing 19 changed files with 2,492 additions and 359 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
},
"rules": {
/* React rules */
"react/react-in-jsx-scope": "off",
"react/no-direct-mutation-state": "error",
"react/no-unused-prop-types": "warn",
"react/self-closing-comp": [
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ on:
- 'next'
- 'v3.x'

permissions:
packages: write
contents: write
id-token: write

jobs:
deploy:
name: Deploy
Expand Down
90 changes: 44 additions & 46 deletions __mocks__/@auth0/auth0-spa-js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,57 +38,55 @@ export const handleRedirectCallback = jest.fn(() => {
export const isAuthenticated = jest.fn();
export const logout = jest.fn();
export const loginWithPopup = jest.fn();
export const createAuth0Client = jest.fn().mockImplementation((options: any) =>
Promise.resolve({
getTokenSilently,
loginWithRedirect,
loginWithPopup,
getUser,
logout,
handleRedirectCallback,
isAuthenticated,
options: {
...options,
onRedirectCallback,
},
cacheLocation: 'localstorage',
httpTimeoutMs: 10000,
cookieStorage: {
export const Auth0Client = jest.fn().mockImplementation((options: any) => ({
getTokenSilently,
loginWithRedirect,
loginWithPopup,
getUser,
logout,
handleRedirectCallback,
isAuthenticated,
options: {
...options,
onRedirectCallback,
},
cacheLocation: 'localstorage',
httpTimeoutMs: 10000,
cookieStorage: {
get: jest.fn(),
save: jest.fn(),
remove: jest.fn(),
},
orgHintCookieName: 'auth0..organization_hint',
isAuthenticatedCookieName: 'auth0..is.authenticated',
sessionCheckExpiryDays: 1,
scope: 'offline_access',
transactionManager: {
storage: {
get: jest.fn(),
save: jest.fn(),
remove: jest.fn(),
},
orgHintCookieName: 'auth0..organization_hint',
isAuthenticatedCookieName: 'auth0..is.authenticated',
sessionCheckExpiryDays: 1,
scope: 'offline_access',
transactionManager: {
storage: {
get: jest.fn(),
save: jest.fn(),
remove: jest.fn(),
},
clientId: '',
storageKey: 'a0.spajs.txs.',
transaction: null,
},
clientId: '',
storageKey: 'a0.spajs.txs.',
transaction: null,
},
nowProvider: jest.fn(),
cacheManager: {
cache: {},
keyManifest: null,
nowProvider: jest.fn(),
cacheManager: {
cache: {},
keyManifest: null,
nowProvider: jest.fn(),
},
domainUrl: 'https://',
tokenIssuer: 'https:///',
defaultScope: 'openid profile email',
customOptions: {
onRedirectCallback,
organization: undefined,
},
useRefreshTokensFallback: true,
useRefreshTokens: true,
})
);
},
domainUrl: 'https://',
tokenIssuer: 'https:///',
defaultScope: 'openid profile email',
customOptions: {
onRedirectCallback,
organization: undefined,
},
useRefreshTokensFallback: true,
useRefreshTokens: true,
}));

/*
* Mock auth0 client with predefined values
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"react-dom": "^18.1.0",
"react-router-dom": "^5.3.1",
"rimraf": "^3.0.2",
"semantic-release": "^22.0.12",
"ts-jest": "^27.1.4",
"ts-lib": "^0.0.5",
"tsc-watch": "^5.0.3",
Expand Down
54 changes: 41 additions & 13 deletions src/__tests__/Authentication.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ class CustomError extends Error {
import { ErrorBoundary, useErrorHandler } from 'react-error-boundary';

import {
fakeTokenData,
FAKE_TOKEN,
fakeTokenData,
getNewFakeToken,
getTokenSilently as mockedGetTokenSilently,
getUser,
handleRedirectCallback as mockedHandleRedirectCallback,
isAuthenticated,
loginWithRedirect,
logout,
Auth0Client as mockedCreateAuth0,
getTokenSilently as mockedGetTokenSilently,
handleRedirectCallback as mockedHandleRedirectCallback,
} from '../../__mocks__/@auth0/auth0-spa-js';
import { defaultAuthenticationContextValues } from '../contexts/authentication';
import { useAuthentication } from '../hooks/useAuthentication';
Expand All @@ -31,7 +33,7 @@ import MockRequest from '../request/mock';
import { orfiumIdBaseInstance } from '../request/orfium-id-base-instance';
import useOrganization from '../store/organizations';
import useRequestToken from '../store/requestToken';
import { getTokenSilently, logoutAuth, onRedirectCallback } from '../utils/auth';
import { getAuth0Client, getTokenSilently, logoutAuth, onRedirectCallback } from '../utils/auth';

const TestingComponentSimple = () => {
const { user, isAuthenticated, isLoading } = useAuthentication();
Expand Down Expand Up @@ -284,6 +286,7 @@ describe('Context', () => {
isAuthenticated.mockResolvedValue(true);
getUser.mockResolvedValue({
name: 'John Doe',
updated_at: new Date().toDateString(),
});

const { findByText, getByTestId } = render(
Expand Down Expand Up @@ -313,7 +316,7 @@ describe('Context', () => {
</ErrorBoundary>
);

await waitFor(() => expect(loginWithRedirect).toBeCalledTimes(1));
await waitFor(() => expect(logout).toBeCalledTimes(1));
});

test('loginWithRedirect when access token fails and handle an error', async () => {
Expand Down Expand Up @@ -422,14 +425,8 @@ describe('Context', () => {
</Organizations>
);

await waitFor(() => expect(screen.getByTestId('isLoading').innerHTML).toBe('false'));
await waitFor(() => expect(loginWithRedirect).toBeCalledTimes(1));
expect(loginWithRedirect).toBeCalledWith({
authorizationParams: {
organization: organizationList[0].org_id,
invitation: undefined,
},
});
await waitFor(() => expect(screen.getByTestId('isLoading').innerHTML).toBe('true'));
await waitFor(() => expect(logout).toBeCalledTimes(1));
}, 10000);

test('Context default functions', async () => {
Expand All @@ -440,4 +437,35 @@ describe('Context', () => {
expect(await defaultAuthenticationContextValues.logout()).toBe('logged out');
expect(await defaultAuthenticationContextValues.loginWithRedirect()).toBe(undefined);
});

test('getAuth0Client failed process', async () => {
expect.assertions(1);
mockedCreateAuth0.mockImplementation(() => {
throw new Error();
});
// @ts-ignore
client = undefined;
try {
getAuth0Client();
} catch (e) {
expect(e).toEqual(new Error(`getAuth0Client Error: Error`));
}
});

test('logoutAuth failed process', async () => {
expect.assertions(1);

// @ts-ignore
client = undefined;
// @ts-ignore make logout fail with no .logout property on client
mockedCreateAuth0.mockImplementation(() => {
return {};
});

try {
await logoutAuth();
} catch (e) {
expect(e).toEqual(new Error(`logoutAuth Error: client is not defined`));
}
});
});
31 changes: 29 additions & 2 deletions src/__tests__/Toolbox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { cleanup, render, waitFor } from '@testing-library/react';
import {
getNewFakeToken,
getTokenSilently,
getUser,
isAuthenticated,
loginWithRedirect,
} from '../../__mocks__/@auth0/auth0-spa-js';
Expand Down Expand Up @@ -38,7 +39,17 @@ describe('Authentication: ', () => {

xit('renders the test component', async () => {
getTokenSilently.mockResolvedValue(getNewFakeToken());
jest.mock('../store/useUser', () => ({
__esModule: true,
default: {
user: {},
},
}));
isAuthenticated.mockResolvedValue(true);
getUser.mockResolvedValue({
name: 'John Doe',
updated_at: new Date().toDateString(),
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mock.onGet('/memberships/').reply(200, [{ org_id: 'a' }]);
Expand All @@ -51,7 +62,11 @@ describe('Authentication: ', () => {

expect(await findByTestId('orfium-auth-loading')).toBeTruthy();

expect(await findByTestId('test')).toBeTruthy();
expect(
await findByTestId('test', undefined, {
timeout: 3000,
})
).toBeTruthy();
});

xit('redirects to login if not authenticated', async () => {
Expand All @@ -73,6 +88,10 @@ describe('Authentication: ', () => {
xit('renders the loading while its authenticating', async () => {
getTokenSilently.mockResolvedValue(getNewFakeToken());
isAuthenticated.mockResolvedValue(true);
getUser.mockResolvedValue({
name: 'John Doe',
updated_at: new Date().toDateString(),
});
const { findByTestId } = render(
<Authentication>
<TestComp />
Expand All @@ -84,6 +103,10 @@ describe('Authentication: ', () => {
xit('renders the no organization message when it should', async () => {
getTokenSilently.mockResolvedValue(getNewFakeToken());
isAuthenticated.mockResolvedValue(true);
getUser.mockResolvedValue({
name: 'John Doe',
updated_at: new Date().toDateString(),
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mock.onGet('/memberships/').replyOnce(200, []);
Expand All @@ -95,6 +118,10 @@ describe('Authentication: ', () => {
);

expect(await findByTestId('orfium-auth-loading')).toBeTruthy();
expect(await findByTestId('orfium-no-organizations')).toBeTruthy();
expect(
await findByTestId('orfium-no-organizations', undefined, {
timeout: 13000,
})
).toBeTruthy();
});
});
4 changes: 1 addition & 3 deletions src/__tests__/request.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { cleanup } from '@testing-library/react';
import { AxiosInstance, type AxiosRequestConfig } from 'axios';

// @ts-ignore
import { FAKE_TOKEN, getTokenSilently } from '../../__mocks__/@auth0/auth0-spa-js';
import { createAPIInstance, CreateAPIInstanceType } from '../request/createAPIInstance';
import { CreateAPIInstanceType, METHODS, createAPIInstance } from '../request';
import MockRequest from '../request/mock';
import { METHODS } from '../request/request';

describe('Request: ', () => {
let factory: CreateAPIInstanceType;
Expand Down
Empty file.
Empty file.
Empty file added src/authentication/context.tsx
Empty file.
2 changes: 1 addition & 1 deletion src/contexts/authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type AuthenticationContextValue = {
isAuthenticated: boolean;
isLoading: boolean;
loginWithRedirect(o?: RedirectLoginOptions): Promise<void>;
logout: () => void;
logout: (props?: { force?: boolean }) => Promise<void | string>;
getAccessTokenSilently: GetAccessTokenSilently;
user: User | undefined;
permissions: Permissions;
Expand Down
Loading

0 comments on commit 5d2be07

Please sign in to comment.