From 940eb77c69c0cbc5c623ebf9288ef3da93328458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Fri, 14 Apr 2017 23:01:32 -0700 Subject: [PATCH] Add ReadJSON that will replace GetJSONFromURL --- transport/transport.go | 39 ++++++++++++++++ transport/transport_test.go | 88 +++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 transport/transport.go create mode 100644 transport/transport_test.go diff --git a/transport/transport.go b/transport/transport.go new file mode 100644 index 000000000..1a0a4025f --- /dev/null +++ b/transport/transport.go @@ -0,0 +1,39 @@ +package transport + +import ( + "encoding/json" + "fmt" + "net/url" + "time" +) + +func readFile(filename string, target interface{}) error { + reader, err := newFileReader(filename) + if err != nil { + return err + } + return json.NewDecoder(reader).Decode(target) +} + +func readHTTP(url string, timeout time.Duration, target interface{}) error { + reader, err := newHTTPReader(url, timeout) + if err != nil { + return err + } + return json.NewDecoder(*reader).Decode(target) +} + +// ReadJSON using one of supported transports (file:// http://) +func ReadJSON(uri string, timeout time.Duration, target interface{}) error { + u, err := url.Parse(uri) + if err != nil { + return err + } + if u.Scheme == "file" { + return readFile(u.Path, target) + } + if u.Scheme == "http" || u.Scheme == "https" { + return readHTTP(u.String(), timeout, target) + } + return fmt.Errorf("Unsupported URI scheme '%s' in '%s'", u.Scheme, u) +} diff --git a/transport/transport_test.go b/transport/transport_test.go new file mode 100644 index 000000000..479e9ea27 --- /dev/null +++ b/transport/transport_test.go @@ -0,0 +1,88 @@ +package transport_test + +import ( + "fmt" + "testing" + "time" + + "github.com/cloudflare/unsee/mock" + "github.com/cloudflare/unsee/transport" + + log "github.com/Sirupsen/logrus" + httpmock "gopkg.in/jarcoal/httpmock.v1" +) + +type transportTest struct { + uri string + timeout time.Duration + failed bool +} + +var transportTests = []transportTest{ + transportTest{ + uri: "http://localhost/status", + }, + transportTest{ + uri: "http://localhost/404", + failed: true, + }, + transportTest{ + uri: "http://localhost/invalid", + failed: true, + }, + transportTest{ + uri: "https://localhost/status", + }, + transportTest{ + uri: "https://localhost/404", + failed: true, + }, + transportTest{ + uri: "https://localhost/invalid", + failed: true, + }, + transportTest{ + uri: fmt.Sprintf("file://%s", mock.GetAbsoluteMockPath("status", "0.4")), + }, + transportTest{ + uri: "file:///non-existing-file.abcdef", + failed: true, + }, + transportTest{ + uri: "file://transport.go", + failed: true, + }, +} + +type mockStatus struct { + status string + integer int + yes bool + no bool +} + +func TestFileReader(t *testing.T) { + log.SetLevel(log.ErrorLevel) + httpmock.Activate() + defer httpmock.DeactivateAndReset() + mockJSON := `{ + "response": "success", + "integer": 123, + "yes": true, + "no": false + }` + httpmock.RegisterResponder("GET", "http://localhost/status", httpmock.NewStringResponder(200, mockJSON)) + httpmock.RegisterResponder("GET", "http://localhost/404", httpmock.NewStringResponder(404, "404")) + httpmock.RegisterResponder("GET", "http://localhost/invalid", httpmock.NewStringResponder(200, "bad json}{}")) + httpmock.RegisterResponder("GET", "https://localhost/status", httpmock.NewStringResponder(200, mockJSON)) + httpmock.RegisterResponder("GET", "https://localhost/404", httpmock.NewStringResponder(404, "404")) + httpmock.RegisterResponder("GET", "https://localhost/invalid", httpmock.NewStringResponder(200, "bad json}{}")) + + for _, testCase := range transportTests { + r := mockStatus{} + err := transport.ReadJSON(testCase.uri, testCase.timeout, &r) + if (err != nil) != testCase.failed { + t.Errorf("[%s] Expected failure: %v, Read() failed: %v, error: %s", testCase.uri, testCase.failed, (err != nil), err) + } + } +}