@transferwise/comparison-components 19.0.1 → 19.1.0-beta.2
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/CHANGELOG.md +11 -0
- package/dist/es/{ComparisonTableHeroContainer-a6db7d33.js → ComparisonTableHeroContainer-373c7ad7.js} +2 -2
- package/dist/es/{ComparisonTableHeroContainer-a6db7d33.js.map → ComparisonTableHeroContainer-373c7ad7.js.map} +1 -1
- package/dist/es/{ErrorTemplate-aa9cc171.js → ErrorTemplate-ca54b701.js} +2 -2
- package/dist/es/{ErrorTemplate-aa9cc171.js.map → ErrorTemplate-ca54b701.js.map} +1 -1
- package/dist/es/ProviderComparisonTable-ffcf7b99.js +2 -0
- package/dist/es/{ProviderComparisonTable-72cea4dc.js.map → ProviderComparisonTable-ffcf7b99.js.map} +1 -1
- package/dist/es/Quote-9f323d3e.js +2 -0
- package/dist/es/Quote-9f323d3e.js.map +1 -0
- package/dist/es/ReceiveAmount-d79ccfd8.js +2 -0
- package/dist/es/{ReceiveAmount-6b98e864.js.map → ReceiveAmount-d79ccfd8.js.map} +1 -1
- package/dist/es/TransferFeeComparisonContainer-f66d3eea.js +2 -0
- package/dist/es/{TransferFeeComparisonContainer-931c55ad.js.map → TransferFeeComparisonContainer-f66d3eea.js.map} +1 -1
- package/dist/es/TravelMoney-f31ec1d4.js +2 -0
- package/dist/es/{TravelMoney-07289b78.js.map → TravelMoney-f31ec1d4.js.map} +1 -1
- package/dist/es/comparison/index.js +1 -1
- package/dist/es/comparison/index.js.map +1 -1
- package/dist/es/comparison-table/index.js +1 -1
- package/dist/es/comparison-table-hero/index.js +1 -1
- package/dist/es/index-27dd3bd3.js +2 -0
- package/dist/es/index-27dd3bd3.js.map +1 -0
- package/dist/es/index.js +1 -1
- package/dist/es/index.js.map +1 -1
- package/dist/es/provider-comparison-table/index.js +1 -1
- package/dist/es/provider-comparison-widget/index.js +1 -1
- package/dist/es/provider-comparison-widget/index.js.map +1 -1
- package/dist/es/savingsCalculator-894a963b.js +2 -0
- package/dist/es/savingsCalculator-894a963b.js.map +1 -0
- package/dist/es/savingsCalculator.js +2 -0
- package/dist/es/savingsCalculator.js.map +1 -0
- package/dist/es/transfer-fee-comparison/index.js +1 -1
- package/dist/es/transformQuotesResponseV2.js +1 -1
- package/dist/es/travel-money/index.js +1 -1
- package/dist/umd/comparison-components.css +1 -1
- package/dist/umd/comparison-components.js +5 -5
- package/dist/umd/comparison-components.js.map +1 -1
- package/dist/umd/transfer-fee-comparison/transfer-fee-comparison.js +4 -4
- package/dist/umd/transfer-fee-comparison/transfer-fee-comparison.js.map +1 -1
- package/package.json +1 -1
- package/src/common/numberEqualsWithRelativeTolerance/index.js +1 -0
- package/src/common/numberEqualsWithRelativeTolerance/numberEqualsWithRelativeTolerance.spec.ts +57 -0
- package/src/common/numberEqualsWithRelativeTolerance/numberEqualsWithRelativeTolerance.ts +26 -0
- package/src/provider-filters/largest-provider/config.ts +2 -2
- package/src/resources/clients/quotes/__test__/transformQuotesResponseV2.spec.ts +244 -3
- package/src/resources/clients/quotes/transformQuotesResponseV2.ts +14 -5
- package/src/transfer-fee-comparison/domain/Quote.ts +1 -0
- package/src/transfer-fee-comparison/mocks/Quotes.ts +16 -0
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/TransferFeeComparisonTableRow.tsx +1 -4
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/FeeMakeupPopover.tsx +2 -6
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_bg.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_cs.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_de.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_el.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_en.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_es.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_fr.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_hu.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_id.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_it.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_ja.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_nl.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_no.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_pl.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_pt.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_ro.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_ru.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_sk.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_sv.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_tr.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_uk.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/messages_zh.json +1 -1
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/assets/translations/translations.json +22 -22
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/fee-element/NonTransparentFeeElement.tsx +1 -2
- package/src/transfer-fee-comparison/transfer-fee-comparison-table-row/fee-makeup-popover/fee-element/TransparentFeeElement.tsx +20 -9
- package/dist/es/ProviderComparisonTable-72cea4dc.js +0 -2
- package/dist/es/Quote-82e8a493.js +0 -2
- package/dist/es/Quote-82e8a493.js.map +0 -1
- package/dist/es/ReceiveAmount-6b98e864.js +0 -2
- package/dist/es/TransferFeeComparisonContainer-931c55ad.js +0 -2
- package/dist/es/TravelMoney-07289b78.js +0 -2
- package/dist/es/index-292bb49a.js +0 -2
- package/dist/es/index-292bb49a.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@transferwise/comparison-components",
|
|
3
|
-
"version": "19.0.
|
|
3
|
+
"version": "19.1.0-beta.2",
|
|
4
4
|
"description": "Display a comparison table of providers given a route and amount.",
|
|
5
5
|
"homepage": "https://wise.com/gb/compare/",
|
|
6
6
|
"main": "dist/umd/comparison-components.js",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { numberEqualsWithRelativeTolerance as default } from './numberEqualsWithRelativeTolerance';
|
package/src/common/numberEqualsWithRelativeTolerance/numberEqualsWithRelativeTolerance.spec.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { numberEqualsWithRelativeTolerance } from './numberEqualsWithRelativeTolerance';
|
|
2
|
+
|
|
3
|
+
describe('numberEqualsWithRelativeTolerance', () => {
|
|
4
|
+
it('should be true when two numbers are exactly the same', () => {
|
|
5
|
+
const x = 42;
|
|
6
|
+
const y = 42;
|
|
7
|
+
|
|
8
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0);
|
|
9
|
+
|
|
10
|
+
expect(result).toBeTruthy();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should be false when two numbers are not the same', () => {
|
|
14
|
+
const x = 42;
|
|
15
|
+
const y = 42.1;
|
|
16
|
+
|
|
17
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0);
|
|
18
|
+
|
|
19
|
+
expect(result).toBeFalsy();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should be true when different numbers are equals given the tolerance', () => {
|
|
23
|
+
const x = 42;
|
|
24
|
+
const y = 42.1;
|
|
25
|
+
|
|
26
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0.003);
|
|
27
|
+
|
|
28
|
+
expect(result).toBeTruthy();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should be false when different numbers are not equals given the tolerance', () => {
|
|
32
|
+
const x = 42;
|
|
33
|
+
const y = 42.1;
|
|
34
|
+
|
|
35
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0.002);
|
|
36
|
+
|
|
37
|
+
expect(result).toBeFalsy();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should be true when different big numbers are equals given the tolerance', () => {
|
|
41
|
+
const x = 42_000_000.0;
|
|
42
|
+
const y = 42_100_000.1;
|
|
43
|
+
|
|
44
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0.003);
|
|
45
|
+
|
|
46
|
+
expect(result).toBeTruthy();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should be false when different big numbers are not equals given the tolerance', () => {
|
|
50
|
+
const x = 42_000_000.0;
|
|
51
|
+
const y = 42_100_000.1;
|
|
52
|
+
|
|
53
|
+
const result = numberEqualsWithRelativeTolerance(x, y, 0.002);
|
|
54
|
+
|
|
55
|
+
expect(result).toBeFalsy();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns {@code true} if there is no double value strictly between the
|
|
3
|
+
* arguments or the relative difference between them is less than or equal
|
|
4
|
+
* to the given tolerance. Returns {@code false} if either of the arguments
|
|
5
|
+
* is NaN.
|
|
6
|
+
*
|
|
7
|
+
* @param x First value.
|
|
8
|
+
* @param y Second value.
|
|
9
|
+
* @param epsilon Amount of allowed relative error.
|
|
10
|
+
* @return {@code true} if the values are two adjacent floating point
|
|
11
|
+
* numbers or they are within range of each other.
|
|
12
|
+
*/
|
|
13
|
+
export const numberEqualsWithRelativeTolerance = (
|
|
14
|
+
x: number,
|
|
15
|
+
y: number,
|
|
16
|
+
epsilon: number,
|
|
17
|
+
): boolean => {
|
|
18
|
+
if (x === y) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const absoluteMax = Math.max(Math.abs(x), Math.abs(y));
|
|
23
|
+
const relativeDifference = Math.abs((x - y) / absoluteMax);
|
|
24
|
+
|
|
25
|
+
return relativeDifference <= epsilon;
|
|
26
|
+
};
|
|
@@ -7,6 +7,6 @@ export const largestProviderByCountry: Map<string, Array<string>> = new Map([
|
|
|
7
7
|
['us', [PAYPAL, WESTERN_UNION, 'chase', 'moneygram', 'wells-fargo', 'xoom', TW_ALIAS]],
|
|
8
8
|
['au', [PAYPAL, WESTERN_UNION, 'commonwealth-bank-of-australia', 'anz', 'westpac', 'national-australia-bank', TW_ALIAS]], //eslint-disable-line prettier/prettier
|
|
9
9
|
['hk', [PAYPAL, WESTERN_UNION, 'hang-seng', 'hsbc-hk', 'ocbc', 'ccb-hk', TW_ALIAS]],
|
|
10
|
-
['
|
|
11
|
-
['
|
|
10
|
+
['es', [PAYPAL, WESTERN_UNION, 'lacaixa', 'bbva', 'sabadell', TW_ALIAS]],
|
|
11
|
+
['nl', [PAYPAL, WESTERN_UNION, 'ing-nl', 'abn-amro-bank', 'rabobank', TW_ALIAS]],
|
|
12
12
|
]);
|
|
@@ -63,6 +63,7 @@ describe('quotes v3 response transformations to the canonical model V2', () => {
|
|
|
63
63
|
total: { value: 2, currency: 'GBP' },
|
|
64
64
|
},
|
|
65
65
|
receiveAmount: { value: 1278.44, currency: 'EUR' },
|
|
66
|
+
sendAmount: { value: 1280.44, currency: 'GBP' },
|
|
66
67
|
},
|
|
67
68
|
],
|
|
68
69
|
};
|
|
@@ -123,6 +124,7 @@ describe('quotes v3 response transformations to the canonical model V2', () => {
|
|
|
123
124
|
total: { value: 27.57, currency: 'GBP' },
|
|
124
125
|
},
|
|
125
126
|
receiveAmount: { value: 1252.8712, currency: 'EUR' },
|
|
127
|
+
sendAmount: { value: 1280.44, currency: 'GBP' },
|
|
126
128
|
},
|
|
127
129
|
],
|
|
128
130
|
};
|
|
@@ -179,12 +181,251 @@ describe('quotes v3 response transformations to the canonical model V2', () => {
|
|
|
179
181
|
total: { value: 4.48, currency: 'GBP' },
|
|
180
182
|
},
|
|
181
183
|
receiveAmount: { value: 1510.55, currency: 'EUR' },
|
|
184
|
+
sendAmount: { value: 1280.44, currency: 'GBP' },
|
|
182
185
|
},
|
|
183
186
|
],
|
|
184
187
|
};
|
|
185
188
|
|
|
186
|
-
expect(transformQuotesResponseV2(providerWise, wiseQuoteApiResponse)).toStrictEqual(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
+
expect(transformQuotesResponseV2(providerWise, wiseQuoteApiResponse)).toStrictEqual(expected);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('given a provider with a high amount of HKD and no hidden fee, dont show hidden fee', () => {
|
|
193
|
+
const wiseProvider = {
|
|
194
|
+
...wiseQuoteApiAdjusted,
|
|
195
|
+
rate: 0.095782,
|
|
196
|
+
};
|
|
197
|
+
const providers = {
|
|
198
|
+
providers: [
|
|
199
|
+
{
|
|
200
|
+
name: 'Western Union',
|
|
201
|
+
alias: 'western-union',
|
|
202
|
+
logo: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
203
|
+
partner: true,
|
|
204
|
+
quotes: [
|
|
205
|
+
{
|
|
206
|
+
rate: 0.095782,
|
|
207
|
+
fee: 109.08,
|
|
208
|
+
dateCollected: new Date('2018-10-23T12:03:27'),
|
|
209
|
+
receivedAmount: 2384.1,
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
sendAmount: 25000,
|
|
215
|
+
sourceCurrency: 'HKD',
|
|
216
|
+
targetCurrency: 'GBP',
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const expected = {
|
|
220
|
+
quotes: [
|
|
221
|
+
{
|
|
222
|
+
provider: {
|
|
223
|
+
name: 'Western Union',
|
|
224
|
+
alias: 'western-union',
|
|
225
|
+
logoUrl: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
226
|
+
partner: true,
|
|
227
|
+
},
|
|
228
|
+
route: {
|
|
229
|
+
sourceCurrency: 'HKD',
|
|
230
|
+
targetCurrency: 'GBP',
|
|
231
|
+
},
|
|
232
|
+
rate: 0.095782,
|
|
233
|
+
fees: {
|
|
234
|
+
breakdown: [
|
|
235
|
+
{
|
|
236
|
+
type: FeeType.MARKETED,
|
|
237
|
+
amount: { value: 109.08, currency: 'HKD' },
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
total: { value: 109.08, currency: 'HKD' },
|
|
241
|
+
},
|
|
242
|
+
receiveAmount: { value: 2384.1, currency: 'GBP' },
|
|
243
|
+
sendAmount: { value: 25000, currency: 'HKD' },
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
expect(transformQuotesResponseV2(providers, wiseProvider)).toStrictEqual(expected);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('given a provider with a better fee than expected, dont show hidden fee', () => {
|
|
252
|
+
const wiseProvider = {
|
|
253
|
+
...wiseQuoteApiAdjusted,
|
|
254
|
+
rate: 0.085782,
|
|
255
|
+
};
|
|
256
|
+
const providers = {
|
|
257
|
+
providers: [
|
|
258
|
+
{
|
|
259
|
+
name: 'Western Union',
|
|
260
|
+
alias: 'western-union',
|
|
261
|
+
logo: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
262
|
+
partner: true,
|
|
263
|
+
quotes: [
|
|
264
|
+
{
|
|
265
|
+
rate: 0.095782,
|
|
266
|
+
fee: 109.08,
|
|
267
|
+
dateCollected: new Date('2018-10-23T12:03:27'),
|
|
268
|
+
receivedAmount: 2384.1,
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
sendAmount: 25000,
|
|
274
|
+
sourceCurrency: 'HKD',
|
|
275
|
+
targetCurrency: 'GBP',
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const expected = {
|
|
279
|
+
quotes: [
|
|
280
|
+
{
|
|
281
|
+
provider: {
|
|
282
|
+
name: 'Western Union',
|
|
283
|
+
alias: 'western-union',
|
|
284
|
+
logoUrl: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
285
|
+
partner: true,
|
|
286
|
+
},
|
|
287
|
+
route: {
|
|
288
|
+
sourceCurrency: 'HKD',
|
|
289
|
+
targetCurrency: 'GBP',
|
|
290
|
+
},
|
|
291
|
+
rate: 0.095782,
|
|
292
|
+
fees: {
|
|
293
|
+
breakdown: [
|
|
294
|
+
{
|
|
295
|
+
type: FeeType.MARKETED,
|
|
296
|
+
amount: { value: 109.08, currency: 'HKD' },
|
|
297
|
+
},
|
|
298
|
+
],
|
|
299
|
+
total: { value: 109.08, currency: 'HKD' },
|
|
300
|
+
},
|
|
301
|
+
receiveAmount: { value: 2384.1, currency: 'GBP' },
|
|
302
|
+
sendAmount: { value: 25000, currency: 'HKD' },
|
|
303
|
+
},
|
|
304
|
+
],
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
expect(transformQuotesResponseV2(providers, wiseProvider)).toStrictEqual(expected);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('given a route with a small conversion rate, and provider doesnt have hidden fee, show no hidden fee', () => {
|
|
311
|
+
const wiseProvider = {
|
|
312
|
+
...wiseQuoteApiAdjusted,
|
|
313
|
+
rate: 0.00769645,
|
|
314
|
+
};
|
|
315
|
+
const providers = {
|
|
316
|
+
providers: [
|
|
317
|
+
{
|
|
318
|
+
name: 'Western Union',
|
|
319
|
+
alias: 'western-union',
|
|
320
|
+
logo: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
321
|
+
partner: true,
|
|
322
|
+
quotes: [
|
|
323
|
+
{
|
|
324
|
+
rate: 0.00769645,
|
|
325
|
+
fee: 43,
|
|
326
|
+
dateCollected: new Date('2018-10-23T12:03:27'),
|
|
327
|
+
receivedAmount: 0.44,
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
},
|
|
331
|
+
],
|
|
332
|
+
sendAmount: 100,
|
|
333
|
+
sourceCurrency: 'JPY',
|
|
334
|
+
targetCurrency: 'EUR',
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const expected = {
|
|
338
|
+
quotes: [
|
|
339
|
+
{
|
|
340
|
+
provider: {
|
|
341
|
+
name: 'Western Union',
|
|
342
|
+
alias: 'western-union',
|
|
343
|
+
logoUrl: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
344
|
+
partner: true,
|
|
345
|
+
},
|
|
346
|
+
route: {
|
|
347
|
+
sourceCurrency: 'JPY',
|
|
348
|
+
targetCurrency: 'EUR',
|
|
349
|
+
},
|
|
350
|
+
rate: 0.00769645,
|
|
351
|
+
fees: {
|
|
352
|
+
breakdown: [
|
|
353
|
+
{
|
|
354
|
+
type: FeeType.MARKETED,
|
|
355
|
+
amount: { value: 43, currency: 'JPY' },
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
total: { value: 43, currency: 'JPY' },
|
|
359
|
+
},
|
|
360
|
+
receiveAmount: { value: 0.44, currency: 'EUR' },
|
|
361
|
+
sendAmount: { value: 100, currency: 'JPY' },
|
|
362
|
+
},
|
|
363
|
+
],
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
expect(transformQuotesResponseV2(providers, wiseProvider)).toStrictEqual(expected);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it('given a route with a small conversion rate, and provider does have hidden fee, show the hidden fee', () => {
|
|
370
|
+
const wiseProvider = {
|
|
371
|
+
...wiseQuoteApiAdjusted,
|
|
372
|
+
rate: 0.00769645,
|
|
373
|
+
};
|
|
374
|
+
const providers = {
|
|
375
|
+
providers: [
|
|
376
|
+
{
|
|
377
|
+
name: 'Western Union',
|
|
378
|
+
alias: 'western-union',
|
|
379
|
+
logo: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
380
|
+
partner: true,
|
|
381
|
+
quotes: [
|
|
382
|
+
{
|
|
383
|
+
rate: 0.00759645,
|
|
384
|
+
fee: 40,
|
|
385
|
+
dateCollected: new Date('2018-10-23T12:03:27'),
|
|
386
|
+
receivedAmount: 0.46,
|
|
387
|
+
},
|
|
388
|
+
],
|
|
389
|
+
},
|
|
390
|
+
],
|
|
391
|
+
sendAmount: 100,
|
|
392
|
+
sourceCurrency: 'JPY',
|
|
393
|
+
targetCurrency: 'EUR',
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
const expected = {
|
|
397
|
+
quotes: [
|
|
398
|
+
{
|
|
399
|
+
provider: {
|
|
400
|
+
name: 'Western Union',
|
|
401
|
+
alias: 'western-union',
|
|
402
|
+
logoUrl: 'https://dq8dwmysp7hk1.cloudfront.net/logos/western-union.svg',
|
|
403
|
+
partner: true,
|
|
404
|
+
},
|
|
405
|
+
route: {
|
|
406
|
+
sourceCurrency: 'JPY',
|
|
407
|
+
targetCurrency: 'EUR',
|
|
408
|
+
},
|
|
409
|
+
rate: 0.00759645,
|
|
410
|
+
fees: {
|
|
411
|
+
breakdown: [
|
|
412
|
+
{
|
|
413
|
+
type: FeeType.MARKETED,
|
|
414
|
+
amount: { value: 40, currency: 'JPY' },
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
type: FeeType.HIDDEN,
|
|
418
|
+
amount: { value: 0.23, currency: 'JPY' },
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
total: { value: 40.23, currency: 'JPY' },
|
|
422
|
+
},
|
|
423
|
+
receiveAmount: { value: 0.46, currency: 'EUR' },
|
|
424
|
+
sendAmount: { value: 100, currency: 'JPY' },
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
expect(transformQuotesResponseV2(providers, wiseProvider)).toStrictEqual(expected);
|
|
189
430
|
});
|
|
190
431
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { numberEqualsWithRelativeTolerance } from '../../../common/numberEqualsWithRelativeTolerance/numberEqualsWithRelativeTolerance';
|
|
1
2
|
import QuoteApi from '../../../domain/QuoteApi';
|
|
2
3
|
import LegacyComparisons, {
|
|
3
4
|
LegacyQuote,
|
|
@@ -21,12 +22,19 @@ function extractHiddenFeeInSourceCurrency(
|
|
|
21
22
|
marketedFee: number,
|
|
22
23
|
midmarketRate: number,
|
|
23
24
|
) {
|
|
24
|
-
const
|
|
25
|
+
const toleranceAmountInPercentage = 0.001;
|
|
25
26
|
const expectedReceivedAmount = midmarketRate * (sendAmount - marketedFee);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
|
|
28
|
+
const receivedTheExpectedAmount = numberEqualsWithRelativeTolerance(
|
|
29
|
+
receivedAmount,
|
|
30
|
+
expectedReceivedAmount,
|
|
31
|
+
toleranceAmountInPercentage,
|
|
32
|
+
);
|
|
33
|
+
const receivedHigherThanExpected =
|
|
34
|
+
!receivedTheExpectedAmount && receivedAmount > expectedReceivedAmount;
|
|
35
|
+
|
|
36
|
+
const hasHiddenFee = !receivedTheExpectedAmount && !receivedHigherThanExpected;
|
|
37
|
+
const hiddenFeePaidOnTargetCurrency = hasHiddenFee ? expectedReceivedAmount - receivedAmount : 0;
|
|
30
38
|
|
|
31
39
|
return parseFloat((hiddenFeePaidOnTargetCurrency * (1 / midmarketRate)).toFixed(2));
|
|
32
40
|
}
|
|
@@ -96,6 +104,7 @@ function transformQuotesResponseV2(
|
|
|
96
104
|
total: { value: quote.fee + hiddenFee, currency: quotesResults.sourceCurrency },
|
|
97
105
|
},
|
|
98
106
|
receiveAmount: { value: quote.receivedAmount, currency: quotesResults.targetCurrency },
|
|
107
|
+
sendAmount: { value: quotesResults.sendAmount, currency: quotesResults.sourceCurrency },
|
|
99
108
|
};
|
|
100
109
|
});
|
|
101
110
|
|
|
@@ -32,6 +32,10 @@ const WISE_QUOTE = {
|
|
|
32
32
|
currency: 'EUR',
|
|
33
33
|
value: 1170.21,
|
|
34
34
|
},
|
|
35
|
+
sendAmount: {
|
|
36
|
+
currency: 'GBP',
|
|
37
|
+
value: 996.2,
|
|
38
|
+
},
|
|
35
39
|
};
|
|
36
40
|
|
|
37
41
|
const TRANSPARENT_PARTNER_QUOTE = {
|
|
@@ -65,6 +69,10 @@ const TRANSPARENT_PARTNER_QUOTE = {
|
|
|
65
69
|
currency: 'EUR',
|
|
66
70
|
value: 1170.21,
|
|
67
71
|
},
|
|
72
|
+
sendAmount: {
|
|
73
|
+
currency: 'GBP',
|
|
74
|
+
value: 996.2,
|
|
75
|
+
},
|
|
68
76
|
};
|
|
69
77
|
|
|
70
78
|
const TRANSPARENT_NON_PARTNER_QUOTE = {
|
|
@@ -98,6 +106,10 @@ const TRANSPARENT_NON_PARTNER_QUOTE = {
|
|
|
98
106
|
currency: 'EUR',
|
|
99
107
|
value: 1175.65,
|
|
100
108
|
},
|
|
109
|
+
sendAmount: {
|
|
110
|
+
currency: 'GBP',
|
|
111
|
+
value: 996.2,
|
|
112
|
+
},
|
|
101
113
|
};
|
|
102
114
|
|
|
103
115
|
const NON_TRANSPARENT_NON_PARTNER_QUOTE = {
|
|
@@ -138,6 +150,10 @@ const NON_TRANSPARENT_NON_PARTNER_QUOTE = {
|
|
|
138
150
|
currency: 'EUR',
|
|
139
151
|
value: 1155.72,
|
|
140
152
|
},
|
|
153
|
+
sendAmount: {
|
|
154
|
+
currency: 'GBP',
|
|
155
|
+
value: 996.2,
|
|
156
|
+
},
|
|
141
157
|
};
|
|
142
158
|
|
|
143
159
|
const ALL_QUOTES: TransferFeeComparisonQuote[] = [
|
|
@@ -78,9 +78,7 @@ const TransferFeeComparisonTableRow = ({
|
|
|
78
78
|
<td className={componentStyles.row__fee}>
|
|
79
79
|
<TotalFeeAndHiddenFee
|
|
80
80
|
totalFee={quote.fees.total}
|
|
81
|
-
hiddenFee={
|
|
82
|
-
isProviderWise(quote) ? { value: 0, currency: hiddenFee.currency } : hiddenFee
|
|
83
|
-
}
|
|
81
|
+
hiddenFee={hiddenFee}
|
|
84
82
|
darkMode={isProviderWise(quote)}
|
|
85
83
|
locale={locale}
|
|
86
84
|
/>
|
|
@@ -93,7 +91,6 @@ const TransferFeeComparisonTableRow = ({
|
|
|
93
91
|
onClose={() => setFeeBreakdownOpen(false)}
|
|
94
92
|
urlLocale={urlLocale}
|
|
95
93
|
locale={locale}
|
|
96
|
-
isProviderWise={isProviderWise(quote)}
|
|
97
94
|
onPopoverClick={() => {
|
|
98
95
|
onFeePopoverClick && onFeePopoverClick(quote.provider.name);
|
|
99
96
|
}}
|
|
@@ -18,7 +18,6 @@ export type FeeMakeupPopoverProps = {
|
|
|
18
18
|
onClose: () => void;
|
|
19
19
|
urlLocale: string;
|
|
20
20
|
locale: Locale;
|
|
21
|
-
isProviderWise: boolean,
|
|
22
21
|
onPopoverClick?: () => void;
|
|
23
22
|
};
|
|
24
23
|
|
|
@@ -29,10 +28,9 @@ const FeeMakeupPopover = ({
|
|
|
29
28
|
onClose,
|
|
30
29
|
urlLocale,
|
|
31
30
|
locale,
|
|
32
|
-
isProviderWise,
|
|
33
31
|
onPopoverClick,
|
|
34
32
|
}: FeeMakeupPopoverProps): JSX.Element => {
|
|
35
|
-
const content = PopoverContent(quote, midmarketRate, urlLocale
|
|
33
|
+
const content = PopoverContent(quote, midmarketRate, urlLocale);
|
|
36
34
|
const messages = translations[locale];
|
|
37
35
|
const intl = createIntl({ locale: locale, messages: messages });
|
|
38
36
|
|
|
@@ -62,9 +60,8 @@ const PopoverContent = (
|
|
|
62
60
|
quote: TransferFeeComparisonQuote,
|
|
63
61
|
midmarketRate: number,
|
|
64
62
|
urlLocale: string,
|
|
65
|
-
isProviderWise: boolean,
|
|
66
63
|
): JSX.Element => {
|
|
67
|
-
const hiddenFeesAmount =
|
|
64
|
+
const hiddenFeesAmount = getFeesSumByType(quote, FeeType.HIDDEN);
|
|
68
65
|
const marketedFeesAmount = getFeesSumByType(quote, FeeType.MARKETED);
|
|
69
66
|
|
|
70
67
|
if (hiddenFeesAmount > 0) {
|
|
@@ -84,7 +81,6 @@ const PopoverContent = (
|
|
|
84
81
|
midmarketRate={midmarketRate}
|
|
85
82
|
marketedFeesAmount={marketedFeesAmount}
|
|
86
83
|
urlLocale={urlLocale}
|
|
87
|
-
isProviderWise={isProviderWise}
|
|
88
84
|
/>
|
|
89
85
|
);
|
|
90
86
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Close",
|
|
3
3
|
"what-makes-up-this-fee": "What makes up this fee",
|
|
4
|
-
"conversion-fees-details": "If you send {
|
|
4
|
+
"conversion-fees-details": "If you send {sendAmount} using {providerName}, you'll pay {marketedFeesAmount} {totalCurrency} in transfer fees.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} is using a conversion rate of <span>{conversionRate}</span> which is worse than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is the same as the mid-market rate of <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is better than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Затваряне",
|
|
3
3
|
"what-makes-up-this-fee": "What makes up this fee",
|
|
4
|
-
"conversion-fees-details": "If you send {
|
|
4
|
+
"conversion-fees-details": "If you send {sendAmount} using {providerName}, you'll pay {marketedFeesAmount} {totalCurrency} in transfer fees.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} is using a conversion rate of <span>{conversionRate}</span> which is worse than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is the same as the mid-market rate of <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is better than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Zavřít",
|
|
3
3
|
"what-makes-up-this-fee": "What makes up this fee",
|
|
4
|
-
"conversion-fees-details": "If you send {
|
|
4
|
+
"conversion-fees-details": "If you send {sendAmount} using {providerName}, you'll pay {marketedFeesAmount} {totalCurrency} in transfer fees.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} is using a conversion rate of <span>{conversionRate}</span> which is worse than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is the same as the mid-market rate of <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is better than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Schließen",
|
|
3
3
|
"what-makes-up-this-fee": "Wie sich diese Gebühr zusammensetzt",
|
|
4
|
-
"conversion-fees-details": "Wenn du {
|
|
4
|
+
"conversion-fees-details": "Wenn du {sendAmount} mit {providerName} überweist, zahlst du dafür {marketedFeesAmount} {totalCurrency} an Überweisungsgebühren.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} verwendet einen Wechselkurs von <span>{conversionRate}</span> – dieser Kurs ist schlechter als der Devisenmittelkurs, der bei <a>{midmarketRate}</a> liegt.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} verwendet einen Wechselkurs von <a>{conversionRate}</a> – dieser Kurs entspricht dem Devisenmittelkurs, der bei <a>{midmarketRate}</a> liegt.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} verwendet einen Wechselkurs von <a>{conversionRate}</a> – dieser Kurs ist besser als der Devisenmittelkurs, der bei <a>{midmarketRate}</a> liegt.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Κλείσιμο",
|
|
3
3
|
"what-makes-up-this-fee": "What makes up this fee",
|
|
4
|
-
"conversion-fees-details": "If you send {
|
|
4
|
+
"conversion-fees-details": "If you send {sendAmount} using {providerName}, you'll pay {marketedFeesAmount} {totalCurrency} in transfer fees.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} is using a conversion rate of <span>{conversionRate}</span> which is worse than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is the same as the mid-market rate of <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is better than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Close",
|
|
3
3
|
"what-makes-up-this-fee": "What makes up this fee",
|
|
4
|
-
"conversion-fees-details": "If you send {
|
|
4
|
+
"conversion-fees-details": "If you send {sendAmount} using {providerName}, you'll pay {marketedFeesAmount} {totalCurrency} in transfer fees.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} is using a conversion rate of <span>{conversionRate}</span> which is worse than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is the same as the mid-market rate of <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} is using a conversion rate of <a>{conversionRate}</a> which is better than the mid-market rate of <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Cerrar",
|
|
3
3
|
"what-makes-up-this-fee": "En qué consiste esta comisión",
|
|
4
|
-
"conversion-fees-details": "Si tú envías {
|
|
4
|
+
"conversion-fees-details": "Si tú envías {sendAmount} usando {providerName}, pagarás {marketedFeesAmount} {totalCurrency} en comisiones por transferencia.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} está usando un tipo de conversión de <span>{conversionRate}</span> , que es peor que el tipo de cambio real del mercado de <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} está usando un tipo de conversión de <a>{conversionRate}</a> , que es el mismo que el tipo de cambio real del mercado de <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} está usando un tipo de conversión de <a>{conversionRate}</a> , que es mejor que el tipo de cambio real del mercado de <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Fermer",
|
|
3
3
|
"what-makes-up-this-fee": "De quoi se compose ces frais",
|
|
4
|
-
"conversion-fees-details": "Si vous envoyez {
|
|
4
|
+
"conversion-fees-details": "Si vous envoyez {sendAmount} avec {providerName}, vous payerez des frais de transferts s'élevant à {marketedFeesAmount} {totalCurrency}.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} utilise un taux de conversion de <span>{conversionRate}</span>, ce qui est moins avantageux que le taux moyen du marché de <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} utilise un taux de conversion de <a>{conversionRate}</a>, ce qui est identique au taux moyen du marché de <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} utilise un taux de conversion de <a>{conversionRate}</a>, ce qui est plus avantageux que le taux moyen du marché de <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Bezárás",
|
|
3
3
|
"what-makes-up-this-fee": "Miből áll össze ez a díj",
|
|
4
|
-
"conversion-fees-details": "Ha {
|
|
4
|
+
"conversion-fees-details": "Ha {sendAmount} összeget küldesz a(z) {providerName} szolgáltatóval, az utalás díja {marketedFeesAmount} {totalCurrency} lesz.",
|
|
5
5
|
"using-bad-conversion-rate": "A(z) {providerName} szolgáltató <span>{conversionRate}</span> árfolyamon vált. Ez rosszabb, mint a piaci középárfolyam (<a>{midmarketRate}</a>).",
|
|
6
6
|
"using-good-conversion-rate": "A(z) {providerName} <a>{conversionRate}</a> árfolyamon vált. Ez megegyezik a piaci középárfolyammal (<a>{midmarketRate}</a>).",
|
|
7
7
|
"using-great-conversion-rate": "A(z) {providerName} <a>{conversionRate}</a>árfolyamon vált. Ez jobb, mint a piaci középárfolyam (<a>{midmarketRate}</a>).",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Tutup",
|
|
3
3
|
"what-makes-up-this-fee": "Biaya ini terdiri dari apa saja",
|
|
4
|
-
"conversion-fees-details": "Jika Anda mengirim {
|
|
4
|
+
"conversion-fees-details": "Jika Anda mengirim {sendAmount} menggunakan {providerName}, Anda akan membayar {marketedFeesAmount} {totalCurrency} untuk biaya transfer. ",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} menggunakan nilai tukar konversi <span>{conversionRate}</span> yang lebih buruk dari nilai tukar nyata dari <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} menggunakan nilai tukar konversi <a>{conversionRate}</a> yang sama dengan nilai tukar nyata dari <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} menggunakan nilai tukar konversi <a>{conversionRate}</a> yang lebih baik dari nilai tukar nyata dari <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "Chiudi",
|
|
3
3
|
"what-makes-up-this-fee": "Come si compone questa commissione",
|
|
4
|
-
"conversion-fees-details": "Se invii {
|
|
4
|
+
"conversion-fees-details": "Se invii {sendAmount} usando {providerName}, pagherai {marketedFeesAmount} {totalCurrency} di commissioni di trasferimento.",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} sta usando un tasso di conversione di <span>{conversionRate}</span>, che è peggiore del tasso medio di mercato di <a>{midmarketRate}</a>.",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} sta usando un tasso di conversione di <a>{conversionRate}</a>, che è pari al tasso medio di mercato di <a>{midmarketRate}</a>.",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} sta usando un tasso di conversione di <a>{conversionRate}</a>, che è migliore del tasso medio di mercato di <a>{midmarketRate}</a>.",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"close": "閉じる",
|
|
3
3
|
"what-makes-up-this-fee": "この料金には何が含まれますか?",
|
|
4
|
-
"conversion-fees-details": "{providerName} を使用して{
|
|
4
|
+
"conversion-fees-details": "{providerName} を使用して{sendAmount} を送金する場合、{marketedFeesAmount} {totalCurrency} の手数料を支払うことになります。",
|
|
5
5
|
"using-bad-conversion-rate": "{providerName} は、<span>{conversionRate}</span> の両替レートを使用していますが、これは<a>{midmarketRate}</a> のミッドマーケットレートよりも悪いです。",
|
|
6
6
|
"using-good-conversion-rate": "{providerName} は<a>{conversionRate}</a> の両替レートを使用しており、<a>{midmarketRate}</a> のミッドマーケットレートと同じです。",
|
|
7
7
|
"using-great-conversion-rate": "{providerName} は、<a>{conversionRate}</a> の両替レートを使用していますが、これは<a>{midmarketRate}</a> のミッドマーケットレートよりも良いです。",
|