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 = """
Please login to Alibaba Cloud """ #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: "", 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: "", 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() {} }