diff --git a/cmd/web/handlers_guestbook.go b/cmd/web/handlers_guestbook.go index e137a81..92b285a 100644 --- a/cmd/web/handlers_guestbook.go +++ b/cmd/web/handlers_guestbook.go @@ -179,9 +179,7 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt form.CheckField(validator.NotBlank(form.AuthorName), "authorName", "This field cannot be blank") form.CheckField(validator.MaxChars(form.AuthorName, 256), "authorName", "This field cannot be more than 256 characters long") - form.CheckField(validator.NotBlank(form.AuthorEmail), "authorEmail", "This field cannot be blank") form.CheckField(validator.MaxChars(form.AuthorEmail, 256), "authorEmail", "This field cannot be more than 256 characters long") - form.CheckField(validator.NotBlank(form.AuthorSite), "authorSite", "This field cannot be blank") form.CheckField(validator.MaxChars(form.AuthorSite, 256), "authorSite", "This field cannot be more than 256 characters long") form.CheckField(validator.NotBlank(form.Content), "content", "This field cannot be blank") @@ -193,7 +191,8 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt return } data := app.newCommonData(r) - views.GuestbookView("Guestbook", data, website, website.Guestbook, comments, forms.CommentCreateForm{}).Render(r.Context(), w) + w.WriteHeader(http.StatusUnprocessableEntity) + views.GuestbookView("Guestbook", data, website, website.Guestbook, comments, form).Render(r.Context(), w) return } @@ -203,7 +202,7 @@ func (app *application) postGuestbookCommentCreate(w http.ResponseWriter, r *htt app.serverError(w, r, err) return } - // app.sessionManager.Put(r.Context(), "flash", "Comment successfully posted!") + app.sessionManager.Put(r.Context(), "flash", "Comment successfully posted!") http.Redirect(w, r, fmt.Sprintf("/websites/%s/guestbook", slug), http.StatusSeeOther) } diff --git a/cmd/web/handlers_guestbook_test.go b/cmd/web/handlers_guestbook_test.go index 3faaa03..c96693b 100644 --- a/cmd/web/handlers_guestbook_test.go +++ b/cmd/web/handlers_guestbook_test.go @@ -3,6 +3,7 @@ package main import ( "fmt" "net/http" + "net/url" "testing" "git.32bit.cafe/32bitcafe/guestbook/internal/assert" @@ -58,3 +59,88 @@ func TestGetGuestbookView(t *testing.T) { }) } } + +func TestPostGuestbookCommentCreate(t *testing.T) { + app := newTestApplication(t) + ts := newTestServer(t, app.routes()) + defer ts.Close() + + _, _, body := ts.get(t, fmt.Sprintf("/websites/%s/guestbook", shortIdToSlug(1))) + validCSRFToken := extractCSRFToken(t, body) + + const ( + validAuthorName = "John Test" + validAuthorEmail = "test@example.com" + validAuthorSite = "example.com" + validContent = "This is a comment" + ) + + tests := []struct { + name string + authorName string + authorEmail string + authorSite string + content string + csrfToken string + wantCode int + }{ + { + name: "Valid input", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank name", + authorName: "", + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusUnprocessableEntity, + }, + { + name: "Blank email", + authorName: validAuthorName, + authorEmail: "", + authorSite: validAuthorSite, + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank site", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: "", + content: validContent, + csrfToken: validCSRFToken, + wantCode: http.StatusSeeOther, + }, + { + name: "Blank content", + authorName: validAuthorName, + authorEmail: validAuthorEmail, + authorSite: validAuthorSite, + content: "", + csrfToken: validCSRFToken, + wantCode: http.StatusUnprocessableEntity, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + form := url.Values{} + form.Add("authorname", tt.authorName) + form.Add("authoremail", tt.authorEmail) + form.Add("authorsite", tt.authorSite) + form.Add("content", tt.content) + form.Add("csrf_token", tt.csrfToken) + code, _, body := ts.postForm(t, fmt.Sprintf("/websites/%s/guestbook/comments/create", shortIdToSlug(1)), form) + assert.Equal(t, code, tt.wantCode) + assert.Equal(t, body, body) + }) + } +} diff --git a/cmd/web/routes.go b/cmd/web/routes.go index 31d0d41..0b72dda 100644 --- a/cmd/web/routes.go +++ b/cmd/web/routes.go @@ -17,7 +17,7 @@ func (app *application) routes() http.Handler { standard := alice.New(app.recoverPanic, app.logRequest, commonHeaders) mux.Handle("/{$}", dynamic.ThenFunc(app.home)) - mux.Handle("POST /websites/{id}/guestbook/comments/create", standard.ThenFunc(app.postGuestbookCommentCreate)) + mux.Handle("POST /websites/{id}/guestbook/comments/create", dynamic.ThenFunc(app.postGuestbookCommentCreate)) mux.Handle("GET /websites/{id}/guestbook", dynamic.ThenFunc(app.getGuestbook)) mux.Handle("GET /users/register", dynamic.ThenFunc(app.getUserRegister)) mux.Handle("POST /users/register", dynamic.ThenFunc(app.postUserRegister)) diff --git a/internal/forms/forms.go b/internal/forms/forms.go index 2014c84..b5edd31 100644 --- a/internal/forms/forms.go +++ b/internal/forms/forms.go @@ -19,7 +19,7 @@ type CommentCreateForm struct { AuthorName string `schema:"authorname"` AuthorEmail string `schema:"authoremail"` AuthorSite string `schema:"authorsite"` - Content string `schema:"content,required"` + Content string `schema:"content"` validator.Validator `schema:"-"` }