From 606fd6cacc097369196b35d5a4188273cc743b82 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:44:27 +1000 Subject: [PATCH 01/11] Remove state from `EventQueueTests` --- Tests/EventQueueTests.swift | 92 ++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/Tests/EventQueueTests.swift b/Tests/EventQueueTests.swift index aec8d56..eaaec68 100644 --- a/Tests/EventQueueTests.swift +++ b/Tests/EventQueueTests.swift @@ -1,58 +1,68 @@ -import XCTest +import Nimble @testable import ParselyAnalytics +import XCTest + +class EventQueueTests: XCTestCase { -class EventQueueTests: ParselyTestCase { - var queue = ParselyAnalytics.EventQueue() - - override func setUp() { - super.setUp() - for i:Int in 0...30 { - self.queue.push(i) - } - } - - override func tearDown() { - super.tearDown() - } - func testPush() { - self.queue.push(31) - XCTAssert(self.queue.list.count == 32) + var queue = makeQueue(loadedWithNumberOfItems: 30) + queue.push(1) + expect(queue.list).to(haveCount(31)) } func testPushContentsOf() { - self.queue.push(contentsOf: [31]) - XCTAssert(self.queue.list.count == 32) - self.queue.push(contentsOf: [32, 33]) - XCTAssert(self.queue.list.count == 34) - self.queue.push(contentsOf: [34, 35].prefix(1)) - XCTAssert(self.queue.list.count == 35) - XCTAssert(self.queue.list.suffix(4) == [31, 32, 33, 34]) - } - + var queue = makeQueue(loadedWithNumberOfItems: 0) + queue.push(contentsOf: [1]) + expect(queue.list).to(haveCount(1)) + + queue.push(contentsOf: [2, 3]) + expect(queue.list).to(haveCount(3)) + + queue.push(contentsOf: [4, 5].prefix(1)) + expect(queue.list).to(haveCount((4))) + + expect(queue.list.suffix(3)) == [2, 3, 4] + } + func testPop() { - XCTAssert(self.queue.pop() == 0) + var queue = makeQueue(loadedWithNumberOfItems: 2) + expect(queue.pop()) == 0 + expect(queue.list).to(haveCount(1)) } - + func testGet() { - XCTAssert(self.queue.get(count:5) == [0,1,2,3,4]) - XCTAssert(self.queue.get(count:5) == [5,6,7,8,9]) - XCTAssert(self.queue.get(count:21) == [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]) - XCTAssert(self.queue.get(count:5) == []) + var queue = makeQueue(loadedWithNumberOfItems: 30) + + expect(queue.get(count: 5)) == [0, 1, 2, 3, 4] + expect(queue.list).to(haveCount(25)) + + expect(queue.get(count: 5)) == [5, 6, 7, 8, 9] + expect(queue.list).to(haveCount(20)) + + expect(queue.get(count: 21)) == (10...29).map { $0 } + expect(queue.list).to(beEmpty()) + + expect(queue.get(count: 5)) == [] } - + func testGetAll() { - XCTAssert(self.queue.get() == [0,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]) + var queue = makeQueue(loadedWithNumberOfItems: 5) + expect(queue.get()) == [0, 1, 2, 3, 4] } - + func testGetTooMany() { - XCTAssert(self.queue.get(count:2147483647) == [0,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]) + var queue = makeQueue(loadedWithNumberOfItems: 5) + expect(queue.get(count: 1_000)) == [0, 1, 2, 3, 4] } - + func testNegativeCount() { - let invalidGetResult = self.queue.get(count:-42) - XCTAssert(invalidGetResult == []) + var queue = makeQueue(loadedWithNumberOfItems: 5) + expect(queue.get(count: -1)) == [] } - -} + func makeQueue(loadedWithNumberOfItems numberOfItem: Int = 30) -> EventQueue { + var queue = EventQueue() + (0.. Date: Thu, 20 Apr 2023 14:47:26 +1000 Subject: [PATCH 02/11] Make `MetadataTests` a simple `XCTestCase` It did not need access to the `ParselyTestCase` APIs --- Tests/MetadataTests.swift | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Tests/MetadataTests.swift b/Tests/MetadataTests.swift index 8399236..e3dd6f5 100644 --- a/Tests/MetadataTests.swift +++ b/Tests/MetadataTests.swift @@ -1,7 +1,8 @@ @testable import ParselyAnalytics import XCTest -class MetadataTests: ParselyTestCase { +class MetadataTests: XCTestCase { + let expected: Dictionary = [ "canonical_url": "http://parsely-test.com", "pub_date": Date(), @@ -12,12 +13,12 @@ class MetadataTests: ParselyTestCase { "tags": ["tag1", "tag2"], "duration": TimeInterval(100) ] - + func testToDictEmpty() { let metas = ParselyMetadata() XCTAssert(metas.toDict().isEmpty, "Creating a ParselyMetadata object with no parameters results in an empty object") } - + func testToDictBasic() { let metas = ParselyMetadata(canonical_url: "http://test.com") let expected = ["link": "http://test.com"] @@ -26,7 +27,7 @@ class MetadataTests: ParselyTestCase { "Creating a ParselyMetadata object with one parameter results in a valid object containing " + "a representation of that parameter") } - + func testToDictFields() { let metasUnderTest = ParselyMetadata( canonical_url: expected["canonical_url"] as? String, @@ -67,7 +68,7 @@ class MetadataTests: ParselyTestCase { "The duration field in the result of ParselyMetadata.toDict should match the duration argument " + "used at initialization") } - + func testMetadata() { let metasUnderTest = ParselyMetadata( canonical_url: expected["canonical_url"] as? String, From 9da8b4692fc9583a7a12e48dfb5a8b0b19da7d45 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:49:04 +1000 Subject: [PATCH 03/11] Make `EventTests` a simple `XCTestCase` It did not need access to the `ParselyTestCase` APIs --- Tests/EventTests.swift | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Tests/EventTests.swift b/Tests/EventTests.swift index 01a7096..6e59533 100644 --- a/Tests/EventTests.swift +++ b/Tests/EventTests.swift @@ -1,37 +1,42 @@ -import XCTest @testable import ParselyAnalytics +import XCTest + +class EventTests: XCTestCase { -class EventTests: ParselyTestCase { let testInc: Int = 5 let testTT: Int = 15 let expectedVisitorID: String = "12345fdffff" let timestampInThePast: UInt64 = 1626963869621 - + let expectedStrings: Dictionary = [ "action": "pageview", "url": "http://parsely-stuff.com", "urlref": "http://testt.com", - "idsite": testApikey, + "idsite": "apikey", "surl": "http://parsely-stuff.com", "sref": "http://parsely-test.com", - ] + ] + let expectedInts: Dictionary = [ "sid": 0, ] + let expectedUInt64s: Dictionary = [ "sts": 1626963869621, "slts": 1626963869621 ] + let extraData: Dictionary = [ "arbitraryParameter1": "testValue", "arbitraryParameter2": "testValue2" ] + let testMetadata: ParselyMetadata = ParselyMetadata( canonical_url: "http://parsely-test.com", pub_date: Date.init(), title: "a title.", authors: ["Yogi Berra"], image_url: "http://parsely-test.com/image2", section: "Things my mother says", tags: ["tag1", "tag2"], duration: TimeInterval(100) ) - + func testEvent() { let eventUnderTest = Event(expectedStrings["action"]!, url: expectedStrings["url"]!, urlref: expectedStrings["urlref"], metadata: testMetadata, @@ -64,7 +69,7 @@ class EventTests: ParselyTestCase { let extraDataIsEquivalent: Bool = NSDictionary(dictionary: eventUnderTest.extra_data!).isEqual(to: extraData) XCTAssert(extraDataIsEquivalent, "The extra_data procided in Event initialization should be stored properly") } - + func testHeartbeatEvents() { let event = Heartbeat( "heartbeat", @@ -80,10 +85,10 @@ class EventTests: ParselyTestCase { XCTAssertEqual(event.url, expectedStrings["url"], "The url used to initialize a heartbeat event should be stored properly") XCTAssertEqual(event.inc, testInc, "The inc parameter used to initialize a heartbeat event should be stored properly") - XCTAssertEqual(event.idsite, ParselyTestCase.testApikey, + XCTAssertEqual(event.idsite, "apikey", "The idsite parameter used to initialize a heartbeat event should be stored properly") } - + func testToDict() { let eventUnderTest = Event(expectedStrings["action"]!, url: expectedStrings["url"]!, urlref: expectedStrings["urlref"], metadata: testMetadata, @@ -120,7 +125,7 @@ class EventTests: ParselyTestCase { XCTAssert((actualExtraData["ts"] as! UInt64) > timestampInThePast, "The data.ts field of the result of Event.toDict should be a non-ancient timestamp") } - + func testSetSessionInfo() { let eventUnderTest = Event(expectedStrings["action"]!, url: expectedStrings["url"]!, urlref: expectedStrings["urlref"], metadata: testMetadata, @@ -143,7 +148,7 @@ class EventTests: ParselyTestCase { XCTAssertEqual(eventUnderTest.session_url, expectedStrings["surl"], "The surl set via setSessionInfo should be stored properly") } - + func testSetVisitorInfo() { let eventUnderTest = Event(expectedStrings["action"]!, url: expectedStrings["url"]!, urlref: expectedStrings["urlref"], metadata: testMetadata, From a13866d00510b35fd218853507048b930d3ed780 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:51:15 +1000 Subject: [PATCH 04/11] Make `RequestBuilderTests` a simple `XCTestCase` It did not need access to the `ParselyTestCase` APIs. --- Tests/RequestBuilderTests.swift | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Tests/RequestBuilderTests.swift b/Tests/RequestBuilderTests.swift index 4f85883..06b443b 100644 --- a/Tests/RequestBuilderTests.swift +++ b/Tests/RequestBuilderTests.swift @@ -2,7 +2,8 @@ import Nimble @testable import ParselyAnalytics import XCTest -class RequestBuilderTests: ParselyTestCase { +class RequestBuilderTests: XCTestCase { + private func makeEvents() -> Array { let exampleMetadata: ParselyMetadata = ParselyMetadata( canonical_url:"http://parsely-test.com", @@ -22,12 +23,12 @@ class RequestBuilderTests: ParselyTestCase { extra_data: nil )] } - + func testEndpoint() { let endpoint = RequestBuilder.buildPixelEndpoint() XCTAssert(endpoint != "", "buildPixelEndpoint should return a non-empty string") } - + func testBuildPixelEndpoint() { var expected: String = "https://p1.parsely.com/mobileproxy" var actual = RequestBuilder.buildPixelEndpoint() @@ -36,7 +37,7 @@ class RequestBuilderTests: ParselyTestCase { actual = RequestBuilder.buildPixelEndpoint() XCTAssert(actual == expected, "buildPixelEndpoint should return the correct URL for the given date") } - + func testHeaders() { let events: Array = makeEvents() let actual: Dictionary = RequestBuilder.buildHeadersDict(events: events) @@ -61,7 +62,7 @@ class RequestBuilderTests: ParselyTestCase { "RequestBuilder.buildRequest should return a request with an events array containing all " + "relevant revents") } - + func testParamsJson() { let events = makeEvents() let request = RequestBuilder.buildRequest(events: events) @@ -71,7 +72,7 @@ class RequestBuilderTests: ParselyTestCase { } catch { } XCTAssertNotNil(jsonData, "Request params should serialize to JSON") } - + func testGetHardwareString() { let result = RequestBuilder.getHardwareString() let expected = Set(["x86_64", "arm64"]) @@ -79,7 +80,7 @@ class RequestBuilderTests: ParselyTestCase { "The result of RequestBuilder.getHardwareString should accurately represent the simulator hardware" ) } - + func testGetUserAgent() { // When the tests run without a host app, like in our setup, the generated User Agent will // be in the format From 18cdbac34c8757cd5987a77af621c0960d5d6415 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:54:00 +1000 Subject: [PATCH 05/11] Make `VisitorTests` a simple `XCTestCase` It did not need access to the `ParselyTestCase` APIs. --- Tests/VisitorTests.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/VisitorTests.swift b/Tests/VisitorTests.swift index 8e2714f..3eaf5cb 100644 --- a/Tests/VisitorTests.swift +++ b/Tests/VisitorTests.swift @@ -1,7 +1,8 @@ import XCTest @testable import ParselyAnalytics -class VisitorTests: ParselyTestCase { +class VisitorTests: XCTestCase { + let visitors: VisitorManager = VisitorManager() func testGetVisitorInfo() { From a7d796b19dabe92d2f75d0c4fb7ef60b40e96fe0 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:55:04 +1000 Subject: [PATCH 06/11] Remove state from `VisitorTests` --- Tests/VisitorTests.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Tests/VisitorTests.swift b/Tests/VisitorTests.swift index 3eaf5cb..9e9221f 100644 --- a/Tests/VisitorTests.swift +++ b/Tests/VisitorTests.swift @@ -3,9 +3,8 @@ import XCTest class VisitorTests: XCTestCase { - let visitors: VisitorManager = VisitorManager() - func testGetVisitorInfo() { + let visitors: VisitorManager = VisitorManager() let visitor = visitors.getVisitorInfo() XCTAssertFalse(visitor.isEmpty, "The first call to VisitorManager.getVisitorInfo should return a non-empty object") // FIXME: Visitor should have a way to expire visitors, at least for testing. Otherwise the first @@ -23,7 +22,9 @@ class VisitorTests: XCTestCase { "Sequential calls to VisitorManager.getVisitorInfo within the default expiry should return objects " + "with the same last session timestamp") } + func testExtendVisitorExpiry() { + let visitors: VisitorManager = VisitorManager() let visitor = visitors.getVisitorInfo() let capturedExpiryOne = visitor["expires"] as! Date let subsequentVisitor = visitors.getVisitorInfo(shouldExtendExisting: true) From 427ba8a08f6a22733b29b8102561e9a5c15fe1c1 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 14:57:46 +1000 Subject: [PATCH 07/11] Refactor `ParselyTestCase` to use `addTeardownBlock` The next step will be to remove the setup method and let subclasses call `makeParselyTracker()`. --- Tests/ParselyTestCase.swift | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Tests/ParselyTestCase.swift b/Tests/ParselyTestCase.swift index 9e56958..418d36e 100644 --- a/Tests/ParselyTestCase.swift +++ b/Tests/ParselyTestCase.swift @@ -7,11 +7,18 @@ class ParselyTestCase: XCTestCase { override func setUp() { super.setUp() - parselyTestTracker = Parsely.getInstance() + parselyTestTracker = makePareslyTracker() } - - override func tearDown() { - parselyTestTracker.hardShutdown() - super.tearDown() + + func makePareslyTracker() -> Parsely { + let tracker = Parsely.getInstance() + + // Note that because we call addTeardownBlock, this method needs to be defined within an + // XCTestCase + addTeardownBlock { + tracker.hardShutdown() + } + + return tracker } } From 79cbfca3f143bc836398bb04dd4fea6329602ca0 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 15:06:21 +1000 Subject: [PATCH 08/11] Replace `testApikey` in `ParselyTestCase` with one on `Parsely` --- Tests/EngagedTimeTests.swift | 30 +++++++++---------- Tests/ParselyTestCase.swift | 6 +++- Tests/ParselyTrackerTests.swift | 13 ++++----- Tests/PixelTests.swift | 2 +- Tests/SamplerTests.swift | 44 ++++++++++++++-------------- Tests/SessionTests.swift | 13 +++++---- Tests/StorageTests.swift | 2 +- Tests/TrackTests.swift | 52 ++++++++++++++++----------------- Tests/VideoTests.swift | 32 ++++++++++---------- 9 files changed, 99 insertions(+), 95 deletions(-) diff --git a/Tests/EngagedTimeTests.swift b/Tests/EngagedTimeTests.swift index 5316af8..a278786 100644 --- a/Tests/EngagedTimeTests.swift +++ b/Tests/EngagedTimeTests.swift @@ -6,16 +6,16 @@ class EngagedTimeTests: ParselyTestCase { var engagedTime: EngagedTime? var sharedInstance: Parsely? let testUrl: String = "http://parsely-stuff.com" - + override func setUp() { super.setUp() engagedTime = EngagedTime(trackerInstance: parselyTestTracker) sharedInstance = Parsely.sharedInstance } - + func testHeartbeatFn() { let dummyEventArgs: Dictionary = engagedTime!.generateEventArgs( - url: testUrl, urlref: "", extra_data: nil, idsite: ParselyTestCase.testApikey) + url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let dummyAccumulator: Accumulator = Accumulator(key: "", accumulatedTime: 0, totalTime: 0, firstSampleTime: Date(), lastSampleTime: Date(), lastPositiveSampleTime: Date(), @@ -25,20 +25,20 @@ class EngagedTimeTests: ParselyTestCase { XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, "A call to EngagedTime.heartbeatFn should add an event to eventQueue") } - + func testStartInteraction() { engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) let internalAccumulators:Dictionary = engagedTime!.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! XCTAssert(testUrlAccumulator.isEngaged, "After a call to EngagedTime.startInteraction, the internal accumulator for the engaged " + "url should exist and its isEngaged flag should be set") } - + func testEndInteraction() { engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) engagedTime!.endInteraction() let internalAccumulators:Dictionary = engagedTime!.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! @@ -47,34 +47,34 @@ class EngagedTimeTests: ParselyTestCase { "EngagedTime.stopInteraction, the internal accumulator for the engaged " + "url should exist and its isEngaged flag should be unset") } - + func testSampleFn() { engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) let sampleResult: Bool = engagedTime!.sampleFn(key: testUrl) XCTAssert(sampleResult, "After a call to EngagedTime.startInteraction, EngagedTime.sample should return true for the interacting key") } - + func testSampleFnPaused() { engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) engagedTime!.endInteraction() let sampleResult: Bool = engagedTime!.sampleFn(key: testUrl) XCTAssertFalse(sampleResult, "After a call to EngagedTime.startInteraction followed by a call to " + "EngagedTime.stopInteraction, EngagedTime.sample should return false for the interacting key") } - - + + func testGlobalPause() { // This is call to configure required for the start-stop mechanism to work - sharedInstance?.configure(siteId: ParselyTestCase.testApikey) + sharedInstance?.configure(siteId: Parsely.testAPIKey) let assertionTimeout:TimeInterval = TimeInterval(3) let acceptableDifference:TimeInterval = TimeInterval(0.2) - sharedInstance!.startEngagement(url: testUrl, urlref: "", extraData: nil, siteId: ParselyTestCase.testApikey) + sharedInstance!.startEngagement(url: testUrl, urlref: "", extraData: nil, siteId: Parsely.testAPIKey) // sleep for three seconds let expectation = self.expectation(description: "Sampling") Timer.scheduledTimer(withTimeInterval: assertionTimeout, repeats: false) { timer in diff --git a/Tests/ParselyTestCase.swift b/Tests/ParselyTestCase.swift index 418d36e..e94e1f3 100644 --- a/Tests/ParselyTestCase.swift +++ b/Tests/ParselyTestCase.swift @@ -3,7 +3,6 @@ import XCTest class ParselyTestCase: XCTestCase { internal var parselyTestTracker: Parsely! - static let testApikey: String = "examplesite.com" override func setUp() { super.setUp() @@ -22,3 +21,8 @@ class ParselyTestCase: XCTestCase { return tracker } } + +extension Parsely { + + static let testAPIKey = "examplesite.com" +} diff --git a/Tests/ParselyTrackerTests.swift b/Tests/ParselyTrackerTests.swift index a689a96..476606f 100644 --- a/Tests/ParselyTrackerTests.swift +++ b/Tests/ParselyTrackerTests.swift @@ -6,18 +6,18 @@ import Nimble class ParselyTrackerTests: ParselyTestCase { let testUrl = "http://example.com/testurl" let testVideoId = "12345" - + override func setUp() { super.setUp() - parselyTestTracker.configure(siteId: ParselyTestCase.testApikey) + parselyTestTracker.configure(siteId: Parsely.testAPIKey) } - + func testConfigure() { - XCTAssertEqual(parselyTestTracker.apikey, ParselyTestCase.testApikey, + XCTAssertEqual(parselyTestTracker.apikey, Parsely.testAPIKey, "After a call to Parsely.configure, Parsely.apikey should be the value used in the call's " + "siteId argument") } - + func testTrackPageView() { XCTAssertEqual(parselyTestTracker.eventQueue.length(), 0, "eventQueue should be empty immediately after initialization") @@ -25,7 +25,7 @@ class ParselyTrackerTests: ParselyTestCase { // A call to Parsely.trackPageView should add an event to eventQueue expectParselyState(self.parselyTestTracker.eventQueue.length()).toEventually(equal(1)) } - + func testStartEngagement() { parselyTestTracker.startEngagement(url: testUrl) // After a call to Parsely.startEngagement, the internal accumulator for the engaged url should exist @@ -88,4 +88,3 @@ class ParselyTrackerTests: ParselyTestCase { } } } - diff --git a/Tests/PixelTests.swift b/Tests/PixelTests.swift index 503c974..1aa5ebc 100644 --- a/Tests/PixelTests.swift +++ b/Tests/PixelTests.swift @@ -4,7 +4,7 @@ import XCTest class PixelTests: ParselyTestCase { func testBeacon() { let dummyEvent = Event("pageview", url: "http://parsely-stuff.com", urlref: "", metadata: nil, extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) parselyTestTracker.track.pixel.beacon(event: dummyEvent) XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, "A call to Parsely.track.pixel.beacon should add an event to eventQueue") diff --git a/Tests/SamplerTests.swift b/Tests/SamplerTests.swift index 9f4d940..4dc0805 100644 --- a/Tests/SamplerTests.swift +++ b/Tests/SamplerTests.swift @@ -4,7 +4,7 @@ import XCTest class SamplerTests: ParselyTestCase { var samplerUnderTest: Sampler? let testKey: String = "thing" - + let extraData: Dictionary = [ "arbitraryParameter1": "testValue", "arbitraryParameter2": "testValue2" @@ -14,12 +14,12 @@ class SamplerTests: ParselyTestCase { image_url: "http://parsely-test.com/image2", section: "Things my mother says", tags: ["tag1", "tag2"], duration: TimeInterval(100) ) - + override func setUp() { super.setUp() samplerUnderTest = Sampler(trackerInstance: parselyTestTracker) } - + func testMultipleTrackedItemsInOneSampler() { let itemOne: String = "itemOne" let itemTwo: String = "itemTwo" @@ -33,15 +33,15 @@ class SamplerTests: ParselyTestCase { func testSampleFn() { let assertionTimeout:TimeInterval = TimeInterval(3) let acceptableDifference:TimeInterval = TimeInterval(0.2) - + samplerUnderTest!.trackKey(key: "sampler-test", contentDuration: nil, eventArgs: [:]) - + let expectation = self.expectation(description: "Sampling") Timer.scheduledTimer(withTimeInterval: assertionTimeout, repeats: false) { timer in expectation.fulfill() } waitForExpectations(timeout: assertionTimeout + acceptableDifference, handler: nil) - + let accumulatedTime:TimeInterval = samplerUnderTest!.accumulators["sampler-test"]!.totalTime XCTAssert(accumulatedTime >= assertionTimeout - acceptableDifference, "The sampler should accumulate time constantly after a call to trackKey") @@ -51,18 +51,18 @@ class SamplerTests: ParselyTestCase { let initialInterval = samplerUnderTest!.heartbeatInterval // Ensure value matches magic number from production code XCTAssertEqual(initialInterval, TimeInterval(10.5)) - + // Track an event, then make the test runner wait for the heartbeat interval plus some extra // time to account for runtime delays. samplerUnderTest!.trackKey(key: "sampler-test", contentDuration: nil, eventArgs: [:]) - + let expectation = self.expectation(description: "Wait for heartbeat") let heartbeatDeliveryInterval = initialInterval + TimeInterval(3) Timer.scheduledTimer(withTimeInterval: heartbeatDeliveryInterval, repeats: false) { timer in expectation.fulfill() } waitForExpectations(timeout: heartbeatDeliveryInterval, handler: nil) - + let actualUpdatedInterval = samplerUnderTest!.heartbeatInterval // This value depends on heartbeatInterval, and two magic numbers in the implementation. // We use the output value instead of writing out the math that computes it because doing @@ -94,24 +94,24 @@ class SamplerTests: ParselyTestCase { XCTAssert(sampler2.accumulators[testKey] != nil, "A Sampler instance should not be affected by dropKey calls on another Sampler instance") } - + func testDropKey() { samplerUnderTest!.trackKey(key: testKey, contentDuration: nil, eventArgs: [:]) samplerUnderTest!.dropKey(key: testKey) XCTAssertNil(samplerUnderTest!.accumulators[testKey], "After a call to Sampler.dropKey, the accumulator for the droppesd key should not exist") } - + func testGenerateEventArgs() { let testUrl: String = "http://parselystuff.com" let eventArgs: Dictionary = samplerUnderTest!.generateEventArgs( url: testUrl, urlref: testUrl, metadata: testMetadata, extra_data: extraData, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) XCTAssertEqual(eventArgs["url"] as! String, testUrl, "The url returned in the result of Sampler.generateEventArgs " + "should match the one passed to the call") XCTAssertEqual(eventArgs["urlref"] as! String, testUrl, "The urlref returned in the result of " + "Sampler.generateEventArgs should match the one passed to the call") - XCTAssertEqual(eventArgs["idsite"] as! String, ParselyTestCase.testApikey, + XCTAssertEqual(eventArgs["idsite"] as! String, Parsely.testAPIKey, "The idsite returned in the result of Sampler.generateEventArgs should match the one passed to the call") let actualExtraData: Dictionary = eventArgs["extra_data"] as! Dictionary for (key, value) in extraData { @@ -124,20 +124,20 @@ class SamplerTests: ParselyTestCase { XCTAssert(result, "The metadata field of the result of Sampler.generateEventArgs should be a dict representation " + "of the given metadata") } - + func testPause() { samplerUnderTest!.pause() XCTAssertNil(samplerUnderTest!.samplerTimer, "After a call to Sampler.pause(), Sampler.samplerTimer should be nil") } - + func testResume() { samplerUnderTest!.pause() samplerUnderTest!.resume() XCTAssertNil(samplerUnderTest!.samplerTimer, "After a call to Sampler.resume() without sampling having started, Sampler.samplerTimer should be nil") } - + func testResumeHasStartedSampling() { samplerUnderTest!.pause() samplerUnderTest!.hasStartedSampling = true @@ -145,30 +145,30 @@ class SamplerTests: ParselyTestCase { XCTAssertNotNil(samplerUnderTest!.samplerTimer, "After a call to Sampler.resume() without sampling having started, Sampler.samplerTimer should be nil") } - + func testPauseStopsCounting() { let assertionTimeout:TimeInterval = TimeInterval(3) let acceptableDifference:TimeInterval = TimeInterval(0.2) - + samplerUnderTest!.trackKey(key: "sampler-test", contentDuration: nil, eventArgs: [:]) - + let expectation = self.expectation(description: "Sampling") Timer.scheduledTimer(withTimeInterval: assertionTimeout, repeats: false) { timer in expectation.fulfill() } waitForExpectations(timeout: assertionTimeout + acceptableDifference, handler: nil) - + let accumulatedTime:TimeInterval = samplerUnderTest!.accumulators["sampler-test"]!.accumulatedTime samplerUnderTest!.pause() XCTAssert(accumulatedTime >= assertionTimeout - acceptableDifference, "The sampler should accumulate time constantly after a call to trackKey") - + let secondExpectation = self.expectation(description: "Paused sampling") Timer.scheduledTimer(withTimeInterval: assertionTimeout, repeats: false) { timer in secondExpectation.fulfill() } waitForExpectations(timeout: assertionTimeout + acceptableDifference, handler: nil) - + let secondAccumulatedTime: TimeInterval = samplerUnderTest!.accumulators["sampler-test"]!.accumulatedTime XCTAssert(secondAccumulatedTime <= assertionTimeout, "AccumulatedTime was \(secondAccumulatedTime)") } diff --git a/Tests/SessionTests.swift b/Tests/SessionTests.swift index 7e342d4..9380e60 100644 --- a/Tests/SessionTests.swift +++ b/Tests/SessionTests.swift @@ -1,20 +1,21 @@ -import XCTest @testable import ParselyAnalytics +import XCTest class SessionTests: ParselyTestCase { + var sessions: SessionManager! let sessionStorageKey = "_parsely_session_identifier" let testInitialUrl = "http://parsely-test.com/123" let testSubsequentUrl = "http://parsely-test.com/" let epochTimeInThePast:UInt64 = 1626963869621 - + override func setUp() { super.setUp() sessions = SessionManager(trackerInstance: parselyTestTracker) - // XXX slight hack, ideally this functionality should be a method on SessionManager + // Note: This is a slight hack, ideally this functionality should be a method on SessionManager Storage().expire(key: sessionStorageKey) } - + func testGet() { let session = sessions.get(url: testInitialUrl, urlref: testSubsequentUrl) XCTAssertGreaterThanOrEqual(session["session_id"] as! Int, 0, @@ -41,7 +42,7 @@ class SessionTests: ParselyTestCase { XCTAssertEqual(session["session_url"] as! String, testInitialUrl, "The url of a session that has been extended with a different url should not have changed") } - + func testGetCorrectlyMutatesVisitor() { let visitorManager = VisitorManager() let visitorInfo = visitorManager.getVisitorInfo() @@ -65,7 +66,7 @@ class SessionTests: ParselyTestCase { "shouldExtendExisting:true should return a session object with an extended expiry value " + "compared to the original expiry of the session") } - + func testExtendExpiry() { let initialSession = sessions.get(url: testInitialUrl, urlref: "") let initialSessionExpiry: Date = initialSession["expires"] as! Date diff --git a/Tests/StorageTests.swift b/Tests/StorageTests.swift index 170da0b..a284a31 100644 --- a/Tests/StorageTests.swift +++ b/Tests/StorageTests.swift @@ -76,7 +76,7 @@ class StorageTests: ParselyTestCase { let actual = storage.get(key: "shouldextend") ?? [:] XCTAssert(actual.isEmpty, "Calls to Storage.get requesting expired keys should return empty objects") } - + func testStoredDataPersistsAcrossStorageInstances() { let expected = ["foo": "bar"] _ = storage.set(key: "baz", value: expected, expires: nil) diff --git a/Tests/TrackTests.swift b/Tests/TrackTests.swift index 360a347..99aab76 100644 --- a/Tests/TrackTests.swift +++ b/Tests/TrackTests.swift @@ -5,32 +5,32 @@ class TrackTests: ParselyTestCase { var track: Track? let testUrl: String = "http://parsely-stuff.com" let testVideoId: String = "1234567dfff" - + override func setUp() { super.setUp() track = Track(trackerInstance: parselyTestTracker) } - + func testTrackEvent() { XCTAssertEqual(parselyTestTracker.eventQueue.length(), 0, "eventQueue should be empty immediately after initialization") let dummyEvent = Event("pageview", url: testUrl, urlref: "", metadata: nil, extra_data: nil, - idsite: ParselyTestCase.testApikey) + idsite: Parsely.testAPIKey) track!.event(event: dummyEvent) XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, "A call to Parsely.track.event should add an event to eventQueue") } - + func testPageview() { XCTAssertEqual(parselyTestTracker.eventQueue.length(), 0, "eventQueue should be empty immediately after initialization") - track!.pageview(url: testUrl, urlref: testUrl, metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + track!.pageview(url: testUrl, urlref: testUrl, metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, "A call to Track.pageview should add an event to eventQueue") } - + func testVideoStart() { track!.videoStart(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), metadata: nil, - extra_data: nil, idsite: ParselyTestCase.testApikey) + extra_data: nil, idsite: Parsely.testAPIKey) let videoManager: VideoManager = track!.videoManager let trackedVideos: Dictionary = videoManager.trackedVideos XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, @@ -41,10 +41,10 @@ class TrackTests: ParselyTestCase { XCTAssert(testVideo.isPlaying, "After a call to Track.videoStart, the tracked video should have its isPlaying flag set") } - + func testVideoPause() { track!.videoStart(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), metadata: nil, - extra_data: nil, idsite: ParselyTestCase.testApikey) + extra_data: nil, idsite: Parsely.testAPIKey) track!.videoPause() let videoManager: VideoManager = track!.videoManager let trackedVideos: Dictionary = videoManager.trackedVideos @@ -55,10 +55,10 @@ class TrackTests: ParselyTestCase { XCTAssertFalse(testVideo.isPlaying, "After a call to Track.videoStart, the tracked video should have its isPlaying flag unset") } - + func testVideoReset() { track!.videoStart(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), metadata: nil, - extra_data: nil, idsite: ParselyTestCase.testApikey) + extra_data: nil, idsite: Parsely.testAPIKey) track!.videoReset(url: testUrl, vId: testVideoId) XCTAssertNotNil(track!.videoManager.samplerTimer, "videoReset should run successfully without the Track instance being paused") @@ -67,18 +67,18 @@ class TrackTests: ParselyTestCase { XCTAssertEqual(trackedVideos.count, 0, "A call to Parsely.resetVideo should remove an tracked video from the video manager") } - + func testStartEngagement() { - track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: ParselyTestCase.testApikey) + track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: Parsely.testAPIKey) let internalAccumulators:Dictionary = track!.engagedTime.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! XCTAssert(testUrlAccumulator.isEngaged, "After a call to Track.startEngagement, the internal accumulator for the engaged url should exist " + "and its isEngaged flag should be set") } - + func testStopEngagement() { - track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: ParselyTestCase.testApikey) + track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: Parsely.testAPIKey) track!.stopEngagement() let internalAccumulators:Dictionary = track!.engagedTime.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! @@ -86,7 +86,7 @@ class TrackTests: ParselyTestCase { "After a call to Track.startEngagement followed by a call to Track.stopEngagement, the internal " + "accumulator for the engaged url should exist and its isEngaged flag should be unset") } - + func testPause() { track!.pause() XCTAssertNil(track!.engagedTime.samplerTimer, @@ -94,7 +94,7 @@ class TrackTests: ParselyTestCase { XCTAssertNil(track!.videoManager.samplerTimer, "After a call to Track.pause(), Track.videoManager.samplerTimer should be nil") } - + func testResumeNoTrack() { track!.pause() track!.resume() @@ -103,11 +103,11 @@ class TrackTests: ParselyTestCase { XCTAssertNil(track!.videoManager.samplerTimer, "After a call to Track.resume() without timers running, Track.videoManager.samplerTimer should be nil") } - + func testResume() { track!.videoStart(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), metadata: nil, - extra_data: nil, idsite: ParselyTestCase.testApikey) - track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: ParselyTestCase.testApikey) + extra_data: nil, idsite: Parsely.testAPIKey) + track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: Parsely.testAPIKey) track!.pause() track!.resume() XCTAssertNotNil(track!.engagedTime.samplerTimer, @@ -115,12 +115,12 @@ class TrackTests: ParselyTestCase { XCTAssertNotNil(track!.videoManager.samplerTimer, "After a call to Track.resume() with timers running, Track.videoManager.samplerTimer should be non-nil") } - + func testSendHeartbeats() { track!.videoStart(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), metadata: nil, - extra_data: nil, idsite: ParselyTestCase.testApikey) - track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: ParselyTestCase.testApikey) - + extra_data: nil, idsite: Parsely.testAPIKey) + track!.startEngagement(url: testUrl, urlref: testUrl, extra_data: nil, idsite: Parsely.testAPIKey) + let assertionTimeout = TimeInterval(2) let acceptableDifference = TimeInterval(0.25) let accumulationExpectation = self.expectation(description: "Heartbeat sending") @@ -128,9 +128,9 @@ class TrackTests: ParselyTestCase { accumulationExpectation.fulfill() } waitForExpectations(timeout: assertionTimeout + acceptableDifference, handler: nil) - + track!.sendHeartbeats() - + let expectedEngagedTimeEvents: Int = 1 let expectedVideoEvents: Int = 2 let expectedTotalEvents: Int = expectedEngagedTimeEvents + expectedVideoEvents diff --git a/Tests/VideoTests.swift b/Tests/VideoTests.swift index bde0e46..a27c08d 100644 --- a/Tests/VideoTests.swift +++ b/Tests/VideoTests.swift @@ -5,32 +5,32 @@ class VideoTests: ParselyTestCase { let testVideoId: String = "videoId" let testUrl: String = "testurl" var videoManager: VideoManager? - + override func setUp() { super.setUp() videoManager = VideoManager(trackerInstance: parselyTestTracker) } - + func testTrackPlay() { XCTAssertEqual(videoManager!.trackedVideos.count, 0, "videoManager.accumulators should be empty before calling trackPlay") videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) XCTAssertEqual(videoManager!.trackedVideos.count, 1, "A call to trackPlay should populate videoManager.accumulators with one object") } - + func testTrackPause() { videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) videoManager!.trackPause() XCTAssertEqual(videoManager!.trackedVideos.count, 1, "A call to trackPause should not remove an accumulator from videoManager.accumulators") } - + func testReset() { videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) videoManager!.reset(url: testUrl, vId: testVideoId) XCTAssertNotNil(videoManager!.samplerTimer, "videoReset should run successfully without the VideoManager instance being paused") @@ -44,7 +44,7 @@ class VideoTests: ParselyTestCase { authors: nil, image_url: nil, section: testSectionFirst, tags: nil, duration: nil) videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: firstTestMetadata, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: firstTestMetadata, extra_data: nil, idsite: Parsely.testAPIKey) let testTrackedVideo: TrackedVideo = videoManager!.trackedVideos.values.first! let actualMetadata: ParselyMetadata = testTrackedVideo.eventArgs["metadata"]! as! ParselyMetadata XCTAssertEqual(actualMetadata.section, testSectionFirst, @@ -54,45 +54,45 @@ class VideoTests: ParselyTestCase { authors: nil, image_url: nil, section: testSectionSecond, tags: nil, duration: nil) videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: secondTestMetadata, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: secondTestMetadata, extra_data: nil, idsite: Parsely.testAPIKey) let secondTestTrackedVideo: TrackedVideo = videoManager!.trackedVideos.values.first! let secondActualMetadata: ParselyMetadata = secondTestTrackedVideo.eventArgs["metadata"]! as! ParselyMetadata XCTAssertEqual(secondActualMetadata.section, testSectionSecond, "The section metadata stored for a preexisting video after a call to parsely.track.videoManager.trackPlay " + "should match the section metadata passed to that call.") } - + func testSampleFn() { let testVideoKey: String = testUrl + "::" + testVideoId videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) let sampleResult: Bool = videoManager!.sampleFn(key: testVideoKey) XCTAssert(sampleResult, "After a call to VideoManager.trackPlay, VideoManager.sample should return true for the viewing key") } - + func testSampleFnPaused() { let testVideoKey: String = testUrl + "::" + testVideoId videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) videoManager!.trackPause() let sampleResult: Bool = videoManager!.sampleFn(key: testVideoKey) XCTAssertFalse(sampleResult, "After a call to VideoManager.trackPlay followed by a call to VideoManager.trackPause, " + "VideoManager.sample should return false for the viewing key") } - + func testHeartbeatFn() { let testVideoKey: String = testUrl + "::" + testVideoId let dummyEventArgs: Dictionary = videoManager!.generateEventArgs( - url: testUrl, urlref: "", extra_data: nil, idsite: ParselyTestCase.testApikey) + url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let dummyAccumulator: Accumulator = Accumulator(key: testVideoKey, accumulatedTime: 0, totalTime: 0, firstSampleTime: Date(), lastSampleTime: Date(), lastPositiveSampleTime: Date(), heartbeatTimeout: 0, contentDuration: 0, isEngaged: false, eventArgs: dummyEventArgs) videoManager!.trackPlay(url: testUrl, urlref: testUrl, vId: testVideoId, duration: TimeInterval(10), - metadata: nil, extra_data: nil, idsite: ParselyTestCase.testApikey) + metadata: nil, extra_data: nil, idsite: Parsely.testAPIKey) videoManager!.heartbeatFn(data: dummyAccumulator, enableHeartbeats: true) XCTAssertEqual(parselyTestTracker.eventQueue.length(), 2, "A call to VideoManager should add two events to eventQueue") From f0eeb6d1c7c15f1bf77013c79497b9e51e6f78d9 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 15:10:41 +1000 Subject: [PATCH 09/11] Remove `sharedInstance` access from `EngagedTimeTests` --- Tests/EngagedTimeTests.swift | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Tests/EngagedTimeTests.swift b/Tests/EngagedTimeTests.swift index a278786..de51e03 100644 --- a/Tests/EngagedTimeTests.swift +++ b/Tests/EngagedTimeTests.swift @@ -4,13 +4,11 @@ import os.log class EngagedTimeTests: ParselyTestCase { var engagedTime: EngagedTime? - var sharedInstance: Parsely? let testUrl: String = "http://parsely-stuff.com" override func setUp() { super.setUp() engagedTime = EngagedTime(trackerInstance: parselyTestTracker) - sharedInstance = Parsely.sharedInstance } func testHeartbeatFn() { @@ -68,13 +66,14 @@ class EngagedTimeTests: ParselyTestCase { func testGlobalPause() { + let parsely = makePareslyTracker() // This is call to configure required for the start-stop mechanism to work - sharedInstance?.configure(siteId: Parsely.testAPIKey) + parsely.configure(siteId: Parsely.testAPIKey) let assertionTimeout:TimeInterval = TimeInterval(3) let acceptableDifference:TimeInterval = TimeInterval(0.2) - sharedInstance!.startEngagement(url: testUrl, urlref: "", extraData: nil, siteId: Parsely.testAPIKey) + parsely.startEngagement(url: testUrl, urlref: "", extraData: nil, siteId: Parsely.testAPIKey) // sleep for three seconds let expectation = self.expectation(description: "Sampling") Timer.scheduledTimer(withTimeInterval: assertionTimeout, repeats: false) { timer in @@ -87,7 +86,7 @@ class EngagedTimeTests: ParselyTestCase { } else{ NotificationCenter.default.post(name: UIApplication.didEnterBackgroundNotification, object: nil) } - let accumulatedTime:TimeInterval = sharedInstance!.track.engagedTime.accumulators[testUrl]!.accumulatedTime + let accumulatedTime:TimeInterval = parsely.track.engagedTime.accumulators[testUrl]!.accumulatedTime XCTAssert(accumulatedTime <= 3, "Engaged time should be less than or equal to 3 seconds but it was \(accumulatedTime)") // sleep for three more seconds @@ -101,8 +100,8 @@ class EngagedTimeTests: ParselyTestCase { NotificationCenter.default.post(name: UIApplication.willEnterForegroundNotification, object: nil) // stop tracking engaged time - sharedInstance!.stopEngagement() - let accumulatedTimeSecond:TimeInterval = sharedInstance!.track.engagedTime.accumulators[testUrl]!.accumulatedTime + parsely.stopEngagement() + let accumulatedTimeSecond:TimeInterval = parsely.track.engagedTime.accumulators[testUrl]!.accumulatedTime XCTAssert(accumulatedTimeSecond == 0.0, "The accumulated time should be zero and it was \(accumulatedTimeSecond)") From dc06f3467dbf89cd9cc37a6c68aead0aedce8c0d Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 15:15:00 +1000 Subject: [PATCH 10/11] Remove `engagedTime` instance property from `EngagedTimeTests` --- Tests/EngagedTimeTests.swift | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/Tests/EngagedTimeTests.swift b/Tests/EngagedTimeTests.swift index de51e03..511a753 100644 --- a/Tests/EngagedTimeTests.swift +++ b/Tests/EngagedTimeTests.swift @@ -1,33 +1,30 @@ -import XCTest import os.log @testable import ParselyAnalytics +import XCTest class EngagedTimeTests: ParselyTestCase { - var engagedTime: EngagedTime? - let testUrl: String = "http://parsely-stuff.com" - override func setUp() { - super.setUp() - engagedTime = EngagedTime(trackerInstance: parselyTestTracker) - } + let testUrl: String = "http://parsely-stuff.com" func testHeartbeatFn() { - let dummyEventArgs: Dictionary = engagedTime!.generateEventArgs( + let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let dummyEventArgs: Dictionary = engagedTime.generateEventArgs( url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let dummyAccumulator: Accumulator = Accumulator(key: "", accumulatedTime: 0, totalTime: 0, firstSampleTime: Date(), lastSampleTime: Date(), lastPositiveSampleTime: Date(), heartbeatTimeout: 0, contentDuration: 0, isEngaged: false, eventArgs: dummyEventArgs) - engagedTime!.heartbeatFn(data: dummyAccumulator, enableHeartbeats: true) + engagedTime.heartbeatFn(data: dummyAccumulator, enableHeartbeats: true) XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, "A call to EngagedTime.heartbeatFn should add an event to eventQueue") } func testStartInteraction() { - engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, + let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) - let internalAccumulators:Dictionary = engagedTime!.accumulators + let internalAccumulators:Dictionary = engagedTime.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! XCTAssert(testUrlAccumulator.isEngaged, "After a call to EngagedTime.startInteraction, the internal accumulator for the engaged " + @@ -35,10 +32,11 @@ class EngagedTimeTests: ParselyTestCase { } func testEndInteraction() { - engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, + let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) - engagedTime!.endInteraction() - let internalAccumulators:Dictionary = engagedTime!.accumulators + engagedTime.endInteraction() + let internalAccumulators:Dictionary = engagedTime.accumulators let testUrlAccumulator: Accumulator = internalAccumulators[testUrl]! XCTAssertFalse(testUrlAccumulator.isEngaged, "After a call to EngagedTime.startInteraction followed by a call to " + @@ -47,18 +45,20 @@ class EngagedTimeTests: ParselyTestCase { } func testSampleFn() { - engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, + let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) - let sampleResult: Bool = engagedTime!.sampleFn(key: testUrl) + let sampleResult: Bool = engagedTime.sampleFn(key: testUrl) XCTAssert(sampleResult, "After a call to EngagedTime.startInteraction, EngagedTime.sample should return true for the interacting key") } func testSampleFnPaused() { - engagedTime!.startInteraction(url: testUrl, urlref: "", extra_data: nil, + let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) - engagedTime!.endInteraction() - let sampleResult: Bool = engagedTime!.sampleFn(key: testUrl) + engagedTime.endInteraction() + let sampleResult: Bool = engagedTime.sampleFn(key: testUrl) XCTAssertFalse(sampleResult, "After a call to EngagedTime.startInteraction followed by a call to " + "EngagedTime.stopInteraction, EngagedTime.sample should return false for the interacting key") From ec6b4bdf350259bba643259fe98d68917b5760e7 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Thu, 20 Apr 2023 15:17:36 +1000 Subject: [PATCH 11/11] Remove state from `EngagedTimeTests` --- Tests/EngagedTimeTests.swift | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Tests/EngagedTimeTests.swift b/Tests/EngagedTimeTests.swift index 511a753..fa4bd27 100644 --- a/Tests/EngagedTimeTests.swift +++ b/Tests/EngagedTimeTests.swift @@ -7,7 +7,8 @@ class EngagedTimeTests: ParselyTestCase { let testUrl: String = "http://parsely-stuff.com" func testHeartbeatFn() { - let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let parsely = makePareslyTracker() + let engagedTime = EngagedTime(trackerInstance: parsely) let dummyEventArgs: Dictionary = engagedTime.generateEventArgs( url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let dummyAccumulator: Accumulator = Accumulator(key: "", accumulatedTime: 0, totalTime: 0, @@ -16,12 +17,12 @@ class EngagedTimeTests: ParselyTestCase { heartbeatTimeout: 0, contentDuration: 0, isEngaged: false, eventArgs: dummyEventArgs) engagedTime.heartbeatFn(data: dummyAccumulator, enableHeartbeats: true) - XCTAssertEqual(parselyTestTracker.eventQueue.length(), 1, + XCTAssertEqual(parsely.eventQueue.length(), 1, "A call to EngagedTime.heartbeatFn should add an event to eventQueue") } func testStartInteraction() { - let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let engagedTime = makeEngagedTime() engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let internalAccumulators:Dictionary = engagedTime.accumulators @@ -32,7 +33,7 @@ class EngagedTimeTests: ParselyTestCase { } func testEndInteraction() { - let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let engagedTime = makeEngagedTime() engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) engagedTime.endInteraction() @@ -45,7 +46,7 @@ class EngagedTimeTests: ParselyTestCase { } func testSampleFn() { - let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let engagedTime = makeEngagedTime() engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) let sampleResult: Bool = engagedTime.sampleFn(key: testUrl) @@ -54,7 +55,7 @@ class EngagedTimeTests: ParselyTestCase { } func testSampleFnPaused() { - let engagedTime = EngagedTime(trackerInstance: parselyTestTracker) + let engagedTime = makeEngagedTime() engagedTime.startInteraction(url: testUrl, urlref: "", extra_data: nil, idsite: Parsely.testAPIKey) engagedTime.endInteraction() @@ -106,4 +107,8 @@ class EngagedTimeTests: ParselyTestCase { "The accumulated time should be zero and it was \(accumulatedTimeSecond)") } + + func makeEngagedTime() -> EngagedTime { + EngagedTime(trackerInstance: makePareslyTracker()) + } }