import Foundation import Testing import RemoteCore import WatchBridgeCommon @Test func payloadUsesUnixMillisecondsInBothDirections() throws { let issued = Date(timeIntervalSince1970: 1_700_000_000.125) let envelope = CommandEnvelope( sessionID: UUID(), televisionID: UUID(), sequence: 1, issuedAt: issued, expiresAt: issued.addingTimeInterval(0.5), command: .right ) let container = try RelayContainer(kind: .command, value: envelope) let data = container.payload #expect(container.schemaVersion == RelayWire.schemaVersion) #expect(container.kind == .command) let object = try #require(JSONSerialization.jsonObject(with: data) as? [String: Any]) #expect((object["issuedAt"] as? Double) == 1_700_000_000_125) #expect((object["expiresAt"] as? Double) == 1_700_000_000_625) #expect(try RelayJSON.decode(CommandEnvelope.self, from: data) == envelope) } @Test func outgoingContainerRejectsOversizedPayload() { #expect(throws: RelayContractError.payloadTooLarge) { try RelayContainer(kind: .error, value: String(repeating: "x", count: RelayWire.maximumPayloadBytes)) } } @Test func incomingContainerRequiresExactTypedShape() throws { let payload = try RelayJSON.encode(BeginRemoteSessionRequest()) let valid: [String: Any] = [ "schemaVersion": 1, "kind": "beginSession", "payload": payload ] #expect(try RelayContainer(dictionary: valid).kind == .beginSession) #expect(throws: RelayContainerError.extraKeys) { var extra = valid extra["token"] = "never accepted" _ = try RelayContainer(dictionary: extra) } #expect(throws: RelayContainerError.invalidSchemaType) { var booleanVersion = valid booleanVersion["schemaVersion"] = true _ = try RelayContainer(dictionary: booleanVersion) } #expect(throws: RelayContainerError.invalidSchemaType) { var floatingVersion = valid floatingVersion["schemaVersion"] = 1.0 _ = try RelayContainer(dictionary: floatingVersion) } #expect(throws: RelayContainerError.invalidPayload) { var wrongPayload = valid wrongPayload["payload"] = "not bytes" _ = try RelayContainer(dictionary: wrongPayload) } } @Test func applicationContextContainsOnlyLatestStateAllowlist() throws { let tv = UUID() let context = try RelayApplicationContext(selectedTelevisionID: tv, displayName: "Living room").dictionary() #expect(context["selectedTelevisionID"] as? String == tv.uuidString) #expect(context["displayName"] as? String == "Living room") #expect(!context.keys.contains("token")) #expect(!context.keys.contains("command")) #expect(try RelayApplicationContext(dictionary: context).selectedTelevisionID == tv) var executable = context executable["command"] = "queued" #expect(throws: RelayContainerError.extraKeys) { _ = try RelayApplicationContext(dictionary: executable) } }