Files
steipete--codexbar/Tests/CodexBarTests/MenuCardAntigravityTests.swift
2026-07-13 12:22:33 +08:00

525 lines
20 KiB
Swift

import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
struct MenuCardAntigravityTests {
@Test
func `antigravity identity only snapshot shows limits unavailable`() throws {
let now = Date(timeIntervalSince1970: 1_742_771_200)
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let snapshot = UsageSnapshot(
primary: nil,
secondary: nil,
updatedAt: now,
identity: ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: "user@example.com",
accountOrganization: nil,
loginMethod: "Paid"))
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.isEmpty)
#expect(model.placeholder == "Limits not available")
#expect(model.subtitleStyle == .info)
#expect(model.email == "user@example.com")
#expect(model.planText == "Paid")
}
@Test
func `antigravity metrics omit missing groups`() throws {
let now = Date()
let identity = ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: nil,
accountOrganization: nil,
loginMethod: "Pro")
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 5,
windowMinutes: nil,
resetsAt: now.addingTimeInterval(3600),
resetDescription: nil),
secondary: nil,
tertiary: nil,
updatedAt: now,
identity: identity)
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.count == 1)
#expect(model.metrics.map(\.title) == ["Gemini Models"])
#expect(model.metrics[0].percent == 95)
#expect(model.metrics[0].percentLabel == "95% left")
}
@Test
func `legacy antigravity family row renders session pace without mutating duration`() throws {
let now = Date(timeIntervalSince1970: 0)
let window = RateWindow(
usedPercent: 80,
windowMinutes: nil,
resetsAt: now.addingTimeInterval(2 * 3600),
resetDescription: nil)
let snapshot = UsageSnapshot(
primary: window,
secondary: nil,
tertiary: nil,
updatedAt: now,
identity: ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: nil,
accountOrganization: nil,
loginMethod: "Pro"))
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(snapshot.primary?.windowMinutes == nil)
#expect(model.metrics.map(\.detailLeftText) == ["20% in deficit"])
#expect(model.metrics.map(\.detailRightText) == ["Projected empty in 45m"])
#expect(model.metrics[0].pacePercent == 40)
#expect(model.metrics[0].paceOnTop == false)
}
@Test
func `antigravity untracked known row does not duplicate grouped summary`() throws {
let now = Date(timeIntervalSince1970: 1_735_000_000)
let resetTime = now.addingTimeInterval(3600)
let antigravitySnapshot = AntigravityStatusSnapshot(
modelQuotas: [
AntigravityModelQuota(
label: "Claude Thinking",
modelId: "MODEL_PLACEHOLDER_M35",
remainingFraction: 0.4,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Gemini 3.1 Pro (Low)",
modelId: "MODEL_PLACEHOLDER_M36",
remainingFraction: nil,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Gemini 3 Flash",
modelId: "MODEL_PLACEHOLDER_M47",
remainingFraction: 1,
resetTime: resetTime,
resetDescription: nil),
],
accountEmail: nil,
accountPlan: "Pro")
let snapshot = try antigravitySnapshot.toUsageSnapshot()
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.map(\.title) == ["Gemini Models", "Claude and GPT"])
#expect(!model.metrics.contains { $0.title == "Gemini 3.1 Pro (Low)" })
}
@Test
func `antigravity metrics collapse complete per model quota windows`() throws {
let now = Date(timeIntervalSince1970: 1_735_000_000)
let resetTime = now.addingTimeInterval(3600)
let antigravitySnapshot = AntigravityStatusSnapshot(
modelQuotas: [
AntigravityModelQuota(
label: "GPT-OSS 120B (Medium)",
modelId: "MODEL_PLACEHOLDER_M55",
remainingFraction: 0.25,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Gemini 3 Pro (Low)",
modelId: "MODEL_PLACEHOLDER_M53",
remainingFraction: 0.5,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Claude Opus 4.6 (Thinking)",
modelId: "MODEL_PLACEHOLDER_M50",
remainingFraction: 0.75,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Gemini 3 Pro (High)",
modelId: "MODEL_PLACEHOLDER_M52",
remainingFraction: 1,
resetTime: resetTime,
resetDescription: nil),
],
accountEmail: nil,
accountPlan: "Pro",
source: .local)
let snapshot = try antigravitySnapshot.toUsageSnapshot()
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.map(\.title) == [
"Gemini Models",
"Claude and GPT",
])
#expect(model.metrics.map(\.percentLabel) == [
"50% left",
"25% left",
])
}
@Test
func `antigravity distinct extra windows still render when optional extras are disabled`() throws {
// Regression: the optional-credits/extra-usage setting is Codex-specific and must NOT hide
// other providers' core extra windows.
let now = Date(timeIntervalSince1970: 1_735_000_000)
let resetTime = now.addingTimeInterval(3600)
let antigravitySnapshot = AntigravityStatusSnapshot(
modelQuotas: [
AntigravityModelQuota(
label: "Experimental Tool",
modelId: "MODEL_PLACEHOLDER_UNKNOWN",
remainingFraction: 0.5,
resetTime: resetTime,
resetDescription: nil),
AntigravityModelQuota(
label: "Gemini 3 Pro (High)",
modelId: "MODEL_PLACEHOLDER_M52",
remainingFraction: 1,
resetTime: resetTime,
resetDescription: nil),
],
accountEmail: nil,
accountPlan: "Pro")
let snapshot = try antigravitySnapshot.toUsageSnapshot()
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: false,
hidePersonalInfo: false,
now: now))
// Distinct extra windows remain visible even with optional extras disabled.
#expect(model.metrics.contains { $0.title == "Experimental Tool" })
#expect(model.metrics.contains { $0.title == "Gemini Models" })
}
@Test
func `antigravity quota summary renders named session and weekly rows`() throws {
let now = Date(timeIntervalSince1970: 1_735_000_000)
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 27,
windowMinutes: 300,
resetsAt: nil,
resetDescription: "You have used some of your 5-hour limit, it will fully refresh in 3 hours."),
secondary: RateWindow(
usedPercent: 18,
windowMinutes: 10080,
resetsAt: nil,
resetDescription: "You have used some of your weekly limit, it will fully refresh in 5 days."),
tertiary: nil,
extraRateWindows: [
NamedRateWindow(
id: "antigravity-quota-summary-gemini-5h",
title: "Gemini Models Five Hour Limit",
window: RateWindow(
usedPercent: 9,
windowMinutes: 300,
resetsAt: nil,
resetDescription: "You have used some of your 5-hour limit, it will fully refresh in "
+ "4 hours.")),
NamedRateWindow(
id: "antigravity-quota-summary-gemini-weekly",
title: "Gemini Models Weekly Limit",
window: RateWindow(
usedPercent: 18,
windowMinutes: 10080,
resetsAt: nil,
resetDescription: "You have used some of your weekly limit, it will fully refresh in 5 days.")),
NamedRateWindow(
id: "antigravity-quota-summary-3p-5h",
title: "Claude and GPT models Five Hour Limit",
window: RateWindow(
usedPercent: 27,
windowMinutes: 300,
resetsAt: nil,
resetDescription: "You have used some of your 5-hour limit, it will fully refresh in "
+ "3 hours.")),
NamedRateWindow(
id: "antigravity-quota-summary-3p-weekly",
title: "Claude and GPT models Weekly Limit",
window: RateWindow(
usedPercent: 36,
windowMinutes: 10080,
resetsAt: nil,
resetDescription: "You have used some of your weekly limit, it will fully refresh in 6 days.")),
],
updatedAt: now,
identity: ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: nil,
accountOrganization: nil,
loginMethod: "Pro"))
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: false,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.map(\.id) == [
"antigravity-quota-summary-gemini-5h",
"antigravity-quota-summary-gemini-weekly",
"antigravity-quota-summary-3p-5h",
"antigravity-quota-summary-3p-weekly",
])
#expect(model.metrics.map(\.title) == [
"Gemini Models Five Hour Limit",
"Gemini Models Weekly Limit",
"Claude and GPT models Five Hour Limit",
"Claude and GPT models Weekly Limit",
])
#expect(model.metrics.map(\.percentLabel) == [
"91% left",
"82% left",
"73% left",
"64% left",
])
#expect(model.metrics[2].resetText == "Resets in 3 hours")
}
@Test
func `antigravity quota summary rows render pace details`() throws {
let now = Date(timeIntervalSince1970: 0)
let snapshot = UsageSnapshot(
primary: nil,
secondary: nil,
tertiary: nil,
extraRateWindows: [
NamedRateWindow(
id: "antigravity-quota-summary-gemini-5h",
title: "Gemini Models Five Hour Limit",
window: RateWindow(
usedPercent: 80,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(2 * 3600),
resetDescription: nil)),
NamedRateWindow(
id: "antigravity-quota-summary-gemini-weekly",
title: "Gemini Models Weekly Limit",
window: RateWindow(
usedPercent: 50,
windowMinutes: 10080,
resetsAt: now.addingTimeInterval(4 * 24 * 3600),
resetDescription: nil)),
],
updatedAt: now,
identity: ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: nil,
accountOrganization: nil,
loginMethod: "Pro"))
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: false,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: false,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.map(\.detailLeftText) == [
"20% in deficit",
"7% in deficit",
])
#expect(model.metrics.map(\.detailRightText) == [
"Projected empty in 45m",
"Runs out in 3d",
])
#expect(model.metrics[0].pacePercent == 40)
#expect(abs((model.metrics[1].pacePercent ?? 0) - (400.0 / 7.0)) < 0.01)
#expect(model.metrics.map(\.paceOnTop) == [false, false])
}
@Test
func `antigravity missing groups are omitted in used mode`() throws {
let now = Date()
let identity = ProviderIdentitySnapshot(
providerID: .antigravity,
accountEmail: nil,
accountOrganization: nil,
loginMethod: "Pro")
let snapshot = UsageSnapshot(
primary: RateWindow(
usedPercent: 5,
windowMinutes: nil,
resetsAt: now.addingTimeInterval(3600),
resetDescription: nil),
secondary: nil,
tertiary: nil,
updatedAt: now,
identity: identity)
let metadata = try #require(ProviderDefaults.metadata[.antigravity])
let model = UsageMenuCardView.Model.make(.init(
provider: .antigravity,
metadata: metadata,
snapshot: snapshot,
credits: nil,
creditsError: nil,
dashboard: nil,
dashboardError: nil,
tokenSnapshot: nil,
tokenError: nil,
account: AccountInfo(email: nil, plan: nil),
isRefreshing: false,
lastError: nil,
usageBarsShowUsed: true,
resetTimeDisplayStyle: .countdown,
tokenCostUsageEnabled: false,
showOptionalCreditsAndExtraUsage: true,
hidePersonalInfo: false,
now: now))
#expect(model.metrics.count == 1)
#expect(model.metrics[0].title == "Gemini Models")
#expect(model.metrics[0].percent == 5)
#expect(model.metrics[0].percentLabel == "5% used")
}
}