Add GK for catalog matching

Reviewed By: wx0165927473

Differential Revision: D33882047

fbshipit-source-id: d7efbd59540a2e44efc3454a62dceb9fa5b0abeb
This commit is contained in:
Zilin Zhang
2022-01-31 15:19:02 -08:00
committed by Facebook GitHub Bot
parent bb5e40c055
commit a2728599f1
12 changed files with 141 additions and 59 deletions

View File

@@ -20,7 +20,8 @@ typedef void (^FBAEMReporterBlock)(NSError *_Nullable);
@property (class, nonatomic) dispatch_queue_t queue;
@property (class, nonatomic) NSDate *timestamp;
@property (class, nonatomic) BOOL isEnabled;
@property (class, nonatomic) BOOL isCatalogReportEnabled;
@property (class, nonatomic) BOOL isConversionFilteringEnabled;
@property (class, nonatomic) BOOL isCatalogMatchingEnabled;
@property (class, nonatomic) NSMutableDictionary<NSString *, NSMutableArray<FBAEMConfiguration *> *> *configs;
@property (class, nonatomic) NSMutableArray<FBAEMInvocation *> *invocations;
@property (class, nonatomic) NSMutableArray<FBAEMReporterBlock> *completionBlocks;

View File

@@ -86,15 +86,26 @@ class FBAEMReporterTests: XCTestCase {
XCTAssertTrue(AEMReporter.isEnabled, "AEM Report should be enabled")
}
func testCatalogReportDefaultConfigure() {
XCTAssertFalse(AEMReporter.isCatalogReportEnabled, "AEM Catalog Report should be disabled by default")
func testConversionFilteringDefaultConfigure() {
XCTAssertFalse(AEMReporter.isConversionFilteringEnabled, "AEM Conversion Filtering should be disabled by default")
}
func testSetCatalogReportEnabled() {
AEMReporter.isCatalogReportEnabled = false
AEMReporter.setCatalogReportEnabled(true)
func testSetConversionFilteringEnabled() {
AEMReporter.isConversionFilteringEnabled = false
AEMReporter.setConversionFilteringEnabled(true)
XCTAssertTrue(AEMReporter.isCatalogReportEnabled, "AEM Catalog Report should be enabled")
XCTAssertTrue(AEMReporter.isConversionFilteringEnabled, "AEM Conversion Filtering should be enabled")
}
func testCatalogMatchingDefaultConfigure() {
XCTAssertFalse(AEMReporter.isCatalogMatchingEnabled, "AEM Catalog Matching should be disabled by default")
}
func testSetCatalogMatchingEnabled() {
AEMReporter.isCatalogMatchingEnabled = false
AEMReporter.setCatalogMatchingEnabled(true)
XCTAssertTrue(AEMReporter.isCatalogMatchingEnabled, "AEM Catalog Matching should be enabled")
}
func testConfigure() {
@@ -1003,22 +1014,28 @@ class FBAEMReporterTests: XCTestCase {
}
func testShouldReportConversionInCatalogLevel() {
for catalogReportEnabled in [true, false] {
for isOptimizedEvent in [true, false] {
for catalogID in ["test_catalog", nil] {
AEMReporter.setCatalogReportEnabled(catalogReportEnabled)
testInvocation.isOptimizedEvent = isOptimizedEvent
testInvocation.catalogID = catalogID
if catalogReportEnabled && isOptimizedEvent && catalogID != nil {
XCTAssertTrue(
AEMReporter._shouldReportConversion(inCatalogLevel: testInvocation, event: Values.purchase),
"Should expect to report conversion in catalog level"
)
} else {
XCTAssertFalse(
AEMReporter._shouldReportConversion(inCatalogLevel: testInvocation, event: Values.purchase),
"Should expect not to report conversion in catalog level"
)
for conversionFilteringEnabled in [true, false] {
for catalogMatchingEnabled in [true, false] {
for isOptimizedEvent in [true, false] {
for catalogID in ["test_catalog", nil] {
AEMReporter.setConversionFilteringEnabled(conversionFilteringEnabled)
AEMReporter.setCatalogMatchingEnabled(catalogMatchingEnabled)
testInvocation.isOptimizedEvent = isOptimizedEvent
testInvocation.catalogID = catalogID
if conversionFilteringEnabled
&& catalogMatchingEnabled
&& isOptimizedEvent
&& catalogID != nil {
XCTAssertTrue(
AEMReporter._shouldReportConversion(inCatalogLevel: testInvocation, event: Values.purchase),
"Should expect to report conversion in catalog level"
)
} else {
XCTAssertFalse(
AEMReporter._shouldReportConversion(inCatalogLevel: testInvocation, event: Values.purchase),
"Should expect not to report conversion in catalog level"
)
}
}
}
}

View File

@@ -1000,7 +1000,8 @@ static BOOL g_explicitEventsLoggedYet = NO;
[self.featureChecker checkFeature:FBSDKFeatureAEM completionBlock:^(BOOL AEMEnabled) {
if (AEMEnabled) {
[self.aemReporter enable];
[self.aemReporter setCatalogReportEnabled:[self.featureChecker isEnabled:FBSDKFeatureAEMCatalogReport]];
[self.aemReporter setCatalogMatchingEnabled:[self.featureChecker isEnabled:FBSDKFeatureAEMCatalogMatching]];
[self.aemReporter setConversionFilteringEnabled:[self.featureChecker isEnabled:FBSDKFeatureAEMConversionFiltering]];
}
}];
}

View File

@@ -216,7 +216,8 @@ static UIApplicationState _applicationState;
#if !TARGET_OS_TV
[self.components.featureChecker checkFeature:FBSDKFeatureAEM completionBlock:^(BOOL enabled) {
if (enabled) {
[FBAEMReporter setCatalogReportEnabled:[self.components.featureChecker isEnabled:FBSDKFeatureAEMCatalogReport]];
[FBAEMReporter setCatalogMatchingEnabled:[self.components.featureChecker isEnabled:FBSDKFeatureAEMCatalogMatching]];
[FBAEMReporter setConversionFilteringEnabled:[self.components.featureChecker isEnabled:FBSDKFeatureAEMConversionFiltering]];
[FBAEMReporter enable];
[FBAEMReporter handleURL:url];
}

View File

@@ -26,7 +26,9 @@ NS_SWIFT_NAME(AEMReporterProtocol)
NS_SWIFT_NAME(recordAndUpdate(event:currency:value:parameters:));
// UNCRUSTIFY_FORMAT_ON
+ (void)setCatalogReportEnabled:(BOOL)enabled;
+ (void)setConversionFilteringEnabled:(BOOL)enabled;
+ (void)setCatalogMatchingEnabled:(BOOL)enabled;
@end

View File

@@ -151,7 +151,8 @@ static FBSDKFeatureManager * sharedInstance;
case FBSDKFeatureErrorReport: featureName = @"ErrorReport"; break;
case FBSDKFeatureATELogging: featureName = @"ATELogging"; break;
case FBSDKFeatureAEM: featureName = @"AEM"; break;
case FBSDKFeatureAEMCatalogReport: featureName = @"AEMCatalogReport"; break;
case FBSDKFeatureAEMConversionFiltering: featureName = @"AEMConversionFiltering"; break;
case FBSDKFeatureAEMCatalogMatching: featureName = @"AEMCatalogMatching"; break;
case FBSDKFeatureLogin: featureName = @"LoginKit"; break;
case FBSDKFeatureShare: featureName = @"ShareKit"; break;
case FBSDKFeatureGamingServices: featureName = @"GamingServicesKit"; break;
@@ -176,7 +177,8 @@ static FBSDKFeatureManager * sharedInstance;
case FBSDKFeatureModelRequest:
case FBSDKFeatureATELogging:
case FBSDKFeatureAEM:
case FBSDKFeatureAEMCatalogReport:
case FBSDKFeatureAEMConversionFiltering:
case FBSDKFeatureAEMCatalogMatching:
case FBSDKFeatureSKAdNetwork:
case FBSDKFeatureSKAdNetworkConversionValue:
return NO;

View File

@@ -51,7 +51,8 @@ typedef NS_ENUM(NSUInteger, FBSDKFeature) {
FBSDKFeatureSKAdNetworkConversionValue = 0x01010601,
FBSDKFeatureATELogging = 0x01010700,
FBSDKFeatureAEM = 0x01010800,
FBSDKFeatureAEMCatalogReport = 0x01010801,
FBSDKFeatureAEMConversionFiltering = 0x01010801,
FBSDKFeatureAEMCatalogMatching = 0x01010802,
/** Instrument */
FBSDKFeatureInstrument = 0x01020000,
FBSDKFeatureCrashReport = 0x01020100,

View File

@@ -1512,9 +1512,9 @@ class AppEventsTests: XCTestCase {
}
}
func testFetchingConfigurationIncludingAEMCatalogReport() {
func testFetchingConfigurationIncludingAEMConversionFiltering() {
if #available(iOS 14.0, *) {
featureManager.enable(feature: .aemCatalogReport)
featureManager.enable(feature: .aemConversionFiltering)
appEvents.fetchServerConfiguration(nil)
appEventsConfigurationProvider.firstCapturedBlock?()
serverConfigurationProvider.capturedCompletionBlock?(nil, nil)
@@ -1523,12 +1523,33 @@ class AppEventsTests: XCTestCase {
with: true
)
XCTAssertTrue(
TestAEMReporter.setCatalogReportEnabledWasCalled,
"Should enable or disable the catalog report"
TestAEMReporter.setCatalogMatchingEnabledWasCalled,
"Should enable or disable the Conversion Filtering"
)
XCTAssertTrue(
TestAEMReporter.capturedSetCatalogReportEnabled,
"AEM Catalog Report should be enabled"
TestAEMReporter.capturedConversionFilteringEnabled,
"AEM Conversion Filtering should be enabled"
)
}
}
func testFetchingConfigurationIncludingAEMCatalogMatching() {
if #available(iOS 14.0, *) {
featureManager.enable(feature: .aemCatalogMatching)
appEvents.fetchServerConfiguration(nil)
appEventsConfigurationProvider.firstCapturedBlock?()
serverConfigurationProvider.capturedCompletionBlock?(nil, nil)
featureManager.completeCheck(
forFeature: .AEM,
with: true
)
XCTAssertTrue(
TestAEMReporter.setCatalogMatchingEnabledWasCalled,
"Should enable or disable the Catalog Matching"
)
XCTAssertTrue(
TestAEMReporter.capturedCatalogMatchingEnabled,
"AEM Catalog Matching should be enabled"
)
}
}

View File

@@ -14,8 +14,10 @@ import UIKit
class TestAEMReporter: NSObject, AEMReporterProtocol {
static var enableWasCalled = false
static var setCatalogReportEnabledWasCalled = false
static var capturedSetCatalogReportEnabled = false
static var setConversionFilteringEnabledWasCalled = false
static var capturedConversionFilteringEnabled = false
static var setCatalogMatchingEnabledWasCalled = false
static var capturedCatalogMatchingEnabled = false
static var capturedEvent: String?
static var capturedCurrency: String?
static var capturedValue: NSNumber?
@@ -37,15 +39,22 @@ class TestAEMReporter: NSObject, AEMReporterProtocol {
capturedParameters = parameters
}
static func setCatalogReportEnabled(_ enabled: Bool) {
setCatalogReportEnabledWasCalled = true
capturedSetCatalogReportEnabled = enabled
static func setConversionFilteringEnabled(_ enabled: Bool) {
setConversionFilteringEnabledWasCalled = true
capturedConversionFilteringEnabled = enabled
}
static func setCatalogMatchingEnabled(_ enabled: Bool) {
setCatalogMatchingEnabledWasCalled = true
capturedCatalogMatchingEnabled = enabled
}
static func reset() {
enableWasCalled = false
setCatalogReportEnabledWasCalled = false
capturedSetCatalogReportEnabled = false
setConversionFilteringEnabledWasCalled = false
capturedConversionFilteringEnabled = false
setCatalogMatchingEnabledWasCalled = false
capturedCatalogMatchingEnabled = false
capturedEvent = nil
capturedCurrency = nil
capturedValue = nil

View File

@@ -226,7 +226,8 @@ FBAEMInvocationConfigMode FBAEMInvocationConfigCpasMode = @"CPAS";
for (FBAEMRule *rule in config.conversionValueRules) {
NSInteger priority = rule.priority;
if (
shouldBoostPriority
self.isConversionFilteringEligible
&& shouldBoostPriority
&& [rule containsEvent:event]
&& [self isOptimizedEvent:event config:config]
) {

View File

@@ -50,7 +50,8 @@ static NSString *const FBAEMHTTPMethodPOST = @"POST";
static BOOL g_isAEMReportEnabled = NO;
static BOOL g_isLoadingConfiguration = NO;
static BOOL g_isCatalogReportEnabled = NO;
static BOOL g_isConversionFilteringEnabled = NO;
static BOOL g_isCatalogMatchingEnabled = NO;
static dispatch_queue_t g_serialQueue;
static NSString *g_reportFile;
static NSString *g_configFile;
@@ -195,9 +196,14 @@ static id<FBSDKDataPersisting> _store;
}
}
+ (void)setCatalogReportEnabled:(BOOL)enabled
+ (void)setConversionFilteringEnabled:(BOOL)enabled
{
g_isCatalogReportEnabled = enabled;
g_isConversionFilteringEnabled = enabled;
}
+ (void)setCatalogMatchingEnabled:(BOOL)enabled
{
g_isCatalogMatchingEnabled = enabled;
}
+ (void)handleURL:(NSURL *)url
@@ -256,9 +262,10 @@ static id<FBSDKDataPersisting> _store;
FBAEMInvocation *attributedInvocation = [self _attributedInvocation:g_invocations Event:event currency:currency value:value parameters:parameters configs:g_configs];
if (attributedInvocation) {
// We will report conversion in catalog level if
// 1. invocation has catalog id
// 2. event is optimized
// 3. event's content id belongs to the catalog
// 1. conversion filtering and catalog matching are enabled
// 2. invocation has catalog id
// 3. event is optimized
// 4. event's content id belongs to the catalog
if ([self _shouldReportConversionInCatalogLevel:attributedInvocation event:event]) {
NSString *contentID = [FBAEMUtility.sharedUtility getContentID:parameters];
[self _loadCatalogOptimizationWithInvocation:attributedInvocation contentID:contentID block:^() {
@@ -274,7 +281,7 @@ static id<FBSDKDataPersisting> _store;
currency:currency
value:value
parameters:parameters
shouldBoostPriority:NO];
shouldBoostPriority:g_isConversionFilteringEnabled];
}
}
}];
@@ -421,7 +428,8 @@ static id<FBSDKDataPersisting> _store;
+ (BOOL)_shouldReportConversionInCatalogLevel:(FBAEMInvocation *)invocation
event:(NSString *)event
{
return g_isCatalogReportEnabled
return g_isConversionFilteringEnabled
&& g_isCatalogMatchingEnabled
&& invocation.catalogID
&& [invocation isOptimizedEvent:event configs:g_configs];
}
@@ -701,7 +709,7 @@ static id<FBSDKDataPersisting> _store;
[FBSDKTypeUtility dictionary:conversionParams setObject:invocation.ACSConfigID forKey:CONFIG_ID_KEY];
[FBSDKTypeUtility dictionary:conversionParams setObject:[invocation getHMAC:delay] forKey:HMAC_KEY];
[FBSDKTypeUtility dictionary:conversionParams setObject:invocation.businessID forKey:BUSINESS_ID_KEY];
[FBSDKTypeUtility dictionary:conversionParams setObject:@(invocation.isConversionFilteringEligible) forKey:IS_CONVERSION_FILTERING_KEY];
[FBSDKTypeUtility dictionary:conversionParams setObject:@(invocation.isConversionFilteringEligible && g_isConversionFilteringEnabled) forKey:IS_CONVERSION_FILTERING_KEY];
return [conversionParams copy];
}
@@ -832,14 +840,24 @@ static id<FBSDKDataPersisting> _store;
return g_isAEMReportEnabled;
}
+ (void)setIsCatalogReportEnabled:(BOOL)enabled
+ (void)setIsConversionFilteringEnabled:(BOOL)enabled
{
g_isCatalogReportEnabled = enabled;
g_isConversionFilteringEnabled = enabled;
}
+ (BOOL)isCatalogReportEnabled
+ (BOOL)isConversionFilteringEnabled
{
return g_isCatalogReportEnabled;
return g_isConversionFilteringEnabled;
}
+ (void)setIsCatalogMatchingEnabled:(BOOL)enabled
{
g_isCatalogMatchingEnabled = enabled;
}
+ (BOOL)isCatalogMatchingEnabled
{
return g_isCatalogMatchingEnabled;
}
+ (void)setCompletionBlocks:(NSMutableArray<FBAEMReporterBlock> *)completionBlocks
@@ -886,7 +904,8 @@ static id<FBSDKDataPersisting> _store;
{
g_isAEMReportEnabled = NO;
g_isLoadingConfiguration = NO;
g_isCatalogReportEnabled = NO;
g_isConversionFilteringEnabled = NO;
g_isCatalogMatchingEnabled = NO;
g_completionBlocks = [NSMutableArray new];
g_configs = [NSMutableDictionary new];
g_minAggregationRequestTimestamp = nil;

View File

@@ -57,11 +57,18 @@ NS_SWIFT_NAME(AEMReporter)
+ (void)enable;
/**
Control whether to enable catalog reporting
Control whether to enable conversion filtering
This function should be called in application(_:open:options:) from ApplicationDelegate
*/
+ (void)setCatalogReportEnabled:(BOOL)enabled;
+ (void)setConversionFilteringEnabled:(BOOL)enabled;
/**
Control whether to enable catalog matching
This function should be called in application(_:open:options:) from ApplicationDelegate
*/
+ (void)setCatalogMatchingEnabled:(BOOL)enabled;
/**
Handle deeplink