Skip to content

Commit

Permalink
refactor: remove duplicated post code
Browse files Browse the repository at this point in the history
Give the tado client a central post method that all setter functions
can rely on.
  • Loading branch information
gonzolino committed Nov 11, 2021
1 parent 05942f0 commit 6500ddc
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 10 deletions.
17 changes: 17 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,23 @@ func (c *Client) get(url string, v interface{}) error {
return nil
}

// post sends a post request to the tado° API.
func (c *Client) post(url string) error {
resp, err := c.Request(http.MethodPost, url, nil)
if err != nil {
return err
}

if err := isError(resp); err != nil {
return fmt.Errorf("tado° API error: %w", err)
}

if resp.StatusCode != http.StatusNoContent {
return fmt.Errorf("unexpected tado° API response status: %s", resp.Status)
}
return nil
}

// put updates an object on the tado° API.
// If the update is successful and v is a pointer, put will decode the response
// body into the value pointed to by v. If v is not a pointer the response body
Expand Down
74 changes: 74 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,80 @@ func TestGet(t *testing.T) {
}
}

func TestPost(t *testing.T) {
tests := map[string]struct {
url string
mockResp *http.Response
mockErr error
wantErr error
}{
"Simple": {
url: "http://example.org",
mockResp: makeResponse(http.StatusNoContent, ""),
mockErr: nil,
wantErr: nil,
},
"InvalidURL": {
url: "invalid://url%%",
mockResp: nil,
mockErr: nil,
wantErr: fmt.Errorf("unable to create http request: parse \"invalid://url%%%%\": invalid URL escape \"%%%%\""),
},
"HTTPClientError": {
url: "http://example.org",
mockResp: nil,
mockErr: fmt.Errorf("http client error"),
wantErr: fmt.Errorf("unable to talk to tado° API: http client error"),
},
"UnexepctedResponseCode": {
url: "http://example.org",
mockResp: makeResponse(http.StatusOK, `{"foo": "foo","bar": "bar"}`),
mockErr: nil,
wantErr: fmt.Errorf("unexpected tado° API response status: OK"),
},
"EmptyErrorList": {
url: "http://example.org",
mockResp: makeResponse(http.StatusInternalServerError, `{"errors":[]}`),
mockErr: nil,
wantErr: fmt.Errorf("tado° API error: API returned empty error"),
},
"SingleError": {
url: "http://example.org",
mockResp: makeResponse(http.StatusInternalServerError, `{"errors":[{"code":"1","title":"One"}]}`),
mockErr: nil,
wantErr: fmt.Errorf("tado° API error: 1: One"),
},
"MultiError": {
url: "http://example.org",
mockResp: makeResponse(http.StatusInternalServerError, `{"errors":[{"code":"1","title":"One"},{"code":"2","title":"Two"}]}`),
mockErr: nil,
wantErr: fmt.Errorf("tado° API error: 1: One, 2: Two"),
},
"UnparseableError": {
url: "http://example.org",
mockResp: makeResponse(http.StatusInternalServerError, `{errorjson}`),
mockErr: nil,
wantErr: fmt.Errorf("tado° API error: unable to decode API error: invalid character 'e' looking for beginning of object key string"),
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
client := NewClient("test", "test")
client.http = mockHTTPClient{Response: tc.mockResp, Error: tc.mockErr}

err := client.post(tc.url)

if tc.wantErr != nil {
assert.EqualError(t, err, tc.wantErr.Error())
} else {
assert.NoError(t, err)
}

})
}
}

func TestPut(t *testing.T) {
type foobar struct {
Foo string `json:"foo"`
Expand Down
11 changes: 1 addition & 10 deletions tado.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package gotado
import (
"errors"
"fmt"
"net/http"
"strconv"
)

Expand Down Expand Up @@ -550,15 +549,7 @@ func DeleteZoneOverlay(client *Client, userHome *UserHome, zone *Zone) error {

// SetWindowOpen marks the window in a zone as open (open window must have been detected before)
func SetWindowOpen(client *Client, userHome *UserHome, zone *Zone) error {
resp, err := client.Request(http.MethodPost, apiURL("homes/%d/zones/%d/state/openWindow/activate", userHome.ID, zone.ID), nil)
if err != nil {
return err
}

if resp.StatusCode != http.StatusNoContent {
return fmt.Errorf("unexpected tado° API response status: %s", resp.Status)
}
return nil
return client.post(apiURL("homes/%d/zones/%d/state/openWindow/activate", userHome.ID, zone.ID))
}

// SetWindowClosed marks the window in a zone as closed
Expand Down

0 comments on commit 6500ddc

Please sign in to comment.