mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-09 19:29:41 +00:00
99 lines
4.6 KiB
Swift
99 lines
4.6 KiB
Swift
import HapiClient
|
|
import HapiProtocol
|
|
import XCTest
|
|
@testable import Hapi
|
|
|
|
@MainActor
|
|
final class SessionRowStatusTests: XCTestCase {
|
|
func testAuthoritativeKindsDetermineAttentionWithoutGuessingFromTools() {
|
|
let cases: [([PendingRequestKind], SessionRowStatus)] = [
|
|
([.input], .needsReply(7)),
|
|
([.permission], .needsApproval(7)),
|
|
([.input, .permission], .needsAttention(7)),
|
|
([.permission, .input], .needsAttention(7)),
|
|
([], .needsAttention(7)),
|
|
]
|
|
for (kinds, expected) in cases {
|
|
var summary = HomeFilterTestData.summary("a", machine: "mac")
|
|
summary.pendingRequestsCount = 7
|
|
summary.pendingRequestKinds = kinds
|
|
// Deliberately misleading and capped: neither its length nor
|
|
// its first tool can replace the authoritative total/kinds.
|
|
summary.pendingRequests = [.init(id: "r", kind: .input, tool: "request_user_input", since: 0)]
|
|
XCTAssertEqual(SessionRowStatus(summary: summary), expected)
|
|
XCTAssertEqual(SessionRowStatus(summary: summary)?.count, 7)
|
|
}
|
|
}
|
|
|
|
func testPendingWinsOverThinkingAndSurvivesDisconnection() {
|
|
var summary = HomeFilterTestData.summary("a", machine: nil)
|
|
summary.thinking = true
|
|
XCTAssertEqual(SessionRowStatus(summary: summary), .running)
|
|
summary.pendingRequestsCount = 1
|
|
summary.pendingRequestKinds = [.input]
|
|
XCTAssertEqual(SessionRowStatus(summary: summary), .needsReply(1))
|
|
summary.active = false
|
|
XCTAssertEqual(SessionRowStatus(summary: summary), .needsReply(1))
|
|
summary.pendingRequestsCount = 0
|
|
XCTAssertNil(SessionRowStatus(summary: summary), "Stale kinds and thinking do not imply pending/connected activity")
|
|
summary.active = true
|
|
XCTAssertEqual(SessionRowStatus(summary: summary), .running)
|
|
summary.thinking = false
|
|
XCTAssertNil(SessionRowStatus(summary: summary))
|
|
}
|
|
|
|
func testReadingDoesNotResolveAttentionAndResolutionKeepsTheProject() {
|
|
var summary = HomeFilterTestData.summary("a", machine: "mac")
|
|
summary.metadata?.summary = .init(text: "Keep the session context visible")
|
|
summary.pendingRequestsCount = 2
|
|
summary.pendingRequestKinds = [.permission]
|
|
let sessions = HomeFilterTestSessions([summary])
|
|
let model = HomeFilterTestData.model(sessions: sessions)
|
|
XCTAssertTrue(model.rows[0].unread)
|
|
XCTAssertEqual(model.rows[0].status, .needsApproval(2))
|
|
|
|
model.onSessionOpened("a")
|
|
XCTAssertFalse(model.rows[0].unread)
|
|
XCTAssertEqual(model.rows[0].status, .needsApproval(2))
|
|
XCTAssertEqual(model.rows[0].project, "hapi")
|
|
|
|
sessions.sessions[0].pendingRequestsCount = 0
|
|
sessions.sessions[0].pendingRequestKinds = []
|
|
XCTAssertNil(model.rows[0].status)
|
|
XCTAssertEqual(model.rows[0].project, "hapi")
|
|
sessions.sessions[0].thinking = true
|
|
XCTAssertEqual(model.rows[0].status, .running)
|
|
sessions.sessions[0].updatedAt += 1
|
|
XCTAssertTrue(model.rows[0].unread, "Existing updatedAt-based unread semantics stay intact")
|
|
}
|
|
|
|
func testMissingMetadataDoesNotCreatePlaceholderContent() {
|
|
var summary = HomeFilterTestData.summary("a", machine: nil)
|
|
summary.metadata = nil
|
|
let model = HomeFilterTestData.model(sessions: HomeFilterTestSessions([summary]))
|
|
XCTAssertNil(model.rows[0].status)
|
|
XCTAssertNil(model.rows[0].project)
|
|
}
|
|
|
|
func testProjectIsOnlyTheRepositoryNameIncludingWorktreesAndWindowsPaths() {
|
|
var summary = HomeFilterTestData.summary("a", machine: "mac")
|
|
XCTAssertEqual(SessionListModel.projectLabel(summary), "hapi")
|
|
summary.metadata?.path = "C:\\workspace\\hapi\\"
|
|
XCTAssertEqual(SessionListModel.projectLabel(summary), "hapi")
|
|
summary.metadata?.path = "/tmp/checkouts/generated-branch"
|
|
summary.metadata?.worktree = .init(basePath: "/workspace/hapi", branch: "feature", name: "generated-branch")
|
|
XCTAssertEqual(SessionListModel.projectLabel(summary), "hapi")
|
|
summary.metadata?.worktree = nil
|
|
summary.metadata?.path = "/"
|
|
XCTAssertNil(SessionListModel.projectLabel(summary))
|
|
}
|
|
|
|
func testStatusCopyIsHumanFacing() {
|
|
XCTAssertEqual(SessionRowStatus.needsReply(1).titleKey, "Needs reply")
|
|
XCTAssertEqual(SessionRowStatus.needsApproval(2).titleKey, "Needs approval")
|
|
XCTAssertEqual(SessionRowStatus.needsAttention(7).titleKey, "Needs attention")
|
|
XCTAssertEqual(SessionRowStatus.running.titleKey, "Running")
|
|
XCTAssertNil(SessionRowStatus.running.count)
|
|
}
|
|
}
|