package main import ( "encoding/json" "fmt" "io" "net/http" "net/http/httptest" "reflect" "testing" "git.andreafazzi.eu/andrea/testhub/models" "github.com/remogatto/prettytest" ) // Start of setup type testSuite struct { prettytest.Suite } type StubPlayerStore struct { scores map[string]int winCalls []string league []models.Player } func (store *StubPlayerStore) GetPlayerScore(player string) int { return store.scores[player] } func (s *StubPlayerStore) RecordWin(name string) { s.winCalls = append(s.winCalls, name) } func (store *StubPlayerStore) GetLeague() []models.Player { return store.league } func TestRunner(t *testing.T) { prettytest.Run( t, new(testSuite), ) } func (t *testSuite) TestGETPlayers() { tests := []struct { name string expectedScore string expectedHTTPStatus int }{ {"Pepper", "20", http.StatusOK}, {"Floyd", "10", http.StatusOK}, {"Apollo", "0", http.StatusNotFound}, } store := &StubPlayerStore{ map[string]int{ "Pepper": 20, "Floyd": 10, }, nil, []models.Player{}, } server := NewPlayerServer(store) for _, test := range tests { request, _ := http.NewRequest(http.MethodGet, "/players/"+test.name, nil) response := httptest.NewRecorder() server.ServeHTTP(response, request) t.Equal(test.expectedScore, response.Body.String()) t.Equal(test.expectedHTTPStatus, response.Code) } } func (t *testSuite) TestPOSTPlayers() { store := &StubPlayerStore{ map[string]int{}, nil, []models.Player{}, } server := NewPlayerServer(store) request, _ := http.NewRequest(http.MethodPost, "/players/Pepper", nil) response := httptest.NewRecorder() server.ServeHTTP(response, request) t.Equal(1, len(store.winCalls)) t.Equal(http.StatusAccepted, response.Code) } func (t *testSuite) TestGETLeague() { expectedResult := []models.Player{ {Name: "Cleo", Wins: 20}, {Name: "Chris", Wins: 10}, } store := &StubPlayerStore{ nil, nil, expectedResult, } server := NewPlayerServer(store) request, _ := http.NewRequest(http.MethodGet, "/league", nil) response := httptest.NewRecorder() server.ServeHTTP(response, request) result := getLeagueFromResponse(response.Body) t.True(leaguesAreEqual(expectedResult, result)) t.Equal(http.StatusOK, response.Code) } func getLeagueFromResponse(body io.Reader) (league []models.Player) { err := json.NewDecoder(body).Decode(&league) if err != nil { panic(fmt.Errorf("Unable to parse response from server %q into slice of Player, '%v'", body, err)) } return } func leaguesAreEqual(got, want []models.Player) bool { return reflect.DeepEqual(got, want) }