test_header_Accept-Language.js (2912B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // 6 // HTTP Accept-Language header test 7 // 8 9 "use strict"; 10 11 var testpath = "/bug672448"; 12 13 function run_test() { 14 let intlPrefs = Services.prefs.getBranch("intl."); 15 16 // Save old value of preference for later. 17 let oldPref = intlPrefs.getCharPref("accept_languages"); 18 19 // Test different numbers of languages, to test different fractions. 20 let acceptLangTests = [ 21 "qaa", // 1 22 "qaa,qab", // 2 23 "qaa,qab,qac,qad", // 4 24 "qaa,qab,qac,qad,qae,qaf,qag,qah", // 8 25 "qaa,qab,qac,qad,qae,qaf,qag,qah,qai,qaj", // 10 26 "qaa,qab,qac,qad,qae,qaf,qag,qah,qai,qaj,qak", // 11 27 "qaa,qab,qac,qad,qae,qaf,qag,qah,qai,qaj,qak,qal,qam,qan,qao,qap,qaq,qar,qas,qat,qau", // 21 28 oldPref, // Restore old value of preference (and test it). 29 ]; 30 31 let acceptLangTestsNum = acceptLangTests.length; 32 33 for (let i = 0; i < acceptLangTestsNum; i++) { 34 // Set preference to test value. 35 intlPrefs.setCharPref("accept_languages", acceptLangTests[i]); 36 37 // Test value. 38 test_accepted_languages(); 39 } 40 } 41 42 function test_accepted_languages() { 43 let channel = setupChannel(testpath); 44 45 let AcceptLanguage = channel.getRequestHeader("Accept-Language"); 46 47 let acceptedLanguages = AcceptLanguage.split(","); 48 49 let acceptedLanguagesLength = acceptedLanguages.length; 50 51 for (let i = 0; i < acceptedLanguagesLength; i++) { 52 let qualityValue; 53 54 try { 55 // The q-value must conform to the definition in HTTP/1.1 Section 3.9. 56 [, , qualityValue] = acceptedLanguages[i] 57 .trim() 58 .match(/^([a-z0-9_-]*?)(?:;q=(1(?:\.0{0,3})?|0(?:\.[0-9]{0,3})))?$/i); 59 } catch (e) { 60 do_throw("Invalid language tag or quality value: " + e); 61 } 62 63 if (i == 0) { 64 // The first language shouldn't have a quality value. 65 Assert.equal(qualityValue, undefined); 66 } else { 67 let decimalPlaces; 68 69 // When the number of languages is small, we keep the quality value to only one decimal place. 70 // Otherwise, it can be up to two decimal places. 71 if (acceptedLanguagesLength < 10) { 72 Assert.equal(qualityValue.length, 3); 73 74 decimalPlaces = 1; 75 } else { 76 Assert.greaterOrEqual(qualityValue.length, 3); 77 Assert.lessOrEqual(qualityValue.length, 4); 78 79 decimalPlaces = 2; 80 } 81 82 // All the other languages should have an evenly-spaced quality value. 83 Assert.equal( 84 parseFloat(qualityValue).toFixed(decimalPlaces), 85 Math.max(1.0 - i * 0.1, 0.1).toFixed(decimalPlaces) 86 ); 87 } 88 } 89 } 90 91 function setupChannel(path) { 92 let chan = NetUtil.newChannel({ 93 uri: "http://localhost:4444" + path, 94 loadUsingSystemPrincipal: true, 95 }); 96 97 chan.QueryInterface(Ci.nsIHttpChannel); 98 return chan; 99 }