2024-12-28 17:58:01 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2025-01-01 19:47:55 +01:00
|
|
|
"code.dlmw.ch/dlmw/qv/internal"
|
2025-01-09 15:35:16 +01:00
|
|
|
"code.dlmw.ch/dlmw/qv/internal/models"
|
|
|
|
"database/sql"
|
2024-12-28 17:58:01 +01:00
|
|
|
"encoding/json"
|
2025-01-08 17:18:53 +01:00
|
|
|
"fmt"
|
2025-01-20 10:04:15 +01:00
|
|
|
"github.com/google/uuid"
|
2024-12-31 14:35:31 +01:00
|
|
|
"github.com/stretchr/testify/assert"
|
2025-01-08 17:18:53 +01:00
|
|
|
"github.com/stretchr/testify/mock"
|
2024-12-28 17:58:01 +01:00
|
|
|
"net/http"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
const baseUri = "/api/"
|
|
|
|
|
2024-12-28 17:58:01 +01:00
|
|
|
func TestCreateElection(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-08 17:18:53 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("Insert", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
2025-01-20 10:04:15 +01:00
|
|
|
Return(id.String(), nil)
|
2025-01-08 17:18:53 +01:00
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election"
|
2025-01-02 17:44:44 +01:00
|
|
|
|
2024-12-28 17:58:01 +01:00
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
urlPath string
|
2024-12-31 14:35:31 +01:00
|
|
|
body any
|
2024-12-28 17:58:01 +01:00
|
|
|
expectedCode int
|
|
|
|
}{
|
|
|
|
{
|
2024-12-31 14:35:31 +01:00
|
|
|
name: "Valid request (small name, other language)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"宮本武蔵", "伊東一刀斎"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 0,
|
|
|
|
Name: "強",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusOK,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Valid request (voters unknown with unlimited voters)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
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,
|
|
|
|
},
|
2025-01-01 19:47:55 +01:00
|
|
|
{
|
|
|
|
name: "Valid request (with 3 choices)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2025-01-01 19:47:55 +01:00
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"Gandhi", "Buddha", "You"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 0,
|
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusOK,
|
|
|
|
},
|
2024-12-31 14:35:31 +01:00
|
|
|
{
|
|
|
|
name: "Valid request (voters unknown with max voters)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: false,
|
2025-01-21 09:24:51 +01:00
|
|
|
MaxVoters: 1000,
|
2024-12-31 14:35:31 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusOK,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Valid request (voters known with max voters)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
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,
|
|
|
|
},
|
2024-12-28 17:58:01 +01:00
|
|
|
expectedCode: http.StatusOK,
|
2024-12-31 14:35:31 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request (not enough choices)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
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)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
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)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
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)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2024-12-31 14:35:31 +01:00
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
ExpiresAt: time.Unix(0, 0),
|
|
|
|
AreVotersKnown: true,
|
|
|
|
MaxVoters: 0,
|
|
|
|
Name: "",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
2024-12-28 17:58:01 +01:00
|
|
|
},
|
2025-01-01 19:47:55 +01:00
|
|
|
{
|
|
|
|
name: "Invalid request (choices are not unique)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2025-01-01 19:47:55 +01:00
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"Gandhi", "Gandhi"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 0,
|
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request (choices contain blank entries)",
|
2025-01-02 17:44:44 +01:00
|
|
|
urlPath: path,
|
2025-01-01 19:47:55 +01:00
|
|
|
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.StatusUnprocessableEntity,
|
|
|
|
},
|
2025-01-21 09:24:51 +01:00
|
|
|
{
|
|
|
|
name: "Invalid request for known voters election (max voters greater than 100)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateElectionRequest{
|
|
|
|
Choices: []string{"Gandhi", "Buddha", ""},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: true,
|
|
|
|
MaxVoters: 101,
|
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
2024-12-28 17:58:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2024-12-31 14:35:31 +01:00
|
|
|
requestBody, err := json.Marshal(tt.body)
|
2024-12-28 17:58:01 +01:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2024-12-31 14:35:31 +01:00
|
|
|
code, _, _ := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
|
|
|
assert.Equal(t, tt.expectedCode, code)
|
2024-12-28 17:58:01 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2025-01-08 17:18:53 +01:00
|
|
|
|
2025-01-17 14:49:51 +01:00
|
|
|
func TestCreateElection_KnownVoters(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
electionId, _ := uuid.NewV7()
|
2025-01-17 14:49:51 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("Insert", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
2025-01-20 10:04:15 +01:00
|
|
|
Return(electionId.String(), nil)
|
2025-01-17 14:49:51 +01:00
|
|
|
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("InsertMultiple", mock.Anything, mock.Anything).
|
|
|
|
Return([]int{1}, nil)
|
|
|
|
|
|
|
|
path := baseUri + "election"
|
|
|
|
requestBody := api.CreateElectionRequest{
|
|
|
|
Choices: []string{"宮本武蔵", "伊東一刀斎"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: true,
|
|
|
|
MaxVoters: 100,
|
|
|
|
Name: "強",
|
|
|
|
Tokens: 100,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, body := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, code)
|
|
|
|
|
|
|
|
var voterIdentities struct {
|
|
|
|
VoterIdentities []string
|
|
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(body), &voterIdentities)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Len(t, voterIdentities.VoterIdentities, 100)
|
|
|
|
}
|
|
|
|
|
2025-01-08 17:18:53 +01:00
|
|
|
func TestCreateElection_ServerError(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("Insert", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
|
|
|
Return(0, fmt.Errorf(""))
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election"
|
2025-01-08 17:18:53 +01:00
|
|
|
requestBody := api.CreateElectionRequest{
|
|
|
|
Choices: []string{"宮本武蔵", "伊東一刀斎"},
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 0,
|
|
|
|
Name: "強",
|
|
|
|
Tokens: 100,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
|
|
|
assert.Equal(t, 500, code)
|
|
|
|
}
|
2025-01-09 15:35:16 +01:00
|
|
|
|
2025-01-09 18:12:18 +01:00
|
|
|
func TestCreateVotes_UnknownVotersElection(t *testing.T) {
|
2025-01-09 15:35:16 +01:00
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-09 15:35:16 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return(&models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: id.String(),
|
2025-01-09 15:35:16 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 100,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}, nil)
|
|
|
|
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(false, nil)
|
|
|
|
mockVoters.
|
2025-01-13 20:06:55 +01:00
|
|
|
On("InsertMultiple", mock.Anything, mock.Anything).
|
|
|
|
Return([]int{1}, nil)
|
2025-01-09 15:35:16 +01:00
|
|
|
mockVoters.
|
|
|
|
On("CountByElection", mock.Anything).
|
|
|
|
Return(0, nil)
|
|
|
|
|
|
|
|
mockVotes := app.votes.(*mockVoteModel)
|
|
|
|
mockVotes.
|
|
|
|
On("Insert", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
|
|
|
Return(1, nil)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1/votes"
|
2025-01-09 15:35:16 +01:00
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
urlPath string
|
|
|
|
body any
|
|
|
|
expectedCode int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Valid request for unknown voters election",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusCreated,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (too many tokens used)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 41},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (choice doesn't exist)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddh", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
requestBody, err := json.Marshal(tt.body)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
|
|
|
assert.Equal(t, tt.expectedCode, code)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-09 18:12:18 +01:00
|
|
|
func TestCreateVotes_KnownVotersElection(t *testing.T) {
|
2025-01-09 15:35:16 +01:00
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-09 15:35:16 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return(&models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: id.String(),
|
2025-01-09 15:35:16 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: true,
|
|
|
|
MaxVoters: 100,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}, nil)
|
|
|
|
|
|
|
|
EXISTING_VOTER_IDENTITY := "EXISTING_VOTER_IDENTITY"
|
|
|
|
NON_EXISTING_VOTER_IDENTITY := "NON_EXISTING_VOTER_IDENTITY"
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", EXISTING_VOTER_IDENTITY, mock.Anything).
|
|
|
|
Return(true, nil)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", NON_EXISTING_VOTER_IDENTITY, mock.Anything).
|
|
|
|
Return(false, nil)
|
|
|
|
|
|
|
|
mockVotes := app.votes.(*mockVoteModel)
|
|
|
|
mockVotes.
|
|
|
|
On("Insert", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
|
|
|
|
Return(1, nil)
|
|
|
|
mockVotes.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(false, nil)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1/votes"
|
2025-01-09 15:35:16 +01:00
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
urlPath string
|
|
|
|
body any
|
|
|
|
expectedCode int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Valid request for unknown voters election",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: &EXISTING_VOTER_IDENTITY,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusCreated,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (non-existing voter identity)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: &NON_EXISTING_VOTER_IDENTITY,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
2025-01-09 18:12:18 +01:00
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (no voter identity provided)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
2025-01-09 15:35:16 +01:00
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (too many tokens used)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 41},
|
|
|
|
},
|
|
|
|
VoterIdentity: &EXISTING_VOTER_IDENTITY,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (choice doesn't exist)",
|
|
|
|
urlPath: path,
|
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddh", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: &EXISTING_VOTER_IDENTITY,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
requestBody, err := json.Marshal(tt.body)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
|
|
|
assert.Equal(t, tt.expectedCode, code)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCreateVotes_NonExistingElection(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return((*models.Election)(nil), sql.ErrNoRows)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1/votes"
|
2025-01-09 15:35:16 +01:00
|
|
|
requestBody := api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
2025-01-11 18:29:01 +01:00
|
|
|
assert.Equal(t, http.StatusNotFound, code)
|
|
|
|
}
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
func TestCreateVotes_NonUuidElectionID(t *testing.T) {
|
2025-01-11 18:29:01 +01:00
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return((*models.Election)(nil), sql.ErrNoRows)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1a/votes"
|
2025-01-11 18:29:01 +01:00
|
|
|
requestBody := api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
assert.Equal(t, http.StatusNotFound, code)
|
2025-01-09 15:35:16 +01:00
|
|
|
}
|
2025-01-09 18:12:18 +01:00
|
|
|
|
|
|
|
func TestCreateVotes_AlreadyVoted(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
unknownVotersElectionId, _ := uuid.NewV7()
|
2025-01-09 18:12:18 +01:00
|
|
|
unknownVotersElection := models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: unknownVotersElectionId.String(),
|
2025-01-09 18:12:18 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 10,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}
|
2025-01-20 10:04:15 +01:00
|
|
|
|
2025-01-09 18:12:18 +01:00
|
|
|
knownVotersElection := unknownVotersElection
|
2025-01-20 10:04:15 +01:00
|
|
|
knownVotersElectionId, _ := uuid.NewV7()
|
|
|
|
knownVotersElection.ID = knownVotersElectionId.String()
|
2025-01-09 18:12:18 +01:00
|
|
|
knownVotersElection.AreVotersKnown = true
|
|
|
|
|
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
2025-01-20 10:04:15 +01:00
|
|
|
On("GetById", knownVotersElectionId.String()).
|
2025-01-09 18:12:18 +01:00
|
|
|
Return(&knownVotersElection, nil)
|
|
|
|
mockElections.
|
2025-01-20 10:04:15 +01:00
|
|
|
On("GetById", unknownVotersElectionId.String()).
|
2025-01-09 18:12:18 +01:00
|
|
|
Return(&unknownVotersElection, nil)
|
|
|
|
|
|
|
|
mockVotes := app.votes.(*mockVoteModel)
|
|
|
|
mockVotes.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(true, nil)
|
|
|
|
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(true, nil)
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
layout := baseUri + "election/%v/votes"
|
|
|
|
knownVotersElectionPath := fmt.Sprintf(layout, unknownVotersElectionId)
|
|
|
|
unknownVotersElectionPath := fmt.Sprintf(layout, knownVotersElectionId)
|
2025-01-09 18:12:18 +01:00
|
|
|
voterIdentity := "anything"
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
urlPath string
|
|
|
|
body any
|
|
|
|
expectedCode int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "Invalid request for known voters election (already voted)",
|
2025-01-11 18:39:46 +01:00
|
|
|
urlPath: knownVotersElectionPath,
|
2025-01-09 18:12:18 +01:00
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: &voterIdentity,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Invalid request for unknown voters election (already voted)",
|
2025-01-11 18:39:46 +01:00
|
|
|
urlPath: unknownVotersElectionPath,
|
2025-01-09 18:12:18 +01:00
|
|
|
body: api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: &voterIdentity,
|
|
|
|
},
|
|
|
|
expectedCode: http.StatusUnprocessableEntity,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
requestBody, err := json.Marshal(tt.body)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, tt.urlPath, bytes.NewReader(requestBody))
|
|
|
|
assert.Equal(t, tt.expectedCode, code)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2025-01-09 18:22:58 +01:00
|
|
|
|
|
|
|
func TestCreateVotes_UnknownVotersElectionMaxVotersReached(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-09 18:22:58 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return(&models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: id.String(),
|
2025-01-09 18:22:58 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 10,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}, nil)
|
|
|
|
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(false, nil)
|
|
|
|
mockVoters.
|
2025-01-13 20:06:55 +01:00
|
|
|
On("InsertMultiple", mock.Anything, mock.Anything).
|
|
|
|
Return([]int{1}, nil)
|
2025-01-09 18:22:58 +01:00
|
|
|
mockVoters.
|
|
|
|
On("CountByElection", mock.Anything).
|
|
|
|
Return(10, nil)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1/votes"
|
2025-01-09 18:22:58 +01:00
|
|
|
requestBody := api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusUnprocessableEntity, code)
|
|
|
|
}
|
2025-01-09 18:26:22 +01:00
|
|
|
|
|
|
|
func TestCreateVotes_ExpiredElection(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-09 18:26:22 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return(&models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: id.String(),
|
2025-01-09 18:26:22 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 10,
|
|
|
|
CreatedAt: time.UnixMilli(1),
|
|
|
|
ExpiresAt: time.UnixMilli(100000),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}, nil)
|
|
|
|
|
|
|
|
mockVoters := app.voters.(*mockVoterModel)
|
|
|
|
mockVoters.
|
|
|
|
On("Exists", mock.Anything, mock.Anything).
|
|
|
|
Return(false, nil)
|
|
|
|
mockVoters.
|
|
|
|
On("Insert", mock.Anything, mock.Anything).
|
|
|
|
Return(1, nil)
|
|
|
|
mockVoters.
|
|
|
|
On("CountByElection", mock.Anything).
|
|
|
|
Return(10, nil)
|
|
|
|
|
2025-01-14 17:32:44 +01:00
|
|
|
path := baseUri + "election/1/votes"
|
2025-01-09 18:26:22 +01:00
|
|
|
requestBody := api.CreateVotesRequest{
|
|
|
|
Choices: []struct {
|
|
|
|
ChoiceText string `json:"choiceText"`
|
|
|
|
Tokens int `json:"tokens"`
|
|
|
|
}{
|
|
|
|
{ChoiceText: "Gandhi", Tokens: 60},
|
|
|
|
{ChoiceText: "Buddha", Tokens: 40},
|
|
|
|
},
|
|
|
|
VoterIdentity: nil,
|
|
|
|
}
|
|
|
|
requestBodyJson, err := json.Marshal(requestBody)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
code, _, _ := server.post(t, path, bytes.NewReader(requestBodyJson))
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusUnprocessableEntity, code)
|
|
|
|
}
|
2025-01-14 17:28:45 +01:00
|
|
|
|
|
|
|
func TestGetElectionResults(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
electionID, _ := uuid.NewV7()
|
2025-01-14 17:28:45 +01:00
|
|
|
votes := []models.Vote{
|
|
|
|
{
|
|
|
|
VoterIdentity: "Voter1",
|
2025-01-20 10:04:15 +01:00
|
|
|
ElectionID: electionID.String(),
|
2025-01-14 17:28:45 +01:00
|
|
|
ChoiceText: "Choice1",
|
|
|
|
Tokens: 2,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
VoterIdentity: "Voter2",
|
2025-01-20 10:04:15 +01:00
|
|
|
ElectionID: electionID.String(),
|
2025-01-14 17:28:45 +01:00
|
|
|
ChoiceText: "Choice2",
|
|
|
|
Tokens: 4,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
VoterIdentity: "Voter3",
|
2025-01-20 10:04:15 +01:00
|
|
|
ElectionID: electionID.String(),
|
2025-01-14 17:28:45 +01:00
|
|
|
ChoiceText: "Choice3",
|
|
|
|
Tokens: 6,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
VoterIdentity: "Voter4",
|
2025-01-20 10:04:15 +01:00
|
|
|
ElectionID: electionID.String(),
|
2025-01-14 17:28:45 +01:00
|
|
|
ChoiceText: "Choice1",
|
|
|
|
Tokens: 8,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
VoterIdentity: "Voter5",
|
2025-01-20 10:04:15 +01:00
|
|
|
ElectionID: electionID.String(),
|
2025-01-14 17:28:45 +01:00
|
|
|
ChoiceText: "Choice2",
|
|
|
|
Tokens: 10,
|
|
|
|
CreatedAt: time.Now(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
mockVotes := app.votes.(*mockVoteModel)
|
|
|
|
mockVotes.
|
2025-01-20 10:04:15 +01:00
|
|
|
On("GetByElection", electionID.String()).
|
2025-01-14 17:28:45 +01:00
|
|
|
Return(&votes, nil)
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
path := baseUri + fmt.Sprintf("election/%v/results", electionID)
|
2025-01-14 17:28:45 +01:00
|
|
|
code, _, body := server.get(t, path)
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, code)
|
|
|
|
|
|
|
|
var response api.ElectionResultsResponse
|
|
|
|
err := json.Unmarshal([]byte(body), &response)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, result := range *response.Results {
|
|
|
|
switch result.Choice {
|
|
|
|
case "Choice1":
|
|
|
|
assert.Equal(t, 3, result.Votes)
|
|
|
|
case "Choice2":
|
|
|
|
assert.Equal(t, 5, result.Votes)
|
|
|
|
case "Choice3":
|
|
|
|
assert.Equal(t, 2, result.Votes)
|
|
|
|
default:
|
|
|
|
t.Fatalf("Unexpected choice: %s", result.Choice)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2025-01-14 17:32:44 +01:00
|
|
|
|
2025-01-17 13:59:37 +01:00
|
|
|
func TestGetElectionResults_NotFound(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
mockVotes := app.votes.(*mockVoteModel)
|
|
|
|
mockVotes.
|
|
|
|
On("GetByElection", mock.Anything).
|
|
|
|
Return(&[]models.Vote{}, sql.ErrNoRows)
|
|
|
|
|
|
|
|
path := baseUri + "election/1/results"
|
|
|
|
code, _, body := server.get(t, path)
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusNotFound, code)
|
|
|
|
|
|
|
|
var response api.ElectionResultsResponse
|
|
|
|
err := json.Unmarshal([]byte(body), &response)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
2025-01-17 14:55:54 +01:00
|
|
|
|
|
|
|
func TestGetElection_Found(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
2025-01-20 10:04:15 +01:00
|
|
|
id, _ := uuid.NewV7()
|
2025-01-17 14:55:54 +01:00
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return(&models.Election{
|
2025-01-20 10:04:15 +01:00
|
|
|
ID: id.String(),
|
2025-01-17 14:55:54 +01:00
|
|
|
Name: "Guy of the year",
|
|
|
|
Tokens: 100,
|
|
|
|
AreVotersKnown: false,
|
|
|
|
MaxVoters: 10,
|
|
|
|
CreatedAt: time.UnixMilli(1),
|
|
|
|
ExpiresAt: time.UnixMilli(100000),
|
|
|
|
Choices: []string{"Gandhi", "Buddha"},
|
|
|
|
}, nil)
|
|
|
|
|
|
|
|
path := baseUri + "election/1"
|
|
|
|
code, _, _ := server.get(t, path)
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusOK, code)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetElection_NotFound(t *testing.T) {
|
|
|
|
app := newTestApplication(t)
|
|
|
|
server := newTestServer(t, app.routes())
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
mockElections := app.elections.(*mockElectionModel)
|
|
|
|
mockElections.
|
|
|
|
On("GetById", mock.Anything).
|
|
|
|
Return((*models.Election)(nil), sql.ErrNoRows)
|
|
|
|
|
|
|
|
path := baseUri + "election/1"
|
|
|
|
code, _, _ := server.get(t, path)
|
|
|
|
|
|
|
|
assert.Equal(t, http.StatusNotFound, code)
|
|
|
|
}
|