ios: add share extension to queue and play video links

Embed an iOS and Catalyst share extension using existing discovery and player APIs. Share saved players through an App Group snapshot, preserve the queue, and verify advancing playback before reporting success.

Cover URL provider transport, settings migration, discovery addresses, duplicate handling, cancellation, and partial enqueue/play outcomes with focused tests. Document authentication and signing limits.
This commit is contained in:
2026-10-20 22:08:12 -07:00
parent ec99065cdf
commit 8723955705
26 changed files with 2104 additions and 241 deletions
@@ -0,0 +1,47 @@
import Foundation
import XCTest
@testable import QueueCubeShareCore
final class ServerTests: XCTestCase {
func testScopedIPv4FromNetworkFrameworkUsesResolvableHost() throws {
let server = try XCTUnwrap(Server(serviceName: nil, host: "192.168.1.153%en1", port: 18731))
XCTAssertEqual(server.baseURL.absoluteString, "http://192.168.1.153:18731/api")
XCTAssertEqual(server.baseURL.host, "192.168.1.153")
}
func testUnscopedIPv4AndHostnameKeepHostAndPort() throws {
for host in ["192.168.1.153", "queuecube.local"] {
let server = try XCTUnwrap(Server(serviceName: nil, host: host, port: 3000))
XCTAssertEqual(server.baseURL.absoluteString, "http://\(host):3000/api")
XCTAssertEqual(server.baseURL.host, host)
}
}
func testIPv6LiteralsAreBracketedAndPreserveEncodedScope() throws {
let cases = [
("2001:db8::1", "http://[2001:db8::1]:3000/api"),
("fe80::1%en1", "http://[fe80::1%25en1]:3000/api"),
("[2001:db8::1]", "http://[2001:db8::1]:3000/api"),
("[fe80::1%en1]", "http://[fe80::1%25en1]:3000/api")
]
for (host, expected) in cases {
let server = try XCTUnwrap(Server(serviceName: nil, host: host, port: 3000))
XCTAssertEqual(server.baseURL.absoluteString, expected)
}
}
func testHostnameUsesURLHostEncoding() throws {
let server = try XCTUnwrap(Server(serviceName: nil, host: "café.local", port: 3000))
XCTAssertEqual(server.baseURL.absoluteString, "http://xn--caf-dma.local:3000/api")
XCTAssertNil(Server(serviceName: nil, host: "queuecube.local/path", port: 3000))
}
func testPlayerDisplayNameUsesBonjourNameAndFallsBackToHost() throws {
let advertised = try XCTUnwrap(Server(serviceName: "QueueCube Media Server (Living Room)", host: "192.168.1.153%en1", port: 3000))
XCTAssertEqual(advertised.displayName, "Living Room")
let custom = try XCTUnwrap(Server(serviceName: "Kitchen", host: "queuecube.local", port: 3000))
XCTAssertEqual(custom.displayName, "Kitchen")
let unnamed = try XCTUnwrap(Server(serviceName: nil, host: "queuecube.local", port: 3000))
XCTAssertEqual(unnamed.displayName, "queuecube.local")
}
}