226 lines · 8.0 KB · Swift
RawDownload
import Foundationimport Testing@testable import CodexBarCore struct CodexCLIWindowNormalizationTests {    @Test    func `normalizer maps lone weekly window into secondary`() {        let weekly = RateWindow(            usedPercent: 5,            windowMinutes: 10080,            resetsAt: nil,            resetDescription: nil)         let normalized = CodexRateWindowNormalizer._normalizeForTesting(primary: weekly, secondary: nil)        #expect(normalized.primary == nil)        #expect(normalized.secondary?.usedPercent == 5)        #expect(normalized.secondary?.windowMinutes == 10080)    }     @Test    func `normalizer keeps lone session window in primary`() {        let session = RateWindow(            usedPercent: 31,            windowMinutes: 300,            resetsAt: nil,            resetDescription: nil)         let normalized = CodexRateWindowNormalizer._normalizeForTesting(primary: session, secondary: nil)        #expect(normalized.primary?.usedPercent == 31)        #expect(normalized.primary?.windowMinutes == 300)        #expect(normalized.secondary == nil)    }     @Test    func `normalizer keeps session and weekly ordering unchanged`() {        let session = RateWindow(            usedPercent: 31,            windowMinutes: 300,            resetsAt: nil,            resetDescription: nil)        let weekly = RateWindow(            usedPercent: 26,            windowMinutes: 10080,            resetsAt: nil,            resetDescription: nil)         let normalized = CodexRateWindowNormalizer._normalizeForTesting(primary: session, secondary: weekly)        #expect(normalized.primary?.usedPercent == 31)        #expect(normalized.primary?.windowMinutes == 300)        #expect(normalized.secondary?.usedPercent == 26)        #expect(normalized.secondary?.windowMinutes == 10080)    }     @Test    func `normalizer swaps reversed weekly and unknown windows`() {        let weekly = RateWindow(            usedPercent: 43,            windowMinutes: 10080,            resetsAt: nil,            resetDescription: nil)        let unknown = RateWindow(            usedPercent: 17,            windowMinutes: 540,            resetsAt: nil,            resetDescription: nil)         let normalized = CodexRateWindowNormalizer._normalizeForTesting(primary: weekly, secondary: unknown)        #expect(normalized.primary?.usedPercent == 17)        #expect(normalized.primary?.windowMinutes == 540)        #expect(normalized.secondary?.usedPercent == 43)        #expect(normalized.secondary?.windowMinutes == 10080)    }     @Test    func `maps weekly only RPC limits into secondary`() throws {        let snapshot = try UsageFetcher._mapCodexRPCLimitsForTesting(            primary: (usedPercent: 5, windowMinutes: 10080, resetsAt: nil),            secondary: nil)         #expect(snapshot.primary == nil)        #expect(snapshot.secondary?.usedPercent == 5)        #expect(snapshot.secondary?.windowMinutes == 10080)    }     @Test    func `maps session only RPC limits into primary`() throws {        let snapshot = try UsageFetcher._mapCodexRPCLimitsForTesting(            primary: (usedPercent: 31, windowMinutes: 300, resetsAt: nil),            secondary: nil)         #expect(snapshot.primary?.usedPercent == 31)        #expect(snapshot.primary?.windowMinutes == 300)        #expect(snapshot.secondary == nil)    }     @Test    func `maps reversed weekly and unknown RPC limits`() throws {        let snapshot = try UsageFetcher._mapCodexRPCLimitsForTesting(            primary: (usedPercent: 43, windowMinutes: 10080, resetsAt: nil),            secondary: (usedPercent: 17, windowMinutes: 540, resetsAt: nil))         #expect(snapshot.primary?.usedPercent == 17)        #expect(snapshot.primary?.windowMinutes == 540)        #expect(snapshot.secondary?.usedPercent == 43)        #expect(snapshot.secondary?.windowMinutes == 10080)    }     @Test    func `throws when RPC limits contain no windows`() {        #expect(throws: UsageError.noRateLimitsFound) {            try UsageFetcher._mapCodexRPCLimitsForTesting(primary: nil, secondary: nil)        }    }     @Test    func `maps plan only RPC limits into empty identified snapshot`() throws {        let snapshot = try UsageFetcher._mapCodexRPCLimitsForTesting(            primary: nil,            secondary: nil,            planType: "pro")         #expect(snapshot.primary == nil)        #expect(snapshot.secondary == nil)        #expect(snapshot.loginMethod(for: .codex) == "pro")        #expect(snapshot.rateLimitsUnavailable(for: .codex))    }     @Test    func `codex no rate limit error means limits unavailable without snapshot`() {        let availability = UsageLimitsAvailability.resolve(            provider: .codex,            snapshot: nil,            account: AccountInfo(email: "user@example.com", plan: nil),            lastErrorDescription: UsageError.noRateLimitsFound.errorDescription)         #expect(availability == .unavailable)    }     @Test    func `codex no rate limit error stays available without account context`() {        let availability = UsageLimitsAvailability.resolve(            provider: .codex,            snapshot: nil,            account: AccountInfo(email: nil, plan: nil),            lastErrorDescription: UsageError.noRateLimitsFound.errorDescription)         #expect(availability == .available)    }     @Test    func `codex windowed snapshot wins over stale no rate limit error`() {        let identity = ProviderIdentitySnapshot(            providerID: .codex,            accountEmail: "user@example.com",            accountOrganization: nil,            loginMethod: "pro")        let snapshot = UsageSnapshot(            primary: RateWindow(                usedPercent: 25,                windowMinutes: 300,                resetsAt: nil,                resetDescription: nil),            secondary: nil,            updatedAt: Date(),            identity: identity)        let availability = UsageLimitsAvailability.resolve(            provider: .codex,            snapshot: snapshot,            lastErrorDescription: UsageError.noRateLimitsFound.errorDescription)         #expect(availability == .available)    }     @Test    func `maps weekly only status snapshot into secondary`() throws {        let status = CodexStatusSnapshot(            credits: nil,            fiveHourPercentLeft: nil,            weeklyPercentLeft: 95,            fiveHourResetDescription: nil,            weeklyResetDescription: "resets next week",            fiveHourResetsAt: nil,            weeklyResetsAt: nil,            rawText: "Weekly limit: 95% left")         let snapshot = try UsageFetcher._mapCodexStatusForTesting(status)        #expect(snapshot.primary == nil)        #expect(snapshot.secondary?.usedPercent == 5)        #expect(snapshot.secondary?.windowMinutes == 10080)    }     @Test    func `maps five hour only status snapshot into primary`() throws {        let status = CodexStatusSnapshot(            credits: nil,            fiveHourPercentLeft: 69,            weeklyPercentLeft: nil,            fiveHourResetDescription: "resets soon",            weeklyResetDescription: nil,            fiveHourResetsAt: nil,            weeklyResetsAt: nil,            rawText: "5h limit: 69% left")         let snapshot = try UsageFetcher._mapCodexStatusForTesting(status)        #expect(snapshot.primary?.usedPercent == 31)        #expect(snapshot.primary?.windowMinutes == 300)        #expect(snapshot.secondary == nil)    }     @Test    func `throws when status snapshot contains no windows`() {        let status = CodexStatusSnapshot(            credits: nil,            fiveHourPercentLeft: nil,            weeklyPercentLeft: nil,            fiveHourResetDescription: nil,            weeklyResetDescription: nil,            fiveHourResetsAt: nil,            weeklyResetsAt: nil,            rawText: "")         #expect(throws: UsageError.noRateLimitsFound) {            try UsageFetcher._mapCodexStatusForTesting(status)        }    }}