diff --git a/app/javascript/src/AuthenticationProviders/components/AccountAuthenticationProviders.tsx b/app/javascript/src/AuthenticationProviders/components/AccountAuthenticationProviders.tsx index 70757f384a..c5ac74236d 100644 --- a/app/javascript/src/AuthenticationProviders/components/AccountAuthenticationProviders.tsx +++ b/app/javascript/src/AuthenticationProviders/components/AccountAuthenticationProviders.tsx @@ -10,6 +10,7 @@ import { useState } from 'react' import { EnforceSSOSwitch } from 'AuthenticationProviders/components/EnforceSSOSwitch' import { AuthenticationProvidersTable } from 'AuthenticationProviders/components/AuthenticationProvidersTable' +import { AuthenticationProvidersEmptyState } from 'AuthenticationProviders/components/AuthenticationProvidersEmptyState' import { createReactWrapper } from 'utilities/createReactWrapper' import { ajaxJSON } from 'utilities/ajax' import * as flash from 'utilities/flash' @@ -110,10 +111,12 @@ const AccountAuthenticationProviders: FunctionComponent = ({ )} - - {/* eslint-disable-next-line react/jsx-props-no-spreading */} - - + {!table.count ? : ( + + {/* eslint-disable-next-line react/jsx-props-no-spreading */} + + + )} {openModal === 'enable' && ( diff --git a/app/javascript/src/AuthenticationProviders/components/AuthenticationProvidersEmptyState.tsx b/app/javascript/src/AuthenticationProviders/components/AuthenticationProvidersEmptyState.tsx new file mode 100644 index 0000000000..ee38512058 --- /dev/null +++ b/app/javascript/src/AuthenticationProviders/components/AuthenticationProvidersEmptyState.tsx @@ -0,0 +1,35 @@ +import React from 'react' +import { + Title, + Button, + EmptyState, + EmptyStateIcon, + EmptyStateBody +} from '@patternfly/react-core' +import UserIcon from '@patternfly/react-icons/dist/esm/icons/user-icon' + +interface Props { + newHref: string; +} + +const AuthenticationProvidersEmptyState: React.FC = ({ newHref }) => ( + + + + No SSO integrations + + + Choose a Single Sign-On (SSO) provider and create an integration to access the Admin Portal. + + + +) + +export type { Props } +export { AuthenticationProvidersEmptyState } diff --git a/features/provider/admin/account/authentication_providers/new.feature b/features/provider/admin/account/authentication_providers/new.feature index c9aed6a9e9..a8879259bb 100644 --- a/features/provider/admin/account/authentication_providers/new.feature +++ b/features/provider/admin/account/authentication_providers/new.feature @@ -6,9 +6,20 @@ Feature: Account Settings > Users > SSO Integrations > New Scenario: Navigation Given they go to the users sso integrations page - When they follow "Create a new SSO integration" + When they follow "Add a SSO integration" Then the current page is the new sso integration page + Scenario: Navigation when there is an integration + Given a red hat single sign-on integration + And they go to the users sso integrations page + Then they should not see "Add a SSO integration" + And there should be a link to "Create a new SSO integration" + + Scenario: Empty state + Given they go to the users sso integrations page + Then they should see "No SSO integrations" + And there should be a link to "Add a SSO integration" + Scenario: Create RH SSO new integration Given they go to the new sso integration page When the form is submitted with: diff --git a/jest.config.js b/jest.config.js index 23afd65ec1..0a5e855289 100644 --- a/jest.config.js +++ b/jest.config.js @@ -191,10 +191,9 @@ module.exports = { }, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - // transformIgnorePatterns: [ - // "/node_modules/", - // "\\.pnp\\.[^\\/]+$" - // ], + transformIgnorePatterns: [ + 'node_modules/(?!(?:@patternfly/react-icons)/)', // Transform @patternfly/react-icons + ], // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them // unmockedModulePathPatterns: undefined, diff --git a/spec/javascripts/AuthenticationProviders/components/AccountAuthenticationProviders.spec.tsx b/spec/javascripts/AuthenticationProviders/components/AccountAuthenticationProviders.spec.tsx index 61bea0f4c5..d02ad50f7b 100644 --- a/spec/javascripts/AuthenticationProviders/components/AccountAuthenticationProviders.spec.tsx +++ b/spec/javascripts/AuthenticationProviders/components/AccountAuthenticationProviders.spec.tsx @@ -8,6 +8,7 @@ import { AccountAuthenticationProviders } from 'AuthenticationProviders/componen import { mockLocation, waitForPromises } from 'utilities/test-utils' import { EnforceSSOSwitch } from 'AuthenticationProviders/components/EnforceSSOSwitch' import { AuthenticationProvidersTable } from 'AuthenticationProviders/components/AuthenticationProvidersTable' +import { AuthenticationProvidersEmptyState } from 'AuthenticationProviders/components/AuthenticationProvidersEmptyState' import type { Props } from 'AuthenticationProviders/components/AccountAuthenticationProviders' @@ -43,15 +44,15 @@ afterAll(() => { describe('when SSO toggle is hidden', () => { const props = { showToggle: false } - it('should only render a table', () => { + it('should render empty state', () => { const wrapper = shallowWrapper(props) expect(wrapper.exists(EnforceSSOSwitch)).toEqual(false) - expect(wrapper.exists(AuthenticationProvidersTable)).toEqual(true) + expect(wrapper.exists(AuthenticationProvidersEmptyState)).toEqual(true) }) }) describe('when SSO toggle is visible', () => { - const props = { showToggle: true } + const props = { showToggle: true, table: { ...defaultProps.table, count: 1 } } it('should render both a switch and a table', () => { const wrapper = shallowWrapper(props) diff --git a/spec/javascripts/AuthenticationProviders/components/AuthenticationProvidersEmptyState.spec.tsx b/spec/javascripts/AuthenticationProviders/components/AuthenticationProvidersEmptyState.spec.tsx new file mode 100644 index 0000000000..3bbce05da1 --- /dev/null +++ b/spec/javascripts/AuthenticationProviders/components/AuthenticationProvidersEmptyState.spec.tsx @@ -0,0 +1,17 @@ +import { mount } from 'enzyme' + +import { AuthenticationProvidersEmptyState } from 'AuthenticationProviders/components/AuthenticationProvidersEmptyState' + +import type { Props } from 'AuthenticationProviders/components/AuthenticationProvidersEmptyState' + +const defaultProps = { + newHref: '/new' +} + +const mountWrapper = (props: Partial = {}) => mount() + +it('should render itself', () => { + const wrapper = mountWrapper() + + expect(wrapper.exists()).toEqual(true) +})