diff --git a/firefox-ios/Client.xcodeproj/project.pbxproj b/firefox-ios/Client.xcodeproj/project.pbxproj index ffe1c747b5e2..0ca72cffd268 100644 --- a/firefox-ios/Client.xcodeproj/project.pbxproj +++ b/firefox-ios/Client.xcodeproj/project.pbxproj @@ -937,6 +937,7 @@ 8A94418A2CE3E190007FF4E5 /* MockSearchEngineManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A9441892CE3E190007FF4E5 /* MockSearchEngineManager.swift */; }; 8A95FF642B1E969E00AC303D /* TelemetryContextualIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A95FF632B1E969E00AC303D /* TelemetryContextualIdentifier.swift */; }; 8A95FF672B1E97A800AC303D /* TelemetryContextualIdentifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A95FF652B1E977E00AC303D /* TelemetryContextualIdentifierTests.swift */; }; + 8A967E422D30419100B1017D /* TelemetryDebugMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A967E412D30418A00B1017D /* TelemetryDebugMessage.swift */; }; 8A96C4BB28F9E7B300B75884 /* XCTestCaseRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A96C4BA28F9E7B300B75884 /* XCTestCaseRootViewController.swift */; }; 8A97E6EA2C58487900F94793 /* AddressLocaleFeatureValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A97E6E92C58487900F94793 /* AddressLocaleFeatureValidator.swift */; }; 8A97E6EF2C584C4900F94793 /* AddressLocaleFeatureValidatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A97E6ED2C584AC300F94793 /* AddressLocaleFeatureValidatorTests.swift */; }; @@ -7743,6 +7744,7 @@ 8A9441892CE3E190007FF4E5 /* MockSearchEngineManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSearchEngineManager.swift; sourceTree = ""; }; 8A95FF632B1E969E00AC303D /* TelemetryContextualIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryContextualIdentifier.swift; sourceTree = ""; }; 8A95FF652B1E977E00AC303D /* TelemetryContextualIdentifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryContextualIdentifierTests.swift; sourceTree = ""; }; + 8A967E412D30418A00B1017D /* TelemetryDebugMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryDebugMessage.swift; sourceTree = ""; }; 8A96C4B828F9DD8700B75884 /* ThemableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemableTests.swift; sourceTree = ""; }; 8A96C4BA28F9E7B300B75884 /* XCTestCaseRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTestCaseRootViewController.swift; sourceTree = ""; }; 8A97E6E92C58487900F94793 /* AddressLocaleFeatureValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressLocaleFeatureValidator.swift; sourceTree = ""; }; @@ -12098,6 +12100,7 @@ 8ACA8F722919870B00D3075D /* Helpers */ = { isa = PBXGroup; children = ( + 8A967E412D30418A00B1017D /* TelemetryDebugMessage.swift */, 8ACA8F73291987AE00D3075D /* AccountSyncHandlerTests.swift */, 2165B2BF2860BB41004C0786 /* AdjustTelemetryHelperTests.swift */, 8A7A26E629D4C0D800EA76F1 /* IntroScreenManagerTests.swift */, @@ -17394,6 +17397,7 @@ 8A36AC2C2886F27F00CDC0AD /* MockTabManager.swift in Sources */, 5A3A7DD62889CF3D0065F81A /* BookmarksDataAdaptorTests.swift in Sources */, 8AD08D1727E91AC800B8E907 /* TabsTelemetryTests.swift in Sources */, + 8A967E422D30419100B1017D /* TelemetryDebugMessage.swift in Sources */, C8C3FE9D29F907B30038E3BA /* MockSearchHandlerRouteCoordinator.swift in Sources */, ED55DC8C2CC2D7DA00E3FE3A /* SearchEngineSelectionCoordinatorTests.swift in Sources */, C8C3FEA129F973C40038E3BA /* MockBrowserViewController.swift in Sources */, diff --git a/firefox-ios/Client/Telemetry/PrivateBrowsingTelemetry.swift b/firefox-ios/Client/Telemetry/PrivateBrowsingTelemetry.swift index 22c9d6cd1ba9..6473da956034 100644 --- a/firefox-ios/Client/Telemetry/PrivateBrowsingTelemetry.swift +++ b/firefox-ios/Client/Telemetry/PrivateBrowsingTelemetry.swift @@ -6,8 +6,14 @@ import Foundation import Glean struct PrivateBrowsingTelemetry { + private let gleanWrapper: GleanWrapper + + init(gleanWrapper: GleanWrapper = DefaultGleanWrapper()) { + self.gleanWrapper = gleanWrapper + } + func sendDataClearanceTappedTelemetry(didConfirm: Bool) { let didConfirmExtra = GleanMetrics.PrivateBrowsing.DataClearanceIconTappedExtra(didConfirm: didConfirm) - GleanMetrics.PrivateBrowsing.dataClearanceIconTapped.record(didConfirmExtra) + gleanWrapper.recordEvent(for: GleanMetrics.PrivateBrowsing.dataClearanceIconTapped, extras: didConfirmExtra) } } diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Helpers/TelemetryDebugMessage.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Helpers/TelemetryDebugMessage.swift new file mode 100644 index 000000000000..c95b30b23277 --- /dev/null +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Helpers/TelemetryDebugMessage.swift @@ -0,0 +1,13 @@ +// 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/ + +struct TelemetryDebugMessage { + let firstText = "Expected savedMetric to be of type " + let lastText = ", but got " + let text: String + + init(expectedMetric: Metatype, resultMetric: Metatype) { + text = "\(firstText)\(expectedMetric)\(lastText)\(resultMetric)" + } +} diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockGleanWrapper.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockGleanWrapper.swift index 856fc1a8e7d8..d93c09b2246b 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockGleanWrapper.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockGleanWrapper.swift @@ -23,6 +23,7 @@ class MockGleanWrapper: GleanWrapper { var cancelTimingCalled = 0 var stopAndAccumulateCalled = 0 var savedEvent: Any? + var savedExtras: Any? var savedHandleDeeplinkUrl: URL? var savedSetUploadIsEnabled: Bool? @@ -45,6 +46,7 @@ class MockGleanWrapper: GleanWrapper { func recordEvent(for metric: EventMetricType, extras: EventExtras) where ExtraObject: EventExtras { savedEvent = metric + savedExtras = extras recordEventCalled += 1 } diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/PrivateBrowsingTelemetryTests.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/PrivateBrowsingTelemetryTests.swift index 184c5da6bcbf..a3d1757c4579 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/PrivateBrowsingTelemetryTests.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/PrivateBrowsingTelemetryTests.swift @@ -8,34 +8,50 @@ import XCTest @testable import Client final class PrivateBrowsingTelemetryTests: XCTestCase { + var gleanWrapper: MockGleanWrapper! + override func setUp() { super.setUp() - // Due to changes allow certain custom pings to implement their own opt-out - // independent of Glean, custom pings may need to be registered manually in - // tests in order to puth them in a state in which they can collect data. - Glean.shared.registerPings(GleanMetrics.Pings.shared) - Glean.shared.resetGlean(clearStores: true) + gleanWrapper = MockGleanWrapper() } func testDataClearanceConfirmed() throws { - let subject = PrivateBrowsingTelemetry() + let subject = PrivateBrowsingTelemetry(gleanWrapper: gleanWrapper) subject.sendDataClearanceTappedTelemetry(didConfirm: true) - testEventMetricRecordingSuccess(metric: GleanMetrics.PrivateBrowsing.dataClearanceIconTapped) - - let resultValue = try XCTUnwrap(GleanMetrics.PrivateBrowsing.dataClearanceIconTapped.testGetValue()) - XCTAssertEqual(resultValue[0].extra?["did_confirm"], "true") + let savedEvent = try XCTUnwrap( + gleanWrapper.savedEvent as? EventMetricType + ) + let savedExtras = try XCTUnwrap( + gleanWrapper.savedExtras as? GleanMetrics.PrivateBrowsing.DataClearanceIconTappedExtra + ) + let expectedMetricType = type(of: GleanMetrics.PrivateBrowsing.dataClearanceIconTapped) + let resultMetricType = type(of: savedEvent) + let message = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + + XCTAssert(resultMetricType == expectedMetricType, message.text) + XCTAssertEqual(gleanWrapper.recordEventCalled, 1) + XCTAssertEqual(savedExtras.didConfirm, true) } func testDataClearanceCancelled() throws { - let subject = PrivateBrowsingTelemetry() + let subject = PrivateBrowsingTelemetry(gleanWrapper: gleanWrapper) subject.sendDataClearanceTappedTelemetry(didConfirm: false) - testEventMetricRecordingSuccess(metric: GleanMetrics.PrivateBrowsing.dataClearanceIconTapped) - - let resultValue = try XCTUnwrap(GleanMetrics.PrivateBrowsing.dataClearanceIconTapped.testGetValue()) - XCTAssertEqual(resultValue[0].extra?["did_confirm"], "false") + let savedEvent = try XCTUnwrap( + gleanWrapper.savedEvent as? EventMetricType + ) + let savedExtras = try XCTUnwrap( + gleanWrapper.savedExtras as? GleanMetrics.PrivateBrowsing.DataClearanceIconTappedExtra + ) + let expectedMetricType = type(of: GleanMetrics.PrivateBrowsing.dataClearanceIconTapped) + let resultMetricType = type(of: savedEvent) + let message = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + + XCTAssert(resultMetricType == expectedMetricType, message.text) + XCTAssertEqual(gleanWrapper.recordEventCalled, 1) + XCTAssertEqual(savedExtras.didConfirm, false) } } diff --git a/firefox-ios/firefox-ios-tests/Tests/ClientTests/TabTray/InactiveTabsTelemetryTests.swift b/firefox-ios/firefox-ios-tests/Tests/ClientTests/TabTray/InactiveTabsTelemetryTests.swift index e1514afc7833..1eac50e0e790 100644 --- a/firefox-ios/firefox-ios-tests/Tests/ClientTests/TabTray/InactiveTabsTelemetryTests.swift +++ b/firefox-ios/firefox-ios-tests/Tests/ClientTests/TabTray/InactiveTabsTelemetryTests.swift @@ -29,7 +29,7 @@ final class InactiveTabsTelemetryTests: XCTestCase { let savedMetric = try XCTUnwrap(gleanWrapper.savedEvent as? CounterMetricType) let expectedMetricType = type(of: GleanMetrics.InactiveTabsTray.inactiveTabShown) let resultMetricType = type(of: savedMetric) - let debugMessage = DebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + let debugMessage = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) XCTAssert(resultMetricType == expectedMetricType, debugMessage.text) XCTAssertEqual(gleanWrapper.incrementCounterCalled, 1) } @@ -40,7 +40,7 @@ final class InactiveTabsTelemetryTests: XCTestCase { let savedMetric = try XCTUnwrap(gleanWrapper.savedEvent as? CounterMetricType) let expectedMetricType = type(of: GleanMetrics.InactiveTabsTray.inactiveTabsCloseAllBtn) let resultMetricType = type(of: savedMetric) - let debugMessage = DebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + let debugMessage = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) XCTAssert(resultMetricType == expectedMetricType, debugMessage.text) XCTAssertEqual(gleanWrapper.incrementCounterCalled, 1) } @@ -51,7 +51,7 @@ final class InactiveTabsTelemetryTests: XCTestCase { let savedMetric = try XCTUnwrap(gleanWrapper.savedEvent as? CounterMetricType) let expectedMetricType = type(of: GleanMetrics.InactiveTabsTray.openInactiveTab) let resultMetricType = type(of: savedMetric) - let debugMessage = DebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + let debugMessage = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) XCTAssert(resultMetricType == expectedMetricType, debugMessage.text) XCTAssertEqual(gleanWrapper.incrementCounterCalled, 1) } @@ -62,7 +62,7 @@ final class InactiveTabsTelemetryTests: XCTestCase { let savedMetric = try XCTUnwrap(gleanWrapper.savedEvent as? CounterMetricType) let expectedMetricType = type(of: GleanMetrics.InactiveTabsTray.inactiveTabSwipeClose) let resultMetricType = type(of: savedMetric) - let debugMessage = DebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + let debugMessage = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) XCTAssert(resultMetricType == expectedMetricType, debugMessage.text) XCTAssertEqual(gleanWrapper.incrementCounterCalled, 1) } @@ -75,20 +75,8 @@ final class InactiveTabsTelemetryTests: XCTestCase { ) let expectedMetricType = type(of: GleanMetrics.InactiveTabsTray.toggleInactiveTabTray) let resultMetricType = type(of: savedMetric) - let debugMessage = DebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) + let debugMessage = TelemetryDebugMessage(expectedMetric: expectedMetricType, resultMetric: resultMetricType) XCTAssert(resultMetricType == expectedMetricType, debugMessage.text) XCTAssertEqual(gleanWrapper.recordEventCalled, 1) } - - // MARK: Helpers - - private struct DebugMessage { - let firstText = "Expected savedMetric to be of type " - let lastText = ", but got " - let text: String - - init(expectedMetric: Metatype, resultMetric: Metatype) { - text = "\(firstText)\(expectedMetric)\(lastText)\(resultMetric)" - } - } }