import CodexBarCoreimport Foundationimport Testing@testable import CodexBar @Suite(.serialized)struct CodexSystemAccountObserverTests { @Test func `observer reads ambient CODEX_HOME when present`() throws { let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: home) } try Self.writeCodexAuthFile( homeURL: home, email: " LIVE@Example.com ", plan: "pro", accountId: "account-live") let observer = DefaultCodexSystemAccountObserver() let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path]) #expect(account?.email == "live@example.com") #expect(account?.codexHomePath == home.path) #expect(account?.identity == .providerAccount(id: "account-live")) } @Test func `observer falls back to nil when ambient home has no readable email`() throws { let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: home) } try FileManager.default.createDirectory(at: home, withIntermediateDirectories: true) let observer = DefaultCodexSystemAccountObserver() let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path]) #expect(account == nil) } @Test func `observer records observation timestamp`() throws { let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: home) } try Self.writeCodexAuthFile(homeURL: home, email: "user@example.com", plan: "team") let before = Date() let observer = DefaultCodexSystemAccountObserver() let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path]) let observed = try #require(account) #expect(observed.observedAt >= before) } @Test func `observer preserves provider account identity from scoped auth`() throws { let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) defer { try? FileManager.default.removeItem(at: home) } try Self.writeCodexAuthFile( homeURL: home, email: "user@example.com", plan: "team", accountId: "account-live-123") let observer = DefaultCodexSystemAccountObserver() let account = try #require(try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path])) #expect(account.identity == .providerAccount(id: "account-live-123")) } @Test func `observer uses cached workspace label for provider account`() throws { let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) let cacheURL = FileManager.default.temporaryDirectory .appendingPathComponent("codex-openai-workspaces-\(UUID().uuidString).json") defer { try? FileManager.default.removeItem(at: home) try? FileManager.default.removeItem(at: cacheURL) } try Self.writeCodexAuthFile( homeURL: home, email: "user@example.com", plan: "team", accountId: "account-live-123") try CodexOpenAIWorkspaceIdentityCache.withFileURLOverrideForTesting(cacheURL) { try CodexOpenAIWorkspaceIdentityCache().store(CodexOpenAIWorkspaceIdentity( workspaceAccountID: "account-live-123", workspaceLabel: "Team Alpha")) let observer = DefaultCodexSystemAccountObserver() let account = try #require(try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path])) #expect(account.workspaceAccountID == "account-live-123") #expect(account.workspaceLabel == "Team Alpha") } } private static func writeCodexAuthFile( homeURL: URL, email: String, plan: String, accountId: String? = nil) throws { try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true) var tokens: [String: Any] = [ "accessToken": "access-token", "refreshToken": "refresh-token", "idToken": Self.fakeJWT(email: email, plan: plan), ] if let accountId { tokens["accountId"] = accountId } let auth = ["tokens": tokens] let data = try JSONSerialization.data(withJSONObject: auth) try data.write(to: homeURL.appendingPathComponent("auth.json")) } private static func fakeJWT(email: String, plan: String) -> String { let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data() let payload = (try? JSONSerialization.data(withJSONObject: [ "email": email, "chatgpt_plan_type": plan, ])) ?? Data() func base64URL(_ data: Data) -> String { data.base64EncodedString() .replacingOccurrences(of: "=", with: "") .replacingOccurrences(of: "+", with: "-") .replacingOccurrences(of: "/", with: "_") } return "\(base64URL(header)).\(base64URL(payload))." }}
import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
@Suite(.serialized)
struct CodexSystemAccountObserverTests {
@Test
func `observer reads ambient CODEX_HOME when present`() throws {
let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: home) }
try Self.writeCodexAuthFile(
homeURL: home,
email: " LIVE@Example.com ",
plan: "pro",
accountId: "account-live")
let observer = DefaultCodexSystemAccountObserver()
let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path])
#expect(account?.email == "live@example.com")
#expect(account?.codexHomePath == home.path)
#expect(account?.identity == .providerAccount(id: "account-live"))
}
@Test
func `observer falls back to nil when ambient home has no readable email`() throws {
let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: home) }
try FileManager.default.createDirectory(at: home, withIntermediateDirectories: true)
let observer = DefaultCodexSystemAccountObserver()
let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path])
#expect(account == nil)
}
@Test
func `observer records observation timestamp`() throws {
let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: home) }
try Self.writeCodexAuthFile(homeURL: home, email: "user@example.com", plan: "team")
let before = Date()
let observer = DefaultCodexSystemAccountObserver()
let account = try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path])
let observed = try #require(account)
#expect(observed.observedAt >= before)
}
@Test
func `observer preserves provider account identity from scoped auth`() throws {
let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
defer { try? FileManager.default.removeItem(at: home) }
try Self.writeCodexAuthFile(
homeURL: home,
email: "user@example.com",
plan: "team",
accountId: "account-live-123")
let observer = DefaultCodexSystemAccountObserver()
let account = try #require(try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path]))
#expect(account.identity == .providerAccount(id: "account-live-123"))
}
@Test
func `observer uses cached workspace label for provider account`() throws {
let home = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true)
let cacheURL = FileManager.default.temporaryDirectory
.appendingPathComponent("codex-openai-workspaces-\(UUID().uuidString).json")
defer {
try? FileManager.default.removeItem(at: home)
try? FileManager.default.removeItem(at: cacheURL)
}
try Self.writeCodexAuthFile(
homeURL: home,
email: "user@example.com",
plan: "team",
accountId: "account-live-123")
try CodexOpenAIWorkspaceIdentityCache.withFileURLOverrideForTesting(cacheURL) {
try CodexOpenAIWorkspaceIdentityCache().store(CodexOpenAIWorkspaceIdentity(
workspaceAccountID: "account-live-123",
workspaceLabel: "Team Alpha"))
let observer = DefaultCodexSystemAccountObserver()
let account = try #require(try observer.loadSystemAccount(environment: ["CODEX_HOME": home.path]))
#expect(account.workspaceAccountID == "account-live-123")
#expect(account.workspaceLabel == "Team Alpha")
}
}
private static func writeCodexAuthFile(
homeURL: URL,
email: String,
plan: String,
accountId: String? = nil) throws
{
try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true)
var tokens: [String: Any] = [
"accessToken": "access-token",
"refreshToken": "refresh-token",
"idToken": Self.fakeJWT(email: email, plan: plan),
]
if let accountId {
tokens["accountId"] = accountId
}
let auth = ["tokens": tokens]
let data = try JSONSerialization.data(withJSONObject: auth)
try data.write(to: homeURL.appendingPathComponent("auth.json"))
}
private static func fakeJWT(email: String, plan: String) -> String {
let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data()
let payload = (try? JSONSerialization.data(withJSONObject: [
"email": email,
"chatgpt_plan_type": plan,
])) ?? Data()
func base64URL(_ data: Data) -> String {
data.base64EncodedString()
.replacingOccurrences(of: "=", with: "")
.replacingOccurrences(of: "+", with: "-")
.replacingOccurrences(of: "/", with: "_")
}
return "\(base64URL(header)).\(base64URL(payload))."
}
}