diff --git a/.gitignore b/.gitignore index 17c517ffa..5a92c6615 100644 --- a/.gitignore +++ b/.gitignore @@ -67,4 +67,4 @@ docs # editor files .vscode -.tsconfig +tsconfig.json diff --git a/.travis.yml b/.travis.yml index 6222310a2..2e1261c1d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,9 +34,7 @@ before_install: - npm install -g coveralls script: - npm link - - npm test + - npm test -- --coverage + - coveralls < ./.coverage/lcov.info || true - "./.scripts/prepare/app.sh" - "./.scripts/deploy/app.sh" -after_success: - - jest --coverage - - coveralls < ./.coverage/lcov.info || true diff --git a/imports/blocks/add-schedule/index.js b/imports/blocks/add-schedule/index.js index ecc253401..2836bb15c 100644 --- a/imports/blocks/add-schedule/index.js +++ b/imports/blocks/add-schedule/index.js @@ -14,7 +14,7 @@ type ICartContainer = { accounts: Object, addTransactions: Function, alive: boolean, - clearAllSchedulesExcept: Function, + // clearAllSchedulesExcept: Function, clearSchedules: Function, clearTransactions: Function, existing: Object, @@ -72,9 +72,9 @@ class CartContainer extends Component { } componentWillReceiveProps(nextProps: Object) { - const { transactions, schedules } = nextProps.give; + const { transactions, schedule } = nextProps.give; - if (Object.keys(transactions).length === 0 && Object.keys(schedules).length === 0) { + if (transactions && Object.keys(transactions).length === 0 && schedule && !schedule.start) { const form: FormElement = (document.getElementById("add-to-cart"): any); if (form) form.reset(); } @@ -93,10 +93,9 @@ class CartContainer extends Component { let keepGoing = true; if (cartFundId && cartTotal && cartFundLabel) { - this.props.clearAllSchedulesExcept(Number(this.state.fundId)); + // this.props.clearAllSchedulesExcept(Number(this.state.fundId)); - this.props.saveSchedule(this.state.fundId, { - label: this.state.fundLabel, + this.props.saveSchedule({ frequency: this.state.frequency, start: this.state.startDate, }); @@ -122,8 +121,7 @@ class CartContainer extends Component { if (this.state.fundId !== id) this.props.removeSchedule(this.state.fundId); this.setState({ fundId: id, fundLabel: name }); - this.props.saveSchedule(id, { - label: name, + this.props.saveSchedule({ frequency: this.state.frequency, start: this.state.startDate, }); @@ -134,7 +132,7 @@ class CartContainer extends Component { setFrequency = (value: string) => { this.setState({ frequency: value }); if (this.state.fundId) { - this.props.saveSchedule(this.state.fundId, { frequency: value }); + this.props.saveSchedule({ frequency: value }); } } @@ -172,7 +170,7 @@ class CartContainer extends Component { this.setState({ startDate: date }); - if (fundId) this.props.saveSchedule(fundId, { start: new Date(value) }); + if (fundId) this.props.saveSchedule({ start: new Date(value) }); return true; } diff --git a/imports/blocks/add-to-cart/index.js b/imports/blocks/add-to-cart/index.js index a579cabd0..be1df2a52 100644 --- a/imports/blocks/add-to-cart/index.js +++ b/imports/blocks/add-to-cart/index.js @@ -4,7 +4,6 @@ import { Component } from "react"; import { connect } from "react-redux"; import { give as giveActions } from "../../store"; -import { monetize } from "../../util/format/currency"; import Layout from "./Layout"; type IStore = { @@ -249,7 +248,7 @@ class CartContainer extends Component { preFillValue = (id: string) => { if (!this.state.subfunds.length) return null; const fund = this.state.subfunds.filter(({ fundId }) => fundId === id); - return fund[0] && fund[0].amount && monetize(`${fund[0].amount}`.replace(/[^0-9\.]+/g, "")); + return fund[0] && fund[0].amount && `$${String(fund[0].amount).replace(/[^0-9\.]+/g, "")}`; } toggleSecondFund = () => { diff --git a/imports/blocks/give/fieldsets/confirm/__tests__/__snapshots__/TransactionLayout.js.snap b/imports/blocks/give/fieldsets/confirm/__tests__/__snapshots__/TransactionLayout.js.snap index e0b605bfb..b026797ae 100644 --- a/imports/blocks/give/fieldsets/confirm/__tests__/__snapshots__/TransactionLayout.js.snap +++ b/imports/blocks/give/fieldsets/confirm/__tests__/__snapshots__/TransactionLayout.js.snap @@ -278,7 +278,7 @@ exports[`TransactionLayout should render with a schedule props 1`] = ` className="btn soft-half-top one-whole" type="submit"> - Schedule Using 6789 + Schedule With 6789    
- Give Using 6789 + Give With 6789    
- Complete Gift in Browser + +    +
); diff --git a/imports/blocks/give/fieldsets/shared/ButtonText.js b/imports/blocks/give/fieldsets/shared/ButtonText.js index 9c644f09d..0675ed607 100644 --- a/imports/blocks/give/fieldsets/shared/ButtonText.js +++ b/imports/blocks/give/fieldsets/shared/ButtonText.js @@ -5,6 +5,7 @@ type IButtonText = { savedAccount: Object, schedule: Object, scheduleToRecover: boolean, + overrideText?: string, }; const ButtonText = ({ @@ -12,6 +13,7 @@ const ButtonText = ({ savedAccount, schedule, scheduleToRecover, + overrideText, }: IButtonText) => { let paymentInfo = payment; @@ -24,10 +26,11 @@ const ButtonText = ({ if (schedule.start) text = "Schedule"; if (scheduleToRecover) text = "Transfer"; + if (overrideText) text = overrideText; if (paymentInfo.accountNumber || paymentInfo.cardNumber) { const masked = paymentInfo.type === "ach" ? paymentInfo.accountNumber : paymentInfo.cardNumber; - text += ` Using ${masked.replace(/-/g, "").slice(-4)}`; + text += ` With ${masked.replace(/-/g, "").slice(-4)}`; } return {text}; diff --git a/imports/blocks/give/fieldsets/shared/__tests__/ButtonText.js b/imports/blocks/give/fieldsets/shared/__tests__/ButtonText.js index 8581030b1..93dc969b8 100644 --- a/imports/blocks/give/fieldsets/shared/__tests__/ButtonText.js +++ b/imports/blocks/give/fieldsets/shared/__tests__/ButtonText.js @@ -16,26 +16,26 @@ const generateComponent = (additionalProps = {}) => { return }; -it("should say `Give Now` with minimal props", () => { +it("should say `Give` with minimal props", () => { const result = renderer.create(generateComponent()); expect(result).toMatchSnapshot(); }); -it("should say `Schedule Now` if schedule present", () => { +it("should say `Schedule` if schedule present", () => { const result = renderer.create(generateComponent({ schedule: { start: "now", frequency: null }, })); expect(result).toMatchSnapshot(); }); -it("should say `Transfer Now` if recoverable schedule", () => { +it("should say `Transfer` if recoverable schedule", () => { const result = renderer.create(generateComponent({ scheduleToRecover: true, })); expect(result).toMatchSnapshot(); }); -it("should say `Give Now using 6789` if accountNumber", () => { +it("should say `Give With 6789` if accountNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "ach", @@ -45,7 +45,7 @@ it("should say `Give Now using 6789` if accountNumber", () => { expect(result).toMatchSnapshot(); }); -it("should say `Give Now using 4321` if cardNumber", () => { +it("should say `Give With 4321` if cardNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "card", @@ -55,7 +55,7 @@ it("should say `Give Now using 4321` if cardNumber", () => { expect(result).toMatchSnapshot(); }); -it("should say `Schedule Now using 6789` if schedule and accountNumber", () => { +it("should say `Schedule With 6789` if schedule and accountNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "ach", @@ -66,7 +66,7 @@ it("should say `Schedule Now using 6789` if schedule and accountNumber", () => { expect(result).toMatchSnapshot(); }); -it("should say `Schedule Now using 4321` if schedule and cardNumber", () => { +it("should say `Schedule With 4321` if schedule and cardNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "card", @@ -77,7 +77,7 @@ it("should say `Schedule Now using 4321` if schedule and cardNumber", () => { expect(result).toMatchSnapshot(); }); -it("should say `Transfer Now using 6789` if recoverable schedule and accountNumber", () => { +it("should say `Transfer With 6789` if recoverable schedule and accountNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "ach", @@ -88,7 +88,7 @@ it("should say `Transfer Now using 6789` if recoverable schedule and accountNumb expect(result).toMatchSnapshot(); }); -it("should say `Transfer Now using 4321` if schedule and cardNumber", () => { +it("should say `Transfer With 4321` if schedule and cardNumber", () => { const result = renderer.create(generateComponent({ payment: { type: "card", diff --git a/imports/blocks/give/fieldsets/shared/__tests__/__snapshots__/ActionButton.js.snap b/imports/blocks/give/fieldsets/shared/__tests__/__snapshots__/ActionButton.js.snap index 1543e562a..f733f69c7 100644 --- a/imports/blocks/give/fieldsets/shared/__tests__/__snapshots__/ActionButton.js.snap +++ b/imports/blocks/give/fieldsets/shared/__tests__/__snapshots__/ActionButton.js.snap @@ -11,7 +11,22 @@ exports[`test should render iOS action button 1`] = `
`; @@ -21,7 +36,7 @@ exports[`test should render web action button 1`] = ` className="btn soft-half-top one-whole" type="submit"> - Give Using 6789 + Give With 6789    
- Give Using 4321 + Give With 4321 `; -exports[`test should say \`Give Now using 6789\` if accountNumber 1`] = ` +exports[`test should say \`Give With 6789\` if accountNumber 1`] = ` - Give Using 6789 + Give With 6789 `; -exports[`test should say \`Give Now\` with minimal props 1`] = ` +exports[`test should say \`Give\` with minimal props 1`] = ` Give `; -exports[`test should say \`Schedule Now using 4321\` if schedule and cardNumber 1`] = ` +exports[`test should say \`Schedule With 4321\` if schedule and cardNumber 1`] = ` - Schedule Using 4321 + Schedule With 4321 `; -exports[`test should say \`Schedule Now using 6789\` if schedule and accountNumber 1`] = ` +exports[`test should say \`Schedule With 6789\` if schedule and accountNumber 1`] = ` - Schedule Using 6789 + Schedule With 6789 `; -exports[`test should say \`Schedule Now\` if schedule present 1`] = ` +exports[`test should say \`Schedule\` if schedule present 1`] = ` Schedule `; -exports[`test should say \`Transfer Now using 4321\` if schedule and cardNumber 1`] = ` +exports[`test should say \`Transfer With 4321\` if schedule and cardNumber 1`] = ` - Transfer Using 4321 + Transfer With 4321 `; -exports[`test should say \`Transfer Now using 6789\` if recoverable schedule and accountNumber 1`] = ` +exports[`test should say \`Transfer With 6789\` if recoverable schedule and accountNumber 1`] = ` - Transfer Using 6789 + Transfer With 6789 `; -exports[`test should say \`Transfer Now\` if recoverable schedule 1`] = ` +exports[`test should say \`Transfer\` if recoverable schedule 1`] = ` Transfer diff --git a/imports/pages/give/history/Filter.js b/imports/pages/give/history/Filter.js index 0315b4fc7..4c2394eb4 100644 --- a/imports/pages/give/history/Filter.js +++ b/imports/pages/give/history/Filter.js @@ -9,7 +9,7 @@ import Date from "../../../blocks/add-to-cart/Schedule/Date"; const DATE_RANGES = [ { label: "Last Month", value: "LastMonth" }, { label: "Last 6 Months", value: "LastSixMonths" }, - { label: "Last Year", value: "LastYear" }, + { label: "Year To Date", value: "YearToDate" }, { label: "All Time", value: "AllTime" }, ]; @@ -91,8 +91,8 @@ export default class Filter extends Component { } else if (value === "LastSixMonths") { startDate = moment().subtract(6, "months"); endDate = moment(); - } else if (value === "LastYear") { - startDate = moment().subtract(12, "months"); + } else if (value === "YearToDate") { + startDate = moment().startOf("year"); endDate = moment(); } else { transactionLimit = 0; diff --git a/imports/pages/give/history/__tests__/Filter.js b/imports/pages/give/history/__tests__/Filter.js index f1b2c18a0..e4f982905 100644 --- a/imports/pages/give/history/__tests__/Filter.js +++ b/imports/pages/give/history/__tests__/Filter.js @@ -192,7 +192,7 @@ it("dataRangeClick with LastSixMonths value sets the start and end dates correct expect(wrapper.state().end).toEqual(""); }) -it("dataRangeClick with LastYear value sets the start and end dates correctly", () => { +it("dataRangeClick with YearToDate value sets the start and end dates correctly", () => { const wrapper = shallow(generateComponent()); wrapper.setState({ start: "", @@ -200,12 +200,12 @@ it("dataRangeClick with LastYear value sets the start and end dates correctly", }); // this should set a 1 year range - wrapper.instance().dateRangeClick("LastYear"); - expect(moment(wrapper.state().start).format("L")).toEqual(moment().subtract(12, "months").format("L")); + wrapper.instance().dateRangeClick("YearToDate"); + expect(moment(wrapper.state().start).format("L")).toEqual(moment().startOf("year").format("L")); expect(moment(wrapper.state().end).format("L")).toEqual(moment().format("L")); // calling it again should reset the start and end dates - wrapper.instance().dateRangeClick("LastYear"); + wrapper.instance().dateRangeClick("YearToDate"); expect(wrapper.state().start).toEqual(""); expect(wrapper.state().end).toEqual(""); }) diff --git a/imports/pages/give/history/__tests__/__snapshots__/Filter.js.snap b/imports/pages/give/history/__tests__/__snapshots__/Filter.js.snap index 116b4b22a..2ce2d8919 100644 --- a/imports/pages/give/history/__tests__/__snapshots__/Filter.js.snap +++ b/imports/pages/give/history/__tests__/__snapshots__/Filter.js.snap @@ -45,8 +45,8 @@ exports[`test doesn't render family members if there are none 1`] = ` "value": "LastSixMonths", }, Object { - "label": "Last Year", - "value": "LastYear", + "label": "Year To Date", + "value": "YearToDate", }, Object { "label": "All Time", @@ -199,8 +199,8 @@ exports[`test renders family members when expanded is true 1`] = ` "value": "LastSixMonths", }, Object { - "label": "Last Year", - "value": "LastYear", + "label": "Year To Date", + "value": "YearToDate", }, Object { "label": "All Time", @@ -381,8 +381,8 @@ exports[`test works with nickname 1`] = ` "value": "LastSixMonths", }, Object { - "label": "Last Year", - "value": "LastYear", + "label": "Year To Date", + "value": "YearToDate", }, Object { "label": "All Time", diff --git a/imports/pages/give/history/index.js b/imports/pages/give/history/index.js index 85c9a55db..d0c77312c 100644 --- a/imports/pages/give/history/index.js +++ b/imports/pages/give/history/index.js @@ -55,7 +55,7 @@ class TemplateWithoutData extends Component { .then(({ data: { transactionStatement } }) => { const blob = base64ToBlob(transactionStatement.file); this.setState({ printLoading: false }); - fileSaver.saveAs(blob, `${moment().year()} NewSpring Church Giving Summary`); + fileSaver.saveAs(blob, `${moment().year()} NewSpring Church Giving Summary.pdf`); }) .catch(() => { this.setState({ printLoading: false }); diff --git a/imports/pages/give/home/Activity.js b/imports/pages/give/home/Activity.js index d47dab3bc..8a0f498df 100644 --- a/imports/pages/give/home/Activity.js +++ b/imports/pages/give/home/Activity.js @@ -87,14 +87,14 @@ export class GivingActivity extends Component { if ((transaction.status === null || transaction.status === "Success" || transaction.status === "Complete") && transaction.details.length) { status = "success"; - linkText = "View Gift"; + linkText = "View Contribution"; linkUrl = `/give/history/${transaction.id}`; message = (

- Your {scheduled ? "scheduled " : ""}gift of ${amount} + Your {scheduled ? "scheduled " : ""}contribution of ${amount} to {transaction.details[0].account.name} {transaction.details.length > 1 ? this.additionalAmount(transaction.details[1]) : null} - was successful. + {" "}was successful.

); } else if (transaction.status === "Failed") { @@ -105,7 +105,7 @@ export class GivingActivity extends Component { {transaction.details[0].account.name} {transaction.details.length > 1 ? and {transaction.details[1].name} : null} - was unsuccessful. + {" "}was unsuccessful. {transaction.statusMessage !== null && transaction.statusMessage !== "" ? ` Unfortunately, ${transaction.statusMessage}.` : ""}

@@ -118,7 +118,7 @@ export class GivingActivity extends Component { {transaction.details[0].account.name} {transaction.details.length > 1 ? and {transaction.details[1].name} : null} - is pending. + {" "}is pending.

); } else { diff --git a/imports/pages/give/home/Schedules.js b/imports/pages/give/home/Schedules.js index 2618000a2..000db72b7 100644 --- a/imports/pages/give/home/Schedules.js +++ b/imports/pages/give/home/Schedules.js @@ -30,7 +30,7 @@ export class SchedulesList extends Component { i + amount, 0).toFixed(2)} fund={schedule.details[0].account.name} frequency={schedule.schedule.description} started={schedule.start} diff --git a/imports/pages/give/home/__tests__/__snapshots__/Schedules.js.snap b/imports/pages/give/home/__tests__/__snapshots__/Schedules.js.snap index 3f3f04ac5..d0e2f14ff 100644 --- a/imports/pages/give/home/__tests__/__snapshots__/Schedules.js.snap +++ b/imports/pages/give/home/__tests__/__snapshots__/Schedules.js.snap @@ -112,7 +112,7 @@ exports[`Giving Schedules List should render properly with data 1`] = `
({ authorized: Meteor.userId() }); // eslint-disable-next-line -export default (component: React$Component) => ( +export default (component: React$Component | Function) => ( createContainer(authorized, withData(component)) ); diff --git a/imports/pages/give/schedules/Details/Layout.js b/imports/pages/give/schedules/Details/Layout.js index 1a40181c0..d2120127e 100644 --- a/imports/pages/give/schedules/Details/Layout.js +++ b/imports/pages/give/schedules/Details/Layout.js @@ -138,7 +138,7 @@ export default ({ {schedule && (
{schedule.details.map(({ amount, account: { name } }, i) => ( -
+

{name}

diff --git a/imports/pages/give/schedules/Details/__tests__/__snapshots__/Layout.js.snap b/imports/pages/give/schedules/Details/__tests__/__snapshots__/Layout.js.snap index 7636c0fb3..2340b21e2 100644 --- a/imports/pages/give/schedules/Details/__tests__/__snapshots__/Layout.js.snap +++ b/imports/pages/give/schedules/Details/__tests__/__snapshots__/Layout.js.snap @@ -58,7 +58,7 @@ exports[`test renders complete message 1`] = `
+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ className="floating one-whole display-inline-block">

+ to="/give/home#saved-payments"> diff --git a/imports/pages/profile/settings/Menu/index.js b/imports/pages/profile/settings/Menu/index.js index 81ea8cd4f..2c4eb02ae 100644 --- a/imports/pages/profile/settings/Menu/index.js +++ b/imports/pages/profile/settings/Menu/index.js @@ -204,7 +204,7 @@ class MenuWithoutData extends Component {
- + diff --git a/imports/pages/studies/entry/index.js b/imports/pages/studies/entry/index.js index 2519f82a7..3e5e96a78 100644 --- a/imports/pages/studies/entry/index.js +++ b/imports/pages/studies/entry/index.js @@ -82,6 +82,7 @@ class StudyEntrySingle extends Component { componentWillUnmount() { if (process.env.WEB) return; + this.props.dispatch(headerActions.set({ fontWeight: null })); this.props.dispatch(liveActions.unfloat()); } diff --git a/imports/store/give/reducer/transactions.js b/imports/store/give/reducer/transactions.js index 38d62828a..79c725f7e 100644 --- a/imports/store/give/reducer/transactions.js +++ b/imports/store/give/reducer/transactions.js @@ -6,7 +6,10 @@ const addTransaction = (state, action) => { // eslint-disable-next-line no-restricted-syntax for (const fund in mergedTransactions) { - if (typeof mergedTransactions[fund].value !== "number") { + if ( + typeof mergedTransactions[fund].value !== "number" || + mergedTransactions[fund].value <= 0 + ) { delete mergedTransactions[fund]; // eslint-disable-next-line continue; @@ -35,7 +38,10 @@ const clearTransaction = (state, action) => { // eslint-disable-next-line no-restricted-syntax for (const fund in state.transactions) { - if (typeof state.transactions[fund].value !== "number") { + if ( + typeof state.transactions[fund].value !== "number" || + state.transactions[fund].value <= 0 + ) { // eslint-disable-next-line no-param-reassign delete state.transactions[fund]; // eslint-disable-next-line