package web import ( "encoding/json" "io" "log" "net/http" "net/http/httptest" "path/filepath" "testing" "github.com/gorilla/mux" "golang.org/x/exp/slices" "code.osinet.fr/fgm/lbc/domain" ) func TestServer_Serve(t *testing.T) { logger := &log.Logger{} logger.SetOutput(io.Discard) const base = "/test" happyPath := filepath.Join(base, "2", "3", "7", domain.Fizz, domain.Buzz) expectedHappy := []string{ "1", domain.Fizz, domain.Buzz, domain.Fizz, "5", domain.Both, "7", } tests := [...]struct { name string headers http.Header path string expCode int expected []string }{ {"happy explicit", http.Header{"Accept": []string{JSON}}, happyPath, http.StatusOK, expectedHappy}, {"happy wild", http.Header{"Accept": []string{"*/*"}}, happyPath, http.StatusOK, expectedHappy}, {"sad accept", http.Header{"Accept": []string{"text/html"}}, happyPath, http.StatusNotAcceptable, nil}, {"sad charset", http.Header{"Accept-Charset": []string{"iso-8859-15"}}, happyPath, http.StatusNotAcceptable, nil}, {"bad route params", nil, filepath.Join(base, "2", "3", "0", domain.Fizz, domain.Buzz), http.StatusNotFound, nil}, {"bad domain params", nil, filepath.Join(base, "2", "3", "2", domain.Fizz, domain.Buzz), http.StatusInternalServerError, nil}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { req, err := http.NewRequest("GET", test.path, nil) if err != nil { t.Fatal(err) } req.Header = test.headers rec := httptest.NewRecorder() // We need a router to inject variables from path, preventing us from a straight handler.ServerHTTP(rec, req) router := mux.NewRouter() router.HandleFunc(base+PathFB, MakeFizzBuzz(logger, true)) router.ServeHTTP(rec, req) status := rec.Code if status != test.expCode { t.Fatalf("handler returned %d, but expected %d", status, test.expCode) } if status >= http.StatusMultipleChoices { return } actual := make([]string, 0, len(test.expected)) err = json.Unmarshal(rec.Body.Bytes(), &actual) if err != nil { t.Fatal(err) } if !slices.Equal(actual, test.expected) { t.Errorf("handler returned:\n%#v\nbut expected:\n%#v\n", actual, test.expected) } }) } }