fix panic when submitting invalid form on guestbook page #24
| @ -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) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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) | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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)) | ||||
|  | ||||
| @ -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:"-"` | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user