| 1 | import XCTest |
| 2 | |
| 3 | @testable import CallsKit |
| 4 | |
| 5 | /// Spec §15.20's two optional members on the roster, as the native core |
| 6 | /// forwards them: absent is none, and a report without them decodes |
| 7 | /// exactly as §15.19's did. |
| 8 | final class PeerMediaHearingTests: XCTestCase { |
| 9 | private func media(_ json: String) throws -> PeerMedia? { |
| 10 | let state = try JSONDecoder().decode( |
| 11 | RoomState.self, |
| 12 | from: Data( |
| 13 | #"{"phase":"admitted","peer":"me","boot":"b","waiting":[],"peers":[{"peer":"tony","name":"Tony","kind":"member","gen":1,"media":\#(json)}]}"# |
| 14 | .utf8)) |
| 15 | return Call.peerMedia("tony", in: state) |
| 16 | } |
| 17 | |
| 18 | func testTheTwoKeyReportStillDecodes() throws { |
| 19 | let m = try XCTUnwrap(media(#"{"muted":false,"cameraOff":true}"#)) |
| 20 | XCTAssertEqual(m, PeerMedia(muted: false, cameraOff: true)) |
| 21 | XCTAssertNil(m.audioBlocked) |
| 22 | XCTAssertNil(m.noSoundFrom) |
| 23 | } |
| 24 | |
| 25 | func testTheReceivingHalfDecodes() throws { |
| 26 | let m = try XCTUnwrap( |
| 27 | media(#"{"muted":false,"cameraOff":false,"audioBlocked":true,"noSoundFrom":["me","bea"]}"#)) |
| 28 | XCTAssertEqual(m.audioBlocked, true) |
| 29 | XCTAssertEqual(m.noSoundFrom, ["me", "bea"]) |
| 30 | XCTAssertEqual( |
| 31 | m, PeerMedia(muted: false, cameraOff: false, audioBlocked: true, noSoundFrom: ["me", "bea"])) |
| 32 | } |
| 33 | |
| 34 | func testEitherMemberAlone() throws { |
| 35 | XCTAssertEqual(try media(#"{"muted":true,"cameraOff":false,"audioBlocked":true}"#)?.noSoundFrom, nil) |
| 36 | XCTAssertEqual(try media(#"{"muted":true,"cameraOff":false,"noSoundFrom":["me"]}"#)?.audioBlocked, nil) |
| 37 | } |
| 38 | |
| 39 | func testAMalformedMemberIsRefusedNotGuessed() { |
| 40 | XCTAssertThrowsError(try media(#"{"muted":false,"cameraOff":false,"noSoundFrom":"me"}"#)) |
| 41 | XCTAssertThrowsError(try media(#"{"muted":false,"cameraOff":false,"audioBlocked":"yes"}"#)) |
| 42 | } |
| 43 | } |
| 44 | |