import XCTest @testable import MusicBridge final class TLSTests: XCTestCase { private func connection(_ name: String, wrongPin: Bool = false) throws -> Connection { let url = try XCTUnwrap(Bundle(for: Self.self).url(forResource: "tls-fixture", withExtension: "json")) let fixtures = try JSONDecoder().decode([String: [String: String]].self, from: Data(contentsOf: url)) guard let fixture = fixtures[name] else { throw XCTSkip("Start tools/tls_fixture.py before building TLS tests.") } return try Connection(endpoint: XCTUnwrap(fixture["endpoint"]), fingerprint: wrongPin ? String(repeating: "0", count: 64) : XCTUnwrap(fixture["fingerprint"])) } func testPinnedSelfSignedHTTPSAndWSS() async throws { let client = BridgeClient(try connection("valid")) defer { client.close() } let state = try await client.state() XCTAssertEqual(state.protocolVersion, 1) client.openEvents() let event = try await client.nextState() XCTAssertEqual(event.title, state.title) } func testWrongFingerprintIsRejected() async throws { let client = BridgeClient(try connection("valid", wrongPin: true)) defer { client.close() } do { _ = try await client.state(); XCTFail("Accepted the wrong fingerprint") } catch { XCTAssertTrue(error is URLError) } } func testExpiredPinnedCertificateIsRejected() async throws { let client = BridgeClient(try connection("expired")) defer { client.close() } do { _ = try await client.state(); XCTFail("Accepted an expired certificate") } catch { XCTAssertTrue(error is URLError) } } }