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

Rates dash cypress #2017

Merged
merged 3 commits into from
Oct 31, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ export const RateReviewsTable = ({
</div>
</div>
<Table fullWidth>
<thead>
<thead data-testid="rate-reviews-table">
{reactTable.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
Expand Down
91 changes: 91 additions & 0 deletions services/cypress/integration/cmsWorkflow/rateReview.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { HealthPlanFormDataType, packageName } from "../../../app-web/src/common-code/healthPlanFormDataType"
import { base64ToDomain } from "../../../app-web/src/common-code/proto/healthPlanFormDataProto"
import { HealthPlanPackage } from "../../gen/gqlClient"
import { cmsUser, minnesotaStatePrograms, stateUser } from "../../utils/apollo-test-utils"

describe('CMS user can view rate reviews', () => {
beforeEach(() => {
cy.stubFeatureFlags()
cy.interceptGraphQL()
})
// By default return lastest revision
const getFormData = (pkg: HealthPlanPackage, indx = 0): HealthPlanFormDataType => {
const latestRevision = pkg.revisions[indx].node
if (!latestRevision) {
throw new Error('no revisions found for package' + pkg.id)
}

const unwrapResult = base64ToDomain(latestRevision.formDataProto)
if (unwrapResult instanceof Error) {
throw unwrapResult
}

return unwrapResult
}


it('and navigate to a specific rate from the rates dashboard', () => {
cy.interceptFeatureFlags({
'rates-db-refactor':true,
'rate-reviews-dashboard': true
})

cy.apiAssignDivisionToCMSUser(cmsUser(), 'DMCO').then(() => {

// 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')

// 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')
})
cy.findByText('rate1SupportingDocument1.pdf').should('exist')

// Go back to dashboard and check both rates in the table
// check the dashboard has the columns we expect
cy.findByText('Back to dashboard').should('exist').click()
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

})
})
})
61 changes: 61 additions & 0 deletions services/cypress/support/apiCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
DivisionType,
adminUser,
contractOnlyData,
contractAndRatesData,
newSubmissionInput,
CMSUserType,
} from '../utils/apollo-test-utils'
Expand Down Expand Up @@ -71,6 +72,53 @@ const createAndSubmitContractOnlyPackage = async (
return submission.data.submitHealthPlanPackage.pkg
}

const createAndSubmitContractWithRates = async (
apolloClient: ApolloClient<NormalizedCacheObject>
): Promise<HealthPlanPackage> => {
const newSubmission1 = await apolloClient.mutate({
mutation: CreateHealthPlanPackageDocument,
variables: {
input: newSubmissionInput({submissionType: 'CONTRACT_AND_RATES'}),
},
})
const pkg1 = newSubmission1.data.createHealthPlanPackage.pkg
const pkg1FirstRev = pkg1.revisions[0].node

const formData1 = base64ToDomain(pkg1FirstRev.formDataProto)
if (formData1 instanceof Error) {
throw new Error(formData1.message)
}

const fullFormData1 = {
...formData1,
...contractAndRatesData(),
}

const formDataProto = domainToBase64(fullFormData1)

await apolloClient.mutate({
mutation: UpdateHealthPlanFormDataDocument,
variables: {
input: {
healthPlanFormData: formDataProto,
pkgID: pkg1.id,
},
},
})

const submission1 = await apolloClient.mutate({
mutation: SubmitHealthPlanPackageDocument,
variables: {
input: {
pkgID: pkg1.id,
submittedReason: 'Submit package for Rates Dashboard tests',
},
},
})
return submission1.data.submitHealthPlanPackage.pkg
}


const assignCmsDivision = async (
apolloClient: ApolloClient<NormalizedCacheObject>,
cmsUser: CMSUserType,
Expand Down Expand Up @@ -127,6 +175,19 @@ Cypress.Commands.add(
)
)


Cypress.Commands.add(
'apiCreateAndSubmitContractWithRates',
(stateUser): Cypress.Chainable<HealthPlanPackage> =>
cy.task<DocumentNode>('readGraphQLSchema').then((schema) =>
apolloClientWrapper(
schema,
stateUser,
createAndSubmitContractWithRates
)
)
)

Cypress.Commands.add(
'apiAssignDivisionToCMSUser',
(cmsUser, division): Cypress.Chainable<void> =>
Expand Down
1 change: 1 addition & 0 deletions services/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Cypress.Commands.add('interceptGraphQL', () => {
aliasQuery(req, 'fetchHealthPlanPackage')
aliasQuery(req, 'fetchHealthPlanPackageWithQuestions')
aliasQuery(req, 'indexHealthPlanPackages')
aliasQuery(req, 'indexRates')
aliasMutation(req, 'createHealthPlanPackage')
aliasMutation(req, 'updateHealthPlanFormData')
aliasMutation(req, 'submitHealthPlanPackage')
Expand Down
1 change: 1 addition & 0 deletions services/cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ declare global {
}): void

apiCreateAndSubmitContractOnlySubmission(stateUser: StateUserType): Cypress.Chainable<HealthPlanPackage>
apiCreateAndSubmitContractWithRates(stateUser: StateUserType): Cypress.Chainable<HealthPlanPackage>
apiAssignDivisionToCMSUser(cmsUser: CMSUserType, division: DivisionType): Cypress.Chainable<void>

interceptGraphQL(): void
Expand Down
8 changes: 6 additions & 2 deletions services/cypress/support/loginCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,15 @@ Cypress.Commands.add(
cy.wait('@fetchCurrentUserQuery', { timeout: 20_000 })
if (initialURL?.includes('submissions')) {
cy.wait('@fetchHealthPlanPackageWithQuestionsQuery', { timeout: 20_000 }) // for cases where CMs user goes to specific submission on login, likely from email link
} else if (initialURL?.includes('rate-reviews')) {
cy.wait('@indexRatesQuery', { timeout: 80_000 })
cy.findByTestId('cms-dashboard-page',{timeout: 10_000 }).should('exist')
cy.findByRole('heading', {name: /rate reviews/}).should('exist')
} else {
// Default behavior on login is to go to CMS dashboard
// Default behavior on login is to go to CMS dashboard submissions
cy.wait('@indexHealthPlanPackagesQuery', { timeout: 80_000 })
cy.findByTestId('cms-dashboard-page',{timeout: 10_000 }).should('exist')
cy.findByRole('heading', {name: 'Submissions'}).should('exist')
cy.findByRole('heading', {name: /Submissions/}).should('exist')
}
}
)
Expand Down
149 changes: 142 additions & 7 deletions services/cypress/utils/apollo-test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxiosResponse } from 'axios'
import { v4 as uuidv4 } from 'uuid'
import {
ApolloClient,
DocumentNode,
Expand Down Expand Up @@ -39,6 +40,30 @@ type DivisionType = 'DMCO' | 'DMCP' | 'OACT'

type UserType = StateUserType | AdminUserType | CMSUserType

// programs for state used in tests
const minnesotaStatePrograms =[
{
"id": "abbdf9b0-c49e-4c4c-bb6f-040cb7b51cce",
"fullName": "Special Needs Basic Care",
"name": "SNBC"
},
{
"id": "d95394e5-44d1-45df-8151-1cc1ee66f100",
"fullName": "Prepaid Medical Assistance Program",
"name": "PMAP"
},
{
"id": "ea16a6c0-5fc6-4df8-adac-c627e76660ab",
"fullName": "Minnesota Senior Care Plus ",
"name": "MSC+"
},
{
"id": "3fd36500-bf2c-47bc-80e8-e7aa417184c5",
"fullName": "Minnesota Senior Health Options",
"name": "MSHO"
}
]

const contractOnlyData = (): Partial<UnlockedHealthPlanFormDataType>=> ({
stateContacts: [
{
Expand Down Expand Up @@ -77,15 +102,123 @@ const contractOnlyData = (): Partial<UnlockedHealthPlanFormDataType>=> ({
rateInfos: [],
})

const newSubmissionInput = (): Partial<UnlockedHealthPlanFormDataType> => ({
populationCovered: 'MEDICAID',
programIDs: ['abbdf9b0-c49e-4c4c-bb6f-040cb7b51cce'],
submissionType: 'CONTRACT_ONLY',
riskBasedContract: false,
submissionDescription: 'Test Q&A',
contractType: 'BASE',
const contractAndRatesData = (): Partial<UnlockedHealthPlanFormDataType>=> ({
stateCode: 'MN',
stateContacts: [
{
name: 'Name',
titleRole: 'Title',
email: 'example@example.com',
},
],
addtlActuaryContacts: [],
documents: [],
contractExecutionStatus: 'EXECUTED' as const,
contractDocuments: [
{
name: 'Contract Cert.pdf',
s3URL: 's3://local-uploads/1684382956834-Contract Cert.pdf/Contract Cert.pdf',
documentCategories: ['CONTRACT'],
sha256: 'abc123',
},
],
contractDateStart: new Date('2023-05-01T00:00:00.000Z'),
contractDateEnd: new Date('2023-05-31T00:00:00.000Z'),
contractAmendmentInfo: {
modifiedProvisions: {
inLieuServicesAndSettings: false,
modifiedRiskSharingStrategy: false,
modifiedIncentiveArrangements: false,
modifiedWitholdAgreements: false,
modifiedStateDirectedPayments: false,
modifiedPassThroughPayments: false,
modifiedPaymentsForMentalDiseaseInstitutions: false,
modifiedNonRiskPaymentArrangements: false,
},
},
managedCareEntities: ['MCO'],
federalAuthorities: ['STATE_PLAN'],
rateInfos:[
{
id: uuidv4(),
rateType: 'NEW' as const,
rateDateStart: new Date(Date.UTC(2025, 5, 1)),
rateDateEnd: new Date(Date.UTC(2026, 4, 30)),
rateDateCertified: new Date(Date.UTC(2025, 3, 15)),
rateDocuments: [
{
name: 'rate1Document1.pdf',
s3URL: 'fakeS3URL',
sha256: 'fakesha',
documentCategories: ['RATES' as const],
},
],
supportingDocuments: [ {
name: 'rate1SupportingDocument1.pdf',
s3URL: 'fakeS3URL',
sha256: 'fakesha',
documentCategories: ['RATES' as const],
}],
rateProgramIDs: [minnesotaStatePrograms[0].id],
actuaryContacts: [
{
name: 'actuary1',
titleRole: 'test title',
email: 'email@example.com',
actuarialFirm: 'MERCER' as const,
actuarialFirmOther: '',
},
],
actuaryCommunicationPreference: 'OACT_TO_ACTUARY' as const,
packagesWithSharedRateCerts: [],
},
{
id: uuidv4(),
rateType: 'NEW' as const,
rateDateStart: new Date(Date.UTC(2030, 5, 1)),
rateDateEnd: new Date(Date.UTC(2036, 4, 30)),
rateDateCertified: new Date(Date.UTC(2035, 3, 15)),
rateDocuments: [
{
name: 'rate2Document1.pdf',
s3URL: 'fakeS3URL',
sha256: 'fakesha',
documentCategories: ['RATES' as const],
},
],
supportingDocuments: [],
rateProgramIDs: [minnesotaStatePrograms[0].id],
actuaryContacts: [
{
name: 'actuary2',
titleRole: 'test title',
email: 'email@example.com',
actuarialFirm: 'MERCER' as const,
actuarialFirmOther: '',
},
],
actuaryCommunicationPreference: 'OACT_TO_ACTUARY' as const,
packagesWithSharedRateCerts: [],
},
]


})

const newSubmissionInput = (overrides?: Partial<UnlockedHealthPlanFormDataType> ): Partial<UnlockedHealthPlanFormDataType> => {
return Object.assign(
{
populationCovered: 'MEDICAID',
programIDs: [minnesotaStatePrograms[0].id],
submissionType: 'CONTRACT_ONLY',
riskBasedContract: false,
submissionDescription: 'Test Q&A',
contractType: 'BASE'
},
overrides
)
}

const stateUser = ():StateUserType => ({
id: 'user1',
email: 'aang@example.com',
Expand Down Expand Up @@ -298,10 +431,12 @@ const apolloClientWrapper = async <T>(
export {
apolloClientWrapper,
contractOnlyData,
contractAndRatesData,
newSubmissionInput,
cmsUser,
adminUser,
stateUser,
minnesotaStatePrograms
}
export type {
StateUserType,
Expand Down
Loading