From 5927e9c855861674a19eb7c9247e89a5906d8a9a Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 10 Jan 2025 10:31:59 +0100 Subject: [PATCH] Refactor createVotes in two different functions (only for the part that was nested in ifs) --- cmd/web/handlers.go | 140 ++++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 63 deletions(-) diff --git a/cmd/web/handlers.go b/cmd/web/handlers.go index 888b6d8..82fa3c0 100644 --- a/cmd/web/handlers.go +++ b/cmd/web/handlers.go @@ -2,6 +2,7 @@ package main import ( api "code.dlmw.ch/dlmw/qv/internal" + "code.dlmw.ch/dlmw/qv/internal/models" "code.dlmw.ch/dlmw/qv/internal/validator" "database/sql" "encoding/json" @@ -165,71 +166,17 @@ func (app *application) createVotes(w http.ResponseWriter, r *http.Request) { return } - // this snippet of code also inserts in the `voters` table - voterIdentity := func() string { - var voterIdentity string - if election.AreVotersKnown { - if request.VoterIdentity == nil || validator.Blank(*request.VoterIdentity) { - app.unprocessableEntityErrorSingle(w, fmt.Errorf("election has known voters; you must provide an identity provided by the organizer")) - return "" - } - - voterIdentity = *request.VoterIdentity - hasCastVotes, err := app.votes.Exists(voterIdentity, election.ID) - if err != nil { - app.serverError(w, r, err) - return "" - } - if hasCastVotes { - app.unprocessableEntityErrorSingle(w, fmt.Errorf("you already voted")) - return "" - } - - voterExists, err := app.voters.Exists(voterIdentity, election.ID) - if err != nil { - app.serverError(w, r, err) - return "" - } - if !voterExists { - app.unprocessableEntityErrorSingle(w, fmt.Errorf("invalid voter identity")) - return "" - } - } else { - voterIdentity = r.RemoteAddr - - // if voters are known, voter will always exist - voterExists, err := app.voters.Exists(voterIdentity, election.ID) - if err != nil { - app.serverError(w, r, err) - return "" - } - if voterExists { - app.unprocessableEntityErrorSingle(w, fmt.Errorf("you already voted")) - return "" - } - - _, err = app.voters.Insert(voterIdentity, election.ID) - if err != nil { - app.serverError(w, r, err) - return "" - } - } - return voterIdentity - }() - - if voterIdentity == "" { - return - } - - if !election.AreVotersKnown { - voterCount, err := app.voters.CountByElection(election.ID) - if err != nil && !errors.Is(sql.ErrNoRows, err) { - app.serverError(w, r, err) + var voterIdentity string + if election.AreVotersKnown { + voterIdentity, err = app.createVotesHandleKnownVotersElection(w, r, request, election) + if err != nil { + // everything will have been logged already return } - // if voters are known, voterCount == election.MaxVoters in all cases - if voterCount == election.MaxVoters { - app.unprocessableEntityErrorSingle(w, fmt.Errorf("maximum voters reached")) + } else { + voterIdentity, err = app.createVotesHandleUnknownVotersElection(w, r, election) + if err != nil { + // everything will have been logged already return } } @@ -243,3 +190,70 @@ func (app *application) createVotes(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) } + +func (app *application) createVotesHandleKnownVotersElection(w http.ResponseWriter, r *http.Request, request createVotesRequestWithValidator, election *models.Election) (string, error) { + if request.VoterIdentity == nil || validator.Blank(*request.VoterIdentity) { + err := fmt.Errorf("election has known voters; you must provide an identity provided by the organizer") + app.unprocessableEntityErrorSingle(w, err) + return "", err + } + + voterIdentity := *request.VoterIdentity + hasCastVotes, err := app.votes.Exists(voterIdentity, election.ID) + if err != nil { + app.serverError(w, r, err) + return "", err + } + if hasCastVotes { + err := fmt.Errorf("you already voted") + app.unprocessableEntityErrorSingle(w, err) + return "", err + } + + voterExists, err := app.voters.Exists(voterIdentity, election.ID) + if err != nil { + app.serverError(w, r, err) + return "", err + } + if !voterExists { + err := fmt.Errorf("invalid voter identity") + app.unprocessableEntityErrorSingle(w, err) + return "", err + } + + return voterIdentity, nil +} + +func (app *application) createVotesHandleUnknownVotersElection(w http.ResponseWriter, r *http.Request, election *models.Election) (string, error) { + voterIdentity := r.RemoteAddr + + voterExists, err := app.voters.Exists(voterIdentity, election.ID) + if err != nil { + app.serverError(w, r, err) + return "", err + } + if voterExists { + err := fmt.Errorf("you already voted") + app.unprocessableEntityErrorSingle(w, err) + return "", err + } + + _, err = app.voters.Insert(voterIdentity, election.ID) + if err != nil { + app.serverError(w, r, err) + return "", err + } + + voterCount, err := app.voters.CountByElection(election.ID) + if err != nil && !errors.Is(sql.ErrNoRows, err) { + app.serverError(w, r, err) + return "", err + } + if voterCount == election.MaxVoters { + err := fmt.Errorf("maximum voters reached") + app.unprocessableEntityErrorSingle(w, err) + return "", err + } + + return voterIdentity, nil +}