@automattic/newspack-blocks 2.6.2 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cache/babel/135eb7c6e583be53418b26a29fcc4d81.json.gz +0 -0
- package/.cache/babel/2bec24377bb9890c2268bcd4c8f3953c.json.gz +0 -0
- package/.cache/babel/9ba57ee86df44178ceb255eaf0e770e3.json.gz +0 -0
- package/.cache/babel/a804bf1963e56137e59e37a567cb5e2e.json.gz +0 -0
- package/.cache/babel/b94e6dc0852876a37bd23ec88c5b2583.json.gz +0 -0
- package/.cache/babel/c04d2af94bb0f10f408a15534301cc86.json.gz +0 -0
- package/.cache/babel/c8d4b9ae4be3002e8507d71f1136ebc6.json.gz +0 -0
- package/.cache/babel/d21f5515648ce2a2349b0ee5cc787fce.json.gz +0 -0
- package/.cache/babel/d3eee0c40fc44bc734dee21a645a4f7d.json.gz +0 -0
- package/.cache/babel/d661309b03e38954105e706a32ef09f6.json.gz +0 -0
- package/.cache/babel/e2dd36051554e75a2bf087b85c11e43d.json.gz +0 -0
- package/.hooks/pre-push +2 -2
- package/CHANGELOG.md +21 -0
- package/composer.lock +38 -36
- package/dist/donate/view.asset.php +1 -1
- package/dist/donate/view.css +1 -1
- package/dist/donate/view.rtl.css +1 -1
- package/dist/editor.asset.php +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.js +11 -11
- package/dist/editor.rtl.css +1 -1
- package/dist/frequencyBased.asset.php +1 -1
- package/dist/frequencyBased.css +1 -1
- package/dist/frequencyBased.rtl.css +1 -1
- package/dist/modalCheckout.asset.php +1 -1
- package/dist/modalCheckout.css +1 -1
- package/dist/modalCheckout.rtl.css +1 -1
- package/dist/tiersBased.asset.php +1 -1
- package/dist/tiersBased.css +1 -1
- package/dist/tiersBased.js +1 -1
- package/dist/tiersBased.rtl.css +1 -1
- package/includes/class-modal-checkout.php +11 -14
- package/includes/class-newspack-blocks.php +87 -43
- package/languages/newspack-blocks-de_DE.po +0 -40
- package/languages/newspack-blocks-es_ES.po +0 -40
- package/languages/newspack-blocks-fr_BE.po +0 -40
- package/languages/newspack-blocks-pt_PT.po +0 -40
- package/languages/newspack-blocks.pot +0 -38
- package/newspack-blocks.php +2 -14
- package/package.json +7 -8
- package/src/blocks/checkout-button/edit.js +5 -1
- package/src/blocks/donate/block.json +0 -12
- package/src/blocks/donate/edit/FrequencyBasedLayout.tsx +61 -106
- package/src/blocks/donate/edit/TierBasedLayout.tsx +7 -26
- package/src/blocks/donate/edit/components/index.tsx +0 -1
- package/src/blocks/donate/edit/index.tsx +157 -152
- package/src/blocks/donate/frequency-based/style.scss +5 -0
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-base.php +33 -147
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-frequency-based.php +21 -10
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer-tiers-based.php +3 -50
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer.php +1 -14
- package/src/blocks/donate/styles/editor.scss +6 -28
- package/src/blocks/donate/styles/style-variations.scss +17 -8
- package/src/blocks/donate/styles/view.scss +9 -0
- package/src/blocks/donate/tiers-based/style.scss +0 -11
- package/src/blocks/donate/tiers-based/utils.test.js +38 -0
- package/src/blocks/donate/tiers-based/utils.ts +1 -2
- package/src/blocks/donate/tiers-based/view.ts +0 -33
- package/src/blocks/donate/types.ts +0 -16
- package/src/blocks/donate/utils.ts +31 -0
- package/src/blocks/homepage-articles/block.json +18 -0
- package/src/blocks/homepage-articles/class-wp-rest-newspack-articles-controller.php +1 -1
- package/src/blocks/homepage-articles/edit.js +3 -0
- package/src/blocks/homepage-articles/utils.ts +4 -0
- package/src/blocks/homepage-articles/view.php +4 -4
- package/src/components/query-controls.js +41 -8
- package/src/modal-checkout/checkout.scss +4 -5
- package/src/types/index.d.ts +4 -3
- package/vendor/autoload.php +1 -1
- package/vendor/composer/autoload_real.php +4 -4
- package/vendor/composer/autoload_static.php +2 -2
- package/vendor/composer/installed.php +2 -2
- package/webpack.config.js +0 -1
- package/.cache/babel/18dda1142078f066419138e7284f03bf.json.gz +0 -0
- package/.cache/babel/1f43960564787ebde7c6d44957cddf0e.json.gz +0 -0
- package/.cache/babel/225618337c609eed2be110274ff82be1.json.gz +0 -0
- package/.cache/babel/29d960d2fc51492a4bea1f4f165810fb.json.gz +0 -0
- package/.cache/babel/2f22325668b5763f8f2c9557833af36f.json.gz +0 -0
- package/.cache/babel/39bcc541624feefe54d1493493ae1ce8.json.gz +0 -0
- package/.cache/babel/4d450b37d365154f05b17cbf6a009255.json.gz +0 -0
- package/.cache/babel/87e2dc4a961b25b0de8d1a8ac88eea13.json.gz +0 -0
- package/.cache/babel/91884d41523f3790da70ea305ee187f2.json.gz +0 -0
- package/.cache/babel/b1ac90699e641ff99e1449b5d7b686e5.json.gz +0 -0
- package/.cache/babel/c5a441fdf7d90d45d2cbeb89967c61fe.json.gz +0 -0
- package/.cache/babel/c7cfb8590e887722a3e715c72ee99bac.json.gz +0 -0
- package/.cache/babel/e1d8932bb19afa36f476f107dbc6ca39.json.gz +0 -0
- package/.cache/babel/f60f8c23ec2b4448cb2815d79207d8c0.json.gz +0 -0
- package/dist/donateStreamlined.asset.php +0 -1
- package/dist/donateStreamlined.css +0 -1
- package/dist/donateStreamlined.js +0 -1
- package/dist/donateStreamlined.rtl.css +0 -1
- package/src/blocks/donate/class-wp-rest-newspack-donate-controller.php +0 -206
- package/src/blocks/donate/edit/components/AdditionalFields.tsx +0 -282
- package/src/blocks/donate/streamlined/index.test.js +0 -132
- package/src/blocks/donate/streamlined/index.ts +0 -356
- package/src/blocks/donate/streamlined/style.scss +0 -306
- package/src/blocks/donate/streamlined/utils.test.js +0 -18
- package/src/blocks/donate/streamlined/utils.ts +0 -217
- package/src/blocks/donate/tiers-based/view.test.js +0 -209
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { __ } from '@wordpress/i18n';
|
|
5
|
-
import { TextControl, ToggleControl, Button, ButtonGroup, MenuItem } from '@wordpress/components';
|
|
6
|
-
import { moreVertical, chevronUp, chevronDown } from '@wordpress/icons';
|
|
7
|
-
import { useState } from '@wordpress/element';
|
|
8
|
-
import { ESCAPE } from '@wordpress/keycodes';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* External dependencies
|
|
12
|
-
*/
|
|
13
|
-
import { omit } from 'lodash';
|
|
14
|
-
import classnames from 'classnames';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Internal dependencies
|
|
18
|
-
*/
|
|
19
|
-
import type { AdditionalField, EditProps } from '../../types';
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
21
|
-
// @ts-ignore – these *are* exported by newspack-components.
|
|
22
|
-
import { Modal, Popover } from 'newspack-components';
|
|
23
|
-
|
|
24
|
-
const getUniqID = () => Math.random().toString( 36 ).substring( 2, 7 );
|
|
25
|
-
const BASE_CSS_CLASSNAME = 'newspack-blocks-additional-fields-editor';
|
|
26
|
-
|
|
27
|
-
type EditableKey = keyof Omit< AdditionalField, 'type' >;
|
|
28
|
-
const FIELD_PROPS = [
|
|
29
|
-
[ 'label', __( 'Label', 'newspack-blocks' ) ],
|
|
30
|
-
[
|
|
31
|
-
'name',
|
|
32
|
-
__( 'Name', 'newspack-blocks' ),
|
|
33
|
-
__(
|
|
34
|
-
'Name of the field which will be sent to the payment procesor and other third parties. Field names must be unique.',
|
|
35
|
-
'newspack-blocks'
|
|
36
|
-
),
|
|
37
|
-
],
|
|
38
|
-
] as [ EditableKey, string, string ][];
|
|
39
|
-
|
|
40
|
-
const FieldOptions = ( { onEdit, onRemove }: { onEdit: () => void; onRemove: () => void } ) => {
|
|
41
|
-
const [ isVisible, setIsVisible ] = useState( false );
|
|
42
|
-
const toggleVisible = () => setIsVisible( ! isVisible );
|
|
43
|
-
return (
|
|
44
|
-
<div>
|
|
45
|
-
<Button
|
|
46
|
-
onClick={ toggleVisible }
|
|
47
|
-
icon={ moreVertical }
|
|
48
|
-
label={ __( 'Options', 'newspack-blocks' ) }
|
|
49
|
-
/>
|
|
50
|
-
{ isVisible && (
|
|
51
|
-
<Popover
|
|
52
|
-
position="bottom left"
|
|
53
|
-
onFocusOutside={ toggleVisible }
|
|
54
|
-
onKeyDown={ ( event: KeyboardEvent ) => ESCAPE === event.keyCode && toggleVisible }
|
|
55
|
-
className={ `${ BASE_CSS_CLASSNAME }__options-popover` }
|
|
56
|
-
>
|
|
57
|
-
<MenuItem onClick={ onEdit } isLink>
|
|
58
|
-
{ __( 'Edit', 'newspack-blocks' ) }
|
|
59
|
-
</MenuItem>
|
|
60
|
-
<MenuItem
|
|
61
|
-
isDestructive
|
|
62
|
-
onClick={ () => {
|
|
63
|
-
onRemove();
|
|
64
|
-
toggleVisible();
|
|
65
|
-
} }
|
|
66
|
-
isLink
|
|
67
|
-
>
|
|
68
|
-
{ __( 'Remove', 'newspack-blocks' ) }
|
|
69
|
-
</MenuItem>
|
|
70
|
-
</Popover>
|
|
71
|
-
) }
|
|
72
|
-
</div>
|
|
73
|
-
);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const FieldEditor = ( {
|
|
77
|
-
attributes,
|
|
78
|
-
setAttributes,
|
|
79
|
-
field,
|
|
80
|
-
closeEditor,
|
|
81
|
-
updateField,
|
|
82
|
-
}: Pick< EditProps, 'attributes' | 'setAttributes' > & {
|
|
83
|
-
field: AdditionalField;
|
|
84
|
-
closeEditor: () => void;
|
|
85
|
-
updateField: ( key: EditableKey ) => ( value: string | boolean | number ) => void;
|
|
86
|
-
} ) => {
|
|
87
|
-
const onSave = () => {
|
|
88
|
-
const fieldToSave = omit( field, [ 'isNew', 'fieldIndex' ] );
|
|
89
|
-
setAttributes( {
|
|
90
|
-
additionalFields: field.isNew
|
|
91
|
-
? [ ...attributes.additionalFields, fieldToSave ]
|
|
92
|
-
: attributes.additionalFields.map( ( _field, i ) =>
|
|
93
|
-
field.fieldIndex === i ? fieldToSave : _field
|
|
94
|
-
),
|
|
95
|
-
} );
|
|
96
|
-
closeEditor();
|
|
97
|
-
};
|
|
98
|
-
const onRemove = () => {
|
|
99
|
-
setAttributes( {
|
|
100
|
-
additionalFields: attributes.additionalFields.filter( ( { name } ) => name !== field.name ),
|
|
101
|
-
} );
|
|
102
|
-
closeEditor();
|
|
103
|
-
};
|
|
104
|
-
const getValidationMessage = ( key: EditableKey ) => {
|
|
105
|
-
switch ( key ) {
|
|
106
|
-
case 'name':
|
|
107
|
-
const isValid =
|
|
108
|
-
attributes.additionalFields.filter(
|
|
109
|
-
( { name }, i ) => i !== field.fieldIndex && name === field.name
|
|
110
|
-
).length === 0;
|
|
111
|
-
return ! isValid ? __( 'Name already exists.', 'newspack-blocks' ) : '';
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
return (
|
|
115
|
-
<>
|
|
116
|
-
{ FIELD_PROPS.map( ( [ key, label, help ] ) => {
|
|
117
|
-
const validationMessage = getValidationMessage( key );
|
|
118
|
-
return (
|
|
119
|
-
<div key={ key }>
|
|
120
|
-
<TextControl
|
|
121
|
-
label={ label }
|
|
122
|
-
placeholder={ label }
|
|
123
|
-
value={ field[ key ] }
|
|
124
|
-
onChange={ updateField( key ) }
|
|
125
|
-
className={ classnames( {
|
|
126
|
-
[ `${ BASE_CSS_CLASSNAME }__field-edited--name` ]: key === 'name',
|
|
127
|
-
[ `${ BASE_CSS_CLASSNAME }__field-edited--invalid` ]: validationMessage,
|
|
128
|
-
} ) }
|
|
129
|
-
/>
|
|
130
|
-
{ validationMessage && (
|
|
131
|
-
<div className={ `${ BASE_CSS_CLASSNAME }__field-edited__validation-message` }>
|
|
132
|
-
{ validationMessage }
|
|
133
|
-
</div>
|
|
134
|
-
) }
|
|
135
|
-
{ help && (
|
|
136
|
-
<div className={ `${ BASE_CSS_CLASSNAME }__field-edited__help` }>{ help }</div>
|
|
137
|
-
) }
|
|
138
|
-
</div>
|
|
139
|
-
);
|
|
140
|
-
} ) }
|
|
141
|
-
<ToggleControl
|
|
142
|
-
label={ __( 'Required', 'newspack-blocks' ) }
|
|
143
|
-
checked={ field.isRequired }
|
|
144
|
-
onChange={ updateField( 'isRequired' ) }
|
|
145
|
-
/>
|
|
146
|
-
<div className={ `${ BASE_CSS_CLASSNAME }__field-edited__width` }>
|
|
147
|
-
<div>{ __( 'Field width:', 'newspack-blocks' ) }</div>
|
|
148
|
-
<ButtonGroup>
|
|
149
|
-
{ [ 100, 66.66, 50, 33.33 ].map( width => (
|
|
150
|
-
<Button
|
|
151
|
-
key={ width }
|
|
152
|
-
onClick={ () => updateField( 'width' )( width ) }
|
|
153
|
-
isPrimary={ field.width === width }
|
|
154
|
-
>
|
|
155
|
-
{ Math.round( width ) }%
|
|
156
|
-
</Button>
|
|
157
|
-
) ) }
|
|
158
|
-
</ButtonGroup>
|
|
159
|
-
</div>
|
|
160
|
-
<div className={ `${ BASE_CSS_CLASSNAME }__edit-buttons` }>
|
|
161
|
-
<Button isLink onClick={ closeEditor }>
|
|
162
|
-
{ __( 'Cancel', 'newspack-blocks' ) }
|
|
163
|
-
</Button>
|
|
164
|
-
{ ! field.isNew && (
|
|
165
|
-
<Button variant="secondary" isDestructive onClick={ onRemove }>
|
|
166
|
-
{ __( 'Remove', 'newspack-blocks' ) }
|
|
167
|
-
</Button>
|
|
168
|
-
) }
|
|
169
|
-
<Button isPrimary onClick={ onSave }>
|
|
170
|
-
{ field.isNew ? __( 'Save', 'newspack-blocks' ) : __( 'Update', 'newspack-blocks' ) }
|
|
171
|
-
</Button>
|
|
172
|
-
</div>
|
|
173
|
-
</>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
const AdditionalFields = ( {
|
|
178
|
-
attributes,
|
|
179
|
-
setAttributes,
|
|
180
|
-
}: Pick< EditProps, 'attributes' | 'setAttributes' > ) => {
|
|
181
|
-
const [ editedField, setEditedField ] = useState< AdditionalField | null >( null );
|
|
182
|
-
const moveField = ( fieldIndex: number, targetIndex: number ) => () => {
|
|
183
|
-
const withoutMovedField = attributes.additionalFields.filter( ( _, i ) => i !== fieldIndex );
|
|
184
|
-
setAttributes( {
|
|
185
|
-
additionalFields: [
|
|
186
|
-
...withoutMovedField.slice( 0, targetIndex ),
|
|
187
|
-
attributes.additionalFields[ fieldIndex ],
|
|
188
|
-
...withoutMovedField.slice( targetIndex ),
|
|
189
|
-
],
|
|
190
|
-
} );
|
|
191
|
-
};
|
|
192
|
-
return (
|
|
193
|
-
<>
|
|
194
|
-
<p>
|
|
195
|
-
{ __(
|
|
196
|
-
'Collect additional data from donors by defining custom form fields.',
|
|
197
|
-
'newspack-blocks'
|
|
198
|
-
) }
|
|
199
|
-
</p>
|
|
200
|
-
<div className={ BASE_CSS_CLASSNAME }>
|
|
201
|
-
{ attributes.additionalFields.map( ( field, i ) => {
|
|
202
|
-
const onEdit = () => setEditedField( { ...field, fieldIndex: i } );
|
|
203
|
-
return (
|
|
204
|
-
<div key={ i } className={ `${ BASE_CSS_CLASSNAME }__field` }>
|
|
205
|
-
<div className={ `${ BASE_CSS_CLASSNAME }__field__left-section` }>
|
|
206
|
-
<div>
|
|
207
|
-
<Button
|
|
208
|
-
onClick={ moveField( i, i - 1 ) }
|
|
209
|
-
icon={ chevronUp }
|
|
210
|
-
label={ __( 'Move up', 'newspack-blocks' ) }
|
|
211
|
-
disabled={ i === 0 }
|
|
212
|
-
/>
|
|
213
|
-
<Button
|
|
214
|
-
onClick={ moveField( i, i + 1 ) }
|
|
215
|
-
icon={ chevronDown }
|
|
216
|
-
label={ __( 'Move down', 'newspack-blocks' ) }
|
|
217
|
-
disabled={ i === attributes.additionalFields.length - 1 }
|
|
218
|
-
/>
|
|
219
|
-
</div>
|
|
220
|
-
<span>{ field.label }</span>
|
|
221
|
-
</div>
|
|
222
|
-
|
|
223
|
-
<FieldOptions
|
|
224
|
-
onEdit={ onEdit }
|
|
225
|
-
onRemove={ () =>
|
|
226
|
-
setAttributes( {
|
|
227
|
-
additionalFields: attributes.additionalFields.filter(
|
|
228
|
-
( value, index ) => index !== i
|
|
229
|
-
),
|
|
230
|
-
} )
|
|
231
|
-
}
|
|
232
|
-
/>
|
|
233
|
-
</div>
|
|
234
|
-
);
|
|
235
|
-
} ) }
|
|
236
|
-
<Button
|
|
237
|
-
variant="secondary"
|
|
238
|
-
onClick={ () => {
|
|
239
|
-
const newField: AdditionalField = {
|
|
240
|
-
type: 'text',
|
|
241
|
-
name: `field-${ getUniqID() }`,
|
|
242
|
-
label: `Field ${ attributes.additionalFields.length }`,
|
|
243
|
-
isRequired: false,
|
|
244
|
-
width: 100,
|
|
245
|
-
isNew: true,
|
|
246
|
-
};
|
|
247
|
-
setEditedField( newField );
|
|
248
|
-
} }
|
|
249
|
-
>
|
|
250
|
-
{ __( 'Add data field', 'newspack-blocks' ) }
|
|
251
|
-
</Button>
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
{ editedField && (
|
|
255
|
-
<Modal
|
|
256
|
-
className={ `${ BASE_CSS_CLASSNAME }__modal` }
|
|
257
|
-
title={
|
|
258
|
-
editedField.isNew
|
|
259
|
-
? __( 'Add data field', 'newspack-blocks' )
|
|
260
|
-
: __( 'Edit data field', 'newspack-blocks' )
|
|
261
|
-
}
|
|
262
|
-
onRequestClose={ () => setEditedField( null ) }
|
|
263
|
-
>
|
|
264
|
-
<FieldEditor
|
|
265
|
-
field={ editedField }
|
|
266
|
-
setAttributes={ setAttributes }
|
|
267
|
-
attributes={ attributes }
|
|
268
|
-
closeEditor={ () => setEditedField( null ) }
|
|
269
|
-
updateField={ ( key: EditableKey ) => ( value: string | boolean | number ) => {
|
|
270
|
-
setEditedField( {
|
|
271
|
-
...editedField,
|
|
272
|
-
[ key ]: value,
|
|
273
|
-
} );
|
|
274
|
-
} }
|
|
275
|
-
/>
|
|
276
|
-
</Modal>
|
|
277
|
-
) }
|
|
278
|
-
</>
|
|
279
|
-
);
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
export default AdditionalFields;
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import * as testingLibrary from '@testing-library/dom';
|
|
2
|
-
import userEvent from '@testing-library/user-event';
|
|
3
|
-
import fetchMock from 'fetch-mock-jest';
|
|
4
|
-
import { encode } from 'html-entities';
|
|
5
|
-
|
|
6
|
-
import { processStreamlinedElements } from '.';
|
|
7
|
-
|
|
8
|
-
const MONTHLY_AMOUNT = 7;
|
|
9
|
-
|
|
10
|
-
const createDOM = settings => {
|
|
11
|
-
const parentElement = document.createElement( 'div' );
|
|
12
|
-
parentElement.innerHTML = `
|
|
13
|
-
<style>.stripe-payment--hidden {display:none;}</style>
|
|
14
|
-
<form data-streamlined-config="${ encode( JSON.stringify( settings ) ) }">
|
|
15
|
-
<div class='frequencies'>
|
|
16
|
-
<div class='frequency'>
|
|
17
|
-
<input type="radio" value="once" id="once" name="donation_frequency">
|
|
18
|
-
<label for="once">Once</label>
|
|
19
|
-
<input type="number" name="donation_value_once" value="${ MONTHLY_AMOUNT * 12 }" />
|
|
20
|
-
</div>
|
|
21
|
-
<div class='frequency'>
|
|
22
|
-
<input type="radio" value="month" id="month" name="donation_frequency" checked>
|
|
23
|
-
<label for="month">Monthly</label>
|
|
24
|
-
<input type="number" name="donation_value_month" value="${ MONTHLY_AMOUNT }" />
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="stripe-payment">
|
|
28
|
-
<div class="stripe-payment__inputs stripe-payment--hidden">
|
|
29
|
-
<input required="" placeholder="Email" type="email" name="email" value="">
|
|
30
|
-
<input required="" placeholder="Full Name" type="text" name="full_name" value="">
|
|
31
|
-
</div>
|
|
32
|
-
<label>
|
|
33
|
-
<input type="checkbox" name="agree_to_pay_fees" checked value="true">Agree to pay fees?
|
|
34
|
-
<span id="stripe-fees-amount">($0)</span>
|
|
35
|
-
</label>
|
|
36
|
-
<div class="stripe-payment__messages"></div>
|
|
37
|
-
<button type="submit">Donate</button>
|
|
38
|
-
</div>
|
|
39
|
-
<input name="cid" type="hidden" value="cid-123" />
|
|
40
|
-
</form>
|
|
41
|
-
`;
|
|
42
|
-
document.body.appendChild( parentElement );
|
|
43
|
-
return document.body;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
fetchMock.post(
|
|
47
|
-
'/wp-json/newspack-blocks/v1/donate',
|
|
48
|
-
{ status: 'success', client_secret: 'sec_123' },
|
|
49
|
-
// A slight delay, necessitated by the async behavior of @testing-library/user-event.
|
|
50
|
-
// See https://github.com/testing-library/user-event/pull/952
|
|
51
|
-
{ delay: 100 }
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const frequencies = { once: 'Once', month: 'Monthly', year: 'Annually' };
|
|
55
|
-
const feeMultiplier = '2.9';
|
|
56
|
-
const feeStatic = '0.3';
|
|
57
|
-
const settings = [ 'USD', '$', 'Testing Site', false, 'US', frequencies, feeMultiplier, feeStatic ];
|
|
58
|
-
|
|
59
|
-
describe( 'Streamlined Donate block processing', () => {
|
|
60
|
-
const container = createDOM( settings );
|
|
61
|
-
processStreamlinedElements( container );
|
|
62
|
-
|
|
63
|
-
const button = testingLibrary.getByText( container, 'Donate' );
|
|
64
|
-
const emailInput = testingLibrary.getByPlaceholderText( container, 'Email' );
|
|
65
|
-
const nameInput = testingLibrary.getByPlaceholderText( container, 'Full Name' );
|
|
66
|
-
|
|
67
|
-
it( 'additional inputs are initially hidden and displayed after user clicks the button', async () => {
|
|
68
|
-
expect( emailInput ).not.toBeVisible();
|
|
69
|
-
await userEvent.click( button );
|
|
70
|
-
expect( emailInput ).toBeVisible();
|
|
71
|
-
} );
|
|
72
|
-
|
|
73
|
-
it( 'form submission with invalid values triggers validation errors', async () => {
|
|
74
|
-
await userEvent.click( button );
|
|
75
|
-
expect(
|
|
76
|
-
testingLibrary.getByText( container, 'Email address is invalid.' )
|
|
77
|
-
).toBeInTheDocument();
|
|
78
|
-
expect(
|
|
79
|
-
testingLibrary.getByText( container, 'Full name should be provided.' )
|
|
80
|
-
).toBeInTheDocument();
|
|
81
|
-
|
|
82
|
-
await userEvent.type( emailInput, 'foo@bar.com' );
|
|
83
|
-
await userEvent.click( button );
|
|
84
|
-
expect(
|
|
85
|
-
testingLibrary.queryByText( container, 'Email address is invalid.' )
|
|
86
|
-
).not.toBeInTheDocument();
|
|
87
|
-
} );
|
|
88
|
-
|
|
89
|
-
it( 'the fee amount is updated', () => {
|
|
90
|
-
expect( testingLibrary.getByText( container, '($0.52 monthly)' ) ).toBeInTheDocument();
|
|
91
|
-
} );
|
|
92
|
-
|
|
93
|
-
it( 'form can be submitted after validation passes', async () => {
|
|
94
|
-
await userEvent.type( nameInput, 'Bax' );
|
|
95
|
-
await userEvent.click( button );
|
|
96
|
-
expect(
|
|
97
|
-
testingLibrary.queryByText( container, 'Full name should be provided.' )
|
|
98
|
-
).not.toBeInTheDocument();
|
|
99
|
-
expect( testingLibrary.getByText( container, 'Processing payment…' ) ).toBeInTheDocument();
|
|
100
|
-
} );
|
|
101
|
-
|
|
102
|
-
it( 'final success message is displayed', async () => {
|
|
103
|
-
await testingLibrary.waitFor( () => {
|
|
104
|
-
expect(
|
|
105
|
-
testingLibrary.getByText(
|
|
106
|
-
container,
|
|
107
|
-
'Your payment has been processed. Thank you for your contribution! You will receive a confirmation email at foo@bar.com.'
|
|
108
|
-
)
|
|
109
|
-
).toBeInTheDocument();
|
|
110
|
-
} );
|
|
111
|
-
} );
|
|
112
|
-
|
|
113
|
-
it( 'correct payload was sent to the API', () => {
|
|
114
|
-
expect( fetchMock ).toHaveLastFetched(
|
|
115
|
-
'/wp-json/newspack-blocks/v1/donate',
|
|
116
|
-
{
|
|
117
|
-
body: {
|
|
118
|
-
stripe_source_id: 'src_123',
|
|
119
|
-
stripe_tokenization_method: 'card',
|
|
120
|
-
amount: 7.52,
|
|
121
|
-
email: 'foo@bar.com',
|
|
122
|
-
full_name: 'Bax',
|
|
123
|
-
frequency: 'month',
|
|
124
|
-
newsletter_opt_in: false,
|
|
125
|
-
clientId: 'cid-123',
|
|
126
|
-
additional_fields: [],
|
|
127
|
-
},
|
|
128
|
-
},
|
|
129
|
-
'post'
|
|
130
|
-
);
|
|
131
|
-
} );
|
|
132
|
-
} );
|