Introduced NominationId as key for maps

This commit is contained in:
2023-07-13 19:44:51 +02:00
parent b2fee57f9e
commit aa533f6c72
16 changed files with 176 additions and 72 deletions
@@ -1,10 +1,12 @@
package de.twomartens.wahlrecht.mapper.v1; package de.twomartens.wahlrecht.mapper.v1;
import de.twomartens.wahlrecht.model.dto.v1.ElectedCandidate; import de.twomartens.wahlrecht.model.dto.v1.ElectedCandidate;
import de.twomartens.wahlrecht.model.dto.v1.VotingResult; import de.twomartens.wahlrecht.model.dto.v1.NominationId;
import de.twomartens.wahlrecht.model.internal.ElectedResult; import de.twomartens.wahlrecht.model.internal.ElectedResult;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValueCheckStrategy;
@@ -17,19 +19,19 @@ public interface ElectedResultMapper {
de.twomartens.wahlrecht.model.dto.v1.ElectedResult mapToExternal(ElectedResult result); de.twomartens.wahlrecht.model.dto.v1.ElectedResult mapToExternal(ElectedResult result);
Map<VotingResult, Collection<ElectedCandidate>> mapToExternal( Map<NominationId, Collection<ElectedCandidate>> mapToExternal(
Map<de.twomartens.wahlrecht.model.internal.VotingResult, Map<de.twomartens.wahlrecht.model.internal.NominationId,
Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate>> value); Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate>> value);
Collection<ElectedCandidate> mapToExternal( Collection<ElectedCandidate> mapToExternal(
Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate> value); Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate> value);
ElectedResult mapToInternal(de.twomartens.wahlrecht.model.dto.v1.ElectedResult result); default Map<de.twomartens.wahlrecht.model.internal.NominationId,
Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate>> map(
Map<de.twomartens.wahlrecht.model.internal.VotingResult, Map<de.twomartens.wahlrecht.model.internal.VotingResult,
Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate>> mapToInternal( Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate>> value) {
Map<VotingResult, Collection<ElectedCandidate>> value); return value.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey().getNominationId(), Entry::getValue));
Collection<de.twomartens.wahlrecht.model.internal.ElectedCandidate> mapToInternal( }
Collection<ElectedCandidate> value);
} }
@@ -0,0 +1,14 @@
package de.twomartens.wahlrecht.mapper.v1;
import de.twomartens.wahlrecht.model.dto.v1.NominationId;
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.NullValueCheckStrategy;
import org.mapstruct.ReportingPolicy;
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface NominationIdMapper {
NominationId mapToExternal(de.twomartens.wahlrecht.model.internal.NominationId id);
}
@@ -2,6 +2,7 @@ package de.twomartens.wahlrecht.mapper.v1;
import de.twomartens.wahlrecht.model.db.Nomination; import de.twomartens.wahlrecht.model.db.Nomination;
import de.twomartens.wahlrecht.model.internal.Candidate; import de.twomartens.wahlrecht.model.internal.Candidate;
import de.twomartens.wahlrecht.model.internal.NominationId;
import java.util.Collection; import java.util.Collection;
import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
@@ -16,15 +17,35 @@ public interface NominationMapper {
de.twomartens.wahlrecht.model.dto.v1.Nomination mapToExternal(Nomination nomination); de.twomartens.wahlrecht.model.dto.v1.Nomination mapToExternal(Nomination nomination);
de.twomartens.wahlrecht.model.internal.Nomination mapToInternal( default de.twomartens.wahlrecht.model.internal.Nomination mapToInternal(
de.twomartens.wahlrecht.model.dto.v1.Nomination nomination); de.twomartens.wahlrecht.model.dto.v1.Nomination nomination) {
de.twomartens.wahlrecht.model.internal.Nomination result =
new de.twomartens.wahlrecht.model.internal.Nomination(
new NominationId(nomination.getElectionName(), nomination.getPartyAbbreviation(),
nomination.getName()),
nomination.isSupportVotesOnNomination()
);
result.addCandidates(mapFromDto(nomination.getCandidates()));
return result;
}
de.twomartens.wahlrecht.model.internal.Nomination mapToInternal(Nomination nomination); default de.twomartens.wahlrecht.model.internal.Nomination mapToInternal(Nomination nomination) {
de.twomartens.wahlrecht.model.internal.Nomination result =
new de.twomartens.wahlrecht.model.internal.Nomination(
new NominationId(nomination.getElectionName(), nomination.getPartyAbbreviation(),
nomination.getName()),
nomination.isSupportVotesOnNomination()
);
result.addCandidates(mapFromDb(nomination.getCandidates()));
return result;
}
@Mapping(target = "id", ignore = true) @Mapping(target = "id", ignore = true)
@Mapping(target = "created", ignore = true) @Mapping(target = "created", ignore = true)
@Mapping(target = "lastModified", ignore = true) @Mapping(target = "lastModified", ignore = true)
Nomination mapToDB(de.twomartens.wahlrecht.model.dto.v1.Nomination nomination); Nomination mapToDB(de.twomartens.wahlrecht.model.dto.v1.Nomination nomination);
Collection<Candidate> map(Collection<de.twomartens.wahlrecht.model.db.Candidate> candidates); Collection<Candidate> mapFromDb(Collection<de.twomartens.wahlrecht.model.db.Candidate> candidates);
Collection<Candidate> mapFromDto(Collection<de.twomartens.wahlrecht.model.dto.v1.Candidate> candidates);
} }
@@ -1,5 +1,6 @@
package de.twomartens.wahlrecht.mapper.v1; package de.twomartens.wahlrecht.mapper.v1;
import de.twomartens.wahlrecht.model.internal.NominationId;
import de.twomartens.wahlrecht.model.internal.VotingResult; import de.twomartens.wahlrecht.model.internal.VotingResult;
import org.mapstruct.CollectionMappingStrategy; import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
@@ -11,7 +12,24 @@ import org.mapstruct.ReportingPolicy;
unmappedTargetPolicy = ReportingPolicy.IGNORE) unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface VotingResultMapper { public interface VotingResultMapper {
de.twomartens.wahlrecht.model.dto.v1.VotingResult mapToExternal(VotingResult result); default de.twomartens.wahlrecht.model.dto.v1.VotingResult mapToExternal(VotingResult result) {
return new de.twomartens.wahlrecht.model.dto.v1.VotingResult(
VotingResult mapToInternal(de.twomartens.wahlrecht.model.dto.v1.VotingResult result); result.getNominationId().electionName(),
result.getNominationId().partyAbbreviation(),
result.getNominationId().name(),
result.getVotesOnNomination(),
result.getVotesThroughHealing(),
result.getVotesPerPosition()
);
}
default VotingResult mapToInternal(de.twomartens.wahlrecht.model.dto.v1.VotingResult result) {
return new VotingResult(
new NominationId(result.electionName(), result.partyAbbreviation(),
result.nominationName()),
result.votesOnNomination(),
result.votesThroughHealing(),
result.votesPerPosition()
);
}
} }
@@ -1,12 +1,13 @@
package de.twomartens.wahlrecht.model.dto.v1; package de.twomartens.wahlrecht.model.dto.v1;
import de.twomartens.wahlrecht.model.internal.NominationId;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
import lombok.Builder; import lombok.Builder;
@Builder @Builder
public record ElectedResult(Map<VotingResult, Collection<ElectedCandidate>> electedCandidates, public record ElectedResult(Map<NominationId, Collection<ElectedCandidate>> electedCandidates,
LinkedList<Double> usedElectionNumbers) { LinkedList<Double> usedElectionNumbers) {
} }
@@ -0,0 +1,5 @@
package de.twomartens.wahlrecht.model.dto.v1;
public record NominationId(String electionName, String partyAbbreviation, String name) {
}
@@ -17,6 +17,7 @@ import org.springframework.lang.NonNull;
@ToString(onlyExplicitlyIncluded = true) @ToString(onlyExplicitlyIncluded = true)
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class PartyInElection { public class PartyInElection {
String electionName; String electionName;
@Include @Include
String abbreviation; String abbreviation;
@@ -2,7 +2,8 @@ package de.twomartens.wahlrecht.model.dto.v1;
import java.util.Map; import java.util.Map;
public record VotingResult(int votesOnNomination, int votesThroughHealing, Integer totalVotes, public record VotingResult(String electionName, String partyAbbreviation, String nominationName,
Map<Integer, Integer> votesPerPosition, String nominationName) { int votesOnNomination, int votesThroughHealing,
Map<Integer, Integer> votesPerPosition) {
} }
@@ -11,9 +11,9 @@ import lombok.Builder;
public record ElectedResult(Map<VotingResult, Collection<ElectedCandidate>> electedCandidates, public record ElectedResult(Map<VotingResult, Collection<ElectedCandidate>> electedCandidates,
LinkedList<Double> usedElectionNumbers) { LinkedList<Double> usedElectionNumbers) {
public Map<Nomination, Collection<ElectedCandidate>> electedCandidatesByNomination() { public Map<NominationId, Collection<ElectedCandidate>> electedCandidatesByNomination() {
return electedCandidates.entrySet().stream() return electedCandidates.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey().getNomination(), Entry::getValue)); .collect(Collectors.toMap(entry -> entry.getKey().getNominationId(), Entry::getValue));
} }
} }
@@ -6,18 +6,13 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.ToString.Include;
@RequiredArgsConstructor @RequiredArgsConstructor
@ToString(onlyExplicitlyIncluded = true)
public class Nomination { public class Nomination {
@Getter
private final String electionName; private final NominationId id;
private final String partyAbbreviation;
@Include
private final String name;
private final boolean supportVotesOnNomination; private final boolean supportVotesOnNomination;
private final List<Candidate> candidates = new ArrayList<>(); private final List<Candidate> candidates = new ArrayList<>();
private final Map<Candidate, Integer> candidateToPosition = new HashMap<>(); private final Map<Candidate, Integer> candidateToPosition = new HashMap<>();
@@ -52,4 +47,9 @@ public class Nomination {
public boolean supportsVotesOnNomination() { public boolean supportsVotesOnNomination() {
return supportVotesOnNomination; return supportVotesOnNomination;
} }
@Override
public String toString() {
return id.name();
}
} }
@@ -10,8 +10,8 @@ import lombok.Builder;
public record SeatResult(Map<VotingResult, Integer> seatsPerResult, public record SeatResult(Map<VotingResult, Integer> seatsPerResult,
LinkedList<Double> usedElectionNumbers) { LinkedList<Double> usedElectionNumbers) {
public Map<Nomination, Integer> seatsPerNomination() { public Map<NominationId, Integer> seatsPerNomination() {
return seatsPerResult.entrySet().stream() return seatsPerResult.entrySet().stream()
.collect(Collectors.toMap(entry -> entry.getKey().getNomination(), Entry::getValue)); .collect(Collectors.toMap(entry -> entry.getKey().getNominationId(), Entry::getValue));
} }
} }
@@ -7,19 +7,19 @@ import lombok.Getter;
@Getter @Getter
public class VotingResult { public class VotingResult {
private final NominationId nominationId;
private final int votesOnNomination; private final int votesOnNomination;
private final int votesThroughHealing; private final int votesThroughHealing;
private final Map<Integer, Integer> votesPerPosition; private final Map<Integer, Integer> votesPerPosition;
private final Nomination nomination;
private Integer totalVotes = null; private Integer totalVotes = null;
@Builder @Builder
public VotingResult(int votesOnNomination, int votesThroughHealing, public VotingResult(NominationId nominationId, int votesOnNomination, int votesThroughHealing,
Map<Integer, Integer> votesPerPosition, Nomination nomination) { Map<Integer, Integer> votesPerPosition) {
this.votesOnNomination = votesOnNomination; this.votesOnNomination = votesOnNomination;
this.votesThroughHealing = votesThroughHealing; this.votesThroughHealing = votesThroughHealing;
this.votesPerPosition = votesPerPosition; this.votesPerPosition = votesPerPosition;
this.nomination = nomination; this.nominationId = nominationId;
} }
public int getTotalVotes() { public int getTotalVotes() {
@@ -7,6 +7,7 @@ import de.twomartens.wahlrecht.model.internal.ElectedCandidate;
import de.twomartens.wahlrecht.model.internal.ElectedResult; import de.twomartens.wahlrecht.model.internal.ElectedResult;
import de.twomartens.wahlrecht.model.internal.Election; import de.twomartens.wahlrecht.model.internal.Election;
import de.twomartens.wahlrecht.model.internal.Nomination; import de.twomartens.wahlrecht.model.internal.Nomination;
import de.twomartens.wahlrecht.model.internal.NominationId;
import de.twomartens.wahlrecht.model.internal.SeatResult; import de.twomartens.wahlrecht.model.internal.SeatResult;
import de.twomartens.wahlrecht.model.internal.VotingResult; import de.twomartens.wahlrecht.model.internal.VotingResult;
import java.util.ArrayList; import java.util.ArrayList;
@@ -20,14 +21,20 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@RequiredArgsConstructor
@Service @Service
public class CalculationService { public class CalculationService {
private final NominationService nominationService;
private final LinkedList<Double> electionNumberHistory = new LinkedList<>(); private final LinkedList<Double> electionNumberHistory = new LinkedList<>();
public ElectedResult calculateConstituency(@NonNull Constituency constituency, public ElectedResult calculateConstituency(@NonNull Constituency constituency,
@NonNull Collection<VotingResult> votingResults) { @NonNull Collection<VotingResult> votingResults) {
electionNumberHistory.clear(); electionNumberHistory.clear();
@@ -127,7 +134,8 @@ public class CalculationService {
Map<Candidate, ElectedCandidate> electedCandidateMap = alreadyElectedCandidates.stream() Map<Candidate, ElectedCandidate> electedCandidateMap = alreadyElectedCandidates.stream()
.collect(Collectors.toMap(ElectedCandidate::candidate, Function.identity())); .collect(Collectors.toMap(ElectedCandidate::candidate, Function.identity()));
Nomination nomination = votingResult.getNomination(); NominationId nominationId = votingResult.getNominationId();
Nomination nomination = nominationService.getNominationInternal(nominationId);
if (nomination.supportsVotesOnNomination()) { if (nomination.supportsVotesOnNomination()) {
int seatsByNomination = calculateSeatsByNominationOrder(votingResult, numberOfSeats); int seatsByNomination = calculateSeatsByNominationOrder(votingResult, numberOfSeats);
seatsByVoteOrder = numberOfSeats - seatsByNomination; seatsByVoteOrder = numberOfSeats - seatsByNomination;
@@ -1,5 +1,6 @@
package de.twomartens.wahlrecht.service; package de.twomartens.wahlrecht.service;
import de.twomartens.wahlrecht.mapper.v1.NominationMapper;
import de.twomartens.wahlrecht.model.db.Candidate; import de.twomartens.wahlrecht.model.db.Candidate;
import de.twomartens.wahlrecht.model.db.Nomination; import de.twomartens.wahlrecht.model.db.Nomination;
import de.twomartens.wahlrecht.model.internal.NominationId; import de.twomartens.wahlrecht.model.internal.NominationId;
@@ -10,16 +11,29 @@ import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.mapstruct.factory.Mappers;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
public class NominationService { public class NominationService {
private final NominationMapper mapper = Mappers.getMapper(NominationMapper.class);
private final NominationRepository repository; private final NominationRepository repository;
private final CandidateService candidateService; private final CandidateService candidateService;
private Map<NominationId, Nomination> nominations; private Map<NominationId, Nomination> nominations;
public Nomination getNomination(NominationId id) {
if (nominations == null) {
fetchNominations();
}
return nominations.get(id);
}
public de.twomartens.wahlrecht.model.internal.Nomination getNominationInternal(NominationId id) {
return mapper.mapToInternal(getNomination(id));
}
public Nomination storeNomination(Nomination nomination) { public Nomination storeNomination(Nomination nomination) {
if (nomination == null) { if (nomination == null) {
return null; return null;
@@ -1,5 +1,7 @@
package de.twomartens.wahlrecht.service; package de.twomartens.wahlrecht.service;
import static org.mockito.Mockito.when;
import de.twomartens.wahlrecht.model.internal.Candidate; import de.twomartens.wahlrecht.model.internal.Candidate;
import de.twomartens.wahlrecht.model.internal.Constituency; import de.twomartens.wahlrecht.model.internal.Constituency;
import de.twomartens.wahlrecht.model.internal.Elected; import de.twomartens.wahlrecht.model.internal.Elected;
@@ -7,6 +9,7 @@ import de.twomartens.wahlrecht.model.internal.ElectedCandidate;
import de.twomartens.wahlrecht.model.internal.ElectedResult; import de.twomartens.wahlrecht.model.internal.ElectedResult;
import de.twomartens.wahlrecht.model.internal.Election; import de.twomartens.wahlrecht.model.internal.Election;
import de.twomartens.wahlrecht.model.internal.Nomination; import de.twomartens.wahlrecht.model.internal.Nomination;
import de.twomartens.wahlrecht.model.internal.NominationId;
import de.twomartens.wahlrecht.model.internal.SeatResult; import de.twomartens.wahlrecht.model.internal.SeatResult;
import de.twomartens.wahlrecht.model.internal.VotingResult; import de.twomartens.wahlrecht.model.internal.VotingResult;
import de.twomartens.wahlrecht.model.internal.VotingThreshold; import de.twomartens.wahlrecht.model.internal.VotingThreshold;
@@ -23,8 +26,12 @@ import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.lang.NonNull; import org.springframework.lang.NonNull;
@ExtendWith(MockitoExtension.class)
class CalculationServiceTest { class CalculationServiceTest {
private static final String BEZIRKSWAHL = "Bezirkswahl 2019"; private static final String BEZIRKSWAHL = "Bezirkswahl 2019";
@@ -106,6 +113,9 @@ class CalculationServiceTest {
871, 1907, 987); 871, 1907, 987);
private CalculationService service; private CalculationService service;
@Mock
private NominationService nominationService;
@BeforeAll @BeforeAll
static void setUp() { static void setUp() {
setUpCandidatesConstituency(); setUpCandidatesConstituency();
@@ -152,7 +162,7 @@ class CalculationServiceTest {
.votesThroughHealing(votesThroughHealing) .votesThroughHealing(votesThroughHealing)
.votesOnNomination(votesOnNomination) .votesOnNomination(votesOnNomination)
.votesPerPosition(buildVotesPerPosition(votes)) .votesPerPosition(buildVotesPerPosition(votes))
.nomination(nomination) .nominationId(nomination.getId())
.build(); .build();
} }
@@ -223,7 +233,8 @@ class CalculationServiceTest {
private static Nomination buildNomination(String partyAbbreviation, private static Nomination buildNomination(String partyAbbreviation,
String name, boolean supportVotesOnNomination) { String name, boolean supportVotesOnNomination) {
return new Nomination(BEZIRKSWAHL, partyAbbreviation, name, supportVotesOnNomination); return new Nomination(new NominationId(BEZIRKSWAHL, partyAbbreviation, name),
supportVotesOnNomination);
} }
private static Collection<Candidate> buildCandidates(String... names) { private static Collection<Candidate> buildCandidates(String... names) {
@@ -239,7 +250,7 @@ class CalculationServiceTest {
@BeforeEach @BeforeEach
void setService() { void setService() {
service = new CalculationService(); service = new CalculationService(nominationService);
} }
@Test @Test
@@ -252,16 +263,18 @@ class CalculationServiceTest {
FDP_NIENDORF_RESULT, FDP_NIENDORF_RESULT,
AFD_NIENDORF_RESULT AFD_NIENDORF_RESULT
); );
when(nominationService.getNominationInternal(SPD_NIENDORF.getId())).thenReturn(SPD_NIENDORF);
when(nominationService.getNominationInternal(CDU_NIENDORF.getId())).thenReturn(CDU_NIENDORF);
when(nominationService.getNominationInternal(GRUENE_NIENDORF.getId())).thenReturn(GRUENE_NIENDORF);
ElectedResult elected = service.calculateConstituency(NIENDORF, votingResults); ElectedResult elected = service.calculateConstituency(NIENDORF, votingResults);
Assertions.assertThat(elected.electedCandidatesByNomination()) Assertions.assertThat(elected.electedCandidatesByNomination())
.containsKey(SPD_NIENDORF) .containsKey(SPD_NIENDORF.getId())
.containsKey(CDU_NIENDORF) .containsKey(CDU_NIENDORF.getId())
.containsKey(GRUENE_NIENDORF) .containsKey(GRUENE_NIENDORF.getId())
.doesNotContainKey(LINKE_NIENDORF) .doesNotContainKey(LINKE_NIENDORF.getId())
.doesNotContainKey(AFD_NIENDORF) .doesNotContainKey(AFD_NIENDORF.getId())
.doesNotContainKey(FDP_NIENDORF); .doesNotContainKey(FDP_NIENDORF.getId());
} }
@Test @Test
@@ -285,12 +298,12 @@ class CalculationServiceTest {
SeatResult result = service.calculateOverallSeatDistribution(election, votingResults); SeatResult result = service.calculateOverallSeatDistribution(election, votingResults);
Assertions.assertThat(result.seatsPerNomination()) Assertions.assertThat(result.seatsPerNomination())
.containsEntry(SPD_BEZIRK, 12) .containsEntry(SPD_BEZIRK.getId(), 12)
.containsEntry(CDU_BEZIRK, 9) .containsEntry(CDU_BEZIRK.getId(), 9)
.containsEntry(LINKE_BEZIRK, 5) .containsEntry(LINKE_BEZIRK.getId(), 5)
.containsEntry(FDP_BEZIRK, 3) .containsEntry(FDP_BEZIRK.getId(), 3)
.containsEntry(GRUENE_BEZIRK, 19) .containsEntry(GRUENE_BEZIRK.getId(), 19)
.containsEntry(AFD_BEZIRK, 3); .containsEntry(AFD_BEZIRK.getId(), 3);
} }
@Test @Test
@@ -304,29 +317,35 @@ class CalculationServiceTest {
AFD_BEZIRK_RESULT, 3 AFD_BEZIRK_RESULT, 3
); );
Map<VotingResult, Collection<ElectedCandidate>> electedCandidates = setUpConstituencyResults(); Map<VotingResult, Collection<ElectedCandidate>> electedCandidates = setUpConstituencyResults();
when(nominationService.getNominationInternal(SPD_BEZIRK.getId())).thenReturn(SPD_BEZIRK);
when(nominationService.getNominationInternal(CDU_BEZIRK.getId())).thenReturn(CDU_BEZIRK);
when(nominationService.getNominationInternal(FDP_BEZIRK.getId())).thenReturn(FDP_BEZIRK);
when(nominationService.getNominationInternal(GRUENE_BEZIRK.getId())).thenReturn(GRUENE_BEZIRK);
when(nominationService.getNominationInternal(LINKE_BEZIRK.getId())).thenReturn(LINKE_BEZIRK);
when(nominationService.getNominationInternal(AFD_BEZIRK.getId())).thenReturn(AFD_BEZIRK);
ElectedResult result = service.calculateElectedOverallCandidates(seatsPerVotingResult, ElectedResult result = service.calculateElectedOverallCandidates(seatsPerVotingResult,
electedCandidates); electedCandidates);
Assertions.assertThat(result.electedCandidatesByNomination()) Assertions.assertThat(result.electedCandidatesByNomination())
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(SPD_BEZIRK); Assertions.assertThat(id).isEqualTo(SPD_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(GOTTLIEB_GABOR) .anyMatch(candidate -> candidate.name().equals(GOTTLIEB_GABOR)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)
.anyMatch(candidate -> candidate.name().equals(RIEGEL_ANN_KATHRIN) .anyMatch(candidate -> candidate.name().equals(RIEGEL_ANN_KATHRIN)
&& candidate.elected() == Elected.OVERALL_VOTE_ORDER); && candidate.elected() == Elected.OVERALL_VOTE_ORDER);
}) })
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(CDU_BEZIRK); Assertions.assertThat(id).isEqualTo(CDU_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(HOEFLICH_JUTTA) .anyMatch(candidate -> candidate.name().equals(HOEFLICH_JUTTA)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)
.anyMatch(candidate -> candidate.name().equals(DR_LANGHEIN_A_W_HEINRICH) .anyMatch(candidate -> candidate.name().equals(DR_LANGHEIN_A_W_HEINRICH)
&& candidate.elected() == Elected.OVERALL_VOTE_ORDER); && candidate.elected() == Elected.OVERALL_VOTE_ORDER);
}) })
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(LINKE_BEZIRK); Assertions.assertThat(id).isEqualTo(LINKE_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(PAGELS_MANUELA) .anyMatch(candidate -> candidate.name().equals(PAGELS_MANUELA)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)
@@ -335,8 +354,8 @@ class CalculationServiceTest {
.anyMatch(candidate -> candidate.name().equals(KLEINERT_MIKEY) .anyMatch(candidate -> candidate.name().equals(KLEINERT_MIKEY)
&& candidate.elected() == Elected.OVERALL_VOTE_ORDER); && candidate.elected() == Elected.OVERALL_VOTE_ORDER);
}) })
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(FDP_BEZIRK); Assertions.assertThat(id).isEqualTo(FDP_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(KRUEGER_KLAUS) .anyMatch(candidate -> candidate.name().equals(KRUEGER_KLAUS)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)
@@ -345,8 +364,8 @@ class CalculationServiceTest {
.anyMatch(candidate -> candidate.name().equals(MUELLER_SOENKSEN_BURKHARDT) .anyMatch(candidate -> candidate.name().equals(MUELLER_SOENKSEN_BURKHARDT)
&& candidate.elected() == Elected.OVERALL_VOTE_ORDER); && candidate.elected() == Elected.OVERALL_VOTE_ORDER);
}) })
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(AFD_BEZIRK); Assertions.assertThat(id).isEqualTo(AFD_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(SCHOEMER_DIRK) .anyMatch(candidate -> candidate.name().equals(SCHOEMER_DIRK)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)
@@ -355,8 +374,8 @@ class CalculationServiceTest {
.anyMatch(candidate -> candidate.name().equals(PILLATZKE_JOERG) .anyMatch(candidate -> candidate.name().equals(PILLATZKE_JOERG)
&& candidate.elected() == Elected.OVERALL_VOTE_ORDER); && candidate.elected() == Elected.OVERALL_VOTE_ORDER);
}) })
.anySatisfy((nomination, candidates) -> { .anySatisfy((id, candidates) -> {
Assertions.assertThat(nomination).isEqualTo(GRUENE_BEZIRK); Assertions.assertThat(id).isEqualTo(GRUENE_BEZIRK.getId());
Assertions.assertThat(candidates) Assertions.assertThat(candidates)
.anyMatch(candidate -> candidate.name().equals(KUHLMANN_DIETMAR) .anyMatch(candidate -> candidate.name().equals(KUHLMANN_DIETMAR)
&& candidate.elected() == Elected.OVERALL_NOMINATION_ORDER) && candidate.elected() == Elected.OVERALL_NOMINATION_ORDER)