Files
ghostty/macos/Tests/Update/UpdateViewModelTests.swift
Mitchell Hashimoto 8f1a014afd macos: clean up the "installing" update state (#9170)
This includes multiple changes to clean up the "installing" state:

- Ghostty will not confirm quit, since the user has already confirmed
they want to restart to install the update.
- If termination fails for any reason, the popover has a button to retry
restarting.
- The copy and badge symbol have been updated to better match the
reality of the "installing" state.

<img width="1756" height="890" alt="CleanShot 2025-10-12 at 15 04 08@2x"
src="https://github.com/user-attachments/assets/1b769518-e15f-4758-be3b-c45163fa2603"
/>

AI written:
https://ampcode.com/threads/T-623d1030-419f-413f-a285-e79c86a4246b fully
understood.
2025-10-12 15:20:26 -07:00

98 lines
3.5 KiB
Swift

import Testing
import Foundation
import SwiftUI
import Sparkle
@testable import Ghostty
struct UpdateViewModelTests {
// MARK: - Text Formatting Tests
@Test func testIdleText() {
let viewModel = UpdateViewModel()
viewModel.state = .idle
#expect(viewModel.text == "")
}
@Test func testPermissionRequestText() {
let viewModel = UpdateViewModel()
let request = SPUUpdatePermissionRequest(systemProfile: [])
viewModel.state = .permissionRequest(.init(request: request, reply: { _ in }))
#expect(viewModel.text == "Enable Automatic Updates?")
}
@Test func testCheckingText() {
let viewModel = UpdateViewModel()
viewModel.state = .checking(.init(cancel: {}))
#expect(viewModel.text == "Checking for Updates…")
}
@Test func testDownloadingTextWithKnownLength() {
let viewModel = UpdateViewModel()
viewModel.state = .downloading(.init(cancel: {}, expectedLength: 1000, progress: 500))
#expect(viewModel.text == "Downloading: 50%")
}
@Test func testDownloadingTextWithUnknownLength() {
let viewModel = UpdateViewModel()
viewModel.state = .downloading(.init(cancel: {}, expectedLength: nil, progress: 500))
#expect(viewModel.text == "Downloading…")
}
@Test func testDownloadingTextWithZeroExpectedLength() {
let viewModel = UpdateViewModel()
viewModel.state = .downloading(.init(cancel: {}, expectedLength: 0, progress: 500))
#expect(viewModel.text == "Downloading…")
}
@Test func testExtractingText() {
let viewModel = UpdateViewModel()
viewModel.state = .extracting(.init(progress: 0.75))
#expect(viewModel.text == "Preparing: 75%")
}
@Test func testReadyToInstallText() {
let viewModel = UpdateViewModel()
viewModel.state = .readyToInstall(.init(reply: { _ in }))
#expect(viewModel.text == "Install Update")
}
@Test func testInstallingText() {
let viewModel = UpdateViewModel()
viewModel.state = .installing(.init(retryTerminatingApplication: {}))
#expect(viewModel.text == "Restart to Complete Update")
}
@Test func testNotFoundText() {
let viewModel = UpdateViewModel()
viewModel.state = .notFound(.init(acknowledgement: {}))
#expect(viewModel.text == "No Updates Available")
}
@Test func testErrorText() {
let viewModel = UpdateViewModel()
let error = NSError(domain: "Test", code: 1, userInfo: [NSLocalizedDescriptionKey: "Network error"])
viewModel.state = .error(.init(error: error, retry: {}, dismiss: {}))
#expect(viewModel.text == "Network error")
}
// MARK: - Max Width Text Tests
@Test func testMaxWidthTextForDownloading() {
let viewModel = UpdateViewModel()
viewModel.state = .downloading(.init(cancel: {}, expectedLength: 1000, progress: 50))
#expect(viewModel.maxWidthText == "Downloading: 100%")
}
@Test func testMaxWidthTextForExtracting() {
let viewModel = UpdateViewModel()
viewModel.state = .extracting(.init(progress: 0.5))
#expect(viewModel.maxWidthText == "Preparing: 100%")
}
@Test func testMaxWidthTextForNonProgressState() {
let viewModel = UpdateViewModel()
viewModel.state = .checking(.init(cancel: {}))
#expect(viewModel.maxWidthText == viewModel.text)
}
}