import CodexBarCore import Foundation import Testing /// Tests for the lightweight JetBrains XML scanner used on Linux. /// These tests verify that the non-libxml2 implementation correctly parses /// JetBrains AI Assistant quota files. @Suite struct JetBrainsParserLinuxTests { @Test func parsesQuotaXMLWithBothOptions() throws { let quotaInfo = [ "{ "type": "Available",", " "current": "7478.3",", " "maximum": "1000000",", " "until": "2026-11-09T21:00:00Z",", " "tariffQuota": {", " "current": "7478.3",", " "maximum": "1000000",", " "available": "992521.7"", " } }", ].joined() let nextRefill = [ "{ "type": "Known",", " "next": "2026-01-16T14:00:54.939Z",", " "tariff": {", " "amount": "1000000",", " "duration": "PT720H"", " } }", ].joined() let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "Available") #expect(snapshot.quotaInfo.used == 7478.3) #expect(snapshot.quotaInfo.maximum == 1_000_000) #expect(snapshot.quotaInfo.available == 992_521.7) #expect(snapshot.refillInfo?.type == "Known") #expect(snapshot.refillInfo?.amount == 1_000_000) } @Test func parsesQuotaXMLWithOnlyQuotaInfo() throws { let quotaInfo = "{"type":"free","current":"5000","maximum":"100000"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "free") #expect(snapshot.quotaInfo.used == 5000) #expect(snapshot.quotaInfo.maximum == 100_000) #expect(snapshot.refillInfo == nil) } @Test func parsesXMLWithReversedAttributeOrder() throws { // Test that parser handles value before name (different attribute order) let quotaInfo = "{"type":"paid","current":"1000","maximum":"50000"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "paid") #expect(snapshot.quotaInfo.used == 1000) #expect(snapshot.quotaInfo.maximum == 50000) } @Test func handlesHTMLEntities() throws { let quotaInfo = [ "{"type":"test"", ","current":"0"", ","maximum":"50000"}", ].joined() let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "test") #expect(snapshot.quotaInfo.maximum == 50000) } @Test func throwsOnMissingQuotaInfo() throws { let xml = """ """ let data = Data(xml.utf8) #expect(throws: JetBrainsStatusProbeError.noQuotaInfo) { _ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) } } @Test func throwsOnMissingComponent() throws { let xml = """ """ let data = Data(xml.utf8) #expect(throws: JetBrainsStatusProbeError.noQuotaInfo) { _ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) } } @Test func throwsOnEmptyQuotaInfo() throws { let xml = """ """ let data = Data(xml.utf8) #expect(throws: JetBrainsStatusProbeError.noQuotaInfo) { _ = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) } } @Test func parsesXMLWithSingleQuotes() throws { let quotaInfo = "{"type":"single","current":"100","maximum":"10000"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "single") #expect(snapshot.quotaInfo.maximum == 10000) } @Test func parsesXMLWithComments() throws { let quotaInfo = "{"type":"comment","current":"10","maximum":"100"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "comment") #expect(snapshot.quotaInfo.maximum == 100) } @Test func parsesXMLWithMultipleComponentsUsesCorrectOne() throws { let otherQuota = "{"type":"wrong","current":"1","maximum":"2"}" let quotaInfo = "{"type":"right","current":"42","maximum":"100"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "right") #expect(snapshot.quotaInfo.used == 42) } @Test func parsesXMLWithNextRefillBeforeQuotaInfo() throws { let quotaInfo = "{"type":"order","current":"5","maximum":"50"}" let nextRefill = "{"type":"Known","next":"2026-01-16T14:00:54.939Z","amount":"100"}" let xml = """ """ let data = Data(xml.utf8) let snapshot = try JetBrainsStatusProbe.parseXMLData(data, detectedIDE: nil) #expect(snapshot.quotaInfo.type == "order") #expect(snapshot.refillInfo?.amount == 100) } }