package protocol import ( "strings" "testing" "github.com/stretchr/testify/require" ) const ( deviceID = "01ARZ3NDEKTSV4RRFFQ69G5FAV" messageID = "01ARZ3NDEKTSV4RRFFQ69G5FAW" commandID = "01ARZ3NDEKTSV4RRFFQ69G5FAX" ) func TestAddressRoundTrip(t *testing.T) { testCases := []struct { name string kind Kind target string suffix string }{ { name: "routes metadata", kind: Descriptor, suffix: "descriptor", }, { name: "routes reachability", kind: Availability, suffix: "availability", }, { name: "routes retained values", kind: Reported, target: "relay.1", suffix: "reported/relay.1", }, { name: "routes samples", kind: Telemetry, target: "power", suffix: "telemetry/power", }, { name: "routes occurrences", kind: Event, target: "press", suffix: "events/press", }, { name: "routes requests", kind: Command, target: "relay", suffix: "commands/relay", }, { name: "routes ordered requests", kind: CommandBatch, suffix: "commands/$batch", }, { name: "routes outcomes", kind: Result, target: commandID, suffix: "results/" + commandID, }, { name: "routes hub diagnostics", kind: HubStatus, suffix: "status", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { address := Address{ Kind: tc.kind, ID: deviceID, Target: tc.target, } topic, err := address.Topic() require.NoError(t, err) expected := Root + "/devices/" + deviceID + "/" + tc.suffix if tc.kind == HubStatus { expected = Root + "/zigbee/hubs/" + deviceID + "/status" } require.Equal(t, expected, topic) parsed, err := ParseTopic(topic) require.NoError(t, err) require.Equal(t, address, parsed) }) } } func TestParseTopicRejectsMalformedAddresses(t *testing.T) { testCases := []string{ "", "onehouse/v2/devices/" + deviceID + "/descriptor", Root + "/devices/" + strings.ToLower(deviceID) + "/descriptor", Root + "/devices/" + deviceID + "/descriptor/extra", Root + "/devices/" + deviceID + "/reported", Root + "/devices/" + deviceID + "/reported/", Root + "/devices/" + deviceID + "/reported/+", Root + "/devices/" + deviceID + "/events/door--open", Root + "/devices/" + deviceID + "/commands/$other", Root + "/devices/" + deviceID + "/results/not-an-id", Root + "/devices/" + deviceID + "/status", Root + "/zigbee/hubs/" + deviceID + "/status/extra", Root + "/devices/" + deviceID + "/unknown", } for _, tc := range testCases { _, err := ParseTopic(tc) require.Error(t, err, tc) } } func TestSubscriptionsSelectOnlyTheirDirection(t *testing.T) { filters := CoreSubscriptions() require.Len(t, filters, 6) require.Equal(t, Subscription{ Filter: Root + "/devices/+/telemetry/+", QoS: 0, }, filters[3]) for index, filter := range filters { require.NotContains(t, filter.Filter, "commands") if index != 3 { require.Equal(t, byte(1), filter.QoS) } } subscription, err := CommandSubscription(deviceID) require.NoError(t, err) require.Equal(t, Root+"/devices/"+deviceID+"/commands/+", subscription.Filter) require.Equal(t, byte(1), subscription.QoS) _, err = CommandSubscription("+") require.Error(t, err) require.Equal(t, Root+"/zigbee/hubs/+/status", HubStatusSubscription().Filter) }