Enable debug mode in tests.

Debug mode allows route integration tests to raise explicit exceptions on
errors, instead of returning error pages. Some portions of the test
suite need to be able to ignore exceptions (the response is not under
test) so they use a separate pytest fixture version of the app and
client that are configured with debug disabled, as it would be in
production.
This commit is contained in:
dandds 2019-08-29 13:07:24 -04:00
parent 094e44a6b0
commit 883947b75f
8 changed files with 82 additions and 32 deletions

View File

@ -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"
}

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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)
)

View File

@ -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()

View File

@ -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

View File

@ -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() != {}