diff options
Diffstat (limited to 'browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js')
-rw-r--r-- | browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js b/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js new file mode 100644 index 0000000000..5191f05d04 --- /dev/null +++ b/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js @@ -0,0 +1,238 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +"use strict"; + +const { AboutWelcomeTelemetry } = ChromeUtils.importESModule( + "resource:///modules/aboutwelcome/AboutWelcomeTelemetry.sys.mjs" +); +const TELEMETRY_PREF = "browser.newtabpage.activity-stream.telemetry"; + +add_setup(function setup() { + do_get_profile(); + Services.fog.initializeFOG(); +}); + +// We recognize two kinds of unexpected data that might reach +// `submitGleanPingForPing`: unknown keys, and keys with unexpectedly-complex +// data (ie, non-scalar). +// We report the keys in special metrics to aid in system health monitoring. +add_task(function test_weird_data() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref(TELEMETRY_PREF); + }); + Services.prefs.setBoolPref(TELEMETRY_PREF, true); + + const AWTelemetry = new AboutWelcomeTelemetry(); + + const unknownKey = "some_unknown_key"; + const camelUnknownKey = AWTelemetry._snakeToCamelCase(unknownKey); + + let pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.unknownKeys[camelUnknownKey].testGetValue(), + 1, + "caught the unknown key" + ); + // TODO(bug 1600008): Also check the for-testing overall count. + Assert.equal(Glean.messagingSystem.unknownKeyCount.testGetValue(), 1); + }); + AWTelemetry.submitGleanPingForPing({ + [unknownKey]: "value doesn't matter", + }); + + Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); + + const invalidNestedDataKey = "event"; + pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.invalidNestedData[ + invalidNestedDataKey + ].testGetValue("messaging-system"), + 1, + "caught the invalid nested data" + ); + }); + AWTelemetry.submitGleanPingForPing({ + [invalidNestedDataKey]: { this_should: "not be", complex: "data" }, + }); + + Assert.ok(pingSubmitted, "Ping with invalid nested data submitted"); +}); + +// `event_context` is weird. It's an object, but it might have been stringified +// before being provided for recording. +add_task(function test_event_context() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref(TELEMETRY_PREF); + }); + Services.prefs.setBoolPref(TELEMETRY_PREF, true); + + const AWTelemetry = new AboutWelcomeTelemetry(); + + const eventContext = { + reason: "reason", + page: "page", + source: "source", + something_else: "not specifically handled", + screen_family: "family", + screen_id: "screen_id", + screen_index: 0, + screen_initlals: "screen_initials", + }; + const stringifiedEC = JSON.stringify(eventContext); + + let pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.eventReason.testGetValue(), + eventContext.reason, + "event_context.reason also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventPage.testGetValue(), + eventContext.page, + "event_context.page also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventSource.testGetValue(), + eventContext.source, + "event_context.source also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenFamily.testGetValue(), + eventContext.screen_family, + "event_context.screen_family also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenId.testGetValue(), + eventContext.screen_id, + "event_context.screen_id also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenIndex.testGetValue(), + eventContext.screen_index, + "event_context.screen_index also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenInitials.testGetValue(), + eventContext.screen_initials, + "event_context.screen_initials also in own metric." + ); + + Assert.equal( + Glean.messagingSystem.eventContext.testGetValue(), + stringifiedEC, + "whole event_context added as text." + ); + }); + AWTelemetry.submitGleanPingForPing({ + event_context: eventContext, + }); + Assert.ok(pingSubmitted, "Ping with object event_context submitted"); + + pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.eventReason.testGetValue(), + eventContext.reason, + "event_context.reason also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventPage.testGetValue(), + eventContext.page, + "event_context.page also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventSource.testGetValue(), + eventContext.source, + "event_context.source also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenFamily.testGetValue(), + eventContext.screen_family, + "event_context.screen_family also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenId.testGetValue(), + eventContext.screen_id, + "event_context.screen_id also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenIndex.testGetValue(), + eventContext.screen_index, + "event_context.screen_index also in own metric." + ); + Assert.equal( + Glean.messagingSystem.eventScreenInitials.testGetValue(), + eventContext.screen_initials, + "event_context.screen_initials also in own metric." + ); + + Assert.equal( + Glean.messagingSystem.eventContext.testGetValue(), + stringifiedEC, + "whole event_context added as text." + ); + }); + AWTelemetry.submitGleanPingForPing({ + event_context: stringifiedEC, + }); + Assert.ok(pingSubmitted, "Ping with string event_context submitted"); +}); + +// For event_context to be more useful, we want to make sure we don't error +// in cases where it doesn't make much sense, such as a plain string that +// doesnt attempt to represent a valid object. +add_task(function test_context_errors() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref(TELEMETRY_PREF); + }); + Services.prefs.setBoolPref(TELEMETRY_PREF, true); + + const AWTelemetry = new AboutWelcomeTelemetry(); + + let weird_context_ping = { + event_context: "oops, this string isn't a valid JS object!", + }; + + let pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.eventContextParseError.testGetValue(), + undefined, + "this poorly formed context shouldn't register because it was not an object!" + ); + }); + + AWTelemetry.submitGleanPingForPing(weird_context_ping); + + Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); + + weird_context_ping = { + event_context: + "{oops : {'this string isn't a valid JS object, but it sure looks like one!}}'", + }; + + pingSubmitted = false; + GleanPings.messagingSystem.testBeforeNextSubmit(() => { + pingSubmitted = true; + Assert.equal( + Glean.messagingSystem.eventContextParseError.testGetValue(), + 1, + "this poorly formed context should register because it was not an object!" + ); + }); + + AWTelemetry.submitGleanPingForPing(weird_context_ping); + + Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); +}); |