Skip to content

Commit

Permalink
Merge pull request #988 from cdhoffmann/addArrayReplaceTokenSupport
Browse files Browse the repository at this point in the history
[PLATIR-35300] Add array replace token support
  • Loading branch information
cdhoffmann committed Jan 18, 2024
2 parents 461d411 + a469027 commit 81f990b
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 8 deletions.
4 changes: 4 additions & 0 deletions AEPCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@
75550A3F2A9930A500747BB7 /* NamedCollectionDataStoreFunctionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75550A3E2A9930A500747BB7 /* NamedCollectionDataStoreFunctionalTests.swift */; };
75C0D9052A9D545100EF74BC /* DatastoreUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75C0D9042A9D545100EF74BC /* DatastoreUtilities.swift */; };
75C0D9062AA1287B00EF74BC /* AEPServicesMocks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3FE6DDA924C62C090065EA05 /* AEPServicesMocks.framework */; };
75ED44D12B56F0B400F2CEB1 /* rules_testAttachDataArray.json in Resources */ = {isa = PBXBuildFile; fileRef = 75ED44D02B56F0B300F2CEB1 /* rules_testAttachDataArray.json */; };
7814B23325CB455200841429 /* URL+Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7814B23225CB455200841429 /* URL+Validator.swift */; };
786C000525B8EE2100F26D34 /* DefaultHeadersFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786C000425B8EE2100F26D34 /* DefaultHeadersFormatter.swift */; };
786C001525B8EE6200F26D34 /* HttpConnectionConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786C001425B8EE6200F26D34 /* HttpConnectionConstants.swift */; };
Expand Down Expand Up @@ -1058,6 +1059,7 @@
75408CF62948EA0A00C44CE1 /* AtomicCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicCounterTests.swift; sourceTree = "<group>"; };
75550A3E2A9930A500747BB7 /* NamedCollectionDataStoreFunctionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NamedCollectionDataStoreFunctionalTests.swift; sourceTree = "<group>"; };
75C0D9042A9D545100EF74BC /* DatastoreUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatastoreUtilities.swift; sourceTree = "<group>"; };
75ED44D02B56F0B300F2CEB1 /* rules_testAttachDataArray.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = rules_testAttachDataArray.json; sourceTree = "<group>"; };
7814B23225CB455200841429 /* URL+Validator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Validator.swift"; sourceTree = "<group>"; };
786C000425B8EE2100F26D34 /* DefaultHeadersFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultHeadersFormatter.swift; sourceTree = "<group>"; };
786C001425B8EE6200F26D34 /* HttpConnectionConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpConnectionConstants.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1854,6 +1856,7 @@
3F08FF9A24DA0DA100D34DE3 /* rules_functional_1.zip */,
BBA512B624F6C4D90030DAD1 /* rules_testAttachData_invalidJson.json */,
BBA512B124F5CF380030DAD1 /* rules_testAttachData.json */,
75ED44D02B56F0B300F2CEB1 /* rules_testAttachDataArray.json */,
BF4A6EB726BB3B9D00612434 /* rules_testDispatchEventCopy.json */,
BF4A6F2326BB4A1A00612434 /* rules_testDispatchEventInvalidAction.json */,
BF4A6F8C26BBAE6500612434 /* rules_testDispatchEventChain.json */,
Expand Down Expand Up @@ -2664,6 +2667,7 @@
BB3E86E224F975E000E39C53 /* rules_testMatcherWithDifferentTypesOfParameters.json in Resources */,
3F39520D24CA096100F7325B /* ADBMobileConfig.json in Resources */,
24A1FCE72704CE6000D28D26 /* rules_testHistory.json in Resources */,
75ED44D12B56F0B400F2CEB1 /* rules_testAttachDataArray.json in Resources */,
BBA5129D24F4899B0030DAD1 /* rules_testMatcherGt.json in Resources */,
BF4A6F0526BB48A200612434 /* rules_testDispatchEventNewNoData.json in Resources */,
BF4A6F2826BB4A1B00612434 /* rules_testDispatchEventNoSource.json in Resources */,
Expand Down
27 changes: 19 additions & 8 deletions AEPCore/Sources/rules/LaunchRulesEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,22 +284,33 @@ public class LaunchRulesEngine {
return RuleConsequence(id: consequence.id, type: consequence.type, details: dict)
}

private func replaceToken(in value: Any, data: Traversable) -> Any {
switch value {
case let valString as String:
return replaceToken(for: valString, data: data)
case let nestedDict as [String: Any?]:
return replaceToken(in: nestedDict, data: data)
case let nestedArray as [Any]:
return replaceToken(in: nestedArray, data: data)
default:
return value
}
}

private func replaceToken(in dict: [String: Any?], data: Traversable) -> [String: Any?] {
var mutableDict = dict
for (key, value) in mutableDict {
switch value {
case is String:
mutableDict[key] = replaceToken(for: value as! String, data: data)
case is [String: Any]:
let valueDict = mutableDict[key] as! [String: Any]
mutableDict[key] = replaceToken(in: valueDict, data: data)
default:
break
if let value = value {
mutableDict[key] = replaceToken(in: value, data: data)
}
}
return mutableDict
}

private func replaceToken(in array: [Any], data: Traversable) -> [Any] {
return array.map { replaceToken(in: $0, data: data) }
}

private func replaceToken(for value: String, data: Traversable) -> String {
let template = Template(templateString: value, tagDelimiterPair: (LaunchRulesEngine.LAUNCH_RULE_TOKEN_LEFT_DELIMITER, LaunchRulesEngine.LAUNCH_RULE_TOKEN_RIGHT_DELIMITER))
return template.render(data: data, transformers: transformer)
Expand Down
56 changes: 56 additions & 0 deletions AEPCore/Tests/FunctionalTests/RulesEngineFunctionalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,62 @@ class RulesEngineFunctionalTests: XCTestCase {
XCTAssertEqual("", attachedData["launches"] as? String)
}

func testAttachDataArray() {
/// Given: a launch rule to attach data to event

// ---------- attach data rule ----------
// "eventdata": {
// "attached_data_array": [
// "{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.carriername%}",
// "testStringTopLevel",
// {
// "testDictKey": "testVal",
// "osversionNested": "{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.osversion%}"
//
// }, [
// "{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.osversion%}",
// "testStringInsideNestedArray"
// ]
// ]
// }
// --------------------------------------

resetRulesEngine(withNewRules: "rules_testAttachDataArray")

/// When: evaluating a launch event

// ------------ launch event ------------
// "eventdata": {
// "lifecyclecontextdata": {
// "launchevent": "LaunchEvent"
// }
// }
// --------------------------------------


mockRuntime.simulateSharedState(for: "com.adobe.module.lifecycle", data: (value: ["lifecyclecontextdata": ["carriername": "AT&T", "osversion": "17.0"]], status: .set))
let processedEvent = rulesEngine.process(event: defaultEvent)

/// Then: no consequence event will be dispatched
XCTAssertEqual(0, mockRuntime.dispatchedEvents.count)
guard let attachedData = processedEvent.data?["attached_data_array"] as? [Any] else {
XCTFail()
return
}
// Token replaces values
XCTAssertEqual(attachedData[0] as? String, "AT&T")
// non token replaced string
XCTAssertEqual(attachedData[1] as? String, "testStringTopLevel")
// Dict with token replaced string, and non token replaced string
let dict = attachedData[2] as? [String: Any?]
XCTAssertEqual(dict?["testDictKey"] as? String, "testVal")
XCTAssertEqual(dict?["osversionNested"] as? String, "17.0")
let arr = attachedData[3] as? [Any]
XCTAssertEqual(arr?[0] as? String, "17.0")
XCTAssertEqual(arr?[1] as? String, "testStringInsideNestedArray")

}

func testAttachData_invalidJson() {
/// Given: a launch rule to attach data to event

Expand Down
101 changes: 101 additions & 0 deletions AEPCore/Tests/TestResources/rules_testAttachDataArray.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"version": 1,
"rules": [
{
"condition": {
"type": "group",
"definition": {
"logic": "and",
"conditions": [
{
"type": "group",
"definition": {
"logic": "or",
"conditions": [
{
"type": "group",
"definition": {
"logic": "and",
"conditions": [
{
"type": "matcher",
"definition": {
"key": "~type",
"matcher": "eq",
"values": [
"com.adobe.eventType.lifecycle"
]
}
},
{
"type": "matcher",
"definition": {
"key": "~source",
"matcher": "eq",
"values": [
"com.adobe.eventSource.responseContent"
]
}
},
{
"type": "matcher",
"definition": {
"key": "lifecyclecontextdata.launchevent",
"matcher": "ex",
"values": []
}
}
]
}
}
]
}
},
{
"type": "group",
"definition": {
"logic": "and",
"conditions": [
{
"type": "matcher",
"definition": {
"key": "~state.com.adobe.module.lifecycle/lifecyclecontextdata.carriername",
"matcher": "eq",
"values": [
"AT&T"
]
}
}
]
}
}
]
}
},
"consequences": [
{
"id": "RCa839e401f54a459a9049328f9b609a07",
"type": "add",
"detail": {
"eventdata": {
"attached_data_array": [
"{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.carriername%}",
"testStringTopLevel",
{
"testDictKey": "testVal",
"osversionNested": "{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.osversion%}"

}, [
"{%~state.com.adobe.module.lifecycle/lifecyclecontextdata.osversion%}",
"testStringInsideNestedArray",
null
],
null
]
}
}
}
]
}
]
}

0 comments on commit 81f990b

Please sign in to comment.