]> git.giacomolli.uk - onehouse/blob - protocol/address_test.go
Define wire addresses and envelopes
[onehouse] / protocol / address_test.go
1 package protocol
2
3 import (
4 "strings"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8 )
9
10 const (
11 deviceID = "01ARZ3NDEKTSV4RRFFQ69G5FAV"
12 messageID = "01ARZ3NDEKTSV4RRFFQ69G5FAW"
13 commandID = "01ARZ3NDEKTSV4RRFFQ69G5FAX"
14 )
15
16 func TestAddressRoundTrip(t *testing.T) {
17 testCases := []struct {
18 name string
19 kind Kind
20 target string
21 suffix string
22 }{
23 {name: "routes metadata", kind: Descriptor, suffix: "descriptor"},
24 {name: "routes reachability", kind: Availability, suffix: "availability"},
25 {name: "routes retained values", kind: Reported, target: "relay.1", suffix: "reported/relay.1"},
26 {name: "routes samples", kind: Telemetry, target: "power", suffix: "telemetry/power"},
27 {name: "routes occurrences", kind: Event, target: "press", suffix: "events/press"},
28 {name: "routes requests", kind: Command, target: "relay", suffix: "commands/relay"},
29 {name: "routes ordered requests", kind: CommandBatch, suffix: "commands/$batch"},
30 {name: "routes outcomes", kind: Result, target: commandID, suffix: "results/" + commandID},
31 {name: "routes hub diagnostics", kind: HubStatus, suffix: "status"},
32 }
33
34 for _, tc := range testCases {
35 t.Run(tc.name, func(t *testing.T) {
36 address := Address{Kind: tc.kind, ID: deviceID, Target: tc.target}
37 topic, err := address.Topic()
38 require.NoError(t, err)
39
40 expected := Root + "/devices/" + deviceID + "/" + tc.suffix
41 if tc.kind == HubStatus {
42 expected = Root + "/zigbee/hubs/" + deviceID + "/status"
43 }
44
45 require.Equal(t, expected, topic)
46
47 parsed, err := ParseTopic(topic)
48 require.NoError(t, err)
49 require.Equal(t, address, parsed)
50 })
51 }
52 }
53
54 func TestParseTopicRejectsMalformedAddresses(t *testing.T) {
55 testCases := []string{
56 "", "onehouse/v2/devices/" + deviceID + "/descriptor",
57 Root + "/devices/" + strings.ToLower(deviceID) + "/descriptor",
58 Root + "/devices/" + deviceID + "/descriptor/extra",
59 Root + "/devices/" + deviceID + "/reported",
60 Root + "/devices/" + deviceID + "/reported/",
61 Root + "/devices/" + deviceID + "/reported/+",
62 Root + "/devices/" + deviceID + "/events/door--open",
63 Root + "/devices/" + deviceID + "/commands/$other",
64 Root + "/devices/" + deviceID + "/results/not-an-id",
65 Root + "/devices/" + deviceID + "/status",
66 Root + "/zigbee/hubs/" + deviceID + "/status/extra",
67 Root + "/devices/" + deviceID + "/unknown",
68 }
69
70 for _, tc := range testCases {
71 _, err := ParseTopic(tc)
72 require.Error(t, err, tc)
73 }
74 }
75
76 func TestSubscriptionsSelectOnlyTheirDirection(t *testing.T) {
77 filters := CoreSubscriptions()
78 require.Len(t, filters, 6)
79 require.Equal(t, Subscription{Filter: Root + "/devices/+/telemetry/+", QoS: 0}, filters[3])
80
81 for index, filter := range filters {
82 require.NotContains(t, filter.Filter, "commands")
83
84 if index != 3 {
85 require.Equal(t, byte(1), filter.QoS)
86 }
87 }
88
89 subscription, err := CommandSubscription(deviceID)
90 require.NoError(t, err)
91 require.Equal(t, Root+"/devices/"+deviceID+"/commands/+", subscription.Filter)
92 require.Equal(t, byte(1), subscription.QoS)
93
94 _, err = CommandSubscription("+")
95 require.Error(t, err)
96 require.Equal(t, Root+"/zigbee/hubs/+/status", HubStatusSubscription().Filter)
97 }