forked from houdiniproject/houdini
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #935 from CommitChange/widget-custom-amounts-with-…
…highlights allow custom amounts with highlight icons in widget custom_amounts param
- Loading branch information
Showing
10 changed files
with
268 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
client/js/nonprofits/donate/parseFields/customAmount/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// License: LGPL-3.0-or-later | ||
import has from 'lodash/has'; | ||
|
||
export interface CustomAmount { | ||
amount: NonNullable<number>; | ||
highlight: NonNullable<string | false>; | ||
} | ||
|
||
export function isCustomAmountObject(item: unknown): item is CustomAmount { | ||
return typeof item == 'object' && has(item, 'amount'); | ||
} |
69 changes: 69 additions & 0 deletions
69
client/js/nonprofits/donate/parseFields/customAmounts/JsonStringParser.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// License: LGPL-3.0-or-later | ||
import JsonStringParser from './JsonStringParser'; | ||
|
||
describe('JsonStringParser', () => { | ||
describe.each([ | ||
['with bracket', '['], | ||
['with brace', '[{]'], | ||
['without brackets', '2,3,4'], | ||
['with letters', '[letters]'], | ||
['with no amount given', "[{highlight: 'car'}]"], | ||
])('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', '[]', []], | ||
[ | ||
'with all numbers', | ||
'[1,2.5,3]', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2.5, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'with some numbers and some objects', | ||
"[1,{amount:2.5,highlight:'icon'},3]", | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2.5, highlight: 'icon' }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'with objects', | ||
"[{amount:2.5,highlight:'icon'},{amount:5}]", | ||
[ | ||
{ amount: 2.5, highlight: 'icon' }, | ||
{ amount: 5, highlight: false }, | ||
], | ||
], | ||
])('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); | ||
}); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
client/js/nonprofits/donate/parseFields/customAmounts/JsonStringParser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// License: LGPL-3.0-or-later | ||
import { parse } from 'json5'; | ||
import { CustomAmount, isCustomAmountObject } from '../customAmount'; | ||
|
||
export default class JsonStringParser { | ||
public errors: SyntaxError[] = []; | ||
public readonly results: CustomAmount[] = []; | ||
constructor(public readonly fieldsString: string) { | ||
this._parse(); | ||
} | ||
|
||
get isValid(): boolean { | ||
return this.errors.length == 0; | ||
} | ||
|
||
private _parse = (): void => { | ||
try { | ||
const result = parse(this.fieldsString); | ||
const emptyCustomAmount = { highlight: false }; | ||
if (result instanceof Array) { | ||
result.forEach((i) => { | ||
if (isCustomAmountObject(i)) { | ||
this.results.push({ ...emptyCustomAmount, ...i }); | ||
} else if (typeof i == 'number') { | ||
this.results.push({ amount: i, highlight: false }); | ||
} 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); | ||
} | ||
}; | ||
} |
67 changes: 67 additions & 0 deletions
67
client/js/nonprofits/donate/parseFields/customAmounts/index.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// License: LGPL-3.0-or-later | ||
import parseCustomAmounts from '.'; | ||
import { getDefaultAmounts } from '../../custom_amounts'; | ||
|
||
describe.each([ | ||
['maps default amounts', '', getDefaultAmounts().map((a: number) => ({ amount: a, highlight: false }))], | ||
[ | ||
'maps integers correctly', | ||
'1,2,3', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'accepts integers, floats, and extraneous spaces', | ||
'1, 2.5,3 ,456', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2.5, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
{ amount: 456, highlight: false }, | ||
], | ||
], | ||
[ | ||
'accepts a mix of numbers and objects with amounts and highlights', | ||
'1, {amount: 2.5, highlight:"icon"},3', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2.5, highlight: 'icon' }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'omits invalid objects', | ||
'1, {highlight: "icon"},3', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'accepts objects without highlights and maps them to false', | ||
'1, {amount:2 },3', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'accepts mixed inputs with array brackets', | ||
'[1,{amount:52},3]', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 52, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
])('parseCustomField', (name, input, result) => { | ||
describe('parseCustomAmounts', () => { | ||
it(name, () => { | ||
expect(parseCustomAmounts(input)).toStrictEqual(result); | ||
}); | ||
}); | ||
}); |
17 changes: 17 additions & 0 deletions
17
client/js/nonprofits/donate/parseFields/customAmounts/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// License: LGPL-3.0-or-later | ||
import JsonStringParser from './JsonStringParser'; | ||
import { getDefaultAmounts } from '../../custom_amounts'; | ||
import { CustomAmount } from '../customAmount'; | ||
import parseNumberAmounts from './parseNumberAmounts'; | ||
|
||
export default function parseCustomAmounts(amountsString: string): CustomAmount[] { | ||
const defaultAmts = getDefaultAmounts().join(); | ||
|
||
if (amountsString.includes('{')) { | ||
if (!amountsString.startsWith('[')) amountsString = `[${amountsString}`; | ||
if (!amountsString.endsWith(']')) amountsString = `${amountsString}]`; | ||
return new JsonStringParser(amountsString).results; | ||
} else { | ||
return parseNumberAmounts(amountsString || defaultAmts); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
client/js/nonprofits/donate/parseFields/customAmounts/parseNumberAmounts.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// License: LGPL-3.0-or-later | ||
import parseNumberAmounts from './parseNumberAmounts'; | ||
|
||
describe.each([ | ||
['when empty', '', []], | ||
[ | ||
'when integers', | ||
'1,2,3', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
], | ||
], | ||
[ | ||
'when integers, floats, and spaces', | ||
'1,2.5,3 ,456', | ||
[ | ||
{ amount: 1, highlight: false }, | ||
{ amount: 2.5, highlight: false }, | ||
{ amount: 3, highlight: false }, | ||
{ amount: 456, highlight: false }, | ||
], | ||
], | ||
])('parseCustomField', (name, input, result) => { | ||
describe(name, () => { | ||
it('maps the numbers as expected', () => { | ||
expect(parseNumberAmounts(input)).toStrictEqual(result); | ||
}); | ||
}); | ||
}); |
8 changes: 8 additions & 0 deletions
8
client/js/nonprofits/donate/parseFields/customAmounts/parseNumberAmounts.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// License: LGPL-3.0-or-later | ||
import { CustomAmount } from '../customAmount'; | ||
import { splitParam } from '..'; | ||
|
||
export default function parseNumberAmounts(amountsString: string): CustomAmount[] { | ||
if (amountsString.length === 0) return []; | ||
return splitParam(amountsString).map((n) => ({ amount: Number(n), highlight: false })); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters