diff --git a/Pipfile b/Pipfile index b0c8024d..cc2d7314 100644 --- a/Pipfile +++ b/Pipfile @@ -38,6 +38,7 @@ pytest-env = "*" pytest-cov = "*" selenium = "*" honcho = "*" +blinker = "*" [requires] python_version = "3.6.6" diff --git a/Pipfile.lock b/Pipfile.lock index 7aefaeb6..3944528d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "339ade228d14f03a31061a114103a5f61686b6efe812a1e0295268e08c18f149" + "sha256": "9f750c048a57b4494e2f4e53711a52a8e9f6ae3f6bbdb5d49491510ca105f40f" }, "pipfile-spec": 6, "requires": { @@ -18,10 +18,10 @@ "default": { "alembic": { "hashes": [ - "sha256:e9ffdece0eece55f4108b14b6b0f29ffc730d58e28446a434fe41a1cc5c5f266" + "sha256:35660f7e6159288e2be111126be148ef04cbf7306da73c8b8bd4400837bb08e3" ], "index": "pypi", - "version": "==1.0.5" + "version": "==1.0.6" }, "apache-libcloud": { "hashes": [ @@ -499,6 +499,13 @@ "index": "pypi", "version": "==18.9b0" }, + "blinker": { + "hashes": [ + "sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6" + ], + "index": "pypi", + "version": "==1.4" + }, "click": { "hashes": [ "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", @@ -775,10 +782,10 @@ }, "pluggy": { "hashes": [ - "sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095", - "sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f" + "sha256:8ddc32f03971bfdf900a81961a48ccf2fb677cf7715108f85295c67405798616", + "sha256:980710797ff6a041e9a73a5787804f848996ecaa6f8a1b1e08224a5894f2074a" ], - "version": "==0.8.0" + "version": "==0.8.1" }, "prompt-toolkit": { "hashes": [ @@ -827,11 +834,11 @@ }, "pytest-cov": { "hashes": [ - "sha256:513c425e931a0344944f84ea47f3956be0e416d95acbd897a44970c8d926d5d7", - "sha256:e360f048b7dae3f2f2a9a4d067b2dd6b6a015d384d1577c994a43f3f7cbad762" + "sha256:0ab664b25c6aa9716cbf203b17ddb301932383046082c081b9848a0edf5add33", + "sha256:230ef817450ab0699c6cc3c9c8f7a829c34674456f2ed8df1fe1d39780f7c87f" ], "index": "pypi", - "version": "==2.6.0" + "version": "==2.6.1" }, "pytest-env": { "hashes": [ @@ -924,30 +931,30 @@ }, "typed-ast": { "hashes": [ - "sha256:0555eca1671ebe09eb5f2176723826f6f44cca5060502fea259de9b0e893ab53", - "sha256:0ca96128ea66163aea13911c9b4b661cb345eb729a20be15c034271360fc7474", - "sha256:16ccd06d614cf81b96de42a37679af12526ea25a208bce3da2d9226f44563868", - "sha256:1e21ae7b49a3f744958ffad1737dfbdb43e1137503ccc59f4e32c4ac33b0bd1c", - "sha256:37670c6fd857b5eb68aa5d193e14098354783b5138de482afa401cc2644f5a7f", - "sha256:46d84c8e3806619ece595aaf4f37743083f9454c9ea68a517f1daa05126daf1d", - "sha256:5b972bbb3819ece283a67358103cc6671da3646397b06e7acea558444daf54b2", - "sha256:6306ffa64922a7b58ee2e8d6f207813460ca5a90213b4a400c2e730375049246", - "sha256:6cb25dc95078931ecbd6cbcc4178d1b8ae8f2b513ae9c3bd0b7f81c2191db4c6", - "sha256:7e19d439fee23620dea6468d85bfe529b873dace39b7e5b0c82c7099681f8a22", - "sha256:7f5cd83af6b3ca9757e1127d852f497d11c7b09b4716c355acfbebf783d028da", - "sha256:81e885a713e06faeef37223a5b1167615db87f947ecc73f815b9d1bbd6b585be", - "sha256:94af325c9fe354019a29f9016277c547ad5d8a2d98a02806f27a7436b2da6735", - "sha256:b1e5445c6075f509d5764b84ce641a1535748801253b97f3b7ea9d948a22853a", - "sha256:cb061a959fec9a514d243831c514b51ccb940b58a5ce572a4e209810f2507dcf", - "sha256:cc8d0b703d573cbabe0d51c9d68ab68df42a81409e4ed6af45a04a95484b96a5", - "sha256:da0afa955865920edb146926455ec49da20965389982f91e926389666f5cf86a", - "sha256:dc76738331d61818ce0b90647aedde17bbba3d3f9e969d83c1d9087b4f978862", - "sha256:e7ec9a1445d27dbd0446568035f7106fa899a36f55e52ade28020f7b3845180d", - "sha256:f741ba03feb480061ab91a465d1a3ed2d40b52822ada5b4017770dfcb88f839f", - "sha256:fe800a58547dd424cd286b7270b967b5b3316b993d86453ede184a17b5a6b17d" + "sha256:023625bfa9359e29bd6e24cac2a4503495b49761d48a5f1e38333fc4ac4d93fe", + "sha256:07591f7a5fdff50e2e566c4c1e9df545c75d21e27d98d18cb405727ed0ef329c", + "sha256:153e526b0f4ffbfada72d0bb5ffe8574ba02803d2f3a9c605c8cf99dfedd72a2", + "sha256:3ad2bdcd46a4a1518d7376e9f5016d17718a9ed3c6a3f09203d832f6c165de4a", + "sha256:3ea98c84df53ada97ee1c5159bb3bc784bd734231235a1ede14c8ae0775049f7", + "sha256:51a7141ccd076fa561af107cfb7a8b6d06a008d92451a1ac7e73149d18e9a827", + "sha256:52c93cd10e6c24e7ac97e8615da9f224fd75c61770515cb323316c30830ddb33", + "sha256:6344c84baeda3d7b33e157f0b292e4dd53d05ddb57a63f738178c01cac4635c9", + "sha256:64699ca1b3bd5070bdeb043e6d43bc1d0cebe08008548f4a6bee782b0ecce032", + "sha256:74903f2e56bbffe29282ef8a5487d207d10be0f8513b41aff787d954a4cf91c9", + "sha256:7891710dba83c29ee2bd51ecaa82f60f6bede40271af781110c08be134207bf2", + "sha256:91976c56224e26c256a0de0f76d2004ab885a29423737684b4f7ebdd2f46dde2", + "sha256:9bad678a576ecc71f25eba9f1e3fd8d01c28c12a2834850b458428b3e855f062", + "sha256:b4726339a4c180a8b6ad9d8b50d2b6dc247e1b79b38fe2290549c98e82e4fd15", + "sha256:ba36f6aa3f8933edf94ea35826daf92cbb3ec248b89eccdc053d4a815d285357", + "sha256:bbc96bde544fd19e9ef168e4dfa5c3dfe704bfa78128fa76f361d64d6b0f731a", + "sha256:c0c927f1e44469056f7f2dada266c79b577da378bbde3f6d2ada726d131e4824", + "sha256:c0f9a3708008aa59f560fa1bd22385e05b79b8e38e0721a15a8402b089243442", + "sha256:f0bf6f36ff9c5643004171f11d2fdc745aa3953c5aacf2536a0685db9ceb3fb1", + "sha256:f5be39a0146be663cbf210a4d95c3c58b2d7df7b043c9047c5448e358f0550a2", + "sha256:fcd198bf19d9213e5cbf2cde2b9ef20a9856e716f76f9476157f90ae6de06cc6" ], "markers": "python_version < '3.7' and implementation_name == 'cpython'", - "version": "==1.1.1" + "version": "==1.2.0" }, "urllib3": { "hashes": [ @@ -978,9 +985,9 @@ }, "wrapt": { "hashes": [ - "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6" + "sha256:e03f19f64d81d0a3099518ca26b04550026f131eced2e76ced7b85c6b8d32128" ], - "version": "==1.10.11" + "version": "==1.11.0" } } } diff --git a/tests/routes/portfolios/test_task_orders.py b/tests/routes/portfolios/test_task_orders.py new file mode 100644 index 00000000..1b2c6aba --- /dev/null +++ b/tests/routes/portfolios/test_task_orders.py @@ -0,0 +1,62 @@ +from flask import url_for +import pytest + +from tests.factories import ( + PortfolioFactory, + TaskOrderFactory, + random_future_date, + random_past_date, +) +from tests.utils import captured_templates + + +class TestPortfolioFunding: + def test_unfunded_portfolio(self, app, user_session): + portfolio = PortfolioFactory.create() + user_session(portfolio.owner) + + with captured_templates(app) as templates: + response = app.test_client().get( + url_for("portfolios.portfolio_funding", portfolio_id=portfolio.id) + ) + + assert response.status_code == 200 + _, context = templates[0] + assert context["funding_end_date"] is None + assert context["total_balance"] == 0 + assert context["pending_task_orders"] == [] + assert context["active_task_orders"] == [] + assert context["expired_task_orders"] == [] + + def test_funded_portfolio(self, app, user_session): + portfolio = PortfolioFactory.create() + user_session(portfolio.owner) + + pending_to = TaskOrderFactory.create(portfolio=portfolio) + active_to1 = TaskOrderFactory.create( + portfolio=portfolio, + start_date=random_past_date(), + end_date=random_future_date(), + number="42", + ) + active_to2 = TaskOrderFactory.create( + portfolio=portfolio, + start_date=random_past_date(), + end_date=random_future_date(), + number="43", + ) + end_date = ( + active_to1.end_date + if active_to1.end_date > active_to2.end_date + else active_to2.end_date + ) + + with captured_templates(app) as templates: + response = app.test_client().get( + url_for("portfolios.portfolio_funding", portfolio_id=portfolio.id) + ) + + assert response.status_code == 200 + _, context = templates[0] + assert context["funding_end_date"] is end_date + assert context["total_balance"] == active_to1.budget + active_to2.budget diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..c590136e --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,16 @@ +from flask import template_rendered +from contextlib import contextmanager + + +@contextmanager +def captured_templates(app): + recorded = [] + + def record(sender, template, context, **extra): + recorded.append((template, context)) + + template_rendered.connect(record, app) + try: + yield recorded + finally: + template_rendered.disconnect(record, app)