diff --git a/eq-author-api/constants/validationErrorCodes.js b/eq-author-api/constants/validationErrorCodes.js index e9fe5bcdcc..1b549dd0a4 100644 --- a/eq-author-api/constants/validationErrorCodes.js +++ b/eq-author-api/constants/validationErrorCodes.js @@ -37,6 +37,7 @@ const ERR_COUNT_OF_GREATER_THAN_AVAILABLE_OPTIONS = "ERR_COUNT_OF_GREATER_THAN_AVAILABLE_OPTIONS"; const ERR_VALID_PIPED_ANSWER_REQUIRED = "ERR_VALID_PIPED_ANSWER_REQUIRED"; const ERR_UNIQUE_PAGE_DESCRIPTION = "ERR_UNIQUE_PAGE_DESCRIPTION"; +const ERR_NO_ANSWERS = "ERR_NO_ANSWERS"; module.exports = { ERR_INVALID, @@ -74,4 +75,5 @@ module.exports = { ERR_COUNT_OF_GREATER_THAN_AVAILABLE_OPTIONS, ERR_VALID_PIPED_ANSWER_REQUIRED, ERR_UNIQUE_PAGE_DESCRIPTION, + ERR_NO_ANSWERS, }; diff --git a/eq-author-api/src/validation/customKeywords/calculatedSummaryMinAnswers.js b/eq-author-api/src/validation/customKeywords/calculatedSummaryMinAnswers.js new file mode 100644 index 0000000000..19e724ea69 --- /dev/null +++ b/eq-author-api/src/validation/customKeywords/calculatedSummaryMinAnswers.js @@ -0,0 +1,60 @@ +const createValidationError = require("../createValidationError"); + +const { ERR_NO_ANSWERS } = require("../../../constants/validationErrorCodes"); +const { getPages, getFolders } = require("../../../schema/resolvers/utils"); + +module.exports = (ajv) => + ajv.addKeyword({ + keyword: "calculatedSummaryMinAnswers", + $data: true, + validate: function isValid( + schema, + _data, + _parentSchema, + { + instancePath, + rootData: questionnaire, + parentData, + parentDataProperty: fieldName, + } + ) { + if (parentData.summaryAnswers.length > 1) { + return true; + } else { + const folders = getFolders({ questionnaire }); + const pages = getPages({ questionnaire }); + + const allAnswers = pages.reduce( + (acc, page) => (page.answers ? [...acc, ...page.answers] : acc), + [] + ); + + const selectedAnswers = allAnswers.filter((answer) => + parentData.summaryAnswers.includes(answer.id) + ); + + let selectedFolder; + folders.forEach((folder) => { + folder.pages.forEach((page) => { + if (page.id === selectedAnswers[0]?.questionPageId) { + selectedFolder = folder; + } + }); + }); + + if (parentData.summaryAnswers.length === 1 && selectedFolder?.listId) { + return true; + } else { + isValid.errors = [ + createValidationError( + instancePath, + fieldName, + ERR_NO_ANSWERS, + questionnaire + ), + ]; + return false; + } + } + }, + }); diff --git a/eq-author-api/src/validation/customKeywords/index.js b/eq-author-api/src/validation/customKeywords/index.js index 87de534bf6..4c325b9007 100644 --- a/eq-author-api/src/validation/customKeywords/index.js +++ b/eq-author-api/src/validation/customKeywords/index.js @@ -19,4 +19,5 @@ module.exports = (ajv) => { require("./validateSecondaryCondition")(ajv); require("./validatePageDescription")(ajv); require("./requiredWhenIntroductionSetting")(ajv); + require("./calculatedSummaryMinAnswers")(ajv); }; diff --git a/eq-author-api/src/validation/schemas/page.json b/eq-author-api/src/validation/schemas/page.json index bb7a9fd778..dbd915b593 100644 --- a/eq-author-api/src/validation/schemas/page.json +++ b/eq-author-api/src/validation/schemas/page.json @@ -217,9 +217,8 @@ "calculatedSummaryPosition": { "$data": "/sections" }, - "minItems": 2, - "errorMessage": { - "minItems": "ERR_NO_ANSWERS" + "calculatedSummaryMinAnswers": { + "$data": "/sections" } }, "totalTitle": { diff --git a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Answers.js b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Answers.js index ec79aebd9a..ceb1d81a54 100644 --- a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Answers.js +++ b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Answers.js @@ -113,6 +113,7 @@ const Answers = ({ page, onUpdateCalculatedSummaryPage, onSelect }) => { {selectedAnswers.map((answer) => ( handleRemoveAnswers([answer])} /> diff --git a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Empty.test.js b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Empty.test.js index de097d096b..e5f3970186 100644 --- a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Empty.test.js +++ b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/Empty.test.js @@ -39,7 +39,7 @@ describe("Empty state", () => { expect(selectBtn).toBeInTheDocument(); const errorMsg = getByText( - "Select at least two answers or calculated summary totals" + "Minimum selection requirements not met. Add an answer or calculated summary total." ); expect(errorMsg).toBeInTheDocument(); }); diff --git a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/SelectedAnswer.js b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/SelectedAnswer.js index 2529e5f53e..8b17eaf17b 100644 --- a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/SelectedAnswer.js +++ b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/AnswerSelector/SelectedAnswer.js @@ -33,6 +33,7 @@ const Title = styled(Truncated)` const Chip = styled(MenuItemType)` color: ${colors.text}; float: right; + font-size: 0.8em; `; const CloseButton = styled.button` @@ -75,6 +76,7 @@ const SelectedAnswer = ({ displayName, properties, type: answerType, + insideListCollectorFolder, onRemove, }) => { const unitType = properties.unit || false; @@ -93,6 +95,7 @@ const SelectedAnswer = ({ {displayName} {unitType && {unitType}} + {insideListCollectorFolder && List collector follow-up} {answerType} { ); expect(pickerHeader[1]).toBeInTheDocument(); - const calculatedSummaryAnswers = getAllByText("CALCULATED SUMMARY"); + const calculatedSummaryAnswers = getAllByText("Calculated summary"); expect(calculatedSummaryAnswers).toBeTruthy(); calculatedSummaryAnswers[0].click(); calculatedSummaryAnswers[1].click(); @@ -182,3 +182,50 @@ describe("Submit selected answers", () => { expect(mockOnUpdateCalculatedSummaryPage).toHaveBeenCalledTimes(1); }); }); + +describe("Select list collector follow-up answers", () => { + let mockOnUpdateCalculatedSummaryPage, mockUseQuestionnaire; + + beforeEach(() => { + mockOnUpdateCalculatedSummaryPage = jest.fn(); + + mockUseQuestionnaire = jest.fn(() => ({ + questionnaire: mockCalculatedSummary, + })); + + questionnaireContext.useQuestionnaire = mockUseQuestionnaire; // eslint-disable-line import/namespace + }); + + it("should submit the selected list collector follow-up answers", () => { + const { getByText, getAllByText, getByTestId } = render(() => ( + + )); + + const btn = getByText("Select an answer or calculated summary total"); + + expect(btn).not.toBeDisabled(); + btn.click(); + + const pickerHeader = getAllByText( + "Select an answer or calculated summary total" + ); + expect(pickerHeader[1]).toBeInTheDocument(); + + const listCollectorFollowupAnswers = getAllByText( + "List collector follow-up" + ); + expect(listCollectorFollowupAnswers).toBeTruthy(); + listCollectorFollowupAnswers[0].click(); + listCollectorFollowupAnswers[1].click(); + + const selectButton = getByTestId("select-summary-answers"); + expect(selectButton).toBeTruthy(); + + selectButton.click(); + + expect(mockOnUpdateCalculatedSummaryPage).toHaveBeenCalledTimes(1); + }); +}); diff --git a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/index.js b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/index.js index ea1898ead4..da49dbf9e8 100644 --- a/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/index.js +++ b/eq-author/src/App/page/Design/CalculatedSummaryPageEditor/index.js @@ -8,6 +8,9 @@ import gql from "graphql-tag"; import { richTextEditorErrors } from "constants/validationMessages"; import { colors } from "constants/theme"; +import { Field } from "components/Forms"; +import Collapsible from "components/Collapsible"; + import RichTextEditor from "components/RichTextEditor"; import withEntityEditor from "components/withEntityEditor"; import PageHeader from "../PageHeader"; @@ -21,7 +24,6 @@ import { VARIABLES, } from "components/ContentPickerSelectv3/content-types"; -//new import AnswerSelector from "./AnswerSelector"; import withPropRenamed from "enhancers/withPropRenamed"; @@ -42,12 +44,42 @@ const PageSegment = styled.div` padding: 0 2em; `; +const Content = styled.p``; + +const ContentCustomMargin = styled.p` + margin-bottom: 0.2em; +`; + +const StyledField = styled(Field)` + padding: 0 2em; +`; + +const ContentContainer = styled.span``; + +const Title = styled.h2` + display: block; + font-size: 1em; + margin-top: 1.33em; + margin-bottom: -0.5em; + margin-left: 0; + margin-right: 0; + font-weight: bold; +`; + const SelectorTitle = styled.h2` font-size: 1em; color: ${colors.black}; margin: 0 0 0.4em; `; +const UnorderedList = styled.ul` + padding-left: 0; + margin-top: 0; + margin-left: 2em; +`; + +const ListItem = styled.li``; + const HorizontalRule = styled.hr` border: 0; border-top: 0.0625em solid ${colors.lightMediumGrey}; @@ -134,6 +166,38 @@ export const CalculatedSummaryPageEditor = (props) => { isMoveDisabled isDuplicateDisabled /> + + What is a calculated summary? + + + A calculated summary allows you to combine answers of the same type + from multiple questions to generate a total. + + + Answer types such as currency, number, percentage, and unit are + permitted, along with the totals of other calculated summaries. The + answers being totalled must belong to the same section, except for + the totals of other calculated summaries, which can come from + different sections. + + + + + A calculated summary can total the answers for each list item's + follow-up question. If additional answers are selected, they must be + of the same answer type. + + + The list item will be displayed in the calculated summary table with + its corresponding value. + + + If 1 list collector follow-up question is selected for the + calculated summary and 1 list item is added by the respondent, the + summary will be shown. + + + { />
- Answers to calculate + + Select answers or calculated summaries to total + + + A calculated summary must include at least: + + + 2 answers of the same type + + or 1 answer from a list collector follow-up question + + or 2 calculated summary totals + { + return { + ...answer, + folders: answer.folders.filter((folder) => folder.listId == null), + }; + }); + const metadata = questionnaire?.metadata?.filter( ({ type }) => type === TEXT.value || type === TEXT_OPTIONAL.value ) || []; const data = { - [ANSWER]: previousAnswers, + [ANSWER]: filteredPreviousAnswers, [METADATA]: metadata, }; diff --git a/eq-author/src/components/AnswerPicker/index.js b/eq-author/src/components/AnswerPicker/index.js index d9d1e41901..befe2002cc 100644 --- a/eq-author/src/components/AnswerPicker/index.js +++ b/eq-author/src/components/AnswerPicker/index.js @@ -56,9 +56,22 @@ const ModalToolbar = styled.div` const MenuContainer = styled.div` overflow: hidden; - height: 25em; + height: 20em; + display: flex; +`; + +const ContentCustomMargin = styled.p` + margin-bottom: 0.2em; `; +const UnorderedList = styled.ul` + padding-left: 0; + margin-top: 0; + margin-left: 2em; +`; + +const ListItem = styled.li``; + const QuestionPicker = ({ data, questionnaire, @@ -157,10 +170,20 @@ const QuestionPicker = ({ {title} - Answers can only be selected from the current section. Calculated - summary totals can be selected from both current and previous - sections. + The answers being totalled must belong to the same section, except + for the totals of other calculated summaries, which can come from + different sections. + + A calculated summary must include at least: + + + 2 answers of the same type + + or 1 answer from a list collector follow-up question + + or 2 calculated summary totals + setSearchTerm(value)} @@ -176,6 +199,7 @@ const QuestionPicker = ({ isDisabled={isDisabled} isSelected={isSelected} data={searchResults} + isCalculatedSummary {...otherProps} /> diff --git a/eq-author/src/components/AnswerPicker/index.test.js b/eq-author/src/components/AnswerPicker/index.test.js index 4839199a9a..9864ad9e47 100644 --- a/eq-author/src/components/AnswerPicker/index.test.js +++ b/eq-author/src/components/AnswerPicker/index.test.js @@ -230,7 +230,7 @@ describe("Question Picker", () => { expect( getByText( - "Answers can only be selected from the current section. Calculated summary totals can be selected from both current and previous sections." + "The answers being totalled must belong to the same section, except for the totals of other calculated summaries, which can come from different sections." ) ).toBeTruthy(); }); diff --git a/eq-author/src/components/ContentPickerv3/Menu.js b/eq-author/src/components/ContentPickerv3/Menu.js index e8fa7b5126..29dd61ccd4 100644 --- a/eq-author/src/components/ContentPickerv3/Menu.js +++ b/eq-author/src/components/ContentPickerv3/Menu.js @@ -24,7 +24,7 @@ export const MenuItem = styled.li` align-items: center; font-size: 0.9em; padding: 0 1em; - height: 3.5em; + min-height: ${(props) => !props.isCalculatedSummary && `3.5em`}; background-color: ${colors.white}; position: relative; cursor: pointer; @@ -103,15 +103,17 @@ export const MenuItemTitle = styled.div` font-size: 1em; margin-bottom: 0.1em; color: var(--color); + width: ${(props) => (props.isCalculatedSummary ? "33em" : "28em")}; `; export const MenuItemSubtitle = styled.div` font-size: 0.9em; color: var(--colorSecondary); + width: ${(props) => (props.isCalculatedSummary ? "33em" : "28em")}; `; export const MenuItemType = styled.span` - font-size: 10px; + font-size: 0.9em; margin: 0 0.25em; background: #e4e8eb; padding: 0.3em 0.7em; @@ -123,7 +125,7 @@ export const MenuItemType = styled.span` `; export const MenuItemPageType = styled.span` - font-size: 10px; + font-size: 0.9em; margin: 0 0.25em; background: #e4e8eb; padding: 0.3em 0.7em; @@ -132,7 +134,7 @@ export const MenuItemPageType = styled.span` color: var(--colorTertiary); flex: 0 1 auto; justify-self: flex-end; - margin-right: 2em; + margin-right: 1em; `; export const SectionTitle = styled.div` @@ -197,7 +199,13 @@ Menu.propTypes = { isSelected: PropTypes.func.isRequired, }; -const SubMenu = ({ data, onSelected, isSelected, isDisabled }) => { +const SubMenu = ({ + data, + onSelected, + isSelected, + isDisabled, + isCalculatedSummary, +}) => { const onEnterUp = (event, item) => { if (event.keyCode === 13) { //13 is the enter keycode @@ -224,17 +232,20 @@ const SubMenu = ({ data, onSelected, isSelected, isDisabled }) => { return ( - - {item.displayName} + + {item.displayName} - + {page.displayName} {page.pageType === "CalculatedSummaryPage" && ( - CALCULATED SUMMARY + Calculated summary + )} + {page.folder?.listId != null && ( + List collector follow-up )} - {item.type.toUpperCase()} + {item.type} {item.type === UNIT && ( {item.properties.unit ? item.properties.unit : "Missing unit"} @@ -253,9 +264,10 @@ SubMenu.propTypes = { onSelected: PropTypes.func.isRequired, isSelected: PropTypes.func.isRequired, isDisabled: PropTypes.func, + isCalculatedSummary: PropTypes.boolean, }; -const FlatSectionMenu = ({ data, ...otherProps }) => +const FlatSectionMenu = ({ data, isCalculatedSummary, ...otherProps }) => data.map((section) => { const numOfPages = getPages({ sections: [section] }).length; @@ -268,6 +280,7 @@ const FlatSectionMenu = ({ data, ...otherProps }) => {section.displayName} pages)} + isCalculatedSummary={isCalculatedSummary} {...otherProps} />
diff --git a/eq-author/src/components/RichTextEditor/PipingMenu.js b/eq-author/src/components/RichTextEditor/PipingMenu.js index 3e8839df2b..21a787ddef 100644 --- a/eq-author/src/components/RichTextEditor/PipingMenu.js +++ b/eq-author/src/components/RichTextEditor/PipingMenu.js @@ -90,11 +90,33 @@ const PipingMenu = ({ [questionnaire, pageId] ); + const filteredAnswerData = answerData.map((answer) => { + return { + ...answer, + folders: answer.folders.filter((folder) => folder.listId == null), + }; + }); + const metadataData = questionnaire?.metadata || []; + let listCollectorFollowUpAnswers = []; + answerData.forEach((answer) => + answer.folders.forEach((folder) => { + if (folder?.listId === listId) { + folder.pages.forEach((page) => { + page.answers.forEach((answer) => { + listCollectorFollowUpAnswers.push(answer); + }); + }); + } + }) + ); + const listAnswers = find(questionnaire?.collectionLists?.lists, { id: listId })?.answers || []; + const listAllAnswers = [...listAnswers, ...listCollectorFollowUpAnswers]; + const supplementaryData = questionnaire?.supplementaryData?.data .filter((list) => list.listName === "" || list.id === listId) @@ -112,11 +134,11 @@ const PipingMenu = ({ case METADATA: return metadataData; case ANSWER: - return answerData; + return filteredAnswerData; case VARIABLES: return allCalculatedSummaryPages; case LIST_ANSWER: - return listAnswers; + return listAllAnswers; case SUPPLEMENTARY_DATA: return supplementaryData; default: diff --git a/eq-author/src/constants/validationMessages.js b/eq-author/src/constants/validationMessages.js index 4644fbc1b1..527a70816b 100644 --- a/eq-author/src/constants/validationMessages.js +++ b/eq-author/src/constants/validationMessages.js @@ -191,7 +191,8 @@ export const characterErrors = { }; export const calculatedSummaryErrors = { - ERR_NO_ANSWERS: "Select at least two answers or calculated summary totals", + ERR_NO_ANSWERS: + "Minimum selection requirements not met. Add an answer or calculated summary total.", ERR_CALCULATED_UNIT_INCONSISTENCY: "Select answers that are the same unit type", CALCSUM_MOVED: "The calculated summary must appear after the answers it uses", diff --git a/eq-author/src/tests/mocks/mockCalculatedSummary.json b/eq-author/src/tests/mocks/mockCalculatedSummary.json index 14cc67ee1e..2e3321608b 100644 --- a/eq-author/src/tests/mocks/mockCalculatedSummary.json +++ b/eq-author/src/tests/mocks/mockCalculatedSummary.json @@ -70,6 +70,255 @@ "type": "Number" } ] + }, + { + "displayName": "", + "title": "Collect1", + "folderId": "collect1", + "listId": "596b8a41-a115-416a-9571-8d13bce6788c", + "pages": [ + { + "answers": [ + { + "qCode": "q3", + "label": "", + "type": "Radio", + "options": [ + { + "qCode": "", + "label": "Yes", + "id": "210b8a3c-bf00-4671-8a2a-93d23333dacf" + }, + { + "qCode": "", + "label": "No", + "id": "1d7ecd54-01d8-4454-bbb0-63ad0b1c8fd7" + } + ], + "id": "7083f5d5-97d2-41b7-aaaa-f3640d4967ea", + "properties": { + "required": false + }, + "validation": {} + } + ], + "title": "

Qualifier1

", + "additionalGuidanceEnabled": false, + "additionalGuidanceContent": "", + "pageType": "ListCollectorQualifierPage", + "pageDescription": "Qualifier page1", + "alias": null, + "id": "04084cc4-8306-4760-b15e-f238b953fa6a", + "position": 0 + }, + { + "definitionEnabled": false, + "additionalInfoContent": null, + "description": null, + "title": "

Add1

", + "definitionLabel": null, + "additionalInfoLabel": null, + "pageType": "ListCollectorAddItemPage", + "descriptionEnabled": false, + "additionalInfoEnabled": false, + "definitionContent": null, + "guidance": null, + "pageDescription": "Add page1", + "alias": null, + "guidanceEnabled": false, + "id": "b9dec144-54fe-4888-9d5a-318237c7c788", + "position": 1 + }, + { + "definitionEnabled": false, + "additionalInfoContent": null, + "answers": [ + { + "qCode": "q4", + "description": "", + "label": "

Num1

", + "type": "Number", + "repeatingLabelAndInputListId": "", + "repeatingLabelAndInput": false, + "guidance": "", + "id": "64702f3e-8973-481f-9892-617365bc32e1", + "questionPageId": "795742a0-0844-474c-a371-99e8af819dbe", + "properties": { + "required": false, + "decimals": 0 + }, + "validation": { + "maxValue": { + "inclusive": true, + "entityType": "Custom", + "validationType": "maxValue", + "enabled": false, + "id": "d7034d76-cb20-45f7-9770-478d300fbbe0" + }, + "minValue": { + "inclusive": true, + "entityType": "Custom", + "validationType": "minValue", + "enabled": false, + "id": "12421c3c-52f9-4a7e-95a8-e38f4b31b8ce" + } + } + } + ], + "folder": { + "id": "collect1", + "position": 2, + "listId": 123, + "__typename": "ListCollectorFolder", + "enabled": false + }, + "description": "", + "title": "

Num1

", + "definitionLabel": null, + "routing": null, + "additionalInfoLabel": null, + "pageType": "QuestionPage", + "descriptionEnabled": false, + "additionalInfoEnabled": false, + "definitionContent": null, + "guidance": null, + "pageDescription": "Num1", + "alias": null, + "guidanceEnabled": false, + "id": "795742a0-0844-474c-a371-99e8af819dbe" + }, + { + "definitionEnabled": false, + "additionalInfoContent": null, + "answers": [ + { + "qCode": "q5", + "description": "", + "label": "

Copy of Num1

", + "type": "Number", + "repeatingLabelAndInputListId": "", + "repeatingLabelAndInput": false, + "guidance": "", + "id": "1cfabf70-11cd-440d-8ceb-0c62c7007dfe", + "questionPageId": "795742a0-0844-474c-a371-99e8af819dbe", + "properties": { + "required": false, + "decimals": 0 + }, + "validation": { + "maxValue": { + "inclusive": true, + "entityType": "Custom", + "validationType": "maxValue", + "enabled": false, + "id": "472aee50-be33-4bc6-b6ce-3969a43ad876" + }, + "minValue": { + "inclusive": true, + "entityType": "Custom", + "validationType": "minValue", + "enabled": false, + "id": "73d4a75e-949f-4927-a3c8-7f60301b065d" + } + } + } + ], + "folder": { + "id": "collect1", + "position": 2, + "listId": 123, + "__typename": "ListCollectorFolder", + "enabled": false + }, + "description": "", + "title": "

Copy of Num1

", + "definitionLabel": null, + "routing": null, + "additionalInfoLabel": null, + "pageType": "QuestionPage", + "descriptionEnabled": false, + "additionalInfoEnabled": false, + "definitionContent": null, + "guidance": null, + "pageDescription": "Copy of Num1", + "alias": "", + "guidanceEnabled": false, + "id": "fbc43059-9633-4977-b228-ef37d9610a0d" + }, + { + "answers": [ + { + "qCode": "q6", + "label": "", + "type": "Radio", + "options": [ + { + "qCode": "", + "label": "Yes", + "id": "81d0d18e-65c5-4ab8-a04a-ca67e67d1260" + }, + { + "qCode": "", + "label": "No", + "id": "9d1cd58e-e054-46a1-ac68-fb5bedb5ad53" + } + ], + "id": "6b4fe99c-5aad-481a-a169-e10f1cdd99e8", + "properties": { + "required": false + }, + "validation": {} + } + ], + "title": "

Confirm1

", + "pageType": "ListCollectorConfirmationPage", + "pageDescription": "Confirm page1", + "alias": null, + "id": "343d14cc-2ee4-409b-96e8-a86c8438348d", + "position": 2 + } + ], + "alias": "", + "id": "234ebaf5-80bd-44e9-aef4-76ef7c48a67d" + }, + { + "folderId": "d1ced4db-c7af-4da0-b287-6e7f343492c5", + "skipConditions": null, + "pages": [ + { + "totalTitle": "

Summary title2

", + "answers": [ + { + "label": "

Summary title2

", + "type": "Number", + "id": "e8f129ae-827e-411f-af36-d6ece81d8b20", + "validation": {}, + "properties": {} + } + ], + "section": { + "id": "1", + "position": 0, + "__typename": "Section", + "displayName": "Untitled section" + }, + "title": "

Summary2

", + "type": "Number", + "pageType": "CalculatedSummaryPage", + "summaryAnswers": [], + "pageDescription": "Summary2", + "alias": null, + "id": "05aaae72-5269-4882-b466-bc450bb4c202", + "validationErrorInfo": { + "id": "e76d80b3-8d5a-46b3-a9df-6659a976b8a2", + "errors": [], + "totalCount": 0, + "__typename": "ValidationErrorInfo" + } + } + ], + "alias": "Folder2", + "id": "d1ced4db-c7af-4da0-b287-6e7f343492c5" } ] }, diff --git a/eq-author/src/utils/getCalculatedSummaryPages.test.js b/eq-author/src/utils/getCalculatedSummaryPages.test.js index 9187e9ac1c..72b7ebc768 100644 --- a/eq-author/src/utils/getCalculatedSummaryPages.test.js +++ b/eq-author/src/utils/getCalculatedSummaryPages.test.js @@ -20,13 +20,13 @@ describe("utils/getCalculatedSummaryPages", () => { expect(previousSections).toHaveLength(0); }); - it("should return the two calculated summary pages when the target is the calculated summary page in the second section", () => { + it("should return the three calculated summary pages when the target is the calculated summary page in the second section", () => { const previousSections = getCalculatedSummaryPages( questionnaire, questionnaire.sections[1].id ); expect(previousSections).toHaveLength(1); - expect(previousSections[0].folders[0].pages).toHaveLength(2); + expect(previousSections[0].folders[0].pages).toHaveLength(3); }); it("Should return all the calculated summary answers which preceed the target page", () => { @@ -36,6 +36,6 @@ describe("utils/getCalculatedSummaryPages", () => { ); expect(previousSections).toHaveLength(2); expect(previousSections[0].folders).toHaveLength(1); - expect(previousSections[0].folders[0].pages).toHaveLength(2); + expect(previousSections[0].folders[0].pages).toHaveLength(3); }); });