Skip to content

Commit

Permalink
Merge pull request #1942 from MoveOnOrg/stage-main-10-1
Browse files Browse the repository at this point in the history
Stage-main Release candidate 10.1
  • Loading branch information
schuyler1d authored Apr 13, 2021
2 parents a5f52ec + 15436cd commit aa672f6
Show file tree
Hide file tree
Showing 113 changed files with 1,848 additions and 1,040 deletions.
7 changes: 6 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@
"polyfill": false,
"regenerator": true
}]
]
],
"env": {
"dev": {
"plugins":["react-hot-loader/babel"]
}
}
}
28 changes: 13 additions & 15 deletions __test__/components/AssignmentSummary.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import React from "react";
import { mount } from "enzyme";
import { StyleSheetTestUtils } from "aphrodite";
import injectTapEventPlugin from "react-tap-event-plugin";
import each from "jest-each";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import { ApolloProvider } from "react-apollo";
Expand Down Expand Up @@ -80,7 +79,6 @@ describe("AssignmentSummary text", function t() {
});

describe("AssignmentSummary actions inUSA and NOT AllowSendAll", () => {
injectTapEventPlugin(); // prevents warning
function create(
unmessaged,
unreplied,
Expand Down Expand Up @@ -170,16 +168,20 @@ describe("AssignmentSummary actions inUSA and NOT AllowSendAll", () => {
const actions = create(0, 0, 0, 9, 0, false);
expect(
actions
.find(Badge)
.find(RaisedButton)
.at(0)
.prop("badgeContent")
).toBe(9);
.prop("label")
).toBe("Past 9 Messages");
});

it('renders "skipped messages (n)" with messaged', () => {
const actions = create(0, 0, 0, 0, 8, false);
expect(
actions
.find(RaisedButton)
.at(0)
.prop("label")
).toBe("Past Messages");
).toBe("Skipped 8 Messages");
});
});

Expand Down Expand Up @@ -242,7 +244,8 @@ it('renders "Send later" when there is a badTimezoneCount', () => {
unmessagedCount: 0,
unrepliedCount: 0,
badTimezoneCount: 4,
skippedMessagesCount: 0
skippedMessagesCount: 0,
pastMessagesCount: 0
}
})}
/>
Expand All @@ -251,28 +254,23 @@ it('renders "Send later" when there is a badTimezoneCount', () => {
expect(
actions
.find(Badge)
.at(1)
.at(0)
.prop("badgeContent")
).toBe(4);
expect(
actions
.find(RaisedButton)
.at(0)
.prop("label")
).toBe("Past Messages");
expect(
actions
.find(RaisedButton)
.at(1)
.prop("label")
).toBe("Send messages");
).toBe("Send later (outside timezone)");
});

describe("contacts filters", () => {
// These are an attempt to confirm that the buttons will work.
// It would be better to simulate clicking them, but I can't
// get it to work right now because of 'react-tap-event-plugin'
// some hints are here https://github.com/mui-org/material-ui/issues/4200#issuecomment-217738345
// 'react-tap-event-plugin' was depricated

it("filters correctly in USA", () => {
window.NOT_IN_USA = 0;
Expand Down
72 changes: 46 additions & 26 deletions __test__/components/CampaignInteractionStepsForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { r } from "../../src/server/models";
import { StyleSheetTestUtils } from "aphrodite";
import MuiThemeProvider from "material-ui/styles/MuiThemeProvider";
import { Card, CardHeader } from "material-ui/Card";
import GSTextField from "../../src/components/forms/GSTextField";
import GSScriptField from "../../src/components/forms/GSScriptField";
import CampaignInteractionStepsForm from "../../src/components/CampaignInteractionStepsForm";
import CampaignFormSectionHeading from "../../src/components/CampaignFormSectionHeading";
import {
Expand Down Expand Up @@ -76,23 +78,14 @@ describe("CampaignInteractionStepsForm", () => {
);

const interactionSteps = getInteractionSteps();
const scripts = component
.findWhere(
x => x.length && x.props()["data-test"] === "editorInteraction"
)
.hostNodes();
const scripts = component.find(GSScriptField);

expect(scripts.at(0).props().value).toEqual(interactionSteps[0].script);
});

it("rendered all the interaction steps", () => {
const interactionSteps = getInteractionSteps().map(step => step.script);

const scripts = component
.findWhere(
x => x.length && x.props()["data-test"] === "editorInteraction"
)
.hostNodes()
.map(script => script.props().value);
const scripts = component.find(GSScriptField).map(c => c.props().value);

expect(interactionSteps.sort()).toEqual(scripts.sort());
});
Expand Down Expand Up @@ -264,12 +257,15 @@ describe("CampaignInteractionStepsForm", () => {
const step1AnswerActionNodes = step1.findWhere(
node => node.props()["data-test"] === "actionSelect"
);

expect(step1AnswerActionNodes.last().props().value).toEqual(
expect(step1AnswerActionNodes.first().props().value).toEqual(
"red-handler"
);

expect(step1AnswerActionNodes.last().props().choices).toEqual([
{
value: "",
label: "",
},
{
value: "red-handler",
label: "Red Action"
Expand All @@ -292,11 +288,15 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step2AnswerActionNodes.last().props().value).toEqual(
expect(step2AnswerActionNodes.first().props().value).toEqual(
"purple-handler"
);

expect(step2AnswerActionNodes.last().props().choices).toEqual([
{
value: "",
label: "",
},
{
value: "red-handler",
label: "Red Action"
Expand All @@ -319,9 +319,13 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step3AnswerActionNodes.last().props().value).toEqual("");
expect(step3AnswerActionNodes.first().props().value).toEqual("");

expect(step3AnswerActionNodes.last().props().choices).toEqual([
{
value: "",
label: "",
},
{
value: "red-handler",
label: "Red Action"
Expand Down Expand Up @@ -455,11 +459,15 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step1AnswerActionNodes.last().props().value).toEqual(
expect(step1AnswerActionNodes.first().props().value).toEqual(
"color-handler"
);

expect(step1AnswerActionNodes.last().props().choices).toEqual([
{
value: "",
label: "",
},
{
value: "color-handler",
label: "Color Action"
Expand All @@ -474,12 +482,12 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionDataAutoComplete"
);

expect(step1ClientChoiceNodes.last().props().value).toEqual({
expect(step1ClientChoiceNodes.first().props().value).toEqual({
label: "red",
value: "#FF0000"
});

expect(step1ClientChoiceNodes.last().props().choices).toEqual([
expect(step1ClientChoiceNodes.first().props().choices).toEqual([
{
label: "red",
value: "#FF0000"
Expand All @@ -500,11 +508,15 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step2AnswerActionNodes.last().props().value).toEqual(
expect(step2AnswerActionNodes.first().props().value).toEqual(
"color-handler"
);

expect(step2AnswerActionNodes.last().props().choices).toEqual([
{
value: "",
label: ""
},
{
value: "color-handler",
label: "Color Action"
Expand All @@ -519,12 +531,12 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionDataAutoComplete"
);

expect(step2ClientChoiceNodes.last().props().value).toEqual({
expect(step2ClientChoiceNodes.first().props().value).toEqual({
label: "purple",
value: "#800080"
});

expect(step2ClientChoiceNodes.last().props().choices).toEqual([
expect(step2ClientChoiceNodes.first().props().choices).toEqual([
{
label: "red",
value: "#FF0000"
Expand All @@ -545,11 +557,15 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step3AnswerActionNodes.last().props().value).toEqual(
expect(step3AnswerActionNodes.first().props().value).toEqual(
"pink-handler"
);

expect(step3AnswerActionNodes.last().props().choices).toEqual([
expect(step3AnswerActionNodes.first().props().choices).toEqual([
{
value: "",
label: ""
},
{
value: "color-handler",
label: "Color Action"
Expand All @@ -572,9 +588,13 @@ describe("CampaignInteractionStepsForm", () => {
node => node.props()["data-test"] === "actionSelect"
);

expect(step4AnswerActionNodes.last().props().value).toEqual("");
expect(step4AnswerActionNodes.first().props().value).toEqual("");

expect(step4AnswerActionNodes.last().props().choices).toEqual([
expect(step4AnswerActionNodes.first().props().choices).toEqual([
{
value: "",
label: ""
},
{
value: "color-handler",
label: "Color Action"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
createStartedCampaign
} from "../../test_helpers";

describe("ConversationPreviewModal", async () => {
describe.skip("ConversationPreviewModal", async () => {
let startedCampaign;
let optOutContact;
let optOut;
Expand Down
9 changes: 5 additions & 4 deletions __test__/components/forms/GSAutoComplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import React from "react";
import { mount } from "enzyme";
import { StyleSheetTestUtils } from "aphrodite";
import AutoComplete from "material-ui/AutoComplete";

import yup from "yup";
import * as yup from "yup";

import Form from "react-formal";
import { GSAutoComplete, GSForm } from "../../../src/components/forms";
Expand Down Expand Up @@ -146,16 +147,16 @@ describe("GSAutoComplete", () => {
>
<Form.Field
name="colors"
type="autocomplete"
as={GSAutoComplete}
choices={colors}
hintText="What's your favorite color?"
/>
</GSForm>
</App>
);

gsAutoCompleteWrapper = formWrapper.find("GSAutoComplete");
autoCompleteWrapper = gsAutoCompleteWrapper.find("AutoComplete");
gsAutoCompleteWrapper = formWrapper.find(GSAutoComplete);
autoCompleteWrapper = gsAutoCompleteWrapper.find(AutoComplete);
});

it("the GSForm creates it and sets its properties", async () => {
Expand Down
12 changes: 9 additions & 3 deletions __test__/cypress/integration/basic-campaign-e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ describe("End-to-end campaign flow", () => {
.first()
.click();
// Click first of the month
cy.get("body > div:nth-of-type(2) button:contains(1)")
.first()
cy.get("body > div:nth-of-type(2) button:not([disabled])")
.eq(3)
.click();

// Wait for modal to close then submit
Expand All @@ -59,6 +59,7 @@ describe("End-to-end campaign flow", () => {

// Upload Contacts
cy.get("#contact-upload").attachFile("two-contacts.csv"), { force: true };
cy.wait(400);
cy.get("button[data-test=submitContactsCsvUpload]").click();

// Assignments
Expand All @@ -70,10 +71,15 @@ describe("End-to-end campaign flow", () => {
.contains(`${texter.first_name} ${texter.last_name}`)
.click();
cy.get("input[data-test=autoSplit]").click();
cy.get("button[data-test=submitCampaignTextersForm]").click();
cy.wait(400);
cy.get("button[data-test=submitCampaignTextersForm]").click({
force: true
});
cy.wait(400);

// Interaction Steps
cy.get("textarea[data-test=editorInteraction]").click();
cy.wait(400);
cy.get(".DraftEditor-root").type(
"Hi {{}firstName{}} this is {{}texterFirstName{}}, how are you?"
);
Expand Down
2 changes: 1 addition & 1 deletion __test__/setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { configure } from "enzyme";
import Adapter from "enzyme-adapter-react-15";
import Adapter from "enzyme-adapter-react-16";

configure({ adapter: new Adapter() });

Expand Down
2 changes: 1 addition & 1 deletion docs/HOWTO-configure-auth0.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ callback(null, user, context);
<script src="https://cdn.auth0.com/js/base64.js"></script>
<script src="https://cdn.auth0.com/js/es5-shim.min.js"></script>
<![endif]-->
<script src="https://cdn.auth0.com/js/lock/11.11/lock.min.js"></script>
<script src="https://cdn.auth0.com/js/lock/11.28/lock.min.js"></script>
<script>
// Decode utf8 characters properly
var config = JSON.parse(decodeURIComponent(escape(window.atob('@@config@@'))));
Expand Down
15 changes: 4 additions & 11 deletions docs/HOWTO_DEPLOYING_AWS_LAMBDA.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,9 @@ Create an RDS instance running Postgres 10.4 with the following settings:
aws_access_key_id = XXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
4. Configure [s3cmd](https://github.com/s3tools/s3cmd)
1. Create an AWS user called `spoke_upload`. Create a new group for it with the `AmazonS3FullAccess` policy
2. Copy the credentials of the `spoke_upload` user to `~/.s3cfg`:
```
[default]
access_key = XXXXXXXXXXXXXXXXXX
secret_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
> _TODO_: figure out how to switch away from default profile in `package.json`'s `prod-static-upload` script using ENV vars
3. [Install s3cmd](https://s3tools.org/download)
4. Install the AWS CLI
- See instructions at [AWS Command Line Interface Version 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)
- On a mac, you can also use [homebrew](https://brew.sh/) command `brew install aws-cli`

### Create Production Environment File

Expand Down Expand Up @@ -170,7 +163,7 @@ Do **NOT** set:
- `"JOB_RUNNER": "lambda-async",`: This dispatches asynchronous tasks that occur after a web response to another Lambda invocation which improves performance and completion.
- `"AWS_ACCESS_AVAILABLE": "1",`: This replaces the AWS\_ key variables for S3 bucket support
- `STATIC_BASE_URL`: You will need to upload your ASSETS_DIR to an S3 bucket (or other static file site) and then set this to something like: `"https://s3.amazonaws.com/YOUR_BUCKET_AND_PATH/"` (don't forget the trailing '/')
- `S3_STATIC_PATH`: This will be the s3cmd upload path that corresponds to STATIC_BASE_URL. So if `STATIC_BASE_URL=https://s3.amazon.com/spoke.example.com/static/` then `S3_STATIC_PATH=s3://spoke.example.com/static/` You will also need a ~/.s3cfg file that has the s3 upload credentials. See `package.json`'s postinstall script and more specifically `prod-static-upload`.
- `S3_STATIC_PATH`: This will be the aws s3 upload path that corresponds to STATIC_BASE_URL. So if `STATIC_BASE_URL=https://s3.amazon.com/spoke.example.com/static/` then `S3_STATIC_PATH=s3://spoke.example.com/static/` You will also need a ~/.s3cfg file that has the s3 upload credentials. See `package.json`'s postinstall script and more specifically `prod-static-upload`.
- `"LAMBDA_DEBUG_LOG": "1",`: (ONLY FOR DEBUGGING) This will send more details of requests to the CloudWatch log. However, it will include the full request details, e.g. so do not use this in production.

For large production environments, it might also be a good idea to add `"SUPPRESS_MIGRATIONS": "1"` so that any time you update the schema with a version upgrade,
Expand Down
Loading

0 comments on commit aa672f6

Please sign in to comment.