Files
MatchLiveTv/native/ios/MatchLiveTvTests/ApiInstantTests.swift
Emiliano Frascaro 80813b390b Fix connessione RTMP in dev: riscrivi host Docker mediamtx per iOS.
Il simulatore non risolve «mediamtx»; l'app riscrive l'ingest verso 127.0.0.1 e docker-compose espone MEDIAMTX_RTMP_URL client-safe con messaggi d'errore RTMP più chiari.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 07:30:06 +02:00

88 lines
3.3 KiB
Swift

import XCTest
/// Smoke test eseguibile senza @testable import (validazione logica pura).
final class ApiInstantTests: XCTestCase {
func testOverlayKindMapping() {
XCTAssertEqual(OverlayKindMapping.fromApi("basket"), "basket")
XCTAssertEqual(OverlayKindMapping.fromApi("none"), "none")
XCTAssertEqual(OverlayKindMapping.fromApi(nil), "volley")
}
func testRTMPUrlParser() {
let target = RTMPUrlParserLogic.parse("rtmp://stream.example.com/live/match_abc-123")
XCTAssertEqual(target?.connectURL, "rtmp://stream.example.com/live")
XCTAssertEqual(target?.streamName, "match_abc-123")
}
func testRtmpIngestUrlRewritesDockerHostForLocalApi() {
let resolved = RtmpIngestUrlLogic.resolve(
"rtmp://mediamtx:1935/live/match_abc",
apiBaseUrl: "http://localhost:3000"
)
XCTAssertEqual(resolved, "rtmp://127.0.0.1:1935/live/match_abc")
}
func testRtmpIngestUrlKeepsProductionHost() {
let url = "rtmp://www.matchlivetv.it:1935/live/match_abc"
let resolved = RtmpIngestUrlLogic.resolve(url, apiBaseUrl: "https://www.matchlivetv.it")
XCTAssertEqual(resolved, url)
}
}
enum OverlayKindMapping {
static func fromApi(_ value: String?) -> String {
switch value?.lowercased() {
case "none", "timer": return "none"
case "basket": return "basket"
case "timed": return "timed"
case "racket": return "racket"
default: return "volley"
}
}
}
enum RTMPUrlParserLogic {
struct Target {
let connectURL: String
let streamName: String
}
static func parse(_ urlString: String) -> Target? {
guard let url = URL(string: urlString), url.scheme?.hasPrefix("rtmp") == true else { return nil }
let pathParts = url.path.split(separator: "/").map(String.init)
guard pathParts.count >= 2 else { return nil }
let app = pathParts.dropLast().joined(separator: "/")
let streamName = pathParts.last ?? ""
var connect = "rtmp://\(url.host ?? "")"
if let port = url.port { connect += ":\(port)" }
connect += "/\(app)"
return Target(connectURL: connect, streamName: streamName)
}
}
/// Copia della logica `RtmpIngestUrl` per test senza bundle Info.plist.
enum RtmpIngestUrlLogic {
private static let dockerInternalHosts: Set<String> = ["mediamtx", "host.docker.internal"]
static func resolve(_ urlString: String, apiBaseUrl: String) -> String {
guard var components = URLComponents(string: urlString),
let host = components.host?.lowercased() else {
return urlString
}
let apiHost = URL(string: apiBaseUrl)?.host?.lowercased()
let isLocalApi = apiHost.map { $0 == "localhost" || $0 == "127.0.0.1" || $0.hasSuffix(".local") } ?? false
guard dockerInternalHosts.contains(host) || isLocalApi else {
return urlString
}
let ingestHost: String
if let apiHost, apiHost != "localhost", apiHost != "127.0.0.1" {
ingestHost = apiHost
} else {
ingestHost = "127.0.0.1"
}
components.host = ingestHost
if components.port == nil { components.port = 1935 }
return components.url?.absoluteString ?? urlString
}
}