Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/views/oauth/OAuthError.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import { SlideDown } from 'src/components/SlideDown'
import { getDelay } from 'src/utilities/getDelay'
import { PostMessageContext } from 'src/ConnectWidget'
import { getSelectedInstitution } from 'src/redux/selectors/Connect'
import { selectConnectConfig } from 'src/redux/reducers/configSlice'

export const OAuthError = React.forwardRef((props, navigationRef) => {
useAnalyticsPath(...PageviewInfo.CONNECT_OAUTH_ERROR)
const { currentMember, onRetry, onReturnToSearch } = props

const postMessageFunctions = useContext(PostMessageContext)
const connectConfig = useSelector(selectConnectConfig)
const errorReason = useSelector((state) => state.connect.oauthErrorReason)
const selectedInstitution = useSelector(getSelectedInstitution)
const tokens = useTokens()
Expand All @@ -35,10 +37,13 @@ export const OAuthError = React.forwardRef((props, navigationRef) => {
onReturnToSearch()
},
showBackButton() {
return true
// Going back leads to the institution search, which is not available
// when disable_institution_search is set. The "Try again" button
// remains as the primary action.
return !connectConfig.disable_institution_search
},
}
}, [])
}, [connectConfig.disable_institution_search])

// If we have an oauth error, send the post message.
useEffect(() => {
Expand Down
16 changes: 14 additions & 2 deletions src/views/oauth/OAuthStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,22 @@ export const OAuthStep = React.forwardRef((props, navigationRef) => {
}
},
showBackButton() {
return true
// The interstitial disclosure and waiting views handle "back" within this
// step, so the back button stays available for them. Otherwise, going back
// leads to the institution search, which is not available when
// disable_institution_search is set.
if (showInterstitialDisclosure || isWaitingForOAuth) {
return true
}
return !config.disable_institution_search
},
}
}, [isWaitingForOAuth, oauthStartError, showInterstitialDisclosure])
}, [
isWaitingForOAuth,
oauthStartError,
showInterstitialDisclosure,
config.disable_institution_search,
])

/**
* Called when we succesfully generate an oauth window uri for the exsting
Expand Down
27 changes: 26 additions & 1 deletion src/views/oauth/__tests__/OAuthError-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { render, screen, waitFor } from 'src/utilities/testingLibrary'

import { OAuthError, getOAuthErrorMessage } from 'src/views/oauth/OAuthError'
import { OAUTH_ERROR_REASONS } from 'src/const/Connect'
import { institutionData } from 'src/services/mockedData'
import { initialState as mockedState, institutionData } from 'src/services/mockedData'

type NavigationHandle = { handleBackButton: () => void; showBackButton: () => boolean }

describe('OAuthError', () => {
const defaultProps = {
Expand Down Expand Up @@ -33,6 +35,29 @@ describe('OAuthError', () => {
expect(defaultProps.onRetry).toHaveBeenCalledTimes(1)
})

it('shows the navigation back button by default', () => {
const ref = React.createRef<NavigationHandle>()

render(<OAuthError {...defaultProps} ref={ref} />, {
preloadedState: initialState,
})

expect(ref.current?.showBackButton()).toBe(true)
})

it('hides the navigation back button when disable_institution_search is true', () => {
const ref = React.createRef<NavigationHandle>()

render(<OAuthError {...defaultProps} ref={ref} />, {
preloadedState: {
...initialState,
config: { ...mockedState.config, disable_institution_search: true },
},
})

expect(ref.current?.showBackButton()).toBe(false)
})

describe('getOAuthErrorMessage util', () => {
it('DEFAULT message is returned when given a blank reason', () => {
expect(getOAuthErrorMessage('Default/Fallback')).toEqual(
Expand Down
55 changes: 54 additions & 1 deletion src/views/oauth/__tests__/OAuthStep-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { render, screen, waitFor } from 'src/utilities/testingLibrary'
import { OAuthStep } from 'src/views/oauth/OAuthStep'
import { apiValue } from 'src/const/apiProviderMock'
import { ApiProvider } from 'src/context/ApiContext'
import { OAUTH_STATE } from 'src/services/mockedData'
import { initialState, OAUTH_STATE } from 'src/services/mockedData'

type NavigationHandle = { handleBackButton: () => void; showBackButton: () => boolean }

describe('OauthStep view', () => {
describe('Ensure OAuthDefault is rendered', () => {
Expand Down Expand Up @@ -111,4 +113,55 @@ describe('OauthStep view', () => {
)
}, 35000)
})

describe('showBackButton', () => {
const defaultProps = {
institution: { guid: 'INS-123', name: 'MX Bank', instructional_data: {} },
onGoBack: vi.fn(),
}

const renderOAuthStep = async (configOverrides = {}) => {
const ref = React.createRef<NavigationHandle>()
const { user } = render(
<ApiProvider apiValue={apiValue}>
<OAuthStep {...defaultProps} ref={ref} />
</ApiProvider>,
{
preloadedState: {
config: { ...initialState.config, ...configOverrides },
connect: {
members: [],
currentMemberGuid: null,
location: [{ step: 'ENTER_CREDENTIALS' }],
},
},
},
)

await screen.findByTestId('continue-button')

return { ref, user }
}

it('shows the back button by default', async () => {
const { ref } = await renderOAuthStep()

expect(ref.current?.showBackButton()).toBe(true)
})

it('hides the back button when disable_institution_search is true', async () => {
const { ref } = await renderOAuthStep({ disable_institution_search: true })

expect(ref.current?.showBackButton()).toBe(false)
})

it('still shows the back button while waiting for OAuth when disable_institution_search is true', async () => {
const { ref, user } = await renderOAuthStep({ disable_institution_search: true })

await user.click(screen.getByTestId('continue-button'))
await screen.findByRole('button', { name: 'Try again' })

expect(ref.current?.showBackButton()).toBe(true)
})
})
})