Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring of contracts/evoting/types/ballots_test.go : #184

Merged
merged 5 commits into from
Oct 17, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 84 additions & 78 deletions contracts/evoting/types/ballots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,23 @@ import (
"github.com/stretchr/testify/require"
)

var ballot1 = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

var ballot2 = string("select:" + encodedQuestionID(1) + ":0,0,0\n" +
"rank:" + encodedQuestionID(2) + ":128,128,128,128\n" +
"select:" + encodedQuestionID(3) + ":0,0,0,0,0\n" +
"text:" + encodedQuestionID(4) + ":xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx," +
const SELECT_STR = "select:"
const RANK_STR = "rank:"
const TEXT_STR = "text:"
const UNMARSHALING_RANK_STR = "could not unmarshal rank answers: "
const UNMARSHALING_TEXT_STR = "could not unmarshal text answers: "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use camel case for constants as well. You can also declare them altogether since they're related, see PR #183 or contract/evoting.go for examples

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I think it would make sense and we will be able to use them in some functions in ballots.go such as unmarshal(...) or MaxEncodedSize(...). The only problem I can see is that the format is slightly different between the strings in the tests and the ones in ballots.go and that they are mostly recurrent in the tests.
Thanks for the note on the camel case convention, I have to get rid of my Java habits :)

Copy link
Contributor

@emduc emduc Oct 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean because of the : ? Since this is just formatting it does not have to be part of the string. It could be written as a join in the tests.
This might be overthinking it (although quite clean), but we could use the Question interface to force the Text/Rank/Select questions to re-define the "String()" function which would simply return "select"/"rank"/"text" and could be called everywhere. It would avoid redefining or hardcoding those strings everywhere. It's just an idea though ;).


var ballot1 = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

var ballot2 = string(SELECT_STR + encodedQuestionID(1) + ":0,0,0\n" +
RANK_STR + encodedQuestionID(2) + ":128,128,128,128\n" +
SELECT_STR + encodedQuestionID(3) + ":0,0,0,0,0\n" +
TEXT_STR + encodedQuestionID(4) + ":xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx," +
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n" +
"text:" + encodedQuestionID(5) + ":xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,,\n\n")
TEXT_STR + encodedQuestionID(5) + ":xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,,\n\n")

func encodedQuestionID(i int) ID {
return ID(base64.StdEncoding.EncodeToString([]byte("Q" + strconv.Itoa(i))))
Expand Down Expand Up @@ -105,28 +111,28 @@ func TestBallot_Unmarshal(t *testing.T) {
require.EqualError(t, err, "a line in the ballot has length != 3: x")

// with ID not encoded in base64
ballotWrongID := string("select:" + "aaa" + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongID := string(SELECT_STR + "aaa" + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

err = b.Unmarshal(ballotWrongID, election)
require.EqualError(t, err, "could not decode question ID: illegal base64 data at input byte 0")

// with question ID not from the election
ballotUnknownID := string("select:" + encodedQuestionID(0) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotUnknownID := string(SELECT_STR + encodedQuestionID(0) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

err = b.Unmarshal(ballotUnknownID, election)
require.EqualError(t, err, "wrong question ID: the question doesn't exist")

// with too many answers in select question
ballotWrongSelect := string("select:" + encodedQuestionID(1) + ":1,0,1,0,0\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongSelect := string(SELECT_STR + encodedQuestionID(1) + ":1,0,1,0,0\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongSelect)

Expand All @@ -136,10 +142,10 @@ func TestBallot_Unmarshal(t *testing.T) {
" of answers: expected 3 got 5")

// with wrong format answers in select question
ballotWrongSelect = string("select:" + encodedQuestionID(1) + ":1,0,wrong\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongSelect = string(SELECT_STR + encodedQuestionID(1) + ":1,0,wrong\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongSelect)

Expand All @@ -149,10 +155,10 @@ func TestBallot_Unmarshal(t *testing.T) {
"ParseBool: parsing \"wrong\": invalid syntax")

// with too many selected answers in select question
ballotWrongSelect = string("select:" + encodedQuestionID(1) + ":1,1,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongSelect = string(SELECT_STR + encodedQuestionID(1) + ":1,1,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongSelect)

Expand All @@ -161,10 +167,10 @@ func TestBallot_Unmarshal(t *testing.T) {
"failed to check number of answers: question Q1 has too many selected answers")

// with not enough selected answers in select question
ballotWrongSelect = string("select:" + encodedQuestionID(1) + ":1,0,0\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongSelect = string(SELECT_STR + encodedQuestionID(1) + ":1,0,0\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongSelect)

Expand All @@ -173,114 +179,114 @@ func TestBallot_Unmarshal(t *testing.T) {
"failed to check number of answers: question Q1 has not enough selected answers")

// with not enough answers in rank question
ballotWrongRank := string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongRank := string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: question"+
" Q2 has a wrong number of answers: expected 5 got 3")

// with wrong format answers in rank question
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,x,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongRank = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,x,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongRank)

err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
require.EqualError(t, err, UNMARSHALING_RANK_STR+
"could not parse rank value for Q.Q2: strconv.ParseInt: parsing \"x\": invalid syntax")

// with too many selected answers in rank question
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,3,4\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongRank = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,3,4\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongRank)

err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
require.EqualError(t, err, UNMARSHALING_RANK_STR+
"invalid rank not in range [0, MaxN[: 3")

// with valid ranks but one is selected twice
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,2,2\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongRank = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,2,2\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongRank)

err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
require.EqualError(t, err, UNMARSHALING_RANK_STR+
"failed to check number of answers: question Q2 has too many selected answers")

// with not enough selected answers in rank question
ballotWrongRank = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongRank = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongRank)

err = b.Unmarshal(ballotWrongRank, election)
require.EqualError(t, err, "could not unmarshal rank answers: "+
require.EqualError(t, err, UNMARSHALING_RANK_STR+
"failed to check number of answers: question"+
" Q2 has not enough selected answers")

// with not enough answers in text question
ballotWrongText := string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":Y2VzdG1vaUVtaQ==\n\n")
ballotWrongText := string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongText)

err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
require.EqualError(t, err, UNMARSHALING_TEXT_STR+
"question Q4 has a wrong number of answers: expected 2 got 1")

// with wrong encoding in text question
ballotWrongText = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":wrongEncoding,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongText = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":wrongEncoding,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongText)

err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
require.EqualError(t, err, UNMARSHALING_TEXT_STR+
"could not decode text for Q.Q4: illegal base64 data at input byte 12")

// with too many selected answers in text question
election.Configuration.Scaffold[0].Texts[0].MaxN = 1

ballotWrongText = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongText = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":YmxhYmxhYmxhZg==,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongText)

err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
require.EqualError(t, err, UNMARSHALING_TEXT_STR+
"failed to check number of answers: question Q4 has too many selected answers")

election.Configuration.Scaffold[0].Texts[0].MaxN = 2

// with not enough elected answers in text question
ballotWrongText = string("select:" + encodedQuestionID(1) + ":1,0,1\n" +
"rank:" + encodedQuestionID(2) + ":1,2,0,,\n" +
"select:" + encodedQuestionID(3) + ":1,0,1,1\n" +
"text:" + encodedQuestionID(4) + ":,Y2VzdG1vaUVtaQ==\n\n")
ballotWrongText = string(SELECT_STR + encodedQuestionID(1) + ":1,0,1\n" +
RANK_STR + encodedQuestionID(2) + ":1,2,0,,\n" +
SELECT_STR + encodedQuestionID(3) + ":1,0,1,1\n" +
TEXT_STR + encodedQuestionID(4) + ":,Y2VzdG1vaUVtaQ==\n\n")

election.BallotSize = len(ballotWrongText)

err = b.Unmarshal(ballotWrongText, election)
require.EqualError(t, err, "could not unmarshal text answers: "+
require.EqualError(t, err, UNMARSHALING_TEXT_STR+
"failed to check number of answers: question Q4 has not enough selected answers")

// with unknown question type
Expand Down