ForgejoKit/Tests/ForgejoKitTests/URLSessionManagerTests.swift
Stefan Hausotte b78c57ffd9 feat: add Attachment model and image upload support
- Add Attachment model with isImage computed property
- Add assets field to Issue, IssueComment, and PullRequest
- Add multipart/form-data upload support to ForgejoClient
- Add uploadIssueAttachment and uploadCommentAttachment to IssueService
2026-06-15 09:48:47 +02:00

148 lines
6.1 KiB
Swift

@testable import ForgejoKit
import Foundation
import Testing
struct URLSessionManagerTests {
// MARK: - trustedHost scoping
@Test func `self signed without trusted host accepts any`() {
let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: nil)
#expect(manager.allowSelfSignedCertificates == true)
}
@Test func `self signed with trusted host is set`() {
let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com")
#expect(manager.allowSelfSignedCertificates == true)
}
@Test func `self signed disabled by default`() {
let manager = URLSessionManager()
#expect(manager.allowSelfSignedCertificates == false)
}
@Test func `session is created with configuration`() {
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 `self signed disabled returns default handling`() {
let manager = URLSessionManager(allowSelfSignedCertificates: false)
let disposition = manager.trustDisposition(for: "forgejo.example.com")
#expect(disposition == .performDefaultHandling)
}
@Test func `self signed enabled with nil trusted host returns default handling`() {
let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: nil)
let disposition = manager.trustDisposition(for: "forgejo.example.com")
#expect(disposition == .performDefaultHandling)
}
@Test func `self signed enabled with matching host returns use credential`() {
let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com")
let disposition = manager.trustDisposition(for: "forgejo.example.com")
#expect(disposition == .useCredential)
}
@Test func `self signed enabled with mismatched host returns default handling`() {
let manager = URLSessionManager(allowSelfSignedCertificates: true, trustedHost: "forgejo.example.com")
let disposition = manager.trustDisposition(for: "evil.example.com")
#expect(disposition == .performDefaultHandling)
}
@Test func `self signed trust matches case insensitive`() {
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 `authenticated request includes auth for matching host`() throws {
let client = ForgejoClient(
serverURL: "https://forgejo.example.com",
username: "user",
password: "pass",
)
let url = try #require(URL(string: "https://forgejo.example.com/api/v1/user"))
let request = client.authenticatedRequest(url: url)
#expect(request.value(forHTTPHeaderField: "Authorization") != nil)
}
@Test func `authenticated request omits auth for different host`() throws {
let client = ForgejoClient(
serverURL: "https://forgejo.example.com",
username: "user",
password: "pass",
)
let url = try #require(URL(string: "https://evil.example.com/api/v1/user"))
let request = client.authenticatedRequest(url: url)
#expect(request.value(forHTTPHeaderField: "Authorization") == nil)
}
@Test func `authenticated request matches case insensitive host`() throws {
let client = ForgejoClient(
serverURL: "https://Forgejo.Example.COM",
username: "user",
password: "pass",
)
let url = try #require(URL(string: "https://forgejo.example.com/api/v1/repos"))
let request = client.authenticatedRequest(url: url)
#expect(request.value(forHTTPHeaderField: "Authorization") != nil)
}
@Test func `authenticated request sets method and body`() throws {
let client = ForgejoClient(
serverURL: "https://forgejo.example.com",
username: "user",
password: "pass",
)
let url = try #require(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 `make URL constructs valid URL`() 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 `make URL with query items`() 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 `client extracts host for trusted cert`() {
// 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")
}
}