-
Notifications
You must be signed in to change notification settings - Fork 16
/
AutomaticPushDeliveredAppInForegroundTest.swift
186 lines (135 loc) · 7.64 KB
/
AutomaticPushDeliveredAppInForegroundTest.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
@testable import CioInternalCommon
@testable import CioMessagingPush
import Foundation
import SharedTests
import XCTest
// When a push is delivered to an iOS device and the app is in the foreground, iOS gives the app the option to either display that push or to not display that push.
class AutomaticPushDeliveredAppInForegrondTest: IntegrationTest {
private var pushEventHandler: PushEventHandler!
private let pushClickHandler = PushClickHandlerMock()
private let pushEventHandlerProxy = PushEventHandlerProxyImpl()
// MARK: SDK configuration behavior
func test_givenCioPushDelivered_givenSdkConfigDisplayPush_expectPushDisplayed() {
configureSdk(shouldDisplayPushAppInForeground: true)
let givenPush = PushNotificationStub.getPushSentFromCIO()
let didPushGetDisplayed = deliverPush(givenPush)
XCTAssertEqual(didPushGetDisplayed, true)
}
func test_givenCioPushDelivered_givenSdkConfigDoNotDisplayPush_expectPushNotDisplayed() {
configureSdk(shouldDisplayPushAppInForeground: false)
let givenPush = PushNotificationStub.getPushSentFromCIO()
let didPushGetDisplayed = deliverPush(givenPush)
XCTAssertEqual(didPushGetDisplayed, false)
}
// MARK: cio SDK only push event handler in app
func test_givenCioOnlyPushHandler_givenNonCioPushDelivered_expectHandleEvent() {
configureSdk(shouldDisplayPushAppInForeground: true)
let givenPush = PushNotificationStub.getPushNotSentFromCIO()
let didPushGetDisplayed = deliverPush(givenPush)
XCTAssertEqual(didPushGetDisplayed, true)
}
// MARK: multiple push handlers in app
func test_givenOtherPushHandlers_givenNonCioPushDelivered_expectHandleEvent() {
configureSdk(shouldDisplayPushAppInForeground: false)
let givenPush = PushNotificationStub.getPushNotSentFromCIO()
var otherPushHandlerCalled = false
let givenOtherPushHandler = PushEventHandlerMock()
givenOtherPushHandler.shouldDisplayPushAppInForegroundClosure = { _, onComplete in
otherPushHandlerCalled = true
onComplete(true)
}
addOtherPushEventHandler(givenOtherPushHandler)
_ = deliverPush(givenPush)
XCTAssertTrue(otherPushHandlerCalled)
}
func test_givenOtherPushHandlers_givenCioPushDelivered_expectOtherPushHandlerGetsCallback_expectIgnoreResultOfOtherHandler() {
configureSdk(shouldDisplayPushAppInForeground: true)
let givenPush = PushNotificationStub.getPushSentFromCIO()
let expectOtherPushHandlerCallbackCalled = expectation(description: "Expect other push handler callback called")
let givenOtherPushHandler = PushEventHandlerMock()
givenOtherPushHandler.shouldDisplayPushAppInForegroundClosure = { _, onComplete in
// We expect that other push handler gets callback of push event from CIO push
expectOtherPushHandlerCallbackCalled.fulfill()
// We expect that this return result is ignored. The CIO SDK config setting is used instead.
onComplete(false)
}
addOtherPushEventHandler(givenOtherPushHandler)
let didPushGetDisplayed = deliverPush(givenPush)
waitForExpectations()
// Check that the decision to display push was determined by SDK config and not from the return result of 3rd party callback.
XCTAssertEqual(didPushGetDisplayed, true)
}
// Important to test that 2+ 3rd party push handlers for some use cases.
func test_givenMultiplePushHandlers_givenCioPushDelivered_expectOtherPushHandlersGetCallback() {
configureSdk(shouldDisplayPushAppInForeground: true)
let givenPush = PushNotificationStub.getPushSentFromCIO()
let expectOtherPushHandlerCallbackCalled = expectation(description: "Expect other push handler callback called")
expectOtherPushHandlerCallbackCalled.expectedFulfillmentCount = 2
// In order to add 2+ push handlers to SDK, each class needs to have a unique name.
// The SDK only accepts unique push event handlers. Creating this class makes each push handler unique.
class PushEventHandlerMock2: PushEventHandlerMock {}
let givenOtherPushHandler1 = PushEventHandlerMock()
let givenOtherPushHandler2 = PushEventHandlerMock2()
givenOtherPushHandler1.shouldDisplayPushAppInForegroundClosure = { _, onComplete in
expectOtherPushHandlerCallbackCalled.fulfill()
onComplete(true)
}
givenOtherPushHandler2.shouldDisplayPushAppInForegroundClosure = { _, onComplete in
expectOtherPushHandlerCallbackCalled.fulfill()
onComplete(true)
}
addOtherPushEventHandler(givenOtherPushHandler1)
addOtherPushEventHandler(givenOtherPushHandler2)
_ = deliverPush(givenPush)
waitForExpectations()
}
// MARK: completion handler
func test_givenMultiplePushHandlers_givenCioPushDelivered_givenOtherPushHandlerDoesNotCallCompletionHandler_expectCompletionHandlerDoesNotGetCalled() {
configureSdk(shouldDisplayPushAppInForeground: true)
let expectOtherClickHandlerToGetCallback = expectation(description: "Receive a callback")
let givenPush = PushNotificationStub.getPushSentFromCIO()
let givenOtherPushHandler = PushEventHandlerMock()
givenOtherPushHandler.shouldDisplayPushAppInForegroundClosure = { _, _ in
// Do not call completion handler.
expectOtherClickHandlerToGetCallback.fulfill()
}
addOtherPushEventHandler(givenOtherPushHandler)
let didPushGetDisplayed = deliverPush(givenPush, expectToCallCompletionHandler: false)
waitForExpectations(for: [expectOtherClickHandlerToGetCallback])
// nil result means that completionHandler never got called and returned a result.
XCTAssertNil(didPushGetDisplayed)
}
}
extension AutomaticPushDeliveredAppInForegrondTest {
private func configureSdk(shouldDisplayPushAppInForeground: Bool) {
var pushModuleConfig = MessagingPushConfigOptions()
pushModuleConfig.showPushAppInForeground = shouldDisplayPushAppInForeground
pushEventHandler = IOSPushEventListener(
jsonAdapter: diGraph.jsonAdapter,
pushEventHandlerProxy: pushEventHandlerProxy,
moduleConfig: pushModuleConfig,
pushClickHandler: pushClickHandler,
pushHistory: diGraph.pushHistory,
logger: diGraph.logger
)
}
func deliverPush(_ push: PushNotification, expectToCallCompletionHandler: Bool = true) -> Bool? {
// Note: It's important that we test that the `withContentHandler` callback function gets called either by our SDK (when we handle it), or the 3rd party handler.
let expectCompletionHandlerCalled = expectation(description: "Expect completion handler called by a handler")
if expectToCallCompletionHandler {
expectCompletionHandlerCalled.expectedFulfillmentCount = 1 // Test will fail if called 2+ times which could indicate a bug because only 1 push click handler should be calling it.
} else {
expectCompletionHandlerCalled.isInverted = true
}
var returnValueFromPushHandler: Bool?
pushEventHandler.shouldDisplayPushAppInForeground(push) { shouldDisplayPush in
returnValueFromPushHandler = shouldDisplayPush
expectCompletionHandlerCalled.fulfill()
}
waitForExpectations(for: [expectCompletionHandlerCalled])
return returnValueFromPushHandler
}
func addOtherPushEventHandler(_ pushEventHandler: PushEventHandler) {
pushEventHandlerProxy.addPushEventHandler(pushEventHandler)
}
}