Browse Source

Fix handler unit tests

dependabot/npm_and_yarn/web/prismjs-1.21.0
Max Schmitt 8 years ago
parent
commit
597f6e86a1
  1. 14
      README.md
  2. 197
      handlers/handlers_test.go

14
README.md

@ -115,10 +115,10 @@ For that you need to send a field `ID` to the backend.
Next changes sorted by priority Next changes sorted by priority
- Fix handler unit tests - [x] Fix handler unit tests
- Switch configuration to TOML - [ ] Switch configuration to TOML
- Add Authorization (oAuth e.g. Google) - [ ] Add Authorization (oAuth e.g. Google)
- Add Deletion functionality (depends on the authorization) - [ ] Add Deletion functionality (depends on the authorization)
- Add ability to track the visitors (Referrer, maybe also live) - [ ] Add ability to track the visitors (Referrer, maybe also live)
- Test docker-compose installation - [ ] Test docker-compose installation
- Provide image on the docker hub - [ ] Provide image on the docker hub

197
handlers/handlers_test.go

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io/ioutil" "io/ioutil"
"mime/multipart"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"net/url" "net/url"
@ -12,6 +11,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/gin-gonic/gin"
"github.com/maxibanki/golang-url-shortener/store" "github.com/maxibanki/golang-url-shortener/store"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -23,18 +23,18 @@ const (
var server *httptest.Server var server *httptest.Server
func TestCreateEntryJSON(t *testing.T) { func TestCreateEntry(t *testing.T) {
tt := []struct { tt := []struct {
name string name string
ignoreResponse bool ignoreResponse bool
contentType string contentType string
response string response gin.H
requestBody URLUtil requestBody URLUtil
statusCode int statusCode int
}{ }{
{ {
name: "body is nil", name: "body is nil",
response: "could not decode JSON: EOF", response: gin.H{"error": "EOF"},
statusCode: http.StatusBadRequest, statusCode: http.StatusBadRequest,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
ignoreResponse: true, ignoreResponse: true,
@ -54,7 +54,7 @@ func TestCreateEntryJSON(t *testing.T) {
}, },
statusCode: http.StatusBadRequest, statusCode: http.StatusBadRequest,
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
response: store.ErrNoValidURL.Error(), response: gin.H{"error": store.ErrNoValidURL.Error()},
ignoreResponse: true, ignoreResponse: true,
}, },
} }
@ -76,8 +76,9 @@ func TestCreateEntryJSON(t *testing.T) {
reqBody = nil reqBody = nil
} }
respBody := createEntryWithJSON(t, reqBody, tc.contentType, tc.statusCode) respBody := createEntryWithJSON(t, reqBody, tc.contentType, tc.statusCode)
if tc.response != "" { if len(tc.response) > 0 {
if string(respBody) != string(tc.response) { raw := makeJSON(t, tc.response)
if string(respBody) != raw {
t.Fatalf("expected body: %s; got: %s", tc.response, respBody) t.Fatalf("expected body: %s; got: %s", tc.response, respBody)
} }
} }
@ -96,161 +97,6 @@ func TestCreateEntryJSON(t *testing.T) {
} }
} }
func TestCreateEntryMultipart(t *testing.T) {
cleanup, err := getBackend()
if err != nil {
t.Fatalf("could not create backend: %v", err)
}
defer cleanup()
t.Run("valid request", func(t *testing.T) {
// Prepare a form that you will submit to that URL.
var b bytes.Buffer
multipartWriter := multipart.NewWriter(&b)
formWriter, err := multipartWriter.CreateFormField("URL")
if err != nil {
t.Fatalf("could not create form field: %v", err)
}
formWriter.Write([]byte(testURL))
multipartWriter.Close()
resp, err := http.Post(server.URL+"/api/v1/create", multipartWriter.FormDataContentType(), &b)
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
var parsed URLUtil
err = json.NewDecoder(resp.Body).Decode(&parsed)
if err != nil {
t.Fatalf("could not unmarshal data: %v", err)
}
t.Run("test if shorted URL is correct", func(t *testing.T) {
testRedirect(t, parsed.URL, testURL)
})
})
t.Run("invalid url", func(t *testing.T) {
// Prepare a form that you will submit to that URL.
var b bytes.Buffer
multipartWriter := multipart.NewWriter(&b)
formWriter, err := multipartWriter.CreateFormField("URL")
if err != nil {
t.Fatalf("could not create form field: %v", err)
}
formWriter.Write([]byte("this is definitely not a valid url"))
multipartWriter.Close()
resp, err := http.Post(server.URL+"/api/v1/create", multipartWriter.FormDataContentType(), &b)
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
body = bytes.TrimSpace(body)
if err != nil {
t.Fatalf("could not read the body: %v", err)
}
if string(body) != store.ErrNoValidURL.Error() {
t.Fatalf("received unexpected response: %s", body)
}
})
t.Run("invalid request", func(t *testing.T) {
// Prepare a form that you will submit to that URL.
var b bytes.Buffer
multipartWriter := multipart.NewWriter(&b)
multipartWriter.Close()
resp, err := http.Post(server.URL+"/api/v1/create", multipartWriter.FormDataContentType(), &b)
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
body = bytes.TrimSpace(body)
if err != nil {
t.Fatalf("could not read the body")
}
if string(body) != "URL key does not exist" {
t.Fatalf("body has not the excepted payload; got: %s", body)
}
})
}
func TestCreateEntryForm(t *testing.T) {
cleanup, err := getBackend()
if err != nil {
t.Fatalf("could not create backend: %v", err)
}
defer cleanup()
t.Run("valid request", func(t *testing.T) {
data := url.Values{}
data.Set("URL", testURL)
resp, err := http.Post(server.URL+"/api/v1/create", "application/x-www-form-urlencoded", bytes.NewBufferString(data.Encode()))
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusOK {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
var parsed URLUtil
err = json.NewDecoder(resp.Body).Decode(&parsed)
if err != nil {
t.Fatalf("could not unmarshal data: %v", err)
}
t.Run("test if shorted URL is correct", func(t *testing.T) {
testRedirect(t, parsed.URL, testURL)
})
})
t.Run("invalid request", func(t *testing.T) {
resp, err := http.Post(server.URL+"/api/v1/create", "application/x-www-form-urlencoded", bytes.NewBufferString(url.Values{}.Encode()))
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
body = bytes.TrimSpace(body)
if err != nil {
t.Fatalf("could not read the body: %v", err)
}
if string(body) != "URL key does not exist" {
t.Fatalf("received unexpected response: %s", body)
}
})
t.Run("invalid url", func(t *testing.T) {
data := url.Values{}
data.Set("URL", "this is definitely not a valid url")
resp, err := http.Post(server.URL+"/api/v1/create", "application/x-www-form-urlencoded", bytes.NewBufferString(data.Encode()))
if err != nil {
t.Fatalf("could not post to the backend: %v", err)
}
if resp.StatusCode != http.StatusBadRequest {
t.Errorf("expected status %d; got %d", http.StatusOK, resp.StatusCode)
}
body, err := ioutil.ReadAll(resp.Body)
body = bytes.TrimSpace(body)
if err != nil {
t.Fatalf("could not read the body: %v", err)
}
if string(body) != store.ErrNoValidURL.Error() {
t.Fatalf("received unexpected response: %s", body)
}
})
}
func TestHandleInfo(t *testing.T) { func TestHandleInfo(t *testing.T) {
cleanup, err := getBackend() cleanup, err := getBackend()
if err != nil { if err != nil {
@ -265,7 +111,7 @@ func TestHandleInfo(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("could not marshal json: %v", err) t.Fatalf("could not marshal json: %v", err)
} }
respBody := createEntryWithJSON(t, reqBody, "application/json", http.StatusOK) respBody := createEntryWithJSON(t, reqBody, "application/json; charset=utf-8", http.StatusOK)
var parsed URLUtil var parsed URLUtil
err = json.Unmarshal(respBody, &parsed) err = json.Unmarshal(respBody, &parsed)
if err != nil { if err != nil {
@ -279,7 +125,7 @@ func TestHandleInfo(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("could not marshal the body: %v", err) t.Fatalf("could not marshal the body: %v", err)
} }
resp, err := http.Post(server.URL+"/api/v1/info", "appplication/json", bytes.NewBuffer(body)) resp, err := http.Post(server.URL+"/api/v1/info", "application/json; charset=utf-8", bytes.NewBuffer(body))
if err != nil { if err != nil {
t.Fatalf("could not post to the backend: %v", err) t.Fatalf("could not post to the backend: %v", err)
} }
@ -304,11 +150,14 @@ func TestHandleInfo(t *testing.T) {
t.Errorf("expected status %d; got %d", http.StatusBadRequest, resp.StatusCode) t.Errorf("expected status %d; got %d", http.StatusBadRequest, resp.StatusCode)
} }
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
body = bytes.TrimSpace(body)
if err != nil { if err != nil {
t.Fatalf("could not read the body: %v", err) t.Fatalf("could not read the body: %v", err)
} }
if string(body) != "could not decode JSON: EOF" { body = bytes.TrimSpace(body)
raw := makeJSON(t, gin.H{
"error": "Key: '.ID' Error:Field validation for 'ID' failed on the 'required' tag",
})
if string(body) != raw {
t.Fatalf("body is not the expected one: %s", body) t.Fatalf("body is not the expected one: %s", body)
} }
}) })
@ -328,12 +177,23 @@ func TestHandleInfo(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("could not read the body: %v", err) t.Fatalf("could not read the body: %v", err)
} }
if string(body) != "no ID provided" { raw := makeJSON(t, gin.H{
"error": "Key: '.ID' Error:Field validation for 'ID' failed on the 'required' tag",
})
if string(body) != raw {
t.Fatalf("body is not the expected one: %s", body) t.Fatalf("body is not the expected one: %s", body)
} }
}) })
} }
func makeJSON(t *testing.T, data interface{}) string {
raw, err := json.Marshal(data)
if err != nil {
t.Fatalf("could not marshal json: %v", err)
}
return string(raw)
}
func createEntryWithJSON(t *testing.T, reqBody []byte, contentType string, statusCode int) []byte { func createEntryWithJSON(t *testing.T, reqBody []byte, contentType string, statusCode int) []byte {
resp, err := http.Post(server.URL+"/api/v1/create", "application/json", bytes.NewBuffer(reqBody)) resp, err := http.Post(server.URL+"/api/v1/create", "application/json", bytes.NewBuffer(reqBody))
if err != nil { if err != nil {
@ -377,6 +237,7 @@ func testRedirect(t *testing.T, shortURL, longURL string) {
} }
func getBackend() (func(), error) { func getBackend() (func(), error) {
gin.SetMode(gin.ReleaseMode)
store, err := store.New(testingDBName, 4) store, err := store.New(testingDBName, 4)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not create store") return nil, errors.Wrap(err, "could not create store")
@ -389,7 +250,7 @@ func getBackend() (func(), error) {
server = httptest.NewServer(handler.engine) server = httptest.NewServer(handler.engine)
return func() { return func() {
server.Close() server.Close()
handler.Stop() handler.CloseStore()
os.Remove(testingDBName) os.Remove(testingDBName)
}, nil }, nil
} }

Loading…
Cancel
Save