summaryrefslogtreecommitdiffstats
path: root/browser/components/search/test/browser_google_codes.js
blob: e166b6868969c6cb6c007b0d0cc5a15fdf27ccca (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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const kUrlPref = "geoSpecificDefaults.url";
const BROWSER_SEARCH_PREF = "browser.search.";

var originalGeoURL;

/**
 * Clean the profile of any cache file left from a previous run.
 * Returns a boolean indicating if the cache file existed.
 */
function removeCacheFile()
{
  const CACHE_FILENAME = "search.json.mozlz4";

  let file =  Services.dirsvc.get("ProfD", Ci.nsIFile);
  file.append(CACHE_FILENAME);
  if (file.exists()) {
    file.remove(false);
    return true;
  }
  return false;
}

/**
 * Returns a promise that is resolved when an observer notification from the
 * search service fires with the specified data.
 *
 * @param aExpectedData
 *        The value the observer notification sends that causes us to resolve
 *        the promise.
 */
function waitForSearchNotification(aExpectedData, aCallback) {
  const SEARCH_SERVICE_TOPIC = "browser-search-service";
  Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
    if (aData != aExpectedData)
      return;

    Services.obs.removeObserver(observer, SEARCH_SERVICE_TOPIC);
    aCallback();
  }, SEARCH_SERVICE_TOPIC, false);
}

function asyncInit() {
  return new Promise(resolve => {
    Services.search.init(function() {
      ok(Services.search.isInitialized, "search service should be initialized");
      resolve();
    });
  });
}

function asyncReInit() {
  const kLocalePref = "general.useragent.locale";

  let promise = new Promise(resolve => {
    waitForSearchNotification("reinit-complete", resolve);
  });

  Services.search.QueryInterface(Ci.nsIObserver)
          .observe(null, "nsPref:changed", kLocalePref);

  return promise;
}

let gEngineCount;

add_task(function* preparation() {
  // ContentSearch is interferring with our async re-initializations of the
  // search service: once _initServicePromise has resolved, it will access
  // the search service, thus causing unpredictable behavior due to
  // synchronous initializations of the service.
  let originalContentSearchPromise = ContentSearch._initServicePromise;
  ContentSearch._initServicePromise = new Promise(resolve => {
    registerCleanupFunction(() => {
      ContentSearch._initServicePromise = originalContentSearchPromise;
      resolve();
    });
  });

  yield asyncInit();
  gEngineCount = Services.search.getVisibleEngines().length;

  waitForSearchNotification("uninit-complete", () => {
    // Verify search service is not initialized
    is(Services.search.isInitialized, false, "Search service should NOT be initialized");

    removeCacheFile();

    // Geo specific defaults won't be fetched if there's no country code.
    Services.prefs.setCharPref("browser.search.geoip.url",
                               'data:application/json,{"country_code": "US"}');

    Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", true);

    // Make the new Google the only engine
    originalGeoURL = Services.prefs.getCharPref(BROWSER_SEARCH_PREF + kUrlPref);
    let geoUrl = 'data:application/json,{"interval": 31536000, "settings": {"searchDefault": "Google", "visibleDefaultEngines": ["google"]}}';
    Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF).setCharPref(kUrlPref, geoUrl);
  });

  yield asyncReInit();

  yield new Promise(resolve => {
    waitForSearchNotification("write-cache-to-disk-complete", resolve);
  });
});

add_task(function* tests() {
  let engines = Services.search.getEngines();
  is(Services.search.currentEngine.name, "Google", "Search engine should be Google");
  is(engines.length, 1, "There should only be one engine");

  let engine = Services.search.getEngineByName("Google");
  ok(engine, "Google");

  let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&client=firefox-b";

  // Keyword uses a slightly different code
  let keywordBase = base + "-ab";

  let url;

  // Test search URLs (including purposes).
  url = engine.getSubmission("foo", null, "contextmenu").uri.spec;
  is(url, base, "Check context menu search URL for 'foo'");
  url = engine.getSubmission("foo", null, "keyword").uri.spec;
  is(url, keywordBase, "Check keyword search URL for 'foo'");
  url = engine.getSubmission("foo", null, "searchbar").uri.spec;
  is(url, base, "Check search bar search URL for 'foo'");
  url = engine.getSubmission("foo", null, "homepage").uri.spec;
  is(url, base, "Check homepage search URL for 'foo'");
  url = engine.getSubmission("foo", null, "newtab").uri.spec;
  is(url, base, "Check newtab search URL for 'foo'");
  url = engine.getSubmission("foo", null, "system").uri.spec;
  is(url, base, "Check system search URL for 'foo'");
});


add_task(function* cleanup() {
  waitForSearchNotification("uninit-complete", () => {
    // Verify search service is not initialized
    is(Services.search.isInitialized, false,
       "Search service should NOT be initialized");
    removeCacheFile();

    Services.prefs.clearUserPref("browser.search.geoip.url");

    // We can't clear the pref because it's set to false by testing/profiles/prefs_general.js
    Services.prefs.setBoolPref("browser.search.geoSpecificDefaults", false);

    Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF).setCharPref(kUrlPref, originalGeoURL);
  });

  yield asyncReInit();
  is(gEngineCount, Services.search.getVisibleEngines().length,
     "correct engine count after cleanup");
});