@transferwise/components 46.85.0 → 46.86.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/build/avatarLayout/AvatarLayout.js +4 -3
- package/build/avatarLayout/AvatarLayout.js.map +1 -1
- package/build/avatarLayout/AvatarLayout.mjs +4 -3
- package/build/avatarLayout/AvatarLayout.mjs.map +1 -1
- package/build/avatarView/AvatarView.js +12 -1
- package/build/avatarView/AvatarView.js.map +1 -1
- package/build/avatarView/AvatarView.mjs +12 -1
- package/build/avatarView/AvatarView.mjs.map +1 -1
- package/build/circularButton/CircularButton.js +18 -21
- package/build/circularButton/CircularButton.js.map +1 -1
- package/build/circularButton/CircularButton.mjs +19 -22
- package/build/circularButton/CircularButton.mjs.map +1 -1
- package/build/definitionList/DefinitionList.js.map +1 -1
- package/build/definitionList/DefinitionList.mjs.map +1 -1
- package/build/i18n/de.json +1 -0
- package/build/i18n/de.json.js +1 -0
- package/build/i18n/de.json.js.map +1 -1
- package/build/i18n/de.json.mjs +1 -0
- package/build/i18n/de.json.mjs.map +1 -1
- package/build/i18n/es.json +1 -0
- package/build/i18n/es.json.js +1 -0
- package/build/i18n/es.json.js.map +1 -1
- package/build/i18n/es.json.mjs +1 -0
- package/build/i18n/es.json.mjs.map +1 -1
- package/build/i18n/fr.json +6 -5
- package/build/i18n/fr.json.js +6 -5
- package/build/i18n/fr.json.js.map +1 -1
- package/build/i18n/fr.json.mjs +6 -5
- package/build/i18n/fr.json.mjs.map +1 -1
- package/build/i18n/hu.json +1 -0
- package/build/i18n/hu.json.js +1 -0
- package/build/i18n/hu.json.js.map +1 -1
- package/build/i18n/hu.json.mjs +1 -0
- package/build/i18n/hu.json.mjs.map +1 -1
- package/build/i18n/id.json +1 -0
- package/build/i18n/id.json.js +1 -0
- package/build/i18n/id.json.js.map +1 -1
- package/build/i18n/id.json.mjs +1 -0
- package/build/i18n/id.json.mjs.map +1 -1
- package/build/i18n/it.json +1 -0
- package/build/i18n/it.json.js +1 -0
- package/build/i18n/it.json.js.map +1 -1
- package/build/i18n/it.json.mjs +1 -0
- package/build/i18n/it.json.mjs.map +1 -1
- package/build/i18n/pl.json +1 -0
- package/build/i18n/pl.json.js +1 -0
- package/build/i18n/pl.json.js.map +1 -1
- package/build/i18n/pl.json.mjs +1 -0
- package/build/i18n/pl.json.mjs.map +1 -1
- package/build/i18n/ro.json +1 -0
- package/build/i18n/ro.json.js +1 -0
- package/build/i18n/ro.json.js.map +1 -1
- package/build/i18n/ro.json.mjs +1 -0
- package/build/i18n/ro.json.mjs.map +1 -1
- package/build/i18n/th.json +1 -0
- package/build/i18n/th.json.js +1 -0
- package/build/i18n/th.json.js.map +1 -1
- package/build/i18n/th.json.mjs +1 -0
- package/build/i18n/th.json.mjs.map +1 -1
- package/build/i18n/tr.json +1 -0
- package/build/i18n/tr.json.js +1 -0
- package/build/i18n/tr.json.js.map +1 -1
- package/build/i18n/tr.json.mjs +1 -0
- package/build/i18n/tr.json.mjs.map +1 -1
- package/build/i18n/zh-CN.json +1 -0
- package/build/i18n/zh-CN.json.js +1 -0
- package/build/i18n/zh-CN.json.js.map +1 -1
- package/build/i18n/zh-CN.json.mjs +1 -0
- package/build/i18n/zh-CN.json.mjs.map +1 -1
- package/build/main.css +18 -159
- package/build/moneyInput/MoneyInput.js.map +1 -1
- package/build/moneyInput/MoneyInput.mjs.map +1 -1
- package/build/styles/avatarLayout/AvatarLayout.css +1 -1
- package/build/styles/circularButton/CircularButton.css +17 -158
- package/build/styles/main.css +18 -159
- package/build/types/avatarLayout/AvatarLayout.d.ts.map +1 -1
- package/build/types/avatarView/AvatarView.d.ts.map +1 -1
- package/build/types/circularButton/CircularButton.d.ts +11 -4
- package/build/types/circularButton/CircularButton.d.ts.map +1 -1
- package/build/types/definitionList/DefinitionList.d.ts +1 -2
- package/build/types/definitionList/DefinitionList.d.ts.map +1 -1
- package/build/types/moneyInput/MoneyInput.d.ts +1 -1
- package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/avatar/Avatar.story.tsx +4 -1
- package/src/avatarLayout/AvatarLayout.css +1 -1
- package/src/avatarLayout/AvatarLayout.less +1 -1
- package/src/avatarLayout/AvatarLayout.story.tsx +2 -0
- package/src/avatarLayout/AvatarLayout.tsx +6 -4
- package/src/avatarView/AvatarView.tsx +15 -1
- package/src/avatarWrapper/AvatarWrapper.story.tsx +4 -0
- package/src/badge/Badge.story.tsx +4 -0
- package/src/circularButton/CircularButton.css +17 -158
- package/src/circularButton/CircularButton.less +22 -91
- package/src/circularButton/CircularButton.story.tsx +45 -24
- package/src/circularButton/CircularButton.tsx +38 -25
- package/src/dateInput/DateInput.spec.tsx +45 -26
- package/src/definitionList/DefinitionList.story.tsx +57 -57
- package/src/definitionList/DefinitionList.tsx +1 -1
- package/src/i18n/de.json +1 -0
- package/src/i18n/es.json +1 -0
- package/src/i18n/fr.json +6 -5
- package/src/i18n/hu.json +1 -0
- package/src/i18n/id.json +1 -0
- package/src/i18n/it.json +1 -0
- package/src/i18n/pl.json +1 -0
- package/src/i18n/ro.json +1 -0
- package/src/i18n/th.json +1 -0
- package/src/i18n/tr.json +1 -0
- package/src/i18n/zh-CN.json +1 -0
- package/src/iconButton/IconButton.story.tsx +6 -6
- package/src/main.css +18 -159
- package/src/moneyInput/MoneyInput.spec.tsx +468 -0
- package/src/moneyInput/MoneyInput.tsx +2 -1
- package/src/phoneNumberInput/PhoneNumberInput.spec.tsx +283 -0
- package/src/slidingPanel/SlidingPanel.spec.tsx +69 -0
- package/src/circularButton/_button-label-states.less +0 -34
- package/src/definitionList/DefinitionList.spec.js +0 -91
- package/src/moneyInput/MoneyInput.rtl.spec.tsx +0 -149
- package/src/moneyInput/MoneyInput.spec.js +0 -820
- package/src/phoneNumberInput/PhoneNumberInput.rtl.spec.tsx +0 -32
- package/src/phoneNumberInput/PhoneNumberInput.spec.js +0 -356
- package/src/slidingPanel/SlidingPanel.spec.js +0 -56
|
@@ -1,820 +0,0 @@
|
|
|
1
|
-
import { shallow } from 'enzyme';
|
|
2
|
-
|
|
3
|
-
import { MoneyInput, Title, Input, SelectInput } from '..';
|
|
4
|
-
import { mockMatchMedia, mockResizeObserver } from '../test-utils';
|
|
5
|
-
|
|
6
|
-
mockMatchMedia();
|
|
7
|
-
mockResizeObserver();
|
|
8
|
-
|
|
9
|
-
jest.mock('../inputs/contexts', () => ({
|
|
10
|
-
...jest.requireActual('../inputs/contexts'),
|
|
11
|
-
withInputAttributes: (Component) => Component,
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
jest.mock('./currencyFormatting', () => ({
|
|
15
|
-
parseAmount: jest.fn(),
|
|
16
|
-
formatAmount: jest.fn(),
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
const numberFormatting = require('./currencyFormatting');
|
|
20
|
-
|
|
21
|
-
const defaultLocale = 'en-GB';
|
|
22
|
-
jest.mock('react-intl', () => ({
|
|
23
|
-
injectIntl: (Component) =>
|
|
24
|
-
function (props) {
|
|
25
|
-
return (
|
|
26
|
-
<Component {...props} intl={{ locale: defaultLocale, formatMessage: (id) => String(id) }} />
|
|
27
|
-
);
|
|
28
|
-
},
|
|
29
|
-
defineMessages: (translations) => translations,
|
|
30
|
-
useIntl: () => ({ locale: defaultLocale, formatMessage: (id) => String(id) }),
|
|
31
|
-
}));
|
|
32
|
-
|
|
33
|
-
describe('Money Input', () => {
|
|
34
|
-
let component;
|
|
35
|
-
let props;
|
|
36
|
-
|
|
37
|
-
let currencies;
|
|
38
|
-
|
|
39
|
-
const EEK = { value: 'EEK', label: 'EEK', currency: 'eek' };
|
|
40
|
-
|
|
41
|
-
beforeEach(() => {
|
|
42
|
-
currencies = [
|
|
43
|
-
{
|
|
44
|
-
header: 'Popular currencies',
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
value: 'EUR',
|
|
48
|
-
label: 'EUR',
|
|
49
|
-
note: 'Euro',
|
|
50
|
-
currency: 'eur',
|
|
51
|
-
searchable: 'Spain, Germany, France, Austria, Estonia',
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
value: 'USD',
|
|
55
|
-
label: 'USD',
|
|
56
|
-
note: 'United States dollar',
|
|
57
|
-
currency: 'usd',
|
|
58
|
-
searchable: 'Hong Kong, Saudi Arabia',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
value: 'GBP',
|
|
62
|
-
label: 'GBP',
|
|
63
|
-
note: 'British pound',
|
|
64
|
-
currency: 'gbp',
|
|
65
|
-
searchable: 'England, Scotland, Wales',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
header: 'Some other currencies',
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
value: 'CAD',
|
|
72
|
-
label: 'CAD',
|
|
73
|
-
note: 'Canadian dollar',
|
|
74
|
-
currency: 'cad',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
value: 'AUD',
|
|
78
|
-
label: 'AUD',
|
|
79
|
-
note: 'Australian dollar',
|
|
80
|
-
currency: 'aud',
|
|
81
|
-
},
|
|
82
|
-
];
|
|
83
|
-
props = {
|
|
84
|
-
currencies,
|
|
85
|
-
selectedCurrency: currencies[1],
|
|
86
|
-
amount: 1000,
|
|
87
|
-
onAmountChange: jest.fn(),
|
|
88
|
-
onCurrencyChange: jest.fn(),
|
|
89
|
-
};
|
|
90
|
-
component = shallow(<MoneyInput {...props} />)
|
|
91
|
-
.dive()
|
|
92
|
-
.dive();
|
|
93
|
-
jest.clearAllMocks();
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
function currencySelect() {
|
|
97
|
-
return component.find(SelectInput);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function fixedCurrencyDisplay() {
|
|
101
|
-
return component.find('.tw-money-input__fixed-currency');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function searchCurrencies(query) {
|
|
105
|
-
currencySelect().prop('onFilterChange')({
|
|
106
|
-
query,
|
|
107
|
-
queryNormalized: query.trim().replace(/\s+/gu, ' ').normalize('NFKC').toLowerCase(),
|
|
108
|
-
});
|
|
109
|
-
component.update();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function displayedCurrencies() {
|
|
113
|
-
return currencySelect().prop('items');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function getFooter() {
|
|
117
|
-
return currencySelect().prop('renderFooter');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function amountInput() {
|
|
121
|
-
return component.find(Input);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function focusAmount() {
|
|
125
|
-
amountInput().simulate('focus');
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function blurAmount() {
|
|
129
|
-
amountInput().simulate('blur');
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function enterAmount(amount) {
|
|
133
|
-
focusAmount();
|
|
134
|
-
amountInput().simulate('change', { target: { value: amount } });
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function addon() {
|
|
138
|
-
return component.find('.input-group-addon').first();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
it('renders a select with all the currencies as options', () => {
|
|
142
|
-
expect(currencySelect()).toHaveLength(1);
|
|
143
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
144
|
-
{
|
|
145
|
-
type: 'group',
|
|
146
|
-
label: 'Popular currencies',
|
|
147
|
-
options: [
|
|
148
|
-
{
|
|
149
|
-
type: 'option',
|
|
150
|
-
value: {
|
|
151
|
-
value: 'EUR',
|
|
152
|
-
label: 'EUR',
|
|
153
|
-
note: 'Euro',
|
|
154
|
-
currency: 'eur',
|
|
155
|
-
searchable: 'Spain, Germany, France, Austria, Estonia',
|
|
156
|
-
},
|
|
157
|
-
filterMatchers: ['EUR', 'EUR', 'Euro', 'Spain, Germany, France, Austria, Estonia'],
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
type: 'option',
|
|
161
|
-
value: {
|
|
162
|
-
value: 'USD',
|
|
163
|
-
label: 'USD',
|
|
164
|
-
note: 'United States dollar',
|
|
165
|
-
currency: 'usd',
|
|
166
|
-
searchable: 'Hong Kong, Saudi Arabia',
|
|
167
|
-
},
|
|
168
|
-
filterMatchers: ['USD', 'USD', 'United States dollar', 'Hong Kong, Saudi Arabia'],
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
type: 'option',
|
|
172
|
-
value: {
|
|
173
|
-
value: 'GBP',
|
|
174
|
-
label: 'GBP',
|
|
175
|
-
note: 'British pound',
|
|
176
|
-
currency: 'gbp',
|
|
177
|
-
searchable: 'England, Scotland, Wales',
|
|
178
|
-
},
|
|
179
|
-
filterMatchers: ['GBP', 'GBP', 'British pound', 'England, Scotland, Wales'],
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
type: 'group',
|
|
185
|
-
label: 'Some other currencies',
|
|
186
|
-
options: [
|
|
187
|
-
{
|
|
188
|
-
type: 'option',
|
|
189
|
-
value: {
|
|
190
|
-
value: 'CAD',
|
|
191
|
-
label: 'CAD',
|
|
192
|
-
note: 'Canadian dollar',
|
|
193
|
-
currency: 'cad',
|
|
194
|
-
},
|
|
195
|
-
filterMatchers: ['CAD', 'CAD', 'Canadian dollar', ''],
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
type: 'option',
|
|
199
|
-
value: {
|
|
200
|
-
value: 'AUD',
|
|
201
|
-
label: 'AUD',
|
|
202
|
-
note: 'Australian dollar',
|
|
203
|
-
currency: 'aud',
|
|
204
|
-
},
|
|
205
|
-
filterMatchers: ['AUD', 'AUD', 'Australian dollar', ''],
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
},
|
|
209
|
-
]);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('renders Select component with generated id when id is not provided', () => {
|
|
213
|
-
const select = component.find('SelectInput');
|
|
214
|
-
|
|
215
|
-
expect(select.prop('id')).toBeTruthy();
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('shows the currently active currency as active and hides its note', () => {
|
|
219
|
-
expect(currencySelect().prop('value')).toStrictEqual({
|
|
220
|
-
value: 'EUR',
|
|
221
|
-
label: 'EUR',
|
|
222
|
-
note: 'Euro',
|
|
223
|
-
currency: 'eur',
|
|
224
|
-
searchable: 'Spain, Germany, France, Austria, Estonia',
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it('calls onCurrencyChange when the user selects a different currency', () => {
|
|
229
|
-
expect(props.onCurrencyChange).not.toHaveBeenCalled();
|
|
230
|
-
|
|
231
|
-
currencySelect().prop('onChange')(props.currencies[2]);
|
|
232
|
-
expect(props.onCurrencyChange).toHaveBeenCalledTimes(1);
|
|
233
|
-
expect(props.onCurrencyChange).toHaveBeenLastCalledWith(props.currencies[2]);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('can be different sizes and defaults to lg', () => {
|
|
237
|
-
expect(component.find('.input-group').hasClass('input-group-lg')).toBe(true);
|
|
238
|
-
expect(currencySelect().prop('size')).toBe('lg');
|
|
239
|
-
['sm', 'md', 'lg'].forEach((size) => {
|
|
240
|
-
component.setProps({ size });
|
|
241
|
-
expect(currencySelect().prop('size')).toBe(size);
|
|
242
|
-
expect(component.find('.input-group').hasClass(`input-group-${size}`)).toBe(true);
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
describe('when searching', () => {
|
|
247
|
-
it('hides headers', () => {
|
|
248
|
-
currencies = [
|
|
249
|
-
{ header: 'A currency' },
|
|
250
|
-
{ value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
251
|
-
{ header: 'Another currency' },
|
|
252
|
-
{ value: 'EUR', label: 'Euro', currency: 'eur' },
|
|
253
|
-
];
|
|
254
|
-
component.setProps({ currencies });
|
|
255
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
256
|
-
{
|
|
257
|
-
type: 'group',
|
|
258
|
-
label: 'A currency',
|
|
259
|
-
options: [
|
|
260
|
-
{
|
|
261
|
-
type: 'option',
|
|
262
|
-
value: { value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
263
|
-
filterMatchers: ['GBP', 'British pound', '', ''],
|
|
264
|
-
},
|
|
265
|
-
],
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
type: 'group',
|
|
269
|
-
label: 'Another currency',
|
|
270
|
-
options: [
|
|
271
|
-
{
|
|
272
|
-
type: 'option',
|
|
273
|
-
value: { value: 'EUR', label: 'Euro', currency: 'eur' },
|
|
274
|
-
filterMatchers: ['EUR', 'Euro', '', ''],
|
|
275
|
-
},
|
|
276
|
-
],
|
|
277
|
-
},
|
|
278
|
-
]);
|
|
279
|
-
|
|
280
|
-
searchCurrencies('O');
|
|
281
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
282
|
-
{
|
|
283
|
-
type: 'option',
|
|
284
|
-
value: { value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
285
|
-
filterMatchers: ['GBP', 'British pound', '', ''],
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
type: 'option',
|
|
289
|
-
value: { value: 'EUR', label: 'Euro', currency: 'eur' },
|
|
290
|
-
filterMatchers: ['EUR', 'Euro', '', ''],
|
|
291
|
-
},
|
|
292
|
-
]);
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
it('searches by label', () => {
|
|
296
|
-
currencies = [
|
|
297
|
-
{ value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
298
|
-
{ value: 'EUR', label: 'Euro', currency: 'eur' },
|
|
299
|
-
];
|
|
300
|
-
component.setProps({ currencies });
|
|
301
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
302
|
-
{
|
|
303
|
-
type: 'option',
|
|
304
|
-
value: { value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
305
|
-
filterMatchers: ['GBP', 'British pound', '', ''],
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
type: 'option',
|
|
309
|
-
value: { value: 'EUR', label: 'Euro', currency: 'eur' },
|
|
310
|
-
filterMatchers: ['EUR', 'Euro', '', ''],
|
|
311
|
-
},
|
|
312
|
-
]);
|
|
313
|
-
|
|
314
|
-
searchCurrencies('P');
|
|
315
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
316
|
-
{
|
|
317
|
-
type: 'option',
|
|
318
|
-
value: { value: 'GBP', label: 'British pound', currency: 'gbp' },
|
|
319
|
-
filterMatchers: ['GBP', 'British pound', '', ''],
|
|
320
|
-
},
|
|
321
|
-
]);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
it('searches by note', () => {
|
|
325
|
-
currencies = [
|
|
326
|
-
{ value: 'GBP', label: 'British pound', currency: 'gbp', note: 'Queen money' },
|
|
327
|
-
{ value: 'EUR', label: 'Euro', currency: 'eur', note: 'Other money' },
|
|
328
|
-
];
|
|
329
|
-
component.setProps({ currencies });
|
|
330
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
331
|
-
{
|
|
332
|
-
type: 'option',
|
|
333
|
-
value: { value: 'GBP', label: 'British pound', currency: 'gbp', note: 'Queen money' },
|
|
334
|
-
filterMatchers: ['GBP', 'British pound', 'Queen money', ''],
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
type: 'option',
|
|
338
|
-
value: { value: 'EUR', label: 'Euro', currency: 'eur', note: 'Other money' },
|
|
339
|
-
filterMatchers: ['EUR', 'Euro', 'Other money', ''],
|
|
340
|
-
},
|
|
341
|
-
]);
|
|
342
|
-
|
|
343
|
-
searchCurrencies('Other');
|
|
344
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
345
|
-
{
|
|
346
|
-
type: 'option',
|
|
347
|
-
value: { value: 'EUR', label: 'Euro', currency: 'eur', note: 'Other money' },
|
|
348
|
-
filterMatchers: ['EUR', 'Euro', 'Other money', ''],
|
|
349
|
-
},
|
|
350
|
-
]);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('searches by searchable string', () => {
|
|
354
|
-
currencies = [
|
|
355
|
-
{
|
|
356
|
-
value: 'GBP',
|
|
357
|
-
label: 'British pound',
|
|
358
|
-
currency: 'gbp',
|
|
359
|
-
searchable: 'Great Britain, United Kingdom',
|
|
360
|
-
},
|
|
361
|
-
{
|
|
362
|
-
value: 'EUR',
|
|
363
|
-
label: 'Euro',
|
|
364
|
-
currency: 'eur',
|
|
365
|
-
searchable: 'Europe',
|
|
366
|
-
},
|
|
367
|
-
];
|
|
368
|
-
component.setProps({ currencies });
|
|
369
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
370
|
-
{
|
|
371
|
-
type: 'option',
|
|
372
|
-
value: {
|
|
373
|
-
value: 'GBP',
|
|
374
|
-
label: 'British pound',
|
|
375
|
-
currency: 'gbp',
|
|
376
|
-
searchable: 'Great Britain, United Kingdom',
|
|
377
|
-
},
|
|
378
|
-
filterMatchers: ['GBP', 'British pound', '', 'Great Britain, United Kingdom'],
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
type: 'option',
|
|
382
|
-
value: {
|
|
383
|
-
value: 'EUR',
|
|
384
|
-
label: 'Euro',
|
|
385
|
-
currency: 'eur',
|
|
386
|
-
searchable: 'Europe',
|
|
387
|
-
},
|
|
388
|
-
filterMatchers: ['EUR', 'Euro', '', 'Europe'],
|
|
389
|
-
},
|
|
390
|
-
]);
|
|
391
|
-
|
|
392
|
-
searchCurrencies('Britain');
|
|
393
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
394
|
-
{
|
|
395
|
-
type: 'option',
|
|
396
|
-
value: {
|
|
397
|
-
value: 'GBP',
|
|
398
|
-
label: 'British pound',
|
|
399
|
-
currency: 'gbp',
|
|
400
|
-
searchable: 'Great Britain, United Kingdom',
|
|
401
|
-
},
|
|
402
|
-
filterMatchers: ['GBP', 'British pound', '', 'Great Britain, United Kingdom'],
|
|
403
|
-
},
|
|
404
|
-
]);
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
it('shows custom action option on every search when onCustomAction is passed to MoneyInput', () => {
|
|
408
|
-
currencies = [
|
|
409
|
-
{
|
|
410
|
-
value: 'GBP',
|
|
411
|
-
label: 'British pound',
|
|
412
|
-
currency: 'gbp',
|
|
413
|
-
searchable: 'Great Britain, United Kingdom',
|
|
414
|
-
},
|
|
415
|
-
{
|
|
416
|
-
value: 'EUR',
|
|
417
|
-
label: 'Euro',
|
|
418
|
-
currency: 'eur',
|
|
419
|
-
searchable: 'Europe',
|
|
420
|
-
},
|
|
421
|
-
];
|
|
422
|
-
component.setProps({
|
|
423
|
-
currencies,
|
|
424
|
-
onCustomAction: jest.fn(),
|
|
425
|
-
customActionLabel: 'I am a label',
|
|
426
|
-
});
|
|
427
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
428
|
-
{
|
|
429
|
-
type: 'option',
|
|
430
|
-
value: {
|
|
431
|
-
value: 'GBP',
|
|
432
|
-
label: 'British pound',
|
|
433
|
-
currency: 'gbp',
|
|
434
|
-
searchable: 'Great Britain, United Kingdom',
|
|
435
|
-
},
|
|
436
|
-
filterMatchers: ['GBP', 'British pound', '', 'Great Britain, United Kingdom'],
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
type: 'option',
|
|
440
|
-
value: {
|
|
441
|
-
value: 'EUR',
|
|
442
|
-
label: 'Euro',
|
|
443
|
-
currency: 'eur',
|
|
444
|
-
searchable: 'Europe',
|
|
445
|
-
},
|
|
446
|
-
filterMatchers: ['EUR', 'Euro', '', 'Europe'],
|
|
447
|
-
},
|
|
448
|
-
]);
|
|
449
|
-
|
|
450
|
-
searchCurrencies('Britain');
|
|
451
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
452
|
-
{
|
|
453
|
-
type: 'option',
|
|
454
|
-
value: {
|
|
455
|
-
value: 'GBP',
|
|
456
|
-
label: 'British pound',
|
|
457
|
-
currency: 'gbp',
|
|
458
|
-
searchable: 'Great Britain, United Kingdom',
|
|
459
|
-
},
|
|
460
|
-
filterMatchers: ['GBP', 'British pound', '', 'Great Britain, United Kingdom'],
|
|
461
|
-
},
|
|
462
|
-
]);
|
|
463
|
-
|
|
464
|
-
searchCurrencies('Random search string');
|
|
465
|
-
expect(displayedCurrencies()).toHaveLength(0);
|
|
466
|
-
const footerNode = shallow(getFooter()()).find('div');
|
|
467
|
-
expect(footerNode).not.toBeNull();
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
it('sorts labels to first', () => {
|
|
471
|
-
searchCurrencies('au');
|
|
472
|
-
expect(displayedCurrencies()).toStrictEqual([
|
|
473
|
-
{
|
|
474
|
-
type: 'option',
|
|
475
|
-
value: {
|
|
476
|
-
value: 'AUD',
|
|
477
|
-
label: 'AUD',
|
|
478
|
-
note: 'Australian dollar',
|
|
479
|
-
currency: 'aud',
|
|
480
|
-
},
|
|
481
|
-
filterMatchers: ['AUD', 'AUD', 'Australian dollar', ''],
|
|
482
|
-
},
|
|
483
|
-
{
|
|
484
|
-
type: 'option',
|
|
485
|
-
value: {
|
|
486
|
-
value: 'EUR',
|
|
487
|
-
label: 'EUR',
|
|
488
|
-
note: 'Euro',
|
|
489
|
-
currency: 'eur',
|
|
490
|
-
searchable: 'Spain, Germany, France, Austria, Estonia',
|
|
491
|
-
},
|
|
492
|
-
filterMatchers: ['EUR', 'EUR', 'Euro', 'Spain, Germany, France, Austria, Estonia'],
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
type: 'option',
|
|
496
|
-
value: {
|
|
497
|
-
value: 'USD',
|
|
498
|
-
label: 'USD',
|
|
499
|
-
note: 'United States dollar',
|
|
500
|
-
currency: 'usd',
|
|
501
|
-
searchable: 'Hong Kong, Saudi Arabia',
|
|
502
|
-
},
|
|
503
|
-
filterMatchers: ['USD', 'USD', 'United States dollar', 'Hong Kong, Saudi Arabia'],
|
|
504
|
-
},
|
|
505
|
-
]);
|
|
506
|
-
});
|
|
507
|
-
});
|
|
508
|
-
|
|
509
|
-
describe('amount formatting', () => {
|
|
510
|
-
beforeEach(() => {
|
|
511
|
-
jest
|
|
512
|
-
.spyOn(numberFormatting, 'formatAmount')
|
|
513
|
-
.mockImplementation(
|
|
514
|
-
(number, currency, locale) => `formatted ${number}, ${locale}, ${currency}`,
|
|
515
|
-
);
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
it('formats the number you input after you blur it', () => {
|
|
519
|
-
component.setProps({ numberFormatPrecision: 3 });
|
|
520
|
-
jest.spyOn(numberFormatting, 'parseAmount').mockImplementation(Number.parseFloat);
|
|
521
|
-
enterAmount('123.45');
|
|
522
|
-
expect(amountInput().prop('value')).toBe('123.45');
|
|
523
|
-
|
|
524
|
-
blurAmount();
|
|
525
|
-
expect(amountInput().prop('value')).toBe('formatted 123.45, en-GB, eur');
|
|
526
|
-
});
|
|
527
|
-
});
|
|
528
|
-
|
|
529
|
-
it('parses the number you input and calls onAmountChange with it', () => {
|
|
530
|
-
const onAmountChange = jest.fn();
|
|
531
|
-
let assertions = 0;
|
|
532
|
-
component.setProps({ onAmountChange, numberFormatPrecision: 1 });
|
|
533
|
-
jest.spyOn(numberFormatting, 'parseAmount').mockImplementation((amount, currency, locale) => {
|
|
534
|
-
expect(amount).toBe('500.1234');
|
|
535
|
-
expect(locale).toBe(defaultLocale);
|
|
536
|
-
expect(currency).toBe('eur');
|
|
537
|
-
assertions += 1;
|
|
538
|
-
return 500.1;
|
|
539
|
-
});
|
|
540
|
-
expect(onAmountChange).not.toHaveBeenCalled();
|
|
541
|
-
|
|
542
|
-
enterAmount('500.1234');
|
|
543
|
-
expect(onAmountChange).toHaveBeenCalledTimes(1);
|
|
544
|
-
expect(onAmountChange).toHaveBeenLastCalledWith(500.1);
|
|
545
|
-
expect(assertions).toBe(1);
|
|
546
|
-
});
|
|
547
|
-
|
|
548
|
-
it('does call onAmountChange when input value is empty', () => {
|
|
549
|
-
const testValue = '';
|
|
550
|
-
const onAmountChange = jest.fn();
|
|
551
|
-
component.setProps({ onAmountChange });
|
|
552
|
-
jest.spyOn(numberFormatting, 'parseAmount').mockImplementation();
|
|
553
|
-
enterAmount(testValue);
|
|
554
|
-
expect(numberFormatting.parseAmount).not.toHaveBeenCalled();
|
|
555
|
-
expect(onAmountChange).toHaveBeenLastCalledWith(null);
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
it.each(['cannot parse this yo', ' '])(
|
|
559
|
-
"does not call onAmountChange with a parsed number if unable to parse value '%s'",
|
|
560
|
-
(testValue) => {
|
|
561
|
-
const onAmountChange = jest.fn();
|
|
562
|
-
component.setProps({ onAmountChange });
|
|
563
|
-
jest.spyOn(numberFormatting, 'parseAmount').mockImplementation(() => NaN);
|
|
564
|
-
enterAmount(testValue);
|
|
565
|
-
expect(onAmountChange).not.toHaveBeenCalled();
|
|
566
|
-
expect(numberFormatting.parseAmount).toHaveBeenLastCalledWith(
|
|
567
|
-
testValue,
|
|
568
|
-
'eur',
|
|
569
|
-
defaultLocale,
|
|
570
|
-
);
|
|
571
|
-
},
|
|
572
|
-
);
|
|
573
|
-
|
|
574
|
-
it('passes the id given to the input element', () => {
|
|
575
|
-
component.setProps({ id: 'some-id' });
|
|
576
|
-
expect(amountInput().prop('id')).toBe('some-id');
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
it('renders addon when element is passed through props', () => {
|
|
580
|
-
const addonElement = <span id="test-addon" />;
|
|
581
|
-
component.setProps({ addon: addonElement });
|
|
582
|
-
expect(addon()).toHaveLength(1);
|
|
583
|
-
|
|
584
|
-
const passedInAddon = () => addon().children().first();
|
|
585
|
-
expect(passedInAddon().prop('id')).toBe('test-addon');
|
|
586
|
-
expect(passedInAddon().type()).toBe('span');
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
it('shows fixed currency view if currencies array is empty but select currency exists', () => {
|
|
590
|
-
expect(fixedCurrencyDisplay()).toHaveLength(0);
|
|
591
|
-
|
|
592
|
-
component.setProps({
|
|
593
|
-
currencies: [],
|
|
594
|
-
selectedCurrency: EEK,
|
|
595
|
-
});
|
|
596
|
-
|
|
597
|
-
expect(currencySelect()).toHaveLength(0);
|
|
598
|
-
expect(fixedCurrencyDisplay()).toHaveLength(1);
|
|
599
|
-
expect(component.find(Title).props().children).toBe('EEK');
|
|
600
|
-
});
|
|
601
|
-
|
|
602
|
-
it('shows fixed currency view if only one currency available and selected', () => {
|
|
603
|
-
expect(fixedCurrencyDisplay()).toHaveLength(0);
|
|
604
|
-
|
|
605
|
-
component.setProps({
|
|
606
|
-
currencies: [EEK],
|
|
607
|
-
selectedCurrency: EEK,
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
expect(currencySelect()).toHaveLength(0);
|
|
611
|
-
expect(fixedCurrencyDisplay()).toHaveLength(1);
|
|
612
|
-
expect(component.find(Title).props().children).toBe('EEK');
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
it('shows fixed currency view when no function is passed to onCurrencyChange prop', () => {
|
|
616
|
-
component.setProps({ onCurrencyChange: undefined });
|
|
617
|
-
expect(currencySelect()).toHaveLength(0);
|
|
618
|
-
expect(fixedCurrencyDisplay()).toHaveLength(1);
|
|
619
|
-
});
|
|
620
|
-
|
|
621
|
-
it('does not shows fixed currency keyline and flag if small input', () => {
|
|
622
|
-
component.setProps({
|
|
623
|
-
currencies: [EEK],
|
|
624
|
-
selectedCurrency: EEK,
|
|
625
|
-
size: 'sm',
|
|
626
|
-
});
|
|
627
|
-
|
|
628
|
-
['md', 'lg'].forEach((size) => {
|
|
629
|
-
component.setProps({ size });
|
|
630
|
-
expect(component.find('.money-input-currency-flag')).toHaveLength(1);
|
|
631
|
-
});
|
|
632
|
-
|
|
633
|
-
component.setProps({ size: 'sm' });
|
|
634
|
-
expect(component.find('.money-input-currency-flag')).toHaveLength(0);
|
|
635
|
-
});
|
|
636
|
-
|
|
637
|
-
it('amount input will be disabled when there is no onAmountChange prop', () => {
|
|
638
|
-
component.setProps({
|
|
639
|
-
currencies: [EEK],
|
|
640
|
-
selectedCurrency: EEK,
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
expect(amountInput().prop('disabled')).toBe(false);
|
|
644
|
-
expect(component.find('.tw-money-input__fixed-currency').hasClass('disabled')).toBe(false);
|
|
645
|
-
|
|
646
|
-
component.setProps({ onAmountChange: undefined });
|
|
647
|
-
expect(amountInput().prop('disabled')).toBe(true);
|
|
648
|
-
expect(component.find('.tw-money-input__fixed-currency').hasClass('disabled')).toBe(true);
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
it('uses the passed in search placeholder', () => {
|
|
652
|
-
component.setProps({ searchPlaceholder: 'a placeholder' });
|
|
653
|
-
expect(currencySelect().prop('filterPlaceholder')).toBe('a placeholder');
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
it('clears the search value when selecting an option', () => {
|
|
657
|
-
const onSearchChange = jest.fn();
|
|
658
|
-
component.setProps({ onSearchChange });
|
|
659
|
-
searchCurrencies('eur');
|
|
660
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
661
|
-
searchQuery: 'eur',
|
|
662
|
-
filteredOptions: [props.currencies[1]],
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
currencySelect().prop('onChange')(props.currencies[1]);
|
|
666
|
-
component.update();
|
|
667
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
668
|
-
searchQuery: '',
|
|
669
|
-
filteredOptions: [...props.currencies],
|
|
670
|
-
});
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
it('shows custom action last when onCustomAction prop is passed to MoneyInput', () => {
|
|
674
|
-
currencies = [
|
|
675
|
-
{
|
|
676
|
-
value: 'GBP',
|
|
677
|
-
label: 'British pound',
|
|
678
|
-
currency: 'gbp',
|
|
679
|
-
searchable: 'Great Britain, United Kingdom',
|
|
680
|
-
},
|
|
681
|
-
{
|
|
682
|
-
value: 'EUR',
|
|
683
|
-
label: 'EUR',
|
|
684
|
-
currency: 'eur',
|
|
685
|
-
searchable: 'Europe',
|
|
686
|
-
},
|
|
687
|
-
];
|
|
688
|
-
const onCustomActionMock = jest.fn();
|
|
689
|
-
component.setProps({
|
|
690
|
-
currencies,
|
|
691
|
-
onCustomAction: onCustomActionMock,
|
|
692
|
-
customActionLabel: 'Label boy',
|
|
693
|
-
});
|
|
694
|
-
|
|
695
|
-
const options = displayedCurrencies();
|
|
696
|
-
|
|
697
|
-
expect(options).toHaveLength(2);
|
|
698
|
-
expect(options[0].value).toStrictEqual(currencies[0]);
|
|
699
|
-
expect(options[1].value).toStrictEqual(currencies[1]);
|
|
700
|
-
|
|
701
|
-
const footerNode = shallow(getFooter()()).find('div');
|
|
702
|
-
|
|
703
|
-
expect(footerNode.prop('role')).toBe('button');
|
|
704
|
-
expect(onCustomActionMock).toHaveBeenCalledTimes(0);
|
|
705
|
-
footerNode.simulate('click');
|
|
706
|
-
expect(onCustomActionMock).toHaveBeenCalledTimes(1);
|
|
707
|
-
});
|
|
708
|
-
|
|
709
|
-
it('calls onCustomAction callback when custom action is selected', () => {
|
|
710
|
-
const onCustomAction = jest.fn();
|
|
711
|
-
component.setProps({ onCustomAction });
|
|
712
|
-
expect(onCustomAction).not.toHaveBeenCalled();
|
|
713
|
-
expect(props.onCurrencyChange).not.toHaveBeenCalled();
|
|
714
|
-
|
|
715
|
-
const footerNode = shallow(getFooter()()).find('div');
|
|
716
|
-
expect(onCustomAction).toHaveBeenCalledTimes(0);
|
|
717
|
-
footerNode.simulate('click');
|
|
718
|
-
expect(onCustomAction).toHaveBeenCalledTimes(1);
|
|
719
|
-
expect(props.onCurrencyChange).toHaveBeenCalledTimes(0);
|
|
720
|
-
});
|
|
721
|
-
|
|
722
|
-
it('ensures namespaced classNames can be provided and used', () => {
|
|
723
|
-
const styles = { 'tw-money-input': 'tw-money-input_TWISAWESOME125' };
|
|
724
|
-
expect(component.find('.tw-money-input').exists()).toBe(true);
|
|
725
|
-
|
|
726
|
-
component.setProps({ classNames: styles });
|
|
727
|
-
expect(component.find('.tw-money-input').exists()).toBe(false);
|
|
728
|
-
expect(component.find('.tw-money-input_TWISAWESOME125').exists()).toBe(true);
|
|
729
|
-
});
|
|
730
|
-
|
|
731
|
-
describe('placeholder', () => {
|
|
732
|
-
beforeEach(() => {
|
|
733
|
-
jest
|
|
734
|
-
.spyOn(numberFormatting, 'formatAmount')
|
|
735
|
-
.mockImplementation(
|
|
736
|
-
(number, currency, locale) => `formatted ${number}, ${locale}, ${currency}`,
|
|
737
|
-
);
|
|
738
|
-
});
|
|
739
|
-
|
|
740
|
-
it('shows a formatted placeholder when provided', () => {
|
|
741
|
-
component.setProps({ placeholder: 12345.67, numberFormatPrecision: 3 });
|
|
742
|
-
expect(amountInput().prop('placeholder')).toBe('formatted 12345.67, en-GB, eur');
|
|
743
|
-
});
|
|
744
|
-
|
|
745
|
-
it('allows a placeholder of 0', () => {
|
|
746
|
-
component.setProps({ placeholder: 0, numberFormatPrecision: 3 });
|
|
747
|
-
expect(amountInput().prop('placeholder')).toBe('formatted 0, en-GB, eur');
|
|
748
|
-
});
|
|
749
|
-
});
|
|
750
|
-
|
|
751
|
-
describe('onSearchChange()', () => {
|
|
752
|
-
it('notifies the consumer when the search field is changed', () => {
|
|
753
|
-
const getCurrencyByValue = (searchValue) =>
|
|
754
|
-
currencies.find(({ value }) => value === searchValue);
|
|
755
|
-
|
|
756
|
-
const onSearchChange = jest.fn();
|
|
757
|
-
const onCustomAction = jest.fn();
|
|
758
|
-
component.setProps({
|
|
759
|
-
onSearchChange,
|
|
760
|
-
customActionLabel: 'customActionLabel',
|
|
761
|
-
onCustomAction,
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
searchCurrencies('e');
|
|
765
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
766
|
-
searchQuery: 'e',
|
|
767
|
-
filteredOptions: [
|
|
768
|
-
getCurrencyByValue('EUR'),
|
|
769
|
-
getCurrencyByValue('USD'),
|
|
770
|
-
getCurrencyByValue('GBP'),
|
|
771
|
-
],
|
|
772
|
-
});
|
|
773
|
-
|
|
774
|
-
searchCurrencies('');
|
|
775
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
776
|
-
searchQuery: '',
|
|
777
|
-
filteredOptions: [...currencies],
|
|
778
|
-
});
|
|
779
|
-
|
|
780
|
-
searchCurrencies('eur');
|
|
781
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
782
|
-
searchQuery: 'eur',
|
|
783
|
-
filteredOptions: [getCurrencyByValue('EUR')],
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
const footerNode = shallow(getFooter()()).find('div');
|
|
787
|
-
footerNode.simulate('click');
|
|
788
|
-
expect(onCustomAction).toHaveBeenCalledTimes(1);
|
|
789
|
-
expect(onSearchChange).toHaveBeenLastCalledWith({
|
|
790
|
-
searchQuery: '',
|
|
791
|
-
filteredOptions: [...currencies],
|
|
792
|
-
});
|
|
793
|
-
});
|
|
794
|
-
});
|
|
795
|
-
|
|
796
|
-
describe('when passed selectProps', () => {
|
|
797
|
-
beforeEach(() => {
|
|
798
|
-
component = shallow(
|
|
799
|
-
<MoneyInput
|
|
800
|
-
selectProps={{
|
|
801
|
-
buttonProps: {
|
|
802
|
-
'aria-label': 'mock-button-label',
|
|
803
|
-
},
|
|
804
|
-
}}
|
|
805
|
-
{...props}
|
|
806
|
-
/>,
|
|
807
|
-
)
|
|
808
|
-
.dive()
|
|
809
|
-
.dive();
|
|
810
|
-
});
|
|
811
|
-
|
|
812
|
-
it('renders Select component with expected props', () => {
|
|
813
|
-
const select = component.find('SelectInput');
|
|
814
|
-
|
|
815
|
-
expect(select.prop('buttonProps')).toStrictEqual({
|
|
816
|
-
'aria-label': 'mock-button-label',
|
|
817
|
-
});
|
|
818
|
-
});
|
|
819
|
-
});
|
|
820
|
-
});
|