From f8fbf00c4db15523bcbce403d515447890955fd8 Mon Sep 17 00:00:00 2001 From: Jan Dittberner Date: Thu, 26 May 2022 16:06:31 +0200 Subject: [PATCH] Refactor new motion form processing - extract form parsing into helper method app.decodePostForm - extract field checks into form.Validate --- cmd/boardvoting/handlers.go | 39 ++++++++++++++++--------------------- cmd/boardvoting/helpers.go | 23 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/cmd/boardvoting/handlers.go b/cmd/boardvoting/handlers.go index 6617f1c..5b9af8e 100644 --- a/cmd/boardvoting/handlers.go +++ b/cmd/boardvoting/handlers.go @@ -324,7 +324,7 @@ func (app *application) newMotionForm(w http.ResponseWriter, r *http.Request) { app.render(w, http.StatusOK, "create_motion.html", data) } -func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request) { +func (form *NewMotionForm) Validate() { const ( minimumTitleLength = 3 maximumTitleLength = 200 @@ -335,28 +335,8 @@ func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request) oneWeek = 7 twoWeeks = 14 threeWeeks = 28 - - hoursInDay = 24 ) - err := r.ParseForm() - if err != nil { - app.clientError(w, http.StatusBadRequest) - - return - } - - var form NewMotionForm - - err = app.formDecoder.Decode(&form, r.PostForm) - if err != nil { - app.errorLog.Printf("form decoding failed: %v", err) - - app.clientError(w, http.StatusBadRequest) - - return - } - form.CheckField( validator.NotBlank(form.Title), "title", @@ -391,6 +371,21 @@ func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request) form.CheckField(validator.PermittedInt( form.Due, threeDays, oneWeek, twoWeeks, threeWeeks), "due", "invalid duration choice", ) +} + +func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request) { + const hoursInDay = 24 + + var form NewMotionForm + + err := app.decodePostForm(r, &form) + if err != nil { + app.clientError(w, http.StatusBadRequest) + + return + } + + form.Validate() if !form.Valid() { form.User = &models.User{} @@ -441,7 +436,7 @@ func (app *application) newMotionSubmit(w http.ResponseWriter, r *http.Request) // TODO: add flash message for new motion - http.Redirect(w, r, fmt.Sprintf("/motions/%s", decision.Tag), http.StatusFound) + http.Redirect(w, r, fmt.Sprintf("/motions/%s", decision.Tag), http.StatusSeeOther) } func (app *application) editMotionForm(_ http.ResponseWriter, _ *http.Request) { diff --git a/cmd/boardvoting/helpers.go b/cmd/boardvoting/helpers.go index 6262ef1..ce919c3 100644 --- a/cmd/boardvoting/helpers.go +++ b/cmd/boardvoting/helpers.go @@ -18,9 +18,12 @@ limitations under the License. package main import ( + "errors" "fmt" "net/http" "runtime/debug" + + "github.com/go-playground/form/v4" ) func (app *application) serverError(w http.ResponseWriter, err error) { @@ -38,3 +41,23 @@ func (app *application) clientError(w http.ResponseWriter, status int) { func (app *application) notFound(w http.ResponseWriter) { app.clientError(w, http.StatusNotFound) } + +func (app *application) decodePostForm(r *http.Request, dst any) error { + err := r.ParseForm() + if err != nil { + return fmt.Errorf("could not parse HTML form: %w", err) + } + + err = app.formDecoder.Decode(dst, r.PostForm) + if err != nil { + var invalidDecoderError *form.InvalidDecoderError + + if errors.As(err, &invalidDecoderError) { + panic(err) + } + + return fmt.Errorf("could not decode form: %w", err) + } + + return nil +}