diff --git a/atst/forms/financial.py b/atst/forms/financial.py index 15ddb955..05390b8e 100644 --- a/atst/forms/financial.py +++ b/atst/forms/financial.py @@ -4,6 +4,7 @@ from wtforms.fields.html5 import DateField, EmailField from wtforms.fields import StringField, FileField, FormField from wtforms.validators import InputRequired, Email, Regexp, Optional from flask_wtf.file import FileAllowed +from werkzeug.datastructures import FileStorage from .fields import NewlineListField, SelectField, NumberStringField from atst.forms.forms import ValidatedForm @@ -237,6 +238,10 @@ class FinancialVerificationForm(ValidatedForm): def task_order_number(self): return self.task_order.number + @property + def has_task_order_pdf(self): + return isinstance(self.task_order.pdf.data, FileStorage) + @property def is_missing_task_order_number(self): return "number" in self.errors.get("task_order", {}) diff --git a/atst/models/attachment.py b/atst/models/attachment.py index 9a8dfcbf..89dfe7f8 100644 --- a/atst/models/attachment.py +++ b/atst/models/attachment.py @@ -65,7 +65,7 @@ class Attachment(Base, mixins.TimestampsMixin): return ( db.session.query(Attachment) .filter_by(resource=resource, resource_id=resource_id) - .delete() + .update({"resource_id": None}) ) except NoResultFound: raise NotFoundError("attachment") diff --git a/atst/routes/requests/financial_verification.py b/atst/routes/requests/financial_verification.py index cb2e1bb5..47235db5 100644 --- a/atst/routes/requests/financial_verification.py +++ b/atst/routes/requests/financial_verification.py @@ -31,11 +31,12 @@ class FinancialVerificationBase(object): fv = FinancialVerification(request) form = FinancialVerificationForm(obj=fv, formdata=_formdata) - try: - attachment = Attachment.get_for_resource("task_order", self.request.id) - form.task_order.pdf.data = attachment.filename - except NotFoundError: - pass + if not form.has_task_order_pdf: + try: + attachment = Attachment.get_for_resource("task_order", self.request.id) + form.task_order.pdf.data = attachment.filename + except NotFoundError: + pass return form diff --git a/tests/conftest.py b/tests/conftest.py index 67912c1d..0304f0ee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,7 +11,7 @@ from atst.app import make_app, make_config from atst.database import db as _db from atst.queue import queue as atst_queue import tests.factories as factories -from tests.mocks import PDF_FILENAME +from tests.mocks import PDF_FILENAME, PDF_FILENAME2 dictConfig({"version": 1, "handlers": {"wsgi": {"class": "logging.NullHandler"}}}) @@ -121,6 +121,12 @@ def pdf_upload(): yield FileStorage(fp, content_type="application/pdf") +@pytest.fixture +def pdf_upload2(): + with open(PDF_FILENAME2, "rb") as fp: + yield FileStorage(fp, content_type="application/pdf") + + @pytest.fixture def extended_financial_verification_data(pdf_upload): return { diff --git a/tests/fixtures/sample2.pdf b/tests/fixtures/sample2.pdf new file mode 100644 index 00000000..c0e31a07 --- /dev/null +++ b/tests/fixtures/sample2.pdf @@ -0,0 +1,198 @@ +%PDF-1.3 +%âãÏÓ + +1 0 obj +<< +/Type /Catalog +/Outlines 2 0 R +/Pages 3 0 R +>> +endobj + +2 0 obj +<< +/Type /Outlines +/Count 0 +>> +endobj + +3 0 obj +<< +/Type /Pages +/Count 2 +/Kids [ 4 0 R 6 0 R ] +>> +endobj + +4 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 5 0 R +>> +endobj + +5 0 obj +<< /Length 1074 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( A Simple PDF File ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( This is a small demonstration .pdf file - ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( just for use in the Virtual Mechanics tutorials. More text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 628.8480 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 616.8960 Td +( text. And more text. Boring, zzzzz. And more text. And more text. And ) Tj +ET +BT +/F1 0010 Tf +69.2500 604.9440 Td +( more text. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 592.9920 Td +( And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 569.0880 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 557.1360 Td +( text. And more text. And more text. Even more. Continued on page 2 ...) Tj +ET +endstream +endobj + +6 0 obj +<< +/Type /Page +/Parent 3 0 R +/Resources << +/Font << +/F1 9 0 R +>> +/ProcSet 8 0 R +>> +/MediaBox [0 0 612.0000 792.0000] +/Contents 7 0 R +>> +endobj + +7 0 obj +<< /Length 676 >> +stream +2 J +BT +0 0 0 rg +/F1 0027 Tf +57.3750 722.2800 Td +( Simple PDF File 2 ) Tj +ET +BT +/F1 0010 Tf +69.2500 688.6080 Td +( ...continued from page 1. Yet more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 676.6560 Td +( And more text. And more text. And more text. And more text. And more ) Tj +ET +BT +/F1 0010 Tf +69.2500 664.7040 Td +( text. Oh, how boring typing this stuff. But not as boring as watching ) Tj +ET +BT +/F1 0010 Tf +69.2500 652.7520 Td +( paint dry. And more text. And more text. And more text. And more text. ) Tj +ET +BT +/F1 0010 Tf +69.2500 640.8000 Td +( Boring. More, a little more text. The end, and just as well. ) Tj +ET +endstream +endobj + +8 0 obj +[/PDF /Text] +endobj + +9 0 obj +<< +/Type /Font +/Subtype /Type1 +/Name /F1 +/BaseFont /Helvetica +/Encoding /WinAnsiEncoding +>> +endobj + +10 0 obj +<< +/Creator (Rave \(http://www.nevrona.com/rave\)) +/Producer (Nevrona Designs) +/CreationDate (D:20060301072826) +>> +endobj + +xref +0 11 +0000000000 65535 f +0000000019 00000 n +0000000093 00000 n +0000000147 00000 n +0000000222 00000 n +0000000390 00000 n +0000001522 00000 n +0000001690 00000 n +0000002423 00000 n +0000002456 00000 n +0000002574 00000 n + +trailer +<< +/Size 11 +/Root 1 0 R +/Info 10 0 R +>> + +startxref +2714 +%%EOF diff --git a/tests/mocks.py b/tests/mocks.py index b42521dc..ee8247ac 100644 --- a/tests/mocks.py +++ b/tests/mocks.py @@ -11,3 +11,4 @@ MOCK_VALID_PE_ID = "080675309U" FIXTURE_EMAIL_ADDRESS = "artgarfunkel@uso.mil" PDF_FILENAME = "tests/fixtures/sample.pdf" +PDF_FILENAME2 = "tests/fixtures/sample2.pdf" diff --git a/tests/routes/test_financial_verification.py b/tests/routes/test_financial_verification.py index 8c1f3da4..427b05a9 100644 --- a/tests/routes/test_financial_verification.py +++ b/tests/routes/test_financial_verification.py @@ -519,3 +519,21 @@ def test_existing_task_order_with_pdf(fv_data, e_fv_data, client, user_session): ) assert response.status_code == 200 + + +def test_pdf_clearing(fv_data, e_fv_data, pdf_upload, pdf_upload2): + user = UserFactory.create() + request = RequestFactory.create(creator=user) + data = {**fv_data, **e_fv_data, "task_order-pdf": pdf_upload} + + SaveFinancialVerificationDraft( + TrueValidator, TrueValidator, user, request, data, is_extended=True + ).execute() + + data = {**data, "task_order-pdf": pdf_upload2} + UpdateFinancialVerification( + TrueValidator, TrueValidator, user, request, data, is_extended=True + ).execute() + + form = GetFinancialVerificationForm(user, request, is_extended=True).execute() + assert form.task_order.pdf.data == pdf_upload2.filename