diff --git a/atst/routes/applications/new.py b/atst/routes/applications/new.py index 41c750aa..a1a1a54c 100644 --- a/atst/routes/applications/new.py +++ b/atst/routes/applications/new.py @@ -157,6 +157,10 @@ def view_new_application_step_3(application_id): @applications_bp.route("/applications//new/step_3", methods=["POST"]) +@applications_bp.route( + "/applications//new/step_3/member/", + methods=["POST"], +) @user_can(Permissions.CREATE_APPLICATION, message="view create new application form") def update_new_application_step_3(application_id, application_role_id=None): if application_role_id: diff --git a/tests/conftest.py b/tests/conftest.py index dce493ae..8c22ddc3 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,7 @@ import alembic.command from logging.config import dictConfig from werkzeug.datastructures import FileStorage from collections import OrderedDict +from unittest.mock import Mock from atst.app import make_app, make_config from atst.database import db as _db diff --git a/tests/routes/applications/test_new.py b/tests/routes/applications/test_new.py index c39f48d5..c4fb83ed 100644 --- a/tests/routes/applications/test_new.py +++ b/tests/routes/applications/test_new.py @@ -1,6 +1,11 @@ from flask import url_for -from tests.factories import PortfolioFactory, ApplicationFactory, UserFactory +from tests.factories import ( + PortfolioFactory, + ApplicationFactory, + UserFactory, + ApplicationRoleFactory, +) from unittest.mock import Mock from atst.forms.data import ENV_ROLE_NO_ACCESS as NO_ACCESS from atst.models.application_invitation import ApplicationInvitation @@ -109,7 +114,7 @@ def test_get_members(client, session, user_session): assert response.status_code == 200 -def test_post_member(monkeypatch, client, user_session, session): +def test_post_new_member(monkeypatch, client, user_session, session): job_mock = Mock() monkeypatch.setattr("atst.jobs.send_mail.delay", job_mock) user = UserFactory.create() @@ -121,7 +126,9 @@ def test_post_member(monkeypatch, client, user_session, session): user_session(application.portfolio.owner) response = client.post( - url_for("applications.create_member", application_id=application.id), + url_for( + "applications.update_new_application_step_3", application_id=application.id + ), data={ "user_data-first_name": user.first_name, "user_data-last_name": user.last_name, @@ -141,10 +148,8 @@ def test_post_member(monkeypatch, client, user_session, session): assert response.status_code == 302 expected_url = url_for( - "applications.settings", + "applications.view_new_application_step_3", application_id=application.id, - fragment="application-members", - _anchor="application-members", _external=True, ) assert response.location == expected_url @@ -159,3 +164,43 @@ def test_post_member(monkeypatch, client, user_session, session): assert invitation.role.application == application assert job_mock.called + + +def test_post_update_member(client, user_session): + user = UserFactory.create() + application = ApplicationFactory.create( + environments=[{"name": "Naboo"}, {"name": "Endor"}] + ) + (env, env_1) = application.environments + app_role = ApplicationRoleFactory(application=application) + + user_session(application.portfolio.owner) + response = client.post( + url_for( + "applications.update_new_application_step_3", + application_id=application.id, + application_role_id=app_role.id, + ), + data={ + "environment_roles-0-environment_id": env.id, + "environment_roles-0-role": "Basic Access", + "environment_roles-0-environment_name": env.name, + "environment_roles-1-environment_id": env_1.id, + "environment_roles-1-role": NO_ACCESS, + "environment_roles-1-environment_name": env_1.name, + "perms_env_mgmt": True, + "perms_team_mgmt": True, + "perms_del_env": True, + }, + ) + + assert response.status_code == 302 + expected_url = url_for( + "applications.view_new_application_step_3", + application_id=application.id, + _external=True, + ) + assert response.location == expected_url + assert len(application.roles) == 1 + assert len(app_role.environment_roles) == 1 + assert app_role.environment_roles[0].environment == env diff --git a/tests/routes/applications/test_settings.py b/tests/routes/applications/test_settings.py index 8eb0079b..3b1c5f63 100644 --- a/tests/routes/applications/test_settings.py +++ b/tests/routes/applications/test_settings.py @@ -2,6 +2,8 @@ import uuid from flask import url_for, get_flashed_messages from unittest.mock import Mock import datetime +from werkzeug.datastructures import ImmutableMultiDict +import pytest from tests.factories import * @@ -20,6 +22,8 @@ from atst.routes.applications.settings import ( filter_env_roles_form_data, filter_env_roles_data, get_environments_obj_for_app, + handle_create_member, + handle_update_member, ) from tests.utils import captured_templates @@ -658,3 +662,89 @@ def test_filter_env_roles_data(): # ensure that the environment roles and environments are associated with the # same application. assert [env["environment_name"] for env in env_role_data] == ["a", "b", "c"] + + +@pytest.fixture +def set_g(monkeypatch): + _g = Mock() + monkeypatch.setattr("atst.app.g", _g) + monkeypatch.setattr("atst.routes.applications.settings.g", _g) + + def _set_g(attr, val): + setattr(_g, attr, val) + + yield _set_g + + +def test_handle_create_member(monkeypatch, set_g, session): + user = UserFactory.create() + application = ApplicationFactory.create( + environments=[{"name": "Naboo"}, {"name": "Endor"}] + ) + (env, env_1) = application.environments + + job_mock = Mock() + monkeypatch.setattr("atst.jobs.send_mail.delay", job_mock) + set_g("current_user", application.portfolio.owner) + set_g("portfolio", application.portfolio) + set_g("application", application) + + form_data = ImmutableMultiDict( + { + "user_data-first_name": user.first_name, + "user_data-last_name": user.last_name, + "user_data-dod_id": user.dod_id, + "user_data-email": user.email, + "environment_roles-0-environment_id": env.id, + "environment_roles-0-role": "Basic Access", + "environment_roles-0-environment_name": env.name, + "environment_roles-1-environment_id": env_1.id, + "environment_roles-1-role": NO_ACCESS, + "environment_roles-1-environment_name": env_1.name, + "perms_env_mgmt": True, + "perms_team_mgmt": True, + "perms_del_env": True, + } + ) + handle_create_member(application.id, form_data) + + assert len(application.roles) == 1 + environment_roles = application.roles[0].environment_roles + assert len(environment_roles) == 1 + assert environment_roles[0].environment == env + invitation = ( + session.query(ApplicationInvitation).filter_by(dod_id=user.dod_id).one() + ) + assert invitation.role.application == application + assert job_mock.called + + +def test_handle_update_member(set_g): + user = UserFactory.create() + application = ApplicationFactory.create( + environments=[{"name": "Naboo"}, {"name": "Endor"}] + ) + (env, env_1) = application.environments + app_role = ApplicationRoleFactory(application=application) + set_g("current_user", application.portfolio.owner) + set_g("portfolio", application.portfolio) + set_g("application", application) + + form_data = ImmutableMultiDict( + { + "environment_roles-0-environment_id": env.id, + "environment_roles-0-role": "Basic Access", + "environment_roles-0-environment_name": env.name, + "environment_roles-1-environment_id": env_1.id, + "environment_roles-1-role": NO_ACCESS, + "environment_roles-1-environment_name": env_1.name, + "perms_env_mgmt": True, + "perms_team_mgmt": True, + "perms_del_env": True, + } + ) + handle_update_member(application.id, app_role.id, form_data) + + assert len(application.roles) == 1 + assert len(app_role.environment_roles) == 1 + assert app_role.environment_roles[0].environment == env