From e3dfd18c7fbeef330f6cb09dee03a7c3e961d1a6 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Thu, 18 Jul 2019 11:26:18 -0400 Subject: [PATCH 1/3] Raise error if TO review or signature page are accessed when the TO is incomplete --- atst/routes/task_orders/new.py | 11 +++++ tests/routes/task_orders/test_new.py | 61 ++++++++++++++++++++-------- tests/test_access.py | 6 ++- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/atst/routes/task_orders/new.py b/atst/routes/task_orders/new.py index a806bda7..8d91ca7d 100644 --- a/atst/routes/task_orders/new.py +++ b/atst/routes/task_orders/new.py @@ -2,6 +2,7 @@ from flask import g, redirect, render_template, request as http_request, url_for from . import task_orders_bp from atst.domain.authz.decorator import user_can_access_decorator as user_can +from atst.domain.exceptions import NoAccessError from atst.domain.task_orders import TaskOrders from atst.forms.task_order import TaskOrderForm, SignatureForm from atst.models.permissions import Permissions @@ -128,6 +129,11 @@ def submit_form_step_three_add_clins(task_order_id): @task_orders_bp.route("/task_orders//form/step_4") @user_can(Permissions.CREATE_TASK_ORDER, message="view task order form") def form_step_four_review(task_order_id): + task_order = TaskOrders.get(task_order_id) + + if task_order.is_completed == False: + raise NoAccessError("task order form review") + return render_task_orders_edit( "task_orders/step_4.html", task_order_id=task_order_id ) @@ -136,6 +142,11 @@ def form_step_four_review(task_order_id): @task_orders_bp.route("/task_orders//form/step_5") @user_can(Permissions.CREATE_TASK_ORDER, message="view task order form") def form_step_five_confirm_signature(task_order_id): + task_order = TaskOrders.get(task_order_id) + + if task_order.is_completed == False: + raise NoAccessError("task order form signature") + return render_task_orders_edit( "task_orders/step_5.html", task_order_id=task_order_id, form=SignatureForm() ) diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py index ab221bca..22c24296 100644 --- a/tests/routes/task_orders/test_new.py +++ b/tests/routes/task_orders/test_new.py @@ -25,6 +25,18 @@ def task_order(): return TaskOrderFactory.create(creator=user, portfolio=portfolio) +@pytest.fixture +def completed_task_order(): + portfolio = PortfolioFactory.create() + task_order = TaskOrderFactory.create( + creator=portfolio.owner, + portfolio=portfolio, + create_clins=["1234567890123456789012345678901234567890123"], + ) + + return task_order + + @pytest.fixture def portfolio(): return PortfolioFactory.create() @@ -114,22 +126,49 @@ def test_task_orders_submit_form_step_three_add_clins(client, user_session, task assert len(task_order.clins) == 2 -def test_task_orders_form_step_four_review(client, user_session, task_order): - user_session(task_order.creator) +def test_task_orders_form_step_four_review(client, user_session, completed_task_order): + user_session(completed_task_order.creator) response = client.get( - url_for("task_orders.form_step_four_review", task_order_id=task_order.id) + url_for( + "task_orders.form_step_four_review", task_order_id=completed_task_order.id + ) ) assert response.status_code == 200 -def test_task_orders_form_step_five_confirm_signature(client, user_session, task_order): +def test_task_orders_form_step_four_review_incomplete_to( + client, user_session, task_order +): + user_session(task_order.creator) + response = client.get( + url_for("task_orders.form_step_four_review", task_order_id=task_order.id) + ) + assert response.status_code == 404 + + +def test_task_orders_form_step_five_confirm_signature( + client, user_session, completed_task_order +): + user_session(completed_task_order.creator) + response = client.get( + url_for( + "task_orders.form_step_five_confirm_signature", + task_order_id=completed_task_order.id, + ) + ) + assert response.status_code == 200 + + +def test_task_orders_form_step_five_confirm_signature_incomplete_to( + client, user_session, task_order +): user_session(task_order.creator) response = client.get( url_for( "task_orders.form_step_five_confirm_signature", task_order_id=task_order.id ) ) - assert response.status_code == 200 + assert response.status_code == 404 def test_task_orders_form_step_one_add_pdf_existing_to( @@ -275,18 +314,6 @@ def test_task_orders_update_invalid_data(client, user_session, portfolio): assert "There were some errors" in response.data.decode() -@pytest.mark.skip(reason="Reevaluate if user can see review page w/ incomplete TO") -def test_cannot_get_to_review_screen_with_incomplete_data( - client, user_session, portfolio -): - user_session(portfolio.owner) - data = {"number": "0123456789"} - response = client.post( - url_for("task_orders.update", portfolio_id=portfolio.id, review=True), data=data - ) - assert response.status_code == 400 - - @pytest.mark.skip(reason="Update after implementing errors on TO form") def test_task_order_form_shows_errors(client, user_session, task_order): creator = task_order.creator diff --git a/tests/test_access.py b/tests/test_access.py index 893cdecc..eefa2160 100644 --- a/tests/test_access.py +++ b/tests/test_access.py @@ -467,7 +467,11 @@ def test_task_orders_new_get_routes(get_url_assert_status): rando = user_with() portfolio = PortfolioFactory.create(owner=owner) - task_order = TaskOrderFactory.create(portfolio=portfolio, creator=owner) + task_order = TaskOrderFactory.create( + creator=owner, + portfolio=portfolio, + create_clins=["1234567890123456789012345678901234567890123"], + ) for route in get_routes: url = url_for(route, task_order_id=task_order.id) From b3515bb14dc5a430d42966131ddef0c1f663b451 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Thu, 18 Jul 2019 11:31:55 -0400 Subject: [PATCH 2/3] Reorder tests so that tests for each step are grouped together --- tests/routes/task_orders/test_new.py | 216 ++++++++++++++------------- 1 file changed, 109 insertions(+), 107 deletions(-) diff --git a/tests/routes/task_orders/test_new.py b/tests/routes/task_orders/test_new.py index 22c24296..74229e00 100644 --- a/tests/routes/task_orders/test_new.py +++ b/tests/routes/task_orders/test_new.py @@ -55,7 +55,9 @@ def test_task_orders_form_step_one_add_pdf(client, user_session, portfolio): assert response.status_code == 200 -def test_task_orders_upload_pdf(client, user_session, portfolio, pdf_upload, session): +def test_task_orders_submit_form_step_one_add_pdf( + client, user_session, portfolio, pdf_upload, session +): user_session(portfolio.owner) form_data = {"pdf": pdf_upload} response = client.post( @@ -68,6 +70,50 @@ def test_task_orders_upload_pdf(client, user_session, portfolio, pdf_upload, ses assert task_order.pdf.filename == pdf_upload.filename +def test_task_orders_form_step_one_add_pdf_existing_to( + client, user_session, task_order +): + user_session(task_order.creator) + response = client.get( + url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order.id) + ) + assert response.status_code == 200 + + +def test_task_orders_submit_form_step_one_add_pdf_existing_to( + client, user_session, task_order, pdf_upload, pdf_upload2 +): + task_order.pdf = pdf_upload + assert task_order.pdf.filename == pdf_upload.filename + + user_session(task_order.creator) + form_data = {"pdf": pdf_upload2} + response = client.post( + url_for( + "task_orders.submit_form_step_one_add_pdf", task_order_id=task_order.id + ), + data=form_data, + ) + assert response.status_code == 302 + assert task_order.pdf.filename == pdf_upload2.filename + + +def test_task_orders_submit_form_step_one_add_pdf_delete_pdf( + client, user_session, portfolio, pdf_upload +): + user_session(portfolio.owner) + task_order = TaskOrderFactory.create(pdf=pdf_upload, portfolio=portfolio) + data = {"pdf": ""} + response = client.post( + url_for( + "task_orders.submit_form_step_one_add_pdf", task_order_id=task_order.id + ), + data=data, + ) + assert task_order.pdf is None + assert response.status_code == 302 + + def test_task_orders_form_step_two_add_number(client, user_session, task_order): user_session(task_order.creator) response = client.get( @@ -90,6 +136,23 @@ def test_task_orders_submit_form_step_two_add_number(client, user_session, task_ assert task_order.number == "1234567890" +def test_task_orders_submit_form_step_two_add_number_existing_to( + client, user_session, task_order +): + user_session(task_order.creator) + form_data = {"number": "0000000000"} + original_number = task_order.number + response = client.post( + url_for( + "task_orders.submit_form_step_two_add_number", task_order_id=task_order.id + ), + data=form_data, + ) + assert response.status_code == 302 + assert task_order.number == "0000000000" + assert task_order.number != original_number + + def test_task_orders_form_step_three_add_clins(client, user_session, task_order): user_session(task_order.creator) response = client.get( @@ -126,6 +189,50 @@ def test_task_orders_submit_form_step_three_add_clins(client, user_session, task assert len(task_order.clins) == 2 +def test_task_orders_submit_form_step_three_add_clins_existing_to( + client, user_session, task_order +): + clin_list = [ + { + "jedi_clin_type": "JEDI_CLIN_1", + "number": "12312", + "start_date": "01/01/2020", + "end_date": "01/01/2021", + "obligated_amount": "5000", + "loas": ["123123123123", "345345234"], + }, + { + "jedi_clin_type": "JEDI_CLIN_1", + "number": "12312", + "start_date": "01/01/2020", + "end_date": "01/01/2021", + "obligated_amount": "5000", + "loas": ["78979087"], + }, + ] + TaskOrders.create_clins(task_order.id, clin_list) + assert len(task_order.clins) == 2 + + user_session(task_order.creator) + form_data = { + "clins-0-jedi_clin_type": "JEDI_CLIN_1", + "clins-0-clin_number": "12312", + "clins-0-start_date": "01/01/2020", + "clins-0-end_date": "01/01/2021", + "clins-0-obligated_amount": "5000", + "clins-0-loas-0": "123123123123", + } + response = client.post( + url_for( + "task_orders.submit_form_step_three_add_clins", task_order_id=task_order.id + ), + data=form_data, + ) + + assert response.status_code == 302 + assert len(task_order.clins) == 1 + + def test_task_orders_form_step_four_review(client, user_session, completed_task_order): user_session(completed_task_order.creator) response = client.get( @@ -171,112 +278,7 @@ def test_task_orders_form_step_five_confirm_signature_incomplete_to( assert response.status_code == 404 -def test_task_orders_form_step_one_add_pdf_existing_to( - client, user_session, task_order -): - user_session(task_order.creator) - response = client.get( - url_for("task_orders.form_step_one_add_pdf", task_order_id=task_order.id) - ) - assert response.status_code == 200 - - -def test_task_orders_upload_pdf_existing_to( - client, user_session, task_order, pdf_upload, pdf_upload2 -): - task_order.pdf = pdf_upload - assert task_order.pdf.filename == pdf_upload.filename - - user_session(task_order.creator) - form_data = {"pdf": pdf_upload2} - response = client.post( - url_for( - "task_orders.submit_form_step_one_add_pdf", task_order_id=task_order.id - ), - data=form_data, - ) - assert response.status_code == 302 - assert task_order.pdf.filename == pdf_upload2.filename - - -def test_task_orders_submit_form_step_one_add_pdf_delete_pdf( - client, user_session, portfolio, pdf_upload -): - user_session(portfolio.owner) - task_order = TaskOrderFactory.create(pdf=pdf_upload, portfolio=portfolio) - data = {"pdf": ""} - response = client.post( - url_for( - "task_orders.submit_form_step_one_add_pdf", task_order_id=task_order.id - ), - data=data, - ) - assert task_order.pdf is None - assert response.status_code == 302 - - -def test_task_orders_submit_form_step_two_add_number_existing_to( - client, user_session, task_order -): - user_session(task_order.creator) - form_data = {"number": "0000000000"} - original_number = task_order.number - response = client.post( - url_for( - "task_orders.submit_form_step_two_add_number", task_order_id=task_order.id - ), - data=form_data, - ) - assert response.status_code == 302 - assert task_order.number == "0000000000" - assert task_order.number != original_number - - -def test_task_orders_submit_form_step_three_add_clins_existing_to( - client, user_session, task_order -): - clin_list = [ - { - "jedi_clin_type": "JEDI_CLIN_1", - "number": "12312", - "start_date": "01/01/2020", - "end_date": "01/01/2021", - "obligated_amount": "5000", - "loas": ["123123123123", "345345234"], - }, - { - "jedi_clin_type": "JEDI_CLIN_1", - "number": "12312", - "start_date": "01/01/2020", - "end_date": "01/01/2021", - "obligated_amount": "5000", - "loas": ["78979087"], - }, - ] - TaskOrders.create_clins(task_order.id, clin_list) - assert len(task_order.clins) == 2 - - user_session(task_order.creator) - form_data = { - "clins-0-jedi_clin_type": "JEDI_CLIN_1", - "clins-0-clin_number": "12312", - "clins-0-start_date": "01/01/2020", - "clins-0-end_date": "01/01/2021", - "clins-0-obligated_amount": "5000", - "clins-0-loas-0": "123123123123", - } - response = client.post( - url_for( - "task_orders.submit_form_step_three_add_clins", task_order_id=task_order.id - ), - data=form_data, - ) - - assert response.status_code == 302 - assert len(task_order.clins) == 1 - - -def test_submit_task_order(client, user_session, task_order): +def test_task_orders_submit_task_order(client, user_session, task_order): user_session(task_order.portfolio.owner) response = client.post( url_for("task_orders.submit_task_order", task_order_id=task_order.id) From 74d49744374861fc2320380dfdf98c20808a90f9 Mon Sep 17 00:00:00 2001 From: leigh-mil Date: Thu, 18 Jul 2019 11:32:13 -0400 Subject: [PATCH 3/3] Clean up code from old version of TO builder --- atst/domain/task_orders.py | 42 -------------------------------------- 1 file changed, 42 deletions(-) diff --git a/atst/domain/task_orders.py b/atst/domain/task_orders.py index cc0920d0..94343c7c 100644 --- a/atst/domain/task_orders.py +++ b/atst/domain/task_orders.py @@ -1,5 +1,4 @@ import datetime -from flask import current_app as app from atst.database import db from atst.models.clin import CLIN @@ -11,10 +10,6 @@ class TaskOrders(BaseDomainClass): model = TaskOrder resource_name = "task_order" - SECTIONS = {"app_info": ["portfolio_name"], "funding": [], "oversight": []} - - UNCLASSIFIED_FUNDING = [] - @classmethod def create(cls, creator, portfolio_id, number, clins, pdf): task_order = TaskOrder( @@ -70,43 +65,6 @@ class TaskOrders(BaseDomainClass): db.session.add(clin) db.session.commit() - @classmethod - def section_completion_status(cls, task_order, section): - if section in TaskOrders.mission_owner_sections(): - passed = [] - failed = [] - - for attr in TaskOrders.SECTIONS[section]: - if getattr(task_order, attr) is not None: - passed.append(attr) - else: - failed.append(attr) - - if not failed: - return "complete" - elif passed and failed: - return "draft" - - return "incomplete" - - @classmethod - def all_sections_complete(cls, task_order): - for section in TaskOrders.SECTIONS.keys(): - if ( - TaskOrders.section_completion_status(task_order, section) - is not "complete" - ): - return False - - return True - - @classmethod - def mission_owner_sections(cls): - section_list = TaskOrders.SECTIONS - if not app.config.get("CLASSIFIED"): - section_list["funding"] = TaskOrders.UNCLASSIFIED_FUNDING - return section_list - @classmethod def sort(cls, task_orders: [TaskOrder]) -> [TaskOrder]: # Sorts a list of task orders on two keys: status (primary) and time_created (secondary)