import Foundation import Testing @testable import ForgejoKit struct URLSessionManagerTests { // MARK: - trustedHost scoping @Test func selfSignedWithoutTrustedHostAcceptsAny() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: nil) #expect(manager.allowSelfSignedCertificates == true) } @Test func selfSignedWithTrustedHostIsSet() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com") #expect(manager.allowSelfSignedCertificates == true) } @Test func selfSignedDisabledByDefault() { let manager = URLSessionManager() #expect(manager.allowSelfSignedCertificates == false) } @Test func sessionIsCreatedWithConfiguration() { let manager = URLSessionManager(allowSelfSignedCertificates: false) let session = manager.session #expect(session.configuration.timeoutIntervalForRequest == 30) #expect(session.configuration.timeoutIntervalForResource == 300) } // MARK: - Trust disposition logic @Test func selfSignedDisabledReturnsDefaultHandling() { let manager = URLSessionManager(allowSelfSignedCertificates: false) let disposition = manager.trustDisposition(for: "forgejo.example.com") #expect(disposition == .performDefaultHandling) } @Test func selfSignedEnabledWithNilTrustedHostReturnsDefaultHandling() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: nil) let disposition = manager.trustDisposition(for: "forgejo.example.com") #expect(disposition == .performDefaultHandling) } @Test func selfSignedEnabledWithMatchingHostReturnsUseCredential() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com") let disposition = manager.trustDisposition(for: "forgejo.example.com") #expect(disposition == .useCredential) } @Test func selfSignedEnabledWithMismatchedHostReturnsDefaultHandling() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com") let disposition = manager.trustDisposition(for: "evil.example.com") #expect(disposition == .performDefaultHandling) } @Test func selfSignedTrustMatchesCaseInsensitive() { let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "Forgejo.Example.COM") let disposition = manager.trustDisposition(for: "forgejo.example.com") #expect(disposition == .useCredential) } } struct ForgejoClientHostMatchTests { // MARK: - Auth header host matching @Test func authenticatedRequestIncludesAuthForMatchingHost() { let client = ForgejoClient( serverURL: "https://forgejo.example.com", username: "user", password: "pass" ) let url = URL(string: "https://forgejo.example.com/api/v1/user")! let request = client.authenticatedRequest(url: url) #expect(request.value(forHTTPHeaderField: "Authorization") != nil) } @Test func authenticatedRequestOmitsAuthForDifferentHost() { let client = ForgejoClient( serverURL: "https://forgejo.example.com", username: "user", password: "pass" ) let url = URL(string: "https://evil.example.com/api/v1/user")! let request = client.authenticatedRequest(url: url) #expect(request.value(forHTTPHeaderField: "Authorization") == nil) } @Test func authenticatedRequestMatchesCaseInsensitiveHost() { let client = ForgejoClient( serverURL: "https://Forgejo.Example.COM", username: "user", password: "pass" ) let url = URL(string: "https://forgejo.example.com/api/v1/repos")! let request = client.authenticatedRequest(url: url) #expect(request.value(forHTTPHeaderField: "Authorization") != nil) } @Test func authenticatedRequestSetsMethodAndBody() { let client = ForgejoClient( serverURL: "https://forgejo.example.com", username: "user", password: "pass" ) let url = URL(string: "https://forgejo.example.com/api/v1/repos")! let body = Data("{\"name\":\"test\"}".utf8) let request = client.authenticatedRequest(url: url, method: "POST", body: body) #expect(request.httpMethod == "POST") #expect(request.httpBody == body) #expect(request.value(forHTTPHeaderField: "Content-Type") == "application/json") } @Test func makeURLConstructsValidURL() throws { let client = ForgejoClient( serverURL: "https://forgejo.example.com", username: "user", password: "pass" ) let url = try client.makeURL(path: "/api/v1/user") #expect(url.absoluteString == "https://forgejo.example.com/api/v1/user") } @Test func makeURLWithQueryItems() throws { let client = ForgejoClient( serverURL: "https://forgejo.example.com", username: "user", password: "pass" ) let url = try client.makeURL(path: "/api/v1/repos/search", queryItems: [ URLQueryItem(name: "q", value: "test"), URLQueryItem(name: "page", value: "2") ]) #expect(url.absoluteString.contains("q=test")) #expect(url.absoluteString.contains("page=2")) } @Test func clientExtractsHostForTrustedCert() { // Verify that the client passes the right host to URLSessionManager let client = ForgejoClient( serverURL: "https://my-forgejo.local:3000", username: "user", password: "pass", allowSelfSignedCertificates: true ) // The session should be created with self-signed support #expect(client.serverURL == "https://my-forgejo.local:3000") } }