import Foundationimport Testing@testable import CodexBarCore @Suitestruct CodexOAuthTests { @Test func parsesOAuthCredentials() throws { let json = """ { "OPENAI_API_KEY": null, "tokens": { "access_token": "access-token", "refresh_token": "refresh-token", "id_token": "id-token", "account_id": "account-123" }, "last_refresh": "2025-12-20T12:34:56Z" } """ let creds = try CodexOAuthCredentialsStore.parse(data: Data(json.utf8)) #expect(creds.accessToken == "access-token") #expect(creds.refreshToken == "refresh-token") #expect(creds.idToken == "id-token") #expect(creds.accountId == "account-123") #expect(creds.lastRefresh != nil) } @Test func parsesAPIKeyCredentials() throws { let json = """ { "OPENAI_API_KEY": "sk-test" } """ let creds = try CodexOAuthCredentialsStore.parse(data: Data(json.utf8)) #expect(creds.accessToken == "sk-test") #expect(creds.refreshToken.isEmpty) #expect(creds.idToken == nil) #expect(creds.accountId == nil) } @Test func decodesCreditsBalanceString() throws { let json = """ { "plan_type": "pro", "rate_limit": { "primary_window": { "used_percent": 12, "reset_at": 1766948068, "limit_window_seconds": 18000 } }, "credits": { "has_credits": false, "unlimited": false, "balance": "0" } } """ let response = try CodexOAuthUsageFetcher._decodeUsageResponseForTesting(Data(json.utf8)) #expect(response.planType?.rawValue == "pro") #expect(response.credits?.balance == 0) #expect(response.credits?.hasCredits == false) #expect(response.credits?.unlimited == false) } @Test func mapsUsageWindowsFromOAuth() throws { let json = """ { "rate_limit": { "primary_window": { "used_percent": 22, "reset_at": 1766948068, "limit_window_seconds": 18000 }, "secondary_window": { "used_percent": 43, "reset_at": 1767407914, "limit_window_seconds": 604800 } } } """ let creds = CodexOAuthCredentials( accessToken: "access", refreshToken: "refresh", idToken: nil, accountId: nil, lastRefresh: Date()) let snapshot = try CodexOAuthFetchStrategy._mapUsageForTesting(Data(json.utf8), credentials: creds) #expect(snapshot.primary?.usedPercent == 22) #expect(snapshot.primary?.windowMinutes == 300) #expect(snapshot.secondary?.usedPercent == 43) #expect(snapshot.secondary?.windowMinutes == 10080) #expect(snapshot.primary?.resetsAt != nil) #expect(snapshot.secondary?.resetsAt != nil) } @Test func resolvesChatGPTUsageURLFromConfig() { let config = "chatgpt_base_url = \"https://chatgpt.com/backend-api/\"\n" let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config) #expect(url.absoluteString == "https://chatgpt.com/backend-api/wham/usage") } @Test func resolvesCodexUsageURLFromConfig() { let config = "chatgpt_base_url = \"https://api.openai.com\"\n" let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config) #expect(url.absoluteString == "https://api.openai.com/api/codex/usage") } @Test func normalizesChatGPTBaseURLWithoutBackendAPI() { let config = "chatgpt_base_url = \"https://chat.openai.com\"\n" let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config) #expect(url.absoluteString == "https://chat.openai.com/backend-api/wham/usage") }}
import Foundation
import Testing
@testable import CodexBarCore
@Suite
struct CodexOAuthTests {
@Test
func parsesOAuthCredentials() throws {
let json = """
{
"OPENAI_API_KEY": null,
"tokens": {
"access_token": "access-token",
"refresh_token": "refresh-token",
"id_token": "id-token",
"account_id": "account-123"
},
"last_refresh": "2025-12-20T12:34:56Z"
}
"""
let creds = try CodexOAuthCredentialsStore.parse(data: Data(json.utf8))
#expect(creds.accessToken == "access-token")
#expect(creds.refreshToken == "refresh-token")
#expect(creds.idToken == "id-token")
#expect(creds.accountId == "account-123")
#expect(creds.lastRefresh != nil)
}
@Test
func parsesAPIKeyCredentials() throws {
let json = """
{
"OPENAI_API_KEY": "sk-test"
}
"""
let creds = try CodexOAuthCredentialsStore.parse(data: Data(json.utf8))
#expect(creds.accessToken == "sk-test")
#expect(creds.refreshToken.isEmpty)
#expect(creds.idToken == nil)
#expect(creds.accountId == nil)
}
@Test
func decodesCreditsBalanceString() throws {
let json = """
{
"plan_type": "pro",
"rate_limit": {
"primary_window": {
"used_percent": 12,
"reset_at": 1766948068,
"limit_window_seconds": 18000
}
},
"credits": {
"has_credits": false,
"unlimited": false,
"balance": "0"
}
}
"""
let response = try CodexOAuthUsageFetcher._decodeUsageResponseForTesting(Data(json.utf8))
#expect(response.planType?.rawValue == "pro")
#expect(response.credits?.balance == 0)
#expect(response.credits?.hasCredits == false)
#expect(response.credits?.unlimited == false)
}
@Test
func mapsUsageWindowsFromOAuth() throws {
let json = """
{
"rate_limit": {
"primary_window": {
"used_percent": 22,
"reset_at": 1766948068,
"limit_window_seconds": 18000
},
"secondary_window": {
"used_percent": 43,
"reset_at": 1767407914,
"limit_window_seconds": 604800
}
}
}
"""
let creds = CodexOAuthCredentials(
accessToken: "access",
refreshToken: "refresh",
idToken: nil,
accountId: nil,
lastRefresh: Date())
let snapshot = try CodexOAuthFetchStrategy._mapUsageForTesting(Data(json.utf8), credentials: creds)
#expect(snapshot.primary?.usedPercent == 22)
#expect(snapshot.primary?.windowMinutes == 300)
#expect(snapshot.secondary?.usedPercent == 43)
#expect(snapshot.secondary?.windowMinutes == 10080)
#expect(snapshot.primary?.resetsAt != nil)
#expect(snapshot.secondary?.resetsAt != nil)
}
@Test
func resolvesChatGPTUsageURLFromConfig() {
let config = "chatgpt_base_url = \"https://chatgpt.com/backend-api/\"\n"
let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config)
#expect(url.absoluteString == "https://chatgpt.com/backend-api/wham/usage")
}
@Test
func resolvesCodexUsageURLFromConfig() {
let config = "chatgpt_base_url = \"https://api.openai.com\"\n"
let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config)
#expect(url.absoluteString == "https://api.openai.com/api/codex/usage")
}
@Test
func normalizesChatGPTBaseURLWithoutBackendAPI() {
let config = "chatgpt_base_url = \"https://chat.openai.com\"\n"
let url = CodexOAuthUsageFetcher._resolveUsageURLForTesting(configContents: config)
#expect(url.absoluteString == "https://chat.openai.com/backend-api/wham/usage")
}
}