You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
7.9 KiB
396 lines
7.9 KiB
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()
|
|
}
|
|
})
|
|
}
|