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

558 lines
24 KiB
Swift

import CodexBarCore
import Foundation
import Testing
@Suite(.serialized)
struct GeminiStatusProbePlanTests {
@Test
func `selects project id for quota requests`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let expectedProject = "gen-lang-client-123"
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
let json = GeminiAPITestHelpers.jsonData([
"projects": [
["projectId": expectedProject],
],
])
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 200, body: json)
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistFreeTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
let bodyText = request.httpBody.flatMap { String(data: $0, encoding: .utf8) } ?? ""
if !bodyText.contains(expectedProject) {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 400, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleFlashQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.modelQuotas.contains { $0.percentLeft == 40 })
let usage = snapshot.toUsageSnapshot()
#expect(usage.secondary?.remainingPercent == 40)
#expect(usage.tertiary == nil)
}
@Test
func `prefers load code assist project for quota requests`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let loadCodeAssistProject = "cloudaicompanion-123"
let fallbackProject = "gen-lang-client-should-not-use"
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
let json = GeminiAPITestHelpers.jsonData([
"projects": [
["projectId": fallbackProject],
],
])
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 200, body: json)
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistResponse(
tierId: "free-tier",
projectId: loadCodeAssistProject))
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
let bodyText = request.httpBody.flatMap { String(data: $0, encoding: .utf8) } ?? ""
if !bodyText.contains(loadCodeAssistProject) {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 400, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleFlashQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.modelQuotas.contains { $0.percentLeft == 40 })
let usage = snapshot.toUsageSnapshot()
#expect(usage.secondary?.remainingPercent == 40)
#expect(usage.tertiary == nil)
}
@Test
func `separates flash and flash lite quota buckets from api response`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistStandardTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
let usage = snapshot.toUsageSnapshot()
#expect(usage.primary?.remainingPercent == 60.0)
#expect(usage.secondary?.remainingPercent == 90.0)
#expect(usage.tertiary?.remainingPercent == 80.0)
}
@Test
func `detects paid from standard tier`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistStandardTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Paid")
}
@Test
func `detects workspace from free tier with hosted domain`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
let idToken = GeminiAPITestHelpers.makeIDToken(email: "user@company.com", hostedDomain: "company.com")
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: idToken)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistFreeTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Workspace")
}
@Test
func `detects consumer plus from free tier with paid tier name`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
let idToken = GeminiAPITestHelpers.makeIDToken(email: "user@gmail.com")
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: idToken)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistConsumerPlusResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Plus")
}
@Test
func `uses paid tier name for standard tier subscriptions`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistGoogleOneProResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Gemini Code Assist in Google One AI Pro")
}
@Test
func `paid tier name overrides workspace fallback`() async throws {
let plan = try await Self.fetchPlan(
tierId: "free-tier",
hostedDomain: "example.com",
paidTierName: "Plus")
#expect(plan == "Plus")
}
@Test
func `paid tier name survives unknown current tier`() async throws {
let plan = try await Self.fetchPlan(
tierId: "future-tier",
hostedDomain: nil,
paidTierName: "Gemini Code Assist in Google One AI Pro")
#expect(plan == "Gemini Code Assist in Google One AI Pro")
}
@Test
func `paid tier name survives missing current tier`() async throws {
let plan = try await Self.fetchPlan(
tierId: nil,
hostedDomain: nil,
paidTierName: "Plus")
#expect(plan == "Plus")
}
@Test
func `detects free from free tier without hosted domain`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
let idToken = GeminiAPITestHelpers.makeIDToken(email: "user@gmail.com")
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: idToken)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistFreeTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleFlashQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Free")
}
@Test
func `detects legacy from legacy tier`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistLegacyTierResponse())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == "Legacy")
}
@Test
func `leaves blank when load code assist fails`() async throws {
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: nil)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 500,
body: Data())
}
if url.path != "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
let snapshot = try await probe.fetch()
#expect(snapshot.accountPlan == nil)
}
private static func fetchPlan(
tierId: String?,
hostedDomain: String?,
paidTierName: String) async throws -> String?
{
let env = try GeminiTestEnvironment()
defer { env.cleanup() }
let idToken = GeminiAPITestHelpers.makeIDToken(
email: "user@example.com",
hostedDomain: hostedDomain)
try env.writeCredentials(
accessToken: "token",
refreshToken: nil,
expiry: Date().addingTimeInterval(3600),
idToken: idToken)
let dataLoader = GeminiAPITestHelpers.dataLoader { request in
guard let url = request.url, let host = url.host else {
throw URLError(.badURL)
}
switch host {
case "cloudresourcemanager.googleapis.com":
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.jsonData(["projects": []]))
case "cloudcode-pa.googleapis.com":
if url.path == "/v1internal:loadCodeAssist" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.loadCodeAssistResponse(
tierId: tierId,
paidTierName: paidTierName))
}
if url.path == "/v1internal:retrieveUserQuota" {
return GeminiAPITestHelpers.response(
url: url.absoluteString,
status: 200,
body: GeminiAPITestHelpers.sampleQuotaResponse())
}
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
default:
return GeminiAPITestHelpers.response(url: url.absoluteString, status: 404, body: Data())
}
}
let probe = GeminiStatusProbe(timeout: 1, homeDirectory: env.homeURL.path, dataLoader: dataLoader)
return try await probe.fetch().accountPlan
}
}