Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Tests\Component\Utility;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Utility\Random;
|
Chris@0
|
6 use Drupal\Component\Utility\UserAgent;
|
Chris@0
|
7 use PHPUnit\Framework\TestCase;
|
Chris@0
|
8
|
Chris@0
|
9 /**
|
Chris@0
|
10 * Tests bytes size parsing helper methods.
|
Chris@0
|
11 *
|
Chris@0
|
12 * @group Utility
|
Chris@0
|
13 *
|
Chris@0
|
14 * @coversDefaultClass \Drupal\Component\Utility\UserAgent
|
Chris@0
|
15 */
|
Chris@0
|
16 class UserAgentTest extends TestCase {
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 * Helper method to supply language codes to testGetBestMatchingLangcode().
|
Chris@0
|
20 *
|
Chris@0
|
21 * @return array
|
Chris@0
|
22 * Language codes, ordered by priority.
|
Chris@0
|
23 */
|
Chris@0
|
24 protected function getLanguages() {
|
Chris@0
|
25 return [
|
Chris@0
|
26 // In our test case, 'en' has priority over 'en-US'.
|
Chris@0
|
27 'en',
|
Chris@0
|
28 'en-US',
|
Chris@0
|
29 // But 'fr-CA' has priority over 'fr'.
|
Chris@0
|
30 'fr-CA',
|
Chris@0
|
31 'fr',
|
Chris@0
|
32 // 'es-MX' is alone.
|
Chris@0
|
33 'es-MX',
|
Chris@0
|
34 // 'pt' is alone.
|
Chris@0
|
35 'pt',
|
Chris@0
|
36 // Language codes with more then one dash are actually valid.
|
Chris@0
|
37 // eh-oh-laa-laa is the official language code of the Teletubbies.
|
Chris@0
|
38 'eh-oh-laa-laa',
|
Chris@0
|
39 // Chinese languages.
|
Chris@0
|
40 'zh-hans',
|
Chris@0
|
41 'zh-hant',
|
Chris@0
|
42 'zh-hant-tw',
|
Chris@0
|
43 ];
|
Chris@0
|
44 }
|
Chris@0
|
45
|
Chris@0
|
46 /**
|
Chris@0
|
47 * Helper method to supply language mappings to testGetBestMatchingLangcode().
|
Chris@0
|
48 *
|
Chris@0
|
49 * @return array
|
Chris@0
|
50 * Language mappings.
|
Chris@0
|
51 */
|
Chris@0
|
52 protected function getMappings() {
|
Chris@0
|
53 return [
|
Chris@0
|
54 'no' => 'nb',
|
Chris@0
|
55 'pt' => 'pt-pt',
|
Chris@0
|
56 'zh' => 'zh-hans',
|
Chris@0
|
57 'zh-tw' => 'zh-hant',
|
Chris@0
|
58 'zh-hk' => 'zh-hant',
|
Chris@0
|
59 'zh-mo' => 'zh-hant',
|
Chris@0
|
60 'zh-cht' => 'zh-hant',
|
Chris@0
|
61 'zh-cn' => 'zh-hans',
|
Chris@0
|
62 'zh-sg' => 'zh-hans',
|
Chris@0
|
63 'zh-chs' => 'zh-hans',
|
Chris@0
|
64 ];
|
Chris@0
|
65 }
|
Chris@0
|
66
|
Chris@0
|
67 /**
|
Chris@0
|
68 * Test matching language from user agent.
|
Chris@0
|
69 *
|
Chris@0
|
70 * @dataProvider providerTestGetBestMatchingLangcode
|
Chris@0
|
71 * @covers ::getBestMatchingLangcode
|
Chris@0
|
72 */
|
Chris@0
|
73 public function testGetBestMatchingLangcode($accept_language, $expected) {
|
Chris@0
|
74 $result = UserAgent::getBestMatchingLangcode($accept_language, $this->getLanguages(), $this->getMappings());
|
Chris@0
|
75 $this->assertSame($expected, $result);
|
Chris@0
|
76 }
|
Chris@0
|
77
|
Chris@0
|
78 /**
|
Chris@0
|
79 * Data provider for testGetBestMatchingLangcode().
|
Chris@0
|
80 *
|
Chris@0
|
81 * @return array
|
Chris@0
|
82 * - An accept-language string.
|
Chris@0
|
83 * - Expected best matching language code.
|
Chris@0
|
84 */
|
Chris@0
|
85 public function providerTestGetBestMatchingLangcode() {
|
Chris@0
|
86 // Random generator.
|
Chris@0
|
87 $random = new Random();
|
Chris@0
|
88
|
Chris@0
|
89 return [
|
Chris@0
|
90 // Equal qvalue for each language, choose the site preferred one.
|
Chris@0
|
91 ['en,en-US,fr-CA,fr,es-MX', 'en'],
|
Chris@0
|
92 ['en-US,en,fr-CA,fr,es-MX', 'en'],
|
Chris@0
|
93 ['fr,en', 'en'],
|
Chris@0
|
94 ['en,fr', 'en'],
|
Chris@0
|
95 ['en-US,fr', 'en-US'],
|
Chris@0
|
96 ['fr,en-US', 'en-US'],
|
Chris@0
|
97 ['fr,fr-CA', 'fr-CA'],
|
Chris@0
|
98 ['fr-CA,fr', 'fr-CA'],
|
Chris@0
|
99 ['fr', 'fr-CA'],
|
Chris@0
|
100 ['fr;q=1', 'fr-CA'],
|
Chris@0
|
101 ['fr,es-MX', 'fr-CA'],
|
Chris@0
|
102 ['fr,es', 'fr-CA'],
|
Chris@0
|
103 ['es,fr', 'fr-CA'],
|
Chris@0
|
104 ['es-MX,de', 'es-MX'],
|
Chris@0
|
105 ['de,es-MX', 'es-MX'],
|
Chris@0
|
106
|
Chris@0
|
107 // Different cases and whitespace.
|
Chris@0
|
108 ['en', 'en'],
|
Chris@0
|
109 ['En', 'en'],
|
Chris@0
|
110 ['EN', 'en'],
|
Chris@0
|
111 [' en', 'en'],
|
Chris@0
|
112 ['en ', 'en'],
|
Chris@0
|
113 ['en, fr', 'en'],
|
Chris@0
|
114
|
Chris@0
|
115 // A less specific language from the browser matches a more specific one
|
Chris@0
|
116 // from the website, and the other way around for compatibility with
|
Chris@0
|
117 // some versions of Internet Explorer.
|
Chris@0
|
118 ['es', 'es-MX'],
|
Chris@0
|
119 ['es-MX', 'es-MX'],
|
Chris@0
|
120 ['pt', 'pt'],
|
Chris@0
|
121 ['pt-PT', 'pt'],
|
Chris@0
|
122 ['pt-PT;q=0.5,pt-BR;q=1,en;q=0.7', 'en'],
|
Chris@0
|
123 ['pt-PT;q=1,pt-BR;q=0.5,en;q=0.7', 'en'],
|
Chris@0
|
124 ['pt-PT;q=0.4,pt-BR;q=0.1,en;q=0.7', 'en'],
|
Chris@0
|
125 ['pt-PT;q=0.1,pt-BR;q=0.4,en;q=0.7', 'en'],
|
Chris@0
|
126
|
Chris@0
|
127 // Language code with several dashes are valid. The less specific language
|
Chris@0
|
128 // from the browser matches the more specific one from the website.
|
Chris@0
|
129 ['eh-oh-laa-laa', 'eh-oh-laa-laa'],
|
Chris@0
|
130 ['eh-oh-laa', 'eh-oh-laa-laa'],
|
Chris@0
|
131 ['eh-oh', 'eh-oh-laa-laa'],
|
Chris@0
|
132 ['eh', 'eh-oh-laa-laa'],
|
Chris@0
|
133
|
Chris@0
|
134 // Different qvalues.
|
Chris@0
|
135 ['fr,en;q=0.5', 'fr-CA'],
|
Chris@0
|
136 ['fr,en;q=0.5,fr-CA;q=0.25', 'fr'],
|
Chris@0
|
137
|
Chris@0
|
138 // Silly wildcards are also valid.
|
Chris@0
|
139 ['*,fr-CA;q=0.5', 'en'],
|
Chris@0
|
140 ['*,en;q=0.25', 'fr-CA'],
|
Chris@0
|
141 ['en,en-US;q=0.5,fr;q=0.25', 'en'],
|
Chris@0
|
142 ['en-US,en;q=0.5,fr;q=0.25', 'en-US'],
|
Chris@0
|
143
|
Chris@0
|
144 // Unresolvable cases.
|
Chris@0
|
145 ['', FALSE],
|
Chris@0
|
146 ['de,pl', FALSE],
|
Chris@0
|
147 ['iecRswK4eh', FALSE],
|
Chris@0
|
148 [$random->name(10, TRUE), FALSE],
|
Chris@0
|
149
|
Chris@0
|
150 // Chinese langcodes.
|
Chris@0
|
151 ['zh-cn, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hans'],
|
Chris@0
|
152 ['zh-tw, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'],
|
Chris@0
|
153 ['zh-hant, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'],
|
Chris@0
|
154 ['zh-hans, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hans'],
|
Chris@0
|
155 // @todo: This is copied from RFC4647 but our regex skips the numbers so
|
Chris@0
|
156 // they where removed. Our code should be updated so private1-private2 is
|
Chris@0
|
157 // valid. http://tools.ietf.org/html/rfc4647#section-3.4
|
Chris@0
|
158 ['zh-hant-CN-x-private-private, en-us;q=0.90, en;q=0.80, zh;q=0.70', 'zh-hant'],
|
Chris@0
|
159 ['zh-cn', 'zh-hans'],
|
Chris@0
|
160 ['zh-sg', 'zh-hans'],
|
Chris@0
|
161 ['zh-tw', 'zh-hant'],
|
Chris@0
|
162 ['zh-hk', 'zh-hant'],
|
Chris@0
|
163 ['zh-mo', 'zh-hant'],
|
Chris@0
|
164 ['zh-hans', 'zh-hans'],
|
Chris@0
|
165 ['zh-hant', 'zh-hant'],
|
Chris@0
|
166 ['zh-chs', 'zh-hans'],
|
Chris@0
|
167 ['zh-cht', 'zh-hant'],
|
Chris@0
|
168 ];
|
Chris@0
|
169 }
|
Chris@0
|
170
|
Chris@0
|
171 }
|