392 lines · 15.8 KB · Swift
RawDownload
import Foundationimport Testing@testable import CodexBarCore @Suite(.serialized)struct DevinUsageFetcherTests {    private static let now = Date(timeIntervalSince1970: 1_780_000_000)     @Test    func `parses quota usage response into daily and weekly windows`() throws {        let response: [String: Any] = [            "plan_name": "pro",            "quota_usage": [                "daily_quota": [                    "used": 3,                    "limit": 10,                    "reset_at": "2026-06-01T08:00:00Z",                ],                "weekly_quota": [                    "remaining_percent": 0.25,                    "next_reset_at": 1_780_560_000,                ],            ],        ]         let snapshot = try DevinUsageParser.parse(response, organization: "org/example-org", now: Self.now)         #expect(snapshot.daily?.usedPercent == 30)        #expect(snapshot.weekly?.usedPercent == 75)        #expect(snapshot.daily?.resetsAt?.timeIntervalSince1970 == 1_780_300_800)        #expect(snapshot.weekly?.resetsAt?.timeIntervalSince1970 == 1_780_560_000)        #expect(snapshot.planName == "Pro")        #expect(snapshot.organization == "example-org")    }     @Test    func `parses current Devin quota response with reset timestamps`() throws {        let response: [String: Any] = [            "is_quota_plan": true,            "has_quota_allocation": true,            "daily_percentage": 0.12,            "weekly_percentage": 42,            "daily_reset_at": "2026-06-11T00:00:00-08:00",            "weekly_reset_at": "2026-06-14T00:00:00-08:00",            "hide_daily_quota": false,        ]         let snapshot = try DevinUsageParser.parse(response, organization: "org/example-org", now: Self.now)         #expect(snapshot.daily?.usedPercent == 12)        #expect(snapshot.weekly?.usedPercent == 42)        #expect(snapshot.daily?.resetsAt?.timeIntervalSince1970 == 1_781_164_800)        #expect(snapshot.weekly?.resetsAt?.timeIntervalSince1970 == 1_781_424_000)    }     @Test    func `keeps weekly quota when current plan hides daily quota`() throws {        let response: [String: Any] = [            "weekly_percentage": 25,            "weekly_reset_at": "2026-06-14T00:00:00-08:00",            "hide_daily_quota": true,        ]         let usage = try DevinUsageParser.parse(response, organization: nil, now: Self.now).toUsageSnapshot()         #expect(usage.primary == nil)        #expect(usage.secondary?.usedPercent == 25)    }     @Test    func `parses zero percentages from JSON response`() throws {        let data = Data("""        {          "daily_percentage": 0,          "weekly_percentage": 0,          "daily_reset_at": "2026-06-11T00:00:00-08:00",          "weekly_reset_at": "2026-06-14T00:00:00-08:00"        }        """.utf8)         let snapshot = try DevinUsageParser.parse(data, organization: nil, now: Self.now)         #expect(snapshot.daily?.usedPercent == 0)        #expect(snapshot.weekly?.usedPercent == 0)    }     @Test    func `usage snapshot maps Devin quotas to primary and secondary windows`() {        let snapshot = DevinUsageSnapshot(            daily: DevinQuotaWindow(usedPercent: 12),            weekly: DevinQuotaWindow(usedPercent: 42),            planName: "Free",            organization: "example-org",            updatedAt: Self.now)         let usage = snapshot.toUsageSnapshot()         #expect(usage.primary?.usedPercent == 12)        #expect(usage.primary?.windowMinutes == 1440)        #expect(usage.primary?.resetDescription == "Daily")        #expect(usage.secondary?.usedPercent == 42)        #expect(usage.secondary?.windowMinutes == 10080)        #expect(usage.secondary?.resetDescription == "Weekly")        #expect(usage.identity?.providerID == .devin)        #expect(usage.identity?.accountOrganization == "example-org")        #expect(usage.identity?.loginMethod == "Free")    }     @Test    func `fetch sends bearer token and organization header`() async throws {        let auth = DevinUsageFetcher.RequestAuth(            bearerToken: "secret-token",            organization: "org/example-org",            internalOrganizationID: "org_GQ6LhcfkW1TSinM6",            sourceLabel: "test")        let stub = ProviderHTTPTransportStub { request in            #expect(request.url?.host == "app.devin.ai")            #expect(request.url?.path == "/api/org_GQ6LhcfkW1TSinM6/billing/quota/usage")            #expect(request.value(forHTTPHeaderField: "Authorization") == "Bearer secret-token")            #expect(request.value(forHTTPHeaderField: "x-cog-org-id") == "org_GQ6LhcfkW1TSinM6")            let body = """            {"daily":{"used_percent":10},"weekly":{"used_percent":20},"plan":"free"}            """            let response = HTTPURLResponse(                url: request.url!,                statusCode: 200,                httpVersion: nil,                headerFields: nil)!            return (Data(body.utf8), response)        }         let snapshot = try await DevinUsageFetcher.fetchQuotaUsage(            auth: auth,            now: Self.now,            transport: stub)         #expect(snapshot.daily?.usedPercent == 10)        #expect(snapshot.weekly?.usedPercent == 20)        #expect(snapshot.planName == "Free")    }     @Test    func `fetch does not mask parser failure with fallback endpoint errors`() async {        let auth = DevinUsageFetcher.RequestAuth(            bearerToken: "secret-token",            organization: "org/example-org",            internalOrganizationID: "org_GQ6LhcfkW1TSinM6",            sourceLabel: "test")        let stub = ProviderHTTPTransportStub { request in            let response = HTTPURLResponse(                url: request.url!,                statusCode: request.url?.path == "/api/org_GQ6LhcfkW1TSinM6/billing/quota/usage" ? 200 : 404,                httpVersion: nil,                headerFields: nil)!            return (Data("{}".utf8), response)        }         do {            _ = try await DevinUsageFetcher.fetchQuotaUsage(                auth: auth,                now: Self.now,                transport: stub)            Issue.record("Expected quota parsing to fail")        } catch let error as DevinUsageError {            guard case .parseFailed = error else {                Issue.record("Expected parseFailed, got \(error)")                return            }        } catch {            Issue.record("Expected DevinUsageError, got \(error)")        }         #expect(await stub.requests().count == 1)    }     @Test    func `normalizes organization inputs`() {        #expect(DevinUsageFetcher.normalizedOrganization("example-org") == "org/example-org")        #expect(DevinUsageFetcher.normalizedOrganization("org/example-org") == "org/example-org")        #expect(DevinUsageFetcher.normalizedOrganization("org_GQ6LhcfkW1TSinM6") ==            "organizations/org_GQ6LhcfkW1TSinM6")        #expect(DevinUsageFetcher.normalizedOrganization("org-b31f951cd01d4c6da84991cf5b970cfb") ==            "organizations/org-b31f951cd01d4c6da84991cf5b970cfb")        #expect(DevinUsageFetcher.normalizedOrganization("https://app.devin.ai/org/example-org/settings/usage") ==            "org/example-org")    }     @Test    func `manual auth strips Authorization and Bearer prefixes`() throws {        let auth = try #require(DevinUsageFetcher.manualAuth(            from: "Authorization: Bearer secret-token",            organization: "example-org"))         #expect(auth.bearerToken == "secret-token")        #expect(auth.organization == "org/example-org")        #expect(auth.sourceLabel == "manual")    }     #if os(macOS)    @Test    func `empty app organization setting preserves imported organization`() async throws {        defer { DevinSessionImporter.importSessionOverrideForTesting = nil }        DevinSessionImporter.importSessionOverrideForTesting = { _, organizationOverride, _ in            #expect(organizationOverride == nil)            return DevinSessionImporter.SessionInfo(                accessToken: "auth1_abcdefghijklmnopqrstuvwxyz0123456789",                organization: "org/example-org",                internalOrganizationID: "org_GQ6LhcfkW1TSinM6",                sourceLabel: "Chrome Default")        }        let stub = ProviderHTTPTransportStub { request in            #expect(request.url?.path == "/api/org_GQ6LhcfkW1TSinM6/billing/quota/usage")            let response = HTTPURLResponse(                url: request.url!,                statusCode: 200,                httpVersion: nil,                headerFields: nil)!            return (Data(#"{"daily_percentage":0,"weekly_percentage":0}"#.utf8), response)        }         let snapshot = try await DevinUsageFetcher(browserDetection: BrowserDetection(cacheTTL: 0)).fetch(            organizationOverride: "",            now: Self.now,            transport: stub)         #expect(snapshot.organization == "example-org")        #expect(snapshot.daily?.usedPercent == 0)        #expect(snapshot.weekly?.usedPercent == 0)    }     @Test    func `session importer extracts current auth1 token and matching org`() throws {        let accessToken = "auth1_abcdefghijklmnopqrstuvwxyz0123456789"        let storage = [            "_https://app.devin.ai\u{0000}\u{0001}auth1_session":                #"{"token":"\#(accessToken)","userId":"github|123"}"#,            "_https://app.devin.ai\u{0000}\u{0001}last-internal-org-for-external-org-v1-example-org":                "\"org_GQ6LhcfkW1TSinM6\"",        ]         let session = try #require(DevinSessionImporter.session(            from: storage,            organizationOverride: "example-org",            sourceLabel: "Chrome Default"))         #expect(session.accessToken == accessToken)        #expect(session.organization == "org/example-org")        #expect(session.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")        #expect(session.sourceLabel == "Chrome Default")    }     @Test    func `session importer infers organization from post auth storage`() throws {        let accessToken = "eyJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2F1dGguZGV2aW4uYWkvIn0.signature"        let storage = [            "_https://app.devin.ai\u{0000}\u{0001}@@auth0spajs@@::client::audience::scope":                #"{"body":{"access_token":"\#(accessToken)"}}"#,            "_https://app.devin.ai\u{0000}\u{0001}post-auth-v3-null-github|123-org_name-example-org": """            {              "externalOrgId": null,              "userId": "github|123",              "internalOrgId": "org_GQ6LhcfkW1TSinM6",              "orgName": "example-org"            }            """,        ]         let session = try #require(DevinSessionImporter.session(            from: storage,            organizationOverride: nil,            sourceLabel: "Brave Default"))         #expect(session.organization == "org/example-org")        #expect(session.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")    }     @Test    func `session importer infers organization from member info storage`() throws {        let accessToken = "eyJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwczovL2F1dGguZGV2aW4uYWkvIn0.signature"        let storage = [            "_https://app.devin.ai\u{0000}\u{0001}@@auth0spajs@@::client::audience::scope":                #"{"body":{"access_token":"\#(accessToken)"}}"#,            "_https://app.devin.ai\u{0000}\u{0001}member-info-v1-org-github|123": """            {              "value": {                "org_id": "org_GQ6LhcfkW1TSinM6",                "org_name": "example-org"              }            }            """,        ]         let session = try #require(DevinSessionImporter.session(            from: storage,            organizationOverride: nil,            sourceLabel: "Brave Default"))         #expect(session.organization == "org/example-org")        #expect(session.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")    }     @Test    func `session importer falls back to internal organization id`() {        let result = DevinSessionImporter.organizationInfo(            from: [                "_https://app.devin.ai\u{0000}\u{0001}feature-flags-cache:org_GQ6LhcfkW1TSinM6": "{}",                "_https://app.devin.ai\u{0000}\u{0001}member-info-v1-org-github|123": """                {"value":{"org_id":"org_GQ6LhcfkW1TSinM6"}}                """,            ],            organizationOverride: nil)         #expect(result.organization == "organizations/org_GQ6LhcfkW1TSinM6")        #expect(result.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")    }     @Test    func `session importer ignores org words inside storage key names`() {        let result = DevinSessionImporter.organizationInfo(            from: [                "_https://app.devin.ai\u{0000}\u{0001}last-internal-org-for-external-org-v1-null": "\"null\"",                "_https://app.devin.ai\u{0000}\u{0001}feature-flags-cache:org_GQ6LhcfkW1TSinM6": "{}",            ],            organizationOverride: nil)         #expect(result.organization == "organizations/org_GQ6LhcfkW1TSinM6")        #expect(result.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")    }     @Test    func `session importer deduplicates repeated browser tokens using richest organization metadata`() {        let sessions = [            DevinSessionImporter.SessionInfo(                accessToken: "auth1_abcdefghijklmnopqrstuvwxyz0123456789",                organization: nil,                internalOrganizationID: nil,                sourceLabel: "Chrome Default"),            DevinSessionImporter.SessionInfo(                accessToken: "auth1_abcdefghijklmnopqrstuvwxyz0123456789",                organization: "org/example",                internalOrganizationID: "org_GQ6LhcfkW1TSinM6",                sourceLabel: "Chrome Profile 1"),        ]         let deduplicated = DevinSessionImporter.deduplicateSessions(sessions)         #expect(deduplicated.count == 1)        #expect(deduplicated.first?.sourceLabel == "Chrome Profile 1")        #expect(deduplicated.first?.organization == "org/example")        #expect(deduplicated.first?.internalOrganizationID == "org_GQ6LhcfkW1TSinM6")    }     @Test    func `session importer ranks organization aware profiles first`() {        let incomplete = DevinSessionImporter.SessionInfo(            accessToken: "auth1_incomplete",            organization: nil,            internalOrganizationID: nil,            sourceLabel: "Chrome Default")        let complete = DevinSessionImporter.SessionInfo(            accessToken: "auth1_complete",            organization: "org/example",            internalOrganizationID: "org_GQ6LhcfkW1TSinM6",            sourceLabel: "Chrome Profile 1")         let ranked = DevinSessionImporter.rankSessions([incomplete, complete])         #expect(ranked.map(\.sourceLabel) == ["Chrome Profile 1", "Chrome Default"])    }     @Test    func `missing organization retries the next browser profile`() {        #expect(DevinUsageFetcher.shouldTryNextSession(after: DevinUsageError.missingOrganization))        #expect(!DevinUsageFetcher.shouldTryNextSession(after: DevinUsageError.parseFailed("invalid response")))    }     @Test    func `automatic local storage import does not fall back beyond Chrome`() throws {        let temp = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)        defer { try? FileManager.default.removeItem(at: temp) }         let braveRoot = temp            .appendingPathComponent("Library/Application Support/BraveSoftware/Brave-Browser/Default")        try FileManager.default.createDirectory(at: braveRoot, withIntermediateDirectories: true)        let detection = BrowserDetection(homeDirectory: temp.path, cacheTTL: 0)         #expect(detection.hasUsableProfileData(.brave))        #expect(!detection.hasUsableProfileData(.chrome))        #expect(DevinSessionImporter.localStorageBrowsers(browserDetection: detection).isEmpty)    }    #endif}