From c2941413e223ac7ef78399135879ec5760e77cc5 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Tue, 9 Apr 2024 15:47:01 +0200 Subject: [PATCH] [DigiTally] Fix bug related to missing votes --- DigiTallyTests/ReadBallotsTests.cs | 81 +++++++++++++++++++ DigiTallyTests/ReadBallotsTests_Weighted.cs | 32 ++++++++ .../Model/WeightedElectionModel.cs | 14 +++- 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/DigiTallyTests/ReadBallotsTests.cs b/DigiTallyTests/ReadBallotsTests.cs index 3718319..cd52a99 100644 --- a/DigiTallyTests/ReadBallotsTests.cs +++ b/DigiTallyTests/ReadBallotsTests.cs @@ -190,5 +190,86 @@ public void AddBallot_BothInvalid() Assert.That(election2.Key.BallotsProcessed, Is.EqualTo(1)); Assert.That(election2.Key.Invalid, Is.EqualTo(1)); } + + [Test] + public void GetResultString_Valid_OnlyOneNominee() + { + File.WriteAllText(_configFileName, @"[Wahlen] +Titel=The election +Wahl1=Election +Email=election@example.com +PublicKey=12345678.asc + +[Election] +Text=Some description +Typ=Weighted +FehlendOk=true +Stimmen=2 +Kandidat1=Mickey Mouse +"); + var ballotFileName = Path.GetTempFileName(); + File.WriteAllText(ballotFileName, "The election\r\n" + + "============\r\n" + + "\r\n" + + "Election\r\n" + + "--------\r\n" + + "(2 Stimmen; Wahl der Reihenfolge nach mit 1.-2. kennzeichnen)\r\n" + + "2. Mickey Mouse\r\n" + + "\r\n" + + "\r\n" + + "12345\r\n"); + _ballotFileNames.Add(ballotFileName); + var sut = new ReadBallots(_configFileName); + Assert.That(sut.AddBallot(ballotFileName), Is.True); + Assert.That(sut.NumberOfInvalidBallots, Is.EqualTo(0)); + + var election1 = sut.Results.First(); + Assert.That(election1.Key.BallotsProcessed, Is.EqualTo(1)); + Assert.That(election1.Key.Invalid, Is.EqualTo(0)); + Assert.That(sut.GetResultString(), Is.EqualTo(@"Election +-------- +1. Mickey Mouse (1 points) +(1 ballots, thereof 0 invalid) + +")); + } + + [Test] + public void GetResultString_Invalid_TwoNomineesOneVote() + { + File.WriteAllText(_configFileName, @"[Wahlen] +Titel=The election +Wahl1=Election +Email=election@example.com +PublicKey=12345678.asc + +[Election] +Text=Some description +Typ=Weighted +FehlendOk=false +Stimmen=2 +Kandidat1=Mickey Mouse +Kandidat2=Dagobert Duck +"); + var ballotFileName = Path.GetTempFileName(); + File.WriteAllText(ballotFileName, "The election\r\n" + + "============\r\n" + + "\r\n" + + "Election\r\n" + + "--------\r\n" + + "(2 Stimmen; Wahl der Reihenfolge nach mit 1.-2. kennzeichnen)\r\n" + + "2. Mickey Mouse\r\n" + + "\r\n" + + "\r\n" + + "12345\r\n"); + _ballotFileNames.Add(ballotFileName); + var sut = new ReadBallots(_configFileName); + Assert.That(sut.AddBallot(ballotFileName), Is.True); + Assert.That(sut.NumberOfInvalidBallots, Is.EqualTo(1)); + + var election1 = sut.Results.First(); + Assert.That(election1.Key.BallotsProcessed, Is.EqualTo(1)); + Assert.That(election1.Key.Invalid, Is.EqualTo(1)); + } } } \ No newline at end of file diff --git a/DigiTallyTests/ReadBallotsTests_Weighted.cs b/DigiTallyTests/ReadBallotsTests_Weighted.cs index 0322b83..7179787 100644 --- a/DigiTallyTests/ReadBallotsTests_Weighted.cs +++ b/DigiTallyTests/ReadBallotsTests_Weighted.cs @@ -340,6 +340,38 @@ Donald Duck (0 points) ")); } + + [Test] + public void GetResultString_Abstains() + { + var ballotFileName = Path.GetTempFileName(); + File.WriteAllText(ballotFileName, "The election\r\n" + + "============\r\n" + + "\r\n" + + "Election\r\n" + + "--------\r\n" + + "(2 Stimmen; Wahl der Reihenfolge nach mit 1.-2. kennzeichnen)\r\n" + + " Mickey Mouse\r\n" + + " Donald Duck\r\n" + + " Dagobert Duck\r\n" + + " Daisy Duck\r\n" + + "\r\n" + + "\r\n" + + "12345\r\n"); + _ballotFileNames.Add(ballotFileName); + var sut = new ReadBallots(_configFileName); + Assert.That(sut.AddBallot(ballotFileName), Is.True); + Assert.That(sut.GetResultString(), Is.EqualTo(@"Election +-------- + Dagobert Duck (0 points) + Daisy Duck (0 points) + Donald Duck (0 points) + Mickey Mouse (0 points) +(1 ballots, thereof 0 invalid) + +")); + } + } } \ No newline at end of file diff --git a/DigitaleBriefwahl/Model/WeightedElectionModel.cs b/DigitaleBriefwahl/Model/WeightedElectionModel.cs index 810e64e..2a55d1c 100644 --- a/DigitaleBriefwahl/Model/WeightedElectionModel.cs +++ b/DigitaleBriefwahl/Model/WeightedElectionModel.cs @@ -88,9 +88,12 @@ protected override Dictionary ReadVotesFromBallotIntern var nomineesSeen = new List(); var rankSeen = new List(); var invalid = false; + var lineCount = 0; for (var line = stream.ReadLine(); !string.IsNullOrEmpty(line); line = stream.ReadLine()) { + lineCount++; + // 1. Mickey Mouse CandidateResult res = null; var regex = new Regex("(([0-9]+).| ) (.+)"); @@ -143,7 +146,7 @@ protected override Dictionary ReadVotesFromBallotIntern } } - if (invalid) + if (invalid || (lineCount < Votes && !MissingOk )) { Invalid++; return null; @@ -154,15 +157,15 @@ protected override Dictionary ReadVotesFromBallotIntern private class FindIndexPredicate { - private string Name; + private readonly string _name; public FindIndexPredicate(string name) { - Name = name; + _name = name; } public bool Find(KeyValuePair kv) { - return kv.Key == Name; + return kv.Key == _name; } } @@ -189,6 +192,9 @@ private static int GetRank(List> results, candidate) { var index = results.FindIndex(new FindIndexPredicate(candidate).Find); + if (index < 0 || ((WeightedCandidateResult)results[index].Value).Points <= 0) + return Int32.MaxValue; + if (index > 0 && ((WeightedCandidateResult)results[index].Value).Points == ((WeightedCandidateResult)results[index-1].Value).Points) { return index;