|
@@ -3,7 +3,7 @@ package api
|
|
import (
|
|
import (
|
|
"bytes"
|
|
"bytes"
|
|
"encoding/json"
|
|
"encoding/json"
|
|
- "fmt"
|
|
|
|
|
|
+ "io/ioutil"
|
|
"net/http"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"testing"
|
|
@@ -11,7 +11,20 @@ import (
|
|
"code.osinet.fr/fgm/kurz/domain"
|
|
"code.osinet.fr/fgm/kurz/domain"
|
|
)
|
|
)
|
|
|
|
|
|
-func setupPost(seed bool) (*httptest.Server, *http.Client) {
|
|
|
|
|
|
+func jsonBody(t *testing.T, res *http.Response) Short {
|
|
|
|
+ body, err := ioutil.ReadAll(res.Body)
|
|
|
|
+ var actual Short
|
|
|
|
+ err = json.Unmarshal(body, &actual)
|
|
|
|
+ if err != nil {
|
|
|
|
+ t.Logf("Response body is not valid JSON: %s", body)
|
|
|
|
+ t.FailNow()
|
|
|
|
+ }
|
|
|
|
+ return actual
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// subTest performs the main test work: settings up repositories, querying the
|
|
|
|
+// web API, and ensuring response status and format.
|
|
|
|
+func subTest(t *testing.T, seed bool, targetURL string, expectedStatus int, errorMessage string) *http.Response {
|
|
tr := domain.MakeMockTargetRepo(!seed)
|
|
tr := domain.MakeMockTargetRepo(!seed)
|
|
if seed {
|
|
if seed {
|
|
tr.Data[domain.TargetURL{URL: domain.URL(sampleTarget)}] = domain.ShortURL{URL: domain.URL(sampleShort)}
|
|
tr.Data[domain.TargetURL{URL: domain.URL(sampleTarget)}] = domain.ShortURL{URL: domain.URL(sampleShort)}
|
|
@@ -19,72 +32,66 @@ func setupPost(seed bool) (*httptest.Server, *http.Client) {
|
|
domain.RegisterRepositories(domain.MockShortRepo{}, tr)
|
|
domain.RegisterRepositories(domain.MockShortRepo{}, tr)
|
|
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(HandlePostTarget))
|
|
ts := httptest.NewServer(http.HandlerFunc(HandlePostTarget))
|
|
|
|
+ defer ts.Close()
|
|
|
|
|
|
c := ts.Client()
|
|
c := ts.Client()
|
|
c.CheckRedirect = doNotFollowRedirects
|
|
c.CheckRedirect = doNotFollowRedirects
|
|
|
|
|
|
- return ts, c
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func TestHandlePostTargetHappy(t *testing.T) {
|
|
|
|
- ts, c := setupPost(false)
|
|
|
|
- defer ts.Close()
|
|
|
|
-
|
|
|
|
- target, err := json.Marshal(map[string]string{"target": sampleTarget})
|
|
|
|
|
|
+ target, err := json.Marshal(Target{Target: targetURL})
|
|
if err != nil {
|
|
if err != nil {
|
|
- t.Log(err)
|
|
|
|
- t.FailNow()
|
|
|
|
|
|
+ panic(err)
|
|
}
|
|
}
|
|
|
|
|
|
- // Submitting a new valid target should succeed with 201 and return new short
|
|
|
|
res, err := c.Post(ts.URL, postContentType, bytes.NewReader(target))
|
|
res, err := c.Post(ts.URL, postContentType, bytes.NewReader(target))
|
|
if err != nil {
|
|
if err != nil {
|
|
t.Log(err)
|
|
t.Log(err)
|
|
t.FailNow()
|
|
t.FailNow()
|
|
}
|
|
}
|
|
- if res.StatusCode != http.StatusCreated {
|
|
|
|
- t.Log("Creation of new short for valid target should succeed")
|
|
|
|
- t.FailNow()
|
|
|
|
- }
|
|
|
|
|
|
|
|
- // Submitting an existing target should fail with 409 and return existing short
|
|
|
|
- res, err = c.Post(ts.URL, postContentType, bytes.NewReader(target))
|
|
|
|
- if err != nil {
|
|
|
|
- t.Log(err)
|
|
|
|
|
|
+ if res.StatusCode != expectedStatus {
|
|
|
|
+ t.Log(errorMessage)
|
|
t.FailNow()
|
|
t.FailNow()
|
|
}
|
|
}
|
|
- if res.StatusCode != http.StatusConflict {
|
|
|
|
- t.Error("Re-creation of existing short should conflict")
|
|
|
|
- }
|
|
|
|
|
|
+ return res
|
|
}
|
|
}
|
|
|
|
|
|
-func TestHandlePostTargetSad(t *testing.T) {
|
|
|
|
- ts, c := setupPost(true)
|
|
|
|
- defer ts.Close()
|
|
|
|
|
|
+// TestHandleGetShortHappyNew ensures that submitting a new valid target succeeds
|
|
|
|
+// with 201 and returns a new short.
|
|
|
|
+func TestHandleGetShortHappyNew(t *testing.T) {
|
|
|
|
+ res := subTest(t, false, sampleTarget,
|
|
|
|
+ http.StatusCreated, "Creation of new short for valid target should succeed")
|
|
|
|
|
|
- target, err := json.Marshal(map[string]string{"target": sampleTarget + "bis"})
|
|
|
|
- if err != nil {
|
|
|
|
- fmt.Println(err)
|
|
|
|
|
|
+ // Mock API creates short URLs equal to the target.
|
|
|
|
+ actual := jsonBody(t, res)
|
|
|
|
+ if actual.Short != sampleTarget {
|
|
|
|
+ t.Logf("Response short URL is %s, expected %s", actual.Short, sampleTarget)
|
|
t.FailNow()
|
|
t.FailNow()
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- // Submitting an invalid target should fail with 400
|
|
|
|
- res, err := c.Post(ts.URL, postContentType, nil)
|
|
|
|
- if err != nil {
|
|
|
|
- fmt.Println(err)
|
|
|
|
- t.FailNow()
|
|
|
|
- }
|
|
|
|
- if res.StatusCode != http.StatusBadRequest {
|
|
|
|
- t.Error("Creation of short for empty target should be a bad request")
|
|
|
|
- }
|
|
|
|
|
|
+// TestHandleGetShortHappyOld ensures that submitting an existing target fails
|
|
|
|
+// with 409 and returns an existing short.
|
|
|
|
+func TestHandleGetShortHappyOld(t *testing.T) {
|
|
|
|
+ res := subTest(t, true, sampleTarget,
|
|
|
|
+ http.StatusConflict, "Re-creation of existing short should conflict")
|
|
|
|
|
|
- // Submitting a new valid target should fail with 50x since mock repo is set to no creation.
|
|
|
|
- res, err = c.Post(ts.URL, postContentType, bytes.NewReader(target))
|
|
|
|
- if err != nil {
|
|
|
|
- fmt.Println(err)
|
|
|
|
|
|
+ // It was created that way in the previous Post() call.
|
|
|
|
+ actual := jsonBody(t, res)
|
|
|
|
+ if actual.Short != sampleShort {
|
|
|
|
+ t.Logf("Response short URL is %s, expected %s", actual.Short, sampleShort)
|
|
t.FailNow()
|
|
t.FailNow()
|
|
}
|
|
}
|
|
- if res.StatusCode != http.StatusInternalServerError {
|
|
|
|
- t.Error("Creation of new short for valid target should fail since repository cannot create")
|
|
|
|
- }
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// TestHandlePostTargetSadEmpty ensures that submitting an invalid target fails with 400.
|
|
|
|
+func TestHandlePostTargetSadEmpty(t *testing.T) {
|
|
|
|
+ subTest(t, true, "",
|
|
|
|
+ http.StatusBadRequest, "Creation of short for empty target should be a bad request")
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// TestHandlePostTargetSadUncreated ensures that submitting a new valid target
|
|
|
|
+// fails with 50x when the repository cannot create new short URLs.
|
|
|
|
+func TestHandlePostTargetSadUncreated(t *testing.T) {
|
|
|
|
+ subTest(t, true, sampleTarget+"bis",
|
|
|
|
+ http.StatusInternalServerError, "Creation of new short for valid target should fail since repository cannot create")
|
|
}
|
|
}
|