package fizzbuzz import ( "encoding/json" "io/ioutil" "net/http" "net/http/httptest" "reflect" "strings" "testing" ) func TestServer(t *testing.T) { restAPI := &Server{} tserver := httptest.NewServer(restAPI.Routes()) defer tserver.Close() t.Run("invalid URLs", func(t *testing.T) { tcases := []struct { urlParams string errCode int errContains string }{ {urlParams: "?limit=toto", errCode: 400, errContains: "invalid integer 'toto'"}, {urlParams: "?int1=tata", errCode: 400, errContains: "int1"}, {urlParams: "?int2=titi", errCode: 400, errContains: "int2"}, {urlParams: "/notFoundPath", errCode: 404, errContains: "not found"}, } for i, tcase := range tcases { resp, err := http.Get(tserver.URL + tcase.urlParams) if err != nil { t.Fatalf("%d: %s", i+1, err) } assertStatus(i, t, resp, tcase.errCode) if got, want := readErrorFromResponse(t, resp), tcase.errContains; !strings.Contains(got, want) { t.Fatalf("%d: expect errors contains %s, got %s", i+1, want, got) } } }) t.Run("valid URLs", func(t *testing.T) { emptyList := []string{} tcases := []struct { urlParams string expectOut []string }{ // Invalid cases {urlParams: "", expectOut: emptyList}, {urlParams: "?", expectOut: emptyList}, {urlParams: "?limit=0", expectOut: emptyList}, {urlParams: "?string1=aa&string2=bb&int1=2&int2=3&limit=0", expectOut: emptyList}, // Valid case { urlParams: "?string1=aa&string2=bb&int1=3&int2=2&limit=12", expectOut: []string{"1", "bb", "aa", "bb", "5", "aabb", "7", "bb", "aa", "bb", "11", "aabb"}, }, } for i, tcase := range tcases { resp, err := http.Get(tserver.URL + tcase.urlParams) if err != nil { t.Fatalf("%d: %s", i+1, err) } assertStatus(i, t, resp, 200) if got, want := readListFromResponse(t, resp), tcase.expectOut; !reflect.DeepEqual(got, want) { t.Fatalf("%d: got %#v, want %#v", i+1, got, want) } } }) } func assertStatus(i int, t *testing.T, resp *http.Response, expect int) { t.Helper() if got, want := resp.StatusCode, expect; got != want { t.Fatalf("%d, got %d, want %d", i+1, got, want) } } func readListFromResponse(t *testing.T, resp *http.Response) []string { t.Helper() defer resp.Body.Close() var list []string bytes, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } if len(bytes) == 0 { return list } if err = json.Unmarshal(bytes, &list); err != nil { t.Fatalf("error while unmarshalling %s: %s", string(bytes), err) } return list } func readErrorFromResponse(t *testing.T, resp *http.Response) string { t.Helper() defer resp.Body.Close() bytes, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } return string(bytes) }