10 "github.com/stretchr/testify/require"
15 func TestConnectionBaselineAndInputEvents(t *testing.T) {
16 synctest.Test(t, func(t *testing.T) {
17 c, client, transport := testConnection(t)
18 require.Empty(t, transport.ofKind(protocol.Event))
20 client.inputs[0], client.inputs[15] = true, true
21 client.inputDelay = time.Millisecond
22 observedAt := time.Now().Add(time.Millisecond).UTC()
24 require.NoError(t, c.poll(t.Context()))
26 events := transport.ofKind(protocol.Event)
27 require.Len(t, events, 2)
29 for _, event := range events {
30 require.Equal(t, &observedAt, event.Metadata.SentAt)
31 require.JSONEq(t, `{"action":"pressed","value":true}`, eventJSON(t, event.Payload))
34 require.NoError(t, c.poll(t.Context()))
35 require.Len(t, transport.ofKind(protocol.Event), 2)
37 client.inputs[0] = false
39 require.NoError(t, c.poll(t.Context()))
41 events = transport.ofKind(protocol.Event)
42 require.Len(t, events, 3)
43 require.JSONEq(t, `{"action":"released","value":false}`, eventJSON(t, events[2].Payload))
45 client.coils[2] = true
46 transport.messages = nil
48 require.NoError(t, c.poll(t.Context()))
49 require.Empty(t, transport.messages)
53 func TestConnectionRejectsConfigurationAndReadFailuresBeforeOnline(t *testing.T) {
54 testCases := []struct {
56 change func(*fakeClient)
58 {name: "rejects pulse register write failure", change: func(c *fakeClient) {
59 c.registerErr = errors.New("configuration failed")
61 {name: "rejects configuration read failure", change: func(c *fakeClient) {
62 c.registerReadErr = errors.New("configuration read failed")
64 {name: "rejects pulse width mismatch", change: func(c *fakeClient) {
65 c.wrongRegister = pulseWidthBase + 2
67 {name: "rejects configuration mismatch", change: func(c *fakeClient) {
70 {name: "rejects input read failure", change: func(c *fakeClient) {
71 c.inputErr = errors.New("input read failed")
73 {name: "rejects coil read failure", change: func(c *fakeClient) {
74 c.readErr = errors.New("coil read failed")
76 {name: "rejects incomplete read", change: func(c *fakeClient) {
79 {name: "rejects unsafe voltage", change: func(c *fakeClient) {
84 for _, tc := range testCases {
85 t.Run(tc.name, func(t *testing.T) {
86 d, client, transport, _ := testAssembly(t)
89 c := &connection{owner: d}
90 err := c.start(t.Context())
92 var failure *deviceError
94 require.ErrorAs(t, err, &failure)
95 require.Empty(t, transport.messages)
100 func TestConnectionReturnsPublicationFailures(t *testing.T) {
101 testCases := []struct {
104 change func(*fakeClient)
106 {name: "returns input report failure", kind: protocol.Reported, change: func(c *fakeClient) {
109 {name: "returns transition failure", kind: protocol.Event, change: func(c *fakeClient) {
112 {name: "returns output report failure", kind: protocol.Reported, change: func(c *fakeClient) {
115 {name: "returns voltage report failure", kind: protocol.Reported, change: func(c *fakeClient) {
120 for _, tc := range testCases {
121 t.Run(tc.name, func(t *testing.T) {
122 c, client, transport := testConnection(t)
123 failure := errors.New("publish failed")
124 transport.failKind, transport.err = tc.kind, failure
126 require.ErrorIs(t, c.poll(t.Context()), failure)
131 func eventJSON(t *testing.T, value any) string {
134 data, err := json.Marshal(value)
135 require.NoError(t, err)