Skip to content

Commit

Permalink
allow custom amounts with highlight icons in widget custom_amounts param
Browse files Browse the repository at this point in the history
  • Loading branch information
hejkal committed Oct 28, 2024
1 parent 5452df5 commit ce0b6e8
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 7 deletions.
10 changes: 3 additions & 7 deletions client/js/nonprofits/donate/get-params.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// License: LGPL-3.0-or-later
const R = require('ramda')
const {getDefaultAmounts} = require('./custom_amounts');
const { parseCustomFields, splitParam } = require('./parseFields');
const { parseCustomFields, parseCustomAmounts, splitParam } = require('./parseFields');

module.exports = params => {
const defaultAmts = getDefaultAmounts().join()
// Set defaults
const merge = R.merge({
custom_amounts: ''
})
const merge = R.merge({ custom_amounts: '' })
// Preprocess data
const evolve = R.evolve({
multiple_designations: splitParam
, custom_amounts: amts => R.compose(R.map(Number), splitParam)(amts || defaultAmts)
, custom_amounts: parseCustomAmounts
, custom_fields: parseCustomFields
, tags: tags => R.map(tag => {
return tag.trim()
Expand Down
5 changes: 5 additions & 0 deletions client/js/nonprofits/donate/get-params.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ describe('.getParams', () => {
it('splits properly', () => {
expect(getParams({custom_amounts: '3.5, 600\n;400;3'})).toHaveProperty('custom_amounts', [3.5, 600, 400, 3]);
});

it('accepts custom amounts with highlight icons properly', () => {
expect(getParams({custom_amounts: "5,{amount:30,highlight:'car'},50"}))
.toHaveProperty('custom_amounts', [5, { amount: 30, highlight: 'car'}, 50]);
});

});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// License: LGPL-3.0-or-later
import JsonStringParser from './JsonStringParser';

describe('JsonStringParser', () => {

describe.each([
["with bracket", "["],
["with brace", "[{]"],
["with no amount given", "[{name:'name', label: 'LABEL'}]"],
])("when invalid %s", (_n, input)=> {
const parser = new JsonStringParser(input)
it('has correct result', () => {
expect(parser.results).toStrictEqual([]);
});

it('has error', () => {
expect(parser.errors).not.toBeEmpty();
});

it('is marked not valid', () => {
expect(parser.isValid).toBe(false)
});
});

describe.each([
['when an empty array', '[]', []],
])("when valid %s", (_name, input, result) => {
const parser = new JsonStringParser(input);

it('has no errors', () => {
expect(parser.errors).toBeEmpty();
});

it('has is marked valid', () => {
expect(parser.isValid).toStrictEqual(true);
});

it('matches expected result', () => {
expect(parser.results).toStrictEqual(result);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// License: LGPL-3.0-or-later
import has from 'lodash/has';
import { parse } from 'json5';
import { Amount, CustomAmount } from '../customAmounts';

function isCustomAmountObject(item: unknown): item is CustomAmount {
return typeof item == 'object' && has(item, 'amount');
}
export default class JsonStringParser {
public errors: SyntaxError[] = [];
public readonly results: Amount[] = [];
constructor(public readonly fieldsString: string) {
this._parse();
}

get isValid(): boolean {
return this.errors.length == 0;
}

private _parse = (): void => {
try {
const result = parse(this.fieldsString);
if (result instanceof Array) {
result.forEach((i) => {
if (isCustomAmountObject(i)) {
this.results.push({ ...i });
} else if (typeof i == 'number') {
this.results.push(i);
} else {
this.errors.push(new SyntaxError(JSON.stringify(i) + ' is not a valid custom amount'));
}
});
} else {
this.errors.push(new SyntaxError('Input did not parse to an array'));
}
} catch (e: any) {
this.errors.push(e);
}
};
}
22 changes: 22 additions & 0 deletions client/js/nonprofits/donate/parseFields/customAmounts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// License: LGPL-3.0-or-later
import JsonStringParser from './JsonStringParser';
const R = require('ramda');
const { getDefaultAmounts } = require('../../custom_amounts');
import { splitParam } from '..';

export type Amount = number | CustomAmount;

export interface CustomAmount {
amount: NonNullable<number>;
highlight: string;
}

export default function parseCustomFields(amountsString: string): Amount[] {
const defaultAmts = getDefaultAmounts().join();

if (amountsString.includes('{')) {
return new JsonStringParser(`[${amountsString}]`).results;
} else {
return R.compose(R.map(Number), splitParam)(amountsString || defaultAmts);
}
}
1 change: 1 addition & 0 deletions client/js/nonprofits/donate/parseFields/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// License: LGPL-3.0-or-later
export {default as parseCustomField, CustomFieldDescription} from "./customField";
export {default as parseCustomFields} from "./customFields";
export {default as parseCustomAmounts} from './customAmounts';

export function splitParam(param:string) : string[] {
return param.split(/[_;,]/);
Expand Down

0 comments on commit ce0b6e8

Please sign in to comment.