From 689453e19cbe07eccc41f6fb5aa7caed157dd8ed Mon Sep 17 00:00:00 2001 From: Kaushal Kapasi Date: Wed, 10 Apr 2024 16:25:54 -0400 Subject: [PATCH] fix: refactor batching of events payload into its own private method --- DevCycle/Networking/DevCycleService.swift | 74 ++++++++++--------- .../Networking/DevCycleServiceTests.swift | 74 +++++++++++-------- 2 files changed, 84 insertions(+), 64 deletions(-) diff --git a/DevCycle/Networking/DevCycleService.swift b/DevCycle/Networking/DevCycleService.swift index 2ef54d6..ad98e86 100644 --- a/DevCycle/Networking/DevCycleService.swift +++ b/DevCycle/Networking/DevCycleService.swift @@ -94,7 +94,6 @@ class DevCycleService: DevCycleServiceProtocol { } func publishEvents(events: [DevCycleEvent], user: DevCycleUser, completion: @escaping PublishEventsCompletionHandler) { - var eventsRequest = createEventsRequest() let userEncoder = JSONEncoder() userEncoder.dateEncodingStrategy = .iso8601 guard let userId = user.userId, let userData = try? userEncoder.encode(user) else { @@ -105,41 +104,8 @@ class DevCycleService: DevCycleServiceProtocol { guard let userBody = try? JSONSerialization.jsonObject(with: userData, options: .fragmentsAllowed) else { return completion((nil, nil, ClientError.InvalidUser)) } - - eventsRequest.httpMethod = "POST" - eventsRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") - eventsRequest.addValue("application/json", forHTTPHeaderField: "Accept") - eventsRequest.addValue(config.sdkKey, forHTTPHeaderField: "Authorization") - - let totalEventsCount = eventPayload.count - var startIndex = 0 - var endIndex = min(self.maxBatchSize, totalEventsCount) - - while startIndex < totalEventsCount { - let batchEvents = Array(eventPayload[startIndex..= totalEventsCount { - return completion((data, response, nil)) - } - } - } + self.batchEventsPayload(events: eventPayload, user: userBody, completion: completion) } func saveEntity(user: DevCycleUser, completion: @escaping SaveEntityCompletionHandler) { @@ -326,4 +292,42 @@ class DevCycleService: DevCycleServiceProtocol { return eventsJSON } + + private func batchEventsPayload(events: [[String:Any]], user: Any, completion: @escaping PublishEventsCompletionHandler) { + var eventsRequest = createEventsRequest() + eventsRequest.httpMethod = "POST" + eventsRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") + eventsRequest.addValue("application/json", forHTTPHeaderField: "Accept") + eventsRequest.addValue(self.config.sdkKey, forHTTPHeaderField: "Authorization") + + let totalEventsCount = events.count + var startIndex = 0 + var endIndex = min(self.maxBatchSize, totalEventsCount) + + while startIndex < totalEventsCount { + let batchEvents = Array(events[startIndex..= totalEventsCount { + return completion((data, response, nil)) + } + } + } + } } diff --git a/DevCycleTests/Networking/DevCycleServiceTests.swift b/DevCycleTests/Networking/DevCycleServiceTests.swift index b822f61..c2a26c9 100644 --- a/DevCycleTests/Networking/DevCycleServiceTests.swift +++ b/DevCycleTests/Networking/DevCycleServiceTests.swift @@ -94,6 +94,7 @@ class DevCycleServiceTests: XCTestCase { expectation.fulfill() } wait(for: [expectation], timeout: 1.0) + XCTAssertTrue(service.publishEventsCalled) XCTAssertEqual(service.makeRequestCallCount, 1, "makeRequest should have been called 1 time") } @@ -114,6 +115,7 @@ class DevCycleServiceTests: XCTestCase { expectation.fulfill() } wait(for: [expectation], timeout: 3.0) + XCTAssertTrue(service.publishEventsCalled) XCTAssertEqual(service.makeRequestCallCount, 3, "makeRequest should have been called 3 times") } } @@ -162,12 +164,11 @@ extension DevCycleServiceTests { var publishEventsCalled = false var makeRequestCallCount = 0 let testMaxBatchSize = 100 + var sdkKey = "my_sdk_key" func publishEvents(events: [DevCycleEvent], user: DevCycleUser, completion: @escaping PublishEventsCompletionHandler) { publishEventsCalled = true - - let url = URL(string: "http://test.com/v1/events")! - var eventsRequest = URLRequest(url: url) + let userEncoder = JSONEncoder() userEncoder.dateEncodingStrategy = .iso8601 guard let userId = user.userId, let userData = try? userEncoder.encode(user) else { @@ -179,38 +180,14 @@ extension DevCycleServiceTests { return completion((nil, nil, ClientError.InvalidUser)) } - let totalEventsCount = eventPayload.count - var startIndex = 0 - var endIndex = min(self.testMaxBatchSize, totalEventsCount) - - while startIndex < totalEventsCount { - let batchEvents = Array(eventPayload[startIndex..= totalEventsCount { - return completion((data, response, nil)) - } - } - } + self.batchEventsPayload(events: eventPayload, user: userBody, completion: completion) } func makeRequest(request: URLRequest, completion: @escaping CompletionHandler) { self.makeRequestCallCount += 1 // Mock implementation for makeRequest - let mockData = "Successfully flushed 100 events".data(using: .utf8) + let mockData = "Successfully flushed \(self.testMaxBatchSize) events".data(using: .utf8) let mockResponse = HTTPURLResponse(url: URL(string: "https://example.com")!, statusCode: 200, httpVersion: "HTTP/1.1", headerFields: nil) completion((mockData, mockResponse, nil)) } @@ -244,6 +221,45 @@ extension DevCycleServiceTests { return eventsJSON } + + private func batchEventsPayload(events: [[String:Any]], user: Any, completion: @escaping PublishEventsCompletionHandler) { + let url = URL(string: "http://test.com/v1/events")! + var eventsRequest = URLRequest(url: url) + eventsRequest.httpMethod = "POST" + eventsRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") + eventsRequest.addValue("application/json", forHTTPHeaderField: "Accept") + eventsRequest.addValue(self.sdkKey, forHTTPHeaderField: "Authorization") + + let totalEventsCount = events.count + var startIndex = 0 + var endIndex = min(self.testMaxBatchSize, totalEventsCount) + + while startIndex < totalEventsCount { + let batchEvents = Array(events[startIndex..= totalEventsCount { + return completion((data, response, nil)) + } + } + } + } }