FBAEMKit/FBAEMKitTests/AEMAdvertiserSingleEntryRuleTests.swift (477 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the license found in the * LICENSE file in the root directory of this source tree. */ @testable import FBAEMKit import XCTest #if !os(tvOS) final class AEMAdvertiserSingleEntryRuleTests: XCTestCase { enum Keys { static let ruleOperator = "operator" static let ruleParamKey = "param_key" static let ruleStringValue = "string_value" static let ruleNumberValue = "number_value" static let ruleArrayValue = "array_value" } func testIsMatchedWithEventParameters() { var rule = _AEMAdvertiserSingleEntryRule( with: .contains, paramKey: "fb_content.title", linguisticCondition: "hello", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isMatchedEventParameters(["fb_content": ["title": "helloworld"]]), "Should expect the event parameter matched with the rule" ) XCTAssertTrue( rule.isMatchedEventParameters(["fb_content": ["title": "HelloWorld"]]), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": ["tt": "helloworld"]]), "Should not expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": ["title": 100]]), "Should not expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["quantitly": ["title": "helloworld"]]), "Should not expect the event parameter matched with the rule" ) rule.setOperator(.notEqual) XCTAssertTrue( rule.isMatchedEventParameters(["fb_content": ["title": "helloworld"]]), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": ["tt": "helloworld"]]), "Should not expect the event parameter matched with the rule" ) rule = _AEMAdvertiserSingleEntryRule( with: .greaterThan, paramKey: "fb_content.product1.quantity", linguisticCondition: nil, numericalCondition: NSNumber(value: 10), arrayCondition: nil ) XCTAssertTrue( rule.isMatchedEventParameters(["fb_content": ["product1": ["quantity": 100]]]), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": ["product1": ["quantity": 1]]]), "Should expect the event parameter matched with the rule" ) } func testIsMatchedWithEventParametersForAsteriskOperator() { let rule = _AEMAdvertiserSingleEntryRule( with: .contains, paramKey: "fb_content[*].id", linguisticCondition: "coffee", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isMatchedEventParameters(["fb_content": [["id": "shop"], ["id": "coffeeshop"]]]), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": ["id": "coffeeshop"]]), "Should not expect the event parameter matched with the rule without expected item" ) XCTAssertFalse( rule.isMatchedEventParameters(["fb_content": [["id": "shop"]]]), "Should not expect the event parameter matched with the rule without expected id" ) } func testIsMatchedWithEventParametersAndAsterisk() { let rule = _AEMAdvertiserSingleEntryRule( with: .contains, paramKey: "fb_content[*].title", linguisticCondition: "hello", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content": [["title": "hello"], ["title", "world"]]], paramPath: ["fb_content[*]", "title"] ), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content": [["title": "aaaa"], ["title", "world"]]], paramPath: ["fb_content[*]", "title"] ), "Should not expect the event parameter matched with the rule" ) } func testIsMatchedWithAsteriskParam() { let rule = _AEMAdvertiserSingleEntryRule( with: .contains, paramKey: "fb_content[*].title", linguisticCondition: "hello", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content": [["title": "hello"], ["title", "world"]]], paramPath: ["fb_content[*]", "title"] ), "Should expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content": [["title": "aaaa"], ["title", "world"]]], paramPath: ["fb_content[*]", "title"] ), "Should not expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content_aaa": [["title": "aaaa"], ["title", "world"]]], paramPath: ["fb_content[*]", "title"] ), "Should not expect the event parameter matched with the rule" ) XCTAssertFalse( rule.isMatched( withAsteriskParam: "fb_content[*]", eventParameters: ["fb_content_aaa": ["title": "aaaa"]], paramPath: ["fb_content[*]", "title"] ), "Should not expect the event parameter matched with the rule" ) } func testIsMatchedWithStringComparision() { let rule = _AEMAdvertiserSingleEntryRule( with: .contains, paramKey: "fb_content.title", linguisticCondition: "hello", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isMatched(withStringValue: "worldhelloworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "worldhellworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) rule.setOperator(.notContains) XCTAssertFalse( rule.isMatched(withStringValue: "worldhelloworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "WorldHelloWorld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) XCTAssertTrue( rule.isMatched(withStringValue: "worldhellworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) rule.setOperator(.startsWith) XCTAssertTrue( rule.isMatched(withStringValue: "helloworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertTrue( rule.isMatched(withStringValue: "HelloWorld", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "worldhelloworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) rule.setOperator(.caseInsensitiveContains) XCTAssertTrue( rule.isMatched(withStringValue: "worldHELLOworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "worldhellworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) rule.setOperator(.caseInsensitiveNotContains) XCTAssertFalse( rule.isMatched(withStringValue: "worldHELLOworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) XCTAssertTrue( rule.isMatched(withStringValue: "worldHELLworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) rule.setOperator(.caseInsensitiveStartsWith) XCTAssertTrue( rule.isMatched(withStringValue: "HELLOworld", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "worldHELLOworld", numericalValue: nil), "Shoule not expect parameter matched with the value" ) rule.setOperator(.equal) XCTAssertTrue( rule.isMatched(withStringValue: "hello", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertTrue( rule.isMatched(withStringValue: "Hello", numericalValue: nil), "Shoule expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "hellw", numericalValue: nil), "Shoule not expect parameter matched with the value" ) rule.setOperator(.notEqual) XCTAssertFalse( rule.isMatched(withStringValue: "hello", numericalValue: nil), "Shoule not expect parameter matched with the value" ) XCTAssertFalse( rule.isMatched(withStringValue: "Hello", numericalValue: nil), "Shoule not expect parameter matched with the value" ) XCTAssertTrue( rule.isMatched(withStringValue: "hellw", numericalValue: nil), "Shoule expect parameter matched with the value" ) } func testIsMatchedWithNumberComparision() { let rule = _AEMAdvertiserSingleEntryRule( with: .lessThan, paramKey: "fb_content.title", linguisticCondition: nil, numericalCondition: NSNumber(value: 100), arrayCondition: nil ) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 90)), "Shoule expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 100)), "Shoule not expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 101)), "Shoule not expect parameter matched with value" ) rule.setOperator(.lessThanOrEqual) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 99)), "Shoule expect parameter matched with value" ) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 100)), "Shoule expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 100.1)), "Shoule not expect parameter matched with value" ) rule.setOperator(.greaterThan) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 101.5)), "Shoule expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 100)), "Shoule not expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 99)), "Shoule not expect parameter matched with value" ) rule.setOperator(.greaterThanOrEqual) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 101.5)), "Shoule expect parameter matched with value" ) XCTAssertTrue( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 100)), "Shoule expect parameter matched with value" ) XCTAssertFalse( rule.isMatched(withStringValue: nil, numericalValue: NSNumber(value: 99)), "Shoule not expect parameter matched with value" ) } func testIsMatchedWithArrayComparision() { let rule = _AEMAdvertiserSingleEntryRule( with: .isAny, paramKey: "fb_content.title", linguisticCondition: nil, numericalCondition: nil, arrayCondition: ["Abc", "aaa", "ABC", "XXXX"] ) XCTAssertTrue( rule.isMatched(withStringValue: "aaa", numericalValue: nil), "Shoule expect parameter matched with item in the array" ) XCTAssertFalse( rule.isMatched(withStringValue: "bbb", numericalValue: nil), "Shoule not expect parameter matched with item in the array" ) rule.setOperator(.caseInsensitiveIsAny) XCTAssertTrue( rule.isMatched(withStringValue: "abc", numericalValue: nil), "Shoule expect parameter matched with item in the array" ) rule.setOperator(.isNotAny) XCTAssertTrue( rule.isMatched(withStringValue: "xxxx", numericalValue: nil), "Shoule expect parameter matched with item in the array" ) rule.setOperator(.caseInsensitiveIsNotAny) XCTAssertTrue( rule.isMatched(withStringValue: "ab", numericalValue: nil), "Shoule expect parameter matched with item in the array" ) } func testIsRegexMatch() { let rule = _AEMAdvertiserSingleEntryRule( with: .isAny, paramKey: "fb_content.title", linguisticCondition: "eylea.us/support/?$|eylea.us/support/?", numericalCondition: nil, arrayCondition: nil ) XCTAssertTrue( rule.isRegexMatch("eylea.us/support"), "Should expect parameter matched with regex" ) XCTAssertFalse( rule.isRegexMatch("eylea.us.support"), "Should not expect parameter matched with regex" ) } func testIsRegexMatchWithEmtpyString() { let rule = _AEMAdvertiserSingleEntryRule( with: .isAny, paramKey: "fb_content.title", linguisticCondition: "", numericalCondition: nil, arrayCondition: nil ) XCTAssertFalse( rule.isRegexMatch("eylea.us.support"), "Should not expect parameter matched with regex" ) } func testIsRegexMatchWithNullableString() { let rule = _AEMAdvertiserSingleEntryRule( with: .isAny, paramKey: "fb_content.title", linguisticCondition: nil, numericalCondition: nil, arrayCondition: nil ) XCTAssertFalse( rule.isRegexMatch("eylea.us.support"), "Should not expect parameter matched with regex" ) } func testIsAnyOf() { let rule = _AEMAdvertiserSingleEntryRule( with: .isAny, paramKey: "fb_content.title", linguisticCondition: nil, numericalCondition: nil, arrayCondition: ["abc", "AAA", "Abc"] ) XCTAssertTrue( rule.isAny(of: ["abc", "AAA", "Abc"], stringValue: "AAA", ignoreCase: false), "Should expect parameter matched" ) XCTAssertTrue( rule.isAny(of: ["abc", "AAA", "Abc"], stringValue: "aaa", ignoreCase: true), "Should expect parameter matched" ) XCTAssertTrue( rule.isAny(of: ["abc", "AAA", "Abc"], stringValue: "ABC", ignoreCase: true), "Should expect parameter matched" ) XCTAssertFalse( rule.isAny(of: ["abc", "AAA", "Abc"], stringValue: "aaa", ignoreCase: false), "Should not expect parameter matched" ) XCTAssertFalse( rule.isAny(of: ["abc", "AAA", "Abc"], stringValue: "ab", ignoreCase: false), "Should not expect parameter matched" ) } func testSecureCoding() { XCTAssertTrue( _AEMAdvertiserSingleEntryRule.supportsSecureCoding, "AEM Advertiser Single Entry Rule should support secure coding" ) } func testEncoding() throws { let coder = TestCoder() let entryRule = SampleAEMData.validAdvertiserSingleEntryRule entryRule.encode(with: coder) let ruleOperator = coder.encodedObject[Keys.ruleOperator] as? NSNumber XCTAssertEqual( ruleOperator?.intValue, entryRule.operator.rawValue, "Should encode the expected operator with the correct key" ) XCTAssertEqual( coder.encodedObject[Keys.ruleParamKey] as? String, entryRule.paramKey, "Should encode the expected param_key with the correct key" ) XCTAssertEqual( coder.encodedObject[Keys.ruleStringValue] as? String, entryRule.linguisticCondition, "Should encode the expected string_value with the correct key" ) let numberValue = try XCTUnwrap(coder.encodedObject[Keys.ruleNumberValue] as? NSNumber) XCTAssertTrue( entryRule.numericalCondition?.isEqual(to: numberValue) == true, "Should encode the expected content with the correct key" ) let arrayValue = try XCTUnwrap(coder.encodedObject[Keys.ruleArrayValue] as? NSArray) let expectedArrayValue = try XCTUnwrap(entryRule.arrayCondition as NSArray?) XCTAssertEqual( arrayValue, expectedArrayValue, "Should encode the expected array_value with the correct key" ) } func testDecoding() { let decoder = TestCoder() _ = _AEMAdvertiserSingleEntryRule(coder: decoder) XCTAssertEqual( decoder.decodedObject[Keys.ruleOperator] as? String, "decodeIntegerForKey", "Should decode the expected type for the operator key" ) XCTAssertTrue( decoder.decodedObject[Keys.ruleParamKey] is NSString.Type, "Should decode the expected type for the param_key key" ) XCTAssertTrue( decoder.decodedObject[Keys.ruleStringValue] is NSString.Type, "Should decode the expected type for the string_value key" ) XCTAssertTrue( decoder.decodedObject[Keys.ruleNumberValue] is NSNumber.Type, "Should decode the expected type for the number_value key" ) XCTAssertTrue( decoder.decodedObject[Keys.ruleArrayValue] is NSArray.Type, "Should decode the expected type for the array_value key" ) } } #endif