feat: auto-update feature
This commit is contained in:
148
GazeTests/Services/UpdateManagerTests.swift
Normal file
148
GazeTests/Services/UpdateManagerTests.swift
Normal file
@@ -0,0 +1,148 @@
|
||||
//
|
||||
// UpdateManagerTests.swift
|
||||
// GazeTests
|
||||
//
|
||||
// Created by Mike Freno on 1/11/26.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Combine
|
||||
@testable import Gaze
|
||||
|
||||
@MainActor
|
||||
final class UpdateManagerTests: XCTestCase {
|
||||
|
||||
var sut: UpdateManager!
|
||||
var cancellables: Set<AnyCancellable>!
|
||||
|
||||
override func setUp() async throws {
|
||||
try await super.setUp()
|
||||
sut = UpdateManager.shared
|
||||
cancellables = []
|
||||
}
|
||||
|
||||
override func tearDown() async throws {
|
||||
cancellables = nil
|
||||
sut = nil
|
||||
try await super.tearDown()
|
||||
}
|
||||
|
||||
// MARK: - Singleton Tests
|
||||
|
||||
func testSingletonInstance() {
|
||||
// Arrange & Act
|
||||
let instance1 = UpdateManager.shared
|
||||
let instance2 = UpdateManager.shared
|
||||
|
||||
// Assert
|
||||
XCTAssertTrue(instance1 === instance2, "UpdateManager should be a singleton")
|
||||
}
|
||||
|
||||
// MARK: - Initialization Tests
|
||||
|
||||
func testInitialization() {
|
||||
// Assert
|
||||
XCTAssertNotNil(sut, "UpdateManager should initialize")
|
||||
}
|
||||
|
||||
func testInitialObservableProperties() {
|
||||
// Assert - Check that properties are initialized (values may vary)
|
||||
// automaticallyChecksForUpdates could be true or false based on Info.plist
|
||||
// Just verify it's a valid boolean
|
||||
XCTAssertTrue(
|
||||
sut.automaticallyChecksForUpdates == true || sut.automaticallyChecksForUpdates == false,
|
||||
"automaticallyChecksForUpdates should be a valid boolean"
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Observable Property Tests
|
||||
|
||||
func testAutomaticallyChecksForUpdatesIsPublished() async throws {
|
||||
// Arrange
|
||||
let expectation = expectation(description: "automaticallyChecksForUpdates property change observed")
|
||||
var observedValue: Bool?
|
||||
|
||||
// Act - Subscribe to published property
|
||||
sut.$automaticallyChecksForUpdates
|
||||
.dropFirst() // Skip initial value
|
||||
.sink { newValue in
|
||||
observedValue = newValue
|
||||
expectation.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// Toggle the value (toggle to ensure change regardless of initial value)
|
||||
let originalValue = sut.automaticallyChecksForUpdates
|
||||
sut.automaticallyChecksForUpdates = !originalValue
|
||||
|
||||
// Assert
|
||||
await fulfillment(of: [expectation], timeout: 2.0)
|
||||
XCTAssertNotNil(observedValue, "Should observe a value change")
|
||||
XCTAssertEqual(observedValue, !originalValue, "Observed value should match the new value")
|
||||
}
|
||||
|
||||
func testLastUpdateCheckDateIsPublished() async throws {
|
||||
// Arrange
|
||||
let expectation = expectation(description: "lastUpdateCheckDate property change observed")
|
||||
var observedValue: Date?
|
||||
var changeDetected = false
|
||||
|
||||
// Act - Subscribe to published property
|
||||
sut.$lastUpdateCheckDate
|
||||
.dropFirst() // Skip initial value
|
||||
.sink { newValue in
|
||||
observedValue = newValue
|
||||
changeDetected = true
|
||||
expectation.fulfill()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
// Set a new date
|
||||
let testDate = Date(timeIntervalSince1970: 1000000)
|
||||
sut.lastUpdateCheckDate = testDate
|
||||
|
||||
// Assert
|
||||
await fulfillment(of: [expectation], timeout: 2.0)
|
||||
XCTAssertTrue(changeDetected, "Should detect property change")
|
||||
XCTAssertEqual(observedValue, testDate, "Observed date should match the set date")
|
||||
}
|
||||
|
||||
// MARK: - Update Check Tests
|
||||
|
||||
func testCheckForUpdatesDoesNotCrash() {
|
||||
// Arrange - method should be callable without crash
|
||||
|
||||
// Act & Assert
|
||||
XCTAssertNoThrow(
|
||||
sut.checkForUpdates(),
|
||||
"checkForUpdates should not throw or crash"
|
||||
)
|
||||
}
|
||||
|
||||
func testCheckForUpdatesIsCallable() {
|
||||
// Arrange
|
||||
var didComplete = false
|
||||
|
||||
// Act
|
||||
sut.checkForUpdates()
|
||||
didComplete = true
|
||||
|
||||
// Assert
|
||||
XCTAssertTrue(didComplete, "checkForUpdates should complete synchronously")
|
||||
}
|
||||
|
||||
// MARK: - Integration Tests
|
||||
|
||||
func testCheckForUpdatesIsAvailableAfterInitialization() {
|
||||
// Arrange & Act
|
||||
// checkForUpdates should be available immediately after initialization
|
||||
var didExecute = false
|
||||
|
||||
// Act - Call the method
|
||||
sut.checkForUpdates()
|
||||
didExecute = true
|
||||
|
||||
// Assert
|
||||
XCTAssertTrue(didExecute, "checkForUpdates should be callable after initialization")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user