Skip to content

Commit b8d67ec

Browse files
authored
feat: SDKE-64 Improve mParticle.m test coverage in swift 2 (#407)
* - add executor mock * - update nullability * - add tests
1 parent d4ef623 commit b8d67ec

File tree

8 files changed

+155
-10
lines changed

8 files changed

+155
-10
lines changed

UnitTests/MParticle+PrivateMethods.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@
3030
- (void)handleWebviewCommand:(NSString *)command dictionary:(NSDictionary *)dictionary;
3131
- (void)sessionDidBegin:(MPSession *)session;
3232
- (void)sessionDidEnd:(nonnull MPSession *)session;
33+
- (void)setExecutor: (id<ExecutorProtocol>)newExecutor;
34+
- (void)setBackendController: (id<MPBackendControllerProtocol>)backendController;
35+
- (void)setKitContainer:(id<MPKitContainerProtocol>) kitContainer;
36+
- (void)forwardLogInstall;
37+
- (void)forwardLogUpdate;
3338

3439
@property (nonatomic, strong, nonnull) id<MPBackendControllerProtocol> backendController;
3540
@property (nonatomic, strong) id<SettingsProviderProtocol> settingsProvider;
3641
@property (nonatomic, strong, nullable) id<MPDataPlanFilterProtocol> dataPlanFilter;
3742
@property (nonatomic, strong, nonnull) id<MPListenerControllerProtocol> listenerController;
3843
@property (nonatomic, strong) id<MPStateMachineProtocol> stateMachine;
39-
@property (nonatomic, strong) id<MPKitContainerProtocol> kitContainer;
4044
@property (nonatomic, strong) id<MPPersistenceControllerProtocol> persistenceController;
4145
@end
4246

UnitTests/MParticleTestsSwift.swift

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ class MParticleTestsSwift: XCTestCase {
637637
func testSessionDidBegin() {
638638
let kitContainer = MPKitContainerMock()
639639
kitContainer.forwardSDKCallExpectation = XCTestExpectation()
640-
mparticle.kitContainer = kitContainer
640+
mparticle.setKitContainer(kitContainer)
641641
mparticle.sessionDidBegin(MPSession())
642642

643643

@@ -654,7 +654,7 @@ class MParticleTestsSwift: XCTestCase {
654654
func testSessionDidEnd() {
655655
let kitContainer = MPKitContainerMock()
656656
kitContainer.forwardSDKCallExpectation = XCTestExpectation()
657-
mparticle.kitContainer = kitContainer
657+
mparticle.setKitContainer(kitContainer)
658658
mparticle.sessionDidEnd(MPSession())
659659

660660

@@ -677,7 +677,7 @@ class MParticleTestsSwift: XCTestCase {
677677

678678
let backendController = MPBackendControllerMock()
679679

680-
mparticle.kitContainer = kitContainer
680+
mparticle.setKitContainer(kitContainer)
681681
mparticle.persistenceController = persistenceController
682682
mparticle.backendController = backendController
683683

@@ -692,5 +692,90 @@ class MParticleTestsSwift: XCTestCase {
692692
XCTAssertEqual(persistenceController.resetDatabaseCalled, true)
693693
XCTAssertTrue(backendController.unproxyOriginalAppDelegateCalled)
694694
}
695+
696+
func testBeginSessionTempSessionAvailableSessionTempSessionShouldNotBeCreated() {
697+
let backendController = MPBackendControllerMock()
698+
backendController.session = nil
699+
backendController.tempSessionReturnValue = MParticleSession()
700+
mparticle.backendController = backendController
701+
mparticle.beginSession()
702+
XCTAssertFalse(backendController.createTempSessionCalled)
703+
}
704+
705+
func testBeginSessionSessionAvailableSessionTempSessionShouldNotBeCreated() {
706+
let backendController = MPBackendControllerMock()
707+
backendController.session = MPSession()
708+
backendController.tempSessionReturnValue = nil
709+
mparticle.backendController = backendController
710+
mparticle.beginSession()
711+
XCTAssertFalse(backendController.createTempSessionCalled)
712+
}
713+
714+
func testBeginSessionSessionUnavailable() {
715+
let backendController = MPBackendControllerMock()
716+
backendController.session = nil
717+
backendController.tempSessionReturnValue = nil
718+
let executor = ExecutorMock()
719+
mparticle.setExecutor(executor)
720+
mparticle.backendController = backendController
721+
mparticle.beginSession()
722+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
723+
XCTAssertTrue(backendController.createTempSessionCalled)
724+
XCTAssertTrue(backendController.beginSessionCalled)
725+
XCTAssertEqual(backendController.beginSessionIsManualParam, true)
726+
XCTAssertNotNil(backendController.beginSessionDateParam)
727+
}
728+
729+
func testEndSessionNoSession() {
730+
let backendController = MPBackendControllerMock()
731+
backendController.session = nil
732+
let executor = ExecutorMock()
733+
mparticle.setExecutor(executor)
734+
mparticle.backendController = backendController
735+
mparticle.endSession()
736+
XCTAssertEqual(executor.executeOnMessageQueueAsync, true)
737+
XCTAssertFalse(backendController.endSessionWithIsManualCalled)
738+
}
739+
740+
func testEndSessionWithSession() {
741+
let backendController = MPBackendControllerMock()
742+
backendController.session = MPSession()
743+
let executor = ExecutorMock()
744+
mparticle.setExecutor(executor)
745+
mparticle.backendController = backendController
746+
mparticle.endSession()
747+
XCTAssertEqual(executor.executeOnMessageQueueAsync, true)
748+
XCTAssertTrue(backendController.endSessionWithIsManualCalled)
749+
XCTAssertEqual(backendController.endSessionIsManualParam, true)
750+
}
751+
752+
func testForwardLogInstall() {
753+
let executor = ExecutorMock()
754+
mparticle.setExecutor(executor)
755+
let kitContainer = MPKitContainerMock()
756+
mparticle.setKitContainer(kitContainer)
757+
mparticle.forwardLogInstall()
758+
XCTAssertEqual(executor.executeOnMainAsync, true)
759+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
760+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "forwardLogInstall")
761+
XCTAssertEqual(kitContainer.forwardSDKCallMessageTypeParam, .unknown)
762+
XCTAssertNil(kitContainer.forwardSDKCallEventParam)
763+
XCTAssertNil(kitContainer.forwardSDKCallParametersParam)
764+
XCTAssertNil(kitContainer.forwardSDKCallUserInfoParam)
765+
}
766+
767+
func testForwardLogUpdate() {
768+
let executor = ExecutorMock()
769+
mparticle.setExecutor(executor)
770+
let kitContainer = MPKitContainerMock()
771+
mparticle.setKitContainer(kitContainer)
772+
mparticle.forwardLogUpdate()
773+
XCTAssertEqual(executor.executeOnMainAsync, true)
774+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
775+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "forwardLogUpdate")
776+
XCTAssertEqual(kitContainer.forwardSDKCallMessageTypeParam, .unknown)
777+
XCTAssertNil(kitContainer.forwardSDKCallEventParam)
778+
XCTAssertNil(kitContainer.forwardSDKCallParametersParam)
779+
XCTAssertNil(kitContainer.forwardSDKCallUserInfoParam)
780+
}
695781
}
696-

UnitTests/Mocks/ExecutorMock.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// ExecutorMock.swift
3+
// mParticle-Apple-SDK
4+
//
5+
// Created by Denis Chilik on 9/9/25.
6+
//
7+
8+
9+
class ExecutorMock: ExecutorProtocol {
10+
func messageQueue() -> dispatch_queue_t {
11+
return DispatchQueue.main
12+
}
13+
14+
func isMessageQueue() -> Bool {
15+
return false
16+
}
17+
18+
var executeOnMessageQueueAsync: Bool = false
19+
20+
func execute(onMessage block: (() -> Void)!) {
21+
executeOnMessageQueueAsync = true
22+
block()
23+
}
24+
25+
var executeOnMessageQueueSync = false
26+
27+
func execute(onMessageSync block: (() -> Void)!) {
28+
executeOnMessageQueueSync = true
29+
block()
30+
}
31+
32+
var executeOnMainAsync = false
33+
34+
func execute(onMain block: (() -> Void)!) {
35+
executeOnMainAsync = true
36+
block()
37+
}
38+
39+
var executeOnMainSync = false
40+
41+
func execute(onMainSync block: (() -> Void)!) {
42+
executeOnMainSync = true
43+
block()
44+
}
45+
}

UnitTests/Mocks/MPBackendControllerMock.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ class MPBackendControllerMock: NSObject, MPBackendControllerProtocol {
6969

7070
// MARK: - Temp session
7171
var tempSessionCalled = false
72-
var tempSessionReturnValue: MParticleSession = MParticleSession()
72+
var tempSessionReturnValue: MParticleSession?
7373

74-
func tempSession() -> MParticleSession {
74+
func tempSession() -> MParticleSession? {
7575
tempSessionCalled = true
7676
return tempSessionReturnValue
7777
}

UnitTests/mParticle_iOS_SDKTests-Bridging-Header.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//
22
// Use this file to import your target's public headers that you would like to expose to Swift.
33
//
4+
#import "Executor.h"
45
#import "MPAttributionResult+MParticlePrivate.h"
56
#import "MParticleSession+MParticlePrivate.h"
67
#import "MParticleOptions+MParticlePrivate.h"

mParticle-Apple-SDK.xcodeproj/project.pbxproj

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
351308422E6B28F5002A3AD6 /* Executor.m in Sources */ = {isa = PBXBuildFile; fileRef = 351308402E6B28F5002A3AD6 /* Executor.m */; };
1616
351308432E6B28F5002A3AD6 /* Executor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3513083F2E6B28F5002A3AD6 /* Executor.h */; };
1717
351308442E6B28F5002A3AD6 /* Executor.m in Sources */ = {isa = PBXBuildFile; fileRef = 351308402E6B28F5002A3AD6 /* Executor.m */; };
18+
3517794F2E706BF8004BF05E /* ExecutorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3517794C2E706BE4004BF05E /* ExecutorMock.swift */; };
19+
351779502E706BF8004BF05E /* ExecutorMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3517794C2E706BE4004BF05E /* ExecutorMock.swift */; };
1820
35329FE92E54C38C009AC4FD /* MPNetworkOptions+MParticlePrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 35329FE82E54C38C009AC4FD /* MPNetworkOptions+MParticlePrivate.m */; };
1921
35329FEA2E54C38C009AC4FD /* MPNetworkOptions+MParticlePrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 35329FE82E54C38C009AC4FD /* MPNetworkOptions+MParticlePrivate.m */; };
2022
35329FEC2E54C483009AC4FD /* MPNetworkOptions+MParticlePrivateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35329FEB2E54C480009AC4FD /* MPNetworkOptions+MParticlePrivateTests.swift */; };
@@ -577,6 +579,7 @@
577579
351308232E676F12002A3AD6 /* MPPersistenceControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPPersistenceControllerMock.swift; sourceTree = "<group>"; };
578580
3513083F2E6B28F5002A3AD6 /* Executor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Executor.h; sourceTree = "<group>"; };
579581
351308402E6B28F5002A3AD6 /* Executor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Executor.m; sourceTree = "<group>"; };
582+
3517794C2E706BE4004BF05E /* ExecutorMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExecutorMock.swift; sourceTree = "<group>"; };
580583
35329FE82E54C38C009AC4FD /* MPNetworkOptions+MParticlePrivate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MPNetworkOptions+MParticlePrivate.m"; sourceTree = "<group>"; };
581584
35329FEB2E54C480009AC4FD /* MPNetworkOptions+MParticlePrivateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPNetworkOptions+MParticlePrivateTests.swift"; sourceTree = "<group>"; };
582585
35329FEE2E54CA49009AC4FD /* MParticleOptions+MParticlePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MParticleOptions+MParticlePrivate.h"; sourceTree = "<group>"; };
@@ -904,6 +907,7 @@
904907
356D4A572E58B01100CB69FE /* Mocks */ = {
905908
isa = PBXGroup;
906909
children = (
910+
3517794C2E706BE4004BF05E /* ExecutorMock.swift */,
907911
351308232E676F12002A3AD6 /* MPPersistenceControllerMock.swift */,
908912
3513081E2E6729D0002A3AD6 /* MPKitContainerMock.swift */,
909913
356752922E60928500DEEE23 /* MPStateMachineMock.swift */,
@@ -1436,13 +1440,13 @@
14361440
53A79BE929CDFB2000E7489F /* MPApplication.h in Headers */,
14371441
D30CD0CB2CFF5FB100F5148A /* MPStateMachine.h in Headers */,
14381442
53A79BF329CDFB2000E7489F /* MPCustomModulePreference.h in Headers */,
1439-
351308412E6B28F5002A3AD6 /* Executor.h in Headers */,
14401443
53A79B8C29CDFB2000E7489F /* MPDataModelProtocol.h in Headers */,
14411444
53A79BFB29CDFB2100E7489F /* MPAppDelegateProxy.h in Headers */,
14421445
359BAFFA2E56330200A8A704 /* SettingsProvider.h in Headers */,
14431446
53A79B9929CDFB2000E7489F /* MPIConstants.h in Headers */,
14441447
53A79B7129CDFB2000E7489F /* MPBackendController.h in Headers */,
14451448
35E3FCCC2E54975C00DB5B18 /* MParticleSession+MParticlePrivate.h in Headers */,
1449+
351308412E6B28F5002A3AD6 /* Executor.h in Headers */,
14461450
53A79B7929CDFB2000E7489F /* MPConnectorResponseProtocol.h in Headers */,
14471451
7E0387832DB913D2003B7D5E /* MPRokt.h in Headers */,
14481452
53A79B7C29CDFB2000E7489F /* MPConnectorFactoryProtocol.h in Headers */,
@@ -1532,12 +1536,12 @@
15321536
53A79D2729CE23F700E7489F /* MPApplication.h in Headers */,
15331537
53A79D2829CE23F700E7489F /* MPCustomModulePreference.h in Headers */,
15341538
53A79D2929CE23F700E7489F /* MPDataModelProtocol.h in Headers */,
1535-
351308432E6B28F5002A3AD6 /* Executor.h in Headers */,
15361539
53A79D2A29CE23F700E7489F /* MPAppDelegateProxy.h in Headers */,
15371540
53A79D2C29CE23F700E7489F /* MPIConstants.h in Headers */,
15381541
359BAFF92E56330200A8A704 /* SettingsProvider.h in Headers */,
15391542
53A79D2E29CE23F700E7489F /* MPBackendController.h in Headers */,
15401543
7E0387812DB913D2003B7D5E /* MPRokt.h in Headers */,
1544+
351308432E6B28F5002A3AD6 /* Executor.h in Headers */,
15411545
35E3FCCD2E54975C00DB5B18 /* MParticleSession+MParticlePrivate.h in Headers */,
15421546
53A79D3029CE23F700E7489F /* MPConnectorResponseProtocol.h in Headers */,
15431547
53A79D3229CE23F700E7489F /* MPConnectorFactoryProtocol.h in Headers */,
@@ -1803,6 +1807,7 @@
18031807
356752932E60928B00DEEE23 /* MPStateMachineMock.swift in Sources */,
18041808
534CD27D29CE2CE1008452B3 /* MPDataModelTests.m in Sources */,
18051809
534CD27F29CE2CE1008452B3 /* NSNumber+MPFormatterTests.m in Sources */,
1810+
351779502E706BF8004BF05E /* ExecutorMock.swift in Sources */,
18061811
351308202E6729DA002A3AD6 /* MPKitContainerMock.swift in Sources */,
18071812
534CD28029CE2CE1008452B3 /* MPResponseEventsTest.m in Sources */,
18081813
534CD28129CE2CE1008452B3 /* MPConsentStateTests.m in Sources */,
@@ -1996,6 +2001,7 @@
19962001
356752942E60928B00DEEE23 /* MPStateMachineMock.swift in Sources */,
19972002
53A79CCC29CE019F00E7489F /* MPIntegrationAttributesTest.m in Sources */,
19982003
53A79CBD29CE019F00E7489F /* MPDataModelTests.m in Sources */,
2004+
3517794F2E706BF8004BF05E /* ExecutorMock.swift in Sources */,
19992005
3513081F2E6729DA002A3AD6 /* MPKitContainerMock.swift in Sources */,
20002006
53A79CEE29CE019F00E7489F /* NSNumber+MPFormatterTests.m in Sources */,
20012007
53A79CD929CE019F00E7489F /* MPResponseEventsTest.m in Sources */,

mParticle-Apple-SDK/Include/MPBackendController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ extern const NSInteger kInvalidKey;
6161
- (nonnull NSMutableDictionary<NSString *, id> *)userAttributesForUserId:(nonnull NSNumber *)userId;
6262
- (void)startWithKey:(nonnull NSString *)apiKey secret:(nonnull NSString *)secret networkOptions:(nullable MPNetworkOptions *)networkOptions firstRun:(BOOL)firstRun installationType:(MPInstallationType)installationType proxyAppDelegate:(BOOL)proxyAppDelegate startKitsAsync:(BOOL)startKitsAsync consentState:(MPConsentState *_Nullable)consentState completionHandler:(dispatch_block_t _Nonnull)completionHandler;
6363
- (void)prepareBatchesForUpload:(nonnull MPUploadSettings *)uploadSettings;
64-
- (nonnull MParticleSession *)tempSession;
64+
- (MParticleSession* _Nullable)tempSession;
6565
- (void)unproxyOriginalAppDelegate;
6666
- (void)endSession;
6767
- (void)beginTimedEvent:(nonnull MPEvent *)event completionHandler:(void (^ _Nonnull)(MPEvent * _Nonnull event, MPExecStatus execStatus))completionHandler;

mParticle-Apple-SDK/mParticle.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ - (instancetype)init {
151151
return self;
152152
}
153153

154+
- (void)setExecutor: (id<ExecutorProtocol>)newExecutor {
155+
executor = newExecutor;
156+
}
157+
154158
- (void)setKitContainer_PRIVATE:(MPKitContainer_PRIVATE*) kitContainer_PRIVATE {
155159
_kitContainer_PRIVATE = kitContainer_PRIVATE;
156160
_kitContainer = kitContainer_PRIVATE;

0 commit comments

Comments
 (0)