Skip to content

Commit

Permalink
Merge pull request #61 from adobe/staging
Browse files Browse the repository at this point in the history
Staging -> Main (v1.0.1)
  • Loading branch information
addb authored Apr 1, 2022
2 parents 5dc40a4 + 055fa41 commit ae631d3
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 59 deletions.
2 changes: 1 addition & 1 deletion AEPEdgeIdentity.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "AEPEdgeIdentity"
s.version = "1.0.0"
s.version = "1.0.1"
s.summary = "Experience Platform Edge Identity extension for Adobe Experience Platform Mobile SDK. Written and maintained by Adobe."

s.description = <<-DESC
Expand Down
4 changes: 2 additions & 2 deletions AEPEdgeIdentity.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.edge.identity;
PRODUCT_MODULE_NAME = AEPEdgeIdentity;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
Expand Down Expand Up @@ -1170,7 +1170,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.0.1;
PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.edge.identity;
PRODUCT_MODULE_NAME = AEPEdgeIdentity;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
Expand Down
38 changes: 19 additions & 19 deletions Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
PODS:
- AEPAssurance (3.0.0):
- AEPAssurance (3.0.1):
- AEPCore (>= 3.1.0)
- AEPServices (>= 3.1.0)
- AEPCore (3.3.1):
- AEPRulesEngine (= 1.0.1)
- AEPServices (= 3.3.1)
- AEPIdentity (3.3.1):
- AEPCore (= 3.3.1)
- AEPLifecycle (3.3.1):
- AEPCore (= 3.3.1)
- AEPRulesEngine (1.0.1)
- AEPServices (3.3.1)
- AEPSignal (3.3.1):
- AEPCore (= 3.3.1)
- AEPCore (3.4.2):
- AEPRulesEngine (>= 1.1.0)
- AEPServices (>= 3.4.2)
- AEPIdentity (3.4.2):
- AEPCore (>= 3.4.2)
- AEPLifecycle (3.4.2):
- AEPCore (>= 3.4.2)
- AEPRulesEngine (1.1.0)
- AEPServices (3.4.2)
- AEPSignal (3.4.2):
- AEPCore (>= 3.4.2)
- SwiftLint (0.44.0)

DEPENDENCIES:
Expand All @@ -36,13 +36,13 @@ SPEC REPOS:
- SwiftLint

SPEC CHECKSUMS:
AEPAssurance: 18068627111e366a851dc2166239f22b665101bd
AEPCore: fc1398728b6b2a4dcc8dc96455f69ec144e087c0
AEPIdentity: 40aedf425fc7cc63dde579135b8c1c65497a42d2
AEPLifecycle: dc131d6744a55d71bc9009d65f3b3428645cbd23
AEPRulesEngine: 5075ed294026a12e37bd26fe260f74604d205354
AEPServices: c49e7b6ef17ec9f874b015f68ac7d2436235282f
AEPSignal: 2d0dd4775c95797bf118300b74a1d9efcdbf8650
AEPAssurance: b25880cd4b14f22c61a1dce19807bd0ca0fe9b17
AEPCore: b01856bf24972e4720cb0511a358d1e68067252a
AEPIdentity: fbf755560afcbb0acd66cd5b6a1c147530fca5f6
AEPLifecycle: 1e0e843465fb143f8d8949dcf06de169d5c26f62
AEPRulesEngine: bb2927ed5501ddf9754c66e97f8d2b1cf8e33b19
AEPServices: 3214311f239c8cdc6267d757200b05ec0ab05878
AEPSignal: be3a4789b492f4d5a5aef7408f30ff8e866d1d79
SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584

PODFILE CHECKSUM: 998b4a8b4d3c95683f7f6f806ef3f2928fc5d84d
Expand Down
12 changes: 9 additions & 3 deletions Sources/Identity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,26 @@ import Foundation
/// Handles update identity requests to add/update customer identifiers.
/// - Parameter event: the identity request event
private func handleUpdateIdentity(event: Event) {
state.updateCustomerIdentifiers(event: event, createXDMSharedState: createXDMSharedState(data:event:))
// Adding pending shared state to avoid race condition between updating and reading identity map
let resolver = createPendingXDMSharedState(event: event)
state.updateCustomerIdentifiers(event: event, resolveXDMSharedState: resolver)
}

/// Handles remove identity requests to remove customer identifiers.
/// - Parameter event: the identity request event
private func handleRemoveIdentity(event: Event) {
state.removeCustomerIdentifiers(event: event, createXDMSharedState: createXDMSharedState(data:event:))
// Adding pending shared state to avoid race condition between updating and reading identity map
let resolver = createPendingXDMSharedState(event: event)
state.removeCustomerIdentifiers(event: event, resolveXDMSharedState: resolver)
}

/// Handles `EventType.edgeIdentity` request reset events.
/// - Parameter event: the identity request reset event
private func handleRequestReset(event: Event) {
// Adding pending shared state to avoid race condition between updating and reading identity map
let resolver = createPendingXDMSharedState(event: event)
state.resetIdentifiers(event: event,
createXDMSharedState: createXDMSharedState(data:event:),
resolveXDMSharedState: resolver,
eventDispatcher: dispatch(event:))
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/IdentityConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Foundation
enum IdentityConstants {
static let EXTENSION_NAME = "com.adobe.edge.identity"
static let FRIENDLY_NAME = "Edge Identity"
static let EXTENSION_VERSION = "1.0.0"
static let EXTENSION_VERSION = "1.0.1"
static let DATASTORE_NAME = EXTENSION_NAME
static let LOG_TAG = FRIENDLY_NAME

Expand Down
2 changes: 1 addition & 1 deletion Sources/IdentityMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public class IdentityMap: NSObject, Codable {
/// already in the map, then the new item replaces the existing item. Empty `withNamespace` or items with an empty `item.id` are not allowed and are ignored.
/// - Parameters:
/// - item: The identity as an `IdentityItem` object
/// - namespace: The namespace for this identity
/// - withNamespace: The namespace for this identity
@objc(addItem:withNamespace:)
public func add(item: IdentityItem, withNamespace: String) {
add(item: item, withNamespace: withNamespace, asFirstItem: false)
Expand Down
29 changes: 16 additions & 13 deletions Sources/IdentityState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,39 +104,43 @@ class IdentityState {
///
/// - Parameters
/// - event: event containing customer identifiers to add or update with the current customer identifiers
/// - createXDMSharedState: function which creates new XDM shared state
func updateCustomerIdentifiers(event: Event, createXDMSharedState: ([String: Any], Event) -> Void) {
/// - resolveXDMSharedState: function which resolves pending XDM shared state
func updateCustomerIdentifiers(event: Event, resolveXDMSharedState: ([String: Any]) -> Void) {
guard let identifiersData = event.data else {
Log.debug(label: IdentityConstants.FRIENDLY_NAME, "IdentityState - Failed to update identifiers as no identifiers were found in the event data.")
resolveXDMSharedState(identityProperties.toXdmData())
return
}

guard let updateIdentityMap = IdentityMap.from(eventData: identifiersData) else {
Log.debug(label: IdentityConstants.FRIENDLY_NAME, "IdentityState - Failed to update identifiers as the event data could not be encoded to an IdentityMap.")
resolveXDMSharedState(identityProperties.toXdmData())
return
}

identityProperties.updateCustomerIdentifiers(updateIdentityMap)
saveToPersistence(and: createXDMSharedState, using: event)
saveToPersistence(and: resolveXDMSharedState)
}

/// Remove customer identifiers specified in `event` from the current `IdentityMap`.
/// - Parameters:
/// - event: event containing customer identifiers to remove from the current customer identities
/// - createXDMSharedState: function which creates new XDM shared states
func removeCustomerIdentifiers(event: Event, createXDMSharedState: ([String: Any], Event) -> Void) {
/// - resolveXDMSharedState: function which resolves pending XDM shared states
func removeCustomerIdentifiers(event: Event, resolveXDMSharedState: ([String: Any]) -> Void) {
guard let identifiersData = event.data else {
Log.debug(label: IdentityConstants.LOG_TAG, "IdentityState - Failed to remove identifier as no identifiers were found in the event data.")
resolveXDMSharedState(identityProperties.toXdmData())
return
}

guard let removeIdentityMap = IdentityMap.from(eventData: identifiersData) else {
Log.debug(label: IdentityConstants.LOG_TAG, "IdentityState - Failed to remove identifier as the event data could not be encoded to an IdentityMap.")
resolveXDMSharedState(identityProperties.toXdmData())
return
}

identityProperties.removeCustomerIdentifiers(removeIdentityMap)
saveToPersistence(and: createXDMSharedState, using: event)
saveToPersistence(and: resolveXDMSharedState)
}

/// Clears all identities and regenerates a new ECID value.
Expand All @@ -146,13 +150,13 @@ class IdentityState {
/// - createXDMSharedState: function which creates new XDM shared states
/// - eventDispatcher: function which dispatches a new `Event`
func resetIdentifiers(event: Event,
createXDMSharedState: ([String: Any], Event) -> Void,
resolveXDMSharedState: ([String: Any]) -> Void,
eventDispatcher: (Event) -> Void) {

identityProperties.clear()
identityProperties.ecid = ECID().ecidString

saveToPersistence(and: createXDMSharedState, using: event)
saveToPersistence(and: resolveXDMSharedState)

let event = Event(name: IdentityConstants.EventNames.RESET_IDENTITIES_COMPLETE,
type: EventType.edgeIdentity,
Expand All @@ -175,13 +179,12 @@ class IdentityState {
return true
}

/// Save `identityProperties` to persistence and create an XDM shared state.
/// Save `identityProperties` to persistence and resolves the XDM shared state.
/// - Parameters:
/// - createXDMSharedState: function which creates an XDM shared state
/// - event: the event used to share the XDM state
private func saveToPersistence(and createXDMSharedState: ([String: Any], Event) -> Void, using event: Event) {
/// - resolveXDMSharedState: function which resolves the XDM shared state
private func saveToPersistence(and resolveXDMSharedState: ([String: Any]) -> Void) {
identityProperties.saveToPersistence()
createXDMSharedState(identityProperties.toXdmData(), event)
resolveXDMSharedState(identityProperties.toXdmData())
}

/// Check if the Identity direct extension is registered by checking the EventHub's shared state list of registered extensions.
Expand Down
2 changes: 2 additions & 0 deletions Tests/Mocks/TestableExtensionRuntime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,6 @@ class TestableExtensionRuntime: ExtensionRuntime {
func startEvents() {}

func stopEvents() {}

func getHistoricalEvents(_ events: [EventHistoryRequest], enforceOrder: Bool, handler: @escaping ([EventHistoryResult]) -> Void) {}
}
50 changes: 49 additions & 1 deletion Tests/UnitTests/IdentityPublicAPITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ class IdentityAPITests: XCTestCase {
wait(for: [expectation], timeout: 1)
}

/// Tests that getIdentities returns an error if the response event data contains no ecid
func testGetExperienceCloudIdReturnsEmptyStringIfResponseContainsDataWithoutECIDValues() {
// setup
let expectation = XCTestExpectation(description: "getExperienceCloudId callback should get called")
expectation.assertForOverFulfill = true
EventHub.shared.getExtensionContainer(MockExtension.self)?.registerListener(type: EventType.edgeIdentity, source: EventSource.requestIdentity) { event in
let responseEvent = event.createResponseEvent(name: IdentityConstants.EventNames.IDENTITY_RESPONSE_CONTENT_ONE_TIME,
type: EventType.edgeIdentity,
source: EventSource.responseIdentity,
data: ["identityMap": ["ECID": []]])
MobileCore.dispatch(event: responseEvent)
}

// test
Identity.getExperienceCloudId { ecid, error in
XCTAssertNil(error)
XCTAssertEqual("", ecid)
expectation.fulfill()
}

// verify
wait(for: [expectation], timeout: 1)
}

/// Tests that getIdentities dispatches an identity request identity event
func testGetIdentities() {
// setup
Expand Down Expand Up @@ -148,7 +172,7 @@ class IdentityAPITests: XCTestCase {
}

/// Tests that updateIdentifiers dispatches an identity update identity event
func testUpdateIdentifiers() {
func testUpdateIdentities() {
// setup
let expectation = XCTestExpectation(description: "updateIdentities should dispatch an event")
expectation.assertForOverFulfill = true
Expand All @@ -165,6 +189,19 @@ class IdentityAPITests: XCTestCase {
wait(for: [expectation], timeout: 1)
}

/// Tests that updateIdentifiers dispatches an identity update identity event
func testUpdateIdentitiesWithEmptyValuesShouldNotDispatchEvent() {
// setup
EventHub.shared.getExtensionContainer(MockExtension.self)?.registerListener(type: EventType.edgeIdentity, source: EventSource.updateIdentity) { _ in
XCTFail("updateIdentities should not dispatch an event")
}

// test
let map = IdentityMap()
map.add(item: IdentityItem(id: ""), withNamespace: "")
Identity.updateIdentities(with: map)
}

/// Tests that removeIdentity dispatches an identity remove identity event
func testRemoveIdentity() {
// setup
Expand All @@ -180,4 +217,15 @@ class IdentityAPITests: XCTestCase {
// verify
wait(for: [expectation], timeout: 1)
}

/// Tests that removeIdentity dispatches an identity remove identity event
func testRemoveIdentityWithEmptyValuesShouldNotDispatchEvent() {
// setup
EventHub.shared.getExtensionContainer(MockExtension.self)?.registerListener(type: EventType.edgeIdentity, source: EventSource.removeIdentity) { _ in
XCTFail("removeIdentity should not dispatch an event")
}

// test
Identity.removeIdentity(item: IdentityItem(id: ""), withNamespace: "")
}
}
Loading

0 comments on commit ae631d3

Please sign in to comment.