241 lines · 10.4 KB · Swift
RawDownload
import CodexBarCoreimport Foundationimport Testing@testable import CodexBar @MainActorstruct CodexConsumerProjectionTests {    @Test    func `live card projection compacts weekly lanes and attaches dashboard extras`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-live-card")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(            UsageSnapshot(                primary: nil,                secondary: RateWindow(                    usedPercent: 25,                    windowMinutes: 10080,                    resetsAt: now.addingTimeInterval(3600),                    resetDescription: nil),                updatedAt: now),            provider: .codex)        store.credits = CreditsSnapshot(remaining: 42, events: [], updatedAt: now)        store.openAIDashboard = OpenAIDashboardSnapshot(            signedInEmail: "codex@example.com",            codeReviewRemainingPercent: 88,            codeReviewLimit: RateWindow(                usedPercent: 12,                windowMinutes: nil,                resetsAt: now.addingTimeInterval(7200),                resetDescription: nil),            creditEvents: [],            dailyBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 3)],            usageBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 4)],            creditsPurchaseURL: "https://chatgpt.com/settings/billing",            updatedAt: now)        store.openAIDashboardAttachmentAuthorized = true        store.openAIDashboardRequiresLogin = false         let projection = store.codexConsumerProjection(surface: .liveCard, now: now)         #expect(projection.visibleRateLanes == [.weekly])        #expect(projection.planUtilizationLanes.map(\.role.rawValue) == ["weekly"])        #expect(projection.dashboardVisibility == .attached)        #expect(projection.supplementalMetrics == [.codeReview])        #expect(projection.remainingPercent(for: .codeReview) == 88)        #expect(projection.credits?.remaining == 42)        #expect(projection.canShowBuyCredits)        #expect(projection.hasUsageBreakdown)        #expect(projection.hasCreditsHistory)    }     @Test    func `display only dashboard stays visible without attached extras`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-display-only")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(            UsageSnapshot(                primary: RateWindow(                    usedPercent: 15,                    windowMinutes: 300,                    resetsAt: now.addingTimeInterval(1800),                    resetDescription: nil),                secondary: RateWindow(                    usedPercent: 30,                    windowMinutes: 10080,                    resetsAt: now.addingTimeInterval(3600),                    resetDescription: nil),                updatedAt: now),            provider: .codex)        store.openAIDashboard = OpenAIDashboardSnapshot(            signedInEmail: "codex@example.com",            codeReviewRemainingPercent: 66,            creditEvents: [],            dailyBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 3)],            usageBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 4)],            creditsPurchaseURL: "https://chatgpt.com/settings/billing",            updatedAt: now)        store.openAIDashboardAttachmentAuthorized = false        store.openAIDashboardRequiresLogin = false         let projection = store.codexConsumerProjection(surface: .liveCard, now: now)         #expect(projection.dashboardVisibility == .displayOnly)        #expect(projection.supplementalMetrics.isEmpty)        #expect(projection.canShowBuyCredits)        #expect(!projection.hasUsageBreakdown)        #expect(!projection.hasCreditsHistory)    }     @Test    func `override card projection does not pull live codex adjuncts`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-override")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(            UsageSnapshot(                primary: RateWindow(                    usedPercent: 18,                    windowMinutes: 300,                    resetsAt: now.addingTimeInterval(1800),                    resetDescription: nil),                secondary: nil,                updatedAt: now),            provider: .codex)        store.credits = CreditsSnapshot(remaining: 42, events: [], updatedAt: now)        store.lastCreditsError = "Frame load interrupted"        store.openAIDashboard = OpenAIDashboardSnapshot(            signedInEmail: "codex@example.com",            codeReviewRemainingPercent: 88,            creditEvents: [],            dailyBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 3)],            usageBreakdown: [OpenAIDashboardDailyBreakdown(day: "2024-01-01", services: [], totalCreditsUsed: 4)],            creditsPurchaseURL: "https://chatgpt.com/settings/billing",            updatedAt: now)        store.openAIDashboardAttachmentAuthorized = true        store.openAIDashboardRequiresLogin = false        store._setErrorForTesting("Live codex error", provider: .codex)         let overrideSnapshot = UsageSnapshot(            primary: RateWindow(                usedPercent: 55,                windowMinutes: 300,                resetsAt: now.addingTimeInterval(1200),                resetDescription: nil),            secondary: nil,            updatedAt: now)         let projection = store.codexConsumerProjection(            surface: .overrideCard,            snapshotOverride: overrideSnapshot,            errorOverride: "Override error",            now: now)         #expect(projection.visibleRateLanes == [.session])        #expect(projection.dashboardVisibility == .hidden)        #expect(projection.credits == nil)        #expect(projection.supplementalMetrics.isEmpty)        #expect(!projection.canShowBuyCredits)        #expect(!projection.hasUsageBreakdown)        #expect(!projection.hasCreditsHistory)        #expect(projection.userFacingErrors.usage == "Override error")        #expect(projection.userFacingErrors.credits == nil)        #expect(projection.userFacingErrors.dashboard == nil)    }     @Test    func `menu bar projection flags credits fallback on exhaustion`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-menu-bar")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(            UsageSnapshot(                primary: RateWindow(                    usedPercent: 100,                    windowMinutes: 300,                    resetsAt: now.addingTimeInterval(1800),                    resetDescription: nil),                secondary: RateWindow(                    usedPercent: 40,                    windowMinutes: 10080,                    resetsAt: now.addingTimeInterval(3600),                    resetDescription: nil),                updatedAt: now),            provider: .codex)        store.credits = CreditsSnapshot(remaining: 80, events: [], updatedAt: now)         let projection = store.codexConsumerProjection(surface: .menuBar, now: now)         #expect(projection.menuBarFallback == .creditsBalance)    }     @Test    func `live card projection keeps buy credits available without dashboard purchase URL`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-buy-credits")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(            UsageSnapshot(                primary: RateWindow(                    usedPercent: 20,                    windowMinutes: 300,                    resetsAt: now.addingTimeInterval(1800),                    resetDescription: nil),                secondary: nil,                updatedAt: now),            provider: .codex)        store.credits = CreditsSnapshot(remaining: 42, events: [], updatedAt: now)        store.openAIDashboardAttachmentAuthorized = false        store.openAIDashboardRequiresLogin = false         let projection = store.codexConsumerProjection(surface: .liveCard, now: now)         #expect(projection.canShowBuyCredits)    }     @Test    func `menu bar projection keeps credits fallback when credits load before usage`() {        let store = self.makeStore(suite: "CodexConsumerProjectionTests-menu-bar-credits-only")        let now = Date(timeIntervalSince1970: 1_700_000_000)         store._setSnapshotForTesting(nil, provider: .codex)        store.credits = CreditsSnapshot(remaining: 80, events: [], updatedAt: now)         let projection = store.codexConsumerProjection(surface: .menuBar, now: now)         #expect(projection.menuBarFallback == .creditsBalance)        #expect(!projection.hasExhaustedRateLane)    }     private func makeStore(suite: String) -> UsageStore {        let defaults = UserDefaults(suiteName: suite)!        defaults.removePersistentDomain(forName: suite)        let configStore = testConfigStore(suiteName: suite)        let settings = SettingsStore(            userDefaults: defaults,            configStore: configStore,            zaiTokenStore: NoopZaiTokenStore(),            syntheticTokenStore: NoopSyntheticTokenStore(),            codexCookieStore: InMemoryCookieHeaderStore(),            claudeCookieStore: InMemoryCookieHeaderStore(),            cursorCookieStore: InMemoryCookieHeaderStore(),            opencodeCookieStore: InMemoryCookieHeaderStore(),            factoryCookieStore: InMemoryCookieHeaderStore(),            minimaxCookieStore: InMemoryMiniMaxCookieStore(),            minimaxAPITokenStore: InMemoryMiniMaxAPITokenStore(),            kimiTokenStore: InMemoryKimiTokenStore(),            kimiK2TokenStore: InMemoryKimiK2TokenStore(),            augmentCookieStore: InMemoryCookieHeaderStore(),            ampCookieStore: InMemoryCookieHeaderStore(),            copilotTokenStore: InMemoryCopilotTokenStore(),            tokenAccountStore: InMemoryTokenAccountStore())         return UsageStore(            fetcher: UsageFetcher(environment: [:]),            browserDetection: BrowserDetection(cacheTTL: 0),            settings: settings,            startupBehavior: .testing)    }}