From a2ddcf07c4ab6e5f99254d3dbcf2817c65182288 Mon Sep 17 00:00:00 2001 From: Will O'Beirne Date: Tue, 5 Feb 2019 06:17:07 -0500 Subject: [PATCH] Mock requests where needed. Come up with a function that mocks all blockchain requests. --- backend/grant/proposal/models.py | 1 + backend/tests/admin/test_api.py | 8 +-- backend/tests/config.py | 4 +- backend/tests/proposal/test_api.py | 51 ++++++++++++++----- .../tests/proposal/test_contribution_api.py | 14 ++--- backend/tests/test_data.py | 16 ++++++ 6 files changed, 65 insertions(+), 29 deletions(-) diff --git a/backend/grant/proposal/models.py b/backend/grant/proposal/models.py index 7a348e06..49e8e8da 100644 --- a/backend/grant/proposal/models.py +++ b/backend/grant/proposal/models.py @@ -214,6 +214,7 @@ class Proposal(db.Model): # Check with node that the address is kosher res = blockchain_get('/validate/address', {'address': self.payout_address}) + print(res) if not res['valid']: raise ValidationException("Payout address is not a valid Zcash address") diff --git a/backend/tests/admin/test_api.py b/backend/tests/admin/test_api.py index 02345475..e6f8a068 100644 --- a/backend/tests/admin/test_api.py +++ b/backend/tests/admin/test_api.py @@ -3,7 +3,7 @@ from grant.utils.admin import generate_admin_password_hash from mock import patch from ..config import BaseProposalCreatorConfig -from ..mocks import mock_request +from ..test_data import mock_blockchain_api_requests plaintext_mock_password = "p4ssw0rd" @@ -96,7 +96,8 @@ class TestAdminAPI(BaseProposalCreatorConfig): resp = self.app.put(f"/api/v1/admin/proposals/{self.proposal.id}", data={"contributionMatching": 2}) self.assert400(resp) - def test_approve_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_approve_proposal(self, mock_get): self.login_admin() # proposal needs to be PENDING @@ -110,7 +111,8 @@ class TestAdminAPI(BaseProposalCreatorConfig): self.assert200(resp) self.assertEqual(resp.json["status"], ProposalStatus.APPROVED) - def test_reject_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_reject_proposal(self, mock_get): self.login_admin() # proposal needs to be PENDING diff --git a/backend/tests/config.py b/backend/tests/config.py index 5ccb4569..d72f45c0 100644 --- a/backend/tests/config.py +++ b/backend/tests/config.py @@ -9,7 +9,7 @@ from grant.user.models import User, SocialMedia, db, Avatar from grant.settings import PROPOSAL_STAKING_AMOUNT from grant.utils.enums import ProposalStatus -from .test_data import test_user, test_other_user, test_proposal, mock_contribution_addresses +from .test_data import test_user, test_other_user, test_proposal, mock_blockchain_api_requests class BaseTestConfig(TestCase): @@ -148,7 +148,7 @@ class BaseProposalCreatorConfig(BaseUserConfig): proposal_reminder = ProposalReminder(self.proposal.id) proposal_reminder.make_task() - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def stake_proposal(self, mock_get): # 1. submit self.proposal.submit_for_approval() diff --git a/backend/tests/proposal/test_api.py b/backend/tests/proposal/test_api.py index d19cadb8..f436fe40 100644 --- a/backend/tests/proposal/test_api.py +++ b/backend/tests/proposal/test_api.py @@ -6,7 +6,15 @@ from grant.proposal.models import Proposal from grant.utils.enums import ProposalStatus from ..config import BaseProposalCreatorConfig -from ..test_data import test_proposal, mock_contribution_addresses +from ..test_data import test_proposal, mock_blockchain_api_requests, mock_invalid_address + + +# Used when a test mocks request.get in multiple ways +def mock_contribution_addresses_and_valid_address(path): + if path == '/contribution/addresses': + return mock_valid_address + else: + return mock_contribution_addresses class TestProposalAPI(BaseProposalCreatorConfig): @@ -68,29 +76,39 @@ class TestProposalAPI(BaseProposalCreatorConfig): self.assert404(resp) # /submit_for_approval - def test_proposal_draft_submit_for_approval(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_proposal_draft_submit_for_approval(self, mock_get): self.login_default_user() resp = self.app.put("/api/v1/proposals/{}/submit_for_approval".format(self.proposal.id)) self.assert200(resp) self.assertEqual(resp.json['status'], ProposalStatus.STAKING) - def test_no_auth_proposal_draft_submit_for_approval(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_no_auth_proposal_draft_submit_for_approval(self, mock_get): resp = self.app.put("/api/v1/proposals/{}/submit_for_approval".format(self.proposal.id)) self.assert401(resp) - def test_invalid_proposal_draft_submit_for_approval(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_invalid_proposal_draft_submit_for_approval(self, mock_get): self.login_default_user() resp = self.app.put("/api/v1/proposals/12345/submit_for_approval") self.assert404(resp) - def test_invalid_status_proposal_draft_submit_for_approval(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_invalid_status_proposal_draft_submit_for_approval(self, mock_get): self.login_default_user() self.proposal.status = ProposalStatus.PENDING # should be ProposalStatus.DRAFT resp = self.app.put("/api/v1/proposals/{}/submit_for_approval".format(self.proposal.id)) self.assert400(resp) + @patch('requests.get', side_effect=mock_invalid_address) + def test_invalid_address_proposal_draft_submit_for_approval(self, mock_get): + self.login_default_user() + resp = self.app.put("/api/v1/proposals/{}/submit_for_approval".format(self.proposal.id)) + self.assert400(resp) + # /stake - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_proposal_stake(self, mock_get): self.login_default_user() self.proposal.status = ProposalStatus.STAKING @@ -99,14 +117,14 @@ class TestProposalAPI(BaseProposalCreatorConfig): self.assert200(resp) self.assertEquals(resp.json['amount'], str(PROPOSAL_STAKING_AMOUNT)) - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_proposal_stake_no_auth(self, mock_get): self.proposal.status = ProposalStatus.STAKING resp = self.app.get(f"/api/v1/proposals/{self.proposal.id}/stake") print(resp) self.assert401(resp) - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_proposal_stake_bad_status(self, mock_get): self.login_default_user() self.proposal.status = ProposalStatus.PENDING # should be staking @@ -114,7 +132,7 @@ class TestProposalAPI(BaseProposalCreatorConfig): print(resp) self.assert400(resp) - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_proposal_stake_funded(self, mock_get): self.login_default_user() # fake stake contribution with confirmation @@ -124,29 +142,34 @@ class TestProposalAPI(BaseProposalCreatorConfig): self.assert404(resp) # /publish - def test_publish_proposal_approved(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_publish_proposal_approved(self, mock_get): self.login_default_user() # proposal needs to be APPROVED self.proposal.status = ProposalStatus.APPROVED resp = self.app.put("/api/v1/proposals/{}/publish".format(self.proposal.id)) self.assert200(resp) - def test_no_auth_publish_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_no_auth_publish_proposal(self, mock_get): resp = self.app.put("/api/v1/proposals/{}/publish".format(self.proposal.id)) self.assert401(resp) - def test_invalid_proposal_publish_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_invalid_proposal_publish_proposal(self, mock_get): self.login_default_user() resp = self.app.put("/api/v1/proposals/12345/publish") self.assert404(resp) - def test_invalid_status_proposal_publish_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_invalid_status_proposal_publish_proposal(self, mock_get): self.login_default_user() self.proposal.status = ProposalStatus.PENDING # should be ProposalStatus.APPROVED resp = self.app.put("/api/v1/proposals/{}/publish".format(self.proposal.id)) self.assert400(resp) - def test_not_verified_email_address_publish_proposal(self): + @patch('requests.get', side_effect=mock_blockchain_api_requests) + def test_not_verified_email_address_publish_proposal(self, mock_get): self.login_default_user() self.mark_user_not_verified() self.proposal.status = "DRAFT" diff --git a/backend/tests/proposal/test_contribution_api.py b/backend/tests/proposal/test_contribution_api.py index 04f51d15..8a606f85 100644 --- a/backend/tests/proposal/test_contribution_api.py +++ b/backend/tests/proposal/test_contribution_api.py @@ -4,18 +4,12 @@ from mock import patch from grant.proposal.models import Proposal from grant.utils.enums import ProposalStatus from ..config import BaseProposalCreatorConfig -from ..test_data import test_proposal +from ..test_data import test_proposal, mock_blockchain_api_requests from ..mocks import mock_request -mock_contribution_addresses = mock_request({ - 'transparent': 't123', - 'sprout': 'z123', - 'memo': '123', -}) - class TestProposalContributionAPI(BaseProposalCreatorConfig): - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_create_proposal_contribution(self, mock_blockchain_get): self.login_default_user() @@ -31,7 +25,7 @@ class TestProposalContributionAPI(BaseProposalCreatorConfig): self.assertStatus(post_res, 201) - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_create_duplicate_contribution(self, mock_blockchain_get): self.login_default_user() @@ -55,7 +49,7 @@ class TestProposalContributionAPI(BaseProposalCreatorConfig): self.assert200(dupe_res) self.assertEqual(dupe_res.json['id'], post_res.json['id']) - @patch('requests.get', side_effect=mock_contribution_addresses) + @patch('requests.get', side_effect=mock_blockchain_api_requests) def test_get_proposal_contribution(self, mock_blockchain_get): self.login_default_user() diff --git a/backend/tests/test_data.py b/backend/tests/test_data.py index b43bc24d..ebf22952 100644 --- a/backend/tests/test_data.py +++ b/backend/tests/test_data.py @@ -64,3 +64,19 @@ mock_contribution_addresses = mock_request({ 'sprout': 'z123', 'memo': '123', }) + +mock_valid_address = mock_request({ + 'valid': True, +}) + +mock_invalid_address = mock_request({ + 'valid': False, +}) + + +def mock_blockchain_api_requests(path, **kwargs): + if '/contribution/addresses' in path: + return mock_contribution_addresses() + if '/validate/address' in path: + return mock_valid_address() + raise Exception('No mock data defined for path {}'.format(path))