Files
Termind/TFITests/MobilePersistentSessionCloseTests.swift

73 lines
3.1 KiB
Swift

// SPDX-FileCopyrightText: 2026 Kaede Akino
// SPDX-License-Identifier: GPL-3.0-only
import Foundation
import TermindApplication
import TermindDomain
import TermindRemoteInfrastructure
import Testing
@testable import TermindIOS
@Suite @MainActor
struct MobilePersistentSessionCloseTests {
@Test(arguments: ["single", "others", "all"], [false, true])
func closeRemovesLocalWorkBeforeCleanupAndNeverRemovesLaterWork(action: String, unopened: Bool) async throws {
var dependencies = MobileAppDependencies.testing()
var attempts = 0
dependencies.persistentSessionTerminator = RemoteSessionTerminator { _ in
attempts += 1
try await Task.sleep(for: .seconds(60))
throw CancellationError()
}
let app = try MobileAppModel(dependencies: dependencies)
let identity = Identity(name: "User", username: "user")
app.library.upsert(identity)
let host = Host(name: "Host", host: "example.invalid", identityID: identity.id)
app.library.upsert(host)
let transports: [HostTerminalProtocol] = [.ssh, .mosh, .eternalTerminal]
let descriptors = (0..<3).map { index in
MobileWorkspaceDescriptor(
hostID: host.id, title: "Shell \(index)", kind: .terminal(transports[index]),
remoteSession: .init(
backend: .tmux, session: .init(id: "\(index)", name: "Shell", identity: Data([UInt8(index)])),
hostID: host.id, endpoint: "example.invalid:22", username: "user", ownershipToken: UUID()))
}
let session = MobileWorkspaceSessionModel(
id: "background-close", app: app, descriptors: unopened ? descriptors : [])
if !unopened { session.restoreClosedStates(descriptors.map { .init(descriptor: $0) }) }
defer {
app.persistentSessionCloser.cancelAll()
session.closeAll(authorized: true)
}
let remaining: Int
switch action {
case "single":
session.close(descriptors[0].id)
remaining = 2
case "others":
session.closeOtherWorkspaces(than: descriptors[0].id)
remaining = 1
default:
session.closeAll()
remaining = 0
}
#expect(session.orderedWorkspaceItems.count == remaining)
#expect(attempts == 0)
#expect(app.persistentSessionCloser.isClosing)
#expect(app.closedWorkspaceRecords.flatMap(\.items).allSatisfy { $0.remoteSession == nil })
let added = MobileWorkspaceDescriptor(hostID: host.id, title: "New work", kind: .ssh)
session.restoreClosedStates([.init(descriptor: added)])
for _ in 0..<200 {
if attempts == 3 - remaining { break }
try await Task.sleep(for: .milliseconds(5))
}
#expect(attempts == 3 - remaining)
app.persistentSessionCloser.cancelAll()
await app.persistentSessionCloser.waitUntilIdle()
#expect(session.orderedWorkspaceItems.count == remaining + 1)
#expect(session.workspaces.contains { $0.id == added.id })
}
}