Skip to content

[MOB-8113] adds placement ids array to sync messages #898

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

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions swift-sdk/Core/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ enum JsonKey {
// embedded
static let embeddedSessionId = "session"
static let placementId = "placementId"
static let placementIds = "placementIds"
static let embeddedSessionStart = "embeddedSessionStart"
static let embeddedSessionEnd = "embeddedSessionEnd"
static let embeddedButtonId = "buttonIdentifier"
Expand Down Expand Up @@ -231,6 +232,12 @@ enum JsonKey {
enum Embedded {
static let packageName = "packageName"
static let sdkVersion = "SDKVersion"

enum Session {
static let id = "id"
static let start = "start"
static let end = "end"
}
}

enum Header {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public protocol IterableEmbeddedManagerProtocol {
func removeUpdateListener(_ listener: IterableEmbeddedUpdateDelegate)

func syncMessages(completion: @escaping () -> Void)
func syncMessages(placementIds: [Int]?, completion: @escaping () -> Void)
func handleEmbeddedClick(message: IterableEmbeddedMessage, buttonIdentifier: String?, clickedUrl: String)
func reset()
}
4 changes: 4 additions & 0 deletions swift-sdk/Internal/EmptyEmbeddedManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

}

func syncMessages(placementIds: [Int]?, completion: @escaping () -> Void) {

Check warning on line 28 in swift-sdk/Internal/EmptyEmbeddedManager.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/EmptyEmbeddedManager.swift#L28

Added line #L28 was not covered by tests

}

public func handleEmbeddedClick(message: IterableEmbeddedMessage, buttonIdentifier: String?, clickedUrl: String) {

}
Expand Down
11 changes: 8 additions & 3 deletions swift-sdk/Internal/IterableEmbeddedManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ class IterableEmbeddedManager: NSObject, IterableInternalEmbeddedManagerProtocol
syncMessages { }
}

private func retrieveEmbeddedMessages(completion: @escaping () -> Void) {
apiClient.getEmbeddedMessages()
private func retrieveEmbeddedMessages(placementIds: [Int]?, completion: @escaping () -> Void) {
apiClient.getEmbeddedMessages(placementIds: placementIds)
.onCompletion(
receiveValue: { embeddedMessagesPayload in
let placements = embeddedMessagesPayload.placements
Expand Down Expand Up @@ -245,8 +245,13 @@ class IterableEmbeddedManager: NSObject, IterableInternalEmbeddedManagerProtocol

extension IterableEmbeddedManager: EmbeddedNotifiable {
public func syncMessages(completion: @escaping () -> Void) {
syncMessages(placementIds: nil, completion: completion)

}

public func syncMessages(placementIds: [Int]?, completion: @escaping () -> Void) {
if (enableEmbeddedMessaging) {
retrieveEmbeddedMessages(completion: completion)
retrieveEmbeddedMessages(placementIds: placementIds, completion: completion)
}
}
}
6 changes: 5 additions & 1 deletion swift-sdk/Internal/api-client/ApiClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@
// MARK: - Embedded Messaging

func getEmbeddedMessages() -> Pending<PlacementsPayload, SendRequestError> {
let result = createRequestCreator().flatMap { $0.createGetEmbeddedMessagesRequest() }
return getEmbeddedMessages(placementIds: nil)

Check warning on line 223 in swift-sdk/Internal/api-client/ApiClient.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/api-client/ApiClient.swift#L223

Added line #L223 was not covered by tests
}

func getEmbeddedMessages(placementIds: [Int]?) -> Pending<PlacementsPayload, SendRequestError> {
let result = createRequestCreator().flatMap { $0.createGetEmbeddedMessagesRequest(placementIds: placementIds) }

Check warning on line 227 in swift-sdk/Internal/api-client/ApiClient.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/api-client/ApiClient.swift#L226-L227

Added lines #L226 - L227 were not covered by tests
return send(iterableRequestResult: result)
}

Expand Down
2 changes: 2 additions & 0 deletions swift-sdk/Internal/api-client/ApiClientProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ protocol ApiClientProtocol: AnyObject {

func getEmbeddedMessages() -> Pending<PlacementsPayload, SendRequestError>

func getEmbeddedMessages(placementIds: [Int]?) -> Pending<PlacementsPayload, SendRequestError>

@discardableResult func track(embeddedMessageReceived message: IterableEmbeddedMessage) -> Pending<SendRequestValue, SendRequestError>

@discardableResult func track(embeddedMessageClick message: IterableEmbeddedMessage, buttonIdentifier: String?, clickedUrl: String) -> Pending<SendRequestValue, SendRequestError>
Expand Down
13 changes: 9 additions & 4 deletions swift-sdk/Internal/api-client/Request/RequestCreator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@

// MARK: - Embedded Messaging Request Calls

func createGetEmbeddedMessagesRequest() -> Result<IterableRequest, IterableError> {
func createGetEmbeddedMessagesRequest(placementIds: [Int]? = []) -> Result<IterableRequest, IterableError> {

Check warning on line 426 in swift-sdk/Internal/api-client/Request/RequestCreator.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/api-client/Request/RequestCreator.swift#L426

Added line #L426 was not covered by tests
if case .none = auth.emailOrUserId {
ITBError(Self.authMissingMessage)
return .failure(IterableError.general(description: Self.authMissingMessage))
Expand All @@ -437,6 +437,11 @@
args[JsonKey.Embedded.packageName] = packageName
}

if let placementIds = placementIds,
!placementIds.isEmpty {
args[JsonKey.placementIds] = placementIds

Check warning on line 442 in swift-sdk/Internal/api-client/Request/RequestCreator.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/api-client/Request/RequestCreator.swift#L440-L442

Added lines #L440 - L442 were not covered by tests
}

setCurrentUser(inDict: &args)

return .success(.get(createGetRequest(forPath: Const.Path.getEmbeddedMessages, withArgs: args as! [String: String])))
Expand Down Expand Up @@ -542,9 +547,9 @@
setCurrentUser(inDict: &body)

body.setValue(for: JsonKey.embeddedSessionId, value: [
"id": embeddedSessionId,
"start": IterableUtil.int(fromDate: sessionStartTime),
"end": IterableUtil.int(fromDate: sessionEndTime)
JsonKey.Embedded.Session.id: embeddedSessionId,
JsonKey.Embedded.Session.start: IterableUtil.int(fromDate: sessionStartTime),
JsonKey.Embedded.Session.end: IterableUtil.int(fromDate: sessionEndTime)

Check warning on line 552 in swift-sdk/Internal/api-client/Request/RequestCreator.swift

View check run for this annotation

Codecov / codecov/patch

swift-sdk/Internal/api-client/Request/RequestCreator.swift#L550-L552

Added lines #L550 - L552 were not covered by tests
])

body.setValue(for: JsonKey.impressions, value: embeddedSession.impressions.compactMap { $0.asDictionary() })
Expand Down
4 changes: 4 additions & 0 deletions tests/unit-tests/BlankApiClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class BlankApiClient: ApiClientProtocol {
Pending()
}

func getEmbeddedMessages(placementIds: [Int]?) -> Pending<PlacementsPayload, SendRequestError> {
return Pending()
}

func track(embeddedMessageReceived message: IterableEmbeddedMessage) -> Pending<SendRequestValue, SendRequestError> {
Pending()
}
Expand Down
52 changes: 49 additions & 3 deletions tests/unit-tests/EmbeddedManagerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ final class EmbeddedManagerTests: XCTestCase {
XCTAssertEqual(message.metadata.placementId, 2, "Fetched message should have placementId 2")
}
}

// syncMessages
func testSyncMessagesSuccessful() {
let syncMessagesExpectation = expectation(description: "syncMessages should complete")
Expand Down Expand Up @@ -105,6 +105,40 @@ final class EmbeddedManagerTests: XCTestCase {
wait(for: [syncMessagesExpectation, delegateExpectation], timeout: 2)
}

func testSyncMessagesForSpecifiedPlacement() {
let mockApiClient = MockApiClient()
mockApiClient.populateMessages([
1: [IterableEmbeddedMessage(messageId: "1", placementId: 1)],
2: [IterableEmbeddedMessage(messageId: "2", placementId: 2),
IterableEmbeddedMessage(messageId: "3", placementId: 2)],
3: [IterableEmbeddedMessage(messageId: "4", placementId: 3)],
])
let manager = IterableEmbeddedManager(apiClient: mockApiClient,
urlDelegate: nil,
customActionDelegate: nil,
urlOpener: MockUrlOpener(),
allowedProtocols: [],
enableEmbeddedMessaging: true)

// Sync only placement 2
manager.syncMessages(placementIds: [2]) { }

// Verify we got updated messages for placement 2
let messagesForPlacement2 = manager.getMessages(for: 2)
XCTAssertEqual(messagesForPlacement2.count, 2, "Should have 2 messages for placementId 2")
for message in messagesForPlacement2 {
XCTAssertEqual(message.metadata.placementId, 2, "Fetched message should have placementId 2")
}

// Verify other placements are not synced
let messagesForPlacement1 = manager.getMessages(for: 1)
XCTAssertEqual(messagesForPlacement1.count, 0, "Should have no messages for placementId 1")

let messagesForPlacement3 = manager.getMessages(for: 3)
XCTAssertEqual(messagesForPlacement3.count, 0, "Should have no messages for placementId 3")
}


func testManagerReset() {
let syncMessagesExpectation = expectation(description: "syncMessages should complete")

Expand Down Expand Up @@ -352,7 +386,8 @@ final class EmbeddedManagerTests: XCTestCase {
private var newMessages = false
private var invalidApiKey = false
private var mockMessages: [Int: [IterableEmbeddedMessage]] = [:]

private var lastRequestedPlacementIds: [Int]?

func haveNewEmbeddedMessages() {
newMessages = true
}
Expand All @@ -367,13 +402,24 @@ final class EmbeddedManagerTests: XCTestCase {
}

override func getEmbeddedMessages() -> IterableSDK.Pending<IterableSDK.PlacementsPayload, IterableSDK.SendRequestError> {
return getEmbeddedMessages(placementIds: nil)
}

override func getEmbeddedMessages(placementIds: [Int]?) -> IterableSDK.Pending<IterableSDK.PlacementsPayload, IterableSDK.SendRequestError> {
lastRequestedPlacementIds = placementIds

if invalidApiKey {
return FailPending(error: IterableSDK.SendRequestError(reason: "Invalid API Key"))
}

if newMessages {
var filteredMessages = mockMessages
if let placementIds = placementIds, !placementIds.isEmpty {
filteredMessages = mockMessages.filter { placementIds.contains($0.key) }
}

var placements: [Placement] = []
for (placementId, messages) in mockMessages {
for (placementId, messages) in filteredMessages {
let placement = Placement(placementId: placementId, embeddedMessages: messages)
placements.append(placement)
}
Expand Down