Add tests for createElection handler
This commit is contained in:
@ -4,22 +4,12 @@ import (
|
||||
"bytes"
|
||||
api "code.dlmw.ch/dlmw/qv/internal"
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
validCreateElectionRequest = api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: nil,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
} // TODO: try to find a way to generate test data
|
||||
)
|
||||
|
||||
func TestCreateElection(t *testing.T) {
|
||||
app := newTestApplication(t)
|
||||
server := newTestServer(t, app.routes())
|
||||
@ -28,27 +18,124 @@ func TestCreateElection(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
urlPath string
|
||||
body any
|
||||
expectedCode int
|
||||
expectedBody string
|
||||
}{
|
||||
{
|
||||
name: "Valid request",
|
||||
urlPath: "/election",
|
||||
name: "Valid request (small name, other language)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"宮本武蔵", "伊東一刀斎"},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 0,
|
||||
Name: "強",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
expectedBody: "",
|
||||
},
|
||||
{
|
||||
name: "Valid request (voters unknown with unlimited voters)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 0,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
name: "Valid request (voters unknown with max voters)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 10,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
name: "Valid request (voters known with max voters)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Now().Add(24 * time.Hour),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 10,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusOK,
|
||||
},
|
||||
{
|
||||
name: "Invalid request (not enough choices)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi"},
|
||||
ExpiresAt: time.Unix(0, 0),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 0,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusUnprocessableEntity,
|
||||
},
|
||||
{
|
||||
name: "Invalid request (expiresAt is not in the future)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Unix(0, 0),
|
||||
AreVotersKnown: false,
|
||||
MaxVoters: 0,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusUnprocessableEntity,
|
||||
},
|
||||
{
|
||||
name: "Invalid request (max voters must be greater than 0 for known elections)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Unix(0, 0),
|
||||
AreVotersKnown: true,
|
||||
MaxVoters: 0,
|
||||
Name: "Guy of the year",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusUnprocessableEntity,
|
||||
},
|
||||
{
|
||||
name: "Invalid request (blank name)",
|
||||
urlPath: "/election",
|
||||
body: api.CreateElectionRequest{
|
||||
Choices: []string{"Gandhi", "Buddha"},
|
||||
ExpiresAt: time.Unix(0, 0),
|
||||
AreVotersKnown: true,
|
||||
MaxVoters: 0,
|
||||
Name: "",
|
||||
Tokens: 100,
|
||||
},
|
||||
expectedCode: http.StatusUnprocessableEntity,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
requestBody, err := json.Marshal(validCreateElectionRequest)
|
||||
requestBody, err := json.Marshal(tt.body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
code, _, body := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
||||
|
||||
t.Logf("Code was %v and body %v", code, body)
|
||||
code, _, _ := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
||||
assert.Equal(t, tt.expectedCode, code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"code.dlmw.ch/dlmw/qv/internal/models"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newTestApplication(t *testing.T) *application {
|
||||
return &application{
|
||||
logger: slog.New(slog.NewTextHandler(io.Discard, nil)),
|
||||
elections: &models.ElectionModel{},
|
||||
elections: &mockElectionModel{},
|
||||
voters: &mockVoterModel{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,3 +40,17 @@ func (ts *testServer) post(t *testing.T, urlPath string, body io.Reader) (int, h
|
||||
|
||||
return res.StatusCode, res.Header, string(responseBody)
|
||||
}
|
||||
|
||||
type mockElectionModel struct {
|
||||
}
|
||||
|
||||
func (e *mockElectionModel) Insert(name string, tokens int, areVotersKnown bool, maxVoters int, choices []string, expiresAt time.Time) (int, error) {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
type mockVoterModel struct {
|
||||
}
|
||||
|
||||
func (v *mockVoterModel) Insert(identity string, electionID int) (int, error) {
|
||||
return 1, nil
|
||||
}
|
||||
|
8
go.mod
8
go.mod
@ -6,14 +6,14 @@ require (
|
||||
github.com/golang-migrate/migrate/v4 v4.18.1
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/stretchr/testify v1.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
gonum.org/v1/gonum v0.11.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
22
go.sum
22
go.sum
@ -1,12 +1,6 @@
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/form/v4 v4.2.1 h1:HjdRDKO0fftVMU5epjPW2SOREcZ6/wLUzEobqUGJuPw=
|
||||
github.com/go-playground/form/v4 v4.2.1/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
|
||||
github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
|
||||
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@ -18,31 +12,17 @@ github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo=
|
||||
github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25 h1:bnhGk2UFFPqylhxTEffs1ehDRn4bEZsEoDH53Z4HqA8=
|
||||
github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25/go.mod h1:RrGEZqqiyEcLyTVLDSgtNZVLqJykj0F4vwuuqvMdT60=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
||||
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gonum.org/v1/gonum v0.11.0 h1:f1IJhK4Km5tBJmaiJXtk/PkL4cdVX6J+tGiM187uT5E=
|
||||
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
Reference in New Issue
Block a user