1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.payments;
6 
7 import androidx.test.filters.MediumTest;
8 
9 import org.junit.Assert;
10 import org.junit.Rule;
11 import org.junit.Test;
12 import org.junit.runner.RunWith;
13 
14 import org.chromium.base.LocaleUtils;
15 import org.chromium.base.test.BaseJUnit4ClassRunner;
16 import org.chromium.chrome.test.ChromeBrowserTestRule;
17 import org.chromium.components.payments.CurrencyFormatter;
18 
19 import java.util.Arrays;
20 import java.util.List;
21 
22 /**
23  * A lightweight integration test for CurrencyFormatter to run on an Android device.
24  */
25 @RunWith(BaseJUnit4ClassRunner.class)
26 public class CurrencyFormatterTest {
27     @Rule
28     public ChromeBrowserTestRule mActivityTestRule = new ChromeBrowserTestRule();
29 
30     /**
31      * Unicode non-breaking space.
32      */
33     private static final String NBSP = "\u00A0";
34     private static final String NarrowNBSP = "\u202F";
35 
longStringOfLength(int len)36     private static String longStringOfLength(int len) {
37         StringBuilder currency = new StringBuilder();
38         for (int i = 0; i < len; i++) {
39             currency.append("A");
40         }
41         return currency.toString();
42     }
43 
44     @Test
45     @MediumTest
testMultipleConversions()46     public void testMultipleConversions() {
47         // Note, all spaces are expected to be unicode non-breaking spaces. Here they are shown as
48         // normal spaces.
49         List<Object[]> testCases = Arrays.asList(new Object[][] {
50                 {"55.00", "USD", "en-US", "USD", "$55.00"},
51                 {"55.00", "USD", "en-CA", "USD", "$55.00"},
52                 {"55.00", "USD", "fr-CA", "USD", "55,00 $"},
53                 {"55.00", "USD", "fr-FR", "USD", "55,00 $"},
54                 {"1234", "USD", "fr-FR", "USD", "1 234,00 $"},
55 
56                 {"55.5", "USD", "en-US", "USD", "$55.50"}, {"55", "USD", "en-US", "USD", "$55.00"},
57                 {"-123", "USD", "en-US", "USD", "-$123.00"},
58                 {"-1234", "USD", "en-US", "USD", "-$1,234.00"},
59                 {"0.1234", "USD", "en-US", "USD", "$0.1234"},
60 
61                 {"55.00", "EUR", "en-US", "EUR", "€55.00"},
62                 {"55.00", "EUR", "en-CA", "EUR", "€55.00"},
63                 {"55.00", "EUR", "fr-CA", "EUR", "55,00 €"},
64                 {"55.00", "EUR", "fr-FR", "EUR", "55,00 €"},
65 
66                 {"55.00", "CAD", "en-US", "CAD", "$55.00"},
67                 {"55.00", "CAD", "en-CA", "CAD", "$55.00"},
68                 {"55.00", "CAD", "fr-CA", "CAD", "55,00 $"},
69                 {"55.00", "CAD", "fr-FR", "CAD", "55,00 $"},
70 
71                 {"55", "JPY", "ja-JP", "JPY", "¥55"}, {"55.0", "JPY", "ja-JP", "JPY", "¥55"},
72                 {"55.00", "JPY", "ja-JP", "JPY", "¥55"},
73                 {"55.12", "JPY", "ja-JP", "JPY", "¥55.12"},
74                 {"55.49", "JPY", "ja-JP", "JPY", "¥55.49"},
75                 {"55.50", "JPY", "ja-JP", "JPY", "¥55.5"},
76                 {"55.9999", "JPY", "ja-JP", "JPY", "¥55.9999"},
77 
78                 // Unofficial ISO 4217 currency code.
79                 {"55.00", "BTX", "en-US", "BTX", "55.00"},
80                 {"-0.00000001", "BTX", "en-US", "BTX", "-0.00000001"},
81                 {"-55.00", "BTX", "fr-FR", "BTX", "-55,00"},
82 
83                 {"123456789012345678901234567890.123456789012345678901234567890", "USD", "fr-FR",
84                         "USD", "123 456 789 012 345 678 901 234 567 890,123456789 $"},
85                 {"123456789012345678901234567890.123456789012345678901234567890", "USD", "en-US",
86                         "USD", "$123,456,789,012,345,678,901,234,567,890.123456789"},
87 
88                 // Any string of at most 2048 characters can be valid amount currency codes.
89                 {"55.00", "", "en-US", "", "55.00"},
90                 {"55.00", "ABCDEF", "en-US", "ABCDE\u2026", "55.00"},
91                 // Currency code more than 6 character is formatted to first 5 characters and
92                 // ellipsis. "\u2026" is unicode for ellipsis.
93                 {"55.00", longStringOfLength(2048), "en-US", "AAAAA\u2026", "55.00"},
94         });
95 
96         for (int i = 0; i < testCases.size(); i++) {
97             Object[] testCase = testCases.get(i);
98 
99             String amount = (String) testCase[0];
100             String currency = (String) testCase[1];
101             String locale = (String) testCase[2];
102             String expectedCurrencyFormatting = (String) testCase[3];
103             String expectedAmountFormatting = (String) testCase[4];
104 
105             CurrencyFormatter formatter =
106                     new CurrencyFormatter(currency, LocaleUtils.forLanguageTag(locale));
107             // To make tests robust against the CLDR data change in terms of space (ASCII
108             // space, NBSP and Narrow NBSP), fold NBSP and NarrowNBSP into U+0020.
109             String formattedAmount = formatter.format(amount).replace(NBSP, " ");
110             Assert.assertEquals("\"" + currency + "\" \"" + amount + "\" (\"" + locale
111                             + "\" locale) should be formatted into \"" + expectedAmountFormatting
112                             + "\"",
113                     expectedAmountFormatting, formattedAmount.replace(NarrowNBSP, " "));
114             Assert.assertEquals("\"" + currency + "\""
115                             + " should be formatted into \"" + expectedCurrencyFormatting + "\"",
116                     expectedCurrencyFormatting, formatter.getFormattedCurrencyCode());
117         }
118     }
119 }
120