import pytest from uuid import uuid4 from atst.domain.exceptions import NotFoundError from atst.domain.requests import Requests from atst.domain.requests.authorization import RequestsAuthorization from atst.models.request import Request from atst.models.request_status_event import RequestStatus from atst.models.task_order import Source as TaskOrderSource from tests.factories import ( RequestFactory, UserFactory, RequestStatusEventFactory, TaskOrderFactory, RequestRevisionFactory, RequestReviewFactory, ) @pytest.fixture(scope="function") def new_request(session): return RequestFactory.create() def test_can_get_request(): factory_req = RequestFactory.create() request = Requests.get(factory_req.creator, factory_req.id) assert request.id == factory_req.id def test_nonexistent_request_raises(): a_user = UserFactory.build() with pytest.raises(NotFoundError): Requests.get(a_user, uuid4()) def test_new_request_has_started_status(): request = Requests.create(UserFactory.build(), {}) assert request.status == RequestStatus.STARTED def test_auto_approve_less_than_1m(): new_request = RequestFactory.create(initial_revision={"dollar_value": 999_999}) request = Requests.submit(new_request) assert request.status == RequestStatus.PENDING_FINANCIAL_VERIFICATION def test_dont_auto_approve_if_dollar_value_is_1m_or_above(): new_request = RequestFactory.create(initial_revision={"dollar_value": 1_000_000}) request = Requests.submit(new_request) assert request.status == RequestStatus.PENDING_CCPO_ACCEPTANCE def test_dont_auto_approve_if_no_dollar_value_specified(): new_request = RequestFactory.create(initial_revision={}) request = Requests.submit(new_request) assert request.status == RequestStatus.PENDING_CCPO_ACCEPTANCE def test_should_allow_submission(): new_request = RequestFactory.create() assert Requests.should_allow_submission(new_request) RequestStatusEventFactory.create( request=new_request, new_status=RequestStatus.CHANGES_REQUESTED, revision=new_request.latest_revision, ) assert Requests.should_allow_submission(new_request) # new, blank revision RequestRevisionFactory.create(request=new_request) assert not Requests.should_allow_submission(new_request) def test_request_knows_its_last_submission_timestamp(new_request): submitted_request = Requests.submit(new_request) assert submitted_request.last_submission_timestamp def test_request_knows_if_it_has_no_last_submission_timestamp(new_request): assert new_request.last_submission_timestamp is None def test_exists(session): user_allowed = UserFactory.create() user_denied = UserFactory.create() request = RequestFactory.create(creator=user_allowed) assert Requests.exists(request.id, user_allowed) assert not Requests.exists(request.id, user_denied) def test_status_count(session): # make sure table is empty session.query(Request).delete() request1 = RequestFactory.create() request2 = RequestFactory.create() RequestStatusEventFactory.create( sequence=2, request_id=request2.id, revision=request2.latest_revision, new_status=RequestStatus.PENDING_FINANCIAL_VERIFICATION, ) assert Requests.status_count(RequestStatus.PENDING_FINANCIAL_VERIFICATION) == 1 assert Requests.status_count(RequestStatus.STARTED) == 1 assert Requests.in_progress_count() == 2 def test_status_count_scoped_to_creator(session): # make sure table is empty session.query(Request).delete() user = UserFactory.create() request1 = RequestFactory.create() request2 = RequestFactory.create(creator=user) assert Requests.status_count(RequestStatus.STARTED) == 2 assert Requests.status_count(RequestStatus.STARTED, creator=user) == 1 request_financial_data = { "pe_id": "123", "task_order_number": "021345", "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", "uii_ids": "1234", "treasury_code": "00123456", "ba_code": "024A", } def test_update_financial_verification_without_task_order( extended_financial_verification_data ): request = RequestFactory.create() financial_data = {**request_financial_data, **extended_financial_verification_data} Requests.update_financial_verification(request.id, financial_data) assert request.task_order assert request.task_order.clin_0001 == int( extended_financial_verification_data["clin_0001"] ) assert request.task_order.source == TaskOrderSource.MANUAL assert request.task_order.pdf def test_update_financial_verification_with_task_order(): task_order = TaskOrderFactory.create(source=TaskOrderSource.EDA) financial_data = {**request_financial_data, "task_order_number": task_order.number} request = RequestFactory.create() Requests.update_financial_verification(request.id, financial_data) assert request.task_order == task_order def test_update_financial_verification_with_invalid_task_order(): request = RequestFactory.create() Requests.update_financial_verification(request.id, request_financial_data) assert not request.task_order assert "task_order_number" in request.body.get("financial_verification") assert ( request.body["financial_verification"]["task_order_number"] == request_financial_data["task_order_number"] ) def test_set_status_sets_revision(): request = RequestFactory.create() Requests.set_status(request, RequestStatus.APPROVED) assert request.latest_revision == request.status_events[-1].revision def test_advance_to_financial_verification(): request = RequestFactory.create_with_status( status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() Requests.advance(UserFactory.create(), request, review_data) assert request.status == RequestStatus.PENDING_FINANCIAL_VERIFICATION current_review = request.latest_status.review assert current_review.fname_mao == review_data["fname_mao"] def test_advance_to_approval(): request = RequestFactory.create_with_status( status=RequestStatus.PENDING_CCPO_APPROVAL ) review_data = RequestReviewFactory.dictionary() Requests.advance(UserFactory.create(), request, review_data) assert request.status == RequestStatus.APPROVED def test_request_changes_to_request_application(): request = RequestFactory.create_with_status( status=RequestStatus.PENDING_CCPO_ACCEPTANCE ) review_data = RequestReviewFactory.dictionary() Requests.request_changes(UserFactory.create(), request, review_data) assert request.status == RequestStatus.CHANGES_REQUESTED current_review = request.latest_status.review assert current_review.fname_mao == review_data["fname_mao"] def test_request_changes_to_financial_verification_info(): request = RequestFactory.create_with_status( status=RequestStatus.PENDING_CCPO_APPROVAL ) review_data = RequestReviewFactory.dictionary() Requests.request_changes(UserFactory.create(), request, review_data) assert request.status == RequestStatus.CHANGES_REQUESTED_TO_FINVER current_review = request.latest_status.review assert current_review.fname_mao == review_data["fname_mao"] def test_add_internal_comment(): request = RequestFactory.create() ccpo = UserFactory.from_atat_role("ccpo") assert len(request.internal_comments) == 0 request = Requests.add_internal_comment(ccpo, request, "this is my comment") assert len(request.internal_comments) == 1 assert request.internal_comments[0].text == "this is my comment" def test_creator_can_view_own_request(): creator = UserFactory.create() request = RequestFactory.create(creator=creator) assert RequestsAuthorization(creator, request).can_view def test_ccpo_can_view_request(): ccpo = UserFactory.from_atat_role("ccpo") request = RequestFactory.create() assert RequestsAuthorization(ccpo, request).can_view def test_random_user_cannot_view_request(): user = UserFactory.create() request = RequestFactory.create() assert not RequestsAuthorization(user, request).can_view