add tests for availabilityJson

This commit is contained in:
vinchent 2024-07-14 14:51:12 +02:00
parent 413bfc1685
commit 904ee95d63
3 changed files with 133 additions and 31 deletions

View File

@ -277,8 +277,14 @@ type jsonResponse struct {
// AvailabilityJSON is the search for availability page handler // AvailabilityJSON is the search for availability page handler
func (m *Repository) AvailabilityJSON(w http.ResponseWriter, r *http.Request) { func (m *Repository) AvailabilityJSON(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
m.App.Session.Put(r.Context(), "error", "can't parse form") // can't parse form, so return appropriate json
http.Redirect(w, r, "/", http.StatusTemporaryRedirect) resp := jsonResponse{
OK: false,
Message: "Internal server error",
}
out, _ := json.MarshalIndent(resp, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(out)
return return
} }
sd := r.Form.Get("start") sd := r.Form.Get("start")
@ -287,24 +293,48 @@ func (m *Repository) AvailabilityJSON(w http.ResponseWriter, r *http.Request) {
layout := "2006-01-02" layout := "2006-01-02"
startDate, err := time.Parse(layout, sd) startDate, err := time.Parse(layout, sd)
if err != nil { if err != nil {
helpers.ServerError(w, err) resp := jsonResponse{
OK: false,
Message: "Wrong startDate",
}
out, _ := json.MarshalIndent(resp, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(out)
return return
} }
endDate, err := time.Parse(layout, ed) endDate, err := time.Parse(layout, ed)
if err != nil { if err != nil {
helpers.ServerError(w, err) resp := jsonResponse{
OK: false,
Message: "Wrong endDate",
}
out, _ := json.MarshalIndent(resp, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(out)
return return
} }
roomID, err := strconv.Atoi(r.Form.Get("room_id")) roomID, err := strconv.Atoi(r.Form.Get("room_id"))
if err != nil { if err != nil {
helpers.ServerError(w, err) resp := jsonResponse{
OK: false,
Message: "Wrong roomID",
}
out, _ := json.MarshalIndent(resp, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(out)
return return
} }
available, err := m.DB.SearchAvailabilityByDatesByRoomID(startDate, endDate, roomID) available, err := m.DB.SearchAvailabilityByDatesByRoomID(startDate, endDate, roomID)
if err != nil { if err != nil {
helpers.ServerError(w, err) resp := jsonResponse{
OK: false,
Message: "Error connecting to database",
}
out, _ := json.MarshalIndent(resp, "", " ")
w.Header().Set("Content-Type", "application/json")
w.Write(out)
return return
} }
@ -316,11 +346,8 @@ func (m *Repository) AvailabilityJSON(w http.ResponseWriter, r *http.Request) {
RoomID: strconv.Itoa(roomID), RoomID: strconv.Itoa(roomID),
} }
out, err := json.MarshalIndent(resp, "", " ") // No error check because all aspects of the json are handled
if err != nil { out, _ := json.MarshalIndent(resp, "", " ")
helpers.ServerError(w, err)
return
}
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@ -2,11 +2,13 @@ package handlers
import ( import (
"context" "context"
"encoding/json"
"fmt" "fmt"
"go-udemy-web-1/internal/models" "go-udemy-web-1/internal/models"
"log" "log"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -110,7 +112,6 @@ func TestRepository_MakeReservation(t *testing.T) {
var postMakeReservationTests = []struct { var postMakeReservationTests = []struct {
name string name string
reservationInfo []postData reservationInfo []postData
roomID int
expectedStatusCode int expectedStatusCode int
}{ }{
@ -125,7 +126,7 @@ var postMakeReservationTests = []struct {
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
1, http.StatusSeeOther, http.StatusSeeOther,
}, },
{ {
"no_session", "no_session",
@ -138,24 +139,20 @@ var postMakeReservationTests = []struct {
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
0, http.StatusTemporaryRedirect, http.StatusTemporaryRedirect,
},
{
"no_post_data",
[]postData{},
0, http.StatusTemporaryRedirect,
}, },
{"no_post_data", []postData{}, http.StatusOK},
{ {
"missing first name", "missing first name",
[]postData{ []postData{
{key: "last_name", value: "Smith"}, {key: "last_name", value: "Smith"},
{key: "email", value: "john@smith.com"}, {key: "email", value: "john@smith.com"},
{key: "phone", value: "1234"}, {key: "phone", value: "1234"},
{key: "room_id", value: "0"}, {key: "room_id", value: "1"},
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
1, http.StatusOK, http.StatusOK,
}, },
{ {
"wrong first name", "wrong first name",
@ -164,11 +161,11 @@ var postMakeReservationTests = []struct {
{key: "last_name", value: "Smith"}, {key: "last_name", value: "Smith"},
{key: "email", value: "john@smith.com"}, {key: "email", value: "john@smith.com"},
{key: "phone", value: "1234"}, {key: "phone", value: "1234"},
{key: "room_id", value: "0"}, {key: "room_id", value: "1"},
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
1, http.StatusOK, http.StatusOK,
}, },
{ {
"wrong email", "wrong email",
@ -177,11 +174,11 @@ var postMakeReservationTests = []struct {
{key: "last_name", value: "Smith"}, {key: "last_name", value: "Smith"},
{key: "email", value: "john@smith"}, {key: "email", value: "john@smith"},
{key: "phone", value: "1234"}, {key: "phone", value: "1234"},
{key: "room_id", value: "0"}, {key: "room_id", value: "1"},
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
1, http.StatusOK, http.StatusOK,
}, },
{ {
"insert reservation error", "insert reservation error",
@ -194,7 +191,7 @@ var postMakeReservationTests = []struct {
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
2, http.StatusTemporaryRedirect, http.StatusTemporaryRedirect,
}, },
{ {
"insert room restriction error", "insert room restriction error",
@ -207,26 +204,33 @@ var postMakeReservationTests = []struct {
{key: "start_date", value: "2050-01-01"}, {key: "start_date", value: "2050-01-01"},
{key: "end_date", value: "2050-01-02"}, {key: "end_date", value: "2050-01-02"},
}, },
100, http.StatusTemporaryRedirect, http.StatusTemporaryRedirect,
}, },
} }
func TestRepository_PostMakeReservation(t *testing.T) { func TestRepository_PostMakeReservation(t *testing.T) {
for _, test := range postMakeReservationTests { for _, test := range postMakeReservationTests {
roomID := 1
var reqBody string var reqBody string
if len(test.reservationInfo) > 0 { if len(test.reservationInfo) > 0 {
if test.reservationInfo[0].key == "room_id" {
roomID, _ = strconv.Atoi(test.reservationInfo[0].value)
}
reqBody = fmt.Sprintf("%s=%s", test.reservationInfo[0].key, reqBody = fmt.Sprintf("%s=%s", test.reservationInfo[0].key,
test.reservationInfo[0].value) test.reservationInfo[0].value)
for _, element := range test.reservationInfo[1:] { for _, element := range test.reservationInfo[1:] {
reqBody = fmt.Sprintf("%s&%s=%s", reqBody, element.key, reqBody = fmt.Sprintf("%s&%s=%s", reqBody, element.key,
element.value) element.value)
if element.key == "room_id" {
roomID, _ = strconv.Atoi(element.value)
}
} }
} }
layout := "2006-01-02" layout := "2006-01-02"
sd, _ := time.Parse(layout, "2050-01-01") sd, _ := time.Parse(layout, "2050-01-01")
ed, _ := time.Parse(layout, "2050-01-02") ed, _ := time.Parse(layout, "2050-01-02")
reservation := models.Reservation{ reservation := models.Reservation{
RoomID: test.roomID, RoomID: roomID,
StartDate: sd, StartDate: sd,
EndDate: ed, EndDate: ed,
} }
@ -237,7 +241,7 @@ func TestRepository_PostMakeReservation(t *testing.T) {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
rr := httptest.NewRecorder() rr := httptest.NewRecorder()
if test.roomID == 0 { if roomID == 0 {
session.Put(ctx, "reservation", nil) session.Put(ctx, "reservation", nil)
} else { } else {
session.Put(ctx, "reservation", reservation) session.Put(ctx, "reservation", reservation)
@ -247,12 +251,80 @@ func TestRepository_PostMakeReservation(t *testing.T) {
handler.ServeHTTP(rr, req) handler.ServeHTTP(rr, req)
if rr.Code != test.expectedStatusCode { if rr.Code != test.expectedStatusCode {
fmt.Printf("for %s, reservation handler returned response code: got %d, wanted %d\n", t.Errorf("for %s, reservation handler returned response code: got %d, wanted %d\n",
test.name, rr.Code, test.expectedStatusCode) test.name, rr.Code, test.expectedStatusCode)
} }
} }
} }
// }}}
// {{{ Test AvailabilityJSON
var availabilityJSONTests = []struct {
name string
queryInfo []postData
expectedStatusJSON jsonResponse
}{
{"ok", []postData{
{key: "start", value: "2050-01-01"},
{key: "end", value: "2050-01-02"},
{key: "room_id", value: "1"},
}, jsonResponse{
OK: true,
Message: "",
StartDate: "2050-01-01",
EndDate: "2050-01-02",
RoomID: "1",
}},
{"wrong date", []postData{
{key: "start", value: "2050-01"},
{key: "end", value: "2050-01-02"},
{key: "room_id", value: "1"},
}, jsonResponse{
OK: false,
Message: "Wrong startDate",
}},
}
func Test_AvailabilityJSON(t *testing.T) {
for _, test := range availabilityJSONTests {
var reqBody string
reqBody = fmt.Sprintf("%s=%s", test.queryInfo[0].key,
test.queryInfo[0].value)
for _, element := range test.queryInfo[1:] {
reqBody = fmt.Sprintf("%s&%s=%s", reqBody, element.key,
element.value)
}
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()
handler := http.HandlerFunc(Repo.AvailabilityJSON)
handler.ServeHTTP(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("for %s, reservation handler returned response code: got %d, wanted %d\n",
test.name, rr.Code, http.StatusOK)
}
var j jsonResponse
err := json.Unmarshal(rr.Body.Bytes(), &j)
if err != nil {
t.Errorf("for %s, failed to parse json", test.name)
}
if j != test.expectedStatusJSON {
expected, _ := json.MarshalIndent(test.expectedStatusJSON, "", " ")
t.Errorf("for %s, returned json is wrong, expected: %s, returned: %s",
test.name, expected, rr.Body.String())
}
}
}
// }}} // }}}
// {{{ Test Helpers // {{{ Test Helpers

View File

@ -29,7 +29,10 @@ func (m *testDBRepo) InsertRoomRestriction(r models.RoomRestriction) error {
// SearchAvailabilityByDatesByRoomID returns true if availability exists for roomID, and false if no availability // SearchAvailabilityByDatesByRoomID returns true if availability exists for roomID, and false if no availability
func (m *testDBRepo) SearchAvailabilityByDatesByRoomID(start, end time.Time, roomID int) (bool, error) { func (m *testDBRepo) SearchAvailabilityByDatesByRoomID(start, end time.Time, roomID int) (bool, error) {
return false, nil if roomID == 2 {
return false, errors.New("deliberate error")
}
return true, nil
} }
// SearchAvailabilityForAllRooms returns a slice of rooms, if any, for given date range // SearchAvailabilityForAllRooms returns a slice of rooms, if any, for given date range