Skip to content

Commit 697cdb7

Browse files
authored
chore(tests): Add in app messaging testing infrastructure and tests (#1615)
* chore(tests): Add Swift `IAMIntegrationTests` file Add Swift `IAMIntegrationTests` test file and check for accessibility of `OSMessagingController` from the test file * nit: remove unused methods `getTriggerValueForKey` * no longer used, dead code * nit: remove methods from OSMessagingController header * Aren't called by anything so no need to be on the interface, these are called by the class itself. * Add description to `OSRequestGetInAppMessages` * Without a description, the object will return something like `<OSRequestGetInAppMessages: 0x600001798bc0>`. By adding a predictable description, we can operate on the object. * chore(tests): Add framework for OneSignalInAppMessagesMocks * Re-usable test helpers and mock functionality * Include own swiftlint file * ❗️ After `OneSignalInAppMessagesMocks` was created, I had to then manually "convert to group" or else the CI had build errors about the following: xcodebuild: error: Unable to read project 'OneSignal.xcodeproj' Reason: The project ‘OneSignal’ is damaged and cannot be opened. Examine the project file for invalid edits or unresolved source control conflicts. Exception: didn't find classname for 'isa' key * chore(tests): move `UIApplication+OneSignal` from OneSIgnal > OneSignalInAppMessages * This extension on `UIApplication` is only used in the `OneSignalInAppMessages` framework, so there is no need to keep it in the umbrella `OneSignalFramework` framework, which causes errors if only `OneSignalInAppMessages` is tested (without also importing OneSignalFramework). * chore(tests): Add ConsistencyManagerTestHelpers to tests * Has helper methods for repeating functionality * Add / migrate some existing IAM integration tests * Attempt to migrate `testDisablingIAMs_stillCreatesMessageQueue_butPreventsMessageDisplay` to new tests, but behavior has changed. It becomes `testPausingIAMs_doesNotCreateMessageQueue` * Migrate `testPreviewIAMIsDisplayedOnPause` * address PR feedback * `messageViewImpressionRequest` was removed from the `OSMessagingController` header file, so update `OSMessagingControllerOverrider` to expose it for internal usage. * Delete old tests that have been migrated
1 parent e557260 commit 697cdb7

17 files changed

+655
-56
lines changed

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 330 additions & 3 deletions
Large diffs are not rendered by default.

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,13 @@ NS_ASSUME_NONNULL_BEGIN
4949

5050
+ (OSMessagingController *)sharedInstance;
5151
+ (void)start;
52-
+ (void)removeInstance;
53-
- (void)presentInAppMessage:(OSInAppMessageInternal *)message;
5452
- (void)getInAppMessagesFromServer:(NSString * _Nullable)subscriptionId;
55-
- (void)messageViewImpressionRequest:(OSInAppMessageInternal *)message;
56-
- (void)messageViewPageImpressionRequest:(OSInAppMessageInternal *)message withPageId:(NSString *)pageId;
5753

5854
- (BOOL)isInAppMessagingPaused;
5955
- (void)setInAppMessagingPaused:(BOOL)pause;
6056
- (void)addTriggers:(NSDictionary<NSString *, id> *)triggers;
6157
- (void)removeTriggersForKeys:(NSArray<NSString *> *)keys;
6258
- (void)clearTriggers;
63-
- (NSDictionary<NSString *, id> *)getTriggers;
64-
- (id)getTriggerValueForKey:(NSString *)key;
6559

6660
- (void)addInAppMessageClickListener:(NSObject<OSInAppMessageClickListener> *_Nullable)listener;
6761
- (void)removeInAppMessageClickListener:(NSObject<OSInAppMessageClickListener> *_Nullable)listener;

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
*/
2727

2828
#import "OSMessagingController.h"
29-
#import "UIApplication+OneSignal.h" // Previously imported via "OneSignalHelper.h"
30-
#import "NSDateFormatter+OneSignal.h" // Previously imported via "OneSignalHelper.h"
29+
#import "UIApplication+OneSignal.h"
30+
#import "NSDateFormatter+OneSignal.h"
3131
#import <OneSignalCore/OneSignalCore.h>
3232
#import "OSInAppMessageClickResult.h"
3333
#import "OSInAppMessageClickEvent.h"
@@ -165,6 +165,7 @@ + (OSMessagingController *)sharedInstance {
165165
return sharedInstance;
166166
}
167167

168+
/// Note: This method is used in tests only.
168169
+ (void)removeInstance {
169170
sharedInstance = nil;
170171
once = 0;
@@ -815,10 +816,6 @@ - (void)clearTriggers {
815816
return self.triggerController.getTriggers;
816817
}
817818

818-
- (id)getTriggerValueForKey:(NSString *)key {
819-
return [self.triggerController getTriggerValueForKey:key];
820-
}
821-
822819
#pragma mark OSInAppMessageViewControllerDelegate Methods
823820
- (void)messageViewControllerDidDisplay:(OSInAppMessageInternal *)message {
824821
[self onDidDisplayInAppMessage:message];
@@ -1227,7 +1224,6 @@ - (void)addTriggers:(NSDictionary<NSString *, id> *)triggers {}
12271224
- (void)removeTriggersForKeys:(NSArray<NSString *> *)keys {}
12281225
- (void)clearTriggers {}
12291226
- (NSDictionary<NSString *, id> *)getTriggers { return @{}; }
1230-
- (id)getTriggerValueForKey:(NSString *)key { return 0; }
12311227
#pragma mark OSInAppMessageViewControllerDelegate Methods
12321228
- (void)messageViewControllerWasDismissed {}
12331229
- (void)messageViewDidSelectAction:(OSInAppMessageInternal *)message withAction:(OSInAppMessageClickResult *)action {}

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSTriggerController.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ NS_ASSUME_NONNULL_BEGIN
5252
- (void)addTriggers:(NSDictionary<NSString *, id> *)triggers;
5353
- (void)removeTriggersForKeys:(NSArray<NSString *> *)keys;
5454
- (NSDictionary<NSString *, id> *)getTriggers;
55-
- (id)getTriggerValueForKey:(NSString *)key;
5655
- (void)timeSinceLastMessage:(NSDate *)date;
5756

5857
@end

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSTriggerController.m

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,6 @@ - (void)removeTriggersForKeys:(NSArray<NSString *> *)keys {
6969
}
7070
}
7171

72-
- (id)getTriggerValueForKey:(NSString *)key {
73-
@synchronized (self.triggers) {
74-
return self.triggers[key];
75-
}
76-
}
77-
7872
/*
7973
* Part of redisplay logic
8074
*

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Requests/OSInAppMessagingRequests.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ of this software and associated documentation files (the "Software"), to deal
2828
#import "OSInAppMessagingRequests.h"
2929

3030
@implementation OSRequestGetInAppMessages
31+
- (NSString *)description {
32+
return [NSString stringWithFormat:@"<OSRequestGetInAppMessages from %@>", self.path];
33+
}
34+
3135
+ (instancetype _Nonnull) withSubscriptionId:(NSString * _Nonnull)subscriptionId
3236
withSessionDuration:(NSNumber * _Nonnull)sessionDuration
3337
withRetryCount:(NSNumber *)retryCount

iOS_SDK/OneSignalSDK/Source/UIApplication+OneSignal.h renamed to iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UIApplication+OneSignal.h

File renamed without changes.

iOS_SDK/OneSignalSDK/Source/UIApplication+OneSignal.m renamed to iOS_SDK/OneSignalSDK/OneSignalInAppMessages/UIApplication+OneSignal.m

File renamed without changes.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
disabled_rules:
2+
- identifier_name
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
Modified MIT License
3+
4+
Copyright 2025 OneSignal
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
1. The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
2. All copies of substantial portions of the Software may only be used in connection
17+
with services provided by OneSignal.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
*/
27+
28+
import Foundation
29+
import OneSignalInAppMessages
30+
31+
let OS_TEST_MESSAGE_ID = "a4b3gj7f-d8cc-11e4-bed1-df8f05be55ba"
32+
let OS_TEST_MESSAGE_VARIANT_ID = "m8dh7234f-d8cc-11e4-bed1-df8f05be55ba"
33+
let OS_TEST_ENGLISH_VARIANT_ID = "11e4-bed1-df8f05be55ba-m8dh7234f-d8cc"
34+
35+
let OS_DUMMY_HTML = "<html><h1>Hello World</h1></html>"
36+
37+
@objc
38+
public class IAMTestHelpers: NSObject {
39+
40+
nonisolated(unsafe) static var messageIdIncrementer = 0
41+
42+
/// Convert OSTriggerOperatorType enum to string
43+
private static func OS_OPERATOR_TO_STRING(_ type: Int32) -> String {
44+
// Trigger operator strings
45+
let OS_OPERATOR_STRINGS: [String] = [
46+
"greater",
47+
"less",
48+
"equal",
49+
"not_equal",
50+
"less_or_equal",
51+
"greater_or_equal",
52+
"exists",
53+
"not_exists",
54+
"in"
55+
]
56+
57+
return OS_OPERATOR_STRINGS[Int(type)]
58+
}
59+
60+
/// Returns the JSON of a minimal in-app message that can be used as a building block.
61+
@objc
62+
public static func testDefaultMessageJson() -> [String: Any] {
63+
messageIdIncrementer += 1
64+
return [
65+
"id": String(format: "%@_%i", OS_TEST_MESSAGE_ID, messageIdIncrementer),
66+
"variants": [
67+
"ios": [
68+
"default": OS_TEST_MESSAGE_VARIANT_ID,
69+
"en": OS_TEST_ENGLISH_VARIANT_ID
70+
],
71+
"all": [
72+
"default": "should_never_be_used_by_any_test"
73+
]
74+
],
75+
"triggers": []
76+
]
77+
}
78+
79+
/// Returns the JSON of an in-app message with trigger.
80+
@objc
81+
public static func testMessageJsonWithTrigger(property: String, triggerId: String, type: Int32, value: Any) -> [String: Any] {
82+
var testMessage = self.testDefaultMessageJson()
83+
84+
testMessage["triggers"] = [
85+
[
86+
[
87+
"kind": property,
88+
"property": property,
89+
"operator": OS_OPERATOR_TO_STRING(type),
90+
"value": value,
91+
"id": triggerId
92+
]
93+
]
94+
]
95+
return testMessage
96+
}
97+
98+
@objc
99+
public static func testFetchMessagesResponse(messages: [[String: Any]]) -> [String: Any] {
100+
return [
101+
"in_app_messages": messages
102+
]
103+
}
104+
105+
/// Returns the JSON of a preview or test in-app message.
106+
@objc
107+
public static func testMessagePreviewJson() -> [String: Any] {
108+
var message = self.testDefaultMessageJson()
109+
message["is_preview"] = true
110+
return message
111+
}
112+
}

0 commit comments

Comments
 (0)