Files
steipete--codexbar/Tests/CodexBarTests/ClaudeLoginRunnerTests.swift
T
2026-07-13 12:22:33 +08:00

108 lines
3.8 KiB
Swift

import Foundation
import Testing
@testable import CodexBar
@Suite(.serialized)
struct ClaudeLoginRunnerTests {
@Test
func `dedicated auth command opens browser prompt and completes successfully`() async throws {
let fixture = try self.makeFixture(script: """
#!/bin/sh
printf 'args:%s\\n' "$*"
printf 'Authenticate your account at (press ENTER to open in browser): '
IFS= read -r _
printf 'https://claude.ai/oauth/authorize?test=1\\n'
printf 'Successfully logged in\\n'
""")
defer { fixture.remove() }
let result = await ClaudeLoginRunner.run(
timeout: 2,
binary: fixture.executable.path,
environment: fixture.environment,
onPhaseChange: { _ in })
guard case .success = result.outcome else {
Issue.record("Expected success, got \(String(describing: result.outcome))")
return
}
#expect(result.output.contains("args:auth login --claudeai"))
#expect(result.authLink == "https://claude.ai/oauth/authorize?test=1")
}
@Test
func `authorization URL alone is not treated as success`() async throws {
let fixture = try self.makeFixture(script: """
#!/bin/sh
printf 'https://claude.ai/oauth/authorize?test=1\\n'
/bin/sleep 5
""")
defer { fixture.remove() }
let result = await ClaudeLoginRunner.run(
timeout: 1,
binary: fixture.executable.path,
environment: fixture.environment,
onPhaseChange: { _ in })
guard case .timedOut = result.outcome else {
Issue.record("Expected timeout, got \(String(describing: result.outcome))")
return
}
#expect(result.authLink == "https://claude.ai/oauth/authorize?test=1")
}
@Test
func `dedicated auth command preserves failure status`() async throws {
let fixture = try self.makeFixture(script: """
#!/bin/sh
printf 'login failed\\n'
exit 7
""")
defer { fixture.remove() }
let result = await ClaudeLoginRunner.run(
timeout: 2,
binary: fixture.executable.path,
environment: fixture.environment,
onPhaseChange: { _ in })
guard case .failed(status: 7) = result.outcome else {
Issue.record("Expected status 7, got \(String(describing: result.outcome))")
return
}
#expect(result.output.contains("login failed"))
}
private func makeFixture(script: String) throws -> Fixture {
let root = FileManager.default.temporaryDirectory
.appendingPathComponent("codexbar-claude-login-\(UUID().uuidString)", isDirectory: true)
let binDirectory = root.appendingPathComponent("bin", isDirectory: true)
let homeDirectory = root.appendingPathComponent("home", isDirectory: true)
try FileManager.default.createDirectory(at: binDirectory, withIntermediateDirectories: true)
try FileManager.default.createDirectory(at: homeDirectory, withIntermediateDirectories: true)
let executable = binDirectory.appendingPathComponent("claude")
try script.write(to: executable, atomically: true, encoding: .utf8)
try FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: executable.path)
return Fixture(
root: root,
executable: executable,
environment: [
"HOME": homeDirectory.path,
"PATH": binDirectory.path,
])
}
private struct Fixture {
let root: URL
let executable: URL
let environment: [String: String]
func remove() {
try? FileManager.default.removeItem(at: self.root)
}
}
}