Skip to content

Commit

Permalink
Merge pull request #182 from sbenedicadb/main
Browse files Browse the repository at this point in the history
Get previously reverted commits into main
  • Loading branch information
sbenedicadb committed Apr 28, 2023
2 parents 4b5101e + 0055f89 commit e18c48a
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 165 deletions.
8 changes: 8 additions & 0 deletions AEPMessaging.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

/* Begin PBXBuildFile section */
01B9DD6617C6AD6E99EE8472 /* Pods_E2EFunctionalTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB180620A608D2821FE98F37 /* Pods_E2EFunctionalTests.framework */; };
2402745C29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2402745B29FC424000884DFE /* TestableMessagingDelegate.swift */; };
2402745D29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2402745B29FC424000884DFE /* TestableMessagingDelegate.swift */; };
2402745E29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2402745B29FC424000884DFE /* TestableMessagingDelegate.swift */; };
240F71FB26868F7100846587 /* SharedStateResult+Messaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240F71FA26868F7100846587 /* SharedStateResult+Messaging.swift */; };
2414ED832899BA080036D505 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2414ED822899BA080036D505 /* AppDelegate.m */; };
2414ED862899BA080036D505 /* SceneDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2414ED852899BA080036D505 /* SceneDelegate.m */; };
Expand Down Expand Up @@ -288,6 +291,7 @@

/* Begin PBXFileReference section */
093DC9CB668BBA547B0C9306 /* Pods-UnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UnitTests.release.xcconfig"; path = "Target Support Files/Pods-UnitTests/Pods-UnitTests.release.xcconfig"; sourceTree = "<group>"; };
2402745B29FC424000884DFE /* TestableMessagingDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableMessagingDelegate.swift; sourceTree = "<group>"; };
240F71FA26868F7100846587 /* SharedStateResult+Messaging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SharedStateResult+Messaging.swift"; sourceTree = "<group>"; };
2414ED7F2899BA080036D505 /* MessagingDemoAppObjC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MessagingDemoAppObjC.app; sourceTree = BUILT_PRODUCTS_DIR; };
2414ED812899BA080036D505 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -719,6 +723,7 @@
9231543E261E3B36004AE7D3 /* MockNetworkService.swift */,
92FC594426372E34005BAE02 /* MockNotificationResponseCoder.swift */,
9231543D261E3B36004AE7D3 /* TestableExtensionRuntime.swift */,
2402745B29FC424000884DFE /* TestableMessagingDelegate.swift */,
243EA6DF2739D9D700195945 /* TestableMessagingMobileParameters.swift */,
928639D026374463000AFA53 /* TestableNetworkService.swift */,
);
Expand Down Expand Up @@ -1489,6 +1494,7 @@
246EFA202797441600C76A6B /* MockLaunchRulesEngine.swift in Sources */,
246EFA212797441600C76A6B /* MockMessage.swift in Sources */,
246EFA222797441600C76A6B /* MockMessaging.swift in Sources */,
2402745C29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */,
246EFA232797441600C76A6B /* MockMessagingRulesEngine.swift in Sources */,
246EFA242797441600C76A6B /* MockNetworkService.swift in Sources */,
246EFA252797441600C76A6B /* MockNotificationResponseCoder.swift in Sources */,
Expand Down Expand Up @@ -1566,6 +1572,7 @@
2450596F2673DBFE00CC7CA0 /* Event+MessagingTests.swift in Sources */,
243EA6DA2739D47500195945 /* MockMessaging.swift in Sources */,
243EA6D42733261E00195945 /* MessagingEdgeEventTypeTests.swift in Sources */,
2402745E29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */,
243EA6CF273325CC00195945 /* Message+FullscreenMessageDelegateTests.swift in Sources */,
245059712673DBFE00CC7CA0 /* MessagingTests.swift in Sources */,
2469A5EB274D49B100E56457 /* JSONFileLoader.swift in Sources */,
Expand Down Expand Up @@ -1594,6 +1601,7 @@
92FC58D326368900005BAE02 /* MockNetworkService.swift in Sources */,
92FC58CE263688FD005BAE02 /* TestableExtensionRuntime.swift in Sources */,
928639FC263757A7000AFA53 /* Dictionary+Flatten.swift in Sources */,
2402745D29FC424000884DFE /* TestableMessagingDelegate.swift in Sources */,
24EE301E28FF61F0005E417C /* InAppMessagingEventTests.swift in Sources */,
92FC58C8263688F0005BAE02 /* EventHub+Testable.swift in Sources */,
928639D126374463000AFA53 /* TestableNetworkService.swift in Sources */,
Expand Down
11 changes: 10 additions & 1 deletion AEPMessaging/Sources/Message+FullscreenMessageDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ import Foundation
import UIKit

extension Message: FullscreenMessageDelegate {
public func onShow(message _: FullscreenMessage) {}
public func onShow(message: FullscreenMessage) {
guard let message = message.parent else {
return
}

if message.autoTrack {
message.track(nil, withEdgeEventType: .inappDisplay)
}
}

public func onShowFailure() {}

/// Informs the parent of the calling `message` that it has been dismissed.
Expand Down
74 changes: 37 additions & 37 deletions AEPMessaging/Sources/Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,48 +73,14 @@ public class Message: NSObject {

// MARK: - UI management

/// Signals to the UIServices that the message should be shown.
/// Requests that UIServices show the this message.
/// This method will bypass calling the `shouldShowMessage(:)` method of the `MessagingDelegate` if one exists.
/// If `autoTrack` is true, calling this method will result in an "inapp.display" Edge Event being dispatched.
/// If `autoTrack` is true and the message is shown, calling this method will result
/// in an "inapp.display" Edge Event being dispatched.
@objc
public func show() {
show(withMessagingDelegateControl: false)
}

/// Signals to the UIServices that the message should be shown.
/// Pass `false` to this method to bypass the `MessagingDelegate` control over showing the message.
/// - Parameter withMessagingDelegateControl: if `true`, the `shouldShowMessage(:)` method of `MessagingDelegate` will be called before the message is shown.
func show(withMessagingDelegateControl callDelegate: Bool) {
if autoTrack {
track(nil, withEdgeEventType: .inappDisplay)
}

fullscreenMessage?.show(withMessagingDelegateControl: callDelegate)
}

/// Generates a mapping of the message's assets to their representation in local cache.
///
/// This method will iterate through the `remoteAssets` of the triggering event for the message.
/// In each iteration, it will check to see if there is a corresponding cache entry for the
/// asset string. If a match is found, an entry will be made in the `Message`s `assets` dictionary.
///
/// - Returns: `true` if an asset map was generated
private func generateAssetMap() -> Bool {
guard let remoteAssetsArray = triggeringEvent.remoteAssets, !remoteAssetsArray.isEmpty else {
return false
}

let cache = Cache(name: MessagingConstants.Caches.CACHE_NAME)
assets = [:]
for asset in remoteAssetsArray {
// check for a matching file in cache and add an entry to the assets map if it exists
if let cachedAsset = cache.get(key: asset) {
assets?[asset] = cachedAsset.metadata?[MessagingConstants.Caches.PATH]
}
}

return true
}

/// Signals to the UIServices that the message should be dismissed.
/// If `autoTrack` is true, calling this method will result in an "inapp.dismiss" Edge Event being dispatched.
Expand Down Expand Up @@ -157,10 +123,44 @@ public class Message: NSObject {

// MARK: - Internal methods

/// Requests that UIServices show the this message.
/// Pass `false` to this method to bypass the `MessagingDelegate` control over showing the message.
/// - Parameters:
/// - withMessagingDelegateControl: if `true`, the `shouldShowMessage(:)` method of `MessagingDelegate` will be called before the message is shown.
func show(withMessagingDelegateControl callDelegate: Bool) {
fullscreenMessage?.show(withMessagingDelegateControl: callDelegate)
}

/// Called when a `Message` is triggered - i.e. it's conditional criteria have been met.
func trigger() {
if autoTrack {
track(nil, withEdgeEventType: .inappTrigger)
}
}

// MARK: - Private methods

/// Generates a mapping of the message's assets to their representation in local cache.
///
/// This method will iterate through the `remoteAssets` of the triggering event for the message.
/// In each iteration, it will check to see if there is a corresponding cache entry for the
/// asset string. If a match is found, an entry will be made in the `Message`s `assets` dictionary.
///
/// - Returns: `true` if an asset map was generated
private func generateAssetMap() -> Bool {
guard let remoteAssetsArray = triggeringEvent.remoteAssets, !remoteAssetsArray.isEmpty else {
return false
}

let cache = Cache(name: MessagingConstants.Caches.CACHE_NAME)
assets = [:]
for asset in remoteAssetsArray {
// check for a matching file in cache and add an entry to the assets map if it exists
if let cachedAsset = cache.get(key: asset) {
assets?[asset] = cachedAsset.metadata?[MessagingConstants.Caches.PATH]
}
}

return true
}
}
2 changes: 0 additions & 2 deletions AEPMessaging/Sources/Messaging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public class Messaging: NSObject, Extension {
private var messagesRequestEventId: String?
private var lastProcessedRequestEventId: String?
private var initialLoadComplete = false
private(set) var currentMessage: Message?
private let rulesEngine: MessagingRulesEngine

// MARK: - Extension protocol methods
Expand Down Expand Up @@ -211,7 +210,6 @@ public class Messaging: NSObject, Extension {

message.trigger()
message.show(withMessagingDelegateControl: true)
currentMessage = message
}

// MARK: - Event Handers
Expand Down
178 changes: 89 additions & 89 deletions AEPMessaging/Tests/FunctionalTests/InAppMessagingEventTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,95 +101,95 @@ class InAppMessagingEventTests: XCTestCase {
wait(for: [messagingRequestContentExpectation], timeout: asyncTimeout)
}

func testMessagesReturnedFromXASHaveCorrectJsonFormat() throws {
// setup
let edgePersonalizationDecisionsExpectation = XCTestExpectation(description: "edge personalization decisions listener called")
registerEdgePersonalizationDecisionsListener() { event in
XCTAssertNotNil(event)

// validate the payload exists
guard let payload = event.data?["payload"] as? [[String: Any]] else {
// no payload means this event is a request, not a response
return
}

// validate the payload is not empty
guard !payload.isEmpty else {
XCTFail("SDK TEST ERROR - expected a payload object, but payload is empty")
return
}

// loop through the payload and verify the format for each object
for payloadObject in payload {
XCTAssertTrue(self.payloadObjectIsValid(payloadObject), "SDK TEST ERROR - payload object returned was invalid: \(payloadObject)")
}

edgePersonalizationDecisionsExpectation.fulfill()
}

// test
Messaging.refreshInAppMessages()

// verify
wait(for: [edgePersonalizationDecisionsExpectation], timeout: asyncTimeout)
}

func testMessagesReturnedFromXASHaveCorrectRuleFormat() throws {
// setup
let edgePersonalizationDecisionsExpectation = XCTestExpectation(description: "edge personalization decisions listener called")
registerEdgePersonalizationDecisionsListener() { event in

// validate the content is a valid rule containing a valid message
guard let propositions = event.payload else {
// no payload means this event is a request, not a response
return
}

let messagingRulesEngine = MessagingRulesEngine(name: "testRulesEngine", extensionRuntime: TestableExtensionRuntime())
messagingRulesEngine.loadPropositions(propositions, clearExisting: true, expectedScope: self.expectedScope)

// rules load async - brief sleep to allow it to finish
self.runAfter(seconds: 3) {
XCTAssertEqual(3, messagingRulesEngine.rulesEngine.rulesEngine.rules.count, "Message definition successfully loaded into the rules engine.")
edgePersonalizationDecisionsExpectation.fulfill()
}
}

// test
Messaging.refreshInAppMessages()

// verify
wait(for: [edgePersonalizationDecisionsExpectation], timeout: asyncTimeout)
}

func testMessagesDisplayInteractDismissEvents() throws {
// setup
let edgeRequestDisplayEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == display received.")
let edgeRequestInteractEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == interact received.")
let edgeRequestDismissEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == dismiss received.")
registerEdgeRequestContentListener() { event in
if event.isPropositionEvent(withType: "display") {
self.currentMessage?.track("clicked", withEdgeEventType: .inappInteract)
edgeRequestDisplayEventExpectation.fulfill()
}
if event.isPropositionEvent(withType: "interact") {
self.currentMessage?.dismiss()
edgeRequestInteractEventExpectation.fulfill()
}
if event.isPropositionEvent(withType: "dismiss") {
edgeRequestDismissEventExpectation.fulfill()
}
}
MobileCore.messagingDelegate = self

// allow rules engine to be hydrated
runAfter(seconds: 5) {
MobileCore.track(action: "showModal", data: nil)
}

// verify
wait(for: [edgeRequestDisplayEventExpectation, edgeRequestInteractEventExpectation, edgeRequestDismissEventExpectation], timeout: asyncTimeout)
}
// func testMessagesReturnedFromXASHaveCorrectJsonFormat() throws {
// // setup
// let edgePersonalizationDecisionsExpectation = XCTestExpectation(description: "edge personalization decisions listener called")
// registerEdgePersonalizationDecisionsListener() { event in
// XCTAssertNotNil(event)
//
// // validate the payload exists
// guard let payload = event.data?["payload"] as? [[String: Any]] else {
// // no payload means this event is a request, not a response
// return
// }
//
// // validate the payload is not empty
// guard !payload.isEmpty else {
// XCTFail("SDK TEST ERROR - expected a payload object, but payload is empty")
// return
// }
//
// // loop through the payload and verify the format for each object
// for payloadObject in payload {
// XCTAssertTrue(self.payloadObjectIsValid(payloadObject), "SDK TEST ERROR - payload object returned was invalid: \(payloadObject)")
// }
//
// edgePersonalizationDecisionsExpectation.fulfill()
// }
//
// // test
// Messaging.refreshInAppMessages()
//
// // verify
// wait(for: [edgePersonalizationDecisionsExpectation], timeout: asyncTimeout)
// }
//
// func testMessagesReturnedFromXASHaveCorrectRuleFormat() throws {
// // setup
// let edgePersonalizationDecisionsExpectation = XCTestExpectation(description: "edge personalization decisions listener called")
// registerEdgePersonalizationDecisionsListener() { event in
//
// // validate the content is a valid rule containing a valid message
// guard let propositions = event.payload else {
// // no payload means this event is a request, not a response
// return
// }
//
// let messagingRulesEngine = MessagingRulesEngine(name: "testRulesEngine", extensionRuntime: TestableExtensionRuntime())
// messagingRulesEngine.loadPropositions(propositions, clearExisting: true, expectedScope: self.expectedScope)
//
// // rules load async - brief sleep to allow it to finish
// self.runAfter(seconds: 3) {
// XCTAssertEqual(3, messagingRulesEngine.rulesEngine.rulesEngine.rules.count, "Message definition successfully loaded into the rules engine.")
// edgePersonalizationDecisionsExpectation.fulfill()
// }
// }
//
// // test
// Messaging.refreshInAppMessages()
//
// // verify
// wait(for: [edgePersonalizationDecisionsExpectation], timeout: asyncTimeout)
// }
//
// func testMessagesDisplayInteractDismissEvents() throws {
// // setup
// let edgeRequestDisplayEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == display received.")
// let edgeRequestInteractEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == interact received.")
// let edgeRequestDismissEventExpectation = XCTestExpectation(description: "edge event with propositionEventType == dismiss received.")
// registerEdgeRequestContentListener() { event in
// if event.isPropositionEvent(withType: "display") {
// self.currentMessage?.track("clicked", withEdgeEventType: .inappInteract)
// edgeRequestDisplayEventExpectation.fulfill()
// }
// if event.isPropositionEvent(withType: "interact") {
// self.currentMessage?.dismiss()
// edgeRequestInteractEventExpectation.fulfill()
// }
// if event.isPropositionEvent(withType: "dismiss") {
// edgeRequestDismissEventExpectation.fulfill()
// }
// }
// MobileCore.messagingDelegate = self
//
// // allow rules engine to be hydrated
// runAfter(seconds: 5) {
// MobileCore.track(action: "showModal", data: nil)
// }
//
// // verify
// wait(for: [edgeRequestDisplayEventExpectation, edgeRequestInteractEventExpectation, edgeRequestDismissEventExpectation], timeout: asyncTimeout)
// }

/// wait for `seconds` before running the code in the closure
func runAfter(seconds: Int, closure: @escaping () -> Void) {
Expand Down
7 changes: 7 additions & 0 deletions AEPMessaging/Tests/TestHelpers/MockMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,11 @@ class MockMessage: Message {
override func overrideUrlLoad(message _: FullscreenMessage, url _: String?) -> Bool {
overrideUrlLoadReturnValue
}

var onShowCalled = false
var paramOnShow: FullscreenMessage?
override func onShow(message: FullscreenMessage) {
onShowCalled = true
paramOnShow = message
}
}
Loading

0 comments on commit e18c48a

Please sign in to comment.