diff --git a/CHANGELOG.md b/CHANGELOG.md index fc1c2f15..9a348814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Fix 404 error page when logging in after changing password in Eureka. Refs STCOR-845. * Always retrieve `clientId` and `tenant` values from `config.tenantOptions` in stripes.config.js. Retires `okapi.tenant`, `okapi.clientId`, and `config.isSingleTenant`. Refs STCOR-787. * List UI apps in "Applications/modules/interfaces" column. STCOR-773 +* Correctly evaluate `stripes.okapi` before rendering ``. Refs STCOR-864. ## [10.1.1](https://github.com/folio-org/stripes-core/tree/v10.1.1) (2024-03-25) [Full Changelog](https://github.com/folio-org/stripes-core/compare/v10.1.0...v10.1.1) diff --git a/src/RootWithIntl.js b/src/RootWithIntl.js index 5f2318d2..b51265cc 100644 --- a/src/RootWithIntl.js +++ b/src/RootWithIntl.js @@ -72,7 +72,7 @@ const RootWithIntl = ({ stripes, token = '', isAuthenticated = false, disableAut event={events.LOGIN} stripes={connectedStripes} /> - { (connectedStripes.okapi !== 'object' || connectedStripes.discovery.isFinished) && ( + { (typeof connectedStripes.okapi !== 'object' || connectedStripes.discovery.isFinished) && ( {connectedStripes.config.useSecureTokens && } diff --git a/src/RootWithIntl.test.js b/src/RootWithIntl.test.js index 4da7f32b..6aa1baba 100644 --- a/src/RootWithIntl.test.js +++ b/src/RootWithIntl.test.js @@ -2,25 +2,34 @@ /* eslint-disable no-unused-vars */ import { render, screen } from '@folio/jest-config-stripes/testing-library/react'; +import { Router as DefaultRouter } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; -import { Redirect as InternalRedirect } from 'react-router-dom'; -import Redirect from './components/Redirect'; -import { Login } from './components'; -import PreLoginLanding from './components/PreLoginLanding'; +import AuthnLogin from './components/AuthnLogin'; +import MainNav from './components/MainNav'; +import MainContainer from './components/MainContainer'; +import ModuleContainer from './components/ModuleContainer'; +import RootWithIntl from './RootWithIntl'; +import Stripes from './Stripes'; -// import { -// renderLogoutComponent -// } from './RootWithIntl'; +jest.mock('./components/AuthnLogin', () => () => ''); +jest.mock('./components/MainNav', () => () => ''); +jest.mock('./components/ModuleContainer', () => () => ''); +jest.mock('./components/MainContainer', () => ({ children }) => children); -import AuthnLogin from './components/AuthnLogin'; +const defaultHistory = createMemoryHistory(); -jest.mock('react-router-dom', () => ({ - Redirect: () => '', - withRouter: (Component) => Component, -})); -jest.mock('./components/Redirect', () => () => ''); -jest.mock('./components/Login', () => () => ''); -jest.mock('./components/PreLoginLanding', () => () => ''); +const Harness = ({ + Router = DefaultRouter, + children, + history = defaultHistory, +}) => { + return ( + + {children} + + ); +}; const store = { getState: () => ({ @@ -34,56 +43,53 @@ const store = { }; describe('RootWithIntl', () => { - describe('AuthnLogin', () => { - it('handles legacy login', () => { - const stripes = { okapi: {}, config: {}, store }; - render(); + it('renders login without one of (isAuthenticated, token, disableAuth)', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, discovery: { isFinished: false } }); + await render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + expect(screen.queryByText(//)).toBeNull(); + }); + + describe('renders MainNav', () => { + it('given isAuthenticated', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, discovery: { isFinished: false } }); + await render(); - expect(screen.getByText(//)).toBeInTheDocument(); + expect(screen.queryByText(//)).toBeNull(); + expect(screen.queryByText(//)).toBeInTheDocument(); }); - describe('handles third-party login', () => { - it('handles single-tenant', () => { - const stripes = { - okapi: { authnUrl: 'https://barbie.com' }, - config: { - isSingleTenant: true, - tenantOptions: { - diku: { name: 'diku', clientId: 'diku-application' } - } - }, - store - }; - render(); - - expect(screen.getByText(//)).toBeInTheDocument(); - }); - - it('handles multi-tenant', () => { - const stripes = { - okapi: { authnUrl: 'https://oppie.com' }, - config: { - isSingleTenant: false, - tenantOptions: { - diku: { name: 'diku', clientId: 'diku-application' }, - diku2: { name: 'diku2', clientId: 'diku2-application' } - } - }, - store - }; - render(); - - expect(screen.getByText(//)).toBeInTheDocument(); - }); + it('given token', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, discovery: { isFinished: false } }); + await render(); + + expect(screen.queryByText(//)).toBeNull(); + expect(screen.queryByText(//)).toBeInTheDocument(); + }); + + it('given disableAuth', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, discovery: { isFinished: false } }); + await render(); + + expect(screen.queryByText(//)).toBeNull(); + expect(screen.queryByText(//)).toBeInTheDocument(); }); }); - // describe('renderLogoutComponent', () => { - // it('handles legacy logout', () => { - // const stripes = { okapi: {}, config: {} }; - // render(renderLogoutComponent(stripes)); + describe('renders ModuleContainer', () => { + it('if config.okapi is not an object', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, discovery: { isFinished: true } }); + await render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + }); - // expect(screen.getByText(//)).toBeInTheDocument(); - // }); - // }); + it('if discovery is finished', async () => { + const stripes = new Stripes({ epics: {}, logger: {}, bindings: {}, config: {}, store, okapi: {}, discovery: { isFinished: true } }); + await render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + }); + }); }); diff --git a/src/components/AuthnLogin/AuthnLogin.test.js b/src/components/AuthnLogin/AuthnLogin.test.js new file mode 100644 index 00000000..e8aa7ffd --- /dev/null +++ b/src/components/AuthnLogin/AuthnLogin.test.js @@ -0,0 +1,76 @@ +/* shhhh, eslint, it's ok. we need "unused" imports for mocks */ +/* eslint-disable no-unused-vars */ + +import { render, screen } from '@folio/jest-config-stripes/testing-library/react'; + +import { Redirect as InternalRedirect } from 'react-router-dom'; +import Redirect from '../Redirect'; +import Login from '../Login'; +import PreLoginLanding from '../PreLoginLanding'; + +import AuthnLogin from './AuthnLogin'; + +jest.mock('react-router-dom', () => ({ + Redirect: () => '', + withRouter: (Component) => Component, +})); +jest.mock('../Redirect', () => () => ''); +jest.mock('../Login', () => () => ''); +jest.mock('../PreLoginLanding', () => () => ''); + +const store = { + getState: () => ({ + okapi: { + token: '123', + }, + }), + dispatch: () => {}, + subscribe: () => {}, + replaceReducer: () => {}, +}; + +describe('RootWithIntl', () => { + describe('AuthnLogin', () => { + it('handles legacy login', () => { + const stripes = { okapi: {}, config: {}, store }; + render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + }); + + describe('handles third-party login', () => { + it('handles single-tenant', () => { + const stripes = { + okapi: { authnUrl: 'https://barbie.com' }, + config: { + isSingleTenant: true, + tenantOptions: { + diku: { name: 'diku', clientId: 'diku-application' } + } + }, + store + }; + render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + }); + + it('handles multi-tenant', () => { + const stripes = { + okapi: { authnUrl: 'https://oppie.com' }, + config: { + isSingleTenant: false, + tenantOptions: { + diku: { name: 'diku', clientId: 'diku-application' }, + diku2: { name: 'diku2', clientId: 'diku2-application' } + } + }, + store + }; + render(); + + expect(screen.getByText(//)).toBeInTheDocument(); + }); + }); + }); +}); diff --git a/test/bigtest/helpers/setup-application.js b/test/bigtest/helpers/setup-application.js index c54aa590..7346300d 100644 --- a/test/bigtest/helpers/setup-application.js +++ b/test/bigtest/helpers/setup-application.js @@ -54,6 +54,9 @@ export default function setupApplication({ currentPerms: permissions, isAuthenticated: true, }; + initialState.discovery = { + isFinished: true, + }; } else { initialState.okapi = { ssoEnabled: true, diff --git a/test/jest/__mock__/stripesComponents.mock.js b/test/jest/__mock__/stripesComponents.mock.js index 444365db..ba14f98f 100644 --- a/test/jest/__mock__/stripesComponents.mock.js +++ b/test/jest/__mock__/stripesComponents.mock.js @@ -49,6 +49,7 @@ jest.mock('@folio/stripes-components', () => ({ {children} )), Headline: jest.fn(({ children }) =>
{ children }
), + HotKeys: jest.fn(({ children }) => <>{ children }), Icon: jest.fn((props) => (props && props.children ? props.children : )), IconButton: jest.fn(({ buttonProps,