def test_add_candidates(self, mock_db_manager, mock_candidatesmanager_add_candidates): processor = EventProcessor() payload = add_candidates # Case 1: voting already started ------------------------------------------------------------------------------- processor.started = "true" result = processor.command_add_candidates(payload) assert result == respond("VOTING ALREADY STARTED", 403) # -------------------------------------------------------------------------------------------------------------- # Case 2: voting not started yet, should call CandidatesManager.add_candidates() processor.started = "false" processor.admin_token = payload["administrator_token"] processor.command_add_candidates(payload) mock_candidatesmanager_add_candidates.assert_called_with( payload["candidates_to_add"]) mock_candidatesmanager_add_candidates.reset_mock() # -------------------------------------------------------------------------------------------------------------- # Case 3: voting not started yet, wrong token, should return the 403 response processor.started = "false" processor.admin_token = "abracadabra" response = processor.command_add_voters(payload) mock_candidatesmanager_add_candidates.assert_not_called() assert response == respond("WRONG TOKEN, COMMAND REJECTED", 403)
def test_lock(self, mock_db_manager, mock_dbmanager_set_parameter): processor = EventProcessor() processor.db_manager.set_parameter = mock_dbmanager_set_parameter payload = lock # Case 1: system already locked -------------------------------------------------------------------------------- processor.locked = "true" result = processor.command_lock(payload) assert result == respond("SYSTEM ALREADY LOCKED", 403) # -------------------------------------------------------------------------------------------------------------- # Case 2: system not locked, should call DynamoDBManager.set_parameter() --------------------------------------- processor.locked = "false" processor.admin_token = payload["administrator_token"] response = processor.command_lock(payload) processor.db_manager.set_parameter.assert_called() assert response == respond("SYSTEM LOCKED", 200) # -------------------------------------------------------------------------------------------------------------- # Case 3: wrong token, reject command -------------------------------------------------------------------------- processor.locked = "false" processor.admin_token = "abracadabra" response = processor.command_lock(payload) assert response == respond("WRONG TOKEN, COMMAND REJECTED", 403)
def command_lock(self, payload): if self.locked == "true": return respond("SYSTEM ALREADY LOCKED", 403) if payload["administrator_token"] == self.admin_token: self.db_manager.set_parameter(parameter="locked", value="true") return respond("SYSTEM LOCKED", 200) else: return respond("WRONG TOKEN, COMMAND REJECTED", 403)
def command_add_voters(self, payload): if self.started == "true": return respond("VOTING ALREADY STARTED", 403) if payload["administrator_token"] == self.admin_token: response = VotersManager.add_voters(payload["voters_to_add"]) return response else: return respond("WRONG TOKEN, COMMAND REJECTED", 403)
def command_start(self, payload): if self.locked == "false": return respond("LOCK THE SYSTEM FIRST", 403) if self.started == "true": return respond("VOTING ALREADY STARTED", 403) if payload["administrator_token"] == self.admin_token: self.db_manager.set_parameter(parameter="started", value="true") return respond("VOTING STARTED", 200) else: return respond("WRONG TOKEN, COMMAND REJECTED", 403)
def command_cast_vote(self, payload): if self.started != "true": return respond("VOTING NOT STARTED YET", 403) voter = self.db_manager.get_voter(id=payload["voter_id"]) if voter["token"] == payload["voter_token"] and voter[ "voted"] == "false": response = self.db_manager.add_vote( voter_id=payload["voter_id"], event_id=self.request_id, candidate=payload["candidate_full_name"]) return response else: return respond("WRONG TOKEN OR ALREADY VOTED, COMMAND REJECTED", 403)
def test_start(self, mock_db_manager, mock_dbmanager_set_parameter): processor = EventProcessor() processor.db_manager.set_parameter = mock_dbmanager_set_parameter payload = start # Case 1: system not locked ------------------------------------------------------------------------------------ processor.locked = "false" result = processor.command_start(payload) assert result == respond("LOCK THE SYSTEM FIRST", 403) # -------------------------------------------------------------------------------------------------------------- # Case 2: voting already started ------------------------------------------------------------------------------- processor.locked = "true" processor.started = "true" processor.admin_token = payload["administrator_token"] response = processor.command_start(payload) assert response == respond("VOTING ALREADY STARTED", 403) # -------------------------------------------------------------------------------------------------------------- # Case 3: start normally --------------------------------------------------------------------------------------- processor.locked = "true" processor.started = "false" processor.admin_token = payload["administrator_token"] response = processor.command_start(payload) processor.db_manager.set_parameter.assert_called() processor.db_manager.set_parameter.reset_mock() assert response == respond("VOTING STARTED", 200) # -------------------------------------------------------------------------------------------------------------- # Case 4: wrong token, reject command -------------------------------------------------------------------------- processor.locked = "true" processor.started = "false" processor.admin_token = "abracadabra" response = processor.command_start(payload) processor.db_manager.set_parameter.assert_not_called() processor.db_manager.set_parameter.reset_mock() assert response == respond("WRONG TOKEN, COMMAND REJECTED", 403)
def add_vote(self, voter_id, event_id, candidate): if not self.get_candidate(candidate): return respond( "NO SUCH CANDIDATE, PLEASE ENTER THE CORRECT FULL NAME", 404) # Set voted status to pending self.mark_voter(voter_id, "pending") try: self.mark_voter(voter_id, "true") response = self.votes_table.put_item(Item={ "event_id": event_id, "candidate": candidate }) email_client = boto3.client("ses", region_name="eu-west-1") sender_email = self.get_parameter("sender_email") voter_email = self.get_voter(voter_id)["email"] email_client.send_email( Source=sender_email, Destination={"ToAddresses": [ voter_email, ]}, Message={ "Subject": { "Data": "Successfuly voted!" }, "Body": { "Text": { "Data": "Congats! You've successfully voted for the candidate {candidate}!" .format(candidate=candidate) } } }) return respond( 'Congratulations! You have successfully cast your vote for the candidate {candidate}!' .format(candidate=candidate), 200) except Exception as e: self.mark_voter(voter_id, "false") return respond("ERROR, VOTE NOT CAST", 500)
def test_get_candidates(self, mock_db_manager): processor = EventProcessor() processor.db_manager.get_candidates = (lambda: "CALLED") payload = get_candidates # Case 1: voting not started yet ------------------------------------------------------------------------------- processor.started = "false" result = processor.command_get_candidates(payload) assert result == respond("VOTING NOT STARTED YET", 403) # -------------------------------------------------------------------------------------------------------------- # Case 2: voting started, should call DynamoDbManager.get_candidates() ----------------------------------------- processor.started = "true" response = processor.command_get_candidates(payload) assert response == respond("CALLED", 200)
def test_add_vote(self, mock_boto3_resource, mock_boto3_client): manager = DynamoDBManager() voter_id = "1337" event_id = "1111" candidate = "Person Personson" # Case 1: everything is normal --------------------------------------------------------------------------------- response = manager.add_vote(voter_id, event_id, candidate) assert response == respond( 'Congratulations! You have successfully cast your vote for the candidate {candidate}!' .format(candidate=candidate), 200) # -------------------------------------------------------------------------------------------------------------- # Case 2: no such candidate ------------------------------------------------------------------------------------ manager.get_candidate = (lambda candidate_name: None) response = manager.add_vote(voter_id, event_id, candidate) assert response == respond( "NO SUCH CANDIDATE, PLEASE ENTER THE CORRECT FULL NAME", 404)
def command_get_candidates(self, payload): # Note that no token is required for this command if self.started == "false": return respond("VOTING NOT STARTED YET", 403) return respond(str(self.db_manager.get_candidates()), 200)
def process_event(self, payload): event_type = self._determine_event(payload) if event_type != "UNKNOWN EVENT TYPE": return self._delegate_event(event_type, payload) else: return respond("EVENT VALIDATION FAILED", 400)
def test_cast_vote(self, mock_db_manager, mock_dbmanager_add_vote, mock_dbmanager_get_voter): processor = EventProcessor() processor.db_manager.get_voter = mock_dbmanager_get_voter processor.db_manager.add_vote = mock_dbmanager_add_vote processor.request_id = 1111 payload = cast_vote # Case 1: voting not started ----------------------------------------------------------------------------------- processor.started = "false" result = processor.command_cast_vote(payload) assert result == respond("VOTING NOT STARTED YET", 403) processor.db_manager.get_voter.assert_not_called() processor.db_manager.add_vote.assert_not_called() # -------------------------------------------------------------------------------------------------------------- # Case 2: cast vote normally ----------------------------------------------------------------------------------- processor.started = "true" processor.db_manager.get_voter.return_value = { "voted": "false", "token": payload["voter_token"] } processor.command_cast_vote(payload) processor.db_manager.get_voter.assert_called_with( id=payload["voter_id"]) processor.db_manager.add_vote.assert_called_with( voter_id=payload["voter_id"], event_id=processor.request_id, candidate=payload["candidate_full_name"]) processor.db_manager.get_voter.reset_mock() processor.db_manager.add_vote.reset_mock() # -------------------------------------------------------------------------------------------------------------- # Case 3: wrong token, rejected -------------------------------------------------------------------------------- processor.locked = "true" processor.started = "true" processor.db_manager.get_voter.return_value = { "voted": "false", "token": "actually a different token" } response = processor.command_cast_vote(payload) processor.db_manager.get_voter.assert_called_with( id=payload["voter_id"]) processor.db_manager.add_vote.assert_not_called() processor.db_manager.get_voter.reset_mock() processor.db_manager.add_vote.reset_mock() assert response == respond( "WRONG TOKEN OR ALREADY VOTED, COMMAND REJECTED", 403) # -------------------------------------------------------------------------------------------------------------- # Case 4: another vote being processed, rejected --------------------------------------------------------------- processor.locked = "true" processor.started = "true" processor.db_manager.get_voter.return_value = { "voted": "pending", "token": payload["voter_token"] } response = processor.command_cast_vote(payload) processor.db_manager.get_voter.assert_called_with( id=payload["voter_id"]) processor.db_manager.add_vote.assert_not_called() processor.db_manager.get_voter.reset_mock() processor.db_manager.add_vote.reset_mock() assert response == respond( "WRONG TOKEN OR ALREADY VOTED, COMMAND REJECTED", 403) # -------------------------------------------------------------------------------------------------------------- # Case 5: voter already voted ---------------------------------------------------------------------------------- processor.locked = "true" processor.started = "true" processor.db_manager.get_voter.return_value = { "voted": "true", "token": payload["voter_token"] } response = processor.command_cast_vote(payload) processor.db_manager.get_voter.assert_called_with( id=payload["voter_id"]) processor.db_manager.add_vote.assert_not_called() processor.db_manager.get_voter.reset_mock() processor.db_manager.add_vote.reset_mock() assert response == respond( "WRONG TOKEN OR ALREADY VOTED, COMMAND REJECTED", 403)