|
|
package wrouter
import ( "encoding/json" "net/http" "net/http/httptest" "net/url" "strings" "testing"
"git.aiterp.net/gisle/wrouter/generate" "git.aiterp.net/gisle/wrouter/response"
"git.aiterp.net/gisle/wrouter/auth" )
var pages = []Page{ Page{generate.ID(), "Test Page", "Blurg blurg"}, Page{generate.ID(), "Test Page 2", "Blurg blurg 2"}, Page{generate.ID(), "Stuff", "And things"}, }
type Page struct { ID string `json:"id"` Title string `json:"title"` Text string `json:"text"` }
type Header struct { ID string `json:"id"` Title string `json:"title"` }
type PageForm struct { Title string `json:"title"` Text string `json:"text"` }
func listPage(w http.ResponseWriter, req *http.Request, user *auth.User) { headers := make([]Header, len(pages)) for i, page := range pages { headers[i] = Header{page.ID, page.Title} }
response.JSON(w, 200, headers) }
func createPage(w http.ResponseWriter, req *http.Request, user *auth.User) { title := req.Form.Get("title") text := req.Form.Get("text")
if title == "" { response.Text(w, 400, "No title") return }
for _, page := range pages { if page.Title == title { response.Text(w, 400, "Title already exists") return } }
page := Page{generate.ID(), title, text} pages = append(pages, page)
response.JSON(w, 200, page) }
func getPage(w http.ResponseWriter, req *http.Request, id string, user *auth.User) { for _, page := range pages { if page.ID == id { response.JSON(w, 200, page) return } }
response.Text(w, 404, "Page not found") }
func updatePage(w http.ResponseWriter, req *http.Request, id string, user *auth.User) { for _, page := range pages { if page.ID == id { title := req.Form.Get("title") text := req.Form.Get("text")
if title != "" { page.Title = title } page.Text = text
response.JSON(w, 200, page) return } }
response.Text(w, 404, "Page not found") }
func deletePage(w http.ResponseWriter, req *http.Request, id string, user *auth.User) { for i, page := range pages { if page.ID == id { pages = append(pages[:i], pages[i+1:]...) response.Empty(w) return } }
response.Text(w, 404, "Page not found") }
var resource = Resource{listPage, createPage, getPage, updatePage, deletePage}
type handlerStruct struct{}
func (hs *handlerStruct) ServeHTTP(w http.ResponseWriter, req *http.Request) { req.ParseForm() // Router does this in non-tests
if strings.HasPrefix(req.URL.Path, "/page") { resource.Handle("/page", w, req, nil) return } }
func runForm(method, url string, data url.Values) (*http.Response, error) { body := strings.NewReader(data.Encode()) req, err := http.NewRequest(method, url, body) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
return http.DefaultClient.Do(req) }
func TestResource(t *testing.T) { server := httptest.NewServer(&handlerStruct{})
t.Run("List", func(t *testing.T) { resp, err := http.Get(server.URL + "/page/") if err != nil { t.Error(err) t.Fail() }
if resp.StatusCode != 200 { t.Error("Expected status 200, got", resp.StatusCode, resp.Status) t.Fail() }
headers := []Header{} err = json.NewDecoder(resp.Body).Decode(&headers) if err != nil { t.Error(err) t.Fail() }
if len(headers) < 3 { t.Error("Expected 3 headers, got", len(headers)) t.Fail() }
for i, header := range headers { page := pages[i]
if header.ID != page.ID { t.Error(header.ID, "!=", page.ID) t.Fail() }
if header.Title != page.Title { t.Error(header.Title, "!=", page.Title) t.Fail() } } })
t.Run("Get", func(t *testing.T) { page := pages[1] resp, err := http.Get(server.URL + "/page/" + page.ID) if err != nil { t.Error(err) t.Fail() }
if resp.StatusCode != 200 { t.Error("Expected status 200, got", resp.StatusCode, resp.Status) t.Fail() }
respPage := Page{} err = json.NewDecoder(resp.Body).Decode(&respPage) if err != nil { t.Error(err) t.Fail() }
if respPage.ID == "" { t.Error("No ID in response page") t.Fail() }
if respPage.ID != page.ID { t.Errorf("ID %s != %s", respPage.ID, page.ID) t.Fail() }
if respPage.Title != page.Title { t.Errorf("Title %s != %s", respPage.Title, page.Title) t.Fail() }
if respPage.Text != page.Text { t.Errorf("Text %s != %s", respPage.Text, page.Text) t.Fail() } })
t.Run("Get_Fail", func(t *testing.T) { resp, err := http.Get(server.URL + "/page/" + generate.ID()) if err != nil { t.Error(err) t.Fail() }
if resp.StatusCode != 404 { t.Error("Expected status 404, got", resp.StatusCode, resp.Status) t.Fail() }
respPage := Page{} err = json.NewDecoder(resp.Body).Decode(&respPage) if err == nil { t.Error("Expected encoder error, got:", respPage) t.Fail() }
if respPage.ID != "" { t.Error("Ad ID in response page", respPage.ID) t.Fail() } })
t.Run("Create", func(t *testing.T) { form := url.Values{} form.Set("title", "Hello World") form.Set("text", "Sei Gegrüßt, Erde")
resp, err := http.PostForm(server.URL+"/page/", form)
if err != nil { t.Error(err) t.Fail() }
if resp.StatusCode != 200 { t.Error("Expected status 200, got", resp.StatusCode, resp.Status) t.Fail() }
respPage := Page{} err = json.NewDecoder(resp.Body).Decode(&respPage) if err != nil { t.Error(err) t.Fail() }
if respPage.ID == "" { t.Error("No ID in response page") t.Fail() }
if respPage.Title != form.Get("title") { t.Errorf("Title %s != %s", respPage.Title, form.Get("title")) t.Fail() }
if respPage.Text != form.Get("text") { t.Errorf("Text %s != %s", respPage.Text, form.Get("text")) t.Fail() }
if len(pages) != 4 { t.Errorf("Page was not added") t.Fail() } })
t.Run("Update", func(t *testing.T) { page := pages[0] form := url.Values{} form.Set("text", "Edits and stuff")
resp, err := runForm("PUT", server.URL+"/page/"+page.ID, form)
if err != nil { t.Error("Request:", err) t.Fail() }
if resp.StatusCode != 200 { t.Error("Expected status 200, got", resp.StatusCode, resp.Status) t.Fail() }
respPage := Page{} err = json.NewDecoder(resp.Body).Decode(&respPage) if err != nil { t.Error("Decode:", err) t.Fail() }
if respPage.ID == "" { t.Error("No ID in response page") t.Fail() }
if respPage.Title != page.Title { t.Errorf("Title %s != %s", respPage.Title, form.Get("title")) t.Fail() }
if respPage.Text != form.Get("text") { t.Errorf("Text %s != %s", respPage.Text, form.Get("text")) t.Fail() } })
t.Run("Update_Fail", func(t *testing.T) { form := url.Values{} form.Set("text", "Edits and stuff")
resp, err := runForm("PUT", server.URL+"/page/NONEXISTENT-ID-GOES-HERE", form)
if err != nil { t.Error("Request:", err) t.Fail() }
if resp.StatusCode != 404 { t.Error("Expected status 404, got", resp.StatusCode, resp.Status) t.Fail() }
respPage := Page{} err = json.NewDecoder(resp.Body).Decode(&respPage) if err == nil { t.Error("A page was returned:", respPage) t.Fail() }
if respPage.ID != "" { t.Error("ID in response page", respPage.ID) t.Fail() } })
t.Run("Delete", func(t *testing.T) { page := pages[3] resp, err := runForm("DELETE", server.URL+"/page/"+page.ID, url.Values{})
if err != nil { t.Error("Request:", err) t.Fail() }
if resp.StatusCode != 204 { t.Error("Expected status 204, got", resp.Status) t.Fail() }
if len(pages) != 3 { t.Error("Page was not deleted") t.Fail() } })
t.Run("Delete_Fail", func(t *testing.T) { resp, err := runForm("DELETE", server.URL+"/page/NONEXISTENT-ID-GOES-HERE", url.Values{})
if err != nil { t.Error("Request:", err) t.Fail() }
if resp.StatusCode != 404 { t.Error("Expected status 404, got", resp.Status) t.Fail() }
if len(pages) != 3 { t.Error("A page was deleted despite the non-existent ID") t.Fail() } }) }
|