tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_geolocationUtils.js (9019B)


      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 // Tests GeolocationUtils.sys.mjs.
      6 
      7 "use strict";
      8 
      9 ChromeUtils.defineESModuleGetters(this, {
     10  GeolocationUtils:
     11    "moz-src:///browser/components/urlbar/private/GeolocationUtils.sys.mjs",
     12 });
     13 
     14 add_setup(async () => {
     15  // This test assume the mock geolocation is Kanagawa, Yokohama, Japan.
     16  await MerinoTestUtils.initGeolocation();
     17 });
     18 
     19 const KAWASAKI = {
     20  latitude: 35.516667,
     21  longitude: 139.7,
     22  country: "JP",
     23  region: "14",
     24  population: 1531646,
     25 };
     26 
     27 // Made up city with the same location Kawasaki except it has a larger
     28 // population.
     29 const KAWASAKI_LARGER_POP = {
     30  latitude: 35.516667,
     31  longitude: 139.7,
     32  country: "JP",
     33  region: "14",
     34  population: Infinity,
     35 };
     36 
     37 const YOKOSUKA = {
     38  latitude: 35.2815,
     39  longitude: 139.672083,
     40  country: "JP",
     41  region: "14",
     42  population: 388078,
     43 };
     44 
     45 const OSAKA = {
     46  latitude: 34.693889,
     47  longitude: 135.502222,
     48  country: "JP",
     49  region: "27",
     50  population: 2753862,
     51 };
     52 
     53 const MITOYO = {
     54  latitude: 34.1825,
     55  longitude: 133.715,
     56  country: "JP",
     57  region: "37",
     58  population: 59876,
     59 };
     60 
     61 const NYC = {
     62  latitude: 40.71427,
     63  longitude: -74.00597,
     64  country: "US",
     65  region: "NY",
     66  population: 8804190,
     67 };
     68 
     69 // Tests items whose locations have latitude and longitude.
     70 add_task(async function bestByDistance() {
     71  // The made-up city with the same location as Kawasaki but with a larger
     72  // population should be returned due to its larger population.
     73  Assert.deepEqual(
     74    await GeolocationUtils.best([
     75      MITOYO,
     76      YOKOSUKA,
     77      KAWASAKI,
     78      KAWASAKI_LARGER_POP,
     79      NYC,
     80    ]),
     81    KAWASAKI_LARGER_POP,
     82    "Made-up Kawasaki-like city should be best when listed after Kawasaki"
     83  );
     84  Assert.deepEqual(
     85    await GeolocationUtils.best([
     86      MITOYO,
     87      YOKOSUKA,
     88      KAWASAKI_LARGER_POP,
     89      KAWASAKI,
     90      NYC,
     91    ]),
     92    KAWASAKI_LARGER_POP,
     93    "Made-up Kawasaki-like city should be best when listed before Kawasaki"
     94  );
     95 
     96  // Kawasaki is closest to Yokohama.
     97  Assert.deepEqual(
     98    await GeolocationUtils.best([MITOYO, YOKOSUKA, KAWASAKI, NYC]),
     99    KAWASAKI,
    100    "Kawasaki should be best"
    101  );
    102 
    103  // Yokosuka is next closest when the Kawasaki location is messed up.
    104  Assert.deepEqual(
    105    await GeolocationUtils.best([
    106      MITOYO,
    107      YOKOSUKA,
    108      { ...KAWASAKI, latitude: null },
    109      NYC,
    110    ]),
    111    YOKOSUKA,
    112    "Yokosuka should be best when Kawasaki location is missing latitude"
    113  );
    114  Assert.deepEqual(
    115    await GeolocationUtils.best([
    116      MITOYO,
    117      YOKOSUKA,
    118      { ...KAWASAKI, longitude: null },
    119      NYC,
    120    ]),
    121    YOKOSUKA,
    122    "Yokosuka should be best when Kawasaki location is missing longitude"
    123  );
    124 });
    125 
    126 // Tests items whose locations have region and country but no latitude or
    127 // longitude.
    128 add_task(async function bestByRegion() {
    129  let kawasaki = { ...KAWASAKI, latitude: null, longitude: null };
    130  let yokosuka = { ...YOKOSUKA, latitude: null, longitude: null };
    131  let osaka = { ...OSAKA, latitude: null, longitude: null };
    132  let mitoyo = { ...MITOYO, latitude: null, longitude: null };
    133  let nyc = { ...NYC, latitude: null, longitude: null };
    134 
    135  // Kawasaki and Yokosuka are in the same region as Yokohama, and Kawasaki has
    136  // a larger population, so it should be returned.
    137  Assert.deepEqual(
    138    await GeolocationUtils.best([mitoyo, yokosuka, kawasaki, nyc]),
    139    kawasaki,
    140    "Kawasaki should be best when listed after Yokosuka"
    141  );
    142  Assert.deepEqual(
    143    await GeolocationUtils.best([mitoyo, kawasaki, yokosuka, nyc]),
    144    kawasaki,
    145    "Kawasaki should be best when listed before Yokosuka"
    146  );
    147 
    148  // Yokosuka is in the same region as Yokohama, so it should be returned.
    149  Assert.deepEqual(
    150    await GeolocationUtils.best([mitoyo, yokosuka, nyc]),
    151    yokosuka,
    152    "Yokosuka should be best"
    153  );
    154 
    155  // Osaka is in a different region but the same country as the geolocation, and
    156  // it has a larger population than Mitoyo, so it should be returned.
    157  Assert.deepEqual(
    158    await GeolocationUtils.best([mitoyo, osaka, nyc]),
    159    osaka,
    160    "Osaka should be best when listed after Mitoyo"
    161  );
    162  Assert.deepEqual(
    163    await GeolocationUtils.best([osaka, mitoyo, nyc]),
    164    osaka,
    165    "Osaka should be best when listed before Mitoyo"
    166  );
    167 
    168  // Mitoyo is in a different region but the same country as the geolocation, so
    169  // it should be returned.
    170  Assert.deepEqual(
    171    await GeolocationUtils.best([mitoyo, nyc]),
    172    mitoyo,
    173    "Mitoyo should be best when listed first"
    174  );
    175  Assert.deepEqual(
    176    await GeolocationUtils.best([nyc, mitoyo]),
    177    mitoyo,
    178    "Mitoyo should be best when listed last"
    179  );
    180 });
    181 
    182 // Tests non-default values for the `locationFromItem` param.
    183 add_task(async function locationFromItem() {
    184  // Return an empty location for everything except NYC. Since NYC is the only
    185  // location with latitude and longitude, `best()` should return it even though
    186  // it's not actually the closest to Merino's mock geolocation.
    187  Assert.deepEqual(
    188    await GeolocationUtils.best([MITOYO, KAWASAKI, YOKOSUKA, NYC], item =>
    189      item == NYC ? NYC : {}
    190    ),
    191    NYC,
    192    "NYC should be best"
    193  );
    194 });
    195 
    196 // Tests unexpected Merino geolocation responses.
    197 add_task(async function unexpectedMerinoGeolocation() {
    198  // The first item should be returned in all these cases.
    199  MerinoTestUtils.server.response = { status: 501 };
    200  Assert.deepEqual(
    201    await GeolocationUtils.best([NYC, MITOYO, YOKOSUKA, KAWASAKI]),
    202    NYC,
    203    "NYC should be best when geolocation response is not a 200"
    204  );
    205 
    206  await MerinoTestUtils.initGeolocation();
    207  MerinoTestUtils.server.response = { status: 200 };
    208  Assert.deepEqual(
    209    await GeolocationUtils.best([NYC, MITOYO, YOKOSUKA, KAWASAKI]),
    210    NYC,
    211    "NYC should be best when geolocation response is empty"
    212  );
    213 
    214  await MerinoTestUtils.initGeolocation();
    215  MerinoTestUtils.server.response.body.suggestions[0].custom_details = null;
    216  Assert.deepEqual(
    217    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    218    NYC,
    219    "NYC should be best when geolocation response is missing custom_details"
    220  );
    221 
    222  await MerinoTestUtils.initGeolocation();
    223  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation =
    224    null;
    225  Assert.deepEqual(
    226    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    227    NYC,
    228    "NYC should be best when geolocation response is missing geolocation"
    229  );
    230 
    231  await MerinoTestUtils.initGeolocation();
    232  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.region_code =
    233    null;
    234  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.country_code =
    235    null;
    236  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.location =
    237    null;
    238  Assert.deepEqual(
    239    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    240    NYC,
    241    "NYC should be best when geolocation response is missing geolocation"
    242  );
    243 
    244  // We should fall back to `#bestByRegion()` in these cases.
    245  await MerinoTestUtils.initGeolocation();
    246  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.location =
    247    null;
    248  Assert.deepEqual(
    249    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    250    KAWASAKI,
    251    "Kawasaki should be best when geolocation response is missing location"
    252  );
    253 
    254  await MerinoTestUtils.initGeolocation();
    255  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.location.latitude =
    256    null;
    257  Assert.deepEqual(
    258    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    259    KAWASAKI,
    260    "Kawasaki should be best when geolocation response is missing latitude"
    261  );
    262 
    263  await MerinoTestUtils.initGeolocation();
    264  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.location.longitude =
    265    null;
    266  Assert.deepEqual(
    267    await GeolocationUtils.best([NYC, MITOYO, KAWASAKI, YOKOSUKA]),
    268    KAWASAKI,
    269    "Kawasaki should be best when geolocation response is missing longitude"
    270  );
    271 
    272  // Here `region_code` and `location` are null but `country_code` is still
    273  // correct, so the item with the same country should be returned.
    274  await MerinoTestUtils.initGeolocation();
    275  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.region_code =
    276    null;
    277  MerinoTestUtils.server.response.body.suggestions[0].custom_details.geolocation.location =
    278    null;
    279  Assert.deepEqual(
    280    await GeolocationUtils.best([NYC, MITOYO]),
    281    MITOYO,
    282    "Mitoyo should be best when geolocation response is missing region_code and location and Mitoyo is listed after NYC"
    283  );
    284  Assert.deepEqual(
    285    await GeolocationUtils.best([MITOYO, NYC]),
    286    MITOYO,
    287    "Mitoyo should be best when geolocation response is missing region_code and location and Mitoyo is listed before NYC"
    288  );
    289 
    290  // Reset for the next task.
    291  await MerinoTestUtils.initGeolocation();
    292 });