import Foundation @main struct StreamResolverTests { static func main() async { testClassifierPrefersObservedDirectFile() testResolverSelectsUnsupportedDirectURLAndHeaders() testResolverRejectsHLSOnlyResponse() testRedactorHandlesPercentEncodedPath() testPlaybackTimeFormatting() testSubtitleCandidateParsing() testOpenSubtitlesV3CandidateParsing() testOpenSubtitlesNestedAttributesFilesParsing() testOpenSubtitlesManifestIDsAreNotResolvedAsSubtitles() testOpenSubtitlesArtworkAndAddonEndpointsAreIgnored() testStremioSubtitleDownloadURLParsing() testOpenSubtitlesV3DownloadResponseResolution() testOpenSubtitlesNestedDownloadResponseResolution() await testSubtitleResolverDownloadJSONReturningLink() await testSubtitleResolverRedirectToDirectSubtitle() await testSubtitleResolverRejectsNonSubtitleAPIResponse() testSubtitleCandidateDeduplicationPreservesLabels() testSubtitleCandidateDeduplicationUpgradesLabels() testSubtitleDisplayNameNormalization() testSubtitleDisplayNameUsesPreservedNamesForGenericVLCTracks() testSubtitleOptionMappingIncludesNone() testHTTPRangeParsing() testContentRangeFormatting() testCacheLookupAcrossChunkBoundaries() testCacheEvictionOutsideByteBudget() testProxyForwardsUpstreamHeaders() testProxyPassThroughFallbackStatus() print("StreamResolverTests passed") } private static func testClassifierPrefersObservedDirectFile() { let body: [String: Any] = [ "url": "https://cdn.example.test/movie.mkv?token=secret", "resolverUrl": "https://addon.debridio.com/play/example" ] let candidate = StreamCandidate(messageBody: body)! let request = StreamClassifier.playbackRequest(from: candidate, userAgent: "DreamioTest/1")! assertEqual(request.playbackURL.absoluteString, "https://cdn.example.test/movie.mkv?token=secret") assertEqual(request.headers["Referer"], "https://web.stremio.com/") assertEqual(request.headers["User-Agent"], "DreamioTest/1") } private static func testHTTPRangeParsing() { assertEqual(HTTPRange.parse("bytes=10-20"), HTTPRange(start: 10, end: 20)) assertEqual(HTTPRange.parse("bytes=10-"), HTTPRange(start: 10, end: nil)) assert(HTTPRange.parse("items=10-20") == nil, "Expected non-byte range to be rejected") assert(HTTPRange.parse("bytes=-20") == nil, "Expected suffix ranges to be rejected for v1") assert(HTTPRange.parse("bytes=20-10") == nil, "Expected inverted ranges to be rejected") assert(HTTPRange.parse("bytes=1-2,3-4") == nil, "Expected multipart ranges to be rejected") } private static func testContentRangeFormatting() { assertEqual(HTTPRange.contentRange(start: 10, end: 20, totalLength: 100), "bytes 10-20/100") assertEqual(HTTPRange.contentRange(start: 10, end: 20, totalLength: nil), "bytes 10-20/*") } private static func testCacheLookupAcrossChunkBoundaries() { let store = CachedRangeStore(sessionID: "test-\(UUID().uuidString)", byteBudget: 1024) defer { store.removeAll() } store.store(data: Data("abc".utf8), start: 0) store.store(data: Data("def".utf8), start: 3) let lookup = store.lookup(range: HTTPRange(start: 0, end: 5), maximumLength: 6) assertEqual(String(data: lookup?.data ?? Data(), encoding: .utf8), "abcdef") assertEqual(lookup?.isComplete, true) } private static func testCacheEvictionOutsideByteBudget() { let store = CachedRangeStore(sessionID: "test-\(UUID().uuidString)", byteBudget: 6) defer { store.removeAll() } store.store(data: Data("abcdef".utf8), start: 0) store.store(data: Data("ghijkl".utf8), start: 6) let oldLookup = store.lookup(range: HTTPRange(start: 0, end: 5), maximumLength: 6) let newLookup = store.lookup(range: HTTPRange(start: 6, end: 11), maximumLength: 6) assert(oldLookup == nil, "Expected old chunk to be evicted outside the byte budget") assertEqual(String(data: newLookup?.data ?? Data(), encoding: .utf8), "ghijkl") } private static func testProxyForwardsUpstreamHeaders() { let proxy = NativeStreamCacheProxy(session: NativeStreamCacheProxy.Session(request: proxyTestRequest())) let upstreamRequest = proxy.upstreamRequest(for: HTTPRange(start: 12, end: 34)) assertEqual(upstreamRequest.value(forHTTPHeaderField: "Range"), "bytes=12-34") assertEqual(upstreamRequest.value(forHTTPHeaderField: "Referer"), "https://resolver.example.test/") assertEqual(upstreamRequest.value(forHTTPHeaderField: "User-Agent"), "DreamioTest/1") assertEqual(upstreamRequest.value(forHTTPHeaderField: "Authorization"), "Bearer secret") } private static func testProxyPassThroughFallbackStatus() { assertEqual(NativeStreamCacheProxy.responseStatusForUpstreamStatus(206), 206) assertEqual(NativeStreamCacheProxy.responseStatusForUpstreamStatus(200), 200) } private static func proxyTestRequest() -> NativePlaybackRequest { NativePlaybackRequest( playbackURL: URL(string: "https://cdn.example.test/movie.mkv")!, observedURL: URL(string: "https://cdn.example.test/movie.mkv")!, resolverURL: URL(string: "https://resolver.example.test/play")!, pageURL: nil, userAgent: "DreamioTest/1", referer: "https://resolver.example.test/", headers: [ "Referer": "https://resolver.example.test/", "User-Agent": "DreamioTest/1", "Authorization": "Bearer secret" ], classification: StreamClassification( sourceKind: .directFile, containerGuess: .mkv, reason: "test", shouldIntercept: true, sanitizedObservedURL: "https://cdn.example.test/movie.mkv", sanitizedResolverURL: nil ), subtitleCandidates: [] ) } private static func testResolverSelectsUnsupportedDirectURLAndHeaders() { let payload: [String: Any] = [ "streams": [ [ "url": "https://cdn.example.test/trailer.mp4" ], [ "externalUrl": "https://cdn.example.test/movie.mkv?signature=secret", "behaviorHints": [ "proxyHeaders": [ "request": [ "Referer": "https://resolver.example.test/", "User-Agent": "ResolverAgent/1" ] ] ] ] ] ] let stream = StremioStreamResolver.bestPlayableStream( in: payload, fallbackHeaders: ["Referer": "https://web.stremio.com/"] )! assertEqual(stream.playbackURL.absoluteString, "https://cdn.example.test/movie.mkv?signature=secret") assertEqual(stream.headers["Referer"], "https://resolver.example.test/") assertEqual(stream.headers["User-Agent"], "ResolverAgent/1") } private static func testResolverRejectsHLSOnlyResponse() { let payload: [String: Any] = [ "streams": [ ["url": "https://cdn.example.test/live.m3u8"] ] ] let stream = StremioStreamResolver.bestPlayableStream( in: payload, fallbackHeaders: ["Referer": "https://web.stremio.com/"] ) assert(stream == nil, "Expected HLS-only resolver response to stay out of native playback") } private static func testRedactorHandlesPercentEncodedPath() { let original = "https://cdn.example.test/video/abcdefghijklmnopqrstuvwxyz012345/%E2%9C%93.mp4?token=secret#fragment" let redacted = URLRedactor.redactedURLString(original) assertEqual(redacted, "https://cdn.example.test/video/%5Bredacted%5D/%E2%9C%93.mp4") } private static func testPlaybackTimeFormatting() { assertEqual(PlaybackTimeFormatter.label(for: 0), "0:00") assertEqual(PlaybackTimeFormatter.label(for: 65), "1:05") assertEqual(PlaybackTimeFormatter.label(for: 3_725), "1:02:05") } private static func testSubtitleCandidateParsing() { let payload: [String: Any] = [ "subtitles": [ [ "lang": "eng", "url": "https://opensubtitles.example.test/download/subtitle.srt?token=secret" ], [ "language": "Spanish", "file": "https://cdn.example.test/movie.es.vtt" ], "https://cdn.example.test/ignored.txt" ], "nested": [ "body": "metadata https://cdn.example.test/movie.fr.ass?download=1" ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 3) assertEqual(candidates[0].language, "eng") assertEqual(candidates[1].label, "Spanish") assertEqual(candidates[2].url.absoluteString, "https://cdn.example.test/movie.fr.ass?download=1") } private static func testOpenSubtitlesV3CandidateParsing() { let payload: [String: Any] = [ "subtitles": [ [ "language": "English", "download": "https://api.opensubtitles.com/api/v1/download/subtitle-file", "nested": [ [ "file": "https://dl.opensubtitles.org/en/subtitle.vtt?download=1" ] ] ], [ "lang": "spa", "url": "https://opensubtitles.example.test/download/episode.srt" ] ], "body": "alternate https://cdn.example.test/from-string.ass?source=opensubtitles", "ignored": [ "https://cdn.example.test/poster.jpg", ["file": "https://cdn.example.test/video.mkv"] ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 4) assertEqual(candidates[0].label, "English") assertEqual(candidates[0].language, "English") assertEqual(candidates[1].url.absoluteString, "https://dl.opensubtitles.org/en/subtitle.vtt?download=1") assertEqual(candidates[1].label, "English") assertEqual(candidates[1].language, "English") assertEqual(candidates[2].label, "spa") assertEqual(candidates[2].language, "spa") assertEqual(candidates[3].url.absoluteString, "https://cdn.example.test/from-string.ass?source=opensubtitles") } private static func testOpenSubtitlesNestedAttributesFilesParsing() { let payload: [String: Any] = [ "data": [ [ "attributes": [ "language": "English", "file_name": "episode.en.srt", "files": [ [ "file_id": 12345, "file_name": "nested.en.srt" ], [ "link": "https://dl.opensubtitles.org/en/download/nested.vtt?token=secret", "language": "eng" ] ] ] ] ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 2) assertEqual(candidates[0].url.absoluteString, "https://api.opensubtitles.com/api/v1/download/12345") assertEqual(candidates[0].label, "nested.en.srt") assertEqual(candidates[0].language, "English") assertEqual(candidates[1].url.absoluteString, "https://dl.opensubtitles.org/en/download/nested.vtt?token=secret") assertEqual(candidates[1].label, "eng") assertEqual(candidates[1].language, "eng") } private static func testOpenSubtitlesManifestIDsAreNotResolvedAsSubtitles() { let payload: [String: Any] = [ "subtitles": [ [ "url": "https://opensubtitles-v3.strem.io/manifest.json_14", "file_id": 98765, "lang": "eng" ], [ "url": "https://opensubtitles-v3.strem.io/manifest.json_15", "lang": "spa" ], "https://opensubtitles-v3.strem.io/manifest.json_16" ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 1) assertEqual(candidates[0].url.absoluteString, "https://api.opensubtitles.com/api/v1/download/98765") assertEqual(candidates[0].language, "eng") } private static func testOpenSubtitlesArtworkAndAddonEndpointsAreIgnored() { let payload: [String: Any] = [ "subtitles": [ [ "label": "External Subtitle", "url": "http://www.strem.io/images/addons/opensubtitles-logo.png" ], [ "label": "External Subtitle", "url": "https://opensubtitles.strem.io/stremio/v1" ], [ "label": "English", "url": "https://opensubtitles.example.test/subtitles/movie.en.srt" ] ], "body": "metadata https://www.strem.io/images/addons/opensubtitles-logo.png" ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 1) assertEqual(candidates[0].url.absoluteString, "https://opensubtitles.example.test/subtitles/movie.en.srt") assertEqual(candidates[0].label, "English") } private static func testStremioSubtitleDownloadURLParsing() { let payload: [String: Any] = [ "subtitles": [ [ "label": "English", "lang": "eng", "url": "https://subs5.strem.io/en/download/subencoding-stremio-utf8/src-api/file/1952341941" ], [ "label": "Not a subtitle", "url": "https://www.strem.io/images/addons/opensubtitles-logo.png" ] ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 1) assertEqual(candidates[0].url.absoluteString, "https://subs5.strem.io/en/download/subencoding-stremio-utf8/src-api/file/1952341941") assertEqual(candidates[0].label, "English") assertEqual(candidates[0].language, "eng") assert(SubtitleResolver.isDirectSubtitleFile(candidates[0].url), "Expected Stremio subtitle downloads to be attachable without another resolver hop") } private static func testOpenSubtitlesV3DownloadResponseResolution() { let payload = """ { "link": "https://dl.opensubtitles.org/en/download/subtitle.srt?token=secret", "file_name": "episode.srt", "requests": 1 } """.data(using: .utf8)! let original = SubtitleCandidate( url: URL(string: "https://api.opensubtitles.com/api/v1/download")!, label: "English", language: "eng" ) let candidate = SubtitleResolver.bestPlayableCandidate( from: payload, responseURL: original.url, original: original ) assertEqual(candidate?.url.absoluteString, "https://dl.opensubtitles.org/en/download/subtitle.srt?token=secret") assertEqual(candidate?.label, "English") assertEqual(candidate?.language, "eng") } private static func testOpenSubtitlesNestedDownloadResponseResolution() { let payload = """ { "data": { "attributes": { "files": [ { "file_name": "ignored.txt", "link": "https://cdn.example.test/ignored.txt" }, { "file_name": "episode.en.ass", "download": { "link": "https://dl.opensubtitles.org/en/download/episode.en.ass?token=secret" } } ] } } } """.data(using: .utf8)! let original = SubtitleCandidate( url: URL(string: "https://api.opensubtitles.com/api/v1/download/987")!, label: "English SDH", language: "eng" ) let candidate = SubtitleResolver.bestPlayableCandidate( from: payload, responseURL: original.url, original: original ) assertEqual(candidate?.url.absoluteString, "https://dl.opensubtitles.org/en/download/episode.en.ass?token=secret") assertEqual(candidate?.label, "English SDH") assertEqual(candidate?.language, "eng") } private static func testSubtitleResolverDownloadJSONReturningLink() async { MockURLProtocol.handlers = [ "https://api.opensubtitles.com/api/v1/download/123": ( 200, URL(string: "https://api.opensubtitles.com/api/v1/download/123")!, #"{"link":"https://dl.opensubtitles.org/en/download/movie.srt?token=secret"}"#.data(using: .utf8)! ) ] let resolver = SubtitleResolver(session: mockSession()) let candidate = await resolver.resolve(SubtitleCandidate( url: URL(string: "https://api.opensubtitles.com/api/v1/download/123")!, label: "English", language: "eng" )) assertEqual(candidate?.url.absoluteString, "https://dl.opensubtitles.org/en/download/movie.srt?token=secret") assertEqual(candidate?.label, "English") assertEqual(candidate?.language, "eng") } private static func testSubtitleResolverRedirectToDirectSubtitle() async { MockURLProtocol.handlers = [ "https://api.opensubtitles.com/api/v1/download/redirect": ( 200, URL(string: "https://dl.opensubtitles.org/en/redirected.vtt?download=1")!, Data() ) ] let resolver = SubtitleResolver(session: mockSession()) let candidate = await resolver.resolve(SubtitleCandidate( url: URL(string: "https://api.opensubtitles.com/api/v1/download/redirect")!, label: "English", language: "eng" )) assertEqual(candidate?.url.absoluteString, "https://dl.opensubtitles.org/en/redirected.vtt?download=1") } private static func testSubtitleResolverRejectsNonSubtitleAPIResponse() async { MockURLProtocol.handlers = [ "https://api.opensubtitles.com/api/v1/download/not-found": ( 200, URL(string: "https://api.opensubtitles.com/api/v1/download/not-found")!, #"{"message":"not found"}"#.data(using: .utf8)! ) ] let resolver = SubtitleResolver(session: mockSession()) let candidate = await resolver.resolve(SubtitleCandidate( url: URL(string: "https://api.opensubtitles.com/api/v1/download/not-found")!, label: "English", language: "eng" )) assert(candidate == nil, "Expected non-subtitle API response to be rejected") } private static func testSubtitleCandidateDeduplicationPreservesLabels() { let payload: [String: Any] = [ "subtitles": [ [ "label": "English SDH", "lang": "eng", "url": "https://opensubtitles.example.test/download/duplicate.srt" ], [ "label": "Duplicate", "language": "English", "download": "https://opensubtitles.example.test/download/duplicate.srt" ], "https://opensubtitles.example.test/download/duplicate.srt" ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 1) assertEqual(candidates[0].label, "English SDH") assertEqual(candidates[0].language, "eng") } private static func testSubtitleCandidateDeduplicationUpgradesLabels() { let payload: [String: Any] = [ "subtitles": [ "https://opensubtitles.example.test/download/duplicate.srt", [ "label": "English SDH", "lang": "eng", "url": "https://opensubtitles.example.test/download/duplicate.srt" ] ] ] let candidates = SubtitleCandidateParser.candidates(in: payload) assertEqual(candidates.count, 1) assertEqual(candidates[0].label, "English SDH") assertEqual(candidates[0].language, "eng") } private static func testSubtitleOptionMappingIncludesNone() { let options = SubtitleOptionMapper.options(from: [ SubtitleTrack(id: 2, name: "English"), SubtitleTrack(id: 5, name: "Spanish") ]) assertEqual(options.map(\.name), ["None", "English", "Spanish"]) assertEqual(options.first?.id, -1) } private static func testSubtitleDisplayNameNormalization() { assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://opensubtitles.example.test/download/subtitle.srt")!, label: "Track 1", language: "eng" )), "English" ) assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://opensubtitles.example.test/download/subtitle.srt")!, label: "Track 2", language: "Spanish" )), "Spanish" ) assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://opensubtitles.example.test/download/subtitle.srt")!, label: "English SDH", language: "eng" )), "English SDH" ) assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://cdn.example.test/subtitles/movie.es.srt")!, label: "External Subtitle", language: nil )), "movie.es" ) assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://opensubtitles.example.test/download/subtitle.srt")!, label: "Track 3", language: "nld" )), "Dutch" ) assertEqual( SubtitleDisplayName.displayName(for: SubtitleCandidate( url: URL(string: "https://opensubtitles.example.test/download/subtitle.srt")!, label: "Track 4", language: "dan" )), "Danish" ) } private static func testSubtitleDisplayNameUsesPreservedNamesForGenericVLCTracks() { let options = SubtitleOptionMapper.options(from: [ SubtitleTrack( id: 3, name: SubtitleDisplayName.name(forVLCTrackName: "Track 1", preservedName: "English") ), SubtitleTrack( id: 4, name: SubtitleDisplayName.name(forVLCTrackName: "Commentary", preservedName: "Spanish") ) ]) assertEqual(options.map(\.name), ["None", "English", "Commentary"]) } private static func assertEqual(_ actual: T?, _ expected: T, file: StaticString = #file, line: UInt = #line) { assert(actual == expected, "Expected \(String(describing: expected)), got \(String(describing: actual))", file: file, line: line) } private static func mockSession() -> URLSession { let configuration = URLSessionConfiguration.ephemeral configuration.protocolClasses = [MockURLProtocol.self] return URLSession(configuration: configuration) } } private final class MockURLProtocol: URLProtocol { static var handlers: [String: (status: Int, url: URL, data: Data)] = [:] override class func canInit(with request: URLRequest) -> Bool { true } override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } override func startLoading() { guard let url = request.url, let handler = Self.handlers[url.absoluteString], let response = HTTPURLResponse( url: handler.url, statusCode: handler.status, httpVersion: "HTTP/1.1", headerFields: nil ) else { client?.urlProtocol(self, didFailWithError: URLError(.badURL)) return } client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) client?.urlProtocol(self, didLoad: handler.data) client?.urlProtocolDidFinishLoading(self) } override func stopLoading() {} }