599 lines
26 KiB
Swift
599 lines
26 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import CodexBar
|
|
@testable import CodexBarCLI
|
|
@testable import CodexBarCore
|
|
|
|
@Suite(.serialized)
|
|
@MainActor
|
|
struct CodexDashboardWorkedExampleParityTests {
|
|
@Test
|
|
func `worked example A wrong email app and CLI both reject and retire owned state`() async throws {
|
|
try await self.withIsolatedDashboardCache {
|
|
OpenAIDashboardCacheStore.clear()
|
|
defer { OpenAIDashboardCacheStore.clear() }
|
|
|
|
let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-a")
|
|
store.settings._test_liveSystemCodexAccount = self.liveAccount(
|
|
email: "work@company.com",
|
|
identity: .emailOnly(normalizedEmail: "work@company.com"))
|
|
store.settings.codexActiveSource = .liveSystem
|
|
|
|
let attachedDashboard = self.makeDashboard(
|
|
email: "work@company.com",
|
|
creditsRemaining: 42,
|
|
usedPercent: 20)
|
|
let attachedCredits = self.credits(remaining: 42)
|
|
store._setSnapshotForTesting(
|
|
self.codexSnapshot(email: "work@company.com", usedPercent: 20),
|
|
provider: .codex)
|
|
store.lastSourceLabels[.codex] = "openai-web"
|
|
store.credits = attachedCredits
|
|
store.lastCreditsSnapshot = attachedCredits
|
|
store.lastCreditsSnapshotAccountKey = "work@company.com"
|
|
store.lastCreditsSource = .dashboardWeb
|
|
store.openAIDashboard = attachedDashboard
|
|
store.lastOpenAIDashboardSnapshot = attachedDashboard
|
|
store.lastOpenAIDashboardTargetEmail = "work@company.com"
|
|
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
|
|
accountEmail: "work@company.com",
|
|
snapshot: attachedDashboard))
|
|
|
|
await store.applyOpenAIDashboard(
|
|
self.makeDashboard(
|
|
email: "personal@gmail.com",
|
|
creditsRemaining: 9,
|
|
usedPercent: 35),
|
|
targetEmail: "work@company.com")
|
|
|
|
#expect(store.openAIDashboard == nil)
|
|
#expect(store.lastOpenAIDashboardSnapshot == nil)
|
|
#expect(store.snapshots[.codex] == nil)
|
|
#expect(store.credits == nil)
|
|
#expect(store.lastCreditsSource == .none)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
#expect(store.openAIDashboardRequiresLogin == true)
|
|
|
|
let authHome = try self.makeAuthHome(
|
|
email: "work@company.com",
|
|
accountId: "acct-work")
|
|
defer { try? FileManager.default.removeItem(at: authHome) }
|
|
let cliContext = self.makeCLIContext(
|
|
authHome: authHome,
|
|
knownOwners: [
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-work"),
|
|
normalizedEmail: "work@company.com"),
|
|
])
|
|
let wrongEmailDashboard = self.makeDashboard(
|
|
email: "personal@gmail.com",
|
|
creditsRemaining: 9,
|
|
usedPercent: 35)
|
|
|
|
do {
|
|
_ = try CodexWebDashboardStrategy.makeAuthorizedDashboardResultForTesting(
|
|
dashboard: wrongEmailDashboard,
|
|
context: cliContext,
|
|
routingTargetEmail: "work@company.com")
|
|
Issue.record("Expected OpenAIWebCodexError.policyRejected")
|
|
} catch let error as OpenAIWebCodexError {
|
|
if case let .policyRejected(decision) = error {
|
|
#expect(decision.reason == .wrongEmail(expected: "work@company.com", actual: "personal@gmail.com"))
|
|
} else {
|
|
Issue.record("Expected policyRejected, got \(error)")
|
|
}
|
|
} catch {
|
|
Issue.record("Expected OpenAIWebCodexError.policyRejected, got \(error)")
|
|
}
|
|
|
|
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
|
|
accountEmail: "personal@gmail.com",
|
|
snapshot: wrongEmailDashboard))
|
|
|
|
let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable(
|
|
usage: self.makeUsage(email: "work@company.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: cliContext)
|
|
|
|
#expect(restored == nil)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `worked example B same email ambiguity is display only in app and non attach in CLI`() async throws {
|
|
try await self.withIsolatedDashboardCache {
|
|
OpenAIDashboardCacheStore.clear()
|
|
defer { OpenAIDashboardCacheStore.clear() }
|
|
|
|
let managedHome = try self.makeAuthHome(
|
|
email: "work@company.com",
|
|
accountId: "acct-managed")
|
|
defer { try? FileManager.default.removeItem(at: managedHome) }
|
|
let managedAccount = ManagedCodexAccount(
|
|
id: UUID(),
|
|
email: "work@company.com",
|
|
managedHomePath: managedHome.path,
|
|
createdAt: 1,
|
|
updatedAt: 1,
|
|
lastAuthenticatedAt: 1)
|
|
let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount])
|
|
defer { try? FileManager.default.removeItem(at: managedStoreURL) }
|
|
|
|
let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-b")
|
|
store.settings._test_managedCodexAccountStoreURL = managedStoreURL
|
|
store.settings._test_liveSystemCodexAccount = self.liveAccount(
|
|
email: "work@company.com",
|
|
identity: .emailOnly(normalizedEmail: "work@company.com"))
|
|
store.settings.codexActiveSource = .liveSystem
|
|
|
|
await store.applyOpenAIDashboard(
|
|
self.makeDashboard(
|
|
email: "work@company.com",
|
|
creditsRemaining: 14,
|
|
usedPercent: 30,
|
|
includeUsageBreakdown: true),
|
|
targetEmail: "work@company.com")
|
|
try await Task.sleep(for: .milliseconds(250))
|
|
|
|
#expect(store.openAIDashboard?.signedInEmail == "work@company.com")
|
|
#expect(store.snapshots[.codex] == nil)
|
|
#expect(store.credits == nil)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
#expect(store.codexHistoricalDataset == nil)
|
|
|
|
let cliAuthHome = try self.makeAuthHome(email: "work@company.com")
|
|
defer { try? FileManager.default.removeItem(at: cliAuthHome) }
|
|
let ambiguousOwners = [
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-alpha"),
|
|
normalizedEmail: "work@company.com"),
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-beta"),
|
|
normalizedEmail: "work@company.com"),
|
|
]
|
|
let cliContext = self.makeCLIContext(
|
|
authHome: cliAuthHome,
|
|
knownOwners: ambiguousOwners)
|
|
let dashboard = self.makeDashboard(
|
|
email: "work@company.com",
|
|
creditsRemaining: 14,
|
|
usedPercent: 30,
|
|
includeUsageBreakdown: true)
|
|
let expectedDecision = CodexDashboardAuthority.evaluate(
|
|
CodexCLIDashboardAuthorityContext.makeLiveWebInput(
|
|
dashboard: dashboard,
|
|
context: cliContext,
|
|
routingTargetEmail: "work@company.com"))
|
|
|
|
do {
|
|
_ = try CodexWebDashboardStrategy.makeAuthorizedDashboardResultForTesting(
|
|
dashboard: dashboard,
|
|
context: cliContext,
|
|
routingTargetEmail: "work@company.com")
|
|
Issue.record("Expected CodexDashboardPolicyError.displayOnly")
|
|
} catch let error as CodexDashboardPolicyError {
|
|
#expect(error == .displayOnly(expectedDecision))
|
|
} catch {
|
|
Issue.record("Expected CodexDashboardPolicyError.displayOnly, got \(error)")
|
|
}
|
|
|
|
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
|
|
accountEmail: "work@company.com",
|
|
snapshot: dashboard))
|
|
|
|
let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable(
|
|
usage: self.makeUsage(email: "work@company.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: cliContext)
|
|
|
|
#expect(restored == nil)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `worked example C unresolved but proven continuity attaches in app and CLI`() async {
|
|
await self.withIsolatedDashboardCache {
|
|
OpenAIDashboardCacheStore.clear()
|
|
defer { OpenAIDashboardCacheStore.clear() }
|
|
|
|
let emptyHome = self.makeEmptyHome()
|
|
defer { try? FileManager.default.removeItem(at: emptyHome) }
|
|
|
|
let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-c")
|
|
store.settings._test_codexReconciliationEnvironment = ["CODEX_HOME": emptyHome.path]
|
|
store.settings._test_liveSystemCodexAccount = nil
|
|
store.settings.codexActiveSource = .liveSystem
|
|
store._setSnapshotForTesting(
|
|
self.codexSnapshot(email: "work@company.com", usedPercent: 12),
|
|
provider: .codex)
|
|
store.lastSourceLabels[.codex] = "codex-cli"
|
|
|
|
let dashboard = self.makeDashboard(
|
|
email: "work@company.com",
|
|
creditsRemaining: 33,
|
|
usedPercent: 12)
|
|
let appAuthority = store.evaluateCodexDashboardAuthority(
|
|
dashboard: dashboard,
|
|
sourceKind: .liveWeb,
|
|
routingTargetEmail: "work@company.com")
|
|
|
|
await store.applyOpenAIDashboard(dashboard, targetEmail: "work@company.com")
|
|
|
|
#expect(store.openAIDashboard?.signedInEmail == "work@company.com")
|
|
#expect(store.credits?.remaining == 33)
|
|
#expect(store.lastCreditsSource == .dashboardWeb)
|
|
#expect(store.lastCodexAccountScopedRefreshGuard?.accountKey == "work@company.com")
|
|
#expect(store.openAIDashboardRequiresLogin == false)
|
|
#expect(store.lastOpenAIDashboardError == nil)
|
|
|
|
let cliContext = self.makeCLIContext(authHome: emptyHome, knownOwners: [])
|
|
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
|
|
accountEmail: "stale-route@example.com",
|
|
snapshot: dashboard))
|
|
|
|
let restored = CodexBarCLI.loadOpenAIDashboardIfAvailable(
|
|
usage: self.makeUsage(email: "work@company.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: cliContext)
|
|
let cliInput = CodexCLIDashboardAuthorityContext.makeCachedDashboardInput(
|
|
dashboard: dashboard,
|
|
cachedAccountEmail: "stale-route@example.com",
|
|
usage: self.makeUsage(email: "work@company.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: cliContext)
|
|
let cliDecision = CodexDashboardAuthority.evaluate(cliInput)
|
|
|
|
#expect(restored == dashboard)
|
|
#expect(appAuthority.decision.disposition == .attach)
|
|
#expect(cliDecision.disposition == .attach)
|
|
#expect(appAuthority.decision.reason == .trustedContinuityNoCompetingOwner)
|
|
#expect(cliDecision.reason == .trustedContinuityNoCompetingOwner)
|
|
}
|
|
}
|
|
|
|
@Test
|
|
func `worked example D prior attach downgrades to ambiguity and retires old owned state`() async throws {
|
|
try await self.withIsolatedDashboardCache {
|
|
OpenAIDashboardCacheStore.clear()
|
|
defer { OpenAIDashboardCacheStore.clear() }
|
|
|
|
let store = self.makeAppStore(suite: "CodexDashboardWorkedExampleParityTests-example-d")
|
|
store.settings._test_liveSystemCodexAccount = self.liveAccount(
|
|
email: "shared@example.com",
|
|
identity: .emailOnly(normalizedEmail: "shared@example.com"))
|
|
store.settings.codexActiveSource = .liveSystem
|
|
|
|
let initialDashboard = self.makeDashboard(
|
|
email: "shared@example.com",
|
|
creditsRemaining: 21,
|
|
usedPercent: 18)
|
|
await store.applyOpenAIDashboard(initialDashboard, targetEmail: "shared@example.com")
|
|
|
|
#expect(store.openAIDashboard?.signedInEmail == "shared@example.com")
|
|
#expect(store.snapshots[.codex]?.accountEmail(for: .codex) == "shared@example.com")
|
|
#expect(store.credits?.remaining == 21)
|
|
#expect(store.lastSourceLabels[.codex] == "openai-web")
|
|
#expect(OpenAIDashboardCacheStore.load()?.accountEmail == "shared@example.com")
|
|
|
|
let managedHome = try self.makeAuthHome(
|
|
email: "shared@example.com",
|
|
accountId: "acct-managed")
|
|
defer { try? FileManager.default.removeItem(at: managedHome) }
|
|
let managedAccount = ManagedCodexAccount(
|
|
id: UUID(),
|
|
email: "shared@example.com",
|
|
managedHomePath: managedHome.path,
|
|
createdAt: 1,
|
|
updatedAt: 1,
|
|
lastAuthenticatedAt: 1)
|
|
let managedStoreURL = try self.makeManagedAccountStoreURL(accounts: [managedAccount])
|
|
defer { try? FileManager.default.removeItem(at: managedStoreURL) }
|
|
store.settings._test_managedCodexAccountStoreURL = managedStoreURL
|
|
|
|
await store.applyOpenAIDashboard(
|
|
self.makeDashboard(
|
|
email: "shared@example.com",
|
|
creditsRemaining: 9,
|
|
usedPercent: 35,
|
|
includeUsageBreakdown: true),
|
|
targetEmail: "shared@example.com")
|
|
|
|
#expect(store.openAIDashboard?.signedInEmail == "shared@example.com")
|
|
#expect(store.lastOpenAIDashboardSnapshot?.signedInEmail == "shared@example.com")
|
|
#expect(store.snapshots[.codex] == nil)
|
|
#expect(store.credits == nil)
|
|
#expect(store.lastCreditsSource == .none)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
|
|
OpenAIDashboardCacheStore.clear()
|
|
let cliAuthHome = try self.makeAuthHome(email: "shared@example.com")
|
|
defer { try? FileManager.default.removeItem(at: cliAuthHome) }
|
|
let attachableContext = self.makeCLIContext(
|
|
authHome: cliAuthHome,
|
|
knownOwners: [
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-alpha"),
|
|
normalizedEmail: "shared@example.com"),
|
|
])
|
|
OpenAIDashboardCacheStore.save(OpenAIDashboardCache(
|
|
accountEmail: "shared@example.com",
|
|
snapshot: initialDashboard))
|
|
|
|
let initiallyRestored = CodexBarCLI.loadOpenAIDashboardIfAvailable(
|
|
usage: self.makeUsage(email: "shared@example.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: attachableContext)
|
|
#expect(initiallyRestored == initialDashboard)
|
|
|
|
let ambiguousContext = self.makeCLIContext(
|
|
authHome: cliAuthHome,
|
|
knownOwners: [
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-alpha"),
|
|
normalizedEmail: "shared@example.com"),
|
|
CodexDashboardKnownOwnerCandidate(
|
|
identity: .providerAccount(id: "acct-beta"),
|
|
normalizedEmail: "shared@example.com"),
|
|
])
|
|
|
|
let downgradedRestored = CodexBarCLI.loadOpenAIDashboardIfAvailable(
|
|
usage: self.makeUsage(email: "shared@example.com"),
|
|
sourceLabel: "codex-cli",
|
|
context: ambiguousContext)
|
|
|
|
#expect(downgradedRestored == nil)
|
|
#expect(OpenAIDashboardCacheStore.load() == nil)
|
|
}
|
|
}
|
|
|
|
private func withIsolatedDashboardCache<T>(
|
|
_ operation: () async throws -> T) async rethrows -> T
|
|
{
|
|
let cacheURL = FileManager.default.temporaryDirectory
|
|
.appendingPathComponent("codexbar-dashboard-\(UUID().uuidString).json")
|
|
defer { try? FileManager.default.removeItem(at: cacheURL) }
|
|
return try await OpenAIDashboardCacheStore.$cacheURLOverride.withValue(cacheURL) {
|
|
try await operation()
|
|
}
|
|
}
|
|
|
|
private func makeDashboard(
|
|
email: String,
|
|
creditsRemaining: Double,
|
|
usedPercent: Double,
|
|
includeUsageBreakdown: Bool = false) -> OpenAIDashboardSnapshot
|
|
{
|
|
let updatedAt = Date(timeIntervalSince1970: 2000)
|
|
let creditEvents = [
|
|
CreditEvent(
|
|
date: Date(timeIntervalSince1970: 1000),
|
|
service: "codex",
|
|
creditsUsed: 3),
|
|
]
|
|
let usageBreakdown = includeUsageBreakdown
|
|
? self.makeUsageBreakdown(endingAt: updatedAt, days: 35, dailyCredits: 10)
|
|
: []
|
|
return OpenAIDashboardSnapshot(
|
|
signedInEmail: email,
|
|
codeReviewRemainingPercent: 75,
|
|
codeReviewLimit: RateWindow(
|
|
usedPercent: 25,
|
|
windowMinutes: 60,
|
|
resetsAt: Date(timeIntervalSince1970: 3600),
|
|
resetDescription: nil),
|
|
creditEvents: creditEvents,
|
|
dailyBreakdown: OpenAIDashboardSnapshot.makeDailyBreakdown(from: creditEvents, maxDays: 30),
|
|
usageBreakdown: usageBreakdown,
|
|
creditsPurchaseURL: nil,
|
|
primaryLimit: RateWindow(
|
|
usedPercent: usedPercent,
|
|
windowMinutes: 300,
|
|
resetsAt: Date(timeIntervalSince1970: 7200),
|
|
resetDescription: nil),
|
|
secondaryLimit: includeUsageBreakdown
|
|
? RateWindow(
|
|
usedPercent: usedPercent,
|
|
windowMinutes: 10080,
|
|
resetsAt: updatedAt.addingTimeInterval(2 * 24 * 60 * 60),
|
|
resetDescription: nil)
|
|
: nil,
|
|
creditsRemaining: creditsRemaining,
|
|
accountPlan: "pro",
|
|
updatedAt: updatedAt)
|
|
}
|
|
|
|
private func makeAppStore(suite: String) -> UsageStore {
|
|
let defaults = UserDefaults(suiteName: suite)!
|
|
defaults.removePersistentDomain(forName: suite)
|
|
let settings = SettingsStore(
|
|
userDefaults: defaults,
|
|
configStore: testConfigStore(suiteName: suite),
|
|
zaiTokenStore: NoopZaiTokenStore(),
|
|
syntheticTokenStore: NoopSyntheticTokenStore())
|
|
settings._test_activeManagedCodexAccount = nil
|
|
settings._test_activeManagedCodexRemoteHomePath = nil
|
|
settings._test_unreadableManagedCodexAccountStore = false
|
|
settings._test_managedCodexAccountStoreURL = nil
|
|
settings._test_liveSystemCodexAccount = nil
|
|
settings._test_codexReconciliationEnvironment = nil
|
|
settings.historicalTrackingEnabled = true
|
|
let historyURL = FileManager.default.temporaryDirectory
|
|
.appendingPathComponent(UUID().uuidString)
|
|
.appendingPathComponent("usage-history.jsonl")
|
|
let planStore = testPlanUtilizationHistoryStore(
|
|
suiteName: "CodexDashboardWorkedExampleParityTests-\(UUID().uuidString)")
|
|
let store = UsageStore(
|
|
fetcher: UsageFetcher(environment: [:]),
|
|
browserDetection: BrowserDetection(cacheTTL: 0),
|
|
settings: settings,
|
|
historicalUsageHistoryStore: HistoricalUsageHistoryStore(fileURL: historyURL),
|
|
planUtilizationHistoryStore: planStore)
|
|
store._cancelPlanUtilizationHistoryLoadForTesting()
|
|
return store
|
|
}
|
|
|
|
private func makeCLIContext(
|
|
authHome: URL?,
|
|
knownOwners: [CodexDashboardKnownOwnerCandidate]) -> ProviderFetchContext
|
|
{
|
|
let env = authHome.map { ["CODEX_HOME": $0.path] } ?? [:]
|
|
let browserDetection = BrowserDetection(cacheTTL: 0)
|
|
return ProviderFetchContext(
|
|
runtime: .cli,
|
|
sourceMode: .auto,
|
|
includeCredits: true,
|
|
webTimeout: 60,
|
|
webDebugDumpHTML: false,
|
|
verbose: false,
|
|
env: env,
|
|
settings: ProviderSettingsSnapshot.make(
|
|
codex: .init(
|
|
usageDataSource: .auto,
|
|
cookieSource: .auto,
|
|
manualCookieHeader: nil,
|
|
dashboardAuthorityKnownOwners: knownOwners)),
|
|
fetcher: UsageFetcher(environment: env),
|
|
claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection),
|
|
browserDetection: browserDetection)
|
|
}
|
|
|
|
private func makeAuthHome(email: String?, accountId: String? = nil) throws -> URL {
|
|
let homeURL = FileManager.default.temporaryDirectory.appendingPathComponent(
|
|
UUID().uuidString,
|
|
isDirectory: true)
|
|
try self.writeCodexAuthFile(homeURL: homeURL, email: email, accountId: accountId)
|
|
return homeURL
|
|
}
|
|
|
|
private func makeEmptyHome() -> URL {
|
|
let homeURL = FileManager.default.temporaryDirectory.appendingPathComponent(
|
|
UUID().uuidString,
|
|
isDirectory: true)
|
|
try? FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true)
|
|
return homeURL
|
|
}
|
|
|
|
private func writeCodexAuthFile(
|
|
homeURL: URL,
|
|
email: String?,
|
|
accountId: String?) throws
|
|
{
|
|
try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true)
|
|
var tokens: [String: Any] = [
|
|
"accessToken": "access-token",
|
|
"refreshToken": "refresh-token",
|
|
"idToken": Self.fakeJWT(email: email, accountId: accountId),
|
|
]
|
|
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?, accountId: String?) -> String {
|
|
let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data()
|
|
var authClaims: [String: Any] = [
|
|
"chatgpt_plan_type": "pro",
|
|
]
|
|
if let accountId {
|
|
authClaims["chatgpt_account_id"] = accountId
|
|
}
|
|
var claims: [String: Any] = [
|
|
"chatgpt_plan_type": "pro",
|
|
"https://api.openai.com/auth": authClaims,
|
|
]
|
|
if let email {
|
|
claims["email"] = email
|
|
}
|
|
let payload = (try? JSONSerialization.data(withJSONObject: claims)) ?? Data()
|
|
|
|
func base64URL(_ data: Data) -> String {
|
|
data.base64EncodedString()
|
|
.replacingOccurrences(of: "=", with: "")
|
|
.replacingOccurrences(of: "+", with: "-")
|
|
.replacingOccurrences(of: "/", with: "_")
|
|
}
|
|
|
|
return "\(base64URL(header)).\(base64URL(payload))."
|
|
}
|
|
|
|
private func makeManagedAccountStoreURL(accounts: [ManagedCodexAccount]) throws -> URL {
|
|
let storeURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
|
|
let store = FileManagedCodexAccountStore(fileURL: storeURL)
|
|
try store.storeAccounts(ManagedCodexAccountSet(
|
|
version: FileManagedCodexAccountStore.currentVersion,
|
|
accounts: accounts))
|
|
return storeURL
|
|
}
|
|
|
|
private func liveAccount(email: String, identity: CodexIdentity = .unresolved) -> ObservedSystemCodexAccount {
|
|
ObservedSystemCodexAccount(
|
|
email: email,
|
|
codexHomePath: "/Users/test/.codex",
|
|
observedAt: Date(),
|
|
identity: identity)
|
|
}
|
|
|
|
private func codexSnapshot(email: String, usedPercent: Double) -> UsageSnapshot {
|
|
UsageSnapshot(
|
|
primary: RateWindow(
|
|
usedPercent: usedPercent,
|
|
windowMinutes: 300,
|
|
resetsAt: nil,
|
|
resetDescription: nil),
|
|
secondary: nil,
|
|
updatedAt: Date(timeIntervalSince1970: 2000),
|
|
identity: ProviderIdentitySnapshot(
|
|
providerID: .codex,
|
|
accountEmail: email,
|
|
accountOrganization: nil,
|
|
loginMethod: "Pro"))
|
|
}
|
|
|
|
private func credits(remaining: Double) -> CreditsSnapshot {
|
|
CreditsSnapshot(remaining: remaining, events: [], updatedAt: Date(timeIntervalSince1970: 2000))
|
|
}
|
|
|
|
private func makeUsage(email: String?) -> UsageSnapshot {
|
|
UsageSnapshot(
|
|
primary: RateWindow(
|
|
usedPercent: 10,
|
|
windowMinutes: 300,
|
|
resetsAt: Date(timeIntervalSince1970: 7200),
|
|
resetDescription: nil),
|
|
secondary: nil,
|
|
updatedAt: Date(timeIntervalSince1970: 2000),
|
|
identity: ProviderIdentitySnapshot(
|
|
providerID: .codex,
|
|
accountEmail: email,
|
|
accountOrganization: nil,
|
|
loginMethod: nil))
|
|
}
|
|
|
|
private func makeUsageBreakdown(
|
|
endingAt endDate: Date,
|
|
days: Int,
|
|
dailyCredits: Double) -> [OpenAIDashboardDailyBreakdown]
|
|
{
|
|
let formatter = DateFormatter()
|
|
formatter.locale = Locale(identifier: "en_US_POSIX")
|
|
formatter.timeZone = .current
|
|
formatter.dateFormat = "yyyy-MM-dd"
|
|
let calendar = Calendar(identifier: .gregorian)
|
|
let endDay = calendar.startOfDay(for: endDate)
|
|
return (0..<days).compactMap { offset in
|
|
guard let date = calendar.date(byAdding: .day, value: -offset, to: endDay) else { return nil }
|
|
return OpenAIDashboardDailyBreakdown(
|
|
day: formatter.string(from: date),
|
|
services: [
|
|
OpenAIDashboardServiceUsage(service: "CLI", creditsUsed: dailyCredits),
|
|
],
|
|
totalCreditsUsed: dailyCredits)
|
|
}
|
|
}
|
|
}
|