package api import ( "bytes" "encoding/json" "io/ioutil" "net/http" "net/http/httptest" "testing" "code.osinet.fr/fgm/kurz/domain" ) 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) if seed { tr.Data[domain.TargetURL{URL: domain.URL(sampleTarget)}] = domain.ShortURL{URL: domain.URL(sampleShort)} } domain.RegisterRepositories(domain.MockShortRepo{}, tr) ts := httptest.NewServer(http.HandlerFunc(handlePostTarget)) defer ts.Close() c := ts.Client() c.CheckRedirect = doNotFollowRedirects target, err := json.Marshal(Target{Target: targetURL}) if err != nil { panic(err) } res, err := c.Post(ts.URL, postContentType, bytes.NewReader(target)) if err != nil { t.Log(err) t.FailNow() } if res.StatusCode != expectedStatus { t.Log(errorMessage) t.FailNow() } return res } // 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") // 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() } } // 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") // 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() } } // 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") }