Skip to content

Commit 2cf9bb2

Browse files
test: add test coverage for log kit batch (#439)
* fixed typo in naming * exposed method to be tested to swift * Created MPKitMock * covered logKitBatch method * added enum for reuse of json parameter * clean up code
1 parent c750ac2 commit 2cf9bb2

File tree

5 files changed

+172
-6
lines changed

5 files changed

+172
-6
lines changed

UnitTests/MParticle+PrivateMethods.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- (void)logEventCallback:(MPEvent *)event execStatus:(MPExecStatus)execStatus;
1717
- (void)logEvent:(MPBaseEvent *)event;
1818
- (void)logCustomEvent:(MPEvent *)event;
19+
- (void)logKitBatch:(NSString *)batch;
1920
- (void)logScreenCallback:(MPEvent *)event execStatus:(MPExecStatus)execStatus;
2021
- (void)leaveBreadcrumbCallback:(MPEvent *)event execStatus:(MPExecStatus)execStatus;
2122
- (void)logErrorCallback:(NSDictionary<NSString *,id> * _Nullable)eventInfo execStatus:(MPExecStatus)execStatus message:(NSString *)message;

UnitTests/MParticleTestsSwift.swift

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ import XCTest
55
import mParticle_Apple_SDK
66
#endif
77

8+
enum LogKitBatchData {
9+
static let invalidJSON = #"{"invalid": "json""#
10+
static let singleEvent = #"{"events":[{"id":1}]}"#
11+
static let multiEvent = #"{"events":[{"id":1},{"id":2}]}"#
12+
static let parsedSingleEvent: [String: Any] = [
13+
"events": [
14+
["id": 1]
15+
]
16+
]
17+
}
18+
819
class MParticleTestsSwift: XCTestCase {
920
var receivedMessage: String?
1021
var mparticle: MParticle!
@@ -16,6 +27,8 @@ class MParticleTestsSwift: XCTestCase {
1627
var notificationController: MPNotificationControllerMock!
1728
var appEnvironmentProvier: AppEnvironmentProviderMock!
1829
var appNotificationHandler: MPAppNotificationHandlerMock!
30+
var persistenceController: MPPersistenceControllerMock!
31+
var kit: MPKitMock!
1932

2033
func customLogger(_ message: String) {
2134
receivedMessage = message
@@ -51,6 +64,11 @@ class MParticleTestsSwift: XCTestCase {
5164

5265
appNotificationHandler = MPAppNotificationHandlerMock()
5366
mparticle.appNotificationHandler = appNotificationHandler
67+
68+
persistenceController = MPPersistenceControllerMock()
69+
mparticle.persistenceController = persistenceController
70+
71+
kit = MPKitMock()
5472
}
5573

5674
override func tearDown() {
@@ -606,9 +624,6 @@ class MParticleTestsSwift: XCTestCase {
606624
func testResetForSwitchingWorkspaces() {
607625
let expectation = XCTestExpectation()
608626

609-
let persistenceController = MPPersistenceControllerMock()
610-
mparticle.persistenceController = persistenceController
611-
612627
mparticle.reset {
613628
expectation.fulfill()
614629
}
@@ -935,6 +950,114 @@ class MParticleTestsSwift: XCTestCase {
935950
XCTAssertTrue(kitContainer.forwardSDKCallEventParam === transformedEvent)
936951
}
937952

953+
// MARK: - logKitBatch
954+
955+
func testLogKitBatch_withNilBatch_doesNotExecuteOrForward() {
956+
mparticle.logKitBatch(nil)
957+
958+
XCTAssertEqual(receivedMessage, "mParticle -> Cannot log nil batch!")
959+
XCTAssertFalse(executor.executeOnMessageQueueAsync)
960+
XCTAssertFalse(kitContainer.hasKitBatchingKitsCalled)
961+
XCTAssertFalse(executor.executeOnMainAsync)
962+
XCTAssertFalse(kitContainer.forwardSDKCallCalled)
963+
XCTAssertFalse(persistenceController.saveCalled)
964+
}
965+
966+
func testLogKitBatch_noBatchingKits_andKitsInitialized_doesNothing() {
967+
kitContainer.kitsInitialized = true
968+
kitContainer.hasKitBatchingKitsReturnValue = false
969+
970+
mparticle.logKitBatch(LogKitBatchData.singleEvent)
971+
972+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
973+
XCTAssertFalse(executor.executeOnMainAsync)
974+
XCTAssertFalse(kitContainer.forwardSDKCallCalled)
975+
XCTAssertFalse(persistenceController.saveCalled)
976+
}
977+
978+
func testLogKitBatch_kitsNotInitialized_defersWorkUntilInitialization() {
979+
kitContainer.kitsInitialized = false
980+
kitContainer.hasKitBatchingKitsReturnValue = true
981+
982+
mparticle.logKitBatch(LogKitBatchData.singleEvent)
983+
984+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
985+
986+
// Should queue deferred block, not execute immediately
987+
XCTAssertFalse(executor.executeOnMainAsync)
988+
XCTAssertFalse(kitContainer.forwardSDKCallCalled)
989+
XCTAssertFalse(persistenceController.saveCalled)
990+
991+
// Simulate kits becoming initialized
992+
kitContainer.kitsInitialized = true
993+
mparticle.executeKitsInitializedBlocks()
994+
995+
XCTAssertEqual(listenerController.onAPICalledApiName?.description, "executeKitsInitializedBlocks")
996+
XCTAssertTrue(executor.executeOnMainAsync)
997+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
998+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "logBatch:")
999+
XCTAssertEqual(kitContainer.forwardSDKCallBatchParam?.count, 1)
1000+
XCTAssertNotNil(kitContainer.forwardSDKCallKitHandlerParam)
1001+
}
1002+
1003+
func testLogKitBatch_withBatchingKits_forwardsParsedBatch_andPersistsForwardRecords() {
1004+
kitContainer.kitsInitialized = true
1005+
kitContainer.hasKitBatchingKitsReturnValue = true
1006+
1007+
mparticle.logKitBatch(LogKitBatchData.multiEvent)
1008+
1009+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
1010+
XCTAssertTrue(executor.executeOnMainAsync)
1011+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
1012+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "logBatch:")
1013+
XCTAssertEqual(kitContainer.forwardSDKCallBatchParam?.count, 1)
1014+
XCTAssertNotNil(kitContainer.forwardSDKCallKitHandlerParam)
1015+
}
1016+
1017+
func testLogKitBatch_invokesKitHandler_andPersistsForwardRecords() {
1018+
kitContainer.kitsInitialized = true
1019+
kitContainer.hasKitBatchingKitsReturnValue = true
1020+
1021+
let forwardRecord = MPForwardRecord()
1022+
kit.logBatchReturnValue = [forwardRecord]
1023+
1024+
mparticle.logKitBatch(LogKitBatchData.singleEvent)
1025+
1026+
guard let kitHandler = kitContainer.forwardSDKCallKitHandlerParam else {
1027+
XCTFail("Expected kitHandler closure to be captured")
1028+
return
1029+
}
1030+
1031+
// Simulate invoking the handler
1032+
let config = MPKitConfiguration()
1033+
kitHandler(kit, LogKitBatchData.parsedSingleEvent, config)
1034+
1035+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
1036+
XCTAssertTrue(executor.executeOnMainAsync)
1037+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
1038+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "logBatch:")
1039+
XCTAssertEqual(kitContainer.forwardSDKCallBatchParam?.count, 1)
1040+
XCTAssertTrue(kit.logBatchCalled)
1041+
XCTAssertEqual(kit.logBatchParam?["events"] as? [[String: Int]], [["id": 1]])
1042+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
1043+
XCTAssertTrue(persistenceController.saveCalled)
1044+
XCTAssertTrue(persistenceController.saveForwardRecordParam === forwardRecord)
1045+
}
1046+
1047+
func testLogKitBatch_invalidJSON_stillForwardsWithNilBatch() {
1048+
kitContainer.kitsInitialized = true
1049+
kitContainer.hasKitBatchingKitsReturnValue = true
1050+
1051+
mparticle.logKitBatch(LogKitBatchData.invalidJSON)
1052+
1053+
XCTAssertTrue(executor.executeOnMessageQueueAsync)
1054+
XCTAssertTrue(executor.executeOnMainAsync)
1055+
XCTAssertTrue(kitContainer.forwardSDKCallCalled)
1056+
XCTAssertEqual(kitContainer.forwardSDKCallSelectorParam?.description, "logBatch:")
1057+
XCTAssertEqual(kitContainer.forwardSDKCallBatchParam?.count, 0)
1058+
XCTAssertNotNil(kitContainer.forwardSDKCallKitHandlerParam)
1059+
}
1060+
9381061
// MARK: - logCommerceEvent
9391062

9401063
func testLogCommerceEvent_assignsTimestampWhenNil() {

UnitTests/Mocks/MPKitMock.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import XCTest
2+
#if MPARTICLE_LOCATION_DISABLE
3+
import mParticle_Apple_SDK_NoLocation
4+
#else
5+
import mParticle_Apple_SDK
6+
#endif
7+
8+
class MPKitMock: NSObject, MPKitProtocol {
9+
10+
// MARK: - Required methods from protocol
11+
12+
var started: Bool = false
13+
14+
func didFinishLaunching(withConfiguration configuration: [AnyHashable : Any]) -> MPKitExecStatus {
15+
return MPKitExecStatus()
16+
}
17+
18+
static func kitCode() -> NSNumber {
19+
return 1
20+
}
21+
22+
// MARK: - Methods used in testing
23+
24+
var logBatchCalled: Bool = false
25+
var logBatchParam: [AnyHashable: Any]?
26+
var logBatchReturnValue: [MPForwardRecord] = []
27+
28+
29+
func logBatch(_ batch: [AnyHashable : Any]) -> [MPForwardRecord] {
30+
logBatchCalled = true
31+
logBatchParam = batch
32+
return logBatchReturnValue
33+
}
34+
35+
36+
}

UnitTests/Mocks/MPPersistenceControllerMock.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ class MPPersistenceControllerMock: MPPersistenceControllerProtocol {
1818
resetDatabaseCalled = true
1919
}
2020

21-
var saveCelled = false
21+
var saveCalled = false
2222
var saveForwardRecordParam: MPForwardRecord?
2323

2424
func save(_ forwardRecord: MPForwardRecord) {
25-
saveCelled = true
25+
saveCalled = true
2626
saveForwardRecordParam = forwardRecord
2727
}
2828

2929
var saveIntegrationAttributesParam: MPIntegrationAttributes?
3030

3131
func save(_ integrationAttributes: MPIntegrationAttributes) {
32-
saveCelled = true
32+
saveCalled = true
3333
saveIntegrationAttributesParam = integrationAttributes
3434
}
3535

mParticle-Apple-SDK.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@
506506
53E20DC82CBFFCD200146A97 /* NSArray+MPCaseInsensitiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E20DC62CBFFCD200146A97 /* NSArray+MPCaseInsensitiveTests.swift */; };
507507
53FDD1BD2AE871AF003D5FA1 /* MPIHasher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FDD1BC2AE871AF003D5FA1 /* MPIHasher.swift */; };
508508
53FDD1BE2AE871AF003D5FA1 /* MPIHasher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FDD1BC2AE871AF003D5FA1 /* MPIHasher.swift */; };
509+
7231B80D2EB3C4AC001565E5 /* MPKitMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7231B80C2EB3C4AC001565E5 /* MPKitMock.swift */; };
510+
7231B80E2EB3C4AC001565E5 /* MPKitMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7231B80C2EB3C4AC001565E5 /* MPKitMock.swift */; };
509511
727801DE2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 727801DD2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift */; };
510512
727801DF2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 727801DD2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift */; };
511513
727801E12EB0FECA00BDAD98 /* AppEnvironmentProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 727801E02EB0FECA00BDAD98 /* AppEnvironmentProviderMock.swift */; };
@@ -853,6 +855,7 @@
853855
53B33E892A4606CD00CC8A19 /* MPSideloadedKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPSideloadedKit.swift; sourceTree = "<group>"; };
854856
53E20DC62CBFFCD200146A97 /* NSArray+MPCaseInsensitiveTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSArray+MPCaseInsensitiveTests.swift"; sourceTree = "<group>"; };
855857
53FDD1BC2AE871AF003D5FA1 /* MPIHasher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPIHasher.swift; sourceTree = "<group>"; };
858+
7231B80C2EB3C4AC001565E5 /* MPKitMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPKitMock.swift; sourceTree = "<group>"; };
856859
727801DD2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPNotificationControllerMock.swift; sourceTree = "<group>"; };
857860
727801E02EB0FECA00BDAD98 /* AppEnvironmentProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppEnvironmentProviderMock.swift; sourceTree = "<group>"; };
858861
727801E32EB1131B00BDAD98 /* MPAppNotificationHandlerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPAppNotificationHandlerMock.swift; sourceTree = "<group>"; };
@@ -937,6 +940,7 @@
937940
727801DD2EB0FE8400BDAD98 /* MPNotificationControllerMock.swift */,
938941
727801E02EB0FECA00BDAD98 /* AppEnvironmentProviderMock.swift */,
939942
727801E32EB1131B00BDAD98 /* MPAppNotificationHandlerMock.swift */,
943+
7231B80C2EB3C4AC001565E5 /* MPKitMock.swift */,
940944
);
941945
path = Mocks;
942946
sourceTree = "<group>";
@@ -1808,6 +1812,7 @@
18081812
356D4A5A2E58B09D00CB69FE /* SettingsProviderMock.swift in Sources */,
18091813
534CD26B29CE2CE1008452B3 /* MPBackendControllerTests.m in Sources */,
18101814
534CD26C29CE2CE1008452B3 /* MPKitConfigurationTests.mm in Sources */,
1815+
7231B80E2EB3C4AC001565E5 /* MPKitMock.swift in Sources */,
18111816
534CD26E29CE2CE1008452B3 /* MPNetworkCommunicationTests.m in Sources */,
18121817
534CD26F29CE2CE1008452B3 /* MPAliasRequestTests.m in Sources */,
18131818
534CD27029CE2CE1008452B3 /* MPAliasResponseTests.m in Sources */,
@@ -2007,6 +2012,7 @@
20072012
356D4A592E58B09D00CB69FE /* SettingsProviderMock.swift in Sources */,
20082013
53A79CD229CE019F00E7489F /* MPBackendControllerTests.m in Sources */,
20092014
53A79CF329CE019F00E7489F /* MPKitConfigurationTests.mm in Sources */,
2015+
7231B80D2EB3C4AC001565E5 /* MPKitMock.swift in Sources */,
20102016
53A79CBE29CE019F00E7489F /* MPNetworkCommunicationTests.m in Sources */,
20112017
53A79CF429CE019F00E7489F /* MPAliasRequestTests.m in Sources */,
20122018
53A79CF129CE019F00E7489F /* MPAliasResponseTests.m in Sources */,

0 commit comments

Comments
 (0)