From 2e591de858d03daca6f03f28c83a0bf83e3a597b Mon Sep 17 00:00:00 2001 From: Nan Date: Thu, 27 Jun 2024 14:47:13 -0700 Subject: [PATCH 1/3] Make null values safe for IAM request payload * If subscription ID (most common) or other properties such as app ID are `nil`, the app crashes when requests for IAM impressions or clicks are created. * The app will crash with Exception `[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]` * Use a null-safe dictionary that will omit the entry if the value is null * We choose to send these requests so we have record of 400-ing requests --- .../Requests/OSInAppMessagingRequests.m | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Requests/OSInAppMessagingRequests.m b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Requests/OSInAppMessagingRequests.m index 159b3ebab..6f837a243 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Requests/OSInAppMessagingRequests.m +++ b/iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Requests/OSInAppMessagingRequests.m @@ -44,13 +44,13 @@ + (instancetype _Nonnull)withAppId:(NSString * _Nonnull)appId forVariantId:(NSString *)variantId { let request = [OSRequestInAppMessageViewed new]; - request.parameters = @{ - @"device_type": @0, - @"player_id": playerId, - @"app_id": appId, - @"variant_id": variantId - }; + let params = [NSMutableDictionary new]; + params[@"device_type"] = @0; + params[@"player_id"] = playerId; + params[@"app_id"] = appId; + params[@"variant_id"] = variantId; + request.parameters = params; request.method = POST; request.path = [NSString stringWithFormat:@"in_app_messages/%@/impression", messageId]; @@ -66,14 +66,14 @@ + (instancetype _Nonnull)withAppId:(NSString * _Nonnull)appId forVariantId:(NSString *)variantId { let request = [OSRequestInAppMessagePageViewed new]; - request.parameters = @{ - @"device_type": @0, - @"player_id": playerId, - @"app_id": appId, - @"variant_id": variantId, - @"page_id": pageId - }; + let params = [NSMutableDictionary new]; + params[@"device_type"] = @0; + params[@"player_id"] = playerId; + params[@"app_id"] = appId; + params[@"variant_id"] = variantId; + params[@"page_id"] = pageId; + request.parameters = params; request.method = POST; request.path = [NSString stringWithFormat:@"in_app_messages/%@/pageImpression", messageId]; @@ -89,15 +89,15 @@ + (instancetype _Nonnull)withAppId:(NSString * _Nonnull)appId withAction:(OSInAppMessageClickResult * _Nonnull)action { let request = [OSRequestInAppMessageClicked new]; - request.parameters = @{ - @"app_id": appId, - @"device_type": @0, - @"player_id": playerId, - @"click_id": action.clickId ?: @"", - @"variant_id": variantId, - @"first_click": @(action.firstClick) - }; + let params = [NSMutableDictionary new]; + params[@"app_id"] = appId; + params[@"device_type"] = @0; + params[@"player_id"] = playerId; + params[@"click_id"] = action.clickId ?: @""; + params[@"variant_id"] = variantId; + params[@"first_click"] = @(action.firstClick); + request.parameters = params; request.method = POST; request.path = [NSString stringWithFormat:@"in_app_messages/%@/click", messageId]; From fcf9496e0dc7f86aa9a7a43502e4e497a3b149c7 Mon Sep 17 00:00:00 2001 From: Nan Date: Thu, 27 Jun 2024 16:18:49 -0700 Subject: [PATCH 2/3] [tests] Add IAM Request tests * Add test module for In App Messages * Add request tests for In App Messages including when some properties can be null * And port over 2 existing IAM request tests --- .../OneSignal.xcodeproj/project.pbxproj | 248 +++++++++++++++++- .../xcschemes/UnitTestApp.xcscheme | 10 + .../IAMRequestTests.m | 182 +++++++++++++ .../OneSignalInAppMessagesTests.swift | 33 +++ iOS_SDK/OneSignalSDK/UnitTests/RequestTests.m | 33 --- 5 files changed, 472 insertions(+), 34 deletions(-) create mode 100644 iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/IAMRequestTests.m create mode 100644 iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift diff --git a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj index 7502651c7..25e2775eb 100644 --- a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj +++ b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj @@ -53,6 +53,9 @@ 03E56DD328405F4A006AA1DA /* OneSignalAppDelegateOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = 03E56DD228405F4A006AA1DA /* OneSignalAppDelegateOverrider.m */; }; 16664C4C25DDB195003B8A14 /* NSTimeZoneOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = 16664C4B25DDB195003B8A14 /* NSTimeZoneOverrider.m */; }; 37E6B2BB19D9CAF300D0C601 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E6B2BA19D9CAF300D0C601 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 3C0151912C2E298F0079E076 /* OneSignalInAppMessagesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */; }; + 3C0151922C2E298F0079E076 /* OneSignalInAppMessages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEBAAE282A4211D900BF2C1C /* OneSignalInAppMessages.framework */; }; + 3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */; }; 3C0EF49E28A1DBCB00E5434B /* OSUserInternalImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */; }; 3C115165289A259500565C41 /* OneSignalOSCore.docc in Sources */ = {isa = PBXBuildFile; fileRef = 3C115164289A259500565C41 /* OneSignalOSCore.docc */; }; 3C115171289A259500565C41 /* OneSignalOSCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C115163289A259500565C41 /* OneSignalOSCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -587,6 +590,20 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 3C0151932C2E298F0079E076 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 37747F8B19147D6400558FAD /* Project object */; + proxyType = 1; + remoteGlobalIDString = DEBAAE272A4211D900BF2C1C; + remoteInfo = OneSignalInAppMessages; + }; + 3C0151992C2E29AC0079E076 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 37747F8B19147D6400558FAD /* Project object */; + proxyType = 1; + remoteGlobalIDString = DEF5CCF02539321A0003E9CC; + remoteInfo = UnitTestApp; + }; 3C115194289AF85400565C41 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 37747F8B19147D6400558FAD /* Project object */; @@ -1156,6 +1173,9 @@ 1AF75EAD1E8567FD0097B315 /* NSString+OneSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+OneSignal.m"; sourceTree = ""; }; 37747F9319147D6500558FAD /* libOneSignal.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOneSignal.a; sourceTree = BUILT_PRODUCTS_DIR; }; 37E6B2BA19D9CAF300D0C601 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 3C01518E2C2E298E0079E076 /* OneSignalInAppMessagesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OneSignalInAppMessagesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneSignalInAppMessagesTests.swift; sourceTree = ""; }; + 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IAMRequestTests.m; sourceTree = ""; }; 3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSUserInternalImpl.swift; sourceTree = ""; }; 3C115161289A259500565C41 /* OneSignalOSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OneSignalOSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3C115163289A259500565C41 /* OneSignalOSCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalOSCore.h; sourceTree = ""; }; @@ -1613,6 +1633,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3C01518B2C2E298E0079E076 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3C0151922C2E298F0079E076 /* OneSignalInAppMessages.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3C11515E289A259500565C41 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1889,6 +1917,7 @@ 3CC063DE2B6D7F2A002BB07F /* OneSignalUserMocks */, 3CC063A52B6D7A8E002BB07F /* OneSignalCoreTests */, 3CC063EC2B6D7FE8002BB07F /* OneSignalUserTests */, + 3C01518F2C2E298F0079E076 /* OneSignalInAppMessagesTests */, 4735424B2B8F93340016DB4C /* OneSignalLiveActivitiesTests */, 37747F9419147D6500558FAD /* Products */, ); @@ -1916,6 +1945,7 @@ 475F471E2B8E398D00EC05B3 /* OneSignalLiveActivities.framework */, 4735424A2B8F93330016DB4C /* OneSignalLiveActivitiesTests.xctest */, DEBA2A1A2C20E35E00E234DB /* OneSignalNotificationsTests.xctest */, + 3C01518E2C2E298E0079E076 /* OneSignalInAppMessagesTests.xctest */, ); name = Products; sourceTree = ""; @@ -1948,6 +1978,15 @@ name = Frameworks; sourceTree = ""; }; + 3C01518F2C2E298F0079E076 /* OneSignalInAppMessagesTests */ = { + isa = PBXGroup; + children = ( + 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */, + 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */, + ); + path = OneSignalInAppMessagesTests; + sourceTree = ""; + }; 3C115162289A259500565C41 /* OneSignalOSCore */ = { isa = PBXGroup; children = ( @@ -3078,6 +3117,25 @@ productReference = 37747F9319147D6500558FAD /* libOneSignal.a */; productType = "com.apple.product-type.library.static"; }; + 3C01518D2C2E298E0079E076 /* OneSignalInAppMessagesTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3C0151982C2E298F0079E076 /* Build configuration list for PBXNativeTarget "OneSignalInAppMessagesTests" */; + buildPhases = ( + 3C01518A2C2E298E0079E076 /* Sources */, + 3C01518B2C2E298E0079E076 /* Frameworks */, + 3C01518C2C2E298E0079E076 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3C0151942C2E298F0079E076 /* PBXTargetDependency */, + 3C01519A2C2E29AC0079E076 /* PBXTargetDependency */, + ); + name = OneSignalInAppMessagesTests; + productName = OneSignalInAppMessagesTests; + productReference = 3C01518E2C2E298E0079E076 /* OneSignalInAppMessagesTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 3C115160289A259500565C41 /* OneSignalOSCore */ = { isa = PBXNativeTarget; buildConfigurationList = 3C115172289A259500565C41 /* Build configuration list for PBXNativeTarget "OneSignalOSCore" */; @@ -3471,13 +3529,18 @@ 37747F8B19147D6400558FAD /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1600; + LastSwiftUpdateCheck = 1520; LastUpgradeCheck = 0800; ORGANIZATIONNAME = Hiptic; TargetAttributes = { 37747F9219147D6500558FAD = { LastSwiftMigration = 1410; }; + 3C01518D2C2E298E0079E076 = { + CreatedOnToolsVersion = 15.2; + LastSwiftMigration = 1520; + TestTargetID = DEF5CCF02539321A0003E9CC; + }; 3C115160289A259500565C41 = { CreatedOnToolsVersion = 13.2.1; DevelopmentTeam = 99SW8E36CT; @@ -3631,11 +3694,19 @@ 3CC063EA2B6D7FE8002BB07F /* OneSignalUserTests */, 473542492B8F93330016DB4C /* OneSignalLiveActivitiesTests */, DEBA2A192C20E35E00E234DB /* OneSignalNotificationsTests */, + 3C01518D2C2E298E0079E076 /* OneSignalInAppMessagesTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 3C01518C2C2E298E0079E076 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3C11515F289A259500565C41 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -3849,6 +3920,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3C01518A2C2E298E0079E076 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3C0151912C2E298F0079E076 /* OneSignalInAppMessagesTests.swift in Sources */, + 3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3C11515D289A259500565C41 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4236,6 +4316,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 3C0151942C2E298F0079E076 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DEBAAE272A4211D900BF2C1C /* OneSignalInAppMessages */; + targetProxy = 3C0151932C2E298F0079E076 /* PBXContainerItemProxy */; + }; + 3C01519A2C2E29AC0079E076 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DEF5CCF02539321A0003E9CC /* UnitTestApp */; + targetProxy = 3C0151992C2E29AC0079E076 /* PBXContainerItemProxy */; + }; 3C115195289AF85400565C41 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DE7D17E527026B95002D3A5D /* OneSignalCore */; @@ -4569,6 +4659,152 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 3C0151952C2E298F0079E076 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 99SW8E36CT; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.OneSignalInAppMessagesTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UnitTestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/UnitTestApp"; + }; + name = Release; + }; + 3C0151962C2E298F0079E076 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 99SW8E36CT; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.OneSignalInAppMessagesTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UnitTestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/UnitTestApp"; + }; + name = Debug; + }; + 3C0151972C2E298F0079E076 /* Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 99SW8E36CT; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.OneSignalInAppMessagesTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UnitTestApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/UnitTestApp"; + }; + name = Test; + }; 3C115173289A259500565C41 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -8008,6 +8244,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 3C0151982C2E298F0079E076 /* Build configuration list for PBXNativeTarget "OneSignalInAppMessagesTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3C0151952C2E298F0079E076 /* Release */, + 3C0151962C2E298F0079E076 /* Debug */, + 3C0151972C2E298F0079E076 /* Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 3C115172289A259500565C41 /* Build configuration list for PBXNativeTarget "OneSignalOSCore" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/xcshareddata/xcschemes/UnitTestApp.xcscheme b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/xcshareddata/xcschemes/UnitTestApp.xcscheme index 94f60e4de..3a019bd92 100644 --- a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/xcshareddata/xcschemes/UnitTestApp.xcscheme +++ b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/xcshareddata/xcschemes/UnitTestApp.xcscheme @@ -194,6 +194,16 @@ ReferencedContainer = "container:OneSignal.xcodeproj"> + + + + +#import "OSInAppMessageBridgeEvent.h" +#import "OSInAppMessagingRequests.h" + +@interface IAMRequestTests : XCTestCase + +@end + +@implementation IAMRequestTests { + NSString *testAppId; + NSString *testSubscriptionId; + NSString *testMessageId; + NSString *testVariantId; + NSString *testPageId; + OSInAppMessageBridgeEvent *testBridgeEvent; + OSInAppMessageClickResult *testClickResult; +} + +- (void)setUp { + testAppId = @"test_app_id"; + testSubscriptionId = @"test_subscription_id"; + testMessageId = @"test_message_id"; + testVariantId = @"test_in_app_message_variant_id"; + testPageId = @"test_page_id"; + testBridgeEvent = [OSInAppMessageBridgeEvent instanceWithJson:@{ + @"type" : @"action_taken", + @"body" : @{ + @"id" : @"test_id", + @"url" : @"https://www.onesignal.com", + @"url_target" : @"browser", + @"close" : @false + } + }]; + + testClickResult = testBridgeEvent.userAction; + testClickResult.firstClick = true; +} + +- (void)tearDown { } + +NSString *correctUrlWithPath(NSString *path) { + return [OS_API_SERVER_URL stringByAppendingString:path]; +} + +BOOL checkHttpBody(NSData *bodyData, NSDictionary *correct) { + NSError *error; + NSDictionary *serialized = [NSJSONSerialization JSONObjectWithData:bodyData options:NSJSONReadingAllowFragments error:&error]; + + if (error) { + return false; + } + + return [serialized isEqualToDictionary:correct]; +} + +- (void)testInAppMessageViewed { + OSRequestInAppMessageViewed *request = [OSRequestInAppMessageViewed + withAppId:testAppId + withPlayerId:testSubscriptionId + withMessageId:testMessageId + forVariantId:testVariantId]; + NSString *correctUrl = correctUrlWithPath([NSString stringWithFormat:@"in_app_messages/%@/impression", testMessageId]); + + XCTAssertEqualObjects(correctUrl, request.urlRequest.URL.absoluteString); + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"device_type": @0, + @"player_id": testSubscriptionId, + @"app_id": testAppId, + @"variant_id": testVariantId + })); +} + +- (void)testInAppMessageViewed_withNilArguments { + OSRequestInAppMessageViewed *request = [OSRequestInAppMessageViewed + withAppId:testAppId + withPlayerId:nil + withMessageId:testMessageId + forVariantId:nil]; + + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"device_type": @0, + @"app_id": testAppId + })); +} + +- (void)testInAppMessagePageViewed { + OSRequestInAppMessagePageViewed *request = [OSRequestInAppMessagePageViewed + withAppId:testAppId + withPlayerId:testSubscriptionId + withMessageId:testMessageId + withPageId:testPageId + forVariantId:testVariantId]; + NSString *correctUrl = correctUrlWithPath([NSString stringWithFormat:@"in_app_messages/%@/pageImpression", testMessageId]); + + XCTAssertEqualObjects(correctUrl, request.urlRequest.URL.absoluteString); + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"device_type": @0, + @"player_id": testSubscriptionId, + @"app_id": testAppId, + @"variant_id": testVariantId, + @"page_id": testPageId + })); +} + +- (void)testInAppMessagePageViewed_withNilArguments { + OSRequestInAppMessagePageViewed *request = [OSRequestInAppMessagePageViewed + withAppId:testAppId + withPlayerId:nil + withMessageId:testMessageId + withPageId:nil + forVariantId:nil]; + + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"device_type": @0, + @"app_id": testAppId, + })); +} + +- (void)testInAppMessageClicked { + OSRequestInAppMessageClicked *request = [OSRequestInAppMessageClicked + withAppId:testAppId + withPlayerId:testSubscriptionId + withMessageId:testMessageId + forVariantId:testVariantId + withAction:testClickResult]; + NSString *correctUrl = correctUrlWithPath([NSString stringWithFormat:@"in_app_messages/%@/click", testMessageId]); + + XCTAssertEqualObjects(correctUrl, request.urlRequest.URL.absoluteString); + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"app_id": testAppId, + @"device_type": @0, + @"player_id": testSubscriptionId, + @"click_id": testClickResult.clickId ?: @"", + @"variant_id": testVariantId, + @"first_click": @(testClickResult.firstClick) + })); +} + +- (void)testInAppMessageClicked_withNilArguments { + OSRequestInAppMessageClicked *request = [OSRequestInAppMessageClicked + withAppId:testAppId + withPlayerId:nil + withMessageId:testMessageId + forVariantId:nil + withAction:testClickResult]; + + XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ + @"app_id": testAppId, + @"device_type": @0, + @"click_id": testClickResult.clickId ?: @"", + @"first_click": @(testClickResult.firstClick) + })); +} + +@end diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift b/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift new file mode 100644 index 000000000..333c325ae --- /dev/null +++ b/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift @@ -0,0 +1,33 @@ +/* + Modified MIT License + + Copyright 2024 OneSignal + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + 1. The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + 2. All copies of substantial portions of the Software may only be used in connection +with services provided by OneSignal. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +import XCTest + +final class OneSignalInAppMessagesTests: XCTestCase { + override func setUpWithError() throws { } + override func tearDownWithError() throws { } +} diff --git a/iOS_SDK/OneSignalSDK/UnitTests/RequestTests.m b/iOS_SDK/OneSignalSDK/UnitTests/RequestTests.m index 7cc3e3241..ee20685dc 100644 --- a/iOS_SDK/OneSignalSDK/UnitTests/RequestTests.m +++ b/iOS_SDK/OneSignalSDK/UnitTests/RequestTests.m @@ -674,39 +674,6 @@ of this software and associated documentation files (the "Software"), to deal // XCTAssertTrue(checkHttpBody(secondRequest.urlRequest.HTTPBody, @{@"app_id" : testAppId, @"state" : @"ping", @"type" : @1, @"active_time" : @2, @"net_type" : @3, @"device_type" : testDeviceType, @"direct" : @NO, @"notification_ids": testNotificationIds})); //} // -//- (void)testInAppMessageViewed { -// let request = [OSRequestInAppMessageViewed withAppId:testAppId withPlayerId:testUserId withMessageId:testInAppMessageId forVariantId:testInAppMessageVariantId]; -// let correctUrl = correctUrlWithPath([NSString stringWithFormat:@"in_app_messages/%@/impression", testInAppMessageId]); -// -// XCTAssertEqualObjects(correctUrl, request.urlRequest.URL.absoluteString); -// XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ -// @"device_type": @0, -// @"player_id": testUserId, -// @"app_id": testAppId, -// @"variant_id": testInAppMessageVariantId -// })); -//} -// -//- (void)testInAppMessageClicked { -// let request = [OSRequestInAppMessageClicked -// withAppId:testAppId -// withPlayerId:testUserId -// withMessageId:testInAppMessageId -// forVariantId:testInAppMessageVariantId -// withAction:testAction]; -// let correctUrl = correctUrlWithPath([NSString stringWithFormat:@"in_app_messages/%@/click", testInAppMessageId]); -// -// XCTAssertEqualObjects(correctUrl, request.urlRequest.URL.absoluteString); -// XCTAssertTrue(checkHttpBody(request.urlRequest.HTTPBody, @{ -// @"app_id": testAppId, -// @"device_type": @0, -// @"player_id": testUserId, -// @"click_id": testAction.clickId ?: @"", -// @"variant_id": testInAppMessageVariantId, -// @"first_click": @(testAction.firstClick) -// })); -//} -// //- (void)testLoadMessageContent { // [UnitTestCommonMethods initOneSignal]; // From f8b8c65dbf49b914a36215141f1b50ab50043db3 Mon Sep 17 00:00:00 2001 From: Nan Date: Fri, 28 Jun 2024 12:24:01 -0700 Subject: [PATCH 3/3] remove extraneous file OneSignalInAppMessagesTests.swift --- .../OneSignal.xcodeproj/project.pbxproj | 4 --- .../OneSignalInAppMessagesTests.swift | 33 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift diff --git a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj index 25e2775eb..56c2f8466 100644 --- a/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj +++ b/iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj @@ -53,7 +53,6 @@ 03E56DD328405F4A006AA1DA /* OneSignalAppDelegateOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = 03E56DD228405F4A006AA1DA /* OneSignalAppDelegateOverrider.m */; }; 16664C4C25DDB195003B8A14 /* NSTimeZoneOverrider.m in Sources */ = {isa = PBXBuildFile; fileRef = 16664C4B25DDB195003B8A14 /* NSTimeZoneOverrider.m */; }; 37E6B2BB19D9CAF300D0C601 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37E6B2BA19D9CAF300D0C601 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 3C0151912C2E298F0079E076 /* OneSignalInAppMessagesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */; }; 3C0151922C2E298F0079E076 /* OneSignalInAppMessages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEBAAE282A4211D900BF2C1C /* OneSignalInAppMessages.framework */; }; 3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */; }; 3C0EF49E28A1DBCB00E5434B /* OSUserInternalImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */; }; @@ -1174,7 +1173,6 @@ 37747F9319147D6500558FAD /* libOneSignal.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOneSignal.a; sourceTree = BUILT_PRODUCTS_DIR; }; 37E6B2BA19D9CAF300D0C601 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 3C01518E2C2E298E0079E076 /* OneSignalInAppMessagesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OneSignalInAppMessagesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OneSignalInAppMessagesTests.swift; sourceTree = ""; }; 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = IAMRequestTests.m; sourceTree = ""; }; 3C0EF49D28A1DBCB00E5434B /* OSUserInternalImpl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSUserInternalImpl.swift; sourceTree = ""; }; 3C115161289A259500565C41 /* OneSignalOSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OneSignalOSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1981,7 +1979,6 @@ 3C01518F2C2E298F0079E076 /* OneSignalInAppMessagesTests */ = { isa = PBXGroup; children = ( - 3C0151902C2E298F0079E076 /* OneSignalInAppMessagesTests.swift */, 3C01519B2C2E29F90079E076 /* IAMRequestTests.m */, ); path = OneSignalInAppMessagesTests; @@ -3924,7 +3921,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3C0151912C2E298F0079E076 /* OneSignalInAppMessagesTests.swift in Sources */, 3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift b/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift deleted file mode 100644 index 333c325ae..000000000 --- a/iOS_SDK/OneSignalSDK/OneSignalInAppMessagesTests/OneSignalInAppMessagesTests.swift +++ /dev/null @@ -1,33 +0,0 @@ -/* - Modified MIT License - - Copyright 2024 OneSignal - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - 1. The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - 2. All copies of substantial portions of the Software may only be used in connection -with services provided by OneSignal. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ - -import XCTest - -final class OneSignalInAppMessagesTests: XCTestCase { - override func setUpWithError() throws { } - override func tearDownWithError() throws { } -}