import Foundation import Testing @testable import Voice /// Focused tests for PinnedMediaResourceLoader.parseTotalLength, covering /// 200, 206 with known total, 206 with unknown total (*), and malformed /// Content-Range headers (Finding 1 / 11). struct PinnedMediaResourceLoaderTests { private func makeResponse(status: Int, contentRange: String? = nil, expectedLength: Int64 = -1) -> HTTPURLResponse { var headers: [String: String] = [:] if let contentRange { headers["Content-Range"] = contentRange } return HTTPURLResponse( url: URL(string: "https://example.com/media/test.mp3")!, statusCode: status, httpVersion: "HTTP/1.1", headerFields: headers )! } @Test("206 with known total parses Content-Range total") func parse206KnownTotal() { let response = makeResponse(status: 206, contentRange: "bytes 0-1023/4096", expectedLength: 1024) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == 4096) } @Test("206 with unknown total (*) returns nil") func parse206UnknownTotal() { let response = makeResponse(status: 206, contentRange: "bytes 0-1023/*", expectedLength: 1024) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == nil) } @Test("200 response returns nil (expectedContentLength is already the full size)") func parse200ReturnsNil() { let response = makeResponse(status: 200, expectedLength: 8192) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == nil) } @Test("206 without Content-Range header returns nil") func parse206NoContentRange() { let response = makeResponse(status: 206, expectedLength: 512) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == nil) } @Test("malformed Content-Range returns nil") func parseMalformedContentRange() { let response = makeResponse(status: 206, contentRange: "garbage", expectedLength: 100) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == nil) } @Test("206 with large total parses correctly") func parseLargeTotal() { let response = makeResponse(status: 206, contentRange: "bytes 1048576-2097151/1073741824", expectedLength: 1048576) #expect(PinnedMediaResourceLoader.parseTotalLength(response) == 1_073_741_824) } @Test("streamURL constructs endpoint without downloading") func streamURLConstruction() { let config = ServerConfig( baseURL: URL(string: "https://192.168.86.2:9178")!, livekitURL: URL(string: "ws://192.168.86.2:7880")! ) let api = MediaAPI(config: config) let url = api.streamURL(trackID: "track-123") // streamURL builds under the /media/api base (MediaAPI.baseURL). #expect(url.absoluteString == "https://192.168.86.2:9178/media/api/stream/track-123") } // MARK: Rewrite / Resolve round-trip (Item 7) @Test("rewrite maps https URL to pinned-media scheme and resolve inverts it") func rewriteResolveRoundTrip() { let loader = PinnedMediaResourceLoader(base: URL(string: "https://192.168.86.2:9178")!) let original = URL(string: "https://192.168.86.2:9178/media/track-123.mp3")! let pinned = loader.rewrite(original) #expect(pinned.scheme == "pinned-media") #expect(pinned.absoluteString == "pinned-media://192.168.86.2:9178/media/track-123.mp3") let resolved = loader.resolve(pinned) #expect(resolved.absoluteString == original.absoluteString) } @Test("rewrite maps path-only URL using base host and port") func rewritePathOnly() { let loader = PinnedMediaResourceLoader(base: URL(string: "https://192.168.86.2:9178")!) let pathURL = URL(string: "/media/track-456.mp3")! let pinned = loader.rewrite(pathURL) #expect(pinned.scheme == "pinned-media") #expect(pinned.absoluteString == "pinned-media://192.168.86.2:9178/media/track-456.mp3") } @Test("resolve leaves non-pinned URLs unchanged") func resolveNonPinned() { let loader = PinnedMediaResourceLoader(base: URL(string: "https://192.168.86.2:9178")!) let https = URL(string: "https://example.com/foo.mp3")! #expect(loader.resolve(https) == https) } // MARK: Asset lifecycle (Item 7) @Test("assetWithPinnedURL creates asset and removeLoader clears mapping") func assetLifecycle() { let loader = PinnedMediaResourceLoader(base: URL(string: "https://192.168.86.2:9178")!) let pinned = loader.rewrite(URL(string: "https://192.168.86.2:9178/media/test.mp3")!) let asset = loader.assetWithPinnedURL(pinned) // The asset should have a valid URL matching the pinned scheme. #expect(asset.url.scheme == PinnedMediaResourceLoader.scheme) // Remove the loader mapping — subsequent calls should not crash. loader.removeLoader(asset) } @Test("removeLoader is idempotent (safe to call twice)") func removeLoaderIdempotent() { let loader = PinnedMediaResourceLoader(base: URL(string: "https://192.168.86.2:9178")!) let pinned = loader.rewrite(URL(string: "https://192.168.86.2:9178/media/test.mp3")!) let asset = loader.assetWithPinnedURL(pinned) loader.removeLoader(asset) // Second call should be a no-op, not a crash. loader.removeLoader(asset) } }