Skip to content

Commit

Permalink
migrate: find+replace Option/Answer flag prop to flags and ensure…
Browse files Browse the repository at this point in the history
… always `string[]` type (#4098)
  • Loading branch information
jessicamcinchak authored Jan 8, 2025
1 parent bfec874 commit 6ea5801
Show file tree
Hide file tree
Showing 10 changed files with 31 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const Responses = ({
if (isAnsweredByUser) return true;

// Retain responses with flags which are auto answered
const hasFlag = response.selections.some((s) => s.data?.flag);
const hasFlag = response.selections.some((s) => s.data?.flags);
return hasFlag;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,13 @@ export const BaseOptionsEditor: React.FC<BaseOptionsEditorProps> = (props) => (
/>
)}
<FlagsSelect
value={
Array.isArray(props.value.data.flag)
? props.value.data.flag
: [props.value.data.flag]
}
value={props.value.data.flags}
onChange={(ev) => {
props.onChange({
...props.value,
data: {
...props.value.data,
flag: ev,
flags: ev,
},
});
}}
Expand Down
2 changes: 1 addition & 1 deletion editor.planx.uk/src/@planx/components/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface Option {
id: string;
data: {
description?: string;
flag?: Array<Flag["value"]>;
flags?: Array<Flag["value"]>;
img?: string;
text: string;
val?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ const Option: React.FC<any> = (props) => {
let flags: Flag[] | undefined;

try {
// Question & Checklist Options set zero or many flag values under "data.flag"
if (props.data?.flag) {
if (Array.isArray(props.data?.flag)) {
flags = flatFlags.filter(
({ value }) => props.data?.flag?.includes(value),
);
} else {
flags = flatFlags.filter(({ value }) => props.data?.flag === value);
}
// Question & Checklist Options set zero or many flag values under "data.flags"
if (props.data?.flags) {
flags = flatFlags.filter(
({ value }) => props.data?.flags?.includes(value),
);
}

// Filter Options set single flag value under "data.val" (Questions & Checklists use this same field for passport values)
Expand All @@ -35,7 +31,7 @@ const Option: React.FC<any> = (props) => {
flags = flatFlags.filter(({ value }) => props.data.val === value);
}
}
} catch (e) {}
} catch (e) { }

return (
<li
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,14 @@ const flowWithFilters: Store.Flow = {
SecondQuestionYesAnswer: {
data: {
val: "alter.landscaping",
flag: "MCOU_TRUE",
flags: ["MCOU_TRUE"],
text: "Yes",
},
type: 200,
},
FirstQuestionNoAnswer: {
data: {
flag: "MCOU_FALSE",
flags: ["MCOU_FALSE"],
text: "No",
},
type: 200,
Expand Down Expand Up @@ -336,7 +336,7 @@ const flowWithFilters: Store.Flow = {
FirstQuestionYesAnswer: {
data: {
val: "alter.facade",
flag: "MCOU_TRUE",
flags: ["MCOU_TRUE"],
text: "Yes",
},
type: 200,
Expand Down Expand Up @@ -371,7 +371,7 @@ const flowWithFilters: Store.Flow = {
},
SecondQuestionNoAnswer: {
data: {
flag: "MCOU_FALSE",
flags: ["MCOU_FALSE"],
text: "No",
},
type: 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe("Collecting flags", () => {
resetPreview();
});

test("Correctly collects flags when an option's `data.flag` prop is the new array format", () => {
setState({ flow: flowWithNewFlags });
test("Correctly collects flags based on an option's `data.flags` prop", () => {
setState({ flow });

// Manually proceed through a Question that sets multiple flags on a single option
clickContinue("Question", { answers: ["YesOption"], auto: false });
Expand All @@ -26,34 +26,8 @@ describe("Collecting flags", () => {
});
});

test("Correctly collects flags when an option's `data.flag` prop is the legacy string format", () => {
setState({ flow: flowWithLegacyFlags });

// Manually proceed a Checklist and select every option that sets a single flag
clickContinue("Checklist", {
answers: [
"PPImmuneOption",
"PPImmune2Option",
"PPPDOption",
"WTTRequiredOption",
"MCUYesOption",
],
auto: false,
});

expect(collectedFlags()).toEqual({
"Community infrastructure levy": [],
"Demolition in a conservation area": [],
"Listed building consent": [],
"Material change of use": ["Material change of use"],
"Planning permission": ["Immune", "Permitted development"], // Multiple flags of same value have been de-deduplicated
"Planning policy": [],
"Works to trees & hedges": ["Required"],
});
});

test("Returns empty arrays for each category if no flags have been collected", () => {
setState({ flow: flowWithNewFlags });
setState({ flow });

// Manually proceed through a Question option without flags
clickContinue("Question", { answers: ["NoOption"], auto: false });
Expand All @@ -70,7 +44,7 @@ describe("Collecting flags", () => {
});
});

const flowWithNewFlags: Store.Flow = {
const flow: Store.Flow = {
_root: {
edges: ["Question"],
},
Expand All @@ -86,7 +60,7 @@ const flowWithNewFlags: Store.Flow = {
type: 200,
data: {
text: "Yes",
flag: ["PP-NOTICE", "EDGE_CASE", "CO_RELIEF", "PRIOR_APPROVAL"], // `flag` is an array for freshly created/updated Question & Checklist options
flags: ["PP-NOTICE", "EDGE_CASE", "CO_RELIEF", "PRIOR_APPROVAL"],
},
},
NoOption: {
Expand All @@ -96,59 +70,3 @@ const flowWithNewFlags: Store.Flow = {
},
},
};

const flowWithLegacyFlags: Store.Flow = {
_root: {
edges: ["Checklist"],
},
Checklist: {
type: 105,
data: {
allRequired: false,
neverAutoAnswer: false,
text: "Pick up flags?",
},
edges: [
"PPImmuneOption",
"PPImmune2Option",
"PPPDOption",
"WTTRequiredOption",
"MCUYesOption",
],
},
PPImmuneOption: {
data: {
text: "PP Immune",
flag: "IMMUNE",
},
type: 200,
},
PPImmune2Option: {
data: {
text: "PP Immune again",
flag: "IMMUNE",
},
type: 200,
},
PPPDOption: {
data: {
text: "PP Permitted dev",
flag: "NO_APP_REQUIRED",
},
type: 200,
},
WTTRequiredOption: {
data: {
text: "WTT Required",
flag: "TR-REQUIRED",
},
type: 200,
},
MCUYesOption: {
data: {
text: "MCU Yes",
flag: "MCOU_TRUE",
},
type: 200,
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ const mockFlowData = {
},
"4FRZMfNlXf": {
data: {
flag: "PP-NOT_DEVELOPMENT",
flags: ["PP-NOT_DEVELOPMENT"],
text: "Not development",
},
type: TYPES.Answer,
Expand Down Expand Up @@ -428,7 +428,7 @@ const mockFlowData = {
},
IzT93uCmyF: {
data: {
flag: "PRIOR_APPROVAL",
flags: ["PRIOR_APPROVAL"],
text: "Prior",
},
type: TYPES.Answer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const mockFlowData = {
},
"4FRZMfNlXf": {
data: {
flag: "PP-NOT_DEVELOPMENT",
flags: ["PP-NOT_DEVELOPMENT"],
text: "Not development",
},
type: 200,
Expand Down Expand Up @@ -113,7 +113,7 @@ const mockFlowData = {
},
IzT93uCmyF: {
data: {
flag: "PRIOR_APPROVAL",
flags: ["PRIOR_APPROVAL"],
text: "Prior",
},
type: 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const flow: Store.Flow = {
},
MaterialOptionNo: {
data: {
flag: ["MCOU_FALSE", "NO_APP_REQUIRED"],
flags: ["MCOU_FALSE", "NO_APP_REQUIRED"],
text: "No",
},
type: 200,
Expand All @@ -156,7 +156,7 @@ const flow: Store.Flow = {
},
ListedBuildingOptionNo: {
data: {
flag: ["LB-NOT_REQUIRED"],
flags: ["LB-NOT_REQUIRED"],
text: "No",
},
type: 200,
Expand Down Expand Up @@ -205,14 +205,14 @@ const flow: Store.Flow = {
},
MaterialOptionYes: {
data: {
flag: ["MCOU_TRUE", "PLANNING_PERMISSION_REQUIRED"],
flags: ["MCOU_TRUE", "PLANNING_PERMISSION_REQUIRED"],
text: "Yes",
},
type: 200,
},
ListedBuildingOptionYes: {
data: {
flag: ["PLANNING_PERMISSION_REQUIRED", "LB-REQUIRED"],
flags: ["PLANNING_PERMISSION_REQUIRED", "LB-REQUIRED"],
text: "Yes",
},
type: 200,
Expand Down
17 changes: 4 additions & 13 deletions editor.planx.uk/src/pages/FlowEditor/lib/store/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,8 @@ export const previewStore: StateCreator<
}));
const hidden = !selections.some(
(selection) =>
selection.data?.flag &&
// Account for both new flag values (array) and legacy flag value (string)
((Array.isArray(selection.data.flag) &&
selection.data.flag.includes(flag?.value)) ||
selection.data.flag === flag?.value),
selection.data?.flags &&
selection.data.flags.includes(flag?.value)
);

return {
Expand Down Expand Up @@ -934,16 +931,10 @@ const collectedFlagValuesByCategory = (
if (breadcrumb.answers) {
breadcrumb.answers.forEach((answerId) => {
const node = flow[answerId];
// Account for both new flag values (array) and legacy flag value (string)
if (node.data?.flag && Array.isArray(node.data.flag)) {
node.data.flag.forEach((flag) => {
if (node.data?.flags) {
node.data.flags.forEach((flag: Flag["value"]) => {
if (possibleFlagValues.includes(flag)) collectedFlags.push(flag);
});
} else if (
node.data?.flag &&
possibleFlagValues.includes(node.data.flag)
) {
collectedFlags.push(node.data.flag);
}
});
}
Expand Down

0 comments on commit 6ea5801

Please sign in to comment.