diff --git a/atst/forms/financial.py b/atst/forms/financial.py index 3bdb8e53..77811ee1 100644 --- a/atst/forms/financial.py +++ b/atst/forms/financial.py @@ -31,7 +31,7 @@ class FinancialForm(ValidatedForm): @tornado.gen.coroutine def perform_extra_validation(self, existing_request, fundz_client): valid = True - if existing_request['pe_id'] != self.pe_id.data: + if not existing_request or existing_request.get('pe_id') != self.pe_id.data: valid = yield validate_pe_id(self.pe_id, existing_request, fundz_client) raise Return(valid) diff --git a/tests/conftest.py b/tests/conftest.py index 469a2100..c650b5f1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,7 @@ import pytest from atst.app import make_app, make_deps, make_config -from tests.mocks import MockApiClient, MockRequestsClient, MockAuthzClient +from tests.mocks import MockApiClient, MockFundzClient, MockRequestsClient, MockAuthzClient from atst.sessions import DictSessions @@ -11,6 +11,7 @@ def app(): "authz_client": MockAuthzClient("authz"), "requests_client": MockRequestsClient("requests"), "authnid_client": MockApiClient("authnid"), + "fundz_client": MockFundzClient("fundz"), "sessions": DictSessions(), } diff --git a/tests/handlers/test_request_new.py b/tests/handlers/test_request_new.py index 7cd99495..6a8a37f6 100644 --- a/tests/handlers/test_request_new.py +++ b/tests/handlers/test_request_new.py @@ -1,5 +1,8 @@ import re import pytest +import tornado +import urllib +from tests.mocks import MOCK_REQUEST, MOCK_VALID_PE_ID ERROR_CLASS = "usa-input-error-message" MOCK_USER = { @@ -47,3 +50,82 @@ def test_submit_valid_request_form(monkeypatch, http_client, base_url): body="meaning=42", ) assert "/requests/new/2" in response.effective_url + + +class TestPENumberInForm: + + required_data = { + "pe_id": "123", + "task_order_id": "1234567899C0001", + "fname_co": "Contracting", + "lname_co": "Officer", + "email_co": "jane@mail.mil", + "office_co": "WHS", + "fname_cor": "Officer", + "lname_cor": "Representative", + "email_cor": "jane@mail.mil", + "office_cor": "WHS", + "funding_type": "RDTE", + "funding_type_other": "other", + "clin_0001": "50,000", + "clin_0003": "13,000", + "clin_1001": "30,000", + "clin_1003": "7,000", + "clin_2001": "30,000", + "clin_2003": "7,000", + } + + def _set_monkeypatches(self, monkeypatch): + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.get_current_user", lambda s: MOCK_USER + ) + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True + ) + monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True) + + @tornado.gen.coroutine + def submit_data(self, http_client, base_url, data): + response = yield http_client.fetch( + base_url + "/requests/new/5/{}".format(MOCK_REQUEST["id"]), + method="POST", + headers={"Content-Type": "application/x-www-form-urlencoded"}, + body=urllib.parse.urlencode(data), + follow_redirects=False, + raise_error=False, + ) + return response + + @pytest.mark.gen_test + def test_submit_request_form_with_invalid_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + response = yield self.submit_data(http_client, base_url, self.required_data) + + assert "We couldn\'t find that PE number" in response.body.decode() + assert response.code == 200 + assert "/requests/new/5" in response.effective_url + + @pytest.mark.gen_test + def test_submit_request_form_with_unchanged_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + data = dict(self.required_data) + data['pe_id'] = MOCK_REQUEST['body']['financial_verification']['pe_id'] + + response = yield self.submit_data(http_client, base_url, data) + + assert response.code == 302 + assert response.headers.get("Location") == "/requests" + + @pytest.mark.gen_test + def test_submit_request_form_with_new_valid_pe_id(self, monkeypatch, http_client, base_url): + self._set_monkeypatches(monkeypatch) + + data = dict(self.required_data) + data['pe_id'] = MOCK_VALID_PE_ID + + response = yield self.submit_data(http_client, base_url, data) + + assert response.code == 302 + assert response.headers.get("Location") == "/requests" diff --git a/tests/mocks.py b/tests/mocks.py index a04e40bf..6cd3540c 100644 --- a/tests/mocks.py +++ b/tests/mocks.py @@ -43,27 +43,39 @@ class MockApiClient(ApiClient): return response +MOCK_REQUEST = { + "id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b", + "creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238", + "body": { + "financial_verification": { + "pe_id": "0203752A", + }, + }, + "status": "incomplete" +} + class MockRequestsClient(MockApiClient): @tornado.gen.coroutine def get(self, path, **kwargs): - json = { - "id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b", - "creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238", - "body": {}, - "status": "incomplete", - } - return self._get_response("GET", path, 200, json=json) + return self._get_response("GET", path, 200, json=MOCK_REQUEST) @tornado.gen.coroutine def post(self, path, **kwargs): - json = { - "id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b", - "creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238", - "body": {}, - "status": "incomplete", - } - return self._get_response("POST", path, 202, json=json) + return self._get_response("POST", path, 202, json=MOCK_REQUEST) + + +MOCK_VALID_PE_ID = "8675309U" + + +class MockFundzClient(MockApiClient): + + @tornado.gen.coroutine + def get(self, path, **kwargs): + if path.endswith(MOCK_VALID_PE_ID): + return self._get_response("GET", path, 200) + else: + return self._get_response("GET", path, 404) class MockAuthzClient(MockApiClient):