Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production deploy #2477

Merged
merged 8 commits into from
Nov 23, 2023
4 changes: 2 additions & 2 deletions .github/workflows/cron-deploy-to-production.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: "Automatic production deployment"

on:
# TODO: Enable CRON after the holiday season
# TODO: Enable CRON if desired
# schedule:
# # “At 09:00 on every day-of-week from Tuesday through Friday.”
# - cron: "0 9 * * 2-5"
Expand All @@ -17,7 +17,7 @@ jobs:
# Requires a Personal Access Token generated by an OSL GitHub org admin
# Allows this action to trigger the push-production.yml action
# PAT requires the "Read and write" permissions on repository "Contents"
# XXX: Expires 01/12/23, see docs here on generating a new one - https://bit.ly/3YNr5sM
# XXX: Expires 23/11/24, see docs here on generating a new one - https://bit.ly/3YNr5sM
PERSONAL_ACCESS_TOKEN: ${{ secrets.PROD_DEPLOY_PAT }}
run: |
set -xe
Expand Down
1 change: 0 additions & 1 deletion editor.planx.uk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-error-boundary": "^3.1.4",
"react-feather": "^2.0.10",
"react-html-parser": "^2.0.2",
"react-markdown": "^8.0.7",
"react-navi": "^0.15.0",
Expand Down
12 changes: 0 additions & 12 deletions editor.planx.uk/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React from "react";
import Wrapper from "../fixtures/Wrapper";
import { WarningContainer } from "../shared/Preview/WarningContainer";
import Editor from "./Editor";
import Public from "./Public/index";
import Public from "./Public";

export default {
title: "PlanX Components/Calculate",
Expand Down
12 changes: 12 additions & 0 deletions editor.planx.uk/src/@planx/components/Calculate/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import InputGroup from "ui/InputGroup";
import InputRow from "ui/InputRow";
import ModalSection from "ui/ModalSection";
import ModalSectionContent from "ui/ModalSectionContent";
import OptionButton from "ui/OptionButton";

import type { Calculate } from "./model";
import { evaluate, getVariables, parseCalculate } from "./model";
Expand Down Expand Up @@ -85,6 +86,17 @@ export default function Component(props: Props) {
onChange={formik.handleChange}
/>
</InputRow>
<OptionButton
selected={formik.values.formatOutputForAutomations}
onClick={() => {
formik.setFieldValue(
"formatOutputForAutomations",
!formik.values.formatOutputForAutomations,
);
}}
>
Format the output to automate a future Question or Checklist only
</OptionButton>
</ModalSectionContent>
<ModalSectionContent title="Formula">
<InputRow>
Expand Down
23 changes: 23 additions & 0 deletions editor.planx.uk/src/@planx/components/Calculate/Public.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import { setup } from "testUtils";

import Calculate from "./Public";

describe("Calculate component", () => {
it("renders correctly", () => {
const handleSubmit = jest.fn();
setup(
<Calculate
output="testGroup"
formula="pickRandom([1,2])"
formatOutputForAutomations={true}
defaults={{}}
samples={{}}
handleSubmit={handleSubmit}
/>,
);

// Calculate should be auto-answered and never shown to user
expect(handleSubmit).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@ import type { PublicProps } from "@planx/components/ui";
import { useStore } from "pages/FlowEditor/lib/store";
import { useEffect } from "react";

import type { Calculate } from "../model";
import { evaluate } from "../model";
import type { Calculate } from "./model";
import { evaluate } from "./model";

export type Props = PublicProps<Calculate>;

export default function Component(props: Props) {
const passport = useStore((state) => state.computePassport().data);

useEffect(() => {
const evaluatedResult = evaluate(props.formula, passport, props.defaults);
props.handleSubmit?.({
...makeData(
props,
evaluate(props.formula, passport, props.defaults),
props.formatOutputForAutomations ? [evaluatedResult.toString()] : evaluatedResult,
props.output,
),
// don't show this component to the user, auto=true required
// for back button to skip past this component when going back
auto: true,
});
}, []);
}, [props, passport]);

return null;
}
185 changes: 185 additions & 0 deletions editor.planx.uk/src/@planx/components/Calculate/logic.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { TYPES } from "@planx/components/types";
import { Store, vanillaStore } from "pages/FlowEditor/lib/store";

const { getState, setState } = vanillaStore;
const { upcomingCardIds, resetPreview, record, currentCard } = getState();

// Helper method
const visitedNodes = () => Object.keys(getState().breadcrumbs);

beforeEach(() => {
resetPreview();
});

test("When formatOutputForAutomations is true, Calculate writes an array and future questions are auto-answered", () => {
// Setup
setState({ flow: flowWithAutomation });
expect(upcomingCardIds()).toEqual([
"Calculate",
"Question",
]);

// Step forwards through the Calculate
record("Calculate", { data: { testGroup: ["2"] }, auto: true });
upcomingCardIds();

// The Question has been auto-answered
expect(visitedNodes()).toEqual([
"Calculate",
"Question",
]);

expect(upcomingCardIds()).toEqual([
"Group2Notice",
]);
});

test("When formatOutputForAutomations is false, Calculate writes a number and future questions are not auto-answered", () => {
// Setup
setState({ flow: flowWithoutAutomation });
expect(upcomingCardIds()).toEqual([
"Calculate",
"Question",
]);

// Step forwards through the Calculate
record("Calculate", { data: { testGroup: 2 }, auto: true });
upcomingCardIds();

// The Question has NOT been auto-answered
expect(visitedNodes()).toEqual([
"Calculate",
]);

expect(upcomingCardIds()).toEqual([
"Question"
]);
});

const flowWithAutomation: Store.flow = {
"_root": {
"edges": [
"Calculate",
"Question"
]
},
"Group2Notice": {
"data": {
"color": "#EFEFEF",
"title": "You are Group 2",
"resetButton": false
},
"type": TYPES.Notice
},
"Calculate": {
"data": {
"output": "testGroup",
"formula": "pickRandom([1,2])",
"formatOutputForAutomations": true
},
"type": TYPES.Calculate
},
"Group1Notice": {
"data": {
"color": "#EFEFEF",
"title": "You are Group 1",
"resetButton": false
},
"type": TYPES.Notice
},
"Group1Response": {
"data": {
"val": "1",
"text": "1"
},
"type": TYPES.Response,
"edges": [
"Group1Notice"
]
},
"Question": {
"data": {
"fn": "testGroup",
"text": "Which test group? "
},
"type": TYPES.Statement,
"edges": [
"Group1Response",
"Group2Response"
]
},
"Group2Response": {
"data": {
"val": "2",
"text": "2"
},
"type": TYPES.Response,
"edges": [
"Group2Notice"
]
}
};

const flowWithoutAutomation: Store.flow = {
"_root": {
"edges": [
"Calculate",
"Question"
]
},
"Group2Notice": {
"data": {
"color": "#EFEFEF",
"title": "You are Group 2",
"resetButton": false
},
"type": TYPES.Notice
},
"Calculate": {
"data": {
"output": "testGroup",
"formula": "pickRandom([1,2])",
"formatOutputForAutomations": false
},
"type": TYPES.Calculate
},
"Group1Notice": {
"data": {
"color": "#EFEFEF",
"title": "You are Group 1",
"resetButton": false
},
"type": TYPES.Notice
},
"Group1Response": {
"data": {
"val": "1",
"text": "1"
},
"type": TYPES.Response,
"edges": [
"Group1Notice"
]
},
"Question": {
"data": {
"fn": "testGroup",
"text": "Which test group? "
},
"type": TYPES.Statement,
"edges": [
"Group1Response",
"Group2Response"
]
},
"Group2Response": {
"data": {
"val": "2",
"text": "2"
},
"type": TYPES.Response,
"edges": [
"Group2Notice"
]
}
};
4 changes: 3 additions & 1 deletion editor.planx.uk/src/@planx/components/Calculate/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export interface Calculate extends MoreInformation {
defaults: Record<string, number>;
formula: string;
samples: Record<string, number>;
formatOutputForAutomations?: boolean;
}

export interface Input {
Expand All @@ -22,6 +23,7 @@ export const parseCalculate = (
defaults: data?.defaults || {},
formula: data?.formula || "",
samples: data?.samples || {},
formatOutputForAutomations: data?.formatOutputForAutomations || false,
});

export function getVariables(input: string): Set<string> {
Expand Down Expand Up @@ -82,7 +84,7 @@ export function evaluate(input: string, scope = {}, defaults = {}): number {
}
}

// Serialization is only necessary internally. v
// Serialization is only necessary internally.
// Mathjs can't handle keys with dots in their names e.g. `property.number`
// This complexity should never be exposed to this component's consumers.
function serialize(x: string) {
Expand Down
Loading
Loading