diff --git a/services/app-web/src/pages/App/AppRoutes.tsx b/services/app-web/src/pages/App/AppRoutes.tsx
index 299677ea3c..7fb031922b 100644
--- a/services/app-web/src/pages/App/AppRoutes.tsx
+++ b/services/app-web/src/pages/App/AppRoutes.tsx
@@ -185,10 +185,6 @@ const CMSUserRoutes = ({
/>
)}
- }
- />
}>
{showQuestionResponse && (
@@ -205,6 +201,10 @@ const CMSUserRoutes = ({
/>
>
)}
+ }
+ />
}
diff --git a/services/app-web/src/pages/MccrsId/MccrsId.test.tsx b/services/app-web/src/pages/MccrsId/MccrsId.test.tsx
new file mode 100644
index 0000000000..a1379a688b
--- /dev/null
+++ b/services/app-web/src/pages/MccrsId/MccrsId.test.tsx
@@ -0,0 +1,165 @@
+import { screen, waitFor } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+
+import {
+ ldUseClientSpy,
+ renderWithProviders,
+} from '../../testHelpers/jestHelpers'
+import { MccrsId } from './MccrsId'
+
+describe('MCCRSID', () => {
+ beforeEach(() => {
+ ldUseClientSpy({ 'cms-questions': false })
+ })
+ afterEach(() => {
+ jest.resetAllMocks()
+ })
+
+ it('renders without errors', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ expect(
+ await screen.findByRole('heading', { name: 'MC-CRS record number' })
+ ).toBeInTheDocument()
+ expect(
+ screen.getByRole('button', { name: 'Save MC-CRS number' })
+ ).not.toHaveAttribute('aria-disabled')
+ })
+
+ it('displays the text field for mccrs id', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ expect(screen.getByTestId('textInput')).toBeInTheDocument()
+ })
+
+ it('cannot continue without providing a MCCRS ID', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+ const continueButton = screen.getByRole('button', {
+ name: 'Save MC-CRS number',
+ })
+ continueButton.click()
+ await waitFor(() => {
+ expect(
+ screen.getAllByText(
+ 'You must enter a record number or delete this field.'
+ )
+ ).toHaveLength(1)
+ expect(continueButton).toHaveAttribute('aria-disabled', 'true')
+ })
+ })
+
+ it('cannot continue with MCCRS ID less than 4 digits', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ screen
+ .getByLabelText(
+ 'Enter the Managed Care Contract and Rate Review System (MC-CRS) record number.'
+ )
+ .focus()
+ await userEvent.paste('123')
+ const continueButton = screen.getByRole('button', {
+ name: 'Save MC-CRS number',
+ })
+ continueButton.click()
+ await waitFor(() => {
+ expect(
+ screen.getAllByText(
+ 'You must enter no more than [4] characters'
+ )
+ ).toHaveLength(1)
+ expect(continueButton).toHaveAttribute('aria-disabled', 'true')
+ })
+ })
+
+ it('cannot continue with MCCRS ID more than 4 digits', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ screen
+ .getByLabelText(
+ 'Enter the Managed Care Contract and Rate Review System (MC-CRS) record number.'
+ )
+ .focus()
+ await userEvent.paste('12345')
+ const continueButton = screen.getByRole('button', {
+ name: 'Save MC-CRS number',
+ })
+ continueButton.click()
+ await waitFor(() => {
+ expect(
+ screen.getAllByText(
+ 'You must enter no more than [4] characters'
+ )
+ ).toHaveLength(1)
+ expect(continueButton).toHaveAttribute('aria-disabled', 'true')
+ })
+ })
+
+ it('cannot continue with MCCRS ID with non number input', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ screen
+ .getByLabelText(
+ 'Enter the Managed Care Contract and Rate Review System (MC-CRS) record number.'
+ )
+ .focus()
+ await userEvent.paste('123a')
+ const continueButton = screen.getByRole('button', {
+ name: 'Save MC-CRS number',
+ })
+ continueButton.click()
+ await waitFor(() => {
+ expect(screen.getAllByText('You must enter a number')).toHaveLength(
+ 1
+ )
+ expect(continueButton).toHaveAttribute('aria-disabled', 'true')
+ })
+ })
+
+ it('successfully adds the MCCRS ID', async () => {
+ renderWithProviders(, {
+ routerProvider: {
+ route: '/submissions/15/MCCRS-record-number',
+ },
+ })
+
+ screen
+ .getByLabelText(
+ 'Enter the Managed Care Contract and Rate Review System (MC-CRS) record number.'
+ )
+ .focus()
+ await userEvent.paste('1234')
+ const continueButton = screen.getByRole('button', {
+ name: 'Save MC-CRS number',
+ })
+ continueButton.click()
+ await waitFor(() => {
+ expect(
+ screen.getByText('Add MC-CRS record number')
+ ).toBeInTheDocument()
+ })
+ })
+})
diff --git a/services/app-web/src/pages/MccrsId/MccrsId.tsx b/services/app-web/src/pages/MccrsId/MccrsId.tsx
index c529f8ff2d..ea78554ae9 100644
--- a/services/app-web/src/pages/MccrsId/MccrsId.tsx
+++ b/services/app-web/src/pages/MccrsId/MccrsId.tsx
@@ -1,18 +1,15 @@
import React, { useState } from 'react'
-import { Form as UswdsForm, ButtonGroup, Button } from '@trussworks/react-uswds'
-import { Formik, FormikErrors, FormikHelpers } from 'formik'
+import { Form as UswdsForm, ButtonGroup } from '@trussworks/react-uswds'
+import { Formik, FormikErrors } from 'formik'
import { FieldTextInput } from '../../components/Form'
-import { ActionButton } from '../../components/ActionButton'
import { MccrsIdFormSchema } from './MccrsIdSchema'
import { recordJSException } from '../../otelHelpers/tracingHelper'
-import { useNavigate, useOutletContext, useParams } from 'react-router-dom'
-
+import { useNavigate, useParams } from 'react-router-dom'
+import { GenericApiErrorBanner } from '../../components/Banner/GenericApiErrorBanner/GenericApiErrorBanner'
+import { ActionButton } from '../../components/ActionButton'
import {
- User,
HealthPlanPackage,
- UpdateInformation,
useUpdateContractMutation,
- UpdateContractInput
} from '../../gen/gqlClient'
import styles from './MccrsId.module.scss'
@@ -23,151 +20,145 @@ type FormError =
FormikErrors[keyof FormikErrors]
type RouteParams = {
- submissionId: string
+ id: string
}
+
export const MccrsId = ({
- mccrsId,
showValidations = false,
-}: {mccrsId: string, showValidations: boolean}): React.ReactElement => {
+}: {
+ showValidations: boolean
+}): React.ReactElement => {
const [shouldValidate, setShouldValidate] = React.useState(showValidations)
- const { submissionId } = useParams()
+ const { id } = useParams()
+ const navigate = useNavigate()
const mccrsIDInitialValues: MccrsIdFormValues = {
- mccrsId: Number(mccrsId),
+ mccrsId: undefined,
}
const showFieldErrors = (error?: FormError) =>
shouldValidate && Boolean(error)
const [showPageErrorMessage, setShowPageErrorMessage] = useState<
- boolean | string
+ boolean | string
>(false) // string is a custom error message, defaults to generic of true
const [updateFormData] = useUpdateContractMutation()
- const handleFormSubmit = async (values: MccrsIdFormValues): Promise => {
+ const handleFormSubmit = async (
+ values: MccrsIdFormValues
+ ): Promise => {
setShowPageErrorMessage(false)
try {
const updateResult = await updateFormData({
variables: {
input: {
mccrsID: values?.mccrsId?.toString(),
- // id: submissionId
- id: '217f8e1e-1b09-4d4a-92b9-189d2dbb1c63'
+ id: id || '',
},
},
})
+
const updatedSubmission: HealthPlanPackage | undefined =
updateResult?.data?.updateContract.pkg
- console.log(updatedSubmission)
+
if (!updatedSubmission) {
setShowPageErrorMessage(true)
+
console.info('Failed to update form data', updateResult)
recordJSException(
`MCCRSIDForm: Apollo error reported. Error message: Failed to update form data ${updateResult}`
)
return new Error('Failed to update form data')
+ } else if (updatedSubmission) {
+ navigate(`/submissions/${updatedSubmission.id}`)
+ return updatedSubmission
}
- console.log(updatedSubmission)
return updatedSubmission
} catch (serverError) {
setShowPageErrorMessage(true)
recordJSException(
`MCCRSIDForm: Apollo error reported. Error message: ${serverError.message}`
)
- console.log(serverError)
return new Error(serverError)
}
}
-
- return (
- {
- return handleFormSubmit(values)
- }}
- validationSchema={() => MccrsIdFormSchema()}
- >
- {({
- values,
- errors,
- handleSubmit,
- setSubmitting,
- isSubmitting,
- setFieldValue,
- }) => (
- <>
- {
- setShouldValidate(true)
- // setFocusErrorSummaryHeading(true)
- handleSubmit(e)
- }}
- >
-
-
- console.info('click')}
- // onClick={actionInProgress ? undefined : backOnClick}
- >
- Delete Number
-
+ return (
+ <>
+ {showPageErrorMessage && }
+ {
+ return handleFormSubmit(values)
+ }}
+ validationSchema={() => MccrsIdFormSchema()}
+ >
+ {({ values, errors, handleSubmit, isSubmitting }) => (
+ <>
+ {
+ setShouldValidate(true)
+ handleSubmit(e)
+ }}
+ >
+
+
+ console.info('delete')}
+ >
+ Delete Number
+
- handleFormSubmit(values)}
- // animationTimeout={1000}
- // loading={actionInProgress && !disableContinue}
- >
- Save MC-CRS number
-
-
-
- >
- )}
-
+ handleFormSubmit(values)}
+ animationTimeout={1000}
+ loading={
+ isSubmitting &&
+ shouldValidate &&
+ !errors.mccrsId
+ }
+ >
+ Save MC-CRS number
+
+
+
+ >
+ )}
+
+ >
)
}
diff --git a/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.test.tsx b/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.test.tsx
index 25d888500c..ffc0d84e57 100644
--- a/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.test.tsx
+++ b/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.test.tsx
@@ -22,7 +22,6 @@ import {
} from '../../testHelpers/jestHelpers'
import { SubmissionSummary } from './SubmissionSummary'
import { SubmissionSideNav } from '../SubmissionSideNav'
-import React from 'react'
import { testS3Client } from '../../testHelpers/s3Helpers'
describe('SubmissionSummary', () => {
@@ -161,6 +160,78 @@ describe('SubmissionSummary', () => {
})
})
+ it('renders add mccrs-id link for CMS user', async () => {
+ const submissionsWithRevisions = mockUnlockedHealthPlanPackage()
+ renderWithProviders(
+
+ }>
+ }
+ />
+
+ ,
+ {
+ apolloProvider: {
+ mocks: [
+ fetchCurrentUserMock({
+ user: mockValidCMSUser(),
+ statusCode: 200,
+ }),
+ fetchStateHealthPlanPackageWithQuestionsMockSuccess({
+ stateSubmission: submissionsWithRevisions,
+ id: '15',
+ }),
+ ],
+ },
+ routerProvider: {
+ route: '/submissions/15',
+ },
+ }
+ )
+ await waitFor(() => {
+ expect(
+ screen.getByText('Add MC-CRS record number')
+ ).toBeInTheDocument()
+ })
+ })
+
+ it('does not render an add mccrs-id link for state user', async () => {
+ const submissionsWithRevisions = mockUnlockedHealthPlanPackage()
+ renderWithProviders(
+
+ }>
+ }
+ />
+
+ ,
+ {
+ apolloProvider: {
+ mocks: [
+ fetchCurrentUserMock({
+ user: mockValidUser(),
+ statusCode: 200,
+ }),
+ fetchStateHealthPlanPackageWithQuestionsMockSuccess({
+ stateSubmission: submissionsWithRevisions,
+ id: '15',
+ }),
+ ],
+ },
+ routerProvider: {
+ route: '/submissions/15',
+ },
+ }
+ )
+ await waitFor(() => {
+ expect(
+ screen.queryByText('Add MC-CRS record number')
+ ).not.toBeInTheDocument()
+ })
+ })
+
it('renders submission unlocked banner for State user', async () => {
const submissionsWithRevisions = mockUnlockedHealthPlanPackage()
renderWithProviders(
diff --git a/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.tsx b/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.tsx
index 45f47f0262..7c8f1a3c2c 100644
--- a/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.tsx
+++ b/services/app-web/src/pages/SubmissionSummary/SubmissionSummary.tsx
@@ -70,7 +70,6 @@ export const SubmissionSummary = (): React.ReactElement => {
const { pkg, currentRevision, packageData, user, documentDates } =
useOutletContext()
-
const isCMSUser = user?.role === 'CMS_USER'
const submissionStatus = pkg.status
const statePrograms = pkg.state.programs
@@ -161,8 +160,12 @@ export const SubmissionSummary = (): React.ReactElement => {
)}