From 6e5db5713e4ab46987b7d5e9e12f747759564f33 Mon Sep 17 00:00:00 2001 From: Jason Lin <98117700+JasonLin0991@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:03:46 -0400 Subject: [PATCH] MCR-4450: Follow up question name change to contractQuestion (#2807) * Change question to contractQuestion everywhere. Remove indexQuestions query. * set up app for test data * Some more typename changes * Create fetchContractWithQuestions query helper. --- .../migration.sql | 17 ++ services/app-api/prisma/schema.prisma | 66 ++--- .../src/domain-models/QuestionsType.ts | 59 +++-- .../contractAndRates/baseContractRateTypes.ts | 9 +- services/app-api/src/domain-models/index.ts | 10 +- services/app-api/src/emailer/emailer.ts | 14 +- .../emailer/emails/resubmitPackageCMSEmail.ts | 2 +- .../emails/sendQuestionCMSEmail.test.ts | 12 +- .../emailer/emails/sendQuestionCMSEmail.ts | 4 +- .../emails/sendQuestionResponseCMSEmail.ts | 6 +- .../sendQuestionResponseStateEmail.test.ts | 7 +- .../emails/sendQuestionResponseStateEmail.ts | 6 +- .../emails/sendQuestionStateEmail.test.ts | 7 +- .../emailer/emails/sendQuestionStateEmail.ts | 4 +- .../app-api/src/emailer/templateHelpers.ts | 6 +- .../app-api/src/postgres/postgresStore.ts | 30 ++- .../findAllQuestionsByContract.ts | 10 +- .../src/postgres/questionResponse/index.ts | 4 +- ...tQuestion.ts => insertContractQuestion.ts} | 15 +- ...e.ts => insertContractQuestionResponse.ts} | 11 +- .../questionResponse/questionHelpers.ts | 20 +- .../src/resolvers/configureResolvers.ts | 21 +- .../contract/contractResolver.test.ts | 9 +- ...test.ts => createContractQuestion.test.ts} | 174 ++++-------- ...eQuestion.ts => createContractQuestion.ts} | 29 +- ...=> createContractQuestionResponse.test.ts} | 111 +++----- ...e.ts => createContractQuestionResponse.ts} | 6 +- .../src/resolvers/questionResponse/index.ts | 5 +- .../questionResponse/indexQuestions.test.ts | 248 ------------------ .../questionResponse/indexQuestions.ts | 62 ----- .../questionResponseDocumentResolver.test.ts | 32 +-- .../app-api/src/testHelpers/emailerHelpers.ts | 8 +- .../src/testHelpers/gqlContractHelpers.ts | 28 ++ .../app-api/src/testHelpers/gqlHelpers.ts | 52 +--- services/app-api/src/testHelpers/index.ts | 1 + .../app-api/src/testHelpers/storeHelpers.ts | 4 +- ...graphql => createContractQuestion.graphql} | 4 +- ...=> createContractQuestionResponse.graphql} | 4 +- .../fetchContractWithQuestions.graphql | 2 +- ...etchHealthPlanPackageWithQuestions.graphql | 2 +- .../src/queries/indexQuestions.graphql | 100 ------- services/app-graphql/src/schema.graphql | 122 +++------ services/app-web/src/gqlHelpers/index.ts | 2 - .../mutationWrappersForUserFriendlyErrors.ts | 46 ++-- .../useIndexQuestionsQueryWrapper.ts | 27 -- .../QuestionResponse.test.tsx | 6 +- .../QuestionResponse/QuestionResponse.tsx | 4 +- .../UploadQuestions/UploadQuestions.test.tsx | 8 +- .../UploadQuestions/UploadQuestions.tsx | 8 +- .../UploadResponse/UploadResponse.test.tsx | 23 +- .../UploadResponse/UploadResponse.tsx | 8 +- .../apolloMocks/contractPackageDataMock.ts | 19 +- .../src/testHelpers/apolloMocks/index.ts | 2 +- .../apolloMocks/questionResponseDataMocks.ts | 20 +- .../apolloMocks/questionResponseGQLMock.ts | 44 ++-- services/cypress/support/commands.ts | 4 +- .../support/questionResponseCommands.ts | 4 +- 57 files changed, 503 insertions(+), 1065 deletions(-) create mode 100644 services/app-api/prisma/migrations/20241003164410_rename_question_tables_to_contract_question/migration.sql rename services/app-api/src/postgres/questionResponse/{insertQuestion.ts => insertContractQuestion.ts} (78%) rename services/app-api/src/postgres/questionResponse/{insertQuestionResponse.ts => insertContractQuestionResponse.ts} (85%) rename services/app-api/src/resolvers/questionResponse/{createQuestion.test.ts => createContractQuestion.test.ts} (79%) rename services/app-api/src/resolvers/questionResponse/{createQuestion.ts => createContractQuestion.ts} (91%) rename services/app-api/src/resolvers/questionResponse/{createQuestionResponse.test.ts => createContractQuestionResponse.test.ts} (77%) rename services/app-api/src/resolvers/questionResponse/{createQuestionResponse.ts => createContractQuestionResponse.ts} (97%) delete mode 100644 services/app-api/src/resolvers/questionResponse/indexQuestions.test.ts delete mode 100644 services/app-api/src/resolvers/questionResponse/indexQuestions.ts rename services/app-graphql/src/mutations/{createQuestion.graphql => createContractQuestion.graphql} (88%) rename services/app-graphql/src/mutations/{createQuestionResponse.graphql => createContractQuestionResponse.graphql} (92%) delete mode 100644 services/app-graphql/src/queries/indexQuestions.graphql delete mode 100644 services/app-web/src/gqlHelpers/useIndexQuestionsQueryWrapper.ts diff --git a/services/app-api/prisma/migrations/20241003164410_rename_question_tables_to_contract_question/migration.sql b/services/app-api/prisma/migrations/20241003164410_rename_question_tables_to_contract_question/migration.sql new file mode 100644 index 0000000000..019ce17b6c --- /dev/null +++ b/services/app-api/prisma/migrations/20241003164410_rename_question_tables_to_contract_question/migration.sql @@ -0,0 +1,17 @@ +BEGIN; + +ALTER TABLE "Question" RENAME TO "ContractQuestion"; + +ALTER TABLE "QuestionDocument" RENAME TO "ContractQuestionDocument"; + +ALTER TABLE "QuestionResponse" RENAME TO "ContractQuestionResponse"; + +ALTER TABLE "QuestionResponseDocument" RENAME TO "ContractQuestionResponseDocument"; + +ALTER TABLE "ContractQuestionDocument" RENAME CONSTRAINT "QuestionDocument_questionID_fkey" TO "ContractQuestionDocument_questionID_fkey"; +ALTER TABLE "ContractQuestionResponse" RENAME CONSTRAINT "QuestionResponse_questionID_fkey" TO "ContractQuestionResponse_questionID_fkey"; +ALTER TABLE "ContractQuestionResponseDocument" RENAME CONSTRAINT "QuestionResponseDocument_responseID_fkey" TO "ContractQuestionResponseDocument_responseID_fkey"; + +ALTER TABLE "ContractQuestion" RENAME CONSTRAINT "Question_contractID_fkey" TO "ContractQuestion_contractID_fkey"; + +COMMIT; diff --git a/services/app-api/prisma/schema.prisma b/services/app-api/prisma/schema.prisma index 2193c6d9bb..c53bca4219 100644 --- a/services/app-api/prisma/schema.prisma +++ b/services/app-api/prisma/schema.prisma @@ -43,7 +43,7 @@ model ContractTable { state State @relation(fields: [stateCode], references: [stateCode]) stateNumber Int - questions Question[] + questions ContractQuestion[] draftRates DraftRateJoinTable[] @@ -302,22 +302,22 @@ model StateProgram { } model User { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt givenName String familyName String email String role Role divisionAssignment Division? stateCode String? - stateAssignments State[] @relation("StateToAssignedCMSUser") - questions Question[] + stateAssignments State[] @relation("StateToAssignedCMSUser") + questions ContractQuestion[] rateQuestions RateQuestion[] - responses QuestionResponse[] + responses ContractQuestionResponse[] rateResponses RateQuestionResponse[] audits UserAudit[] - updatedByAuditEntries UserAudit[] @relation("UpdatedBy") + updatedByAuditEntries UserAudit[] @relation("UpdatedBy") updateInfos UpdateInfoTable[] } @@ -334,48 +334,48 @@ model UserAudit { priorValue Json? } -model Question { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt +model ContractQuestion { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt contractID String - contract ContractTable @relation(fields: [contractID], references: [id]) - addedBy User @relation(fields: [addedByUserID], references: [id]) + contract ContractTable @relation(fields: [contractID], references: [id]) + addedBy User @relation(fields: [addedByUserID], references: [id]) addedByUserID String division Division - documents QuestionDocument[] - responses QuestionResponse[] + documents ContractQuestionDocument[] + responses ContractQuestionResponse[] } -model QuestionDocument { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt +model ContractQuestionDocument { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @default(now()) @updatedAt name String s3URL String questionID String - question Question @relation(fields: [questionID], references: [id]) + question ContractQuestion @relation(fields: [questionID], references: [id]) } -model QuestionResponseDocument { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - response QuestionResponse @relation(fields: [responseID], references: [id]) +model ContractQuestionResponseDocument { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + response ContractQuestionResponse @relation(fields: [responseID], references: [id]) responseID String name String s3URL String } -model QuestionResponse { - id String @id @default(uuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt +model ContractQuestionResponse { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt questionID String - question Question @relation(fields: [questionID], references: [id]) + question ContractQuestion @relation(fields: [questionID], references: [id]) addedByUserID String - addedBy User @relation(fields: [addedByUserID], references: [id]) - documents QuestionResponseDocument[] + addedBy User @relation(fields: [addedByUserID], references: [id]) + documents ContractQuestionResponseDocument[] } model RateQuestion { diff --git a/services/app-api/src/domain-models/QuestionsType.ts b/services/app-api/src/domain-models/QuestionsType.ts index ed9d3a59e8..be1466af72 100644 --- a/services/app-api/src/domain-models/QuestionsType.ts +++ b/services/app-api/src/domain-models/QuestionsType.ts @@ -18,7 +18,7 @@ const commonQuestionSchema = z.object({ responses: z.array(questionResponseType), }) -const question = commonQuestionSchema.extend({ +const contractQuestion = commonQuestionSchema.extend({ contractID: z.string().uuid(), }) @@ -26,17 +26,17 @@ const rateQuestion = commonQuestionSchema.extend({ rateID: z.string().uuid(), }) -const questionEdge = z.object({ - node: question, +const contractQuestionEdge = z.object({ + node: contractQuestion, }) const rateQuestionEdge = z.object({ node: rateQuestion, }) -const questionList = z.object({ +const contractQuestionList = z.object({ totalCount: z.number(), - edges: z.array(questionEdge), + edges: z.array(contractQuestionEdge), }) const rateQuestionList = z.object({ @@ -44,10 +44,10 @@ const rateQuestionList = z.object({ edges: z.array(rateQuestionEdge), }) -const indexQuestionsPayload = z.object({ - DMCOQuestions: questionList, - DMCPQuestions: questionList, - OACTQuestions: questionList, +const indexContractQuestionsPayload = z.object({ + DMCOQuestions: contractQuestionList, + DMCPQuestions: contractQuestionList, + OACTQuestions: contractQuestionList, }) const indexRateQuestionsPayload = z.object({ @@ -56,11 +56,11 @@ const indexRateQuestionsPayload = z.object({ OACTQuestions: rateQuestionList, }) -const createQuestionPayload = z.object({ - question: question, +const createContractQuestionPayload = z.object({ + question: contractQuestion, }) -const createQuestionInput = z.object({ +const createContractQuestionInput = z.object({ contractID: z.string().uuid(), documents: z.array(document), }) @@ -70,43 +70,48 @@ const createRateQuestionInput = z.object({ documents: z.array(document), }) -type CreateQuestionPayload = z.infer +type CreateContractQuestionPayload = z.infer< + typeof createContractQuestionPayload +> -type CreateQuestionInput = z.infer +type CreateContractQuestionInput = z.infer -type IndexQuestionsPayload = z.infer +type IndexContractQuestionsPayload = z.infer< + typeof indexContractQuestionsPayload +> -type Question = z.infer +type ContractQuestionType = z.infer type RateQuestionType = z.infer type CreateRateQuestionInputType = z.infer -type QuestionList = z.infer +type ContractQuestionList = z.infer type Document = z.infer type IndexRateQuestionsPayload = z.infer export type { - IndexQuestionsPayload, - CreateQuestionPayload, - CreateQuestionInput, - Question, + IndexContractQuestionsPayload, + CreateContractQuestionPayload, + CreateContractQuestionInput, + ContractQuestionList, + ContractQuestionType, Document, - QuestionList, RateQuestionType, CreateRateQuestionInputType, IndexRateQuestionsPayload, } export { - indexQuestionsPayload, - createQuestionInput, - createQuestionPayload, - question, + indexContractQuestionsPayload, + createContractQuestionInput, + createContractQuestionPayload, + contractQuestion, document, - questionList, + contractQuestionList, rateQuestion, createRateQuestionInput, + indexRateQuestionsPayload, } diff --git a/services/app-api/src/domain-models/contractAndRates/baseContractRateTypes.ts b/services/app-api/src/domain-models/contractAndRates/baseContractRateTypes.ts index 8a53570c94..2354a76272 100644 --- a/services/app-api/src/domain-models/contractAndRates/baseContractRateTypes.ts +++ b/services/app-api/src/domain-models/contractAndRates/baseContractRateTypes.ts @@ -5,7 +5,10 @@ import { } from './packageSubmissions' import { contractRevisionSchema, rateRevisionSchema } from './revisionTypes' import { statusSchema } from './statusType' -import { indexQuestionsPayload } from '../QuestionsType' +import { + indexContractQuestionsPayload, + indexRateQuestionsPayload, +} from '../QuestionsType' import { updateInfoSchema } from './updateInfoType' // Contract represents the contract specific information in a submission package @@ -27,7 +30,7 @@ const contractWithoutDraftRatesSchema = z.object({ packageSubmissions: z.array(contractPackageSubmissionSchema), - questions: indexQuestionsPayload.optional(), + questions: indexContractQuestionsPayload.optional(), }) type ContractWithoutDraftRatesType = z.infer< @@ -49,6 +52,8 @@ const rateWithoutDraftContractsSchema = z.object({ revisions: z.array(rateRevisionSchema), packageSubmissions: z.array(ratePackageSubmissionSchema), + + questions: indexRateQuestionsPayload.optional(), }) type RateWithoutDraftContractsType = z.infer< diff --git a/services/app-api/src/domain-models/index.ts b/services/app-api/src/domain-models/index.ts index 4c323c6ba5..aa8e537974 100644 --- a/services/app-api/src/domain-models/index.ts +++ b/services/app-api/src/domain-models/index.ts @@ -63,12 +63,12 @@ export type { } from './HealthPlanPackageType' export type { - IndexQuestionsPayload, - CreateQuestionPayload, - CreateQuestionInput, - Question, + IndexContractQuestionsPayload, + CreateContractQuestionPayload, + CreateContractQuestionInput, + ContractQuestionType, Document, - QuestionList, + ContractQuestionList, RateQuestionType, CreateRateQuestionInputType, IndexRateQuestionsPayload, diff --git a/services/app-api/src/emailer/emailer.ts b/services/app-api/src/emailer/emailer.ts index b2aab97ac1..16c7f27c38 100644 --- a/services/app-api/src/emailer/emailer.ts +++ b/services/app-api/src/emailer/emailer.ts @@ -22,7 +22,7 @@ import type { import type { UpdateInfoType, ProgramType, - Question, + ContractQuestionType, ContractRevisionType, UnlockedContractType, } from '../domain-models' @@ -124,27 +124,27 @@ type Emailer = { contract: ContractRevisionType, submitterEmails: string[], statePrograms: ProgramType[], - question: Question + question: ContractQuestionType ) => Promise sendQuestionsCMSEmail: ( contract: ContractRevisionType, stateAnalystsEmails: StateAnalystsEmails, statePrograms: ProgramType[], - questions: Question[] + questions: ContractQuestionType[] ) => Promise sendQuestionResponseCMSEmail: ( contractRevision: ContractRevisionType, statePrograms: ProgramType[], stateAnalystsEmails: StateAnalystsEmails, - currentQuestion: Question, - allContractQuestions: Question[] + currentQuestion: ContractQuestionType, + allContractQuestions: ContractQuestionType[] ) => Promise sendQuestionResponseStateEmail: ( contractRevision: ContractRevisionType, statePrograms: ProgramType[], submitterEmails: string[], - currentQuestion: Question, - allContractQuestions: Question[] + currentQuestion: ContractQuestionType, + allContractQuestions: ContractQuestionType[] ) => Promise } const localEmailerLogger = (emailData: EmailData) => diff --git a/services/app-api/src/emailer/emails/resubmitPackageCMSEmail.ts b/services/app-api/src/emailer/emails/resubmitPackageCMSEmail.ts index ee36a7698d..bf1d761477 100644 --- a/services/app-api/src/emailer/emails/resubmitPackageCMSEmail.ts +++ b/services/app-api/src/emailer/emails/resubmitPackageCMSEmail.ts @@ -55,7 +55,7 @@ export const resubmitPackageCMSEmail = async ( resubmittedBy: updateInfo.updatedBy.email, resubmittedOn: formatCalendarDate(updateInfo.updatedAt), resubmissionReason: updateInfo.updatedReason, - shouldIncludeRates: pkg.submissionType === 'CONTRACT_AND_RATES', + shouldIncludeRates: isContractAndRates, rateInfos: isContractAndRates && pkg.rateInfos.map((rate) => ({ diff --git a/services/app-api/src/emailer/emails/sendQuestionCMSEmail.test.ts b/services/app-api/src/emailer/emails/sendQuestionCMSEmail.test.ts index 9db345a2ec..582900fe6d 100644 --- a/services/app-api/src/emailer/emails/sendQuestionCMSEmail.test.ts +++ b/services/app-api/src/emailer/emails/sendQuestionCMSEmail.test.ts @@ -4,7 +4,11 @@ import { mockMNState, mockQuestionAndResponses, } from '../../testHelpers/emailerHelpers' -import type { CMSUserType, StateType, Question } from '../../domain-models' +import type { + CMSUserType, + StateType, + ContractQuestionType, +} from '../../domain-models' import { packageName } from '../../common-code/healthPlanFormDataType' import { sendQuestionCMSEmail } from './index' import { getTestStateAnalystsEmails } from '../../testHelpers/parameterStoreHelpers' @@ -27,7 +31,7 @@ const cmsUser: CMSUserType = { stateAssignments: [flState], } -const questions: Question[] = [ +const questions: ContractQuestionType[] = [ mockQuestionAndResponses({ id: 'test-question-id-1', addedBy: cmsUser, @@ -75,7 +79,7 @@ test('to addresses list includes state analyst and OACT group emails when an OAC ...cmsUser, divisionAssignment: 'OACT', } - const questionsFromOACT: Question[] = [ + const questionsFromOACT: ContractQuestionType[] = [ { ...questions[0], addedBy: oactUser, @@ -110,7 +114,7 @@ test('to addresses list includes state analyst and DMCP group emails when a DMCP ...cmsUser, divisionAssignment: 'DMCP', } - const questionsFromDMCP: Question[] = [ + const questionsFromDMCP: ContractQuestionType[] = [ { ...questions[0], addedBy: dmcpUser, diff --git a/services/app-api/src/emailer/emails/sendQuestionCMSEmail.ts b/services/app-api/src/emailer/emails/sendQuestionCMSEmail.ts index 2e14cdafd5..961f10c8d8 100644 --- a/services/app-api/src/emailer/emails/sendQuestionCMSEmail.ts +++ b/services/app-api/src/emailer/emails/sendQuestionCMSEmail.ts @@ -2,7 +2,7 @@ import { packageName as generatePackageName } from '../../common-code/healthPlan import { formatCalendarDate } from '../../../../app-web/src/common-code/dateHelpers' import { pruneDuplicateEmails } from '../formatters' import type { EmailConfiguration, EmailData, StateAnalystsEmails } from '..' -import type { ProgramType, Question } from '../../domain-models' +import type { ProgramType, ContractQuestionType } from '../../domain-models' import { stripHTMLFromTemplate, renderTemplate, @@ -17,7 +17,7 @@ export const sendQuestionCMSEmail = async ( stateAnalystsEmails: StateAnalystsEmails, config: EmailConfiguration, statePrograms: ProgramType[], - questions: Question[] + questions: ContractQuestionType[] ): Promise => { const newQuestion = questions[questions.length - 1] let receiverEmails = [...stateAnalystsEmails, ...config.devReviewTeamEmails] diff --git a/services/app-api/src/emailer/emails/sendQuestionResponseCMSEmail.ts b/services/app-api/src/emailer/emails/sendQuestionResponseCMSEmail.ts index 8ba69a8e6c..206181d08b 100644 --- a/services/app-api/src/emailer/emails/sendQuestionResponseCMSEmail.ts +++ b/services/app-api/src/emailer/emails/sendQuestionResponseCMSEmail.ts @@ -2,7 +2,7 @@ import { packageName as generatePackageName } from '../../common-code/healthPlan import { formatCalendarDate } from '../../../../app-web/src/common-code/dateHelpers' import { pruneDuplicateEmails } from '../formatters' import type { EmailConfiguration, EmailData } from '..' -import type { ProgramType, Question } from '../../domain-models' +import type { ProgramType, ContractQuestionType } from '../../domain-models' import { stripHTMLFromTemplate, renderTemplate, @@ -18,8 +18,8 @@ export const sendQuestionResponseCMSEmail = async ( config: EmailConfiguration, statePrograms: ProgramType[], stateAnalystsEmails: StateAnalystsEmails, - currentQuestion: Question, - allContractQuestions: Question[] + currentQuestion: ContractQuestionType, + allContractQuestions: ContractQuestionType[] ): Promise => { // currentQuestion is the question the new response belongs to. Responses can be uploaded to any question round. const { responses, division } = currentQuestion diff --git a/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.test.ts b/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.test.ts index be3c3c098d..ef91369ef6 100644 --- a/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.test.ts +++ b/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.test.ts @@ -8,7 +8,10 @@ import type { ContractRevisionType, StateType, } from '../../domain-models' -import type { ContractFormDataType, Question } from '../../domain-models' +import type { + ContractFormDataType, + ContractQuestionType, +} from '../../domain-models' import { packageName } from '../../common-code/healthPlanFormDataType' import { sendQuestionResponseStateEmail } from './index' @@ -30,7 +33,7 @@ const cmsUser: CMSUserType = { stateAssignments: [flState], } -const questions: Question[] = [ +const questions: ContractQuestionType[] = [ { id: '1234', contractID: 'contract-id-test', diff --git a/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.ts b/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.ts index 1ce2ca9645..9fa321d1d8 100644 --- a/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.ts +++ b/services/app-api/src/emailer/emails/sendQuestionResponseStateEmail.ts @@ -2,7 +2,7 @@ import { packageName as generatePackageName } from '../../common-code/healthPlan import { formatCalendarDate } from '../../../../app-web/src/common-code/dateHelpers' import { pruneDuplicateEmails } from '../formatters' import type { EmailConfiguration, EmailData } from '..' -import type { ProgramType, Question } from '../../domain-models' +import type { ProgramType, ContractQuestionType } from '../../domain-models' import { stripHTMLFromTemplate, renderTemplate, @@ -17,8 +17,8 @@ export const sendQuestionResponseStateEmail = async ( config: EmailConfiguration, submitterEmails: string[], statePrograms: ProgramType[], - allContractQuestions: Question[], - currentQuestion: Question + allContractQuestions: ContractQuestionType[], + currentQuestion: ContractQuestionType ): Promise => { // currentQuestion is the question the new response belongs to. Responses can be uploaded to any question round. const division = currentQuestion.division diff --git a/services/app-api/src/emailer/emails/sendQuestionStateEmail.test.ts b/services/app-api/src/emailer/emails/sendQuestionStateEmail.test.ts index e7fb1aae18..25a03bcf4f 100644 --- a/services/app-api/src/emailer/emails/sendQuestionStateEmail.test.ts +++ b/services/app-api/src/emailer/emails/sendQuestionStateEmail.test.ts @@ -8,7 +8,10 @@ import type { ContractRevisionType, StateType, } from '../../domain-models' -import type { ContractFormDataType, Question } from '../../domain-models' +import type { + ContractFormDataType, + ContractQuestionType, +} from '../../domain-models' import { packageName } from '../../common-code/healthPlanFormDataType' import { sendQuestionStateEmail } from './index' @@ -30,7 +33,7 @@ const cmsUser: CMSUserType = { stateAssignments: [flState], } -const currentQuestion: Question = { +const currentQuestion: ContractQuestionType = { id: '1234', contractID: 'contract-id-test', createdAt: new Date('01/01/2024'), diff --git a/services/app-api/src/emailer/emails/sendQuestionStateEmail.ts b/services/app-api/src/emailer/emails/sendQuestionStateEmail.ts index a1ac021ee3..3d57951e36 100644 --- a/services/app-api/src/emailer/emails/sendQuestionStateEmail.ts +++ b/services/app-api/src/emailer/emails/sendQuestionStateEmail.ts @@ -2,7 +2,7 @@ import { packageName as generatePackageName } from '../../common-code/healthPlan import { formatCalendarDate } from '../../../../app-web/src/common-code/dateHelpers' import { pruneDuplicateEmails } from '../formatters' import type { EmailConfiguration, EmailData } from '..' -import type { ProgramType, Question } from '../../domain-models' +import type { ProgramType, ContractQuestionType } from '../../domain-models' import { stripHTMLFromTemplate, renderTemplate, @@ -16,7 +16,7 @@ export const sendQuestionStateEmail = async ( submitterEmails: string[], config: EmailConfiguration, statePrograms: ProgramType[], - currentQuestion: Question + currentQuestion: ContractQuestionType ): Promise => { const stateContactEmails: string[] = [] diff --git a/services/app-api/src/emailer/templateHelpers.ts b/services/app-api/src/emailer/templateHelpers.ts index eff4eeca46..814b891eaf 100644 --- a/services/app-api/src/emailer/templateHelpers.ts +++ b/services/app-api/src/emailer/templateHelpers.ts @@ -12,10 +12,10 @@ import type { ProgramType, RateRevisionType, UnlockedContractType, + ContractQuestionType, } from '../domain-models' import { logError } from '../logger' import { pruneDuplicateEmails } from './formatters' -import type { Question } from '../domain-models' // ETA SETUP Eta.configure({ @@ -328,8 +328,8 @@ const stripHTMLFromTemplate = (template: string) => { } const getQuestionRound = ( - allQuestions: Question[], - currentQuestion: Question + allQuestions: ContractQuestionType[], + currentQuestion: ContractQuestionType ): number | Error => { // Filter out other divisions question and sort by created at in ascending order const divisionQuestions = allQuestions diff --git a/services/app-api/src/postgres/postgresStore.ts b/services/app-api/src/postgres/postgresStore.ts index efaf684f96..150656ebfc 100644 --- a/services/app-api/src/postgres/postgresStore.ts +++ b/services/app-api/src/postgres/postgresStore.ts @@ -4,8 +4,8 @@ import type { ProgramType, UserType, StateUserType, - Question, - CreateQuestionInput, + ContractQuestionType, + CreateContractQuestionInput, InsertQuestionResponseArgs, StateType, RateType, @@ -26,8 +26,8 @@ import { } from './user' import { findAllQuestionsByContract, - insertQuestion, - insertQuestionResponse, + insertContractQuestion, + insertContractQuestionResponse, insertRateQuestion, findAllQuestionsByRate, } from './questionResponse' @@ -104,17 +104,19 @@ type Store = { description?: string | null ) => Promise - insertQuestion: ( - questionInput: CreateQuestionInput, + insertContractQuestion: ( + questionInput: CreateContractQuestionInput, user: CMSUsersUnionType - ) => Promise + ) => Promise - findAllQuestionsByContract: (pkgID: string) => Promise + findAllQuestionsByContract: ( + pkgID: string + ) => Promise - insertQuestionResponse: ( + insertContractQuestionResponse: ( questionInput: InsertQuestionResponseArgs, user: StateUserType - ) => Promise + ) => Promise insertRateQuestion: ( questionInput: CreateRateQuestionInputType, @@ -217,12 +219,12 @@ function NewPostgresStore(client: PrismaClient): Store { findStateAssignedUsers: (stateCode) => findStateAssignedUsers(client, stateCode), - insertQuestion: (questionInput, user) => - insertQuestion(client, questionInput, user), + insertContractQuestion: (questionInput, user) => + insertContractQuestion(client, questionInput, user), findAllQuestionsByContract: (pkgID) => findAllQuestionsByContract(client, pkgID), - insertQuestionResponse: (questionInput, user) => - insertQuestionResponse(client, questionInput, user), + insertContractQuestionResponse: (questionInput, user) => + insertContractQuestionResponse(client, questionInput, user), insertRateQuestion: (questionInput, user) => insertRateQuestion(client, questionInput, user), findAllQuestionsByRate: (rateID) => diff --git a/services/app-api/src/postgres/questionResponse/findAllQuestionsByContract.ts b/services/app-api/src/postgres/questionResponse/findAllQuestionsByContract.ts index bb3dce6bed..f1e54ed6b8 100644 --- a/services/app-api/src/postgres/questionResponse/findAllQuestionsByContract.ts +++ b/services/app-api/src/postgres/questionResponse/findAllQuestionsByContract.ts @@ -1,13 +1,13 @@ import type { PrismaClient } from '@prisma/client' -import type { Question } from '../../domain-models' +import type { ContractQuestionType } from '../../domain-models' import { questionPrismaToDomainType, questionInclude } from './questionHelpers' export async function findAllQuestionsByContract( client: PrismaClient, contractID: string -): Promise { +): Promise { try { - const findResult = await client.question.findMany({ + const findResult = await client.contractQuestion.findMany({ where: { contractID: contractID, }, @@ -17,11 +17,9 @@ export async function findAllQuestionsByContract( }, }) - const questions: Question[] = findResult.map((question) => + return findResult.map((question) => questionPrismaToDomainType(question) ) - - return questions } catch (e: unknown) { if (e instanceof Error) { return e diff --git a/services/app-api/src/postgres/questionResponse/index.ts b/services/app-api/src/postgres/questionResponse/index.ts index 7737cdd376..fb99e0599c 100644 --- a/services/app-api/src/postgres/questionResponse/index.ts +++ b/services/app-api/src/postgres/questionResponse/index.ts @@ -1,11 +1,11 @@ export { findAllQuestionsByContract } from './findAllQuestionsByContract' -export { insertQuestion } from './insertQuestion' +export { insertContractQuestion } from './insertContractQuestion' export { convertToIndexQuestionsPayload, questionPrismaToDomainType, rateQuestionPrismaToDomainType, convertToIndexRateQuestionsPayload, } from './questionHelpers' -export { insertQuestionResponse } from './insertQuestionResponse' +export { insertContractQuestionResponse } from './insertContractQuestionResponse' export { insertRateQuestion } from './insertRateQuestion' export { findAllQuestionsByRate } from './findAllQuestionsByRate' diff --git a/services/app-api/src/postgres/questionResponse/insertQuestion.ts b/services/app-api/src/postgres/questionResponse/insertContractQuestion.ts similarity index 78% rename from services/app-api/src/postgres/questionResponse/insertQuestion.ts rename to services/app-api/src/postgres/questionResponse/insertContractQuestion.ts index 6ecd3a34f3..c4bc3e68da 100644 --- a/services/app-api/src/postgres/questionResponse/insertQuestion.ts +++ b/services/app-api/src/postgres/questionResponse/insertContractQuestion.ts @@ -1,28 +1,25 @@ import type { PrismaClient } from '@prisma/client' import type { - Question, - CreateQuestionInput, + ContractQuestionType, + CreateContractQuestionInput, DivisionType, CMSUsersUnionType, } from '../../domain-models' -import { v4 as uuidv4 } from 'uuid' import { questionPrismaToDomainType, questionInclude } from './questionHelpers' -export async function insertQuestion( +export async function insertContractQuestion( client: PrismaClient, - questionInput: CreateQuestionInput, + questionInput: CreateContractQuestionInput, user: CMSUsersUnionType -): Promise { +): Promise { const documents = questionInput.documents.map((document) => ({ - id: uuidv4(), name: document.name, s3URL: document.s3URL, })) try { - const result = await client.question.create({ + const result = await client.contractQuestion.create({ data: { - id: uuidv4(), contract: { connect: { id: questionInput.contractID, diff --git a/services/app-api/src/postgres/questionResponse/insertQuestionResponse.ts b/services/app-api/src/postgres/questionResponse/insertContractQuestionResponse.ts similarity index 85% rename from services/app-api/src/postgres/questionResponse/insertQuestionResponse.ts rename to services/app-api/src/postgres/questionResponse/insertContractQuestionResponse.ts index 630c5eb56a..efca2b0814 100644 --- a/services/app-api/src/postgres/questionResponse/insertQuestionResponse.ts +++ b/services/app-api/src/postgres/questionResponse/insertContractQuestionResponse.ts @@ -2,32 +2,29 @@ import type { PrismaClient } from '@prisma/client' import type { InsertQuestionResponseArgs, StateUserType, - Question, + ContractQuestionType, } from '../../domain-models' -import { v4 as uuidv4 } from 'uuid' import { questionInclude, questionPrismaToDomainType } from './questionHelpers' import { NotFoundError } from '../postgresErrors' -export async function insertQuestionResponse( +export async function insertContractQuestionResponse( client: PrismaClient, response: InsertQuestionResponseArgs, user: StateUserType -): Promise { +): Promise { const documents = response.documents.map((document) => ({ - id: uuidv4(), name: document.name, s3URL: document.s3URL, })) try { - const result = await client.question.update({ + const result = await client.contractQuestion.update({ where: { id: response.questionID, }, data: { responses: { create: { - id: uuidv4(), addedBy: { connect: { id: user.id, diff --git a/services/app-api/src/postgres/questionResponse/questionHelpers.ts b/services/app-api/src/postgres/questionResponse/questionHelpers.ts index dca5009498..e6206d2389 100644 --- a/services/app-api/src/postgres/questionResponse/questionHelpers.ts +++ b/services/app-api/src/postgres/questionResponse/questionHelpers.ts @@ -1,8 +1,8 @@ import type { CMSUsersUnionType, - IndexQuestionsPayload, + IndexContractQuestionsPayload, IndexRateQuestionsPayload, - Question, + ContractQuestionType, QuestionResponseType, RateQuestionType, } from '../../domain-models' @@ -28,9 +28,9 @@ const questionInclude = { stateAssignments: true, }, }, -} satisfies Prisma.QuestionInclude +} satisfies Prisma.ContractQuestionInclude | Prisma.RateQuestionInclude -type PrismaQuestionType = Prisma.QuestionGetPayload<{ +type PrismaQuestionType = Prisma.ContractQuestionGetPayload<{ include: typeof questionInclude }> @@ -41,7 +41,7 @@ type PrismaRateQuestionType = Prisma.RateQuestionGetPayload<{ // Both types are similar only difference is one related to a contract and the other a rate. const commonQuestionPrismaToDomainType = < P extends PrismaQuestionType | PrismaRateQuestionType, - R extends Question | RateQuestionType, + R extends ContractQuestionType | RateQuestionType, >( prismaQuestion: P ): R => @@ -53,14 +53,14 @@ const commonQuestionPrismaToDomainType = < const questionPrismaToDomainType = ( prismaQuestion: PrismaQuestionType -): Question => commonQuestionPrismaToDomainType(prismaQuestion) +): ContractQuestionType => commonQuestionPrismaToDomainType(prismaQuestion) const rateQuestionPrismaToDomainType = ( prismaQuestion: PrismaRateQuestionType ): RateQuestionType => commonQuestionPrismaToDomainType(prismaQuestion) const convertToCommonIndexQuestionsPayload = < - P extends Question | RateQuestionType, - R extends IndexQuestionsPayload | IndexRateQuestionsPayload, + P extends ContractQuestionType | RateQuestionType, + R extends IndexContractQuestionsPayload | IndexRateQuestionsPayload, >( questions: P[] ): R => { @@ -82,8 +82,8 @@ const convertToCommonIndexQuestionsPayload = < } const convertToIndexQuestionsPayload = ( - contractQuestions: Question[] -): IndexQuestionsPayload => + contractQuestions: ContractQuestionType[] +): IndexContractQuestionsPayload => convertToCommonIndexQuestionsPayload(contractQuestions) const convertToIndexRateQuestionsPayload = ( rateQuestions: RateQuestionType[] diff --git a/services/app-api/src/resolvers/configureResolvers.ts b/services/app-api/src/resolvers/configureResolvers.ts index da1832916b..2bcf43243a 100644 --- a/services/app-api/src/resolvers/configureResolvers.ts +++ b/services/app-api/src/resolvers/configureResolvers.ts @@ -12,9 +12,8 @@ import { updateHealthPlanFormDataResolver, } from './healthPlanPackage' import { - indexQuestionsResolver, - createQuestionResolver, - createQuestionResponseResolver, + createContractQuestionResolver, + createContractQuestionResponseResolver, questionResponseDocumentResolver, createRateQuestionResolver, } from './questionResponse' @@ -72,7 +71,6 @@ export function configureResolvers( indexHealthPlanPackages: indexHealthPlanPackagesResolver(store), indexContracts: indexContractsResolver(store), indexUsers: indexUsersResolver(store), - indexQuestions: indexQuestionsResolver(store), fetchEmailSettings: fetchEmailSettingsResolver( store, emailer, @@ -126,18 +124,19 @@ export function configureResolvers( updateDivisionAssignment: updateDivisionAssignment(store), updateStateAssignment: updateStateAssignment(store), updateStateAssignmentsByState: updateStateAssignmentsByState(store), - createQuestion: createQuestionResolver( + createContractQuestion: createContractQuestionResolver( store, emailParameterStore, emailer, launchDarkly ), - createQuestionResponse: createQuestionResponseResolver( - store, - emailer, - emailParameterStore, - launchDarkly - ), + createContractQuestionResponse: + createContractQuestionResponseResolver( + store, + emailer, + emailParameterStore, + launchDarkly + ), createRateQuestion: createRateQuestionResolver(store), createAPIKey: createAPIKeyResolver(jwt), unlockRate: unlockRate(store), diff --git a/services/app-api/src/resolvers/contract/contractResolver.test.ts b/services/app-api/src/resolvers/contract/contractResolver.test.ts index dfbd573f31..e791987693 100644 --- a/services/app-api/src/resolvers/contract/contractResolver.test.ts +++ b/services/app-api/src/resolvers/contract/contractResolver.test.ts @@ -1,13 +1,12 @@ +import FETCH_CONTRACT_WITH_QUESTIONS from '../../../../app-graphql/src/queries/fetchContractWithQuestions.graphql' import { constructTestPostgresServer, createTestQuestion, createTestQuestionResponse, - indexTestQuestions, } from '../../testHelpers/gqlHelpers' - -import FETCH_CONTRACT_WITH_QUESTIONS from '../../../../app-graphql/src/queries/fetchContractWithQuestions.graphql' import { createAndUpdateTestContractWithoutRates, + fetchTestContractWithQuestions, submitTestContract, } from '../../testHelpers/gqlContractHelpers' import { testS3Client } from '../../testHelpers' @@ -115,10 +114,12 @@ describe('contractResolver', () => { createdOACTQuestion.question.id ) - const indexQuestionsResult = await indexTestQuestions( + const contractWithQuestions = await fetchTestContractWithQuestions( stateServer, stateSubmission.id ) + const indexQuestionsResult = contractWithQuestions.questions + draft.questions = indexQuestionsResult const fetchContractResult = await stateServer.executeOperation({ query: FETCH_CONTRACT_WITH_QUESTIONS, diff --git a/services/app-api/src/resolvers/questionResponse/createQuestion.test.ts b/services/app-api/src/resolvers/questionResponse/createContractQuestion.test.ts similarity index 79% rename from services/app-api/src/resolvers/questionResponse/createQuestion.test.ts rename to services/app-api/src/resolvers/questionResponse/createContractQuestion.test.ts index 1b514536c9..d86f438692 100644 --- a/services/app-api/src/resolvers/questionResponse/createQuestion.test.ts +++ b/services/app-api/src/resolvers/questionResponse/createContractQuestion.test.ts @@ -1,32 +1,30 @@ -import CREATE_QUESTION from 'app-graphql/src/mutations/createQuestion.graphql' +import CREATE_QUESTION from 'app-graphql/src/mutations/createContractQuestion.graphql' import { constructTestPostgresServer, - createAndSubmitTestHealthPlanPackage, - createTestHealthPlanPackage, - resubmitTestHealthPlanPackage, - unlockTestHealthPlanPackage, createTestQuestion, - indexTestQuestions, - defaultFloridaProgram, updateTestStateAssignments, } from '../../testHelpers/gqlHelpers' import { getTestStateAnalystsEmails } from '../../testHelpers/parameterStoreHelpers' -import { packageName } from '../../common-code/healthPlanFormDataType' import { assertAnError, assertAnErrorCode, createAndSubmitTestContract, + createTestContract, + fetchTestContractWithQuestions, } from '../../testHelpers' import { createDBUsersWithFullData, testCMSApproverUser, testCMSUser, } from '../../testHelpers/userHelpers' -import { base64ToDomain } from '../../common-code/proto/healthPlanFormDataProto' import { testEmailConfig, testEmailer } from '../../testHelpers/emailerHelpers' import { testLDService } from '../../testHelpers/launchDarklyHelpers' import { sharedTestPrismaClient } from '../../testHelpers/storeHelpers' import { NewPostgresStore } from '../../postgres' +import { + submitTestContract, + unlockTestContract, +} from '../../testHelpers/gqlContractHelpers' describe('createQuestion', () => { const cmsUser = testCMSUser() @@ -43,18 +41,14 @@ describe('createQuestion', () => { }, }) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) - const createdQuestion = await createTestQuestion( - cmsServer, - submittedPkg.id - ) + const createdQuestion = await createTestQuestion(cmsServer, contract.id) expect(createdQuestion.question).toEqual( expect.objectContaining({ id: expect.any(String), - contractID: submittedPkg.id, + contractID: contract.id, division: 'DMCO', documents: [ { @@ -73,26 +67,12 @@ describe('createQuestion', () => { user: cmsUser, }, }) + const contract = await createAndSubmitTestContract(stateServer) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) - - const unlockedPkg = await unlockTestHealthPlanPackage( - cmsServer, - submittedPkg.id, - 'test unlock' - ) - - await createTestQuestion(cmsServer, submittedPkg.id) - - // Resubmit package - await resubmitTestHealthPlanPackage( - stateServer, - unlockedPkg.id, - 'resubmit reason' - ) - - await createTestQuestion(cmsServer, submittedPkg.id, { + await unlockTestContract(cmsServer, contract.id, 'test unlock') + await createTestQuestion(cmsServer, contract.id) + await submitTestContract(stateServer, contract.id, 'resubmit reason') + await createTestQuestion(cmsServer, contract.id, { documents: [ { name: 'Test Question 2', @@ -101,11 +81,13 @@ describe('createQuestion', () => { ], }) - const indexQuestionsPayload = await indexTestQuestions( - cmsServer, - submittedPkg.id + const contractWithQuestions = await fetchTestContractWithQuestions( + stateServer, + contract.id ) + const indexQuestionsPayload = contractWithQuestions.questions + // Expect package to have two questions expect(indexQuestionsPayload).toEqual( expect.objectContaining({ @@ -116,7 +98,7 @@ describe('createQuestion', () => { node: expect.objectContaining({ id: expect.any(String), createdAt: expect.any(Date), - contractID: submittedPkg.id, + contractID: contract.id, division: 'DMCO', documents: [ { @@ -132,7 +114,7 @@ describe('createQuestion', () => { node: expect.objectContaining({ id: expect.any(String), createdAt: expect.any(Date), - contractID: submittedPkg.id, + contractID: contract.id, division: 'DMCO', documents: [ { @@ -165,13 +147,13 @@ describe('createQuestion', () => { }, }) - const draftPkg = await createTestHealthPlanPackage(stateServer) + const draftContract = await createTestContract(stateServer) const createdQuestion = await cmsServer.executeOperation({ query: CREATE_QUESTION, variables: { input: { - contractID: draftPkg.id, + contractID: draftContract.id, documents: [ { name: 'Test Question', @@ -190,14 +172,13 @@ describe('createQuestion', () => { }) it('returns an error if a state user attempts to create a question for a package', async () => { const stateServer = await constructTestPostgresServer() - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) const createdQuestion = await stateServer.executeOperation({ query: CREATE_QUESTION, variables: { input: { - contractID: submittedPkg.id, + contractID: contract.id, documents: [ { name: 'Test Question', @@ -222,7 +203,7 @@ describe('createQuestion', () => { }, }) - await createAndSubmitTestHealthPlanPackage(stateServer) + await createAndSubmitTestContract(stateServer) const createdQuestion = await cmsServer.executeOperation({ query: CREATE_QUESTION, @@ -257,7 +238,7 @@ describe('createQuestion', () => { }, }) - await createAndSubmitTestHealthPlanPackage(stateServer) + await createAndSubmitTestContract(stateServer) const createdQuestion = await cmsServer.executeOperation({ query: CREATE_QUESTION, @@ -292,7 +273,7 @@ describe('createQuestion', () => { }, }) - await createAndSubmitTestHealthPlanPackage(stateServer) + await createAndSubmitTestContract(stateServer) const createdQuestion = await cmsServer.executeOperation({ query: CREATE_QUESTION, @@ -327,29 +308,18 @@ describe('createQuestion', () => { emailer: mockEmailer, }) - const stateSubmission = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) - await createTestQuestion(cmsServer, stateSubmission.id) - - const currentRevision = stateSubmission.revisions[0].node.formDataProto + await createTestQuestion(cmsServer, contract.id) - const sub = base64ToDomain(currentRevision) - if (sub instanceof Error) { - throw sub - } - - const programs = [defaultFloridaProgram()] - const name = packageName( - sub.stateCode, - sub.stateNumber, - sub.programIDs, - programs - ) + const formData = + contract.packageSubmissions[0].contractRevision.formData + const contractName = + contract.packageSubmissions[0].contractRevision.contractName const stateReceiverEmails = [ 'james@example.com', - ...sub.stateContacts.map((contact) => contact.email), + ...formData.stateContacts.map((contact) => contact.email), ] // email subject line is correct for state email @@ -358,17 +328,17 @@ describe('createQuestion', () => { 1, expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] New questions about ${name}` + `[LOCAL] New questions about ${contractName}` ), sourceEmail: config.emailSource, toAddresses: expect.arrayContaining( Array.from(stateReceiverEmails) ), bodyText: expect.stringContaining( - `CMS asked questions about ${name}` + `CMS asked questions about ${contractName}` ), bodyHTML: expect.stringContaining( - `http://localhost/submissions/${sub.id}/question-and-answers` + `http://localhost/submissions/${contract.id}/question-and-answers` ), }) ) @@ -386,26 +356,16 @@ describe('createQuestion', () => { emailer: mockEmailer, }) - const stateSubmission = - await createAndSubmitTestHealthPlanPackage(stateServer) - - await createTestQuestion(cmsServer, stateSubmission.id) + const contract = await createAndSubmitTestContract(stateServer) - const currentRevision = stateSubmission.revisions[0].node.formDataProto + await createTestQuestion(cmsServer, contract.id) - const sub = base64ToDomain(currentRevision) - if (sub instanceof Error) { - throw sub - } + const contractName = + contract.packageSubmissions[0].contractRevision.contractName - const programs = [defaultFloridaProgram()] - const name = packageName( - sub.stateCode, - sub.stateNumber, - sub.programIDs, - programs + const stateAnalystsEmails = getTestStateAnalystsEmails( + contract.stateCode ) - const stateAnalystsEmails = getTestStateAnalystsEmails(sub.stateCode) const cmsEmails = [ ...config.devReviewTeamEmails, @@ -421,15 +381,15 @@ describe('createQuestion', () => { 2, expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] Questions sent for ${name}` + `[LOCAL] Questions sent for ${contractName}` ), sourceEmail: config.emailSource, toAddresses: expect.arrayContaining(Array.from(cmsEmails)), bodyText: expect.stringContaining( - `DMCO sent questions to the state for submission ${name}` + `DMCO sent questions to the state for submission ${contractName}` ), bodyHTML: expect.stringContaining( - `http://localhost/submissions/${sub.id}/question-and-answers` + `http://localhost/submissions/${contract.id}/question-and-answers` ), }) ) @@ -479,16 +439,8 @@ describe('createQuestion', () => { await createTestQuestion(cmsServer, stateSubmission.id) - const currentRevision = - stateSubmission.packageSubmissions[0].contractRevision - - const programs = [defaultFloridaProgram()] - const name = packageName( - stateSubmission.stateCode, - stateSubmission.stateNumber, - currentRevision.formData.programIDs, - programs - ) + const contractName = + stateSubmission.packageSubmissions[0].contractRevision.contractName const cmsEmails = [...config.devReviewTeamEmails, ...assignedUserEmails] @@ -501,12 +453,12 @@ describe('createQuestion', () => { 2, expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] Questions sent for ${name}` + `[LOCAL] Questions sent for ${contractName}` ), sourceEmail: config.emailSource, toAddresses: expect.arrayContaining(Array.from(cmsEmails)), bodyText: expect.stringContaining( - `DMCO sent questions to the state for submission ${name}` + `DMCO sent questions to the state for submission ${contractName}` ), bodyHTML: expect.stringContaining( `http://localhost/submissions/${stateSubmission.id}/question-and-answers` @@ -533,28 +485,18 @@ describe('createQuestion', () => { }, emailer: mockEmailer, }) - const stateSubmission = - await createAndSubmitTestHealthPlanPackage(stateServer) + const stateSubmission = await createAndSubmitTestContract(stateServer) await createTestQuestion(cmsDMCPServer, stateSubmission.id) await createTestQuestion(cmsServer, stateSubmission.id) await createTestQuestion(cmsServer, stateSubmission.id) - const currentRevision = stateSubmission.revisions[0].node.formDataProto - - const sub = base64ToDomain(currentRevision) - if (sub instanceof Error) { - throw sub - } + const contractName = + stateSubmission.packageSubmissions[0].contractRevision.contractName - const programs = [defaultFloridaProgram()] - const name = packageName( - sub.stateCode, - sub.stateNumber, - sub.programIDs, - programs + const stateAnalystsEmails = getTestStateAnalystsEmails( + stateSubmission.stateCode ) - const stateAnalystsEmails = getTestStateAnalystsEmails(sub.stateCode) const cmsEmails = [ ...config.devReviewTeamEmails, @@ -570,7 +512,7 @@ describe('createQuestion', () => { 6, expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] Questions sent for ${name}` + `[LOCAL] Questions sent for ${contractName}` ), sourceEmail: config.emailSource, toAddresses: expect.arrayContaining(Array.from(cmsEmails)), diff --git a/services/app-api/src/resolvers/questionResponse/createQuestion.ts b/services/app-api/src/resolvers/questionResponse/createContractQuestion.ts similarity index 91% rename from services/app-api/src/resolvers/questionResponse/createQuestion.ts rename to services/app-api/src/resolvers/questionResponse/createContractQuestion.ts index be31590c47..8163d2876c 100644 --- a/services/app-api/src/resolvers/questionResponse/createQuestion.ts +++ b/services/app-api/src/resolvers/questionResponse/createContractQuestion.ts @@ -15,22 +15,22 @@ import type { EmailParameterStore } from '../../parameterStore' import type { LDService } from '../../launchDarkly/launchDarkly' import type { StateCodeType } from '../../testHelpers' -export function createQuestionResolver( +export function createContractQuestionResolver( store: Store, emailParameterStore: EmailParameterStore, emailer: Emailer, launchDarkly: LDService -): MutationResolvers['createQuestion'] { +): MutationResolvers['createContractQuestion'] { return async (_parent, { input }, context) => { const { user, ctx, tracer } = context - const span = tracer?.startSpan('createQuestion', {}, ctx) + const span = tracer?.startSpan('createContractQuestion', {}, ctx) const featureFlags = await launchDarkly.allFlags(context) const readStateAnalystsFromDBFlag = featureFlags?.['read-write-state-assignments'] if (!hasCMSPermissions(user)) { const msg = 'user not authorized to create a question' - logError('createQuestion', msg) + logError('createContractQuestion', msg) setErrorAttributesOnActiveSpan(msg, span) throw new ForbiddenError(msg) } @@ -42,14 +42,14 @@ export function createQuestionResolver( ) { const msg = 'users without an assigned division are not authorized to create a question' - logError('createQuestion', msg) + logError('createContractQuestion', msg) setErrorAttributesOnActiveSpan(msg, span) throw new ForbiddenError(msg) } if (input.documents.length === 0) { const msg = 'question documents are required' - logError('createQuestion', msg) + logError('createContractQuestion', msg) setErrorAttributesOnActiveSpan(msg, span) throw new UserInputError(msg) } @@ -61,7 +61,7 @@ export function createQuestionResolver( if (contractResult instanceof Error) { if (contractResult instanceof NotFoundError) { const errMessage = `Package with id ${input.contractID} does not exist` - logError('createQuestion', errMessage) + logError('createContractQuestion', errMessage) setErrorAttributesOnActiveSpan(errMessage, span) throw new GraphQLError(errMessage, { extensions: { code: 'NOT_FOUND' }, @@ -69,7 +69,7 @@ export function createQuestionResolver( } const errMessage = `Issue finding a package. Message: ${contractResult.message}` - logError('createQuestion', errMessage) + logError('createContractQuestion', errMessage) setErrorAttributesOnActiveSpan(errMessage, span) throw new GraphQLError(errMessage, { extensions: { @@ -82,7 +82,7 @@ export function createQuestionResolver( // Return error if package status is DRAFT, contract will have no submitted revisions if (contractResult.revisions.length === 0) { const errMessage = `Issue creating question for health plan package. Message: Cannot create question for health plan package in DRAFT status` - logError('createQuestion', errMessage) + logError('createContractQuestion', errMessage) setErrorAttributesOnActiveSpan(errMessage, span) throw new UserInputError(errMessage) } @@ -106,7 +106,7 @@ export function createQuestionResolver( ) if (allQuestions instanceof Error) { const errMessage = `Issue finding all questions associated with the contract: ${contractResult.id}` - logError('createQuestion', errMessage) + logError('createContractQuestion', errMessage) setErrorAttributesOnActiveSpan(errMessage, span) throw new Error(errMessage) } @@ -120,11 +120,14 @@ export function createQuestionResolver( ...input, documents: docs, } - const questionResult = await store.insertQuestion(inputFormatted, user) + const questionResult = await store.insertContractQuestion( + inputFormatted, + user + ) if (questionResult instanceof Error) { const errMessage = `Issue creating question for package. Message: ${questionResult.message}` - logError('createQuestion', errMessage) + logError('createContractQuestion', errMessage) setErrorAttributesOnActiveSpan(errMessage, span) throw new Error(errMessage) } @@ -220,7 +223,7 @@ export function createQuestionResolver( }, }) } - logSuccess('createQuestion') + logSuccess('createContractQuestion') setSuccessAttributesOnActiveSpan(span) return { diff --git a/services/app-api/src/resolvers/questionResponse/createQuestionResponse.test.ts b/services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.test.ts similarity index 77% rename from services/app-api/src/resolvers/questionResponse/createQuestionResponse.test.ts rename to services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.test.ts index 6c29e35470..89f59fddf2 100644 --- a/services/app-api/src/resolvers/questionResponse/createQuestionResponse.test.ts +++ b/services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.test.ts @@ -1,13 +1,10 @@ -import CREATE_QUESTION_RESPONSE from 'app-graphql/src/mutations/createQuestionResponse.graphql' +import CREATE_CONTRACT_QUESTION_RESPONSE from 'app-graphql/src/mutations/createContractQuestionResponse.graphql' import { constructTestPostgresServer, - createAndSubmitTestHealthPlanPackage, createTestQuestion, createTestQuestionResponse, - defaultFloridaProgram, updateTestStateAssignments, } from '../../testHelpers/gqlHelpers' -import { base64ToDomain } from '../../common-code/proto/healthPlanFormDataProto' import { assertAnError, assertAnErrorCode, @@ -18,9 +15,7 @@ import { testCMSUser, } from '../../testHelpers/userHelpers' import { testEmailConfig, testEmailer } from '../../testHelpers/emailerHelpers' -import { latestFormData } from '../../testHelpers/healthPlanPackageHelpers' import { findStatePrograms, NewPostgresStore } from '../../postgres' -import { packageName } from '../../common-code/healthPlanFormDataType' import { getTestStateAnalystsEmails } from '../../testHelpers/parameterStoreHelpers' import { testLDService } from '../../testHelpers/launchDarklyHelpers' import { sharedTestPrismaClient } from '../../testHelpers/storeHelpers' @@ -40,13 +35,9 @@ describe('createQuestionResponse', () => { }, }) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) - const createdQuestion = await createTestQuestion( - cmsServer, - submittedPkg.id - ) + const createdQuestion = await createTestQuestion(cmsServer, contract.id) const createResponseResult = await createTestQuestionResponse( stateServer, @@ -80,7 +71,7 @@ describe('createQuestionResponse', () => { const fakeID = 'abc-123' const createResponseResult = await stateServer.executeOperation({ - query: CREATE_QUESTION_RESPONSE, + query: CREATE_CONTRACT_QUESTION_RESPONSE, variables: { input: { questionID: fakeID, @@ -108,15 +99,11 @@ describe('createQuestionResponse', () => { user: cmsUser, }, }) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) - const createdQuestion = await createTestQuestion( - cmsServer, - submittedPkg.id - ) + const contract = await createAndSubmitTestContract(stateServer) + const createdQuestion = await createTestQuestion(cmsServer, contract.id) const createResponseResult = await cmsServer.executeOperation({ - query: CREATE_QUESTION_RESPONSE, + query: CREATE_CONTRACT_QUESTION_RESPONSE, variables: { input: { questionID: createdQuestion.question.id, @@ -153,35 +140,21 @@ describe('createQuestionResponse', () => { emailer: mockEmailer, }) - const submittedPkg = await createAndSubmitTestHealthPlanPackage( - stateServer, - { riskBasedContract: true } - ) - const formData = latestFormData(submittedPkg) + const contract = await createAndSubmitTestContract(stateServer, 'FL', { + riskBasedContract: true, + }) - const createdQuestion = await createTestQuestion(cmsServer, formData.id) + const createdQuestion = await createTestQuestion(cmsServer, contract.id) await createTestQuestionResponse( stateServer, createdQuestion?.question.id ) - const statePrograms = findStatePrograms(formData.stateCode) - if (statePrograms instanceof Error) { - throw new Error( - `Unexpected error: No state programs found for stateCode ${formData.stateCode}` - ) - } - - const pkgName = packageName( - formData.stateCode, - formData.stateNumber, - formData.programIDs, - statePrograms - ) - + const contractName = + contract.packageSubmissions[0].contractRevision.contractName const stateAnalystsEmails = getTestStateAnalystsEmails( - formData.stateCode + contract.stateCode ) const cmsRecipientEmails = [ ...stateAnalystsEmails, @@ -193,17 +166,17 @@ describe('createQuestionResponse', () => { 5, // New response CMS email notification is the fifth email expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] New Responses for ${pkgName}` + `[LOCAL] New Responses for ${contractName}` ), sourceEmail: emailConfig.emailSource, toAddresses: expect.arrayContaining( Array.from(cmsRecipientEmails) ), bodyText: expect.stringContaining( - `The state submitted responses to OACT's questions about ${pkgName}` + `The state submitted responses to OACT's questions about ${contractName}` ), bodyHTML: expect.stringContaining( - `View submission Q&A` + `View submission Q&A` ), }) ) @@ -253,23 +226,13 @@ describe('createQuestionResponse', () => { await updateTestStateAssignments(cmsServer, 'FL', assignedUserIDs) const stateSubmission = await createAndSubmitTestContract(stateServer) - const question = ( await createTestQuestion(cmsServer, stateSubmission.id) ).question await createTestQuestionResponse(stateServer, question.id) - const currentRevision = - stateSubmission.packageSubmissions[0].contractRevision - - const programs = [defaultFloridaProgram()] - const name = packageName( - stateSubmission.stateCode, - stateSubmission.stateNumber, - currentRevision.formData.programIDs, - programs - ) - + const contractName = + stateSubmission.packageSubmissions[0].contractRevision.contractName const cmsEmails = [...config.devReviewTeamEmails, ...assignedUserEmails] // email subject line is correct for CMS email @@ -281,12 +244,12 @@ describe('createQuestionResponse', () => { 3, expect.objectContaining({ subject: expect.stringContaining( - `[LOCAL] New Responses for ${name}` + `[LOCAL] New Responses for ${contractName}` ), sourceEmail: config.emailSource, toAddresses: expect.arrayContaining(Array.from(cmsEmails)), bodyText: expect.stringContaining( - `The state submitted responses to DMCO's questions about ${name}` + `The state submitted responses to DMCO's questions about ${contractName}` ), bodyHTML: expect.stringContaining( `View submission Q&A` @@ -311,41 +274,29 @@ describe('createQuestionResponse', () => { emailer: mockEmailer, }) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) - const formData = latestFormData(submittedPkg) - - const createdQuestion = await createTestQuestion(cmsServer, formData.id) + const createdQuestion = await createTestQuestion(cmsServer, contract.id) await createTestQuestionResponse( stateServer, createdQuestion?.question.id ) - const statePrograms = findStatePrograms(formData.stateCode) + const statePrograms = findStatePrograms(contract.stateCode) if (statePrograms instanceof Error) { throw new Error( - `Unexpected error: No state programs found for stateCode ${formData.stateCode}` + `Unexpected error: No state programs found for stateCode ${contract.stateCode}` ) } - const pkgName = packageName( - formData.stateCode, - formData.stateNumber, - formData.programIDs, - statePrograms - ) - const currentRevision = submittedPkg.revisions[0].node.formDataProto - - const sub = base64ToDomain(currentRevision) - if (sub instanceof Error) { - throw sub - } - + const pkgName = + contract.packageSubmissions[0].contractRevision.contractName + const formData = + contract.packageSubmissions[0].contractRevision.formData const stateReceiverEmails = [ 'james@example.com', - ...sub.stateContacts.map((contact) => contact.email), + ...formData.stateContacts.map((contact) => contact.email), ] expect(mockEmailer.sendEmail).toHaveBeenNthCalledWith( @@ -362,7 +313,7 @@ describe('createQuestionResponse', () => { `${oactCMS.divisionAssignment} round 1 response was successfully submitted` ), bodyHTML: expect.stringContaining( - `View response` + `View response` ), }) ) diff --git a/services/app-api/src/resolvers/questionResponse/createQuestionResponse.ts b/services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.ts similarity index 97% rename from services/app-api/src/resolvers/questionResponse/createQuestionResponse.ts rename to services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.ts index 06891afedf..4706b643b0 100644 --- a/services/app-api/src/resolvers/questionResponse/createQuestionResponse.ts +++ b/services/app-api/src/resolvers/questionResponse/createContractQuestionResponse.ts @@ -14,12 +14,12 @@ import type { EmailParameterStore } from '../../parameterStore' import type { LDService } from '../../launchDarkly/launchDarkly' import type { StateCodeType } from '../../common-code/healthPlanFormDataType' -export function createQuestionResponseResolver( +export function createContractQuestionResponseResolver( store: Store, emailer: Emailer, emailParameterStore: EmailParameterStore, launchDarkly: LDService -): MutationResolvers['createQuestionResponse'] { +): MutationResolvers['createContractQuestionResponse'] { return async (_parent, { input }, context) => { const { user, ctx, tracer } = context const span = tracer?.startSpan('createQuestionResponse', {}, ctx) @@ -51,7 +51,7 @@ export function createQuestionResponseResolver( ...input, documents: docs, } - const createResponseResult = await store.insertQuestionResponse( + const createResponseResult = await store.insertContractQuestionResponse( inputFormatted, user ) diff --git a/services/app-api/src/resolvers/questionResponse/index.ts b/services/app-api/src/resolvers/questionResponse/index.ts index 763f956c79..221edaf5fe 100644 --- a/services/app-api/src/resolvers/questionResponse/index.ts +++ b/services/app-api/src/resolvers/questionResponse/index.ts @@ -1,5 +1,4 @@ -export { indexQuestionsResolver } from './indexQuestions' -export { createQuestionResolver } from './createQuestion' -export { createQuestionResponseResolver } from './createQuestionResponse' +export { createContractQuestionResolver } from './createContractQuestion' +export { createContractQuestionResponseResolver } from './createContractQuestionResponse' export { questionResponseDocumentResolver } from './questionResponseDocumentResolver' export { createRateQuestionResolver } from './createRateQuestion' diff --git a/services/app-api/src/resolvers/questionResponse/indexQuestions.test.ts b/services/app-api/src/resolvers/questionResponse/indexQuestions.test.ts deleted file mode 100644 index c7781f7efb..0000000000 --- a/services/app-api/src/resolvers/questionResponse/indexQuestions.test.ts +++ /dev/null @@ -1,248 +0,0 @@ -import INDEX_QUESTIONS from 'app-graphql/src/queries/indexQuestions.graphql' -import { - constructTestPostgresServer, - createAndSubmitTestHealthPlanPackage, - createTestQuestion, - createTestQuestionResponse, - indexTestQuestions, -} from '../../testHelpers/gqlHelpers' -import { assertAnError, assertAnErrorCode } from '../../testHelpers' -import { - createDBUsersWithFullData, - testCMSUser, -} from '../../testHelpers/userHelpers' -import { testS3Client } from '../../testHelpers/s3Helpers' - -describe('indexQuestions', () => { - const mockS3 = testS3Client() - - const dmcoCMSUser = testCMSUser({ - divisionAssignment: 'DMCO', - }) - const dmcpCMSUser = testCMSUser({ - divisionAssignment: 'DMCP', - }) - const oactCMSUser = testCMSUser({ - divisionAssignment: 'OACT', - }) - beforeAll(async () => { - //Inserting a new CMS user, with division assigned, in postgres in order to create the question to user relationship. - await createDBUsersWithFullData([dmcoCMSUser, dmcpCMSUser, oactCMSUser]) - }) - - it('returns package with questions and responses for each division', async () => { - const stateServer = await constructTestPostgresServer() - const dmcoCMSServer = await constructTestPostgresServer({ - context: { - user: dmcoCMSUser, - }, - s3Client: mockS3, - }) - const dmcpCMSServer = await constructTestPostgresServer({ - context: { - user: dmcpCMSUser, - }, - s3Client: mockS3, - }) - const oactCMServer = await constructTestPostgresServer({ - context: { - user: oactCMSUser, - }, - s3Client: mockS3, - }) - - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) - - const createdDMCOQuestion = await createTestQuestion( - dmcoCMSServer, - submittedPkg.id, - { - documents: [ - { - name: 'Test Question 1', - s3URL: 's3://bucketname/key/test11', - }, - ], - } - ) - - const responseToDMCO = await createTestQuestionResponse( - stateServer, - createdDMCOQuestion.question.id - ) - - const createdDMCPQuestion = await createTestQuestion( - dmcpCMSServer, - submittedPkg.id, - { - documents: [ - { - name: 'Test Question 2', - s3URL: 's3://bucketname/key/test12', - }, - ], - } - ) - - const responseToDMCP = await createTestQuestionResponse( - stateServer, - createdDMCPQuestion.question.id - ) - - const createdOACTQuestion = await createTestQuestion( - oactCMServer, - submittedPkg.id, - { - documents: [ - { - name: 'Test Question 3', - s3URL: 's3://bucketname/key/test13', - }, - ], - } - ) - - const responseToOACT = await createTestQuestionResponse( - stateServer, - createdOACTQuestion.question.id - ) - - const indexQuestionsResult = await indexTestQuestions( - stateServer, - submittedPkg.id - ) - - expect(indexQuestionsResult).toEqual( - expect.objectContaining({ - DMCOQuestions: expect.objectContaining({ - totalCount: 1, - edges: expect.arrayContaining([ - { - node: expect.objectContaining({ - id: expect.any(String), - createdAt: expect.any(Date), - contractID: submittedPkg.id, - division: 'DMCO', - documents: [ - { - name: 'Test Question 1', - s3URL: 's3://bucketname/key/test11', - downloadURL: expect.any(String), - }, - ], - addedBy: responseToDMCO.question.addedBy, - }), - }, - ]), - }), - DMCPQuestions: expect.objectContaining({ - totalCount: 1, - edges: [ - { - node: expect.objectContaining({ - id: expect.any(String), - createdAt: expect.any(Date), - contractID: submittedPkg.id, - division: 'DMCP', - documents: [ - { - name: 'Test Question 2', - s3URL: 's3://bucketname/key/test12', - downloadURL: expect.any(String), - }, - ], - addedBy: responseToDMCP.question.addedBy, - }), - }, - ], - }), - OACTQuestions: expect.objectContaining({ - totalCount: 1, - edges: [ - { - node: expect.objectContaining({ - id: expect.any(String), - createdAt: expect.any(Date), - contractID: submittedPkg.id, - division: 'OACT', - documents: [ - { - name: 'Test Question 3', - s3URL: 's3://bucketname/key/test13', - downloadURL: expect.any(String), - }, - ], - addedBy: responseToOACT.question.addedBy, - }), - }, - ], - }), - }) - ) - }) - it('returns an error if you are requesting for a different state (403)', async () => { - const stateServer = await constructTestPostgresServer({ - s3Client: mockS3, - }) - const otherStateServer = await constructTestPostgresServer({ - context: { - user: { - id: '4fed22c0-6d05-4bae-9e9a-b2345073ccf8', - stateCode: 'VA', - role: 'STATE_USER', - email: 'aang@va.gov', - familyName: 'Aang', - givenName: 'Aang', - }, - }, - s3Client: mockS3, - }) - const cmsServer = await constructTestPostgresServer({ - context: { - user: dmcoCMSUser, - }, - s3Client: mockS3, - }) - - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) - - await createTestQuestion(cmsServer, submittedPkg.id) - - const result = await otherStateServer.executeOperation({ - query: INDEX_QUESTIONS, - variables: { - input: { - contractID: submittedPkg.id, - }, - }, - }) - - expect(result.errors).toBeDefined() - expect(assertAnErrorCode(result)).toBe('FORBIDDEN') - expect(assertAnError(result).message).toBe( - 'User not authorized to fetch data from a different state' - ) - }) - it('returns an error if health plan package does not exist', async () => { - const server = await constructTestPostgresServer({ s3Client: mockS3 }) - - await createAndSubmitTestHealthPlanPackage(server) - - const result = await server.executeOperation({ - query: INDEX_QUESTIONS, - variables: { - input: { - contractID: 'invalid-pkg-id', - }, - }, - }) - - expect(result.errors).toBeDefined() - expect(assertAnErrorCode(result)).toBe('NOT_FOUND') - expect(assertAnError(result).message).toBe( - 'Issue finding a contract with id invalid-pkg-id. Message: Contract with id invalid-pkg-id does not exist' - ) - }) -}) diff --git a/services/app-api/src/resolvers/questionResponse/indexQuestions.ts b/services/app-api/src/resolvers/questionResponse/indexQuestions.ts deleted file mode 100644 index c2303bcbfd..0000000000 --- a/services/app-api/src/resolvers/questionResponse/indexQuestions.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { isStateUser } from '../../domain-models' -import type { QueryResolvers } from '../../gen/gqlServer' -import { NotFoundError } from '../../postgres' -import type { Store } from '../../postgres' -import { logError } from '../../logger' -import { setErrorAttributesOnActiveSpan } from '../attributeHelper' -import { ForbiddenError, UserInputError } from 'apollo-server-lambda' -import { GraphQLError } from 'graphql' -import { convertToIndexQuestionsPayload } from '../../postgres/questionResponse' - -export function indexQuestionsResolver( - store: Store -): QueryResolvers['indexQuestions'] { - return async (_parent, { input }, context) => { - const { user, ctx, tracer } = context - const span = tracer?.startSpan('indexQuestions', {}, ctx) - - const contractResult = await store.findContractWithHistory( - input.contractID - ) - if (contractResult instanceof Error) { - if (contractResult instanceof NotFoundError) { - const errMessage = `Issue finding a contract with id ${input.contractID}. Message: Contract with id ${input.contractID} does not exist` - logError('indexQuestion', errMessage) - setErrorAttributesOnActiveSpan(errMessage, span) - throw new GraphQLError(errMessage, { - extensions: { code: 'NOT_FOUND' }, - }) - } - const errMessage = `Issue finding a package. Message: ${contractResult.message}` - logError('indexQuestion', errMessage) - setErrorAttributesOnActiveSpan(errMessage, span) - throw new UserInputError(errMessage) - } - - const contract = contractResult - // State users can only view if the state matches - if (isStateUser(user) && contract.stateCode !== user.stateCode) { - const errMessage = - 'User not authorized to fetch data from a different state' - logError('indexQuestions', errMessage) - setErrorAttributesOnActiveSpan(errMessage, span) - throw new ForbiddenError(errMessage) - } - - const questionResult = await store.findAllQuestionsByContract( - input.contractID - ) - - if (questionResult instanceof Error) { - const errMessage = `Issue finding questions. Message: ${questionResult.message}` - logError('indexQuestions', errMessage) - setErrorAttributesOnActiveSpan(errMessage, span) - throw new Error(errMessage) - } - - const indexQuestionPayload = - convertToIndexQuestionsPayload(questionResult) - - return indexQuestionPayload - } -} diff --git a/services/app-api/src/resolvers/questionResponse/questionResponseDocumentResolver.test.ts b/services/app-api/src/resolvers/questionResponse/questionResponseDocumentResolver.test.ts index 54461f9d29..97c7c8c987 100644 --- a/services/app-api/src/resolvers/questionResponse/questionResponseDocumentResolver.test.ts +++ b/services/app-api/src/resolvers/questionResponse/questionResponseDocumentResolver.test.ts @@ -1,15 +1,17 @@ import { constructTestPostgresServer, - createAndSubmitTestHealthPlanPackage, createTestQuestion, createTestQuestionResponse, - indexTestQuestions, } from '../../testHelpers/gqlHelpers' import { testCMSUser, createDBUsersWithFullData, } from '../../testHelpers/userHelpers' import { testS3Client } from '../../testHelpers/s3Helpers' +import { + createAndSubmitTestContract, + fetchTestContractWithQuestions, +} from '../../testHelpers' describe(`questionResponseDocumentResolver`, () => { const mockS3 = testS3Client() @@ -48,12 +50,11 @@ describe(`questionResponseDocumentResolver`, () => { s3Client: mockS3, }) - const submittedPkg = - await createAndSubmitTestHealthPlanPackage(stateServer) + const contract = await createAndSubmitTestContract(stateServer) const createdDMCOQuestion = await createTestQuestion( dmcoCMSServer, - submittedPkg.id, + contract.id, { documents: [ { @@ -63,15 +64,13 @@ describe(`questionResponseDocumentResolver`, () => { ], } ) - const responseToDMCO = await createTestQuestionResponse( stateServer, createdDMCOQuestion.question.id ) - const createdDMCPQuestion = await createTestQuestion( dmcpCMSServer, - submittedPkg.id, + contract.id, { documents: [ { @@ -81,15 +80,13 @@ describe(`questionResponseDocumentResolver`, () => { ], } ) - const responseToDMCP = await createTestQuestionResponse( stateServer, createdDMCPQuestion.question.id ) - const createdOACTQuestion = await createTestQuestion( oactCMServer, - submittedPkg.id, + contract.id, { documents: [ { @@ -99,16 +96,15 @@ describe(`questionResponseDocumentResolver`, () => { ], } ) - const responseToOACT = await createTestQuestionResponse( stateServer, createdOACTQuestion.question.id ) - - const indexQuestionsResult = await indexTestQuestions( + const contractWithQuestions = await fetchTestContractWithQuestions( stateServer, - submittedPkg.id + contract.id ) + const indexQuestionsResult = contractWithQuestions.questions expect(indexQuestionsResult).toEqual( expect.objectContaining({ @@ -119,7 +115,7 @@ describe(`questionResponseDocumentResolver`, () => { node: expect.objectContaining({ id: expect.any(String), createdAt: expect.any(Date), - contractID: submittedPkg.id, + contractID: contract.id, division: 'DMCO', documents: [ { @@ -140,7 +136,7 @@ describe(`questionResponseDocumentResolver`, () => { node: expect.objectContaining({ id: expect.any(String), createdAt: expect.any(Date), - contractID: submittedPkg.id, + contractID: contract.id, division: 'DMCP', documents: [ { @@ -161,7 +157,7 @@ describe(`questionResponseDocumentResolver`, () => { node: expect.objectContaining({ id: expect.any(String), createdAt: expect.any(Date), - contractID: submittedPkg.id, + contractID: contract.id, division: 'OACT', documents: [ { diff --git a/services/app-api/src/testHelpers/emailerHelpers.ts b/services/app-api/src/testHelpers/emailerHelpers.ts index 32f3c151f1..c9e7fe34a3 100644 --- a/services/app-api/src/testHelpers/emailerHelpers.ts +++ b/services/app-api/src/testHelpers/emailerHelpers.ts @@ -7,7 +7,7 @@ import type { } from '../common-code/healthPlanFormDataType' import type { ContractRevisionType, - Question, + ContractQuestionType, RatePackageSubmissionType, RateRevisionType, RateType, @@ -684,9 +684,9 @@ const mockContractAmendmentFormData = ( } const mockQuestionAndResponses = ( - questionData?: Partial -): Question => { - const question: Question = { + questionData?: Partial +): ContractQuestionType => { + const question: ContractQuestionType = { id: `test-question-id-1`, contractID: 'contract-id-test', createdAt: new Date('01/01/2024'), diff --git a/services/app-api/src/testHelpers/gqlContractHelpers.ts b/services/app-api/src/testHelpers/gqlContractHelpers.ts index 2579442f1e..4a57a4af93 100644 --- a/services/app-api/src/testHelpers/gqlContractHelpers.ts +++ b/services/app-api/src/testHelpers/gqlContractHelpers.ts @@ -32,6 +32,7 @@ import type { ContractFormDataType } from '../domain-models' import type { CreateHealthPlanPackageInput } from '../gen/gqlServer' import CREATE_CONTRACT from 'app-graphql/src/mutations/createContract.graphql' import { mockGqlContractDraftRevisionFormDataInput } from './gqlContractInputMocks' +import FETCH_CONTRACT_WITH_QUESTIONS from '*.graphql' const createAndSubmitTestContract = async ( server: ApolloServer, @@ -154,6 +155,32 @@ async function fetchTestContract( return result.data.fetchContract.contract } +const fetchTestContractWithQuestions = async ( + server: ApolloServer, + contractID: string +): Promise => { + const result = await server.executeOperation({ + query: FETCH_CONTRACT_WITH_QUESTIONS, + variables: { + input: { + contractID: contractID, + }, + }, + }) + + if (result.errors) { + throw new Error( + `fetchTestContractWithQuestions query failed with errors ${result.errors}` + ) + } + + if (!result.data) { + throw new Error('fetchTestContractWithQuestions returned nothing') + } + + return result.data.fetchContract.contract +} + async function updateTestContractToReplaceRate( server: ApolloServer, args: { @@ -410,6 +437,7 @@ export { unlockTestContract, createAndSubmitTestContract, fetchTestContract, + fetchTestContractWithQuestions, createAndUpdateTestContractWithoutRates, createAndUpdateTestContractWithRate, createAndSubmitTestContractWithRate, diff --git a/services/app-api/src/testHelpers/gqlHelpers.ts b/services/app-api/src/testHelpers/gqlHelpers.ts index e479deb610..b0f641cb1e 100644 --- a/services/app-api/src/testHelpers/gqlHelpers.ts +++ b/services/app-api/src/testHelpers/gqlHelpers.ts @@ -4,9 +4,8 @@ import SUBMIT_HEALTH_PLAN_PACKAGE from 'app-graphql/src/mutations/submitHealthPl import UNLOCK_HEALTH_PLAN_PACKAGE from 'app-graphql/src/mutations/unlockHealthPlanPackage.graphql' import FETCH_HEALTH_PLAN_PACKAGE from 'app-graphql/src/queries/fetchHealthPlanPackage.graphql' import UPDATE_HEALTH_PLAN_FORM_DATA from 'app-graphql/src/mutations/updateHealthPlanFormData.graphql' -import CREATE_QUESTION from 'app-graphql/src/mutations/createQuestion.graphql' -import INDEX_QUESTIONS from 'app-graphql/src/queries/indexQuestions.graphql' -import CREATE_QUESTION_RESPONSE from 'app-graphql/src/mutations/createQuestionResponse.graphql' +import CREATE_CONTRACT_QUESTION from 'app-graphql/src/mutations/createContractQuestion.graphql' +import CREATE_CONTRACT_QUESTION_RESPONSE from 'app-graphql/src/mutations/createContractQuestionResponse.graphql' import UPDATE_STATE_ASSIGNMENTS_BY_STATE from 'app-graphql/src/mutations/updateStateAssignmentsByState.graphql' import CREATE_RATE_QUESTION from 'app-graphql/src/mutations/createRateQuestion.graphql' import typeDefs from 'app-graphql/src/schema.graphql' @@ -16,7 +15,7 @@ import type { StateCodeType, } from '../common-code/healthPlanFormDataType' import type { - CreateQuestionInput, + CreateContractQuestionInput, InsertQuestionResponseArgs, ProgramType, CreateRateQuestionInputType, @@ -26,9 +25,8 @@ import { newLocalEmailer } from '../emailer' import type { CreateHealthPlanPackageInput, HealthPlanPackage, - CreateQuestionResponsePayload, - CreateQuestionPayload, - IndexQuestionsPayload, + CreateContractQuestionResponsePayload, + CreateContractQuestionPayload, UpdateStateAssignmentsByStatePayload, } from '../gen/gqlServer' import type { Context } from '../handlers/apollo_gql' @@ -420,8 +418,8 @@ const fetchTestHealthPlanPackageById = async ( const createTestQuestion = async ( server: ApolloServer, contractID: string, - questionData?: Omit -): Promise => { + questionData?: Omit +): Promise => { const question = questionData || { documents: [ { @@ -431,7 +429,7 @@ const createTestQuestion = async ( ], } const createdQuestion = await server.executeOperation({ - query: CREATE_QUESTION, + query: CREATE_CONTRACT_QUESTION, variables: { input: { contractID, @@ -449,7 +447,7 @@ const createTestQuestion = async ( throw new Error('createTestQuestion returned nothing') } - return createdQuestion.data.createQuestion + return createdQuestion.data.createContractQuestion } const createTestRateQuestion = async ( @@ -476,36 +474,11 @@ const createTestRateQuestion = async ( }) } -const indexTestQuestions = async ( - server: ApolloServer, - contractID: string -): Promise => { - const indexQuestionsResult = await server.executeOperation({ - query: INDEX_QUESTIONS, - variables: { - input: { - contractID, - }, - }, - }) - - if (indexQuestionsResult.errors) - throw new Error( - `indexTestQuestions query failed with errors ${indexQuestionsResult.errors}` - ) - - if (!indexQuestionsResult.data) { - throw new Error('indexTestQuestions returned nothing') - } - - return indexQuestionsResult.data.indexQuestions -} - const createTestQuestionResponse = async ( server: ApolloServer, questionID: string, responseData?: Omit -): Promise => { +): Promise => { const response = responseData || { documents: [ { @@ -515,7 +488,7 @@ const createTestQuestionResponse = async ( ], } const createdResponse = await server.executeOperation({ - query: CREATE_QUESTION_RESPONSE, + query: CREATE_CONTRACT_QUESTION_RESPONSE, variables: { input: { ...response, @@ -533,7 +506,7 @@ const createTestQuestionResponse = async ( throw new Error('createTestQuestionResponse returned nothing') } - return createdResponse.data.createQuestionResponse + return createdResponse.data.createContractQuestionResponse } const updateTestStateAssignments = async ( @@ -577,7 +550,6 @@ export { defaultFloridaProgram, defaultFloridaRateProgram, createTestQuestion, - indexTestQuestions, createTestQuestionResponse, updateTestHealthPlanPackage, updateTestStateAssignments, diff --git a/services/app-api/src/testHelpers/index.ts b/services/app-api/src/testHelpers/index.ts index 063f0e9fd8..b8eb794009 100644 --- a/services/app-api/src/testHelpers/index.ts +++ b/services/app-api/src/testHelpers/index.ts @@ -35,6 +35,7 @@ export { fetchTestContract, updateTestContractDraftRevision, createTestContract, + fetchTestContractWithQuestions, } from './gqlContractHelpers' export { diff --git a/services/app-api/src/testHelpers/storeHelpers.ts b/services/app-api/src/testHelpers/storeHelpers.ts index 28cb9ec93e..64652ec317 100644 --- a/services/app-api/src/testHelpers/storeHelpers.ts +++ b/services/app-api/src/testHelpers/storeHelpers.ts @@ -69,13 +69,13 @@ function mockStoreThatErrors(): Store { updateCmsUserProperties: async (_ID, _State) => { return genericError }, - insertQuestion: async (_ID) => { + insertContractQuestion: async (_ID) => { return genericError }, findAllQuestionsByContract: async (_pkgID) => { return genericError }, - insertQuestionResponse: async (_ID) => { + insertContractQuestionResponse: async (_ID) => { return genericError }, insertRateQuestion: async (_ID) => { diff --git a/services/app-graphql/src/mutations/createQuestion.graphql b/services/app-graphql/src/mutations/createContractQuestion.graphql similarity index 88% rename from services/app-graphql/src/mutations/createQuestion.graphql rename to services/app-graphql/src/mutations/createContractQuestion.graphql index ee839ea5ff..7e9eebf66a 100644 --- a/services/app-graphql/src/mutations/createQuestion.graphql +++ b/services/app-graphql/src/mutations/createContractQuestion.graphql @@ -1,5 +1,5 @@ -mutation createQuestion($input: CreateQuestionInput!) { - createQuestion(input: $input) { +mutation createContractQuestion($input: CreateContractQuestionInput!) { + createContractQuestion(input: $input) { question { id contractID diff --git a/services/app-graphql/src/mutations/createQuestionResponse.graphql b/services/app-graphql/src/mutations/createContractQuestionResponse.graphql similarity index 92% rename from services/app-graphql/src/mutations/createQuestionResponse.graphql rename to services/app-graphql/src/mutations/createContractQuestionResponse.graphql index f5c6d9460c..d3fd00c2b7 100644 --- a/services/app-graphql/src/mutations/createQuestionResponse.graphql +++ b/services/app-graphql/src/mutations/createContractQuestionResponse.graphql @@ -1,5 +1,5 @@ -mutation createQuestionResponse($input: CreateQuestionResponseInput!) { - createQuestionResponse(input: $input) { +mutation createContractQuestionResponse($input: CreateContractQuestionResponseInput!) { + createContractQuestionResponse(input: $input) { question { id contractID diff --git a/services/app-graphql/src/queries/fetchContractWithQuestions.graphql b/services/app-graphql/src/queries/fetchContractWithQuestions.graphql index 3636ad3e27..31edd8a750 100644 --- a/services/app-graphql/src/queries/fetchContractWithQuestions.graphql +++ b/services/app-graphql/src/queries/fetchContractWithQuestions.graphql @@ -275,7 +275,7 @@ fragment updateInformationFields on UpdateInformation { updatedReason } -fragment questionEdgeFragment on QuestionEdge { +fragment questionEdgeFragment on ContractQuestionEdge { node { id contractID diff --git a/services/app-graphql/src/queries/fetchHealthPlanPackageWithQuestions.graphql b/services/app-graphql/src/queries/fetchHealthPlanPackageWithQuestions.graphql index b16ecc593a..8049189b43 100644 --- a/services/app-graphql/src/queries/fetchHealthPlanPackageWithQuestions.graphql +++ b/services/app-graphql/src/queries/fetchHealthPlanPackageWithQuestions.graphql @@ -1,4 +1,4 @@ -fragment questionEdgeFragment on QuestionEdge { +fragment questionEdgeFragment on ContractQuestionEdge { node { id contractID diff --git a/services/app-graphql/src/queries/indexQuestions.graphql b/services/app-graphql/src/queries/indexQuestions.graphql deleted file mode 100644 index db8a806239..0000000000 --- a/services/app-graphql/src/queries/indexQuestions.graphql +++ /dev/null @@ -1,100 +0,0 @@ -fragment questionEdgeFragmentIndexQuestions on QuestionEdge { - node { - id - contractID - createdAt - addedBy { - ... on CMSUser { - id - email - role - familyName - givenName - stateAssignments { - code - name - programs { - id - name - fullName - isRateProgram - } - } - divisionAssignment - } - ... on CMSApproverUser { - id - email - role - familyName - givenName - stateAssignments { - code - name - programs { - id - name - fullName - isRateProgram - } - } - divisionAssignment - } - } - division - documents { - s3URL - name - downloadURL - } - responses { - id - questionID - createdAt - addedBy { - id - role - email - givenName - familyName - state { - code - name - programs { - id - name - fullName - isRateProgram - } - } - } - documents { - name - s3URL - downloadURL - } - } - } -} -query indexQuestions($input: IndexQuestionsInput!) { - indexQuestions(input: $input) { - DMCOQuestions { - edges { - ...questionEdgeFragmentIndexQuestions - } - totalCount - } - DMCPQuestions { - edges { - ...questionEdgeFragmentIndexQuestions - } - totalCount - } - OACTQuestions { - edges { - ...questionEdgeFragmentIndexQuestions - } - totalCount - } - } -} diff --git a/services/app-graphql/src/schema.graphql b/services/app-graphql/src/schema.graphql index d77d11e09c..d75135f3a4 100644 --- a/services/app-graphql/src/schema.graphql +++ b/services/app-graphql/src/schema.graphql @@ -55,18 +55,6 @@ type Query { """ indexUsers: IndexUsersPayload! - """ - indexQuestions returns three arrays of Questions for the given HealthPlanPackage, one array - for each division that asks questions. - - It can be called by CMS or State Users - - Errors: - - ForbiddenError: A State users attempts to request Questions for a HPP not in their state - - UserInputError: pkgID not found - """ - indexQuestions(input: IndexQuestionsInput!): IndexQuestionsPayload - """ indexRates returns an array of rates with their revisions and related contracts Only rates with at least one submitted revision are returned @@ -100,17 +88,6 @@ type Query { - NotFoundError: contract for contractID not found in database """ fetchContract(input: FetchContractInput!): FetchContractPayload! - """ - fetchContractWithQuestions returns a single contract, linked to revisions and related rates and questionsList - given a contractID - - It can be called by CMS or State users - - Errors: - - ForbiddenError: A State user requests a contract that belongs to another state - - NotFoundError: contract for contractID not found in database - """ - fetchContractWithQuestions(input: FetchContractWithQuestionsInput!): FetchContractWithQuestionsPayload! """ fetchMcReviewSettings returns settings for the MC review app @@ -374,7 +351,7 @@ type Mutation { updateStateAssignmentsByState(input: UpdateStateAssignmentsByStateInput!): UpdateStateAssignmentsByStatePayload! """ - createQuestion creates a new Question for the given HealthPlanPackage + createContractQuestion creates a new question for the given Contract A CMS User can add text to a note field and append a document to their question They can also specify a due date, and specify rate IDs that are associated with the question @@ -385,12 +362,12 @@ type Mutation { - A non CMSUser called this - A CMS user with unassigned division - UserInputError - - A package cannot be found with the given `pkgID` - - The package is in the DRAFT state + - A package cannot be found with the given `contractID` + - The contract is in the DRAFT state - The due date is in the past - The rateIDs are not associated with the package """ - createQuestion(input: CreateQuestionInput!): CreateQuestionPayload! + createContractQuestion(input: CreateContractQuestionInput!): CreateContractQuestionPayload! # """ # updateQuestion updates a Question for the given HealthPlanPackage @@ -408,7 +385,7 @@ type Mutation { # updateQuestion(input: UpdateQuestionInput!): UpdateQuestionPayload! """ - createQuestionResponse creates a new QuestionResponse for the given Question + createContractQuestionResponse creates a new response for the given question A State User can add text to a note field and append a document to their response This can only be called by a StateUser @@ -419,9 +396,9 @@ type Mutation { - UserInputError - A Question cannot be found given `questionID` """ - createQuestionResponse( - input: CreateQuestionResponseInput! - ): CreateQuestionResponsePayload! + createContractQuestionResponse( + input: CreateContractQuestionResponseInput! + ): CreateContractQuestionResponsePayload! """ createRateQuestion creates a new Question for the given rate @@ -633,19 +610,13 @@ type IndexContractsPayload { edges: [ContractEdge!]! } - -input IndexQuestionsInput { - "The ID of the package for which to fetch associated questions" - contractID: ID! -} - -type IndexQuestionsPayload { +type IndexContractQuestionsPayload { "Questions for a given submission that were asked by DMCO within CMS" - DMCOQuestions: QuestionList! + DMCOQuestions: ContractQuestionList! "Questions for a given submission that were asked by DMCP within CMS" - DMCPQuestions: QuestionList! + DMCPQuestions: ContractQuestionList! "Questions for a given submission that were asked by OACT within CMS" - OACTQuestions: QuestionList! + OACTQuestions: ContractQuestionList! } type IndexRateQuestionsPayload { @@ -657,9 +628,9 @@ type IndexRateQuestionsPayload { OACTQuestions: RateQuestionList! } -type QuestionList { +type ContractQuestionList { totalCount: Int - edges: [QuestionEdge!]! + edges: [ContractQuestionEdge!]! } type RateQuestionList { @@ -667,8 +638,8 @@ type RateQuestionList { edges: [RateQuestionEdge!]! } -type QuestionEdge { - node: Question! +type ContractQuestionEdge { + node: ContractQuestion! } type RateQuestionEdge { @@ -684,7 +655,7 @@ input DocumentInput { downloadURL: String } -input CreateQuestionInput { +input CreateContractQuestionInput { "The ID of the package for which to create a question" contractID: ID! "A list of documents to attach to the question" @@ -697,9 +668,9 @@ input CreateQuestionInput { rateIDs: [String!] } -type CreateQuestionPayload { +type CreateContractQuestionPayload { "The newly created Question" - question: Question! + question: ContractQuestion! } input CreateRateQuestionInput { @@ -730,7 +701,7 @@ type CreateRateQuestionPayload { # question: Question! #} -input CreateQuestionResponseInput { +input CreateContractQuestionResponseInput { "The ID of the question for which to create a response" questionID: ID! "A list of documents to attach to the response" @@ -739,9 +710,9 @@ input CreateQuestionResponseInput { noteText: String } -type CreateQuestionResponsePayload { +type CreateContractQuestionResponsePayload { "Question with newly created response" - question: Question! + question: ContractQuestion! } type UserEdge { @@ -1030,7 +1001,7 @@ type HealthPlanPackage { for the package and contains the full data from when it was submitted """ revisions: [HealthPlanRevisionEdge!]! - questions: IndexQuestionsPayload + questions: IndexContractQuestionsPayload } type UpdatedBy { @@ -1113,11 +1084,11 @@ type Document { } """ -Question is a question sent by CMS to the States for a response, associated with a single package. -CMS may upload one or more documents full of questions to a single Question. States submit a +ContractQuestion is a question sent by CMS to the States for a response, associated with a single contract. +CMS may upload one or more documents full of questions to a single ContractQuestion. States submit a QuestionResponse with documents that answer the questions posed by CMS. """ -type Question { +type ContractQuestion { id: ID! contractID: ID! createdAt: DateTime! @@ -1131,21 +1102,8 @@ type Question { responses: [QuestionResponse!]! } -#""" -#QuestionResponse is a response by a StateUser to a Question sent by CMS. States may upload one or -#more documents full of responses to a single QuestionResponse, in addition to a text note. -#""" -type QuestionResponse { - id: ID! - questionID: ID! - createdAt: DateTime! - addedBy: StateUser! - documents: [Document!]! - # noteText: String -} - """ -Question is a question sent by CMS to the States for a response, associated with a single rate. +RateQuestion is a question sent by CMS to the States for a response, associated with a single rate. CMS may upload one or more documents full of questions to a single Question. States submit a QuestionResponse with documents that answer the questions posed by CMS. """ @@ -1163,6 +1121,19 @@ type RateQuestion { responses: [QuestionResponse!]! } +""" +QuestionResponse are responses to Rate or Contract questions, the graphql type has no differentiation between responses +for both questions types. +""" +type QuestionResponse { + id: ID! + questionID: ID! + createdAt: DateTime! + addedBy: StateUser! + documents: [Document!]! + # noteText: String +} + type EmailConfiguration { stage: String! baseUrl: String! @@ -1790,7 +1761,7 @@ type Contract { to the question submitted by the State. DRAFT contracts will not have questions, only contracts that have been submitted , unlocked, or resubmitted. The array is in descending order by createdAt. """ - questions: IndexQuestionsPayload + questions: IndexContractQuestionsPayload } """ @@ -1873,21 +1844,10 @@ type FetchContractPayload { contract: Contract! } -type FetchContractWithQuestionsPayload { - """ - A rate that include contract and rate revisions - """ - contract: Contract! -} - input FetchContractInput { contractID: ID! } -input FetchContractWithQuestionsInput { - contractID: ID! -} - type UnlockRatePayload { rate: Rate! } diff --git a/services/app-web/src/gqlHelpers/index.ts b/services/app-web/src/gqlHelpers/index.ts index 964c0e1bfd..c5f2f9426d 100644 --- a/services/app-web/src/gqlHelpers/index.ts +++ b/services/app-web/src/gqlHelpers/index.ts @@ -11,7 +11,6 @@ import { useFetchHealthPlanPackageWrapper, useFetchHealthPlanPackageWithQuestionsWrapper, } from './fetchHealthPlanPackageWrapper' -import { useIndexQuestionsQueryWrapper } from './useIndexQuestionsQueryWrapper' import { hasCMSUserPermissions, hasAdminUserPermissions, getUpdatedByDisplayName } from './userHelpers' import { updateDivisionAssignment } from './updateDivisionAssignment' @@ -31,7 +30,6 @@ export { useFetchHealthPlanPackageWrapper, unlockMutationWrapper, submitMutationWrapper, - useIndexQuestionsQueryWrapper, useFetchHealthPlanPackageWithQuestionsWrapper, hasCMSUserPermissions, hasAdminUserPermissions, diff --git a/services/app-web/src/gqlHelpers/mutationWrappersForUserFriendlyErrors.ts b/services/app-web/src/gqlHelpers/mutationWrappersForUserFriendlyErrors.ts index 7d4c5bb9fe..9d72e51145 100644 --- a/services/app-web/src/gqlHelpers/mutationWrappersForUserFriendlyErrors.ts +++ b/services/app-web/src/gqlHelpers/mutationWrappersForUserFriendlyErrors.ts @@ -1,21 +1,19 @@ import { - CreateQuestionMutationFn, + CreateContractQuestionMutationFn, HealthPlanPackage, SubmitHealthPlanPackageMutationFn, UnlockHealthPlanPackageMutationFn, UnlockContractMutationFn, - FetchHealthPlanPackageWithQuestionsQuery, FetchContractWithQuestionsQuery, FetchContractWithQuestionsDocument, - FetchHealthPlanPackageWithQuestionsDocument, - IndexQuestionsPayload, - CreateQuestionMutation, - CreateQuestionResponseMutationFn, - CreateQuestionResponseMutation, - Question, + IndexContractQuestionsPayload, + CreateContractQuestionMutation, + CreateContractQuestionResponseMutationFn, + CreateContractQuestionResponseMutation, + ContractQuestion, Division, - CreateQuestionInput, - CreateQuestionResponseInput, + CreateContractQuestionInput, + CreateContractQuestionResponseInput, SubmitContractMutationFn, Contract, UnlockedContract, @@ -310,15 +308,15 @@ export async function updateStateAssignmentsWrapper( * cache.evict() to force a refetch, but would then cause the loading UI to show. **/ export const createQuestionWrapper = async ( - createQuestion: CreateQuestionMutationFn, - input: CreateQuestionInput -): Promise => { + createQuestion: CreateContractQuestionMutationFn, + input: CreateContractQuestionInput +): Promise => { try { const result = await createQuestion({ variables: { input }, update(cache, { data }) { if (data) { - const newQuestion = data.createQuestion.question as Question + const newQuestion = data.createContractQuestion.question as ContractQuestion const result = cache.readQuery( { @@ -338,7 +336,7 @@ export const createQuestionWrapper = async ( divisionToIndexQuestionDivision( newQuestion.division ) - const questions = contract.questions as IndexQuestionsPayload + const questions = contract.questions as IndexContractQuestionsPayload const divisionQuestions = questions[indexQuestionDivision] @@ -359,7 +357,7 @@ export const createQuestionWrapper = async ( edges: [ { __typename: - 'QuestionEdge', + 'ContractQuestionEdge', node: { ...newQuestion, responses: [], @@ -379,7 +377,7 @@ export const createQuestionWrapper = async ( onQueryUpdated: () => true, }) - if (result.data?.createQuestion) { + if (result.data?.createContractQuestion) { return result.data } else { recordJSException( @@ -393,18 +391,18 @@ export const createQuestionWrapper = async ( } export const createResponseWrapper = async ( - createResponse: CreateQuestionResponseMutationFn, + createResponse: CreateContractQuestionResponseMutationFn, contractID: string, - input: CreateQuestionResponseInput, + input: CreateContractQuestionResponseInput, division: Division -): Promise => { +): Promise => { try { const result = await createResponse({ variables: { input }, update(cache, { data }) { if (data) { const newResponse = - data.createQuestionResponse.question.responses[0] + data.createContractQuestionResponse.question.responses[0] const result = cache.readQuery( { @@ -419,7 +417,7 @@ export const createResponseWrapper = async ( const contract = result?.fetchContract.contract if (contract) { - const questions = contract.questions as IndexQuestionsPayload + const questions = contract.questions as IndexContractQuestionsPayload const indexQuestionDivision = divisionToIndexQuestionDivision(division) const divisionQuestions = @@ -438,7 +436,7 @@ export const createResponseWrapper = async ( newResponse.questionID ) { return { - __typename: 'QuestionEdge', + __typename: 'ContractQuestionEdge', node: { ...edge.node, responses: [ @@ -470,7 +468,7 @@ export const createResponseWrapper = async ( onQueryUpdated: () => true, }) - if (result.data?.createQuestionResponse) { + if (result.data?.createContractQuestionResponse) { return result.data } else { recordJSException( diff --git a/services/app-web/src/gqlHelpers/useIndexQuestionsQueryWrapper.ts b/services/app-web/src/gqlHelpers/useIndexQuestionsQueryWrapper.ts deleted file mode 100644 index b4dea6219d..0000000000 --- a/services/app-web/src/gqlHelpers/useIndexQuestionsQueryWrapper.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { wrapApolloResult, WrappedApolloResultType } from './apolloQueryWrapper' -import { useIndexQuestionsQuery } from '../gen/gqlClient' - -type WrappedFetchResultType = WrappedApolloResultType< - ReturnType -> - -function useIndexQuestionsQueryWrapper(id: string): WrappedFetchResultType { - const results = wrapApolloResult( - useIndexQuestionsQuery({ - variables: { - input: { - contractID: id, - }, - }, - }) - ) - - const result = results.result - - return { - ...results, - result: result, - } -} - -export { useIndexQuestionsQueryWrapper } diff --git a/services/app-web/src/pages/QuestionResponse/QuestionResponse.test.tsx b/services/app-web/src/pages/QuestionResponse/QuestionResponse.test.tsx index 9556550798..744a6fc46a 100644 --- a/services/app-web/src/pages/QuestionResponse/QuestionResponse.test.tsx +++ b/services/app-web/src/pages/QuestionResponse/QuestionResponse.test.tsx @@ -13,7 +13,7 @@ import { mockContractPackageSubmittedWithQuestions, mockContractPackageDraft, } from '../../testHelpers/apolloMocks' -import { IndexQuestionsPayload } from '../../gen/gqlClient' +import { IndexContractQuestionsPayload } from '../../gen/gqlClient' import { useStringConstants } from '../../hooks/useStringConstants' describe('QuestionResponse', () => { @@ -284,7 +284,7 @@ describe('QuestionResponse', () => { expect(qaSections[2]).toHaveTextContent('Asked by DMCP') }) it('does not render the divisions question if no question exist', async () => { - const mockQuestionWithNoOACT: IndexQuestionsPayload = { + const mockQuestionWithNoOACT: IndexContractQuestionsPayload = { ...mockQuestionsPayload('15'), OACTQuestions: { totalCount: 0, @@ -349,7 +349,7 @@ describe('QuestionResponse', () => { expect(qaSections[1]).toHaveTextContent('Asked by DMCP') }) it('renders no questions have been submitted yet text', async () => { - const mockQuestionWithNoOACT: IndexQuestionsPayload = { + const mockQuestionWithNoOACT: IndexContractQuestionsPayload = { DMCOQuestions: { totalCount: 0, edges: [], diff --git a/services/app-web/src/pages/QuestionResponse/QuestionResponse.tsx b/services/app-web/src/pages/QuestionResponse/QuestionResponse.tsx index 46f57c4f85..1a98e8dcb0 100644 --- a/services/app-web/src/pages/QuestionResponse/QuestionResponse.tsx +++ b/services/app-web/src/pages/QuestionResponse/QuestionResponse.tsx @@ -11,7 +11,7 @@ import { UserAccountWarningBanner, } from '../../components/Banner' import { QATable, QuestionData, Division } from './QATable/QATable' -import { CmsUser, QuestionEdge, StateUser } from '../../gen/gqlClient' +import { CmsUser, ContractQuestionEdge, StateUser } from '../../gen/gqlClient' import { GenericErrorPage } from '../Errors/GenericErrorPage' import { hasCMSUserPermissions } from '../../gqlHelpers' import { ContactSupportLink } from '../../components/ErrorAlert/ContactSupportLink' @@ -21,7 +21,7 @@ type divisionQuestionDataType = { questions: QuestionData[] } -const extractQuestions = (edges?: QuestionEdge[]): QuestionData[] => { +const extractQuestions = (edges?: ContractQuestionEdge[]): QuestionData[] => { if (!edges) { return [] } diff --git a/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.test.tsx b/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.test.tsx index be850e3937..5fc29be0b6 100644 --- a/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.test.tsx +++ b/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.test.tsx @@ -21,8 +21,8 @@ import { mockContractPackageSubmitted, } from '../../../testHelpers/apolloMocks' import { - createQuestionNetworkFailure, - createQuestionSuccess, + createContractQuestionNetworkFailure, + createContractQuestionSuccess, } from '../../../testHelpers/apolloMocks/questionResponseGQLMock' import { SubmissionSideNav } from '../../SubmissionSideNav' import { Location } from 'react-router-dom' @@ -176,7 +176,7 @@ describe('UploadQuestions', () => { id: '15', }, }), - createQuestionSuccess({ + createContractQuestionSuccess({ contractID: '15', documents: [ { @@ -441,7 +441,7 @@ describe('UploadQuestions', () => { id: '15', }, }), - createQuestionNetworkFailure({ + createContractQuestionNetworkFailure({ contractID: '15', documents: [ { diff --git a/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.tsx b/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.tsx index 301034ab50..5167bb83e6 100644 --- a/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.tsx +++ b/services/app-web/src/pages/QuestionResponse/UploadQuestions/UploadQuestions.tsx @@ -19,8 +19,8 @@ import { ACCEPTED_SUBMISSION_FILE_TYPES } from '../../../components/FileUpload' import { PageActionsContainer } from '../../StateSubmission/PageActions' import { useErrorSummary } from '../../../hooks/useErrorSummary' import { - CreateQuestionInput, - useCreateQuestionMutation, + CreateContractQuestionInput, + useCreateContractQuestionMutation, } from '../../../gen/gqlClient' import { SideNavOutletContextType } from '../../SubmissionSideNav/SubmissionSideNav' import { usePage } from '../../../contexts/PageContext' @@ -39,7 +39,7 @@ export const UploadQuestions = () => { // api const [createQuestion, { loading: apiLoading, error: apiError }] = - useCreateQuestionMutation() + useCreateContractQuestionMutation() // page level state const [shouldValidate, setShouldValidate] = React.useState(false) @@ -85,7 +85,7 @@ export const UploadQuestions = () => { } }) - const input: CreateQuestionInput = { + const input: CreateContractQuestionInput = { contractID: id as string, documents: questionDocs, } diff --git a/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.test.tsx b/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.test.tsx index 544b9f3b95..dbbb15e38a 100644 --- a/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.test.tsx +++ b/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.test.tsx @@ -14,15 +14,12 @@ import { RoutesRecord } from '../../../constants/routes' import { ACCEPTED_SUBMISSION_FILE_TYPES } from '../../../components/FileUpload' import { fetchCurrentUserMock, - mockDraftHealthPlanPackage, mockValidUser, mockContractPackageDraft, mockContractPackageSubmittedWithQuestions, - fetchContractWithQuestionsMockSuccess + fetchContractWithQuestionsMockSuccess, } from '../../../testHelpers/apolloMocks' -import { - createQuestionResponseNetworkFailure, -} from '../../../testHelpers/apolloMocks/questionResponseGQLMock' +import { createContractQuestionResponseNetworkFailure } from '../../../testHelpers/apolloMocks/questionResponseGQLMock' import { SubmissionSideNav } from '../../SubmissionSideNav' describe('UploadResponse', () => { @@ -31,7 +28,7 @@ describe('UploadResponse', () => { it('displays file upload for correct cms division', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -75,7 +72,7 @@ describe('UploadResponse', () => { it('file upload accepts multiple pdf, word, excel documents', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -127,7 +124,7 @@ describe('UploadResponse', () => { it('displays form validation error if attempting to add question with zero files', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -178,7 +175,7 @@ describe('UploadResponse', () => { it('displays file upload alert if attempting to add question with all invalid files', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -233,7 +230,7 @@ describe('UploadResponse', () => { it('displays file upload error alert if attempting to add question while a file is still uploading', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -297,9 +294,9 @@ describe('UploadResponse', () => { ).toHaveLength(2) }) - it('displays api error if createQuestionResponse fails', async () => { + it('displays api error if createContractQuestionResponse fails', async () => { const contract = mockContractPackageSubmittedWithQuestions('15') - + renderWithProviders( }> @@ -322,7 +319,7 @@ describe('UploadResponse', () => { id: '15', }, }), - createQuestionResponseNetworkFailure(), + createContractQuestionResponseNetworkFailure(), ], }, routerProvider: { diff --git a/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.tsx b/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.tsx index f6c86b9d4e..0417d27f65 100644 --- a/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.tsx +++ b/services/app-web/src/pages/QuestionResponse/UploadResponse/UploadResponse.tsx @@ -19,8 +19,8 @@ import { ACCEPTED_SUBMISSION_FILE_TYPES } from '../../../components/FileUpload' import { PageActionsContainer } from '../../StateSubmission/PageActions' import { useErrorSummary } from '../../../hooks/useErrorSummary' import { - CreateQuestionResponseInput, - useCreateQuestionResponseMutation, + CreateContractQuestionResponseInput, + useCreateContractQuestionResponseMutation, Division, } from '../../../gen/gqlClient' import { usePage } from '../../../contexts/PageContext' @@ -42,7 +42,7 @@ export const UploadResponse = () => { // api const [createResponse, { loading: apiLoading, error: apiError }] = - useCreateQuestionResponseMutation() + useCreateContractQuestionResponseMutation() // page level state const [shouldValidate, setShouldValidate] = React.useState(false) @@ -90,7 +90,7 @@ export const UploadResponse = () => { } }) - const input: CreateQuestionResponseInput = { + const input: CreateContractQuestionResponseInput = { questionID: questionID as string, documents: responseDocs, } diff --git a/services/app-web/src/testHelpers/apolloMocks/contractPackageDataMock.ts b/services/app-web/src/testHelpers/apolloMocks/contractPackageDataMock.ts index 4e2d93155d..31fd116719 100644 --- a/services/app-web/src/testHelpers/apolloMocks/contractPackageDataMock.ts +++ b/services/app-web/src/testHelpers/apolloMocks/contractPackageDataMock.ts @@ -1,8 +1,7 @@ import { mockMNState } from '../../common-code/healthPlanFormDataMocks/healthPlanFormData' -import { Contract, ContractFormData, ContractRevision, RateRevision, UnlockedContract } from '../../gen/gqlClient' +import { Contract, ContractFormData, ContractRevision, RateRevision, UnlockedContract, CmsUser, StateUser } from '../../gen/gqlClient' import { s3DlUrl } from './documentDataMock' -import { CmsUser, IndexQuestionsPayload, StateUser } from '../../gen/gqlClient' import { mockValidCMSUser, mockValidUser } from './userGQLMock' function mockContractRevision(name?: string, partial?: Partial): ContractRevision { @@ -457,9 +456,9 @@ function mockContractPackageSubmittedWithQuestions( totalCount: 2, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmco-question-1-id', contractID, createdAt: new Date('2022-12-15'), @@ -493,9 +492,9 @@ function mockContractPackageSubmittedWithQuestions( }, }, { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmco-question-2-id', contractID, createdAt: new Date('2022-12-18'), @@ -537,9 +536,9 @@ function mockContractPackageSubmittedWithQuestions( totalCount: 1, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmcp-question-1-id', contractID, createdAt: new Date('2022-12-15'), @@ -578,9 +577,9 @@ function mockContractPackageSubmittedWithQuestions( totalCount: 1, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'oact-question-1-id', contractID, createdAt: new Date('2022-12-15'), diff --git a/services/app-web/src/testHelpers/apolloMocks/index.ts b/services/app-web/src/testHelpers/apolloMocks/index.ts index de734fc91b..47e0434be2 100644 --- a/services/app-web/src/testHelpers/apolloMocks/index.ts +++ b/services/app-web/src/testHelpers/apolloMocks/index.ts @@ -51,7 +51,7 @@ export { export { fetchStateHealthPlanPackageWithQuestionsMockSuccess, fetchStateHealthPlanPackageWithQuestionsMockNotFound, - createQuestionNetworkFailure, + createContractQuestionNetworkFailure, } from './questionResponseGQLMock' export { mockQuestionsPayload } from './questionResponseDataMocks' diff --git a/services/app-web/src/testHelpers/apolloMocks/questionResponseDataMocks.ts b/services/app-web/src/testHelpers/apolloMocks/questionResponseDataMocks.ts index 805adffc69..bc094cbcf8 100644 --- a/services/app-web/src/testHelpers/apolloMocks/questionResponseDataMocks.ts +++ b/services/app-web/src/testHelpers/apolloMocks/questionResponseDataMocks.ts @@ -1,15 +1,15 @@ -import { CmsUser, IndexQuestionsPayload, StateUser } from '../../gen/gqlClient' +import { CmsUser, IndexContractQuestionsPayload, StateUser } from '../../gen/gqlClient' import { mockValidCMSUser, mockValidUser } from './userGQLMock' -function mockQuestionsPayload(contractID: string): IndexQuestionsPayload { +function mockQuestionsPayload(contractID: string): IndexContractQuestionsPayload { return { DMCOQuestions: { totalCount: 2, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmco-question-1-id', contractID, createdAt: new Date('2022-12-15'), @@ -43,9 +43,9 @@ function mockQuestionsPayload(contractID: string): IndexQuestionsPayload { }, }, { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmco-question-2-id', contractID, createdAt: new Date('2022-12-18'), @@ -87,9 +87,9 @@ function mockQuestionsPayload(contractID: string): IndexQuestionsPayload { totalCount: 1, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'dmcp-question-1-id', contractID, createdAt: new Date('2022-12-15'), @@ -128,9 +128,9 @@ function mockQuestionsPayload(contractID: string): IndexQuestionsPayload { totalCount: 1, edges: [ { - __typename: 'QuestionEdge' as const, + __typename: 'ContractQuestionEdge' as const, node: { - __typename: 'Question' as const, + __typename: 'ContractQuestion' as const, id: 'oact-question-1-id', contractID, createdAt: new Date('2022-12-15'), diff --git a/services/app-web/src/testHelpers/apolloMocks/questionResponseGQLMock.ts b/services/app-web/src/testHelpers/apolloMocks/questionResponseGQLMock.ts index 537548708e..c637a7d7a7 100644 --- a/services/app-web/src/testHelpers/apolloMocks/questionResponseGQLMock.ts +++ b/services/app-web/src/testHelpers/apolloMocks/questionResponseGQLMock.ts @@ -1,14 +1,14 @@ import { MockedResponse } from '@apollo/client/testing' import { - CreateQuestionDocument, - CreateQuestionResponseDocument, - CreateQuestionInput, - CreateQuestionMutation, + CreateContractQuestionDocument, + CreateContractQuestionResponseDocument, + CreateContractQuestionInput, + CreateContractQuestionMutation, QuestionResponse as QuestionResponseType, FetchHealthPlanPackageWithQuestionsDocument, FetchHealthPlanPackageWithQuestionsQuery, HealthPlanPackage, - IndexQuestionsPayload, + IndexContractQuestionsPayload, } from '../../gen/gqlClient' import { mockValidCMSUser } from './userGQLMock' import { mockSubmittedHealthPlanPackage, mockQuestionsPayload } from './' @@ -17,13 +17,13 @@ import { GraphQLError } from 'graphql' type fetchStateHealthPlanPackageWithQuestionsProps = { stateSubmission?: HealthPlanPackage | Partial id: string - questions?: IndexQuestionsPayload + questions?: IndexContractQuestionsPayload } -const createQuestionSuccess = ( - question?: CreateQuestionInput | Partial -): MockedResponse => { - const defaultQuestionInput: CreateQuestionInput = { +const createContractQuestionSuccess = ( + question?: CreateContractQuestionInput | Partial +): MockedResponse => { + const defaultQuestionInput: CreateContractQuestionInput = { // dueDate: new Date('11-11-2100'), contractID: '123-abc', documents: [ @@ -38,12 +38,12 @@ const createQuestionSuccess = ( return { request: { - query: CreateQuestionDocument, + query: CreateContractQuestionDocument, variables: { input: testInput }, }, result: { data: { - createQuestion: { + createContractQuestion: { question: { id: 'test123', contractID: testInput.contractID, @@ -58,22 +58,22 @@ const createQuestionSuccess = ( } } -const createQuestionNetworkFailure = ( - input: CreateQuestionInput -): MockedResponse => { +const createContractQuestionNetworkFailure = ( + input: CreateContractQuestionInput +): MockedResponse => { return { request: { - query: CreateQuestionDocument, + query: CreateContractQuestionDocument, variables: { input }, }, error: new Error('A network error occurred'), } } -const createQuestionResponseNetworkFailure = ( +const createContractQuestionResponseNetworkFailure = ( _question?: QuestionResponseType | Partial -): MockedResponse => { +): MockedResponse => { return { - request: { query: CreateQuestionResponseDocument }, + request: { query: CreateContractQuestionResponseDocument }, error: new Error('A network error occurred'), } } @@ -133,9 +133,9 @@ const fetchStateHealthPlanPackageWithQuestionsMockNotFound = ({ } export { - createQuestionNetworkFailure, - createQuestionResponseNetworkFailure, - createQuestionSuccess, + createContractQuestionNetworkFailure, + createContractQuestionResponseNetworkFailure, + createContractQuestionSuccess, fetchStateHealthPlanPackageWithQuestionsMockSuccess, fetchStateHealthPlanPackageWithQuestionsMockNotFound, } diff --git a/services/cypress/support/commands.ts b/services/cypress/support/commands.ts index c8174abaa9..4920f4af67 100644 --- a/services/cypress/support/commands.ts +++ b/services/cypress/support/commands.ts @@ -61,8 +61,8 @@ Cypress.Commands.add('interceptGraphQL', () => { aliasMutation(req, 'updateHealthPlanFormData') aliasMutation(req, 'submitHealthPlanPackage') aliasMutation(req, 'updateDivisionAssignment') - aliasMutation(req, 'createQuestion') - aliasMutation(req, 'createQuestionResponse') + aliasMutation(req, 'createContractQuestion') + aliasMutation(req, 'createContractQuestionResponse') aliasMutation(req, 'updateDraftContractRates') aliasMutation(req, 'updateContractDraftRevision') aliasMutation(req, 'submitContract') diff --git a/services/cypress/support/questionResponseCommands.ts b/services/cypress/support/questionResponseCommands.ts index b2becf7306..add0becd82 100644 --- a/services/cypress/support/questionResponseCommands.ts +++ b/services/cypress/support/questionResponseCommands.ts @@ -20,7 +20,7 @@ Cypress.Commands.add( .click() // Wait for re-fetching of health plan package. - cy.wait(['@createQuestionMutation', '@fetchContractWithQuestionsQuery'], { timeout: 50_000 }) + cy.wait(['@createContractQuestionMutation', '@fetchContractWithQuestionsQuery'], { timeout: 50_000 }) } ) @@ -49,6 +49,6 @@ Cypress.Commands.add( .click() // Wait for re-fetching of health plan package. - cy.wait(['@createQuestionResponseMutation', '@fetchContractWithQuestionsQuery'], { timeout: 50_000 }) + cy.wait(['@createContractQuestionResponseMutation', '@fetchContractWithQuestionsQuery'], { timeout: 50_000 }) } )