Skip to content

Commit 8c42daf

Browse files
Merge branch 'workstation/9.0-Release' into ci/add-swift-unit-tests
2 parents e2a2a70 + 6a61cc0 commit 8c42daf

File tree

14 files changed

+991
-231
lines changed

14 files changed

+991
-231
lines changed

MIGRATING.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,64 @@ This change only affects users who:
9393

9494
The `MPListenerController` class has been removed. The SDK no longer invokes any listener callbacks.
9595

96+
---
97+
98+
### Source-Based Distribution Changes
99+
100+
As part of the transition from binary (XCFramework) to source-based distribution, several public Swift classes have been converted to Objective-C. This improves compatibility with Swift Package Manager and reduces integration complexity, but may require code changes for Swift users who were referencing Swift-specific type hierarchies.
101+
102+
#### MPRoktEvent Classes Moved to Top-Level
103+
104+
The `MPRoktEvent` subclasses have been converted from Swift nested classes to Objective-C top-level classes. This changes how Swift users reference these types.
105+
106+
**Before (Swift):**
107+
108+
```swift
109+
let initEvent = MPRoktEvent.MPRoktInitComplete(success: true)
110+
let readyEvent = MPRoktEvent.MPRoktPlacementReady(placementId: "abc")
111+
let purchaseEvent = MPRoktEvent.MPRoktCartItemInstantPurchase(...)
112+
```
113+
114+
**After (Swift):**
115+
116+
```swift
117+
let initEvent = MPRoktInitComplete(success: true)
118+
let readyEvent = MPRoktPlacementReady(placementId: "abc")
119+
let purchaseEvent = MPRoktCartItemInstantPurchase(...)
120+
```
121+
122+
**Affected Classes:**
123+
124+
| Before (Swift) | After (Swift) |
125+
| ------------------------------------------- | ------------------------------- |
126+
| `MPRoktEvent.MPRoktInitComplete` | `MPRoktInitComplete` |
127+
| `MPRoktEvent.MPRoktShowLoadingIndicator` | `MPRoktShowLoadingIndicator` |
128+
| `MPRoktEvent.MPRoktHideLoadingIndicator` | `MPRoktHideLoadingIndicator` |
129+
| `MPRoktEvent.MPRoktPlacementInteractive` | `MPRoktPlacementInteractive` |
130+
| `MPRoktEvent.MPRoktPlacementReady` | `MPRoktPlacementReady` |
131+
| `MPRoktEvent.MPRoktOfferEngagement` | `MPRoktOfferEngagement` |
132+
| `MPRoktEvent.MPRoktOpenUrl` | `MPRoktOpenUrl` |
133+
| `MPRoktEvent.MPRoktPositiveEngagement` | `MPRoktPositiveEngagement` |
134+
| `MPRoktEvent.MPRoktPlacementClosed` | `MPRoktPlacementClosed` |
135+
| `MPRoktEvent.MPRoktPlacementCompleted` | `MPRoktPlacementCompleted` |
136+
| `MPRoktEvent.MPRoktPlacementFailure` | `MPRoktPlacementFailure` |
137+
| `MPRoktEvent.MPRoktFirstPositiveEngagement` | `MPRoktFirstPositiveEngagement` |
138+
| `MPRoktEvent.MPRoktCartItemInstantPurchase` | `MPRoktCartItemInstantPurchase` |
139+
140+
**Migration Steps:**
141+
142+
1. Find all usages of `MPRoktEvent.MPRokt*` in your Swift code
143+
2. Remove the `MPRoktEvent.` prefix
144+
3. Type checking with `is` remains unchanged since they still inherit from `MPRoktEvent`
145+
146+
**Notes:**
147+
148+
- Objective-C users are not affected by this change
149+
- The `MPRoktEvent` base class still exists and can be used for type checking
150+
- All initializers and properties remain the same
151+
152+
---
153+
96154
### Direct Routing Enabled by Default
97155

98156
API requests now route directly to regional endpoints based on your API key prefix:

UnitTests/MParticle+PrivateMethods.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#import "MPDataPlanFilter.h"
44
#import "AppEnvironmentProvider.h"
55
#import "MPAppNotificationHandler.h"
6+
#import "SceneDelegateHandler.h"
67

78
@interface MParticle (Tests)
89
- (void)setOptOutCompletion:(MPExecStatus)execStatus optOut:(BOOL)optOut;

UnitTests/Mocks/SceneDelegateHandlerMock.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import XCTest
22
import mParticle_Apple_SDK_NoLocation
33

4-
class OpenURLHandlerProtocolMock: OpenURLHandlerProtocol {
4+
class OpenURLHandlerProtocolMock: NSObject, OpenURLHandlerProtocol {
55

66
var openURLWithOptionsCalled = false
77
var openURLWithOptionsURLParam: URL?
@@ -18,7 +18,7 @@ class OpenURLHandlerProtocolMock: OpenURLHandlerProtocol {
1818
var continueUserActivityRestorationHandlerParam: (([UIUserActivityRestoring]?) -> Void)?
1919
var continueUserActivityReturnValue: Bool = false
2020

21-
func continueUserActivity(
21+
func `continue`(
2222
_ userActivity: NSUserActivity,
2323
restorationHandler: @escaping ([any UIUserActivityRestoring]?) -> Void
2424
) -> Bool {
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
#import <XCTest/XCTest.h>
2+
#import "MPRoktEvent.h"
3+
4+
@interface MPRoktEventTests : XCTestCase
5+
@end
6+
7+
@implementation MPRoktEventTests
8+
9+
#pragma mark - MPRoktInitComplete Tests
10+
11+
- (void)testInitCompleteWithSuccessTrue {
12+
MPRoktInitComplete *event = [[MPRoktInitComplete alloc] initWithSuccess:YES];
13+
XCTAssertNotNil(event);
14+
XCTAssertTrue(event.success);
15+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
16+
}
17+
18+
- (void)testInitCompleteWithSuccessFalse {
19+
MPRoktInitComplete *event = [[MPRoktInitComplete alloc] initWithSuccess:NO];
20+
XCTAssertNotNil(event);
21+
XCTAssertFalse(event.success);
22+
}
23+
24+
#pragma mark - MPRoktShowLoadingIndicator Tests
25+
26+
- (void)testShowLoadingIndicator {
27+
MPRoktShowLoadingIndicator *event = [[MPRoktShowLoadingIndicator alloc] init];
28+
XCTAssertNotNil(event);
29+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
30+
}
31+
32+
#pragma mark - MPRoktHideLoadingIndicator Tests
33+
34+
- (void)testHideLoadingIndicator {
35+
MPRoktHideLoadingIndicator *event = [[MPRoktHideLoadingIndicator alloc] init];
36+
XCTAssertNotNil(event);
37+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
38+
}
39+
40+
#pragma mark - MPRoktPlacementInteractive Tests
41+
42+
- (void)testPlacementInteractiveWithPlacementId {
43+
NSString *placementId = @"test-placement-123";
44+
MPRoktPlacementInteractive *event = [[MPRoktPlacementInteractive alloc] initWithPlacementId:placementId];
45+
XCTAssertNotNil(event);
46+
XCTAssertEqualObjects(event.placementId, placementId);
47+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
48+
}
49+
50+
- (void)testPlacementInteractiveWithNilPlacementId {
51+
MPRoktPlacementInteractive *event = [[MPRoktPlacementInteractive alloc] initWithPlacementId:nil];
52+
XCTAssertNotNil(event);
53+
XCTAssertNil(event.placementId);
54+
}
55+
56+
#pragma mark - MPRoktPlacementReady Tests
57+
58+
- (void)testPlacementReadyWithPlacementId {
59+
NSString *placementId = @"ready-placement-456";
60+
MPRoktPlacementReady *event = [[MPRoktPlacementReady alloc] initWithPlacementId:placementId];
61+
XCTAssertNotNil(event);
62+
XCTAssertEqualObjects(event.placementId, placementId);
63+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
64+
}
65+
66+
- (void)testPlacementReadyWithNilPlacementId {
67+
MPRoktPlacementReady *event = [[MPRoktPlacementReady alloc] initWithPlacementId:nil];
68+
XCTAssertNotNil(event);
69+
XCTAssertNil(event.placementId);
70+
}
71+
72+
#pragma mark - MPRoktOfferEngagement Tests
73+
74+
- (void)testOfferEngagementWithPlacementId {
75+
NSString *placementId = @"offer-placement-789";
76+
MPRoktOfferEngagement *event = [[MPRoktOfferEngagement alloc] initWithPlacementId:placementId];
77+
XCTAssertNotNil(event);
78+
XCTAssertEqualObjects(event.placementId, placementId);
79+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
80+
}
81+
82+
#pragma mark - MPRoktOpenUrl Tests
83+
84+
- (void)testOpenUrlWithPlacementIdAndUrl {
85+
NSString *placementId = @"url-placement";
86+
NSString *url = @"https://example.com/offer";
87+
MPRoktOpenUrl *event = [[MPRoktOpenUrl alloc] initWithPlacementId:placementId url:url];
88+
XCTAssertNotNil(event);
89+
XCTAssertEqualObjects(event.placementId, placementId);
90+
XCTAssertEqualObjects(event.url, url);
91+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
92+
}
93+
94+
- (void)testOpenUrlWithNilPlacementId {
95+
NSString *url = @"https://example.com/offer";
96+
MPRoktOpenUrl *event = [[MPRoktOpenUrl alloc] initWithPlacementId:nil url:url];
97+
XCTAssertNotNil(event);
98+
XCTAssertNil(event.placementId);
99+
XCTAssertEqualObjects(event.url, url);
100+
}
101+
102+
#pragma mark - MPRoktPositiveEngagement Tests
103+
104+
- (void)testPositiveEngagementWithPlacementId {
105+
NSString *placementId = @"positive-placement";
106+
MPRoktPositiveEngagement *event = [[MPRoktPositiveEngagement alloc] initWithPlacementId:placementId];
107+
XCTAssertNotNil(event);
108+
XCTAssertEqualObjects(event.placementId, placementId);
109+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
110+
}
111+
112+
#pragma mark - MPRoktPlacementClosed Tests
113+
114+
- (void)testPlacementClosedWithPlacementId {
115+
NSString *placementId = @"closed-placement";
116+
MPRoktPlacementClosed *event = [[MPRoktPlacementClosed alloc] initWithPlacementId:placementId];
117+
XCTAssertNotNil(event);
118+
XCTAssertEqualObjects(event.placementId, placementId);
119+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
120+
}
121+
122+
#pragma mark - MPRoktPlacementCompleted Tests
123+
124+
- (void)testPlacementCompletedWithPlacementId {
125+
NSString *placementId = @"completed-placement";
126+
MPRoktPlacementCompleted *event = [[MPRoktPlacementCompleted alloc] initWithPlacementId:placementId];
127+
XCTAssertNotNil(event);
128+
XCTAssertEqualObjects(event.placementId, placementId);
129+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
130+
}
131+
132+
#pragma mark - MPRoktPlacementFailure Tests
133+
134+
- (void)testPlacementFailureWithPlacementId {
135+
NSString *placementId = @"failed-placement";
136+
MPRoktPlacementFailure *event = [[MPRoktPlacementFailure alloc] initWithPlacementId:placementId];
137+
XCTAssertNotNil(event);
138+
XCTAssertEqualObjects(event.placementId, placementId);
139+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
140+
}
141+
142+
#pragma mark - MPRoktFirstPositiveEngagement Tests
143+
144+
- (void)testFirstPositiveEngagementWithPlacementId {
145+
NSString *placementId = @"first-positive-placement";
146+
MPRoktFirstPositiveEngagement *event = [[MPRoktFirstPositiveEngagement alloc] initWithPlacementId:placementId];
147+
XCTAssertNotNil(event);
148+
XCTAssertEqualObjects(event.placementId, placementId);
149+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
150+
}
151+
152+
#pragma mark - MPRoktCartItemInstantPurchase Tests
153+
154+
- (void)testCartItemInstantPurchaseWithAllParameters {
155+
NSString *placementId = @"cart-placement";
156+
NSString *name = @"Test Product";
157+
NSString *cartItemId = @"cart-123";
158+
NSString *catalogItemId = @"catalog-456";
159+
NSString *currency = @"USD";
160+
NSString *description = @"A test product description";
161+
NSString *linkedProductId = @"linked-789";
162+
NSString *providerData = @"provider-data";
163+
NSDecimalNumber *quantity = [NSDecimalNumber decimalNumberWithString:@"2"];
164+
NSDecimalNumber *totalPrice = [NSDecimalNumber decimalNumberWithString:@"19.99"];
165+
NSDecimalNumber *unitPrice = [NSDecimalNumber decimalNumberWithString:@"9.995"];
166+
167+
MPRoktCartItemInstantPurchase *event = [[MPRoktCartItemInstantPurchase alloc]
168+
initWithPlacementId:placementId
169+
name:name
170+
cartItemId:cartItemId
171+
catalogItemId:catalogItemId
172+
currency:currency
173+
description:description
174+
linkedProductId:linkedProductId
175+
providerData:providerData
176+
quantity:quantity
177+
totalPrice:totalPrice
178+
unitPrice:unitPrice];
179+
180+
XCTAssertNotNil(event);
181+
XCTAssertEqualObjects(event.placementId, placementId);
182+
XCTAssertEqualObjects(event.name, name);
183+
XCTAssertEqualObjects(event.cartItemId, cartItemId);
184+
XCTAssertEqualObjects(event.catalogItemId, catalogItemId);
185+
XCTAssertEqualObjects(event.currency, currency);
186+
XCTAssertEqualObjects(event.description, description);
187+
XCTAssertEqualObjects(event.linkedProductId, linkedProductId);
188+
XCTAssertEqualObjects(event.providerData, providerData);
189+
XCTAssertEqualObjects(event.quantity, quantity);
190+
XCTAssertEqualObjects(event.totalPrice, totalPrice);
191+
XCTAssertEqualObjects(event.unitPrice, unitPrice);
192+
XCTAssertTrue([event isKindOfClass:[MPRoktEvent class]]);
193+
}
194+
195+
- (void)testCartItemInstantPurchaseWithNilOptionalParameters {
196+
NSString *placementId = @"cart-placement";
197+
NSString *cartItemId = @"cart-123";
198+
NSString *catalogItemId = @"catalog-456";
199+
NSString *currency = @"USD";
200+
NSString *description = @"A test product";
201+
NSString *providerData = @"provider-data";
202+
203+
MPRoktCartItemInstantPurchase *event = [[MPRoktCartItemInstantPurchase alloc]
204+
initWithPlacementId:placementId
205+
name:nil
206+
cartItemId:cartItemId
207+
catalogItemId:catalogItemId
208+
currency:currency
209+
description:description
210+
linkedProductId:nil
211+
providerData:providerData
212+
quantity:nil
213+
totalPrice:nil
214+
unitPrice:nil];
215+
216+
XCTAssertNotNil(event);
217+
XCTAssertEqualObjects(event.placementId, placementId);
218+
XCTAssertNil(event.name);
219+
XCTAssertEqualObjects(event.cartItemId, cartItemId);
220+
XCTAssertEqualObjects(event.catalogItemId, catalogItemId);
221+
XCTAssertEqualObjects(event.currency, currency);
222+
XCTAssertEqualObjects(event.description, description);
223+
XCTAssertNil(event.linkedProductId);
224+
XCTAssertEqualObjects(event.providerData, providerData);
225+
XCTAssertNil(event.quantity);
226+
XCTAssertNil(event.totalPrice);
227+
XCTAssertNil(event.unitPrice);
228+
}
229+
230+
- (void)testCartItemInstantPurchaseDescriptionOverride {
231+
NSString *customDescription = @"Custom description text";
232+
233+
MPRoktCartItemInstantPurchase *event = [[MPRoktCartItemInstantPurchase alloc]
234+
initWithPlacementId:@"placement"
235+
name:nil
236+
cartItemId:@"cart"
237+
catalogItemId:@"catalog"
238+
currency:@"USD"
239+
description:customDescription
240+
linkedProductId:nil
241+
providerData:@"data"
242+
quantity:nil
243+
totalPrice:nil
244+
unitPrice:nil];
245+
246+
// Verify the description property returns the custom description
247+
XCTAssertEqualObjects(event.description, customDescription);
248+
}
249+
250+
#pragma mark - Inheritance Tests
251+
252+
- (void)testAllEventTypesInheritFromMPRoktEvent {
253+
// Test that all event types inherit from MPRoktEvent
254+
XCTAssertTrue([[[MPRoktInitComplete alloc] initWithSuccess:YES] isKindOfClass:[MPRoktEvent class]]);
255+
XCTAssertTrue([[[MPRoktShowLoadingIndicator alloc] init] isKindOfClass:[MPRoktEvent class]]);
256+
XCTAssertTrue([[[MPRoktHideLoadingIndicator alloc] init] isKindOfClass:[MPRoktEvent class]]);
257+
XCTAssertTrue([[[MPRoktPlacementInteractive alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
258+
XCTAssertTrue([[[MPRoktPlacementReady alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
259+
XCTAssertTrue([[[MPRoktOfferEngagement alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
260+
XCTAssertTrue([[[MPRoktOpenUrl alloc] initWithPlacementId:@"test" url:@"url"] isKindOfClass:[MPRoktEvent class]]);
261+
XCTAssertTrue([[[MPRoktPositiveEngagement alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
262+
XCTAssertTrue([[[MPRoktPlacementClosed alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
263+
XCTAssertTrue([[[MPRoktPlacementCompleted alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
264+
XCTAssertTrue([[[MPRoktPlacementFailure alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
265+
XCTAssertTrue([[[MPRoktFirstPositiveEngagement alloc] initWithPlacementId:@"test"] isKindOfClass:[MPRoktEvent class]]);
266+
XCTAssertTrue([[[MPRoktCartItemInstantPurchase alloc] initWithPlacementId:@"p" name:nil cartItemId:@"c" catalogItemId:@"cat" currency:@"USD" description:@"d" linkedProductId:nil providerData:@"prov" quantity:nil totalPrice:nil unitPrice:nil] isKindOfClass:[MPRoktEvent class]]);
267+
}
268+
269+
@end

UnitTests/ObjCTests/MPRoktTests.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#import "MPKitContainer.h"
77
#import "MPForwardQueueParameters.h"
88
#import "MParticleSwift.h"
9+
#import "MPRoktEvent.h"
910
#import "MPIConstants.h"
1011

1112
@interface MPRokt ()

0 commit comments

Comments
 (0)