amplify-swift/AmplifyPlugins/Analytics/Tests/AWSPinpointAnalyticsPluginU.../Pinpoint/SessionClientTests.swift

341 lines
15 KiB
Swift

//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
@testable import AWSPinpointAnalyticsPlugin
import XCTest
class SessionClientTests: XCTestCase {
private var client: SessionClient!
private var activityTracker: MockActivityTracker!
private var analyticsClient: MockAnalyticsClient!
private var archiver: MockArchiver!
private var endpointClient: MockEndpointClient!
private var userDefaults: MockUserDefaults!
private var sessionTimeout: TimeInterval = 5
override func setUp() {
activityTracker = MockActivityTracker()
archiver = MockArchiver()
userDefaults = MockUserDefaults()
analyticsClient = MockAnalyticsClient()
endpointClient = MockEndpointClient()
createNewSessionClient()
}
override func tearDown() {
activityTracker = nil
archiver = nil
userDefaults = nil
analyticsClient = nil
endpointClient = nil
client = nil
}
func createNewSessionClient() {
client = SessionClient(activityTracker: activityTracker,
analyticsClient: analyticsClient,
archiver: archiver,
configuration: SessionClientConfiguration(appId: "appId",
uniqueDeviceId: "deviceId",
sessionBackgroundTimeout: sessionTimeout),
endpointClient: endpointClient,
userDefaults: userDefaults)
}
func resetCounters() async {
await analyticsClient.resetCounters()
activityTracker.resetCounters()
archiver.resetCounters()
await endpointClient.resetCounters()
userDefaults.resetCounters()
}
func storeSession(isPaused: Bool = false, isExpired: Bool = false) {
let start = isExpired ? Date().addingTimeInterval(-sessionTimeout) : Date()
let end: Date? = isPaused ? Date() : nil
let savedSession = PinpointSession(sessionId: "stored", startTime: start, stopTime: end)
userDefaults.mockedValue = Data()
archiver.decoded = savedSession
}
func testRetrieveStoredSessionWithoutSavedSession() {
XCTAssertEqual(userDefaults.dataForKeyCount, 1)
XCTAssertEqual(archiver.decodeCount, 0)
}
func testRetrieveStoredSession() {
// Validate SessionClient created without a stored Session
XCTAssertEqual(userDefaults.dataForKeyCount, 1)
XCTAssertEqual(archiver.decodeCount, 0)
// Validate SessionClient created with a stored Session
storeSession()
createNewSessionClient()
XCTAssertEqual(userDefaults.dataForKeyCount, 2)
XCTAssertEqual(archiver.decodeCount, 1)
}
func testCurrentSession_withoutStoredSession_shouldStartNewSession() async {
let currentSession = client.currentSession
XCTAssertFalse(currentSession.isPaused)
XCTAssertNil(currentSession.stopTime)
XCTAssertEqual(archiver.encodeCount, 1)
XCTAssertEqual(activityTracker.beginActivityTrackingCount, 0)
XCTAssertEqual(userDefaults.saveCount, 1)
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
await waitForExpectations(timeout: 1)
let updateEndpointProfileCount = await endpointClient.updateEndpointProfileCount
XCTAssertEqual(updateEndpointProfileCount, 1)
let createEventCount = await analyticsClient.createEventCount
XCTAssertEqual(createEventCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
}
func testCurrentSession_withStoredSession_shouldNotStartNewSession() async {
storeSession()
createNewSessionClient()
let currentSession = client.currentSession
XCTAssertFalse(currentSession.isPaused)
XCTAssertNil(currentSession.stopTime)
XCTAssertEqual(archiver.encodeCount, 0)
XCTAssertEqual(activityTracker.beginActivityTrackingCount, 0)
XCTAssertEqual(userDefaults.saveCount, 0)
}
func testValidateSession_withValidSession_andStoredSession_shouldReturnValidSession() async {
storeSession()
await resetCounters()
let session = PinpointSession(sessionId: "valid", startTime: Date(), stopTime: nil)
let retrievedSession = client.validateOrRetrieveSession(session)
XCTAssertEqual(userDefaults.dataForKeyCount, 0)
XCTAssertEqual(archiver.decodeCount, 0)
XCTAssertEqual(retrievedSession.sessionId, "valid")
}
func testValidateSession_withInvalidSession_andStoredSession_shouldReturnStoredSession() async {
storeSession()
await resetCounters()
let session = PinpointSession(sessionId: "", startTime: Date(), stopTime: nil)
let retrievedSession = client.validateOrRetrieveSession(session)
XCTAssertEqual(userDefaults.dataForKeyCount, 1)
XCTAssertEqual(archiver.decodeCount, 1)
XCTAssertEqual(retrievedSession.sessionId, "stored")
}
func testValidateSession_withInvalidSession_andWithoutStoredSession_shouldCreateDefaultSession() async {
await resetCounters()
let session = PinpointSession(sessionId: "", startTime: Date(), stopTime: nil)
let retrievedSession = client.validateOrRetrieveSession(session)
XCTAssertEqual(userDefaults.dataForKeyCount, 1)
XCTAssertEqual(archiver.decodeCount, 0)
XCTAssertEqual(retrievedSession.sessionId, PinpointSession.Constants.defaultSessionId)
}
func testValidateSession_withNilSession_andWithoutStoredSession_shouldCreateDefaultSession() async {
await resetCounters()
let retrievedSession = client.validateOrRetrieveSession(nil)
XCTAssertEqual(userDefaults.dataForKeyCount, 1)
XCTAssertEqual(archiver.decodeCount, 0)
XCTAssertEqual(retrievedSession.sessionId, PinpointSession.Constants.defaultSessionId)
}
func testStartPinpointSession_shouldRecordStartEvent() async {
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
client.startPinpointSession()
await waitForExpectations(timeout: 1)
let updateEndpointProfileCount = await endpointClient.updateEndpointProfileCount
XCTAssertEqual(updateEndpointProfileCount, 1)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
guard let event = await analyticsClient.lastRecordedEvent else {
XCTFail("Expected recorded event")
return
}
XCTAssertEqual(event.eventType, SessionClient.Constants.Events.start)
}
func testStartPinpointSession_withExistingSession_shouldRecordStopEvent() async {
storeSession()
createNewSessionClient()
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Stop event for current session and Start event for a new one"),
count: 2)
client.startPinpointSession()
await waitForExpectations(timeout: 1)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 2)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 2)
let events = await analyticsClient.recordedEvents
XCTAssertEqual(events.count, 2)
XCTAssertNotNil(events.first(where: { $0.eventType == SessionClient.Constants.Events.stop }))
XCTAssertNotNil(events.first(where: { $0.eventType == SessionClient.Constants.Events.start }))
}
#if !os(macOS)
func testApplicationMovedToBackground_notStale_shouldSaveSession_andRecordPauseEvent() async {
client.startPinpointSession()
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
await waitForExpectations(timeout: 1)
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Pause event for current session"))
activityTracker.callback?(.runningInBackground(isStale: false))
await waitForExpectations(timeout: 1)
XCTAssertEqual(archiver.encodeCount, 1)
XCTAssertEqual(userDefaults.saveCount, 1)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
guard let event = await analyticsClient.lastRecordedEvent else {
XCTFail("Expected recorded event")
return
}
XCTAssertEqual(event.eventType, SessionClient.Constants.Events.pause)
}
func testApplicationMovedToBackground_stale_shouldRecordStopEvent_andSubmit() async {
client.startPinpointSession()
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
await waitForExpectations(timeout: 1)
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Stop event for current session"))
await analyticsClient.setSubmitEventsExpectation(expectation(description: "Submit events"))
activityTracker.callback?(.runningInBackground(isStale: true))
await waitForExpectations(timeout: 1)
XCTAssertEqual(archiver.encodeCount, 0)
XCTAssertEqual(userDefaults.saveCount, 0)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
guard let event = await analyticsClient.lastRecordedEvent else {
XCTFail("Expected recorded event")
return
}
XCTAssertEqual(event.eventType, SessionClient.Constants.Events.stop)
let submitCount = await analyticsClient.submitEventsCount
XCTAssertEqual(submitCount, 1)
}
func testApplicationMovedToForeground_withNonPausedSession_shouldDoNothing() async {
client.startPinpointSession()
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
await waitForExpectations(timeout: 1)
await resetCounters()
activityTracker.callback?(.runningInForeground)
XCTAssertEqual(archiver.encodeCount, 0)
XCTAssertEqual(userDefaults.saveCount, 0)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 0)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 0)
let event = await analyticsClient.lastRecordedEvent
XCTAssertNil(event)
}
func testApplicationMovedToForeground_withNonExpiredSession_shouldRecordResumeEvent() async {
sessionTimeout = 1000
createNewSessionClient()
client.startPinpointSession()
// First pause the session
activityTracker.callback?(.runningInBackground(isStale: false))
await analyticsClient.setRecordExpectation(expectation(description: "Start and Pause event for new session"), count: 2)
await waitForExpectations(timeout: 1)
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Resume event for non-expired session"))
activityTracker.callback?(.runningInForeground)
await waitForExpectations(timeout: 1)
XCTAssertEqual(archiver.encodeCount, 1)
XCTAssertEqual(userDefaults.saveCount, 1)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
guard let event = await analyticsClient.lastRecordedEvent else {
XCTFail("Expected recorded event")
return
}
XCTAssertEqual(event.eventType, SessionClient.Constants.Events.resume)
}
func testApplicationMovedToForeground_withExpiredSession_shouldStartNewSession() async {
sessionTimeout = 0
createNewSessionClient()
client.startPinpointSession()
// First pause the session
activityTracker.callback?(.runningInBackground(isStale: false))
await analyticsClient.setRecordExpectation(expectation(description: "Start and Pause event for new session"), count: 2)
await waitForExpectations(timeout: 1)
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Stop event for expired session and Start event for a new one"),
count: 2)
activityTracker.callback?(.runningInForeground)
await waitForExpectations(timeout: 1)
XCTAssertEqual(archiver.encodeCount, 1)
XCTAssertEqual(userDefaults.saveCount, 1)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 2)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 2)
let events = await analyticsClient.recordedEvents
XCTAssertEqual(events.count, 2)
XCTAssertNotNil(events.first(where: { $0.eventType == SessionClient.Constants.Events.stop }))
XCTAssertNotNil(events.first(where: { $0.eventType == SessionClient.Constants.Events.start }))
}
#endif
func testApplicationTerminated_shouldRecordStopEvent() async {
client.startPinpointSession()
await analyticsClient.setRecordExpectation(expectation(description: "Start event for new session"))
await waitForExpectations(timeout: 1)
await resetCounters()
await analyticsClient.setRecordExpectation(expectation(description: "Stop event for current session"))
activityTracker.callback?(.terminated)
await waitForExpectations(timeout: 1)
XCTAssertEqual(archiver.encodeCount, 0)
XCTAssertEqual(userDefaults.saveCount, 0)
let createCount = await analyticsClient.createEventCount
XCTAssertEqual(createCount, 1)
let recordCount = await analyticsClient.recordCount
XCTAssertEqual(recordCount, 1)
guard let event = await analyticsClient.lastRecordedEvent else {
XCTFail("Expected recorded event")
return
}
XCTAssertEqual(event.eventType, SessionClient.Constants.Events.stop)
let submitCount = await analyticsClient.submitEventsCount
XCTAssertEqual(submitCount, 0)
}
}