Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SubmissonSummaryV2 tests #2370

Merged
merged 6 commits into from
Apr 24, 2024
Merged
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
53 changes: 48 additions & 5 deletions services/app-web/src/gqlHelpers/contractsAndRates.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
/*
These helpers help you access nested data from the Contract and Rate Apollo Client types
If the data doesn't exist, returs undefined reliably
If the data doesn't exist, returns undefined reliably
*/

import { Contract, ContractFormData, ContractPackageSubmission, Rate } from "../gen/gqlClient"
import { Contract, ContractFormData, ContractPackageSubmission, Rate, RateRevision } from "../gen/gqlClient"


function getVisibleLatestRateRevisions(contract: Contract, isEditing: boolean): RateRevision[] | undefined {
if (isEditing) {
if (!contract.draftRates) {
console.error('Programming Error: on the rate details page with no draft rates')
return undefined
}
const rateRevs = []
for (const rate of contract.draftRates) {
// if this is a child rate, return draft revision
if (rate.parentContractID === contract.id) {
if (!rate.draftRevision) {
// TODO: this error will likely no longer apply once we have Unlock/Submit Rate
// child rates will no longer be assumed to be unlocked with their parent contracts
console.error('Programming Error: A child rate is not a draft')
return undefined
}
rateRevs.push(rate.draftRevision)
} else {
// otherwise return the latest revision submitted.
const lastRateSubmission = rate.revisions[0]
if (!lastRateSubmission) {
console.error('Programming Error: non-child rate was not previously submitted')
return undefined
}
rateRevs.push(lastRateSubmission)
}
}
return rateRevs
} else {
const lastContractSubmission = getLastContractSubmission(contract)
if (!lastContractSubmission) {
console.error('Programming Error: no contract submission for a contract were not editing')
return undefined
}
return lastContractSubmission.rateRevisions
}
}

// returns draft form data for unlocked and draft, and last package submission data for submitted or resubmitted
const getLatestContractFormData = (contract: Contract): ContractFormData | undefined =>{
return contract.draftRevision?.formData ||
// only state users get to see draft data.
const getVisibleLatestContractFormData = (contract: Contract, isStateUser: boolean): ContractFormData | undefined =>{
if (isStateUser) {
return contract.draftRevision?.formData ||
getLastContractSubmission(contract)?.contractRevision.formData
}
return getLastContractSubmission(contract)?.contractRevision.formData
}

const getLastContractSubmission = (contract: Contract): ContractPackageSubmission | undefined => {
Expand All @@ -19,4 +62,4 @@ const getDraftRates = (contract: Contract): Rate[] | undefined => {
return (contract.draftRates && contract.draftRates[0]) ? contract.draftRates : undefined
}

export {getDraftRates, getLastContractSubmission, getLatestContractFormData}
export {getDraftRates, getLastContractSubmission, getVisibleLatestContractFormData, getVisibleLatestRateRevisions}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ export const LinkRateSelect = ({
) => {
if (action === 'select-option') {
const linkedRateID = newValue.value
// const linkedRateName = newValue.label
const linkedRate = rates.find((rate) => rate.id === linkedRateID)
const linkedRateForm: FormikRateForm = convertGQLRateToRateForm(
getKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { Column, createColumnHelper, getCoreRowModel, getFacetedUniqueValues, getFilteredRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table"
import { StateAnalystsConfiguration } from "../../../gen/gqlClient"
import { useMemo, useRef } from "react"
import { FilterSelect, FilterSelectedOptionsType } from "../../../components/FilterAccordion"
import { DoubleColumnGrid } from "../../../components"
import { formatEmails } from "./EmailSettingsTables"
import { Table } from "@trussworks/react-uswds"
import {
Column,
createColumnHelper,
getCoreRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getSortedRowModel,
useReactTable,
} from '@tanstack/react-table'
import { StateAnalystsConfiguration } from '../../../gen/gqlClient'
import { useMemo, useRef } from 'react'
import {
FilterSelect,
FilterSelectedOptionsType,
} from '../../../components/FilterAccordion'
import { DoubleColumnGrid } from '../../../components'
import { formatEmails } from './EmailSettingsTables'
import { Table } from '@trussworks/react-uswds'

import styles from '../Settings.module.scss'
import { pluralize } from "../../../common-code/formatters"
import { pluralize } from '../../../common-code/formatters'

const columnHelper = createColumnHelper< StateAnalystsConfiguration>()
const columnHelper = createColumnHelper<StateAnalystsConfiguration>()

const EmailAnalystsTable = ({
analysts,
Expand Down Expand Up @@ -58,9 +69,9 @@ const EmailAnalystsTable = ({
'emails'
) as Column<StateAnalystsConfiguration>
const rowCount = `Displaying ${filteredRows.length} of ${analysts.length} ${pluralize(
'analyst',
analysts.length
)}`
'analyst',
analysts.length
)}`
const updateFilters = (
column: Column<StateAnalystsConfiguration>,
selectedOptions: FilterSelectedOptionsType,
Expand Down Expand Up @@ -93,11 +104,7 @@ const EmailAnalystsTable = ({
label: state,
}))}
onChange={(selectedOptions) =>
updateFilters(
stateColumn,
selectedOptions,
'state'
)
updateFilters(stateColumn, selectedOptions, 'state')
}
/>
<FilterSelect
Expand All @@ -112,17 +119,11 @@ const EmailAnalystsTable = ({
label: state,
}))}
onChange={(selectedOptions) =>
updateFilters(
emailsColumn,
selectedOptions,
'emails'
)
updateFilters(emailsColumn, selectedOptions, 'emails')
}
/>
</DoubleColumnGrid>
<div className={styles.filterCount}>
{rowCount}
</div>
<div className={styles.filterCount}>{rowCount}</div>
<hr />

<Table bordered>
Expand All @@ -135,19 +136,18 @@ const EmailAnalystsTable = ({
</thead>
<tbody>
{filteredRows.map((row) => {
return (
<tr key={row.id}>
<td>{row.getValue('stateCode')}</td>
<td>
{formatEmails(row.getValue('emails') || [])}
</td>

</tr>
)
})}
return (
<tr key={row.id}>
<td>{row.getValue('stateCode')}</td>
<td>
{formatEmails(row.getValue('emails') || [])}
</td>
</tr>
)
})}
</tbody>
</Table>
</>
)
}
export {EmailAnalystsTable}
export { EmailAnalystsTable }
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,4 @@ const EmailSupportTable = ({ config }: { config: EmailConfiguration }) => {
)
}

export {EmailSettingsTable, formatEmails}
export { EmailSettingsTable, formatEmails }
4 changes: 2 additions & 2 deletions services/app-web/src/pages/Settings/Settings.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
border-right: 0;
}
td {
word-wrap: break-word;
overflow-wrap: break-word;
word-wrap: break-word;
overflow-wrap: break-word;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ describe('RateDetailsv2', () => {
})

it('display rest of the form when linked rates question is answered', async () => {
renderWithProviders(
const { user } = renderWithProviders(
<Routes>
<Route
path={RoutesRecord.SUBMISSIONS_RATE_DETAILS}
Expand All @@ -315,11 +315,8 @@ describe('RateDetailsv2', () => {
contract: {
...mockContractWithLinkedRateDraft(),
id: 'test-abc-123',
},
}),
updateDraftContractRatesMockSuccess({
contract: {
id: 'test-abc-123',
// clean draft rates for this test.
draftRates: []
},
}),
],
Expand All @@ -340,16 +337,17 @@ describe('RateDetailsv2', () => {
'No, this rate certification was not included with any other submissions'
)
)

const input = screen.getByLabelText(
'Upload one rate certification document'
)
await expect(input).toBeInTheDocument()
expect(input).toBeInTheDocument()
const submitButton = screen.getByRole('button', {
name: 'Continue',
})

// trigger validations
await submitButton.click()
await user.click(submitButton)
await waitFor(() => {
expect(
screen.getByText('Rate certification 1')
Expand Down Expand Up @@ -458,7 +456,7 @@ describe('RateDetailsv2', () => {
})
})
it('cannot continue with partially filled out second rate', async () => {
renderWithProviders(
const { user } = renderWithProviders(
<Routes>
<Route
path={RoutesRecord.SUBMISSIONS_RATE_DETAILS}
Expand Down Expand Up @@ -495,15 +493,14 @@ describe('RateDetailsv2', () => {
await screen.findByText('Rate Details')
const rateCertsOnLoad = rateCertifications(screen)
expect(rateCertsOnLoad).toHaveLength(1)
await fillOutIndexRate(screen, 0)

await clickAddNewRate(screen)
const submitButton = screen.getByRole('button', {
name: 'Continue',
})

// trigger validations
await submitButton.click()
await user.click(submitButton)
await waitFor(() => {
expect(
screen.getByText('Rate certification 1')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ const RateDetailsV2 = ({
const [submitRate, { error: submitRateError }] = useSubmitRateMutation()

// Set up data for form. Either based on contract API (for multi rate) or rates API (for edit and submit of standalone rate)
const ratesFromContract =
fetchContractData?.fetchContract.contract.draftRates
const contract = fetchContractData?.fetchContract.contract
const ratesFromContract = contract?.draftRates
const initialRequestLoading = fetchContractLoading || fetchRateLoading
const initialRequestError = fetchContractError || fetchRateError
const submitRequestError = updateContractError || submitRateError
Expand All @@ -188,7 +188,7 @@ const RateDetailsV2 = ({
rateForms:
initialRates.length > 0
? initialRates.map((rate) =>
convertGQLRateToRateForm(getKey, rate)
convertGQLRateToRateForm(getKey, rate, contract?.id)
)
: [convertGQLRateToRateForm(getKey)],
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ const convertRateFormToGQLRateFormData = (
// Convert from GQL Rate to FormikRateForm object used in the form
// if rate is not passed in, return an empty RateForm // we need to pass in the s3 handler because 3 urls generated client-side
// useLatestSubmission means to pull the latest submitted info rather than the draft info
const convertGQLRateToRateForm = (getKey: S3ClientT['getKey'], rate?: Rate): FormikRateForm => {
const handleAsLinkedRate = rate?.status && rate.status !== 'DRAFT' && rate.status !== 'UNLOCKED' // TODO: Make this a more sophisticated check for child-rates
const convertGQLRateToRateForm = (getKey: S3ClientT['getKey'], rate?: Rate, parentContractID?: string): FormikRateForm => {
const handleAsLinkedRate = rate && rate.parentContractID !== parentContractID // TODO: Make this a more sophisticated check for child-rates
const rateRev = handleAsLinkedRate ? rate?.revisions[0] : rate?.draftRevision
const rateForm = rateRev?.formData
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ describe('ContractDetailsSummarySection', () => {
<ContractDetailsSummarySection
contract={mockContractPackageDraft()}
submissionName="MN-PMAP-0001"
editNavigateTo="/contract-details"
/>,
{
apolloProvider: defaultApolloMocks,
Expand Down Expand Up @@ -269,6 +270,7 @@ describe('ContractDetailsSummarySection', () => {
<ContractDetailsSummarySection
contract={contract}
submissionName="MN-PMAP-0001"
editNavigateTo="/contract-details"
/>,
{
apolloProvider: defaultApolloMocks,
Expand Down Expand Up @@ -379,6 +381,7 @@ describe('ContractDetailsSummarySection', () => {
<ContractDetailsSummarySection
contract={contract}
submissionName="MN-PMAP-0001"
editNavigateTo="/contract-details"
/>,
{
apolloProvider: defaultApolloMocks,
Expand Down Expand Up @@ -422,6 +425,7 @@ describe('ContractDetailsSummarySection', () => {
<ContractDetailsSummarySection
contract={contract}
submissionName="MN-PMAP-0001"
editNavigateTo="/contract-details"
/>,
{
apolloProvider: defaultApolloMocks,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { SectionCard } from '../../../../../components/SectionCard'
import { Contract } from '../../../../../gen/gqlClient'
import {
getLastContractSubmission,
getLatestContractFormData,
getVisibleLatestContractFormData,
} from '../../../../../gqlHelpers/contractsAndRates'

export type ContractDetailsSummarySectionV2Props = {
Expand Down Expand Up @@ -84,8 +84,12 @@ export const ContractDetailsSummarySectionV2 = ({
string | undefined | Error
>(undefined)
const ldClient = useLDClient()
const isEditing = !isSubmitted(contract) && editNavigateTo !== undefined

const contractFormData = getLatestContractFormData(contract)
const contractFormData = getVisibleLatestContractFormData(
contract,
isEditing
)
const contract438Attestation = ldClient?.variation(
featureFlags.CONTRACT_438_ATTESTATION.flag,
featureFlags.CONTRACT_438_ATTESTATION.defaultValue
Expand All @@ -96,7 +100,6 @@ export const ContractDetailsSummarySectionV2 = ({
booleanAsYesNoFormValue(contractFormData.statutoryRegulatoryAttestation)

const contractSupportingDocuments = contractFormData?.supportingDocuments
const isEditing = !isSubmitted(contract) && editNavigateTo !== undefined
const applicableFederalAuthorities = isCHIPOnly(contract)
? contractFormData?.federalAuthorities.filter((authority) =>
federalAuthorityKeysForCHIP.includes(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('RateDetailsSummarySection', () => {
state: mockMNState(),
stateCode: 'MN',
stateNumber: 5,
parentContractID: 'fake-id',
parentContractID: 'test-abc-123',
revisions: [],
draftRevision: {
id: '1234',
Expand Down Expand Up @@ -74,7 +74,7 @@ describe('RateDetailsSummarySection', () => {
state: mockMNState(),
stateCode: 'MN',
stateNumber: 5,
parentContractID: 'fake-id',
parentContractID: 'test-abc-123',
revisions: [],
draftRevision: {
id: '1234',
Expand Down
Loading
Loading