-
Notifications
You must be signed in to change notification settings - Fork 12
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
Feature/refactor can modify vote to validator service #334
Open
szirbucz
wants to merge
3
commits into
edemo:develop
Choose a base branch
from
szirbucz:feature/refactor_can_modify_vote_to_validator_service
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
src/main/java/org/rulez/demokracia/pdengine/choice/ChoiceModificationValidatorService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.rulez.demokracia.pdengine.choice; | ||
|
||
import org.rulez.demokracia.pdengine.dataobjects.VoteAdminInfo; | ||
import org.rulez.demokracia.pdengine.vote.Vote; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public interface ChoiceModificationValidatorService { | ||
|
||
void validateModification( | ||
VoteAdminInfo voteAdminInfo, Vote vote, Choice choice | ||
); | ||
|
||
void validateDeletion(VoteAdminInfo voteAdminInfo, Vote vote, Choice choice); | ||
|
||
} |
68 changes: 68 additions & 0 deletions
68
...ain/java/org/rulez/demokracia/pdengine/choice/ChoiceModificationValidatorServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.rulez.demokracia.pdengine.choice; | ||
|
||
import org.rulez.demokracia.pdengine.authentication.AuthenticatedUserService; | ||
import org.rulez.demokracia.pdengine.dataobjects.VoteAdminInfo; | ||
import org.rulez.demokracia.pdengine.exception.ReportedException; | ||
import org.rulez.demokracia.pdengine.vote.Vote; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class ChoiceModificationValidatorServiceImpl | ||
implements ChoiceModificationValidatorService { | ||
|
||
private static final String MODIFICATION = "modification"; | ||
private static final String DELETION = "deletion"; | ||
private static final String CAN_ADDIN_IS_FALSE_MESSAGE = | ||
"Choice %s disallowed: adminKey is user, but canAddin is false"; | ||
private static final String DIFFERENT_USER_MESSAGE = | ||
"Choice %s disallowed: adminKey is user, and the choice was added by a different user"; | ||
@Autowired | ||
private AuthenticatedUserService authenticationService; | ||
|
||
@Override | ||
public void validateModification( | ||
final VoteAdminInfo voteAdminInfo, final Vote vote, final Choice choice | ||
) { | ||
validate(voteAdminInfo, vote, choice, MODIFICATION); | ||
} | ||
|
||
@Override | ||
public void validateDeletion( | ||
final VoteAdminInfo voteAdminInfo, final Vote vote, final Choice choice | ||
) { | ||
validate(voteAdminInfo, vote, choice, DELETION); | ||
} | ||
|
||
private void validate( | ||
final VoteAdminInfo voteAdminInfo, | ||
final Vote vote, | ||
final Choice choice, | ||
final String operation | ||
) { | ||
if (voteAdminInfo.isUserAdminKey()) { | ||
validateAddinability(vote, operation); | ||
validateMatchingUser(choice, operation); | ||
} | ||
} | ||
|
||
private void | ||
validateMatchingUser(final Choice choice, final String operation) { | ||
if (!choice.getUserName().equals(getUserName())) | ||
throw new ReportedException( | ||
String.format(DIFFERENT_USER_MESSAGE, operation) | ||
); | ||
} | ||
|
||
private void validateAddinability(final Vote vote, final String operation) { | ||
if (!vote.getParameters().isAddinable()) | ||
throw new ReportedException( | ||
String.format(CAN_ADDIN_IS_FALSE_MESSAGE, operation) | ||
); | ||
} | ||
|
||
private String getUserName() { | ||
return authenticationService.getAuthenticatedUserName(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package org.rulez.demokracia.pdengine.choice; | ||
|
||
import static org.mockito.Mockito.*; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
@@ -9,12 +10,17 @@ | |
import org.rulez.demokracia.pdengine.annotations.TestedFeature; | ||
import org.rulez.demokracia.pdengine.annotations.TestedOperation; | ||
import org.rulez.demokracia.pdengine.dataobjects.VoteAdminInfo; | ||
import org.rulez.demokracia.pdengine.exception.ReportedException; | ||
|
||
@TestedFeature("Manage votes") | ||
@TestedOperation("delete choice") | ||
@RunWith(MockitoJUnitRunner.class) | ||
public class ChoiceDeleteAdminKeyIsUserTest extends ChoiceTestBase { | ||
|
||
private static final String NOT_SAME_USER_MESSAGE = | ||
"The adminKey is \"user\" but the user is not same with that user who added the choice."; | ||
private static final String CAN_ADDIN_IS_FALSE_MESSAGE = | ||
"The adminKey is \"user\" but canAddin is false."; | ||
private static final String IF_THE_VOTE_HAS_BALLOTS_ISSUED = | ||
"if the vote has ballots issued, the choice cannot be deleted"; | ||
private static final String IF_USER_IS_USED_AS_ADMIN_KEY = | ||
|
@@ -33,52 +39,84 @@ public void setUp() { | |
@Test | ||
public void if_canAddin_is_false_then_other_users_cannot_delete_choices() { | ||
final Choice choiceToDelete = createChoice(TEST_USER_NAME, false); | ||
when(authService.getAuthenticatedUserName()).thenReturn(TEST_USER_NAME); | ||
assertThrows(() -> choiceService.deleteChoice(new VoteAdminInfo(vote.getId(), USER), | ||
choiceToDelete.getId())).assertMessageIs("The adminKey is \"user\" but canAddin is false."); | ||
final VoteAdminInfo voteAdminInfo = new VoteAdminInfo(vote.getId(), USER); | ||
doThrow(new ReportedException(CAN_ADDIN_IS_FALSE_MESSAGE)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Service stub, should be put into a stub provider. |
||
.when(choiceModificationValidatorService) | ||
.validateDeletion(voteAdminInfo, vote, choiceToDelete); | ||
assertThrows( | ||
() -> choiceService.deleteChoice( | ||
voteAdminInfo, | ||
choiceToDelete.getId() | ||
) | ||
).assertMessageIs("The adminKey is \"user\" but canAddin is false."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once a java constant, once an inline constant. |
||
} | ||
|
||
@TestedBehaviour(IF_USER_IS_USED_AS_ADMIN_KEY) | ||
@Test | ||
public void if_adminKey_is_user_and_the_user_is_not_the_one_who_added_the_choice_then_the_choice_cannot_be_deleted() { | ||
public void | ||
if_adminKey_is_user_and_the_user_is_not_the_one_who_added_the_choice_then_the_choice_cannot_be_deleted() { | ||
final Choice choiceToDelete = createChoice(USER, true); | ||
assertThrows(() -> choiceService.deleteChoice(new VoteAdminInfo(vote.getId(), USER), | ||
choiceToDelete.getId())).assertMessageIs( | ||
"The adminKey is \"user\" but the user is not same with that user who added the choice."); | ||
final VoteAdminInfo voteAdminInfo = new VoteAdminInfo(vote.getId(), USER); | ||
|
||
doThrow(new ReportedException(NOT_SAME_USER_MESSAGE)) | ||
.when(choiceModificationValidatorService) | ||
.validateDeletion(voteAdminInfo, vote, choiceToDelete); | ||
|
||
assertThrows( | ||
() -> { | ||
choiceService.deleteChoice( | ||
voteAdminInfo, | ||
choiceToDelete.getId() | ||
); | ||
} | ||
).assertMessageIs( | ||
NOT_SAME_USER_MESSAGE | ||
|
||
); | ||
} | ||
|
||
@TestedBehaviour(IF_USER_IS_USED_AS_ADMIN_KEY) | ||
@Test | ||
public void if_adminKey_is_user_and_canAddin_is_true_then_the_user_who_added_the_choice_is_able_to_delete_it() { | ||
public void | ||
if_adminKey_is_user_and_canAddin_is_true_then_the_user_who_added_the_choice_is_able_to_delete_it() { | ||
final Choice choiceToDelete = createChoice(TEST_USER_NAME, true); | ||
when(authService.getAuthenticatedUserName()).thenReturn(TEST_USER_NAME); | ||
choiceService.deleteChoice(new VoteAdminInfo(vote.getId(), USER), choiceToDelete.getId()); | ||
choiceService.deleteChoice( | ||
new VoteAdminInfo(vote.getId(), USER), choiceToDelete.getId() | ||
); | ||
|
||
assertThrows(() -> choiceService.getChoice(vote.getId(), choiceToDelete.getId())) | ||
assertThrows( | ||
() -> choiceService.getChoice(vote.getId(), choiceToDelete.getId()) | ||
) | ||
.assertMessageIs("Illegal choiceId"); | ||
} | ||
|
||
@TestedBehaviour(IF_USER_IS_USED_AS_ADMIN_KEY) | ||
@Test | ||
public void deleteChoice_saves_vote_if_the_choice_is_deleted() { | ||
final Choice choiceToDelete = createChoice(TEST_USER_NAME, true); | ||
when(authService.getAuthenticatedUserName()).thenReturn(TEST_USER_NAME); | ||
choiceService.deleteChoice(new VoteAdminInfo(vote.getId(), USER), choiceToDelete.getId()); | ||
|
||
choiceService.deleteChoice( | ||
new VoteAdminInfo(vote.getId(), USER), choiceToDelete.getId() | ||
); | ||
verify(voteService).saveVote(vote); | ||
} | ||
|
||
@TestedBehaviour(IF_THE_VOTE_HAS_BALLOTS_ISSUED) | ||
@Test | ||
public void if_the_vote_has_issued_ballots_then_the_choice_cannot_be_deleted() { | ||
public void | ||
if_the_vote_has_issued_ballots_then_the_choice_cannot_be_deleted() { | ||
final Choice choiceToDelete = createChoice(TEST_USER_NAME, true); | ||
vote.getBallots().add("TestBallot"); | ||
|
||
assertThrows(() -> choiceService | ||
.deleteChoice(new VoteAdminInfo(vote.getId(), vote.getAdminKey()), choiceToDelete.getId())) | ||
.assertMessageIs("Vote modification disallowed: ballots already issued"); | ||
assertThrows( | ||
() -> choiceService | ||
.deleteChoice(new VoteAdminInfo(vote.getId(), vote.getAdminKey()), choiceToDelete.getId()) | ||
) | ||
.assertMessageIs("Vote modification disallowed: ballots already issued"); | ||
} | ||
|
||
private Choice createChoice(final String userName, final boolean isAddinable) { | ||
private Choice | ||
createChoice(final String userName, final boolean isAddinable) { | ||
vote.getParameters().setAddinable(isAddinable); | ||
final Choice choiceToDelete = new Choice(CHOICE1, userName); | ||
vote.addChoice(choiceToDelete); | ||
|
62 changes: 62 additions & 0 deletions
62
src/test/java/org/rulez/demokracia/pdengine/choice/ChoiceDeleteValidatorServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.rulez.demokracia.pdengine.choice; | ||
|
||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.mockito.junit.MockitoJUnitRunner; | ||
import org.rulez.demokracia.pdengine.annotations.TestedBehaviour; | ||
import org.rulez.demokracia.pdengine.annotations.TestedFeature; | ||
import org.rulez.demokracia.pdengine.annotations.TestedOperation; | ||
|
||
@TestedFeature("Manage votes") | ||
@TestedOperation("delete choice") | ||
@RunWith(MockitoJUnitRunner.class) | ||
public class ChoiceDeleteValidatorServiceTest extends ChoiceValidatorBaseTest { | ||
|
||
@Test | ||
@TestedBehaviour( | ||
"if 'user' is used as adminKey, then the user must be the one who added the choice and canAddIn be true" | ||
) | ||
public void userAdmin_cannot_delete_choice_if_canAddin_is_false() { | ||
assertFalseCanAddinCauseException( | ||
() -> underTest.validateDeletion(getUserAdminInfo(), vote, choice) | ||
); | ||
} | ||
|
||
@TestedBehaviour("modifies the string of the choice") | ||
@Test | ||
public void proper_voteId_choiceId_and_adminKey_does_modify_choice() { | ||
assertNotThrows( | ||
() -> { | ||
underTest.validateDeletion(getAdminInfo(), vote, choice); | ||
} | ||
); | ||
} | ||
|
||
@TestedBehaviour( | ||
"if 'user' is used as adminKey, then the user must be the one who added the choice and canAddIn be true" | ||
) | ||
@Test | ||
public void | ||
userAdmin_cannot_modify_choice_if_it_is_not_added_by_other_user() { | ||
assertDifferentUserCauseException( | ||
() -> underTest.validateDeletion(getUserAdminInfo(), vote, choice) | ||
); | ||
} | ||
|
||
@TestedBehaviour( | ||
"if 'user' is used as adminKey, then the user must be the one who added the choice and canAddIn be true" | ||
) | ||
@Test | ||
public void | ||
userAdmin_can_modify_the_choice_if_canAddin_is_true_and_he_is_the_choice_creator() { | ||
assertNoExceptionWithCorrectParameters( | ||
() -> underTest.validateDeletion(getUserAdminInfo(), vote, choice2) | ||
); | ||
} | ||
|
||
@Override | ||
protected String getOperation() { | ||
return "deletion"; | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't those strings are constants in the production code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are. If you mean, we should use constants of the production code, I suggest to forget it.
Let's imagine the situation, when someone accidentally removes some words from this string or an unlucky regex overwrites it. We wouldn't realize it, since we compare this constant to itself.