test_IPProtectionServerlist.js (6283B)
1 /* Any copyright is dedicated to the Public Domain. 2 https://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { 7 IPProtectionServerlist, 8 PrefServerList, 9 RemoteSettingsServerlist, 10 IPProtectionServerlistFactory, 11 } = ChromeUtils.importESModule( 12 "moz-src:///browser/components/ipprotection/IPProtectionServerlist.sys.mjs" 13 ); 14 15 const COLLECTION_NAME = "vpn-serverlist"; 16 17 const TEST_SERVER_1 = { 18 hostname: "test1.example.com", 19 port: 443, 20 quarantined: false, 21 protocols: [ 22 { 23 name: "connect", 24 host: "test1.example.com", 25 port: 8443, 26 scheme: "https", 27 }, 28 ], 29 }; 30 const TEST_SERVER_2 = { 31 hostname: "test2.example.com", 32 port: 443, 33 quarantined: false, 34 protocols: [ 35 { 36 name: "connect", 37 host: "test2.example.com", 38 port: 8443, 39 scheme: "https", 40 }, 41 ], 42 }; 43 const TEST_SERVER_QUARANTINED = { 44 hostname: "quarantined.example.com", 45 port: 443, 46 quarantined: true, 47 protocols: [ 48 { 49 name: "connect", 50 host: "quarantined.example.com", 51 port: 8443, 52 scheme: "https", 53 }, 54 ], 55 }; 56 57 const TEST_US_CITY = { 58 name: "Test City", 59 code: "TC", 60 servers: [TEST_SERVER_1, TEST_SERVER_2], 61 }; 62 63 const TEST_COUNTRIES = [ 64 { 65 name: "United States", 66 code: "US", 67 cities: [TEST_US_CITY], 68 }, 69 { 70 name: "Canada", 71 code: "CA", 72 cities: [ 73 { 74 name: "Test City 2", 75 code: "TC2", 76 servers: [TEST_SERVER_1], 77 }, 78 ], 79 }, 80 ]; 81 82 const client = RemoteSettings(COLLECTION_NAME); 83 84 add_setup(async function () { 85 do_get_profile(); 86 await client.db.clear(); 87 for (const country of TEST_COUNTRIES) { 88 await client.db.create(country); 89 } 90 await client.db.importChanges({}, Date.now()); 91 92 await IPProtectionServerlist.maybeFetchList(); 93 await IPProtectionServerlist.initOnStartupCompleted(); 94 Assert.ok(IPProtectionServerlist instanceof RemoteSettingsServerlist); 95 }); 96 97 add_task(async function test_getDefaultLocation() { 98 const { country, city } = IPProtectionServerlist.getDefaultLocation(); 99 Assert.equal(country.code, "US", "The default country should be US"); 100 Assert.deepEqual(city, TEST_US_CITY, "The default city should be returned"); 101 }); 102 103 add_task(async function test_selectServer() { 104 // Test with a city with multiple non-quarantined servers 105 let selected = IPProtectionServerlist.selectServer(TEST_US_CITY); 106 Assert.ok( 107 [TEST_SERVER_1, TEST_SERVER_2].some(s => s.hostname === selected.hostname), 108 "A valid server should be selected" 109 ); 110 111 // Test with a city with one server 112 const cityWithOneServer = { 113 name: "One Server City", 114 code: "OSC", 115 servers: [TEST_SERVER_1], 116 }; 117 selected = IPProtectionServerlist.selectServer(cityWithOneServer); 118 Assert.deepEqual( 119 selected, 120 TEST_SERVER_1, 121 "The single server should be selected" 122 ); 123 124 // Test with a city with a mix of quarantined and non-quarantined servers 125 const cityWithMixedServers = { 126 name: "Mixed Servers City", 127 code: "MSC", 128 servers: [TEST_SERVER_1, TEST_SERVER_QUARANTINED], 129 }; 130 selected = IPProtectionServerlist.selectServer(cityWithMixedServers); 131 Assert.deepEqual( 132 selected, 133 TEST_SERVER_1, 134 "The non-quarantined server should be selected" 135 ); 136 137 // Test with a city with only quarantined servers 138 const cityWithQuarantinedServers = { 139 name: "Quarantined City", 140 code: "QC", 141 servers: [TEST_SERVER_QUARANTINED], 142 }; 143 selected = IPProtectionServerlist.selectServer(cityWithQuarantinedServers); 144 Assert.equal(selected, null, "No server should be selected"); 145 146 // Test with a city with no servers 147 const cityWithNoServers = { 148 name: "No Server City", 149 code: "NSC", 150 servers: [], 151 }; 152 selected = IPProtectionServerlist.selectServer(cityWithNoServers); 153 Assert.equal(selected, null, "No server should be selected"); 154 }); 155 156 add_task(async function test_syncRespected() { 157 let { country, city } = IPProtectionServerlist.getDefaultLocation(); 158 Assert.equal(country.code, "US", "The default country should be US"); 159 Assert.deepEqual(city, TEST_US_CITY, "The correct city should be returned"); 160 161 // Now, update the server list to remove the US entry 162 const updated_server = { 163 ...TEST_SERVER_1, 164 hostname: "updated.example.com", 165 }; 166 const updated_city = { 167 ...TEST_US_CITY, 168 servers: [updated_server], 169 }; 170 const updated_country = { 171 ...TEST_COUNTRIES[0], 172 cities: [updated_city], 173 }; 174 175 await client.db.clear(); 176 await client.db.create(updated_country); 177 await client.db.importChanges({}, Date.now()); 178 await client.emit("sync", { data: {} }); 179 180 await IPProtectionServerlist.maybeFetchList(); 181 182 ({ country, city } = IPProtectionServerlist.getDefaultLocation()); 183 Assert.equal(country.code, "US", "The default country should be US"); 184 Assert.deepEqual(city, updated_city, "The updated city should be returned"); 185 }); 186 187 add_task(async function test_PrefServerList() { 188 registerCleanupFunction(() => { 189 Services.prefs.clearUserPref(PrefServerList.PREF_NAME); 190 }); 191 Services.prefs.setCharPref( 192 PrefServerList.PREF_NAME, 193 JSON.stringify(TEST_COUNTRIES) 194 ); 195 196 Assert.equal( 197 PrefServerList.hasPrefValue, 198 true, 199 "PrefServerList should have a pref value set." 200 ); 201 Assert.deepEqual( 202 PrefServerList.prefValue, 203 TEST_COUNTRIES, 204 "PrefServerList's pref value should match the set value." 205 ); 206 207 const serverList = new PrefServerList(); 208 await serverList.maybeFetchList(); 209 210 const { country, city } = serverList.getDefaultLocation(); 211 Assert.equal(country.code, "US", "The default country should be US"); 212 Assert.deepEqual(city, TEST_US_CITY, "The default city should be returned."); 213 }); 214 215 add_task(async function test_IPProtectionServerlistFactory() { 216 registerCleanupFunction(() => { 217 Services.prefs.clearUserPref(PrefServerList.PREF_NAME); 218 }); 219 // Without the pref set, it should return RemoteSettingsServerlist 220 Services.prefs.clearUserPref(PrefServerList.PREF_NAME); 221 let instance = IPProtectionServerlistFactory(); 222 Assert.ok(instance instanceof RemoteSettingsServerlist); 223 Services.prefs.setCharPref( 224 PrefServerList.PREF_NAME, 225 JSON.stringify(TEST_COUNTRIES) 226 ); 227 // With the pref set, it should return PrefServerList 228 Assert.ok(IPProtectionServerlistFactory() instanceof PrefServerList); 229 });