michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {utils: Cu} = Components; michael@0: michael@0: Cu.import("resource://gre/modules/Metrics.jsm"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: let bsp = Cu.import("resource://gre/modules/services/healthreport/providers.jsm"); michael@0: michael@0: const DEFAULT_ENGINES = [ michael@0: {name: "Amazon.com", identifier: "amazondotcom"}, michael@0: {name: "Bing", identifier: "bing"}, michael@0: {name: "Google", identifier: "google"}, michael@0: {name: "Yahoo", identifier: "yahoo"}, michael@0: {name: "Foobar Search", identifier: "foobar"}, michael@0: ]; michael@0: michael@0: function MockSearchCountMeasurement() { michael@0: bsp.SearchCountMeasurement3.call(this); michael@0: } michael@0: MockSearchCountMeasurement.prototype = { michael@0: __proto__: bsp.SearchCountMeasurement3.prototype, michael@0: }; michael@0: michael@0: function MockSearchesProvider() { michael@0: SearchesProvider.call(this); michael@0: } michael@0: MockSearchesProvider.prototype = { michael@0: __proto__: SearchesProvider.prototype, michael@0: measurementTypes: [MockSearchCountMeasurement], michael@0: }; michael@0: michael@0: function run_test() { michael@0: run_next_test(); michael@0: } michael@0: michael@0: add_test(function test_constructor() { michael@0: let provider = new SearchesProvider(); michael@0: michael@0: run_next_test(); michael@0: }); michael@0: michael@0: add_task(function* test_record() { michael@0: let storage = yield Metrics.Storage("record"); michael@0: let provider = new MockSearchesProvider(); michael@0: michael@0: yield provider.init(storage); michael@0: michael@0: let now = new Date(); michael@0: michael@0: // Record searches for all but one of our defaults, and one engine that's michael@0: // not a default. michael@0: for (let engine of DEFAULT_ENGINES.concat([{name: "Not Default", identifier: "notdef"}])) { michael@0: if (engine.identifier == "yahoo") { michael@0: continue; michael@0: } michael@0: yield provider.recordSearch(engine, "abouthome"); michael@0: yield provider.recordSearch(engine, "contextmenu"); michael@0: yield provider.recordSearch(engine, "newtab"); michael@0: yield provider.recordSearch(engine, "searchbar"); michael@0: yield provider.recordSearch(engine, "urlbar"); michael@0: } michael@0: michael@0: // Invalid sources should throw. michael@0: let errored = false; michael@0: try { michael@0: yield provider.recordSearch(DEFAULT_ENGINES[0], "bad source"); michael@0: } catch (ex) { michael@0: errored = true; michael@0: } finally { michael@0: do_check_true(errored); michael@0: } michael@0: michael@0: let m = provider.getMeasurement("counts", 3); michael@0: let data = yield m.getValues(); michael@0: do_check_eq(data.days.size, 1); michael@0: do_check_true(data.days.hasDay(now)); michael@0: michael@0: let day = data.days.getDay(now); michael@0: for (let engine of DEFAULT_ENGINES) { michael@0: let identifier = engine.identifier; michael@0: let expected = identifier != "yahoo"; michael@0: michael@0: for (let source of ["abouthome", "contextmenu", "searchbar", "urlbar"]) { michael@0: let field = identifier + "." + source; michael@0: if (expected) { michael@0: do_check_true(day.has(field)); michael@0: do_check_eq(day.get(field), 1); michael@0: } else { michael@0: do_check_false(day.has(field)); michael@0: } michael@0: } michael@0: } michael@0: michael@0: // Also, check that our non-default engine contributed, with a computed michael@0: // identifier. michael@0: let identifier = "notdef"; michael@0: for (let source of ["abouthome", "contextmenu", "searchbar", "urlbar"]) { michael@0: let field = identifier + "." + source; michael@0: do_check_true(day.has(field)); michael@0: } michael@0: michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function* test_includes_other_fields() { michael@0: let storage = yield Metrics.Storage("includes_other_fields"); michael@0: let provider = new MockSearchesProvider(); michael@0: michael@0: yield provider.init(storage); michael@0: let m = provider.getMeasurement("counts", 3); michael@0: michael@0: // Register a search against a provider that isn't live in this session. michael@0: let id = yield m.storage.registerField(m.id, "test.searchbar", michael@0: Metrics.Storage.FIELD_DAILY_COUNTER); michael@0: michael@0: let testField = "test.searchbar"; michael@0: let now = new Date(); michael@0: yield m.storage.incrementDailyCounterFromFieldID(id, now); michael@0: michael@0: // Make sure we don't know about it. michael@0: do_check_false(testField in m.fields); michael@0: michael@0: // But we want to include it in payloads. michael@0: do_check_true(m.shouldIncludeField(testField)); michael@0: michael@0: // And we do so. michael@0: let data = yield provider.storage.getMeasurementValues(m.id); michael@0: let serializer = m.serializer(m.SERIALIZE_JSON); michael@0: let formatted = serializer.daily(data.days.getDay(now)); michael@0: do_check_true(testField in formatted); michael@0: do_check_eq(formatted[testField], 1); michael@0: michael@0: yield storage.close(); michael@0: }); michael@0: michael@0: add_task(function* test_default_search_engine() { michael@0: let storage = yield Metrics.Storage("default_search_engine"); michael@0: let provider = new SearchesProvider(); michael@0: yield provider.init(storage); michael@0: michael@0: let m = provider.getMeasurement("engines", 1); michael@0: michael@0: // Ensure no collection if Telemetry not enabled. michael@0: Services.prefs.setBoolPref("toolkit.telemetry.enabled", false); michael@0: michael@0: let now = new Date(); michael@0: yield provider.collectDailyData(); michael@0: michael@0: let data = yield m.getValues(); michael@0: Assert.equal(data.days.hasDay(now), false); michael@0: michael@0: // Now enable telemetry and ensure we populate. michael@0: Services.prefs.setBoolPref("toolkit.telemetry.enabled", true); michael@0: michael@0: yield provider.collectDailyData(); michael@0: data = yield m.getValues(); michael@0: Assert.ok(data.days.hasDay(now)); michael@0: michael@0: let day = data.days.getDay(now); michael@0: Assert.equal(day.size, 1); michael@0: Assert.ok(day.has("default")); michael@0: michael@0: // test environment doesn't have a default engine. michael@0: Assert.equal(day.get("default"), "NONE"); michael@0: michael@0: Services.search.addEngineWithDetails("testdefault", michael@0: "http://localhost/icon.png", michael@0: null, michael@0: "test description", michael@0: "GET", michael@0: "http://localhost/search/%s"); michael@0: let engine1 = Services.search.getEngineByName("testdefault"); michael@0: Assert.ok(engine1); michael@0: Services.search.defaultEngine = engine1; michael@0: michael@0: yield provider.collectDailyData(); michael@0: data = yield m.getValues(); michael@0: Assert.equal(data.days.getDay(now).get("default"), "other-testdefault"); michael@0: michael@0: yield storage.close(); michael@0: });