summaryrefslogtreecommitdiffstats
path: root/intl/locale/tests/LangPackMatcherTestUtils.sys.mjs
blob: 4b18f1be134e23f4dff7cc015e66e55a680e8657 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { LangPackMatcher } from "resource://gre/modules/LangPackMatcher.sys.mjs";

/**
 * LangPackMatcher.jsm calls out to to the addons store, which involves network requests.
 * Other tests create a fake addons server, and install mock XPIs. At the time of this
 * writing that infrastructure is not available for mochitests.
 *
 * Instead, this test mocks out APIs that have a side-effect, so the addons of the browser
 * are never modified.
 *
 * The calls to get the app's locale and system's locale are also mocked so that the
 * different language mismatch scenarios can be run through.
 *
 * The locales are BCP 47 identifiers:
 *
 * @param {{
 *   sandbox: SinonSandbox,
 *   systemLocale: string,
 *   appLocale, string,
 * }}
 */
export function getAddonAndLocalAPIsMocker(testScope, sandbox) {
  const { info } = testScope;
  return function mockAddonAndLocaleAPIs({ systemLocale, appLocale }) {
    info("Mocking LangPackMatcher.jsm APIs");

    let resolveLangPacks;
    const langPackPromise = new Promise(resolve => {
      resolveLangPacks = availableLangpacks => {
        info(
          `Resolving which langpacks are available for download: ${JSON.stringify(
            availableLangpacks
          )}`
        );
        resolve(
          availableLangpacks.map(locale => ({
            guid: `langpack-${locale}@firefox.mozilla.org`,
            type: "language",
            hash: locale,
            target_locale: locale,
            current_compatible_version: {
              files: [
                {
                  platform: "all",
                  url: `http://example.com/${locale}.langpack.xpi`,
                },
              ],
            },
          }))
        );
      };
    });

    let resolveInstaller;
    const installerPromise = new Promise(resolve => {
      resolveInstaller = () => {
        info("LangPack install finished.");
        resolve();
      };
    });

    const { mockable } = LangPackMatcher;
    if (appLocale) {
      const availableLocales = [appLocale];
      if (appLocale !== "en-US") {
        // Ensure the fallback behavior is accurately simulated for Firefox.
        availableLocales.push("en-US");
      }
      sandbox
        .stub(mockable, "getAvailableLocalesIncludingFallback")
        .returns(availableLocales);
      sandbox.stub(mockable, "getDefaultLocale").returns(appLocale);
      sandbox.stub(mockable, "getAppLocaleAsBCP47").returns(appLocale);
      sandbox.stub(mockable, "getLastFallbackLocale").returns("en-US");
    }
    if (systemLocale) {
      sandbox.stub(mockable, "getSystemLocale").returns(systemLocale);
    }

    sandbox.stub(mockable, "getAvailableLangpacks").callsFake(() => {
      info("Requesting which langpacks are available for download");
      return langPackPromise;
    });

    sandbox.stub(mockable, "installLangPack").callsFake(langPack => {
      info(`LangPack install started, but pending: ${langPack.target_locale}`);
      return installerPromise;
    });

    sandbox.stub(mockable, "setRequestedAppLocales").callsFake(locales => {
      info(
        `Changing the browser's requested locales to: ${JSON.stringify(
          locales
        )}`
      );
    });

    return {
      /**
       * Resolves the addons API call with available langpacks. Call with a list
       * of BCP 47 identifiers.
       *
       * @type {(availableLangpacks: string[]) => {}}
       */
      resolveLangPacks,

      /**
       * Resolves the pending call to install a langpack.
       *
       * @type {() => {}}
       */
      resolveInstaller,

      /**
       * The mocked APIs.
       */
      mockable,
    };
  };
}