Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: in app click tracking #284

Merged
merged 9 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions Sources/Common/Background Queue/Queue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public protocol Queue: AutoMockable {
See list of refactors: https://github.com/customerio/issues/issues/6934
*/

func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric) -> ModifyQueueResult
func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric, metaData: [String: String]) -> ModifyQueueResult

/**
Add a task to the queue to be performed sometime in the future.
Expand All @@ -57,6 +57,10 @@ public protocol Queue: AutoMockable {
}

public extension Queue {
func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric, metaData: [String: String] = [:]) -> ModifyQueueResult {
addTrackInAppDeliveryTask(deliveryId: deliveryId, event: event, metaData: metaData)
}

func addTask<TaskData: Codable>(
type: String,
// sourcery:Type=AnyEncodable
Expand Down Expand Up @@ -122,15 +126,16 @@ public class CioQueue: Queue {
self.dateUtil = dateUtil
}

public func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric) -> ModifyQueueResult {
public func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric, metaData: [String: String]) -> ModifyQueueResult {
addTask(
type: QueueTaskType.trackDeliveryMetric.rawValue,
data: TrackDeliveryEventRequestBody(
type: .inApp,
payload: DeliveryPayload(
deliveryId: deliveryId,
event: event,
timestamp: dateUtil.now
timestamp: dateUtil.now,
metaData: metaData
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ internal struct DeliveryPayload: Codable {
internal let deliveryId: String
internal let event: InAppMetric
internal let timestamp: Date
internal let metaData: [String: String]

enum CodingKeys: String, CodingKey {
case deliveryId = "delivery_id"
case event
case timestamp
case metaData = "metadata"
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
2 changes: 1 addition & 1 deletion Sources/Common/autogenerated/AutoLenses.generated.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
54 changes: 9 additions & 45 deletions Sources/Common/autogenerated/AutoMockable.generated.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down Expand Up @@ -1672,25 +1672,25 @@ public class QueueMock: Queue, Mock {
}

/// The arguments from the *last* time the function was called.
public private(set) var addTrackInAppDeliveryTaskReceivedArguments: (deliveryId: String, event: InAppMetric)?
public private(set) var addTrackInAppDeliveryTaskReceivedArguments: (deliveryId: String, event: InAppMetric, metaData: [String: String])?
/// Arguments from *all* of the times that the function was called.
public private(set) var addTrackInAppDeliveryTaskReceivedInvocations: [(deliveryId: String, event: InAppMetric)] = []
public private(set) var addTrackInAppDeliveryTaskReceivedInvocations: [(deliveryId: String, event: InAppMetric, metaData: [String: String])] = []
/// Value to return from the mocked function.
public var addTrackInAppDeliveryTaskReturnValue: ModifyQueueResult!
/**
Set closure to get called when function gets called. Great way to test logic or return a value for the function.
The closure has first priority to return a value for the mocked function. If the closure returns `nil`,
then the mock will attempt to return the value for `addTrackInAppDeliveryTaskReturnValue`
*/
public var addTrackInAppDeliveryTaskClosure: ((String, InAppMetric) -> ModifyQueueResult)?
public var addTrackInAppDeliveryTaskClosure: ((String, InAppMetric, [String: String]) -> ModifyQueueResult)?

/// Mocked function for `addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric)`. Your opportunity to return a mocked value and check result of mock in test code.
public func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric) -> ModifyQueueResult {
/// Mocked function for `addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric, metaData: [String: String])`. Your opportunity to return a mocked value and check result of mock in test code.
public func addTrackInAppDeliveryTask(deliveryId: String, event: InAppMetric, metaData: [String: String]) -> ModifyQueueResult {
mockCalled = true
addTrackInAppDeliveryTaskCallsCount += 1
addTrackInAppDeliveryTaskReceivedArguments = (deliveryId: deliveryId, event: event)
addTrackInAppDeliveryTaskReceivedInvocations.append((deliveryId: deliveryId, event: event))
return addTrackInAppDeliveryTaskClosure.map { $0(deliveryId, event) } ?? addTrackInAppDeliveryTaskReturnValue
addTrackInAppDeliveryTaskReceivedArguments = (deliveryId: deliveryId, event: event, metaData: metaData)
addTrackInAppDeliveryTaskReceivedInvocations.append((deliveryId: deliveryId, event: event, metaData: metaData))
return addTrackInAppDeliveryTaskClosure.map { $0(deliveryId, event, metaData) } ?? addTrackInAppDeliveryTaskReturnValue
}

// MARK: - addTask<TaskData: Codable>
Expand Down Expand Up @@ -2131,11 +2131,6 @@ public class QueueStorageMock: QueueStorage, Mock {
deleteReceivedArguments = nil
deleteReceivedInvocations = []

mockCalled = false // do last as resetting properties above can make this true
deleteTasksMemberOfGroupCallsCount = 0
deleteTasksMemberOfGroupReceivedArguments = nil
deleteTasksMemberOfGroupReceivedInvocations = []

mockCalled = false // do last as resetting properties above can make this true
deleteExpiredCallsCount = 0

Expand Down Expand Up @@ -2322,37 +2317,6 @@ public class QueueStorageMock: QueueStorage, Mock {
return deleteClosure.map { $0(storageId) } ?? deleteReturnValue
}

// MARK: - deleteTasksMemberOfGroup

/// Number of times the function was called.
public private(set) var deleteTasksMemberOfGroupCallsCount = 0
/// `true` if the function was ever called.
public var deleteTasksMemberOfGroupCalled: Bool {
deleteTasksMemberOfGroupCallsCount > 0
}

/// The arguments from the *last* time the function was called.
public private(set) var deleteTasksMemberOfGroupReceivedArguments: String?
/// Arguments from *all* of the times that the function was called.
public private(set) var deleteTasksMemberOfGroupReceivedInvocations: [String] = []
/// Value to return from the mocked function.
public var deleteTasksMemberOfGroupReturnValue: [QueueTaskMetadata]!
/**
Set closure to get called when function gets called. Great way to test logic or return a value for the function.
The closure has first priority to return a value for the mocked function. If the closure returns `nil`,
then the mock will attempt to return the value for `deleteTasksMemberOfGroupReturnValue`
*/
public var deleteTasksMemberOfGroupClosure: ((String) -> [QueueTaskMetadata])?

/// Mocked function for `deleteTasksMemberOfGroup(groupId: String)`. Your opportunity to return a mocked value and check result of mock in test code.
public func deleteTasksMemberOfGroup(groupId: String) -> [QueueTaskMetadata] {
mockCalled = true
deleteTasksMemberOfGroupCallsCount += 1
deleteTasksMemberOfGroupReceivedArguments = groupId
deleteTasksMemberOfGroupReceivedInvocations.append(groupId)
return deleteTasksMemberOfGroupClosure.map { $0(groupId) } ?? deleteTasksMemberOfGroupReturnValue
}

// MARK: - deleteExpired

/// Number of times the function was called.
Expand Down
2 changes: 1 addition & 1 deletion Sources/MessagingInApp/MessagingInAppImplementation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ extension MessagingInAppImplementation: GistDelegate {
if action != "gist://close" {
if let deliveryId = getDeliveryId(from: message) {
// the state of the SDK does not change if adding this queue task isn't successful so ignore result
_ = queue.addTrackInAppDeliveryTask(deliveryId: deliveryId, event: .clicked)
_ = queue.addTrackInAppDeliveryTask(deliveryId: deliveryId, event: .clicked, metaData: ["action_name": name, "action_value": action])
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
2 changes: 1 addition & 1 deletion Sources/Tracking/autogenerated/AutoLenses.generated.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.0.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all

Expand Down
46 changes: 46 additions & 0 deletions Tests/MessagingInApp/MessagingInAppImplementationTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ class MessagingInAppImplementationTest: UnitTest {
private let inAppProviderMock = InAppProviderMock()
private let eventListenerMock = InAppEventListenerMock()
private let profileStoreMock = ProfileStoreMock()
private let backgroundQueueMock = QueueMock()

override func setUp() {
super.setUp()

diGraph.override(value: inAppProviderMock, forType: InAppProvider.self)
diGraph.override(value: profileStoreMock, forType: ProfileStore.self)
diGraph.override(value: backgroundQueueMock, forType: Queue.self)

messagingInApp = MessagingInAppImplementation(diGraph: diGraph)
messagingInApp.initialize(eventListener: eventListenerMock)
Expand Down Expand Up @@ -101,6 +103,11 @@ class MessagingInAppImplementationTest: UnitTest {
let givenGistMessage = Message.random
let expectedInAppMessage = InAppMessage(gistMessage: givenGistMessage)

backgroundQueueMock.addTrackInAppDeliveryTaskReturnValue = (
success: true,
queueStatus: QueueStatus.successAddingSingleTask
)

// Message opened
XCTAssertFalse(eventListenerMock.messageShownCalled)
messagingInApp.messageShown(message: givenGistMessage)
Expand Down Expand Up @@ -139,6 +146,11 @@ class MessagingInAppImplementationTest: UnitTest {
func test_eventListeners_expectCallListenerForEachEvent() {
let givenGistMessage = Message.random

backgroundQueueMock.addTrackInAppDeliveryTaskReturnValue = (
success: true,
queueStatus: QueueStatus.successAddingSingleTask
)

// Message opened
XCTAssertEqual(eventListenerMock.messageShownCallsCount, 0)
messagingInApp.messageShown(message: givenGistMessage)
Expand Down Expand Up @@ -175,6 +187,11 @@ class MessagingInAppImplementationTest: UnitTest {
let givenAction = "gist://close"
let givenName = String.random

backgroundQueueMock.addTrackInAppDeliveryTaskReturnValue = (
success: true,
queueStatus: QueueStatus.successAddingSingleTask
)

XCTAssertEqual(eventListenerMock.messageActionTakenCallsCount, 0)

messagingInApp.action(
Expand All @@ -183,9 +200,38 @@ class MessagingInAppImplementationTest: UnitTest {
action: givenAction,
name: givenName
)

XCTAssertEqual(eventListenerMock.messageActionTakenCallsCount, 1)
XCTAssertEqual(eventListenerMock.messageActionTakenReceivedArguments?.message, expectedInAppMessage)
XCTAssertEqual(eventListenerMock.messageActionTakenReceivedArguments?.actionValue, givenAction)
XCTAssertEqual(eventListenerMock.messageActionTakenReceivedArguments?.actionName, givenName)

// make sure there is no click tracking for "close" action
XCTAssertEqual(backgroundQueueMock.addTrackInAppDeliveryTaskCallsCount, 0)
}

func test_inAppTracking_givenCustomAction_expectBQTrackInAppClicked() {
levibostian marked this conversation as resolved.
Show resolved Hide resolved
let givenGistMessage = Message.random
let expectedInAppMessage = InAppMessage(gistMessage: givenGistMessage)
let givenCurrentRoute = String.random
let givenAction = String.random
let givenName = String.random
let givenMetaData = ["action_name": givenName, "action_value": givenAction]

backgroundQueueMock.addTrackInAppDeliveryTaskReturnValue = (
success: true,
queueStatus: QueueStatus.successAddingSingleTask
)

messagingInApp.action(
message: givenGistMessage,
currentRoute: givenCurrentRoute,
action: givenAction,
name: givenName
)

XCTAssertEqual(backgroundQueueMock.addTrackInAppDeliveryTaskReceivedArguments?.deliveryId, expectedInAppMessage.deliveryId)
XCTAssertEqual(backgroundQueueMock.addTrackInAppDeliveryTaskReceivedArguments?.event, .clicked)
XCTAssertEqual(backgroundQueueMock.addTrackInAppDeliveryTaskReceivedArguments?.metaData, givenMetaData)
}
}