diff --git a/packages/mocks/src/apollo/contractPackageDataMock.ts b/packages/mocks/src/apollo/contractPackageDataMock.ts index 08da819027..0a0b9a7189 100644 --- a/packages/mocks/src/apollo/contractPackageDataMock.ts +++ b/packages/mocks/src/apollo/contractPackageDataMock.ts @@ -510,6 +510,7 @@ function mockContractPackageSubmittedWithQuestions( __typename: 'ContractQuestion' as const, id: 'dmco-question-1-id', contractID, + round: 1, createdAt: new Date('2022-12-16'), addedBy: mockValidCMSUser({ divisionAssignment: null, @@ -548,6 +549,7 @@ function mockContractPackageSubmittedWithQuestions( contractID, createdAt: new Date('2022-12-18'), addedBy: mockValidCMSUser() as CmsUser, + round: 1, documents: [ { s3URL: 's3://bucketname/key/dmco-question-2-document-1', @@ -576,6 +578,7 @@ function mockContractPackageSubmittedWithQuestions( id: 'dmcp-question-1-id', contractID, createdAt: new Date('2022-12-15'), + round: 1, addedBy: mockValidCMSUser({ divisionAssignment: 'DMCP', }) as CmsUser, @@ -617,6 +620,7 @@ function mockContractPackageSubmittedWithQuestions( id: 'oact-question-1-id', contractID, createdAt: new Date('2022-12-14'), + round: 1, addedBy: mockValidCMSUser({ divisionAssignment: 'OACT', }) as CmsUser, @@ -656,6 +660,7 @@ function mockContractPackageSubmittedWithQuestions( addedBy: mockValidCMSUser({ divisionAssignment: 'OACT', }) as CmsUser, + round: 2, documents: [ { s3URL: 's3://bucketname/key/oact-question-1-document-1', @@ -1508,6 +1513,7 @@ function mockContractPackageApprovedWithQuestions( addedBy: mockValidCMSUser({ divisionAssignment: null, }) as CmsUser, + round: 1, documents: [ { s3URL: 's3://bucketname/key/dmco-question-1-document-1', @@ -1542,6 +1548,7 @@ function mockContractPackageApprovedWithQuestions( contractID, createdAt: new Date('2022-12-18'), addedBy: mockValidCMSUser() as CmsUser, + round: 2, documents: [ { s3URL: 's3://bucketname/key/dmco-question-2-document-1', @@ -1570,6 +1577,7 @@ function mockContractPackageApprovedWithQuestions( id: 'dmcp-question-1-id', contractID, createdAt: new Date('2022-12-15'), + round: 1, addedBy: mockValidCMSUser({ divisionAssignment: 'DMCP', }) as CmsUser, @@ -1614,6 +1622,7 @@ function mockContractPackageApprovedWithQuestions( addedBy: mockValidCMSUser({ divisionAssignment: 'OACT', }) as CmsUser, + round: 1, documents: [ { s3URL: 's3://bucketname/key/oact-question-1-document-1', @@ -1647,6 +1656,7 @@ function mockContractPackageApprovedWithQuestions( id: 'oact-question-2-id', contractID: 'test-abc-123', createdAt: new Date('2022-12-17'), + round: 2, addedBy: mockValidCMSUser({ divisionAssignment: 'OACT', }) as CmsUser, diff --git a/packages/mocks/src/apollo/questionResponseDataMocks.ts b/packages/mocks/src/apollo/questionResponseDataMocks.ts index 0d4b057848..c55bba8a09 100644 --- a/packages/mocks/src/apollo/questionResponseDataMocks.ts +++ b/packages/mocks/src/apollo/questionResponseDataMocks.ts @@ -29,6 +29,7 @@ function mockQuestionsPayload( downloadURL: expect.any(String), }, ], + round: 1, division: 'DMCO', responses: [ { @@ -56,6 +57,7 @@ function mockQuestionsPayload( contractID, createdAt: new Date('2022-12-18'), addedBy: mockValidCMSUser() as CmsUser, + round: 1, documents: [ { s3URL: 's3://bucketname/key/dmco-question-2-document-1', @@ -110,6 +112,7 @@ function mockQuestionsPayload( }, ], division: 'DMCP', + round: 1, responses: [ { __typename: 'QuestionResponse' as const, @@ -143,6 +146,7 @@ function mockQuestionsPayload( addedBy: mockValidCMSUser({ divisionAssignment: 'OACT', }) as CmsUser, + round: 1, documents: [ { s3URL: 's3://bucketname/key/oact-question-1-document-1', diff --git a/services/app-api/src/resolvers/configureResolvers.ts b/services/app-api/src/resolvers/configureResolvers.ts index 4c13ad653c..265603dfe4 100644 --- a/services/app-api/src/resolvers/configureResolvers.ts +++ b/services/app-api/src/resolvers/configureResolvers.ts @@ -17,6 +17,7 @@ import { questionResponseDocumentResolver, createRateQuestionResolver, createRateQuestionResponseResolver, + questionResolver, } from './questionResponse' import { fetchCurrentUserResolver, @@ -171,6 +172,7 @@ export function configureResolvers( Rate: rateResolver(store, applicationEndpoint), RateRevision: rateRevisionResolver(store), RateFormData: rateFormDataResolver(), + ContractQuestion: questionResolver(store), Contract: contractResolver(store, applicationEndpoint), UnlockedContract: unlockedContractResolver(store, applicationEndpoint), ContractRevision: contractRevisionResolver(store), diff --git a/services/app-api/src/resolvers/questionResponse/index.ts b/services/app-api/src/resolvers/questionResponse/index.ts index 231774af57..2962b676f8 100644 --- a/services/app-api/src/resolvers/questionResponse/index.ts +++ b/services/app-api/src/resolvers/questionResponse/index.ts @@ -3,3 +3,4 @@ export { createContractQuestionResponseResolver } from './createContractQuestion export { questionResponseDocumentResolver } from './questionResponseDocumentResolver' export { createRateQuestionResolver } from './createRateQuestion' export { createRateQuestionResponseResolver } from './createRateQuestionResponse' +export { questionResolver } from './questionResolver' diff --git a/services/app-api/src/resolvers/questionResponse/questionResolver.test.ts b/services/app-api/src/resolvers/questionResponse/questionResolver.test.ts new file mode 100644 index 0000000000..13d8b706d7 --- /dev/null +++ b/services/app-api/src/resolvers/questionResponse/questionResolver.test.ts @@ -0,0 +1,80 @@ +import { + constructTestPostgresServer, + createTestQuestion, +} from '../../testHelpers/gqlHelpers' +import { + testCMSUser, + createDBUsersWithFullData, +} from '../../testHelpers/userHelpers' +import { testS3Client } from '../../testHelpers/s3Helpers' +import { + createAndSubmitTestContract, + fetchTestContractWithQuestions, +} from '../../testHelpers' + +describe(`questionResolver`, () => { + const mockS3 = testS3Client() + const dmcpCMSUser = testCMSUser({ + divisionAssignment: 'DMCP', + }) + + beforeAll(async () => { + //Inserting a new CMS user, with division assigned, in postgres in order to create the question to user relationship. + await createDBUsersWithFullData([dmcpCMSUser]) + }) + + it('populates a round number on fetch', async () => { + const stateServer = await constructTestPostgresServer() + + const dmcpCMSServer = await constructTestPostgresServer({ + context: { + user: dmcpCMSUser, + }, + s3Client: mockS3, + }) + + const contract = await createAndSubmitTestContract(stateServer) + + const createdDMCPQuestion = await createTestQuestion( + dmcpCMSServer, + contract.id, + { + documents: [ + { + name: 'Test Question 2', + s3URL: 's3://bucketname/key/test12', + }, + ], + } + ) + + const createdDMCPQuestion2 = await createTestQuestion( + dmcpCMSServer, + contract.id, + { + documents: [ + { + name: 'Test Question 2', + s3URL: 's3://bucketname/key/test12', + }, + ], + } + ) + + const contractWithQuestions = await fetchTestContractWithQuestions( + stateServer, + contract.id + ) + const indexQuestionsResult = contractWithQuestions.questions + const firstDMCPQuestion = + indexQuestionsResult?.DMCPQuestions.edges.find( + (q) => q.node.id === createdDMCPQuestion.question.id + ) + const secondDMCPQuestion = + indexQuestionsResult?.DMCPQuestions.edges.find( + (q) => q.node.id === createdDMCPQuestion2.question.id + ) + expect(firstDMCPQuestion?.node.round).toBe(1) + expect(secondDMCPQuestion?.node.round).toBe(2) + }) +}) diff --git a/services/app-api/src/resolvers/questionResponse/questionResolver.ts b/services/app-api/src/resolvers/questionResponse/questionResolver.ts new file mode 100644 index 0000000000..6fa77bf94a --- /dev/null +++ b/services/app-api/src/resolvers/questionResponse/questionResolver.ts @@ -0,0 +1,46 @@ +import type { Resolvers } from '../../gen/gqlServer' + +import type { ContractQuestionType } from '../../domain-models' +import type { Store } from '../../postgres' +import { GraphQLError } from 'graphql' + +export function questionResolver(store: Store): Resolvers['QuestionResolver'] { + return { + round: async (parent: ContractQuestionType) => { + const questions = await store.findAllQuestionsByContract( + parent.contractID + ) + if (!questions) { + throw new Error( + `Questions not found for contract: ${parent.contractID}` + ) + } + if (questions instanceof Error) { + const errMessage = `Issue return questions for contract message: ${questions.message}` + + throw new GraphQLError(errMessage, { + extensions: { + code: 'INTERNAL_SERVER_ERROR', + cause: 'DB_ERROR', + }, + }) + } + + const divisionQuestions = questions + .filter((q) => q.division === parent.division) + .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()) + + const matchingQuestion = divisionQuestions.find( + (question) => question.id == parent.id + ) + + if (!matchingQuestion) { + return 0 + } else { + return divisionQuestions.indexOf(matchingQuestion) !== undefined + ? divisionQuestions.indexOf(matchingQuestion) + 1 + : 0 + } + }, + } +} diff --git a/services/app-graphql/src/fragments/questionsEdgeFragment.graphql b/services/app-graphql/src/fragments/questionsEdgeFragment.graphql index 28a06b9b6c..84db054cde 100644 --- a/services/app-graphql/src/fragments/questionsEdgeFragment.graphql +++ b/services/app-graphql/src/fragments/questionsEdgeFragment.graphql @@ -12,6 +12,7 @@ fragment contractQuestionEdgeFragment on ContractQuestionEdge { } } division + round documents { s3URL name diff --git a/services/app-graphql/src/schema.graphql b/services/app-graphql/src/schema.graphql index 44c060e0b3..f3f1d42654 100644 --- a/services/app-graphql/src/schema.graphql +++ b/services/app-graphql/src/schema.graphql @@ -1239,6 +1239,7 @@ type ContractQuestion { addedBy: CMSUsersUnion! documents: [Document!]! division: Division! + round: Int! # noteText: String # dueDate: Date # rateIDs: [String!]