Skip to content
This repository was archived by the owner on Mar 22, 2025. It is now read-only.

Commit 99dc342

Browse files
committed
Tested pretty much all the code possible in things.go, moving on to ZigBeeValve.go
1 parent 39a4dc4 commit 99dc342

File tree

2 files changed

+141
-59
lines changed

2 files changed

+141
-59
lines changed

ZigBeeValve/thing.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ func findGateway() (err error) {
204204
// ours is index 0 since there's no other RaspBee/ZigBee gateways on the network
205205
res, err := http.Get(discoveryURL)
206206
if err != nil {
207-
//log.Println("Couldn't get gateway, error:", err)
208207
return
209208
}
210209
defer res.Body.Close()
@@ -214,13 +213,11 @@ func findGateway() (err error) {
214213
}
215214
body, err := io.ReadAll(res.Body) // Read the payload into body variable
216215
if err != nil {
217-
//log.Println("Something went wrong while reading the body during discovery, error:", err)
218216
return
219217
}
220218
var gw []discoverJSON // Create a list to hold the gateway json
221219
err = json.Unmarshal(body, &gw) // "unpack" body from []byte to []discoverJSON, save errors
222220
if err != nil {
223-
//log.Println("Error during Unmarshal, error:", err)
224221
return
225222
}
226223

@@ -260,8 +257,11 @@ func (ua *UnitAsset) sendSetPoint() (err error) {
260257

261258
// Create http friendly payload
262259
s := fmt.Sprintf(`{"heatsetpoint":%f}`, ua.Setpt*100) // Create payload
263-
data := []byte(s) // Turned into byte array
264-
return sendRequest(data, apiURL)
260+
req, err := createRequest(s, apiURL)
261+
if err != nil {
262+
return
263+
}
264+
return sendRequest(req)
265265
}
266266

267267
func (ua *UnitAsset) toggleState(state bool) (err error) {
@@ -270,37 +270,37 @@ func (ua *UnitAsset) toggleState(state bool) (err error) {
270270

271271
// Create http friendly payload
272272
s := fmt.Sprintf(`{"on":%t}`, state) // Create payload
273-
data := []byte(s) // Turned into byte array
274-
err = sendRequest(data, apiURL)
275-
return err
273+
req, err := createRequest(s, apiURL)
274+
if err != nil {
275+
return
276+
}
277+
return sendRequest(req)
276278
}
277279

278-
func sendRequest(data []byte, apiURL string) (err error) {
279-
body := bytes.NewBuffer(data) // Put data into buffer
280-
281-
req, err := http.NewRequest(http.MethodPut, apiURL, body) // Put request is made
280+
func createRequest(data string, apiURL string) (req *http.Request, err error) {
281+
body := bytes.NewReader([]byte(data)) // Put data into buffer
282+
req, err = http.NewRequest(http.MethodPut, apiURL, body) // Put request is made
282283
if err != nil {
283-
// log.Println("Error making new HTTP PUT request, error:", err)
284-
return err
284+
return nil, err
285285
}
286286

287287
req.Header.Set("Content-Type", "application/json") // Make sure it's JSON
288+
return req, err
289+
}
288290

289-
client := &http.Client{} // Make a client
290-
resp, err := client.Do(req) // Perform the put request
291+
func sendRequest(req *http.Request) (err error) {
292+
resp, err := http.DefaultClient.Do(req)
291293
if err != nil {
292-
// log.Println("Error sending HTTP PUT request, error:", err)
293294
return err
294295
}
296+
295297
defer resp.Body.Close()
296298
_, err = io.ReadAll(resp.Body) // Read the payload into body variable
297299
if err != nil {
298-
// log.Println("Something went wrong while reading payload into body variable, error:", err)
299-
return err
300+
return
300301
}
301302
if resp.StatusCode > 299 {
302-
// log.Printf("Response failed with status code: %d and\nbody: %s\n", resp.StatusCode, string(b))
303-
return err
303+
return errStatusCode
304304
}
305305
return
306306
}

ZigBeeValve/zigbee_test.go

Lines changed: 120 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,24 @@ import (
1919
// http.DefaultClient) and it will intercept network requests.
2020

2121
type mockTransport struct {
22-
resp *http.Response
23-
hits map[string]int
24-
err error
22+
returnError bool
23+
resp *http.Response
24+
hits map[string]int
25+
err error
2526
}
2627

27-
func newMockTransport(resp *http.Response, err error) mockTransport {
28+
func newMockTransport(resp *http.Response, retErr bool, err error) mockTransport {
2829
t := mockTransport{
29-
resp: resp,
30-
hits: make(map[string]int),
31-
err: err,
30+
returnError: retErr,
31+
resp: resp,
32+
hits: make(map[string]int),
33+
err: err,
3234
}
3335
// Highjack the default http client so no actuall http requests are sent over the network
3436
http.DefaultClient.Transport = t
3537
return t
3638
}
3739

38-
// domainHits returns the number of requests to a domain (or -1 if domain wasn't found).
39-
40-
func (t mockTransport) domainHits(domain string) int {
41-
for u, hits := range t.hits {
42-
if u == domain {
43-
return hits
44-
}
45-
}
46-
return -1
47-
}
48-
4940
// TODO: this might need to be expanded to a full JSON array?
5041

5142
const discoverExample string = `[{
@@ -61,12 +52,19 @@ const discoverExample string = `[{
6152
// It prevents the request from being sent over the network and count how many times
6253
// a domain was requested.
6354

55+
var errHTTP error = fmt.Errorf("bad http request")
56+
6457
func (t mockTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
65-
t.resp.Request = req
6658
t.hits[req.URL.Hostname()] += 1
6759
if t.err != nil {
6860
return nil, t.err
6961
}
62+
if t.returnError != false {
63+
req.GetBody = func() (io.ReadCloser, error) {
64+
return nil, errHTTP
65+
}
66+
}
67+
t.resp.Request = req
7068
return t.resp, nil
7169
}
7270

@@ -165,9 +163,6 @@ func TestNewResource(t *testing.T) {
165163
}
166164
}
167165

168-
const thermostatDomain string = "http://localhost:8870/api/B3AFB6415A/sensors/2/config"
169-
const plugDomain string = "http://localhost:8870/api/B3AFB6415A/lights/1/config"
170-
171166
type errReader int
172167

173168
var errBodyRead error = fmt.Errorf("bad body read")
@@ -180,18 +175,33 @@ func (errReader) Close() error {
180175
return nil
181176
}
182177

183-
func TestFindGateway(t *testing.T) {
184-
// New mocktransport
185-
//gatewayDomain := "https://phoscon.de/discover"
178+
func TestProcessFeedbackLoop(t *testing.T) {
179+
// TODO: Test as much of the code as possible.
180+
// Maybe try to pass arguments to processFeedbackLoop, to skip the GetState() function?
181+
/*
182+
fakeBody := // Find out what a form looks like, and pass it to this test function
183+
184+
resp := &http.Response{
185+
Status: "200 OK",
186+
StatusCode: 200,
187+
Body: io.NopCloser(strings.NewReader(fakeBody)),
188+
}
189+
newMockTransport(resp, false, nil)
190+
191+
ua := initTemplate().(*UnitAsset)
192+
ua.processFeedbackLoop()
193+
*/
194+
}
186195

196+
func TestFindGateway(t *testing.T) {
187197
fakeBody := fmt.Sprint(discoverExample)
188198

189199
resp := &http.Response{
190200
Status: "200 OK",
191201
StatusCode: 200,
192202
Body: io.NopCloser(strings.NewReader(fakeBody)),
193203
}
194-
newMockTransport(resp, nil)
204+
newMockTransport(resp, false, nil)
195205

196206
// ---- All ok! ----
197207
err := findGateway()
@@ -203,19 +213,18 @@ func TestFindGateway(t *testing.T) {
203213
t.Fatalf("Expected gateway to be localhost:8080, was %s", gateway)
204214
}
205215

206-
// Have to make changes to mockTransport to test this?
207216
// ---- Error cases ----
208217

209218
// Unmarshall error
210-
newMockTransport(resp, fmt.Errorf("Test error"))
219+
newMockTransport(resp, false, fmt.Errorf("Test error"))
211220
err = findGateway()
212221
if err == nil {
213222
t.Error("Error expcted, got nil instead", err)
214223
}
215224

216225
// Statuscode > 299, have to make changes to mockTransport to test this
217226
resp.StatusCode = 300
218-
newMockTransport(resp, nil)
227+
newMockTransport(resp, false, nil)
219228
err = findGateway()
220229
if err != errStatusCode {
221230
t.Error("Expected errStatusCode, got", err)
@@ -224,43 +233,47 @@ func TestFindGateway(t *testing.T) {
224233
// Broken body - https://stackoverflow.com/questions/45126312/how-do-i-test-an-error-on-reading-from-a-request-body
225234
resp.StatusCode = 200
226235
resp.Body = errReader(0)
227-
newMockTransport(resp, nil)
236+
newMockTransport(resp, false, nil)
228237
err = findGateway()
229238
if err != errBodyRead {
230239
t.Error("Expected error")
231240
}
232241

233242
// Actual http body is unmarshaled correctly
234243
resp.Body = io.NopCloser(strings.NewReader(fakeBody + "123"))
235-
newMockTransport(resp, nil)
244+
newMockTransport(resp, false, nil)
236245
err = findGateway()
237246
if err == nil {
238247
t.Error("Expected error")
239248
}
240249

241250
// Empty list of gateways
242251
resp.Body = io.NopCloser(strings.NewReader("[]"))
243-
newMockTransport(resp, nil)
252+
newMockTransport(resp, false, nil)
244253
err = findGateway()
245254
if err != errMissingGateway {
246255
t.Error("Expected error", err)
247256
}
248257
}
249258

250259
func TestToggleState(t *testing.T) {
251-
fakeBody := fmt.Sprint("")
260+
fakeBody := fmt.Sprint(`{"on":true, "Version": "SignalA_v1a"}`)
252261

253262
resp := &http.Response{
254263
Status: "200 OK",
255264
StatusCode: 200,
256265
Body: io.NopCloser(strings.NewReader(fakeBody)),
257266
}
258267

259-
newMockTransport(resp, nil)
260-
268+
newMockTransport(resp, false, nil)
261269
ua := initTemplate().(*UnitAsset)
262-
270+
// All ok!
263271
ua.toggleState(true)
272+
// Error
273+
// change gateway to bad character/url, return gateway to original value
274+
gateway = brokenURL
275+
ua.toggleState(true)
276+
findGateway()
264277
}
265278

266279
func TestSendSetPoint(t *testing.T) {
@@ -272,10 +285,79 @@ func TestSendSetPoint(t *testing.T) {
272285
Body: io.NopCloser(strings.NewReader(fakeBody)),
273286
}
274287

275-
newMockTransport(resp, nil)
276-
288+
newMockTransport(resp, false, nil)
277289
ua := initTemplate().(*UnitAsset)
290+
// All ok!
291+
gateway = ""
292+
err := ua.sendSetPoint()
293+
if err != nil {
294+
t.Error("Unexpected error:", err)
295+
}
278296

297+
// Error
298+
gateway = brokenURL
279299
ua.sendSetPoint()
300+
findGateway()
301+
302+
}
303+
304+
// func createRequest(data string, apiURL string) (req *http.Request, err error)
305+
func TestCreateRequest(t *testing.T) {
306+
data := "test"
307+
apiURL := "http://localhost:8080/test"
308+
309+
_, err := createRequest(data, apiURL)
310+
if err != nil {
311+
t.Error("Error occured, expected none")
312+
}
313+
314+
_, err = createRequest(data, brokenURL)
315+
if err == nil {
316+
t.Error("Expected error")
317+
}
318+
319+
}
320+
321+
var brokenURL string = string([]byte{0x7f})
322+
323+
func TestSendRequest(t *testing.T) {
324+
// Set up standard response & catch http requests
325+
fakeBody := fmt.Sprint(`Test`)
326+
327+
resp := &http.Response{
328+
Status: "200 OK",
329+
StatusCode: 200,
330+
Body: io.NopCloser(strings.NewReader(fakeBody)),
331+
}
332+
333+
// All ok!
334+
newMockTransport(resp, false, nil)
335+
apiURL := "http://localhost:8080/test"
336+
s := fmt.Sprintf(`{"heatsetpoint":%f}`, 25.0) // Create payload
337+
req, _ := createRequest(s, apiURL)
338+
err := sendRequest(req)
339+
if err != nil {
340+
t.Error("Expected no errors, error occured:", err)
341+
}
342+
343+
// Error unpacking body
344+
resp.Body = errReader(0)
345+
newMockTransport(resp, false, nil)
346+
347+
err = sendRequest(req)
348+
349+
if err == nil {
350+
t.Error("Expected errors, no error occured:")
351+
}
352+
353+
// Error StatusCode
354+
resp.Body = io.NopCloser(strings.NewReader(fakeBody))
355+
resp.StatusCode = 300
356+
newMockTransport(resp, false, nil)
357+
err = sendRequest(req)
358+
359+
if err != errStatusCode {
360+
t.Error("Expected errStatusCode, got", err)
361+
}
280362

281363
}

0 commit comments

Comments
 (0)