diff --git a/services/app-web/src/pages/CMSDashboard/RateReviewsDashboard/RateReviewsTable.tsx b/services/app-web/src/pages/CMSDashboard/RateReviewsDashboard/RateReviewsTable.tsx index a45234174c..12ba2faef9 100644 --- a/services/app-web/src/pages/CMSDashboard/RateReviewsDashboard/RateReviewsTable.tsx +++ b/services/app-web/src/pages/CMSDashboard/RateReviewsDashboard/RateReviewsTable.tsx @@ -54,7 +54,7 @@ declare module '@tanstack/table-core' { export type RateInDashboardType = { id: string name: string - rateNumber: number, + rateNumber: number submittedAt: string updatedAt: Date status: HealthPlanPackageStatus @@ -251,6 +251,7 @@ export const RateReviewsTable = ({ asCustom={NavLink} to={rateURL(info.getValue())} className={`${styles.ID}`} + data-testid={`rate-link-${info.getValue().id}`} > {info.getValue().name} @@ -343,7 +344,7 @@ export const RateReviewsTable = ({ ), initialState: { columnVisibility: { - rateNumber: isAdminUser, + rateNumber: isAdminUser, }, }, columns: tableColumns, @@ -359,7 +360,6 @@ export const RateReviewsTable = ({ getFilteredRowModel: getFilteredRowModel(), getSortedRowModel: getSortedRowModel(), getFacetedMinMaxValues: getFacetedMinMaxValues(), - }) const filteredRows = reactTable.getRowModel().rows diff --git a/services/cypress/integration/cmsWorkflow/rateReview.spec.ts b/services/cypress/integration/cmsWorkflow/rateReview.spec.ts index b4e03ffed7..d737beee50 100644 --- a/services/cypress/integration/cmsWorkflow/rateReview.spec.ts +++ b/services/cypress/integration/cmsWorkflow/rateReview.spec.ts @@ -29,49 +29,44 @@ describe('CMS user can view rate reviews', () => { // Create a new contract and rates submission with two attached rates cy.apiCreateAndSubmitContractWithRates(stateUser()).then( - (pkg) => { - const submission = getFormData(pkg) - const submissionName = packageName( - pkg.stateCode, - submission.stateNumber, - submission.programIDs, - minnesotaStatePrograms - ) - // Then check both rates in rate reviews table - cy.logInAsCMSUser({ - initialURL: `/dashboard/rate-reviews`, - }) - const rate1 = submission.rateInfos[0] - const rate2 = submission.rateInfos[1] - cy.get('table') - .findByRole('link', { name: rate1.rateCertificationName }) - .should('exist') - cy.get('table') - .findByRole('link', { name: rate2.rateCertificationName }) - .should('exist') + (contract) => { + + const latestSubmission = contract.packageSubmissions[0] - // click the first rate to navigate to rate summary page - cy.get('table') - .findByRole('link', { name: rate1.rateCertificationName }) - .should('exist').click() - cy.url({ timeout: 10_000 }).should('contain',rate1.id) - cy.findByRole('heading', { - name: `${rate1.rateCertificationName}`, - }).should('exist') - cy.findByText('Rate certification type').should('exist').siblings('dd').should('have.text', 'New rate certification') - cy.findByText('Rating period').should('exist').siblings('dd').should('have.text', '06/01/2025 to 05/30/2026') - cy.findByText('Date certified').should('exist').siblings('dd').should('have.text', '04/15/2025') - cy.findByText('Submission this rate was submitted with').should('exist').siblings('dd').should('have.text', submissionName) - cy.findByText('Certifying actuary').should('exist').siblings('dd').should('have.text', 'actuary1test titleemail@example.comMercer') - // cy.findByText('Download all rate documents').should('exist') - cy.findByRole('table', { - name: 'Rate certification', - }).should('exist') - cy.findByText('rate1Document1.pdf').should('exist') - cy.findByRole('table', { - name: 'Rate supporting documents', - }).should('exist') + const rate1 = latestSubmission.rateRevisions[0] + const rate2 = latestSubmission.rateRevisions[1] + + // Then check both rates in rate reviews table + cy.logInAsCMSUser({ + initialURL: `/dashboard/rate-reviews`, }) + + cy.get('table') + .findByTestId(`rate-link-${rate1.rateID}`).should('exist') + cy.get('table') + .findByTestId(`rate-link-${rate2.rateID}`).should('exist') + + // click the first rate to navigate to rate summary page + cy.get('table') + .findByTestId(`rate-link-${rate1.rateID}`).click() + cy.url({ timeout: 10_000 }).should('contain',rate1.rateID) + cy.findByRole('heading', { + name: `${rate1.formData.rateCertificationName}`, + }).should('exist') + cy.findByText('Rate certification type').should('exist').siblings('dd').should('have.text', 'New rate certification') + cy.findByText('Rating period').should('exist').siblings('dd').should('have.text', '06/01/2025 to 05/30/2026') + cy.findByText('Date certified').should('exist').siblings('dd').should('have.text', '04/15/2025') + cy.findByText('Submission this rate was submitted with').should('exist').siblings('dd').should('have.text', latestSubmission.contractRevision.contractName) + cy.findByText('Certifying actuary').should('exist').siblings('dd').should('have.text', 'actuary1test titleemail@example.comMercer') + // cy.findByText('Download all rate documents').should('exist') + cy.findByRole('table', { + name: 'Rate certification', + }).should('exist') + cy.findByText('rate1Document1.pdf').should('exist') + cy.findByRole('table', { + name: 'Rate supporting documents', + }).should('exist') + }) cy.findByText('rate1SupportingDocument1.pdf').should('exist') // No document dates or other fields are undefined @@ -83,7 +78,6 @@ describe('CMS user can view rate reviews', () => { cy.url({ timeout: 10_000 }).should('contain', 'rate-reviews') cy.findByText('Rate reviews').should('exist') cy.get('thead').should('have.attr', 'data-testid', 'rate-reviews-table').should('be.visible') // can't put id on table itself because data attributes not passing through in react-uswds component - }) }) }) diff --git a/services/cypress/integration/cmsWorkflow/unlockResubmit.spec.ts b/services/cypress/integration/cmsWorkflow/unlockResubmit.spec.ts index 0b099ef75b..4b57240b78 100644 --- a/services/cypress/integration/cmsWorkflow/unlockResubmit.spec.ts +++ b/services/cypress/integration/cmsWorkflow/unlockResubmit.spec.ts @@ -1,3 +1,5 @@ +import {stateUser} from '../../utils/apollo-test-utils'; + describe('CMS user', () => { beforeEach(() => { cy.stubFeatureFlags() @@ -454,6 +456,229 @@ describe('CMS user', () => { }) // TODO AFTER LINKED RATES AND LINKED RATES CHANGE HISTORY SHIPS - // it('can unlock and resubmit a linked rate and change history updates') + it.only('can unlock and resubmit a linked rate and change history updates', () => { + // turn on feature flag + cy.interceptFeatureFlags({'link-rates': true, '438-attestation': true}) + + // Set up a submission with linked rates + cy.apiCreateAndSubmitContractWithRates(stateUser()).then(() => { + cy.logInAsStateUser() + + // This section still uses old API, so we want to do that first before using the new link-rates UI + cy.startNewContractAndRatesSubmission() + cy.fillOutBaseContractDetails() + + cy.navigateFormByButtonClick('CONTINUE') + cy.findByRole('heading', { level: 2, name: /Rate details/ }) + + // Test unlock and resubmit with a linked rate submission + cy.location().then((fullUrl) => { + const submissionURL = fullUrl.toString().replace( + 'edit/rate-details', + '' + ) + const reviewURL = `${submissionURL}edit/review-and-submit` + + /** + * The updateHealthPlanFormData endpoint fails to update rates when the flag is on, causing an error after + * the rate details page due to Cypress's inability to toggle backend flags. This is due to the API's + * attempt to update the new rate format with HPP. The solution is to apply old API updates before new + * rate API updates in a non-sequential order. + */ + cy.navigateFormByDirectLink(`${submissionURL}edit/contacts`) + cy.findByRole('heading', { level: 2, name: /Contacts/ }) + cy.fillOutStateContact() + + cy.navigateFormByButtonClick('CONTINUE') + cy.findByRole('heading', { level: 2, name: /Supporting documents/ }) + + // New API + cy.navigateFormByDirectLink(`${submissionURL}edit/rate-details`) + cy.findByRole('heading', { level: 2, name: /Rate details/ }) + cy.fillOutLinkedRate() + + cy.navigateContractRatesFormByButtonClick('CONTINUE') + cy.findByRole('heading', { level: 2, name: /Contacts/ }) + + cy.navigateFormByDirectLink(`${submissionURL}edit/review-and-submit`) + cy.findByRole('heading', { level: 2, name: /Review and submit/ }) + + // Submit, sent to dashboard + cy.submitStateSubmissionForm() + + // Login as CMS User + cy.logOut() + cy.logInAsCMSUser({ initialURL: submissionURL }) + cy.wait('@fetchContractQuery', { timeout: 20_000 }) + // click on the unlock button, type in reason and confirm + cy.unlockSubmission() + + //Unlock banner for CMS user to be present with correct data. + cy.findByTestId('unlockedBanner') + .should('exist') + .and('contain.text', 'zuko@example.com') + .and('contain.text', 'Unlock submission reason.') + .contains( + /Unlocked on: (0?[1-9]|[12][0-9]|3[01])\/[0-9]+\/[0-9]+\s[0-9]+:[0-9]+[a-zA-Z]+ ET/i + ) + .should('exist') + + //Find unlocked submission name + cy.get('#submissionName', {timeout: 2_000}).then(($h2) => { + //Set name to variable for later use in finding the unlocked submission + const submissionName = $h2.text() + + // Login as state user + cy.logOut() + cy.logInAsStateUser() + + // State user sees unlocked submission - check tag then submission link + cy.get('table') + .should('exist') + .findByText(submissionName) + .parent() + .siblings('[data-testid="submission-status"]') + .should('have.text', 'Unlocked') + + cy.get('table') + .should('exist') + .findByText(submissionName) + .should('have.attr', 'href') + .and('include', 'review-and-submit') + + cy.navigateFormByDirectLink(reviewURL) + cy.wait('@fetchContractQuery', { timeout: 20_000 }) + + //Unlock banner for state user to be present with correct data. + cy.findByRole('heading', { + level: 2, + name: /Review and submit/, + }) + cy.findByRole('heading', { + name: `Minnesota ${submissionName}`, + }).should('exist') + cy.findByTestId('unlockedBanner') + .should('exist') + .and('contain.text', 'zuko@example.com') + .and('contain.text', 'Unlock submission reason.') + .contains( + /Unlocked on: (0?[1-9]|[12][0-9]|3[01])\/[0-9]+\/[0-9]+\s[0-9]+:[0-9]+[a-zA-Z]+ ET+/i + ) + .should('exist') + + cy.submitStateSubmissionForm({success: true, resubmission: true}) + + cy.get('table') + .should('exist') + .findByText(submissionName) + .parent() + .siblings('[data-testid="submission-status"]') + .should('have.text', 'Submitted') + + cy.get('table') + .findByText(submissionName) + .should('have.attr', 'href') + .and('not.include', 'review-and-submit') + + // Navigate to resubmitted submission and check for submission updated banner + cy.get('table') + .findByRole('link', { name: submissionName }) + .should('exist') + .click() + + cy.findByTestId('updatedSubmissionBanner').should('exist') + + // Login as CMS User + cy.logOut() + cy.logInAsCMSUser({ initialURL: submissionURL }) + cy.wait('@fetchContractQuery', { timeout: 20_000 }) + + // CMS user sees resubmitted submission and active unlock button + cy.findByTestId('submission-summary', {timeout: 4_000}).should('exist') + cy.findByRole('button', { name: 'Unlock submission' }).should( + 'not.be.disabled' + ) + + //CMS user should not see unlock banner and should see updated submission banner + cy.findByTestId('unlockedBanner').should('not.exist') + cy.findByTestId('updatedSubmissionBanner').should('exist') + + //Open all change history accordion items + cy.findByTestId('accordion').should('exist') + + cy.get('[data-testid^="accordionButton_"]').each((button) => { + button.trigger('click') + button.siblings().hasClass('usa-accordion__content') /// make sure accordion is expanded + }) + + //Check for view previous submission link in the initial accordion item to exist + cy.findByTestId('revision-link-1').should('be.visible') + cy.clickSubmissionLink('revision-link-1') + //Making sure we are on SubmissionRevisionSummary page and contains version text + cy.findByTestId('revision-version') + .should('exist') + .contains( + /(0?[1-9]|[12][0-9]|3[01])\/[0-9]+\/[0-9]+\s[0-9]+:[0-9]+[a-zA-Z]+ ET version/i + ) + //Previous submission banner should exist and able to click link to go back to current submission + cy.findByTestId('previous-submission-banner').should('exist') + //Navigate back to current submission using link inside banner. + cy.clickSubmissionLink('currentSubmissionLink') + //Make sure banner and revision version text are gone. + cy.findByTestId('previous-submission-banner').should( + 'not.exist' + ) + cy.findByTestId('revision-version').should('not.exist') + + // Unlock again and resubmit to test change history + cy.unlockSubmission('Second Unlock') + + // Resubmit again + cy.logOut() + cy.logInAsStateUser() + cy.navigateFormByDirectLink(reviewURL) + cy.wait('@fetchContractQuery', { timeout: 20_000 }) + cy.findByTestId('unlockedBanner').should('exist') + cy.submitStateSubmissionForm({ + success: true, + resubmission: true, + summary: 'Second resubmit' + } + ) + + // Visit the submission url and check the history + cy.navigateFormByDirectLink(submissionURL) + cy.findByTestId('updatedSubmissionBanner').should('exist') + + // No document dates or other fields are undefined + cy.findByText('N/A').should('not.exist') + + // Should have change history records + cy.findAllByTestId('change-history-record').should('have.length', 5) + + cy.findAllByTestId('change-history-record').then(records => { + // We put all the text of each record into an array + const recordText = records.map((index, record) => Cypress.$(record).text()) + + // Records are in reverse + // Second set of unlock and resubmit + expect(recordText[0]).to.contain('Changes made: Second resubmit') + expect(recordText[1]).to.contain('Reason for unlock: Second Unlock') + + // First set of unlock and resubmit + expect(recordText[2]).to.contain('Changes made: Resubmission summary') + expect(recordText[3]).to.contain('Reason for unlock: Unlock submission reason.') + + // Test for initial submission + expect(recordText[4]).to.contain('aang@example.com') + expect(recordText[4]).to.contain('View past submission version') + expect(recordText[4]).to.not.contain('Changes made:') + expect(recordText[4]).to.not.contain('Reason for unlock:') + + }) + }) + }) + }) + }) // it('can unlock and resubmit combination of linked and child rates as expected' ) }) diff --git a/services/cypress/support/apiCommands.ts b/services/cypress/support/apiCommands.ts index 901ca24d7f..efc35aef0a 100644 --- a/services/cypress/support/apiCommands.ts +++ b/services/cypress/support/apiCommands.ts @@ -8,6 +8,9 @@ import { User, UpdateCmsUserDocument, FetchCurrentUserDocument, + UpdateDraftContractRatesDocument, + UpdateDraftContractRatesInput, + Contract, SubmitContractDocument, } from '../gen/gqlClient' import { domainToBase64, @@ -20,7 +23,8 @@ import { contractOnlyData, contractAndRatesData, newSubmissionInput, - CMSUserType, + rateFormData, + CMSUserType, minnesotaStatePrograms, } from '../utils/apollo-test-utils' import { ApolloClient, DocumentNode, NormalizedCacheObject } from '@apollo/client' import {UnlockedHealthPlanFormDataType} from 'app-web/src/common-code/healthPlanFormDataType'; @@ -75,7 +79,7 @@ const createAndSubmitContractOnlyPackage = async ( const createAndSubmitContractWithRates = async ( apolloClient: ApolloClient -): Promise => { +): Promise => { const newSubmission1 = await apolloClient.mutate({ mutation: CreateHealthPlanPackageDocument, variables: { @@ -90,9 +94,11 @@ const createAndSubmitContractWithRates = async ( throw new Error(formData1.message) } - const fullFormData1 = { + const fullFormData1: UnlockedHealthPlanFormDataType = { ...formData1, ...contractAndRatesData(), + status: 'DRAFT', + rateInfos: [] } const formDataProto = domainToBase64(fullFormData1 as UnlockedHealthPlanFormDataType) @@ -107,16 +113,50 @@ const createAndSubmitContractWithRates = async ( }, }) - const submission1 = await apolloClient.mutate({ - mutation: SubmitHealthPlanPackageDocument, + // Using new API to create child rates + const updateDraftContractRatesInput: UpdateDraftContractRatesInput = { + contractID: pkg1.id, + updatedRates: [ + { + formData: rateFormData({ + rateDateStart: '2025-06-01', + rateDateEnd: '2026-05-30', + rateDateCertified: '2025-04-15', + rateProgramIDs: [minnesotaStatePrograms[0].id] + }), + rateID: undefined, + type: 'CREATE' + }, + { + formData: rateFormData({ + rateDateStart: '2024-03-01', + rateDateEnd: '2025-04-30', + rateDateCertified: '2025-03-15', + rateProgramIDs: [minnesotaStatePrograms[1].id] + }), + rateID: undefined, + type: 'CREATE' + } + ] + } + + await apolloClient.mutate({ + mutation: UpdateDraftContractRatesDocument, + variables: { + input: updateDraftContractRatesInput + } + }) + + const submission = await apolloClient.mutate({ + mutation: SubmitContractDocument, variables: { input: { - pkgID: pkg1.id, - submittedReason: 'Submit package for Rates Dashboard tests', + contractID: pkg1.id, }, }, }) - return submission1.data.submitHealthPlanPackage.pkg + + return submission.data.submitContract.contract } @@ -179,7 +219,7 @@ Cypress.Commands.add( Cypress.Commands.add( 'apiCreateAndSubmitContractWithRates', - (stateUser): Cypress.Chainable => + (stateUser): Cypress.Chainable => cy.task('readGraphQLSchema').then((schema) => apolloClientWrapper( schema, diff --git a/services/cypress/support/index.ts b/services/cypress/support/index.ts index b5f7b92a46..041844f133 100644 --- a/services/cypress/support/index.ts +++ b/services/cypress/support/index.ts @@ -26,7 +26,7 @@ import { FeatureFlagSettings, } from '../../app-web/src/common-code/featureFlags' import './apiCommands' -import { HealthPlanPackage } from '../gen/gqlClient'; +import { HealthPlanPackage, Contract } from '../gen/gqlClient'; import { CMSUserType, DivisionType } from '../utils/apollo-test-utils'; import { StateUserType } from 'app-api/src/domain-models'; @@ -105,7 +105,7 @@ declare global { }): void apiCreateAndSubmitContractOnlySubmission(stateUser: StateUserType): Cypress.Chainable - apiCreateAndSubmitContractWithRates(stateUser: StateUserType): Cypress.Chainable + apiCreateAndSubmitContractWithRates(stateUser: StateUserType): Cypress.Chainable apiAssignDivisionToCMSUser(cmsUser: CMSUserType, division: DivisionType): Cypress.Chainable interceptGraphQL(): void diff --git a/services/cypress/support/stateSubmissionFormCommands.ts b/services/cypress/support/stateSubmissionFormCommands.ts index e1a7801e0e..4b0557124d 100644 --- a/services/cypress/support/stateSubmissionFormCommands.ts +++ b/services/cypress/support/stateSubmissionFormCommands.ts @@ -393,28 +393,31 @@ Cypress.Commands.add('fillOutNewRateCertification', () => { Cypress.Commands.add('fillOutLinkedRate', () => { // Must be on '/submissions/:id/edit/rate-details' // Must be a contract and rates submission - cy.getFeatureFlagStore(['link-rates']).then((store) => { - //If this flag value is true, then it will test this code hidden behind the feature flag - cy.findByRole('radiogroup', { - name: /Was this rate certification included with another submission?/, + // Must have existing rates to work. Otherwise, there will be no options + cy.getFeatureFlagStore(['link-rates']).then((store) => { + //If this flag value is true, then it will test this code hidden behind the feature flag + cy.findByRole('radiogroup', { + name: /Was this rate certification included with another submission?/, + }) + .should('exist') + .within(() => { + cy.findByText('Yes, this rate certification is part of another submission').click() }) - .should('exist') - .within(() => { - cy.findByText('Yes, this rate certification is part of another submission').click() - }) - - if (store['link-rates']) { - cy.findByRole('combobox', { name: 'Which rate certification was it?' }).click({ - force: true, - }) - cy.findAllByRole('option').first().click() - cy.findByText(/`Rate ID:/).should('be.visible') - } - cy.verifyDocumentsHaveNoErrors() - cy.waitForDocumentsToLoad() - cy.findAllByTestId('errorMessage').should('have.length', 0) - }) + if (store['link-rates']) { + cy.findByLabelText('Which rate certification was it?').should('be.visible').click({ + force: true + }) + let rateName = '' + cy.findAllByRole('option').first().within(current => { + cy.get('strong').should($div => { + rateName = $div.text() + }).click() + }).then(() => { + cy.root().findByRole('heading', { level: 3, name: `Rate ID: ${rateName}`}).should('exist') + }) + } + }) }) Cypress.Commands.add('fillOutAmendmentToPriorRateCertification', (id = 0) => { diff --git a/services/cypress/utils/apollo-test-utils.ts b/services/cypress/utils/apollo-test-utils.ts index 7dc1e86e9c..56397aaec9 100644 --- a/services/cypress/utils/apollo-test-utils.ts +++ b/services/cypress/utils/apollo-test-utils.ts @@ -9,6 +9,7 @@ import { } from '@apollo/client' import { Amplify, Auth as AmplifyAuth, API } from 'aws-amplify' import { UnlockedHealthPlanFormDataType } from '../../app-web/src/common-code/healthPlanFormDataType' +import { RateFormDataInput } from '../gen/gqlClient'; type StateUserType = { id: string @@ -41,34 +42,35 @@ type DivisionType = 'DMCO' | 'DMCP' | 'OACT' type UserType = StateUserType | AdminUserType | CMSUserType // programs for state used in tests -const minnesotaStatePrograms =[ +const minnesotaStatePrograms = [ { "id": "abbdf9b0-c49e-4c4c-bb6f-040cb7b51cce", "fullName": "Special Needs Basic Care", "name": "SNBC", - "isRateProgram": "false" + "isRateProgram": false }, { "id": "d95394e5-44d1-45df-8151-1cc1ee66f100", "fullName": "Prepaid Medical Assistance Program", "name": "PMAP", - "isRateProgram": "false" + "isRateProgram": false }, { "id": "ea16a6c0-5fc6-4df8-adac-c627e76660ab", "fullName": "Minnesota Senior Care Plus ", "name": "MSC+", - "isRateProgram": "false" + "isRateProgram": false }, { "id": "3fd36500-bf2c-47bc-80e8-e7aa417184c5", "fullName": "Minnesota Senior Health Options", "name": "MSHO", - "isRateProgram": "false" + "isRateProgram": false } ] -const contractOnlyData = (): Partial=> ({ +const contractOnlyData = (): Partial => ({ + stateCode: 'MN', stateContacts: [ { name: 'Name', @@ -103,7 +105,8 @@ const contractOnlyData = (): Partial=> ({ managedCareEntities: ['MCO'], federalAuthorities: ['STATE_PLAN'], rateInfos: [], - statutoryRegulatoryAttestation: true + statutoryRegulatoryAttestation: true, + programIDs: [minnesotaStatePrograms[0].id] }) const contractAndRatesData = (): Partial=> ({ @@ -202,7 +205,42 @@ const contractAndRatesData = (): Partial=> ({ }, ], statutoryRegulatoryAttestation: false, - statutoryRegulatoryAttestationDescription: 'No compliance' + statutoryRegulatoryAttestationDescription: 'No compliance', + programIDs: [minnesotaStatePrograms[0].id] +}) + +const rateFormData = (data?: Partial): RateFormDataInput => ({ + rateType: 'NEW', + rateCapitationType: 'RATE_CELL', + rateDocuments: [ + { + name: 'rate1Document1.pdf', + s3URL: 's3://local-uploads/1684382956834-rate1Document1.pdf/rate1Document1.pdf', + sha256: 'fakesha', + }, + ], + supportingDocuments: [ { + name: 'rate1SupportingDocument1.pdf', + s3URL: 's3://local-uploads/1684382956834-rate1SupportingDocument1.pdf/rate1SupportingDocument1.pdf', + sha256: 'fakesha2', + }], + rateDateStart: '2025-05-01', + rateDateEnd: '2026-04-30', + rateDateCertified: '2025-03-15', + rateProgramIDs: [minnesotaStatePrograms[0].id], + certifyingActuaryContacts: [ + { + name: 'actuary1', + titleRole: 'test title', + email: 'email@example.com', + actuarialFirm: 'MERCER' as const, + actuarialFirmOther: '', + }, + ], + deprecatedRateProgramIDs: [], + addtlActuaryContacts: [], + actuaryCommunicationPreference: 'OACT_TO_ACTUARY' as const, + ...data }) const newSubmissionInput = (overrides?: Partial ): Partial => { @@ -436,6 +474,7 @@ export { cmsUser, adminUser, stateUser, + rateFormData, minnesotaStatePrograms } export type {