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

927 lines
37 KiB
Swift

import Foundation
import Testing
@testable import CodexBarCore
struct AlibabaTokenPlanSettingsReaderTests {
@Test
func `cookie reads from environment`() {
let cookie = AlibabaTokenPlanSettingsReader.cookieHeader(environment: [
AlibabaTokenPlanSettingsReader.cookieHeaderKey: "\"login_aliyunid_ticket=ticket\"",
])
#expect(cookie == "login_aliyunid_ticket=ticket")
}
@Test
func `quota URL infers HTTPS scheme`() {
let url = AlibabaTokenPlanSettingsReader.quotaURL(environment: [
AlibabaTokenPlanSettingsReader.quotaURLKey: "quota.token-plan.test/data/api.json",
])
#expect(url?.scheme == "https")
#expect(url?.host == "quota.token-plan.test")
}
@Test
func `quota URL rejects non HTTPS schemes`() {
let httpURL = AlibabaTokenPlanSettingsReader.quotaURL(environment: [
AlibabaTokenPlanSettingsReader.quotaURLKey: "http://quota.token-plan.test/data/api.json",
])
let ftpURL = AlibabaTokenPlanSettingsReader.quotaURL(environment: [
AlibabaTokenPlanSettingsReader.quotaURLKey: "ftp://quota.token-plan.test/data/api.json",
])
#expect(httpURL == nil)
#expect(ftpURL == nil)
}
@Test
func `host override rejects non HTTPS schemes`() {
let httpHost = AlibabaTokenPlanSettingsReader.hostOverride(environment: [
AlibabaTokenPlanSettingsReader.hostKey: "http://dashboard.token-plan.test",
])
let httpsHost = AlibabaTokenPlanSettingsReader.hostOverride(environment: [
AlibabaTokenPlanSettingsReader.hostKey: "https://dashboard.token-plan.test",
])
let bareHost = AlibabaTokenPlanSettingsReader.hostOverride(environment: [
AlibabaTokenPlanSettingsReader.hostKey: "dashboard.token-plan.test",
])
#expect(httpHost == nil)
#expect(httpsHost == "dashboard.token-plan.test")
#expect(bareHost == "dashboard.token-plan.test")
}
@Test
func `default quota URL targets subscription summary API`() {
let url = AlibabaTokenPlanUsageFetcher.defaultQuotaURL
#expect(url.host == "modelstudio.console.alibabacloud.com")
#expect(url.absoluteString.contains("GetSubscriptionSummary"))
#expect(url.absoluteString.contains("BssOpenAPI-V3"))
}
@Test
func `default quota URL for china mainland targets bailian`() {
let url = AlibabaTokenPlanUsageFetcher.defaultQuotaURL(region: .chinaMainland)
#expect(url.host == "bailian.console.aliyun.com")
#expect(url.absoluteString.contains("GetSubscriptionSummary"))
#expect(url.absoluteString.contains("BssOpenAPI-V3"))
}
}
struct AlibabaTokenPlanCookieHeaderTests {
@Test
func `builds URL scoped headers for API and dashboard`() throws {
let cookies = [
self.cookie(name: "login_aliyunid_ticket", value: "ticket", domain: ".alibabacloud.com"),
self.cookie(name: "login_current_pk", value: "account", domain: ".alibabacloud.com"),
self.cookie(name: "sec_token", value: "shared", domain: ".console.alibabacloud.com"),
self.cookie(name: "sec_token", value: "dashboard", domain: "modelstudio.console.alibabacloud.com"),
self.cookie(name: "bailian_only", value: "bailian", domain: "bailian.console.aliyun.com"),
]
let headers = try #require(AlibabaTokenPlanCookieHeader.headers(from: cookies))
#expect(headers.apiCookieHeader.contains("login_aliyunid_ticket=ticket"))
#expect(headers.apiCookieHeader.contains("login_current_pk=account"))
#expect(headers.apiCookieHeader.contains("sec_token=dashboard"))
#expect(!headers.apiCookieHeader.contains("bailian_only=bailian"))
#expect(headers.dashboardCookieHeader.contains("sec_token=dashboard"))
#expect(!headers.dashboardCookieHeader.contains("bailian_only=bailian"))
}
@Test
func `builds URL scoped headers for china mainland region`() throws {
let cookies = [
self.cookie(name: "login_aliyunid_ticket", value: "ticket", domain: ".aliyun.com"),
self.cookie(name: "login_current_pk", value: "account", domain: ".aliyun.com"),
self.cookie(name: "sec_token", value: "shared", domain: ".console.aliyun.com"),
self.cookie(name: "sec_token", value: "dashboard", domain: "bailian.console.aliyun.com"),
self.cookie(name: "modelstudio_only", value: "modelstudio", domain: "modelstudio.console.alibabacloud.com"),
]
let headers = try #require(AlibabaTokenPlanCookieHeader.headers(from: cookies, region: .chinaMainland))
#expect(headers.apiCookieHeader.contains("login_aliyunid_ticket=ticket"))
#expect(headers.apiCookieHeader.contains("login_current_pk=account"))
#expect(headers.apiCookieHeader.contains("sec_token=dashboard"))
#expect(!headers.apiCookieHeader.contains("modelstudio_only=modelstudio"))
#expect(headers.dashboardCookieHeader.contains("sec_token=dashboard"))
#expect(!headers.dashboardCookieHeader.contains("modelstudio_only=modelstudio"))
}
@Test
func `cached token plan headers preserve URL scoping`() throws {
let headers = AlibabaTokenPlanCookieHeaders(
apiCookieHeader: "login_aliyunid_ticket=ticket; api_only=api",
dashboardCookieHeader: "login_aliyunid_ticket=ticket; dashboard_only=dashboard")
let cached = try #require(AlibabaTokenPlanCookieHeaders(cachedHeader: headers.cacheCookieHeader))
#expect(cached.apiCookieHeader.contains("api_only=api"))
#expect(!cached.apiCookieHeader.contains("dashboard_only=dashboard"))
#expect(cached.dashboardCookieHeader.contains("dashboard_only=dashboard"))
#expect(!cached.dashboardCookieHeader.contains("api_only=api"))
}
@Test
func `builds headers from environment scoped URLs`() throws {
let cookies = [
self.cookie(name: "login_aliyunid_ticket", value: "ticket", domain: ".token-plan.test"),
self.cookie(name: "api_only", value: "api", domain: "quota.token-plan.test"),
self.cookie(name: "dashboard_only", value: "dashboard", domain: "dashboard.token-plan.test"),
self.cookie(name: "prod_api_only", value: "prod-api", domain: "modelstudio.console.alibabacloud.com"),
self.cookie(
name: "prod_dashboard_only",
value: "prod-dashboard",
domain: "modelstudio.console.alibabacloud.com"),
]
let headers = try #require(AlibabaTokenPlanCookieHeader.headers(
from: cookies,
environment: [
AlibabaTokenPlanSettingsReader.quotaURLKey: "https://quota.token-plan.test/data/api.json",
AlibabaTokenPlanSettingsReader.hostKey: "https://dashboard.token-plan.test",
]))
#expect(headers.apiCookieHeader.contains("login_aliyunid_ticket=ticket"))
#expect(headers.apiCookieHeader.contains("api_only=api"))
#expect(!headers.apiCookieHeader.contains("prod_api_only=prod-api"))
#expect(headers.dashboardCookieHeader.contains("dashboard_only=dashboard"))
#expect(!headers.dashboardCookieHeader.contains("prod_dashboard_only=prod-dashboard"))
}
private func cookie(
name: String,
value: String,
domain: String,
path: String = "/",
expires: Date = Date(timeIntervalSinceNow: 3600)) -> HTTPCookie
{
HTTPCookie(properties: [
.domain: domain,
.path: path,
.name: name,
.value: value,
.expires: expires,
.secure: true,
])!
}
}
struct AlibabaTokenPlanUsageSnapshotTests {
@Test
func `maps used and total quota to primary window`() {
let now = Date(timeIntervalSince1970: 1_700_000_000)
let reset = Date(timeIntervalSince1970: 1_700_100_000)
let snapshot = AlibabaTokenPlanUsageSnapshot(
planName: "TOKEN PLAN",
usedQuota: 250,
totalQuota: 1000,
remainingQuota: nil,
resetsAt: reset,
updatedAt: now)
let usage = snapshot.toUsageSnapshot()
#expect(usage.primary?.usedPercent == 25)
#expect(usage.primary?.resetsAt == reset)
#expect(usage.primary?.resetDescription == "250 / 1,000 credits used")
#expect(usage.loginMethod(for: .alibabatokenplan) == "TOKEN PLAN")
}
@Test
func `does not create primary window from balance only`() {
let snapshot = AlibabaTokenPlanUsageSnapshot(
planName: "TOKEN PLAN",
usedQuota: nil,
totalQuota: nil,
remainingQuota: 700,
resetsAt: nil,
updatedAt: Date(timeIntervalSince1970: 1_700_000_000))
let usage = snapshot.toUsageSnapshot()
#expect(usage.primary == nil)
#expect(usage.loginMethod(for: .alibabatokenplan) == "TOKEN PLAN")
}
}
@Suite(.serialized)
struct AlibabaTokenPlanUsageParsingTests {
@Test
func `parses subscription summary payload`() throws {
let now = Date(timeIntervalSince1970: 1_700_000_000)
let json = """
{
"Success": true,
"Data": {
"TotalCount": 1,
"TotalValue": 1000,
"TotalSurplusValue": 875,
"NearestExpireDate": 1701000000000
},
"Code": "200"
}
"""
let snapshot = try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8), now: now)
#expect(snapshot.planName == "TOKEN PLAN")
#expect(snapshot.usedQuota == 125)
#expect(snapshot.totalQuota == 1000)
#expect(snapshot.remainingQuota == 875)
#expect(snapshot.resetsAt == Date(timeIntervalSince1970: 1_701_000_000))
#expect(snapshot.toUsageSnapshot().primary?.usedPercent == 12.5)
}
@Test
func `parses nested subscription summary body`() throws {
let body = """
{
"success": true,
"data": {
"totalCount": 1,
"totalSurplusValue": 750,
"totalValue": 1000
}
}
"""
let payload = ["successResponse": ["body": body]]
let data = try JSONSerialization.data(withJSONObject: payload)
let snapshot = try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: data)
#expect(snapshot.planName == "TOKEN PLAN")
#expect(snapshot.usedQuota == 250)
#expect(snapshot.remainingQuota == 750)
#expect(snapshot.totalQuota == 1000)
#expect(snapshot.toUsageSnapshot().primary?.usedPercent == 25)
}
@Test
func `empty subscription summary stays visible without quota window`() throws {
let json = """
{
"Success": true,
"Data": {
"TotalCount": 0
}
}
"""
let snapshot = try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8))
#expect(snapshot.planName == nil)
#expect(snapshot.totalQuota == nil)
#expect(snapshot.toUsageSnapshot().primary == nil)
}
@Test
func `login payload maps to login required`() {
let json = """
{
"code": "ConsoleNeedLogin",
"message": "You need to log in.",
"successResponse": false
}
"""
#expect(throws: AlibabaTokenPlanUsageError.loginRequired) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8))
}
}
@Test
func `post only token payload maps to login required`() {
let json = """
{
"code": "PostonlyOrTokenError",
"message": "Your request has expired. Please refresh the page.",
"successResponse": false
}
"""
#expect(throws: AlibabaTokenPlanUsageError.loginRequired) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8))
}
}
@Test
func `nested unsuccessful subscription summary maps to API error`() throws {
let body = """
{
"success": false,
"message": "Subscription lookup failed"
}
"""
let payload = ["successResponse": ["body": body]]
let data = try JSONSerialization.data(withJSONObject: payload)
#expect(throws: AlibabaTokenPlanUsageError.apiError("Subscription lookup failed")) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: data)
}
}
@Test
func `forbidden payload maps to invalid credentials`() {
let json = """
{
"statusCode": 403,
"message": "Forbidden"
}
"""
#expect(throws: AlibabaTokenPlanUsageError.invalidCredentials) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8))
}
}
@Test
func `failed forbidden payload maps to invalid credentials`() {
let json = """
{
"successResponse": false,
"statusCode": 403,
"message": "Forbidden"
}
"""
#expect(throws: AlibabaTokenPlanUsageError.invalidCredentials) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(json.utf8))
}
}
@Test
func `html login payload maps to login required`() {
let html = """
<html>
<body>Please login to Alibaba Cloud</body>
</html>
"""
#expect(throws: AlibabaTokenPlanUsageError.loginRequired) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data(html.utf8))
}
}
@Test
func `non json payload maps to parse failed`() {
#expect(throws: AlibabaTokenPlanUsageError.parseFailed("Invalid JSON response")) {
try AlibabaTokenPlanUsageFetcher.parseUsageSnapshot(from: Data("not-json".utf8))
}
}
@Test
func `SEC token preflight falls back to user info`() async throws {
defer {
AlibabaTokenPlanStubURLProtocol.handler = nil
}
let hostOverride = "https://alibaba-token-plan.test:9443"
let environment: [String: String] = [
AlibabaTokenPlanSettingsReader.hostKey: hostOverride,
]
let expectedReferer = AlibabaTokenPlanUsageFetcher.dashboardURL(
region: .international,
environment: environment).absoluteString
AlibabaTokenPlanStubURLProtocol.handler = { request in
guard let url = request.url else { throw URLError(.badURL) }
if url.host == "alibaba-token-plan.test",
url.path == "/ap-southeast-1/",
request.httpMethod == "GET"
{
#expect(url.port == 9443)
return Self.makeResponse(url: url, body: "<html></html>", statusCode: 200)
}
if url.host == "alibaba-token-plan.test",
url.path == "/tool/user/info.json",
request.httpMethod == "GET"
{
#expect(url.port == 9443)
#expect(request.value(forHTTPHeaderField: "Cookie") == "login_aliyunid_ticket=ticket; raw_only=keep")
#expect(request.value(forHTTPHeaderField: "Accept") == "application/json, text/plain, */*")
let json = """
{
"code": "200",
"data": {
"secToken": "user-info-token"
},
"successResponse": true
}
"""
return Self.makeResponse(url: url, body: json, statusCode: 200)
}
if url.host == "alibaba-token-plan.test", request.httpMethod == "POST" {
#expect(request.value(forHTTPHeaderField: "Cookie") == "login_aliyunid_ticket=ticket; raw_only=keep")
#expect(request.value(forHTTPHeaderField: "Origin") == "https://modelstudio.console.alibabacloud.com")
#expect(request.value(forHTTPHeaderField: "Referer") == expectedReferer)
let body = Self.requestBodyString(from: request)
#expect(body.contains("sec_token=user-info-token"))
#expect(body.contains("GetSubscriptionSummary"))
#expect(body.contains("BssOpenAPI-V3"))
#expect(body.contains("ProductCode"))
#expect(body.contains("sfm_tokenplanteams_dp_intl"))
let json = """
{
"Success": true,
"Data": {
"TotalCount": 1,
"TotalValue": 1000,
"TotalSurplusValue": 900
}
}
"""
return Self.makeResponse(url: url, body: json, statusCode: 200)
}
throw URLError(.unsupportedURL)
}
let configuration = URLSessionConfiguration.ephemeral
configuration.protocolClasses = [AlibabaTokenPlanStubURLProtocol.self]
let session = URLSession(configuration: configuration)
let snapshot = try await AlibabaTokenPlanUsageFetcher.fetchUsage(
apiCookieHeader: "login_aliyunid_ticket=ticket; raw_only=keep",
dashboardCookieHeader: "login_aliyunid_ticket=ticket; raw_only=keep",
environment: environment,
session: session)
#expect(snapshot.planName == "TOKEN PLAN")
}
@Test
func `SEC token preflight uses injected session`() async throws {
AlibabaTokenPlanStubURLProtocol.handler = { request in
guard let url = request.url else { throw URLError(.badURL) }
if url.host == "session-token.test", request.httpMethod == "GET" {
return Self.makeResponse(
url: url,
body: "<html><script>sec_token = \"session-html-token\";</script></html>",
statusCode: 200)
}
if url.host == "session-token.test", request.httpMethod == "POST" {
let body = Self.requestBodyString(from: request)
#expect(body.contains("sec_token=session-html-token"))
let json = """
{
"Success": true,
"Data": {
"TotalCount": 1,
"TotalValue": 1000,
"TotalSurplusValue": 900
}
}
"""
return Self.makeResponse(url: url, body: json, statusCode: 200)
}
throw URLError(.unsupportedURL)
}
defer {
AlibabaTokenPlanStubURLProtocol.handler = nil
}
let configuration = URLSessionConfiguration.ephemeral
configuration.protocolClasses = [AlibabaTokenPlanStubURLProtocol.self]
let session = URLSession(configuration: configuration)
let snapshot = try await AlibabaTokenPlanUsageFetcher.fetchUsage(
apiCookieHeader: "login_aliyunid_ticket=ticket",
dashboardCookieHeader: "login_aliyunid_ticket=ticket",
environment: [AlibabaTokenPlanSettingsReader.hostKey: "https://session-token.test"],
session: session)
#expect(snapshot.planName == "TOKEN PLAN")
}
@Test
func `redirect preserves cookie only for same host HTTPS requests`() throws {
let sourceURL = try #require(URL(string: "https://bailian.console.aliyun.com/data/api.json"))
let sameHostURL = try #require(URL(string: "https://bailian.console.aliyun.com/redirected"))
let crossHostURL = try #require(URL(string: "https://signin.aliyun.com/login"))
let insecureURL = try #require(URL(string: "http://bailian.console.aliyun.com/redirected"))
let response = try #require(HTTPURLResponse(
url: sourceURL,
statusCode: 302,
httpVersion: "HTTP/1.1",
headerFields: nil))
var sameHostRequest = URLRequest(url: sameHostURL)
sameHostRequest.setValue("old=value", forHTTPHeaderField: "Cookie")
let sameHostRedirect = try #require(AlibabaTokenPlanUsageFetcher.redirectedRequest(
response: response,
request: sameHostRequest,
cookieHeader: "login_aliyunid_ticket=ticket"))
#expect(sameHostRedirect.value(forHTTPHeaderField: "Cookie") == "login_aliyunid_ticket=ticket")
var crossHostRequest = URLRequest(url: crossHostURL)
crossHostRequest.setValue("old=value", forHTTPHeaderField: "Cookie")
let crossHostRedirect = try #require(AlibabaTokenPlanUsageFetcher.redirectedRequest(
response: response,
request: crossHostRequest,
cookieHeader: "login_aliyunid_ticket=ticket"))
#expect(crossHostRedirect.value(forHTTPHeaderField: "Cookie") == nil)
let insecureRedirect = AlibabaTokenPlanUsageFetcher.redirectedRequest(
response: response,
request: URLRequest(url: insecureURL),
cookieHeader: "login_aliyunid_ticket=ticket")
#expect(insecureRedirect == nil)
}
@Test
func `dashboard redirect preserves dashboard cookie header`() throws {
let sourceURL = try #require(URL(string: "https://bailian.console.aliyun.com/cn-beijing"))
let targetURL = try #require(URL(string: "https://bailian.console.aliyun.com/redirected"))
let response = try #require(HTTPURLResponse(
url: sourceURL,
statusCode: 302,
httpVersion: "HTTP/1.1",
headerFields: nil))
var request = URLRequest(url: targetURL)
request.setValue("api_only=wrong", forHTTPHeaderField: "Cookie")
let redirected = try #require(AlibabaTokenPlanUsageFetcher.redirectedRequest(
response: response,
request: request,
cookieHeader: "dashboard_only=keep"))
#expect(redirected.value(forHTTPHeaderField: "Cookie") == "dashboard_only=keep")
}
private static func makeResponse(url: URL, body: String, statusCode: Int) -> (HTTPURLResponse, Data) {
let response = HTTPURLResponse(
url: url,
statusCode: statusCode,
httpVersion: "HTTP/1.1",
headerFields: ["Content-Type": "application/json"])!
return (response, Data(body.utf8))
}
private static func requestBodyString(from request: URLRequest) -> String {
if let data = request.httpBody {
return String(data: data, encoding: .utf8) ?? ""
}
if let stream = request.httpBodyStream {
stream.open()
defer {
stream.close()
}
var data = Data()
var buffer = [UInt8](repeating: 0, count: 1024)
while stream.hasBytesAvailable {
let count = stream.read(&buffer, maxLength: buffer.count)
if count <= 0 {
break
}
data.append(buffer, count: count)
}
return String(data: data, encoding: .utf8) ?? ""
}
return ""
}
}
@Suite(.serialized)
struct AlibabaTokenPlanWebStrategyTests {
private struct StubClaudeFetcher: ClaudeUsageFetching {
func loadLatestUsage(model _: String) async throws -> ClaudeUsageSnapshot {
throw ClaudeUsageError.parseFailed("stub")
}
func debugRawProbe(model _: String) async -> String {
"stub"
}
func detectVersion() -> String? {
nil
}
}
private func clearCookieCaches() {
CookieHeaderCache.clear(provider: .alibabatokenplan)
for region in AlibabaTokenPlanAPIRegion.allCases {
CookieHeaderCache.clear(provider: .alibabatokenplan, scope: region.cookieCacheScope)
}
}
@Test
func `auto web strategy surfaces cookie import errors`() async throws {
let strategy = AlibabaTokenPlanWebFetchStrategy()
let settings = ProviderSettingsSnapshot.make(
alibabaTokenPlan: ProviderSettingsSnapshot.AlibabaTokenPlanProviderSettings(
cookieSource: .auto,
manualCookieHeader: nil))
let context = ProviderFetchContext(
runtime: .cli,
sourceMode: .web,
includeCredits: false,
webTimeout: 1,
webDebugDumpHTML: false,
verbose: false,
env: [:],
settings: settings,
fetcher: UsageFetcher(environment: [:]),
claudeFetcher: StubClaudeFetcher(),
browserDetection: BrowserDetection(cacheTTL: 0))
self.clearCookieCaches()
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
throw AlibabaCodingPlanSettingsError.missingCookie(
details: "macOS Keychain denied access to Chrome Safe Storage.")
}
defer {
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = nil
self.clearCookieCaches()
}
#expect(await strategy.isAvailable(context))
do {
_ = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeader(context: context, allowCached: false)
Issue.record("Expected cookie import failure to be surfaced")
} catch let error as AlibabaTokenPlanSettingsError {
guard case let .missingCookie(details) = error else {
Issue.record("Expected missingCookie, got \(error)")
return
}
#expect(details == "macOS Keychain denied access to Chrome Safe Storage.")
#expect(error.localizedDescription.contains("Alibaba Token Plan"))
#expect(!error.localizedDescription.contains("Alibaba Coding Plan"))
}
}
@Test
func `auto web strategy imports subscription scoped token plan cookies`() throws {
let strategy = AlibabaTokenPlanWebFetchStrategy()
let settings = ProviderSettingsSnapshot.make(
alibabaTokenPlan: ProviderSettingsSnapshot.AlibabaTokenPlanProviderSettings(
cookieSource: .auto,
manualCookieHeader: nil))
let context = ProviderFetchContext(
runtime: .cli,
sourceMode: .web,
includeCredits: false,
webTimeout: 1,
webDebugDumpHTML: false,
verbose: false,
env: [:],
settings: settings,
fetcher: UsageFetcher(environment: [:]),
claudeFetcher: StubClaudeFetcher(),
browserDetection: BrowserDetection(cacheTTL: 0))
self.clearCookieCaches()
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
AlibabaCodingPlanCookieImporter.SessionInfo(
cookies: [
self.cookie(name: "login_aliyunid_ticket", value: "ticket", domain: ".alibabacloud.com"),
self.cookie(name: "login_current_pk", value: "account", domain: ".alibabacloud.com"),
self.cookie(
name: "dashboard_only",
value: "dashboard",
domain: "modelstudio.console.alibabacloud.com"),
self.cookie(
name: "bailian_only",
value: "bailian",
domain: "bailian.console.aliyun.com"),
self.cookie(name: "aliyun_only", value: "aliyun", domain: ".aliyun.com"),
],
sourceLabel: "Chrome Default")
}
defer {
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = nil
self.clearCookieCaches()
}
let headers = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(context: context, allowCached: false)
#expect(headers.apiCookieHeader == headers.dashboardCookieHeader)
#expect(headers.apiCookieHeader.contains("dashboard_only=dashboard"))
#expect(!headers.apiCookieHeader.contains("bailian_only=bailian"))
#expect(!headers.apiCookieHeader.contains("aliyun_only=aliyun"))
#expect(headers.dashboardCookieHeader.contains("dashboard_only=dashboard"))
#expect(!headers.dashboardCookieHeader.contains("bailian_only=bailian"))
#expect(!headers.dashboardCookieHeader.contains("aliyun_only=aliyun"))
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
throw AlibabaCodingPlanSettingsError.missingCookie(details: "unexpected import")
}
let cachedHeaders = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(
context: context,
allowCached: true)
#expect(cachedHeaders.apiCookieHeader == headers.apiCookieHeader)
#expect(cachedHeaders.dashboardCookieHeader == headers.dashboardCookieHeader)
#expect(strategy.id == "alibaba-token-plan.web")
}
@Test
func `auto web strategy scopes imported cookies to environment overrides`() throws {
let settings = ProviderSettingsSnapshot.make(
alibabaTokenPlan: ProviderSettingsSnapshot.AlibabaTokenPlanProviderSettings(
cookieSource: .auto,
manualCookieHeader: nil))
let environment = [
AlibabaTokenPlanSettingsReader.quotaURLKey: "https://quota.token-plan.test/data/api.json",
AlibabaTokenPlanSettingsReader.hostKey: "https://dashboard.token-plan.test",
]
let context = ProviderFetchContext(
runtime: .cli,
sourceMode: .web,
includeCredits: false,
webTimeout: 1,
webDebugDumpHTML: false,
verbose: false,
env: environment,
settings: settings,
fetcher: UsageFetcher(environment: environment),
claudeFetcher: StubClaudeFetcher(),
browserDetection: BrowserDetection(cacheTTL: 0))
self.clearCookieCaches()
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
AlibabaCodingPlanCookieImporter.SessionInfo(
cookies: [
self.cookie(name: "login_aliyunid_ticket", value: "ticket", domain: ".token-plan.test"),
self.cookie(name: "api_only", value: "api", domain: "quota.token-plan.test"),
self.cookie(name: "dashboard_only", value: "dashboard", domain: "dashboard.token-plan.test"),
self.cookie(name: "prod_api_only", value: "prod-api", domain: "bailian.console.aliyun.com"),
self.cookie(
name: "prod_dashboard_only",
value: "prod-dashboard",
domain: "bailian.console.aliyun.com"),
],
sourceLabel: "Chrome Default")
}
defer {
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = nil
self.clearCookieCaches()
}
let headers = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(context: context, allowCached: false)
#expect(headers.apiCookieHeader.contains("api_only=api"))
#expect(!headers.apiCookieHeader.contains("prod_api_only=prod-api"))
#expect(headers.dashboardCookieHeader.contains("dashboard_only=dashboard"))
#expect(!headers.dashboardCookieHeader.contains("prod_dashboard_only=prod-dashboard"))
}
@Test
func `cached browser cookies stay isolated by gateway region`() throws {
self.clearCookieCaches()
defer { self.clearCookieCaches() }
CookieHeaderCache.store(
provider: .alibabatokenplan,
scope: AlibabaTokenPlanAPIRegion.international.cookieCacheScope,
cookieHeader: "login_aliyunid_ticket=intl-ticket; gateway=intl",
sourceLabel: "International fixture")
CookieHeaderCache.store(
provider: .alibabatokenplan,
scope: AlibabaTokenPlanAPIRegion.chinaMainland.cookieCacheScope,
cookieHeader: "login_aliyunid_ticket=cn-ticket; gateway=cn",
sourceLabel: "China fixture")
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
throw AlibabaCodingPlanSettingsError.missingCookie(details: "unexpected import")
}
defer { AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = nil }
let context = self.context(region: .international)
let international = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(
context: context,
allowCached: true,
region: .international)
let china = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(
context: context,
allowCached: true,
region: .chinaMainland)
#expect(international.apiCookieHeader.contains("gateway=intl"))
#expect(!international.apiCookieHeader.contains("gateway=cn"))
#expect(china.apiCookieHeader.contains("gateway=cn"))
#expect(!china.apiCookieHeader.contains("gateway=intl"))
}
@Test
func `legacy unscoped cache migrates only to China gateway`() throws {
self.clearCookieCaches()
defer {
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = nil
self.clearCookieCaches()
}
CookieHeaderCache.store(
provider: .alibabatokenplan,
cookieHeader: "login_aliyunid_ticket=legacy; gateway=legacy-cn",
sourceLabel: "Legacy fixture")
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
AlibabaCodingPlanCookieImporter.SessionInfo(
cookies: [
self.cookie(
name: "login_aliyunid_ticket",
value: "intl",
domain: ".alibabacloud.com"),
self.cookie(
name: "gateway",
value: "intl",
domain: "modelstudio.console.alibabacloud.com"),
],
sourceLabel: "International fixture")
}
let context = self.context(region: .international)
let international = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(
context: context,
allowCached: true,
region: .international)
AlibabaCodingPlanCookieImporter.importSessionOverrideForTesting = { _, _ in
throw AlibabaCodingPlanSettingsError.missingCookie(details: "unexpected China import")
}
let china = try AlibabaTokenPlanWebFetchStrategy.resolveCookieHeaders(
context: context,
allowCached: true,
region: .chinaMainland)
#expect(international.apiCookieHeader.contains("gateway=intl"))
#expect(!international.apiCookieHeader.contains("gateway=legacy-cn"))
#expect(china.apiCookieHeader.contains("gateway=legacy-cn"))
#expect(CookieHeaderCache.load(provider: .alibabatokenplan) == nil)
#expect(CookieHeaderCache.load(
provider: .alibabatokenplan,
scope: AlibabaTokenPlanAPIRegion.chinaMainland.cookieCacheScope) != nil)
}
private func context(region: AlibabaTokenPlanAPIRegion) -> ProviderFetchContext {
let settings = ProviderSettingsSnapshot.make(
alibabaTokenPlan: ProviderSettingsSnapshot.AlibabaTokenPlanProviderSettings(
cookieSource: .auto,
manualCookieHeader: nil,
apiRegion: region))
return ProviderFetchContext(
runtime: .cli,
sourceMode: .web,
includeCredits: false,
webTimeout: 1,
webDebugDumpHTML: false,
verbose: false,
env: [:],
settings: settings,
fetcher: UsageFetcher(environment: [:]),
claudeFetcher: StubClaudeFetcher(),
browserDetection: BrowserDetection(cacheTTL: 0))
}
private func cookie(
name: String,
value: String,
domain: String,
path: String = "/",
expires: Date = Date(timeIntervalSinceNow: 3600)) -> HTTPCookie
{
HTTPCookie(properties: [
.domain: domain,
.path: path,
.name: name,
.value: value,
.expires: expires,
.secure: true,
])!
}
}
final class AlibabaTokenPlanStubURLProtocol: URLProtocol {
nonisolated(unsafe) static var handler: ((URLRequest) throws -> (HTTPURLResponse, Data))?
override static func canInit(with request: URLRequest) -> Bool {
guard let host = request.url?.host else { return false }
return host == "bailian.console.aliyun.com" ||
host == "alibaba-token-plan.test" ||
host == "session-token.test"
}
override static func canonicalRequest(for request: URLRequest) -> URLRequest {
request
}
override func startLoading() {
guard let handler = Self.handler else {
self.client?.urlProtocol(self, didFailWithError: URLError(.badServerResponse))
return
}
do {
let (response, data) = try handler(self.request)
self.client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
self.client?.urlProtocol(self, didLoad: data)
self.client?.urlProtocolDidFinishLoading(self)
} catch {
self.client?.urlProtocol(self, didFailWithError: error)
}
}
override func stopLoading() {}
}