diff --git a/.secrets.baseline b/.secrets.baseline index 814fd704..36866487 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "^.secrets.baseline$", "lines": null }, - "generated_at": "2019-08-28T19:50:39Z", + "generated_at": "2019-08-29T17:03:11Z", "plugins_used": [ { "base64_limit": 4.5, @@ -194,11 +194,10 @@ "hashed_secret": "e4f14805dfd1e6af030359090c535e149e6b4207", "is_secret": false, "is_verified": false, - "line_number": 523, + "line_number": 544, "type": "Hex High Entropy String" } ] }, "version": "0.12.5" } - diff --git a/config/test.ini b/config/test.ini index c39d4de4..c323f599 100644 --- a/config/test.ini +++ b/config/test.ini @@ -1,7 +1,8 @@ [default] -DEBUG = false +DEBUG = true ENVIRONMENT = test PGDATABASE = atat_test CRL_STORAGE_CONTAINER = tests/fixtures/crl WTF_CSRF_ENABLED = false STORAGE_PROVIDER=LOCAL +PRESERVE_CONTEXT_ON_EXCEPTION = false diff --git a/tests/conftest.py b/tests/conftest.py index cede1f3c..9a667936 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -28,13 +28,7 @@ dictConfig({"version": 1, "handlers": {"wsgi": {"class": "logging.NullHandler"}} @pytest.fixture(scope="session") def app(request): - upload_dir = TemporaryDirectory() - config = make_config() - config.update( - {"STORAGE_CONTAINER": upload_dir.name, "CRL_STORAGE_PROVIDER": "LOCAL"} - ) - _app = make_app(config) ctx = _app.app_context() @@ -42,11 +36,27 @@ def app(request): yield _app - upload_dir.cleanup() + ctx.pop() + + +@pytest.fixture(scope="function") +def no_debug_app(request): + config = make_config(direct_config={"DEBUG": False}) + _app = make_app(config) + + ctx = _app.app_context() + ctx.push() + + yield _app ctx.pop() +@pytest.fixture(scope="function") +def no_debug_client(no_debug_app): + yield no_debug_app.test_client() + + def apply_migrations(): """Applies all alembic migrations.""" alembic_config = os.path.join(os.path.dirname(__file__), "../", "alembic.ini") diff --git a/tests/routes/portfolios/test_admin.py b/tests/routes/portfolios/test_admin.py index 52ae1965..312ab2ee 100644 --- a/tests/routes/portfolios/test_admin.py +++ b/tests/routes/portfolios/test_admin.py @@ -1,5 +1,5 @@ from flask import url_for -from unittest.mock import Mock +from unittest.mock import MagicMock from atst.domain.permission_sets import PermissionSets from atst.domain.portfolio_roles import PortfolioRoles @@ -129,7 +129,7 @@ def test_rerender_admin_page_if_member_perms_form_does_not_validate( "members_permissions-0-perms_portfolio_mgmt": "view_portfolio_admin", } - mock_route = Mock() + mock_route = MagicMock(return_value=("", 200, {})) monkeypatch.setattr("atst.routes.portfolios.admin.render_admin_page", mock_route) client.post( url_for("portfolios.edit_members", portfolio_id=portfolio.id), data=form_data diff --git a/tests/routes/portfolios/test_index.py b/tests/routes/portfolios/test_index.py index e54e2a23..153ea406 100644 --- a/tests/routes/portfolios/test_index.py +++ b/tests/routes/portfolios/test_index.py @@ -1,4 +1,5 @@ from flask import url_for +import pytest from tests.factories import ( random_future_date, @@ -9,7 +10,7 @@ from tests.factories import ( UserFactory, ) from atst.utils.localization import translate -from atst.domain.portfolios import Portfolios +from atst.domain.portfolios import Portfolios, PortfolioDeletionApplicationsExistError from atst.domain.portfolios.query import PortfoliosQuery @@ -128,7 +129,7 @@ def test_delete_portfolio_success(client, user_session): assert len(Portfolios.for_user(user=owner)) == 0 -def test_delete_portfolio_failure(client, user_session): +def test_delete_portfolio_failure(no_debug_client, user_session): portfolio = PortfolioFactory.create() application = ApplicationFactory.create(portfolio=portfolio) owner = portfolio.owner @@ -136,7 +137,7 @@ def test_delete_portfolio_failure(client, user_session): assert len(Portfolios.for_user(user=owner)) == 1 - response = client.post( + response = no_debug_client.post( url_for("portfolios.delete_portfolio", portfolio_id=portfolio.id) ) diff --git a/tests/routes/test_errors.py b/tests/routes/test_errors.py index f5b0289e..caf7fc0e 100644 --- a/tests/routes/test_errors.py +++ b/tests/routes/test_errors.py @@ -1,6 +1,8 @@ import pytest from flask import url_for -from copy import copy + +from atst.app import make_config, make_app + from tests.factories import UserFactory @@ -24,14 +26,28 @@ def test_csrf_error(csrf_enabled_app, client): assert "Log in required" in body -def test_errors_generate_notifications(app, client, user_session, notification_sender): - user_session(UserFactory.create()) - new_app = copy(app) +@pytest.fixture +def blowup_app(notification_sender): + _blowup_app = make_app(make_config(direct_config={"DEBUG": False})) + _blowup_app.notification_sender = notification_sender - @new_app.route("/throw") + @_blowup_app.route("/throw") def throw(): raise ValueError() - new_app.test_client().get("/throw") + yield _blowup_app + + +@pytest.fixture +def blowup_client(blowup_app): + yield blowup_app.test_client() + + +def test_errors_generate_notifications( + blowup_client, client, user_session, notification_sender +): + user_session(UserFactory.create()) + + blowup_client.get("/throw") notification_sender.send.assert_called_once() diff --git a/tests/test_access.py b/tests/test_access.py index 7da4868e..787742a2 100644 --- a/tests/test_access.py +++ b/tests/test_access.py @@ -12,6 +12,9 @@ from atst.models import CSPRole, PortfolioRoleStatus, ApplicationRoleStatus from tests.factories import * + +from atst.app import make_config, make_app + _NO_ACCESS_CHECK_REQUIRED = _NO_LOGIN_REQUIRED + [ "applications.accept_invitation", # available to all users; access control is built into invitation logic "atst.catch_all", # available to all users @@ -90,21 +93,39 @@ def user_with(*perm_sets_names): return UserFactory.create(permission_sets=PermissionSets.get_many(perm_sets_names)) +@pytest.fixture(scope="session") +def app(request): + config = make_config(direct_config={"DEBUG": False}) + _app = make_app(config) + + ctx = _app.app_context() + ctx.push() + + yield _app + + ctx.pop() + + +@pytest.fixture(scope="session") +def client(app): + yield app.test_client() + + @pytest.fixture -def get_url_assert_status(client, user_session): +def get_url_assert_status(no_debug_client, user_session): def _get_url_assert_status(user, url, status): user_session(user) - resp = client.get(url) + resp = no_debug_client.get(url) assert resp.status_code == status return _get_url_assert_status @pytest.fixture -def post_url_assert_status(client, user_session): +def post_url_assert_status(no_debug_client, user_session): def _get_url_assert_status(user, url, status, data=None): user_session(user) - resp = client.post(url, data=data) + resp = no_debug_client.post(url, data=data) assert resp.status_code == status return _get_url_assert_status diff --git a/tests/utils/test_context_processors.py b/tests/utils/test_context_processors.py index e2802b4e..73a26cbc 100644 --- a/tests/utils/test_context_processors.py +++ b/tests/utils/test_context_processors.py @@ -1,3 +1,5 @@ +from unittest.mock import Mock + import pytest from atst.domain.permission_sets import PermissionSets @@ -33,16 +35,15 @@ def test_get_resources_from_context(): @pytest.fixture -def set_g(request_ctx): +def set_g(monkeypatch): + _g = Mock() + monkeypatch.setattr("atst.utils.context_processors.g", _g) + def _set_g(attr, val): - setattr(request_ctx.g, attr, val) + setattr(_g, attr, val) yield _set_g - setattr(request_ctx.g, "application", None) - setattr(request_ctx.g, "portfolio", None) - setattr(request_ctx.g, "current_user", None) - def test_user_can_view(set_g): owner = UserFactory.create() @@ -77,4 +78,5 @@ def test_portfolio_no_user(set_g): def test_portfolio_with_user(set_g): user = UserFactory.create() set_g("current_user", user) + set_g("portfolio", None) assert portfolio_context() != {}