diff --git a/src/eq_schema/builders/basicQuestionnaireJSON.js b/src/eq_schema/builders/basicQuestionnaireJSON.js index 45ba3a25..fe263e7e 100644 --- a/src/eq_schema/builders/basicQuestionnaireJSON.js +++ b/src/eq_schema/builders/basicQuestionnaireJSON.js @@ -92,6 +92,42 @@ const questionnaireJson = { }, ], }, + { + id: "3", + title: "
Section 3
", + folders: [ + { + id: "folder-3", + enabled: false, + pages: [ + { + id: "4", + title: "Page 4
", + pageType: "QuestionPage", + routingRuleSet: null, + confirmation: null, + answers: [ + { + id: "5", + type: "Number", + label: "Answer 5", + }, + { + id: "6", + type: "MutuallyExclusive", + options: [ + { + id: "exclusive-option-1", + label: "Not known", + }, + ], + }, + ], + }, + ], + }, + ], + }, ], }; diff --git a/src/eq_schema/builders/routing2/newRoutingDestination/index.js b/src/eq_schema/builders/routing2/newRoutingDestination/index.js index 504a3cc3..32332af5 100644 --- a/src/eq_schema/builders/routing2/newRoutingDestination/index.js +++ b/src/eq_schema/builders/routing2/newRoutingDestination/index.js @@ -6,6 +6,7 @@ const { getValueSource } = require("../../valueSource"); const { getListFromAll } = require("../../../../utils/functions/listGetters"); const { flatMap, filter, find } = require("lodash"); +const { getAnswerById } = require("../../../../utils/functions/answerGetters"); const authorConditions = { UNANSWERED: "Unanswered", @@ -122,16 +123,30 @@ const buildAnswerObject = ( return SelectedOptions; } - if (condition === "OneOf") { - const swapOptionValues = ([optionValues[0], optionValues[1]] = [ - optionValues[1], - optionValues[0], - ]); - const SelectedOptions = { - [routingConditionConversion(condition)]: swapOptionValues, - }; + const leftSideAnswer = getAnswerById(ctx, left.answerId); - return SelectedOptions; + if (condition === "OneOf") { + if ( + leftSideAnswer && + leftSideAnswer.type === "MutuallyExclusive" && + leftSideAnswer.options.length === 1 + ) { + const SelectedOptions = { + [routingConditionConversion("AllOf")]: optionValues, + }; + + return SelectedOptions; + } else { + const swapOptionValues = ([optionValues[0], optionValues[1]] = [ + optionValues[1], + optionValues[0], + ]); + const SelectedOptions = { + [routingConditionConversion(condition)]: swapOptionValues, + }; + + return SelectedOptions; + } } const SelectedOptions = { diff --git a/src/eq_schema/builders/routing2/newRoutingDestination/index.test.js b/src/eq_schema/builders/routing2/newRoutingDestination/index.test.js index ba1ac519..90c1ec03 100644 --- a/src/eq_schema/builders/routing2/newRoutingDestination/index.test.js +++ b/src/eq_schema/builders/routing2/newRoutingDestination/index.test.js @@ -181,6 +181,36 @@ describe("Should build a runner representation of a binary expression", () => { }); }); + describe("With mutually exclusive answers", () => { + it("should return all of condition for mutually exclusive answers with one option", () => { + const expression = { + left: { + answerId: "6", + type: "Answer", + }, + condition: "OneOf", + right: { + type: "SelectedOptions", + optionIds: ["exclusive-option-1"], + }, + }; + + const runnerExpression = checkValidRoutingType(expression, { + questionnaireJson, + }); + + expect(runnerExpression).toMatchObject({ + "all-in": [ + ["Not known"], + { + identifier: "answer6", + source: "answers", + }, + ], + }); + }); + }); + describe("With metadata", () => { describe("Text metadata", () => { it("should return correct metadata object for text metadata", () => { diff --git a/src/eq_schema/builders/routing2/translateRoutingDestination/index.test.js b/src/eq_schema/builders/routing2/translateRoutingDestination/index.test.js index 47257f88..a9003011 100644 --- a/src/eq_schema/builders/routing2/translateRoutingDestination/index.test.js +++ b/src/eq_schema/builders/routing2/translateRoutingDestination/index.test.js @@ -57,7 +57,7 @@ describe("Translation of a routing destination", () => { logical: "NextPage", }; expect( - translateRoutingDestination(authorDestination, "3", { questionnaireJson }) + translateRoutingDestination(authorDestination, "4", { questionnaireJson }) ).toMatchObject({ group: "confirmation-group" }); }); @@ -66,7 +66,7 @@ describe("Translation of a routing destination", () => { logical: "NextPage", }; expect( - translateRoutingDestination(authorDestination, "3", { + translateRoutingDestination(authorDestination, "4", { questionnaireJson: questionnaireJsonWithSummary, }) ).toMatchObject({ group: "summary-group" }); diff --git a/src/utils/functions/answerGetters.js b/src/utils/functions/answerGetters.js new file mode 100644 index 00000000..051aa4cf --- /dev/null +++ b/src/utils/functions/answerGetters.js @@ -0,0 +1,11 @@ +const { getPages } = require("./pageGetters"); +const { flatMap } = require("lodash"); + +const getAnswerById = (ctx, answerId) => { + const pages = getPages(ctx); + const answers = flatMap(pages, (page) => page.answers); + + return answers.find((answer) => answer.id === answerId); +}; + +module.exports = { getAnswerById }; diff --git a/src/utils/functions/answerGetters.test.js b/src/utils/functions/answerGetters.test.js new file mode 100644 index 00000000..afb0a4e8 --- /dev/null +++ b/src/utils/functions/answerGetters.test.js @@ -0,0 +1,37 @@ +const { getAnswerById } = require("./answerGetters"); + +describe("getAnswerById", () => { + it("should return an answer by id", () => { + const ctx = { + questionnaireJson: { + sections: [ + { + folders: [ + { + pages: [ + { + answers: [ + { + id: "1", + label: "Answer 1", + }, + { + id: "2", + label: "Answer 2", + }, + ], + }, + ], + }, + ], + }, + ], + }, + }; + + expect(getAnswerById(ctx, "2")).toMatchObject({ + id: "2", + label: "Answer 2", + }); + }); +});