udemy-go-web-1/internal/handlers/handlers_test.go

267 lines
5.8 KiB
Go
Raw Normal View History

package handlers
import (
"context"
"fmt"
"go-udemy-web-1/internal/models"
"log"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
)
type postData struct {
key string
value string
}
var theTests = []struct {
name string
url string
method string
expectedStatusCode int
}{
{"home", "/", "GET", http.StatusOK},
{"about", "/about", "GET", http.StatusOK},
{"gq", "/generals-quarters", "GET", http.StatusOK},
{"ms", "/majors-suite", "GET", http.StatusOK},
{"sa", "/availability", "GET", http.StatusOK},
{"contact", "/contact", "GET", http.StatusOK},
// {"post-search-avail", "/availability", "POST", []postData{
// {key: "start", value: "2020-01-01"},
// {key: "end", value: "2020-01-02"},
// }, http.StatusOK},
// {"post-search-avail-json", "/availability-json", "POST", []postData{
// {key: "start", value: "2020-01-01"},
// {key: "end", value: "2020-01-02"},
// }, http.StatusOK},
// {"make-reservation", "/make-reservation", "POST", []postData{
// {key: "first_name", value: "John"},
// {key: "last_name", value: "Smith"},
// {key: "email", value: "me@here.com"},
// {key: "phone", value: "12345"},
// }, http.StatusOK},
}
func TestHandlers(t *testing.T) {
routes := getRoutes()
ts := httptest.NewTLSServer(routes)
defer ts.Close()
for _, e := range theTests {
resp, err := ts.Client().Get(ts.URL + e.url)
if err != nil {
t.Log(err)
t.Fatal(err)
}
if resp.StatusCode != e.expectedStatusCode {
t.Errorf("for %s, expected %d but got %d", e.name, e.expectedStatusCode, resp.StatusCode)
}
}
}
// {{{ Make Reservation Tests
var makeReservationTests = []struct {
name string
roomID int
expectedStatusCode int
}{
{"ok", 1, http.StatusOK},
{"no session", 0, http.StatusTemporaryRedirect},
{"non-existant room", 100, http.StatusTemporaryRedirect},
}
func TestRepository_MakeReservation(t *testing.T) {
for _, test := range makeReservationTests {
reservation := models.Reservation{
RoomID: test.roomID,
Room: models.Room{
ID: test.roomID,
RoomName: "Room name",
},
}
req, _ := http.NewRequest("GET", "/make-reservation", nil)
ctx := getCtx(req)
req = req.WithContext(ctx)
rr := httptest.NewRecorder()
if test.roomID == 0 {
session.Put(ctx, "reservation", nil)
} else {
session.Put(ctx, "reservation", reservation)
}
handler := http.HandlerFunc(Repo.MakeReservation)
handler.ServeHTTP(rr, req)
if rr.Code != test.expectedStatusCode {
t.Errorf("for %s, reservation handler returned response code: got %d, wanted %d",
test.name, rr.Code, http.StatusOK)
}
}
}
// }}}
// {{{ PostMakeReservation tests
var postMakeReservationTests = []struct {
name string
reservationInfo []string
roomID int
expectedStatusCode int
}{
{
"ok",
[]string{
"first_name=John",
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=1",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
1, http.StatusSeeOther,
},
{
"no_session",
[]string{
"first_name=John",
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=0",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
0, http.StatusTemporaryRedirect,
},
{
"no_post_data",
[]string{},
0, http.StatusTemporaryRedirect,
},
{
"missing first name",
[]string{
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=1",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
1, http.StatusOK,
},
{
"wrong first name",
[]string{
"first_name=J",
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=1",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
1, http.StatusOK,
},
{
"wrong email",
[]string{
"first_name=John",
"last_name=Smith",
"email=john@smith",
"phone=1234",
"room_id=1",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
1, http.StatusOK,
},
{
"insert reservation error",
[]string{
"first_name=John",
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=2",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
2, http.StatusTemporaryRedirect,
},
{
"insert room restriction error",
[]string{
"first_name=John",
"last_name=Smith",
"email=john@smith.com",
"phone=1234",
"room_id=100",
"start_date=2050-01-01",
"end_date=2050-01-02",
},
100, http.StatusTemporaryRedirect,
},
}
func TestRepository_PostMakeReservation(t *testing.T) {
for _, test := range postMakeReservationTests {
var reqBody string
if len(test.reservationInfo) > 0 {
reqBody = test.reservationInfo[0]
for _, element := range test.reservationInfo[1:] {
reqBody = fmt.Sprintf("%s&%s", reqBody, element)
}
}
layout := "2006-01-02"
sd, _ := time.Parse(layout, "2050-01-01")
ed, _ := time.Parse(layout, "2050-01-02")
reservation := models.Reservation{
RoomID: test.roomID,
StartDate: sd,
EndDate: ed,
}
req, _ := http.NewRequest("POST", "/make-reservation", strings.NewReader(reqBody))
ctx := getCtx(req)
req = req.WithContext(ctx)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
rr := httptest.NewRecorder()
if test.roomID == 0 {
session.Put(ctx, "reservation", nil)
} else {
session.Put(ctx, "reservation", reservation)
}
handler := http.HandlerFunc(Repo.PostMakeReservation)
handler.ServeHTTP(rr, req)
if rr.Code != test.expectedStatusCode {
fmt.Printf("for %s, reservation handler returned response code: got %d, wanted %d",
test.name, rr.Code, test.expectedStatusCode)
}
}
}
// }}}
// {{{ Test Helpers
func getCtx(req *http.Request) context.Context {
ctx, err := session.Load(req.Context(), req.Header.Get("X-Session"))
if err != nil {
log.Println(err)
}
return ctx
}
// }}}