84 lines
3.6 KiB
Swift
84 lines
3.6 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import CodexBarCore
|
|
|
|
struct ClaudeWebUsageExtraWindowTests {
|
|
@Test
|
|
func `parses claude web API sonnet usage response`() throws {
|
|
let json = """
|
|
{
|
|
"five_hour": { "utilization": 9, "resets_at": "2025-12-23T16:00:00.000Z" },
|
|
"seven_day_sonnet": { "utilization": 6, "resets_at": "2025-12-30T23:00:00.000Z" }
|
|
}
|
|
"""
|
|
let data = Data(json.utf8)
|
|
let parsed = try ClaudeWebAPIFetcher._parseUsageResponseForTesting(data)
|
|
#expect(parsed.opusPercentUsed == 6)
|
|
}
|
|
|
|
@Test
|
|
func `ignores merged claude web API omelette usage window`() throws {
|
|
let json = """
|
|
{
|
|
"five_hour": { "utilization": 9, "resets_at": "2025-12-23T16:00:00.000Z" },
|
|
"seven_day_omelette": { "utilization": 26, "resets_at": "2025-12-30T23:00:00.000Z" },
|
|
"seven_day_cowork": { "utilization": 11, "resets_at": "2025-12-31T23:00:00.000Z" }
|
|
}
|
|
"""
|
|
let data = Data(json.utf8)
|
|
let parsed = try ClaudeWebAPIFetcher._parseUsageResponseForTesting(data)
|
|
#expect(parsed.extraRateWindows.count == 1)
|
|
#expect(parsed.extraRateWindows.contains { $0.id == "claude-design" } == false)
|
|
#expect(parsed.extraRateWindows.first(where: { $0.id == "claude-routines" })?.window.usedPercent == 11)
|
|
}
|
|
|
|
@Test
|
|
func `parses claude web API cowork null as zero routines window`() throws {
|
|
let json = """
|
|
{
|
|
"five_hour": { "utilization": 9, "resets_at": "2025-12-23T16:00:00.000Z" },
|
|
"seven_day_omelette": { "utilization": 26, "resets_at": "2025-12-30T23:00:00.000Z" },
|
|
"seven_day_cowork": null
|
|
}
|
|
"""
|
|
let data = Data(json.utf8)
|
|
let parsed = try ClaudeWebAPIFetcher._parseUsageResponseForTesting(data)
|
|
#expect(parsed.extraRateWindows.first(where: { $0.id == "claude-routines" })?.window.usedPercent == 0)
|
|
#expect(parsed.extraRateWindows.contains { $0.id == "claude-design" } == false)
|
|
}
|
|
|
|
@Test
|
|
func `surfaces Fable scoped weekly limit from claude web API limits array`() throws {
|
|
// Real shape observed 2026-07-03 from claude.ai/api/organizations/{org}/usage during
|
|
// Anthropic's Fable 5 promotional access window (up to 50% of the weekly limit).
|
|
let json = """
|
|
{
|
|
"five_hour": { "utilization": 16, "resets_at": "2026-07-03T00:30:00.440902+00:00" },
|
|
"seven_day": { "utilization": 10, "resets_at": "2026-07-08T09:00:00.440924+00:00" },
|
|
"limits": [
|
|
{
|
|
"kind": "session", "group": "session", "percent": 16,
|
|
"resets_at": "2026-07-03T00:30:00.440902+00:00", "scope": null, "is_active": true
|
|
},
|
|
{
|
|
"kind": "weekly_all", "group": "weekly", "percent": 10,
|
|
"resets_at": "2026-07-08T09:00:00.440924+00:00", "scope": null, "is_active": false
|
|
},
|
|
{
|
|
"kind": "weekly_scoped", "group": "weekly", "percent": 5,
|
|
"resets_at": "2026-07-08T09:00:00.441154+00:00",
|
|
"scope": { "model": { "id": null, "display_name": "Fable" }, "surface": null },
|
|
"is_active": false
|
|
}
|
|
]
|
|
}
|
|
"""
|
|
let data = Data(json.utf8)
|
|
let parsed = try ClaudeWebAPIFetcher._parseUsageResponseForTesting(data)
|
|
let fable = parsed.extraRateWindows.first(where: { $0.id == "claude-weekly-scoped-fable" })
|
|
#expect(fable?.title == "Fable only")
|
|
#expect(fable?.window.usedPercent == 5)
|
|
#expect(fable?.window.resetsAt != nil)
|
|
}
|
|
}
|