Skip to content

Commit 3b4f05a

Browse files
committed
Enable voting for very old accounts with few valid games
(e.g. single player fanatics). Lex Uveso
1 parent 1292b21 commit 3b4f05a

3 files changed

Lines changed: 65 additions & 17 deletions

File tree

src/main/java/com/faforever/api/voting/VotingService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
@Service
2626
@RequiredArgsConstructor
2727
public class VotingService {
28+
public static final int ACCOUNT_AGE_YEARS_VOTE_QUALIFIED = 3;
2829
private final VoteRepository voteRepository;
2930
private final VotingSubjectRepository votingSubjectRepository;
3031
private final GamePlayerStatsRepository gamePlayerStatsRepository;
@@ -100,7 +101,9 @@ private List<Error> ableToVote(Player player, int votingSubjectId) {
100101
errors.add(new Error(ErrorCode.VOTE_ALREADY_ENDED, subject.getEndOfVoteTime()));
101102
}
102103

103-
if (gamesPlayed < subject.getMinGamesToVote()) {
104+
boolean accountQualifiedBySteamAndAge = player.getSteamId() != null && OffsetDateTime.now().minusYears(ACCOUNT_AGE_YEARS_VOTE_QUALIFIED).isAfter(player.getCreateTime());
105+
106+
if (!accountQualifiedBySteamAndAge && gamesPlayed < subject.getMinGamesToVote()) {
104107
errors.add(new Error(ErrorCode.NOT_ENOUGH_GAMES, gamesPlayed, subject.getMinGamesToVote()));
105108
}
106109
return errors;

src/test/java/com/faforever/api/error/ApiExceptionMatcher.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
import java.util.Arrays;
77

88
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
9+
import static org.hamcrest.Matchers.hasItemInArray;
910

1011
public final class ApiExceptionMatcher {
1112

1213
public static Matcher<ApiException> hasErrorCodes(ErrorCode... errorCodes) {
13-
return new FeatureMatcher<ApiException, ErrorCode[]>(arrayContainingInAnyOrder(errorCodes), "error codes", "error codes") {
14+
return new FeatureMatcher<>(arrayContainingInAnyOrder(errorCodes), "error codes", "error codes") {
1415
@Override
1516
protected ErrorCode[] featureValueOf(ApiException actual) {
1617
return Arrays.stream(actual.getErrors())
@@ -21,7 +22,7 @@ protected ErrorCode[] featureValueOf(ApiException actual) {
2122
}
2223

2324
public static Matcher<ApiException> hasErrorCode(ErrorCode errorCode) {
24-
return new FeatureMatcher<ApiException, ErrorCode[]>(arrayContainingInAnyOrder(errorCode), "error code", "error code") {
25+
return new FeatureMatcher<>(hasItemInArray(errorCode), "error code", "error code") {
2526
@Override
2627
protected ErrorCode[] featureValueOf(ApiException actual) {
2728
return Arrays.stream(actual.getErrors())

src/test/java/com/faforever/api/voting/VotingServiceTest.java

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@
1616
import org.mockito.junit.jupiter.MockitoExtension;
1717

1818
import java.time.OffsetDateTime;
19-
import java.util.Arrays;
19+
import java.time.temporal.ChronoUnit;
2020
import java.util.Optional;
2121
import java.util.Set;
2222

2323
import static com.faforever.api.error.ApiExceptionMatcher.hasErrorCode;
2424
import static org.hamcrest.MatcherAssert.assertThat;
2525
import static org.junit.jupiter.api.Assertions.assertThrows;
26-
import static org.junit.jupiter.api.Assertions.assertTrue;
2726
import static org.mockito.ArgumentMatchers.anyInt;
2827
import static org.mockito.Mockito.never;
2928
import static org.mockito.Mockito.verify;
@@ -102,7 +101,7 @@ public void notSaveVoteIfUserVotedAlready() {
102101
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
103102

104103
ApiException result = assertThrows(ApiException.class, () -> instance.saveVote(vote, player));
105-
assertTrue(Arrays.stream(result.getErrors()).anyMatch(error -> error.getErrorCode().equals(ErrorCode.VOTED_TWICE)));
104+
assertThat(result, hasErrorCode(ErrorCode.VOTED_TWICE));
106105

107106
verify(voteRepository, never()).save(vote);
108107
}
@@ -176,7 +175,6 @@ public void saveVoteInvalidChoiceId() {
176175
when(voteRepository.findByPlayerAndVotingSubjectId(player, votingSubject.getId())).thenReturn(Optional.empty());
177176
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
178177

179-
180178
ApiException result = assertThrows(ApiException.class, () -> instance.saveVote(vote, player));
181179
assertThat(result, hasErrorCode(ErrorCode.VOTING_CHOICE_DOES_NOT_EXIST));
182180

@@ -219,11 +217,9 @@ public void notSaveVoteIfAlternativeOrdinalWrong() {
219217
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
220218
when(votingChoiceRepository.findById(anyInt())).thenReturn(Optional.of(votingChoice)).thenReturn(Optional.of(votingChoice2));
221219

222-
try {
223-
instance.saveVote(vote, player);
224-
} catch (ApiException e) {
225-
assertTrue(Arrays.stream(e.getErrors()).anyMatch(error -> error.getErrorCode().equals(ErrorCode.MALFORMATTED_ALTERNATIVE_ORDINALS)));
226-
}
220+
ApiException result = assertThrows(ApiException.class, () -> instance.saveVote(vote, player));
221+
assertThat(result, hasErrorCode(ErrorCode.MALFORMATTED_ALTERNATIVE_ORDINALS));
222+
227223
verify(voteRepository, never()).save(vote);
228224
}
229225

@@ -261,11 +257,59 @@ public void notSaveVoteOnTooManyAnswers() {
261257
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
262258
when(votingChoiceRepository.findById(anyInt())).thenReturn(Optional.of(votingChoice)).thenReturn(Optional.of(votingChoice2));
263259

264-
try {
265-
instance.saveVote(vote, player);
266-
} catch (ApiException e) {
267-
assertTrue(Arrays.stream(e.getErrors()).anyMatch(error -> error.getErrorCode().equals(ErrorCode.TOO_MANY_ANSWERS)));
268-
}
260+
ApiException result = assertThrows(ApiException.class, () -> instance.saveVote(vote, player));
261+
assertThat(result, hasErrorCode(ErrorCode.TOO_MANY_ANSWERS));
262+
263+
verify(voteRepository, never()).save(vote);
264+
}
265+
266+
@Test
267+
public void notSaveVoteOnNotEnoughGames() {
268+
Vote vote = new Vote();
269+
VotingSubject votingSubject = new VotingSubject();
270+
votingSubject.setId(1);
271+
votingSubject.setBeginOfVoteTime(OffsetDateTime.now());
272+
votingSubject.setEndOfVoteTime(OffsetDateTime.MAX);
273+
VotingQuestion votingQuestion = new VotingQuestion();
274+
votingQuestion.setAlternativeQuestion(false);
275+
votingQuestion.setMaxAnswers(1);
276+
votingSubject.setVotingQuestions(Set.of(votingQuestion));
277+
votingSubject.setMinGamesToVote(100);
278+
279+
vote.setVotingSubject(votingSubject);
280+
Player player = new Player();
281+
282+
when(voteRepository.findByPlayerAndVotingSubjectId(player, votingSubject.getId())).thenReturn(Optional.empty());
283+
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
284+
285+
ApiException result = assertThrows(ApiException.class, () -> instance.saveVote(vote, player));
286+
assertThat(result, hasErrorCode(ErrorCode.NOT_ENOUGH_GAMES));
287+
269288
verify(voteRepository, never()).save(vote);
270289
}
290+
291+
@Test
292+
public void saveVoteOnNotEnoughGamesButSteamLinkAndAccountAge() {
293+
Vote vote = new Vote();
294+
VotingSubject votingSubject = new VotingSubject();
295+
votingSubject.setId(1);
296+
votingSubject.setBeginOfVoteTime(OffsetDateTime.now());
297+
votingSubject.setEndOfVoteTime(OffsetDateTime.MAX);
298+
VotingQuestion votingQuestion = new VotingQuestion();
299+
votingQuestion.setAlternativeQuestion(false);
300+
votingQuestion.setMaxAnswers(1);
301+
votingSubject.setVotingQuestions(Set.of(votingQuestion));
302+
votingSubject.setMinGamesToVote(100);
303+
304+
vote.setVotingSubject(votingSubject);
305+
Player player = new Player();
306+
player.setSteamId("someSteamId");
307+
player.setCreateTime(OffsetDateTime.now().minus(5, ChronoUnit.YEARS));
308+
309+
when(voteRepository.findByPlayerAndVotingSubjectId(player, votingSubject.getId())).thenReturn(Optional.empty());
310+
when(votingSubjectRepository.findById(votingSubject.getId())).thenReturn(Optional.of(votingSubject));
311+
312+
instance.saveVote(vote, player);
313+
verify(voteRepository).save(vote);
314+
}
271315
}

0 commit comments

Comments
 (0)