Bug 1857386 [wpt PR 42383] - Update wpt metadata, a=testonly
[gecko.git] / netwerk / test / unit / test_idn_urls.js
blob0059b133c0ac1f5ba1b7e3a51346a75afd5b6e76
1 // Test algorithm for unicode display of IDNA URL (bug 722299)
3 "use strict";
5 const testcases = [
6   //  Original             Punycode or         Expected UTF-8 by profile
7   //    URL              normalized form      ASCII-Only, High, Moderate
8   //
9   // Latin script
10   ["cuillère", "xn--cuillre-6xa", false, true, true],
12   // repeated non-spacing marks
13   ["gruz̀̀ere", "xn--gruzere-ogea", false, false, false],
15   // non-XID character
16   ["I♥NY", "xn--iny-zx5a", false, false, false],
18   /*
19   Behaviour of this test changed in IDNA2008, replacing the non-XID
20   character with U+FFFD replacement character - when all platforms use
21   IDNA2008 it can be uncommented and the punycode URL changed to
22    "xn--mgbl3eb85703a"
24     // new non-XID character in Unicode 6.3
25     ["حلا\u061cل", "xn--bgbvr6gc",                    false, false, false],
28   // U+30FB KATAKANA MIDDLE DOT is excluded from non-XID characters (bug 857490)
29   ["乾燥肌・石けん", "xn--08j4gylj12hz80b0uhfup", false, true, true],
31   // Cyrillic alone
32   ["толсто́й", "xn--lsa83dealbred", false, true, true],
34   // Mixed script Cyrillic/Latin
35   [
36     "толсто́й-in-Russian",
37     "xn---in-russian-1jg071b0a8bb4cpd",
38     false,
39     false,
40     false,
41   ],
43   // Mixed script Latin/Cyrillic
44   ["war-and-миръ", "xn--war-and--b9g3b7b3h", false, false, false],
46   // Cherokee (Restricted script)
47   ["ᏣᎳᎩ", "xn--f9dt7l", false, false, false],
49   // Yi (former Aspirational script, now Restricted per Unicode 10.0 update to UAX 31)
50   ["ꆈꌠꁱꂷ", "xn--4o7a6e1x64c", false, false, false],
52   // Greek alone
53   ["πλάτων", "xn--hxa3ahjw4a", false, true, true],
55   // Mixed script Greek/Latin
56   [
57     "πλάτωνicrelationship",
58     "xn--icrelationship-96j4t9a3cwe2e",
59     false,
60     false,
61     false,
62   ],
64   // Mixed script Latin/Greek
65   ["spaceὈδύσσεια", "xn--space-h9dui0b0ga2j1562b", false, false, false],
67   // Devanagari alone
68   ["मराठी", "xn--d2b1ag0dl", false, true, true],
70   // Devanagari with Armenian
71   ["मराठीՀայաստան", "xn--y9aaa1d0ai1cq964f8dwa2o1a", false, false, false],
73   // Devanagari with common
74   ["मराठी123", "xn--123-mhh3em2hra", false, true, true],
76   // Common with Devanagari
77   ["123मराठी", "xn--123-phh3em2hra", false, true, true],
79   // Latin with Han
80   ["chairman毛", "xn--chairman-k65r", false, true, true],
82   // Han with Latin
83   ["山葵sauce", "xn--sauce-6j9ii40v", false, true, true],
85   // Latin with Han, Hiragana and Katakana
86   ["van語ではドイ", "xn--van-ub4bpb6w0in486d", false, true, true],
88   // Latin with Han, Katakana and Hiragana
89   ["van語ドイでは", "xn--van-ub4bpb4w0ip486d", false, true, true],
91   // Latin with Hiragana, Han and Katakana
92   ["vanでは語ドイ", "xn--van-ub4bpb6w0ip486d", false, true, true],
94   // Latin with Hiragana, Katakana and Han
95   ["vanではドイ語", "xn--van-ub4bpb6w0ir486d", false, true, true],
97   // Latin with Katakana, Han and Hiragana
98   ["vanドイ語では", "xn--van-ub4bpb4w0ir486d", false, true, true],
100   // Latin with Katakana, Hiragana and Han
101   ["vanドイでは語", "xn--van-ub4bpb4w0it486d", false, true, true],
103   // Han with Latin, Hiragana and Katakana
104   ["語vanではドイ", "xn--van-ub4bpb6w0ik486d", false, true, true],
106   // Han with Latin, Katakana and Hiragana
107   ["語vanドイでは", "xn--van-ub4bpb4w0im486d", false, true, true],
109   // Han with Hiragana, Latin and Katakana
110   ["語ではvanドイ", "xn--van-rb4bpb9w0ik486d", false, true, true],
112   // Han with Hiragana, Katakana and Latin
113   ["語ではドイvan", "xn--van-rb4bpb6w0in486d", false, true, true],
115   // Han with Katakana, Latin and Hiragana
116   ["語ドイvanでは", "xn--van-ub4bpb1w0ip486d", false, true, true],
118   // Han with Katakana, Hiragana and Latin
119   ["語ドイではvan", "xn--van-rb4bpb4w0ip486d", false, true, true],
121   // Hiragana with Latin, Han and Katakana
122   ["イツvan語ではド", "xn--van-ub4bpb1wvhsbx330n", false, true, true],
124   // Hiragana with Latin, Katakana and Han
125   ["ではvanドイ語", "xn--van-rb4bpb9w0ir486d", false, true, true],
127   // Hiragana with Han, Latin and Katakana
128   ["では語vanドイ", "xn--van-rb4bpb9w0im486d", false, true, true],
130   // Hiragana with Han, Katakana and Latin
131   ["では語ドイvan", "xn--van-rb4bpb6w0ip486d", false, true, true],
133   // Hiragana with Katakana, Latin and Han
134   ["ではドイvan語", "xn--van-rb4bpb6w0iu486d", false, true, true],
136   // Hiragana with Katakana, Han and Latin
137   ["ではドイ語van", "xn--van-rb4bpb6w0ir486d", false, true, true],
139   // Katakana with Latin, Han and Hiragana
140   ["ドイvan語では", "xn--van-ub4bpb1w0iu486d", false, true, true],
142   // Katakana with Latin, Hiragana and Han
143   ["ドイvanでは語", "xn--van-ub4bpb1w0iw486d", false, true, true],
145   // Katakana with Han, Latin and Hiragana
146   ["ドイ語vanでは", "xn--van-ub4bpb1w0ir486d", false, true, true],
148   // Katakana with Han, Hiragana and Latin
149   ["ドイ語ではvan", "xn--van-rb4bpb4w0ir486d", false, true, true],
151   // Katakana with Hiragana, Latin and Han
152   ["ドイではvan語", "xn--van-rb4bpb4w0iw486d", false, true, true],
154   // Katakana with Hiragana, Han and Latin
155   ["ドイでは語van", "xn--van-rb4bpb4w0it486d", false, true, true],
157   // Han with common
158   ["中国123", "xn--123-u68dy61b", false, true, true],
160   // common with Han
161   ["123中国", "xn--123-x68dy61b", false, true, true],
163   // Characters that normalize to permitted characters
164   //  (also tests Plane 1 supplementary characters)
165   ["super𝟖", "super8", true, true, true],
167   // Han from Plane 2
168   ["𠀀𠀁𠀂", "xn--j50icd", false, true, true],
170   // Han from Plane 2 with js (UTF-16) escapes
171   ["\uD840\uDC00\uD840\uDC01\uD840\uDC02", "xn--j50icd", false, true, true],
173   // Same with a lone high surrogate at the end
174   ["\uD840\uDC00\uD840\uDC01\uD840", "xn--zn7c0336bda", false, false, false],
176   // Latin text and Bengali digits
177   ["super৪", "xn--super-k2l", false, false, true],
179   // Bengali digits and Latin text
180   ["৫ab", "xn--ab-x5f", false, false, true],
182   // Bengali text and Latin digits
183   ["অঙ্কুর8", "xn--8-70d2cp0j6dtd", false, true, true],
185   // Latin digits and Bengali text
186   ["5াব", "xn--5-h3d7c", false, true, true],
188   // Mixed numbering systems
189   ["٢٠۰٠", "xn--8hbae38c", false, false, false],
191   // Traditional Chinese
192   ["萬城", "xn--uis754h", false, true, true],
194   // Simplified Chinese
195   ["万城", "xn--chq31v", false, true, true],
197   // Simplified-only and Traditional-only Chinese in the same label
198   ["万萬城", "xn--chq31vsl1b", false, true, true],
200   // Traditional-only and Simplified-only Chinese in the same label
201   ["萬万城", "xn--chq31vrl1b", false, true, true],
203   // Han and Latin and Bopomofo
204   [
205     "注音符号bopomofoㄅㄆㄇㄈ",
206     "xn--bopomofo-hj5gkalm1637i876cuw0brk5f",
207     false,
208     true,
209     true,
210   ],
212   // Han, bopomofo, Latin
213   [
214     "注音符号ㄅㄆㄇㄈbopomofo",
215     "xn--bopomofo-8i5gkalm9637i876cuw0brk5f",
216     false,
217     true,
218     true,
219   ],
221   // Latin, Han, Bopomofo
222   [
223     "bopomofo注音符号ㄅㄆㄇㄈ",
224     "xn--bopomofo-hj5gkalm9637i876cuw0brk5f",
225     false,
226     true,
227     true,
228   ],
230   // Latin, Bopomofo, Han
231   [
232     "bopomofoㄅㄆㄇㄈ注音符号",
233     "xn--bopomofo-hj5gkalm3737i876cuw0brk5f",
234     false,
235     true,
236     true,
237   ],
239   // Bopomofo, Han, Latin
240   [
241     "ㄅㄆㄇㄈ注音符号bopomofo",
242     "xn--bopomofo-8i5gkalm3737i876cuw0brk5f",
243     false,
244     true,
245     true,
246   ],
248   // Bopomofo, Latin, Han
249   [
250     "ㄅㄆㄇㄈbopomofo注音符号",
251     "xn--bopomofo-8i5gkalm1837i876cuw0brk5f",
252     false,
253     true,
254     true,
255   ],
257   // Han, bopomofo and katakana
258   [
259     "注音符号ㄅㄆㄇㄈボポモフォ",
260     "xn--jckteuaez1shij0450gylvccz9asi4e",
261     false,
262     false,
263     false,
264   ],
266   // Han, katakana, bopomofo
267   [
268     "注音符号ボポモフォㄅㄆㄇㄈ",
269     "xn--jckteuaez6shij5350gylvccz9asi4e",
270     false,
271     false,
272     false,
273   ],
275   // bopomofo, han, katakana
276   [
277     "ㄅㄆㄇㄈ注音符号ボポモフォ",
278     "xn--jckteuaez1shij4450gylvccz9asi4e",
279     false,
280     false,
281     false,
282   ],
284   // bopomofo, katakana, han
285   [
286     "ㄅㄆㄇㄈボポモフォ注音符号",
287     "xn--jckteuaez1shij9450gylvccz9asi4e",
288     false,
289     false,
290     false,
291   ],
293   // katakana, Han, bopomofo
294   [
295     "ボポモフォ注音符号ㄅㄆㄇㄈ",
296     "xn--jckteuaez6shij0450gylvccz9asi4e",
297     false,
298     false,
299     false,
300   ],
302   // katakana, bopomofo, Han
303   [
304     "ボポモフォㄅㄆㄇㄈ注音符号",
305     "xn--jckteuaez6shij4450gylvccz9asi4e",
306     false,
307     false,
308     false,
309   ],
311   // Han, Hangul and Latin
312   ["韓한글hangul", "xn--hangul-2m5ti09k79ze", false, true, true],
314   // Han, Latin and Hangul
315   ["韓hangul한글", "xn--hangul-2m5to09k79ze", false, true, true],
317   // Hangul, Han and Latin
318   ["한글韓hangul", "xn--hangul-2m5th09k79ze", false, true, true],
320   // Hangul, Latin and Han
321   ["한글hangul韓", "xn--hangul-8m5t898k79ze", false, true, true],
323   // Latin, Han and Hangul
324   ["hangul韓한글", "xn--hangul-8m5ti09k79ze", false, true, true],
326   // Latin, Hangul and Han
327   ["hangul한글韓", "xn--hangul-8m5th09k79ze", false, true, true],
329   // Hangul and katakana
330   ["한글ハングル", "xn--qck1c2d4a9266lkmzb", false, false, false],
332   // Katakana and Hangul
333   ["ハングル한글", "xn--qck1c2d4a2366lkmzb", false, false, false],
335   // Thai (also tests that node with over 63 UTF-8 octets doesn't fail)
336   [
337     "เครื่องทําน้ําทําน้ําแข็ง",
338     "xn--22cdjb2fanb9fyepcbbb9dwh4a3igze4fdcd",
339     false,
340     true,
341     true,
342   ],
344   // Effect of adding valid or invalid subdomains (bug 1399540)
345   ["䕮䕵䕶䕱.ascii", "xn--google.ascii", false, true, true],
346   ["ascii.䕮䕵䕶䕱", "ascii.xn--google", false, true, true],
347   ["中国123.䕮䕵䕶䕱", "xn--123-u68dy61b.xn--google", false, true, true],
348   ["䕮䕵䕶䕱.中国123", "xn--google.xn--123-u68dy61b", false, true, true],
349   [
350     "xn--accountlogin.䕮䕵䕶䕱",
351     "xn--accountlogin.xn--google",
352     false,
353     true,
354     true,
355   ],
356   [
357     "䕮䕵䕶䕱.xn--accountlogin",
358     "xn--google.xn--accountlogin",
359     false,
360     true,
361     true,
362   ],
364   // Arabic diacritic not allowed in Latin text (bug 1370497)
365   ["goo\u0650gle", "xn--google-yri", false, false, false],
366   // ...but Arabic diacritics are allowed on Arabic text
367   ["العَرَبِي", "xn--mgbc0a5a6cxbzabt", false, true, true],
369   // Hebrew diacritic also not allowed in Latin text (bug 1404349)
370   ["goo\u05b4gle", "xn--google-rvh", false, false, false],
372   // Accents above dotless-i are not allowed
373   ["na\u0131\u0308ve", "xn--nave-mza04z", false, false, false],
374   ["d\u0131\u0302ner", "xn--dner-lza40z", false, false, false],
375   // but the corresponding accented-i (based on dotted i) is OK
376   ["na\u00efve.com", "xn--nave-6pa.com", false, true, true],
377   ["d\u00eener.com", "xn--dner-0pa.com", false, true, true],
380 const profiles = ["ASCII", "high", "moderate"];
382 function run_test() {
383   var pbi = Services.prefs;
384   var oldProfile = pbi.getCharPref(
385     "network.IDN.restriction_profile",
386     "moderate"
387   );
388   var idnService = Cc["@mozilla.org/network/idn-service;1"].getService(
389     Ci.nsIIDNService
390   );
392   for (var i = 0; i < profiles.length; ++i) {
393     pbi.setCharPref("network.IDN.restriction_profile", profiles[i]);
395     dump("testing " + profiles[i] + " profile");
397     for (var j = 0; j < testcases.length; ++j) {
398       var test = testcases[j];
399       var URL = test[0] + ".com";
400       var punycodeURL = test[1] + ".com";
401       var expectedUnicode = test[2 + i];
402       var isASCII = {};
404       var result;
405       try {
406         result = idnService.convertToDisplayIDN(URL, isASCII);
407       } catch (e) {
408         result = ".com";
409       }
410       if (
411         punycodeURL.substr(0, 4) == "xn--" ||
412         punycodeURL.indexOf(".xn--") > 0
413       ) {
414         // test convertToDisplayIDN with a Unicode URL and with a
415         //  Punycode URL if we have one
416         Assert.equal(
417           escape(result),
418           expectedUnicode ? escape(URL) : escape(punycodeURL)
419         );
421         result = idnService.convertToDisplayIDN(punycodeURL, isASCII);
422         Assert.equal(
423           escape(result),
424           expectedUnicode ? escape(URL) : escape(punycodeURL)
425         );
426       } else {
427         // The "punycode" URL isn't punycode. This happens in testcases
428         // where the Unicode URL has become normalized to an ASCII URL,
429         // so, even though expectedUnicode is true, the expected result
430         // is equal to punycodeURL
431         Assert.equal(escape(result), escape(punycodeURL));
432       }
433     }
434   }
435   pbi.setCharPref("network.IDN.restriction_profile", oldProfile);