Refactor createVotes in two different functions (only for the part that was nested in ifs)
This commit is contained in:
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user