import flask import pytest from pytest_lazyfixture import lazy_fixture import sqlalchemy from flask import url_for from werkzeug.datastructures import ImmutableMultiDict from atlas_um.helpers import either from atlas_um import tasks from atlas_um.dna_accounts.forms import ( BaseProductForm, DNAAccountForm, product_form_factory, ) from atlas_um.dna_accounts.services import ( UpdateDNAAccountClaimsService, DisableDNAAccountClaimsService, ) from atlas_um.helpers.ordering import QueryOrdering from atlas_um.helpers.pagination import QueryPagination from atlas_um.pgdb import DNAAccount, Product from atlas_um.pgdb import DNAAccountStatuses from atlas_um.pgdb.queries.dna_account import DNAAccountQuery from tests.atlas_um import factories from tests.atlas_um.factories import ( ClaimValueFactory, ClaimNameFactory, ResourceGroupFactory, ) from tests.atlas_um.factories import DNAAccountFactory from tests.atlas_um.pytest_helpers import ( get_default_users_list_ordering, UrlForThisMixin, ) class TestViews(UrlForThisMixin): ENDPOINT = "dna_accounts.list" def test_list_accounts_failure_authentication(self, app): with app.test_client() as client: resp = client.get(url_for("dna_accounts.list")) assert resp.status_code == 302 def test_list_accounts_failure_authorization(self, app, authenticated): with app.test_client() as client: resp = client.get(url_for("dna_accounts.list")) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_list_accounts_no_access(self, app, authorized_user, status): with app.test_client() as client: resp = client.get(url_for("dna_accounts.list")) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_list_accounts_no_param( self, app, faker, mocker, pgdb_session, authorized_user ): accounts_count = faker.pyint(min_value=2, max_value=10) accounts = DNAAccountFactory.build_batch(accounts_count) for account in accounts: pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get(url_for("dna_accounts.list")) assert resp.status_code == 200 mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=list(reversed(accounts)), pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, resource_groups=mocked_active, tags=mocked_tags, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_list_accounts_pagination_default_page( self, app, faker, mocker, pgdb_session, authorized_user ): per_page = 10 accounts_count = faker.pyint(min_value=20, max_value=50) accounts = DNAAccountFactory.build_batch(accounts_count) for account in accounts: pgdb_session.add(account) pgdb_session.commit() accounts = list(reversed(accounts)) mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get(url_for("dna_accounts.list", per_page=per_page)) assert resp.status_code == 200 mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=accounts[:per_page], pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts[:per_page]), status="", DNAAccountStatuses=DNAAccountStatuses, resource_groups=mocked_active, tags=mocked_tags, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_list_accounts_pagination_specific_page( self, app, faker, mocker, pgdb_session, authorized_user ): per_page = 10 page = 2 accounts_count = faker.pyint(min_value=20, max_value=50) accounts = DNAAccountFactory.build_batch(accounts_count) for account in accounts: pgdb_session.add(account) pgdb_session.commit() accounts = list(reversed(accounts)) mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get( url_for("dna_accounts.list", per_page=per_page, page=page) ) assert resp.status_code == 200 mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=accounts[ per_page * (page - 1) : per_page * page # noqa ], pagination=QueryPagination(), ordering=get_default_users_list_ordering( accounts[per_page * (page - 1) : per_page * page], # noqa ), status="", DNAAccountStatuses=DNAAccountStatuses, resource_groups=mocked_active, tags=mocked_tags, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_accounts_export_no_access(self, app, authorized_user, status): with app.test_client() as client: resp = client.get(url_for("dna_accounts.export")) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_accounts_export( self, app, faker, mocker, pgdb_session, authorized_user ): mocked_dna_accounts_and_assigned_claims = mocker.patch( "atlas_um.dna_accounts.reports.dna_accounts_and_assigned_claims" ) test_data = [ ("col1", "col2", "col3"), ("col1_value", "col2_value", "col3_value"), ("col1_value", "col2_value", "col3_value"), ] expected_response_body = ( "col1,col2,col3\r\n" "col1_value,col2_value,col3_value\r\n" "col1_value,col2_value,col3_value\r\n" ) mocked_dna_accounts_and_assigned_claims.return_value = test_data with app.test_client() as client: resp = client.get(url_for("dna_accounts.export")) assert mocked_dna_accounts_and_assigned_claims.called assert resp.status_code == 200 assert resp.mimetype == "text/csv" assert ( resp.headers["Content-Disposition"] == "attachment; filename=users.csv" ) assert resp.data.decode() == expected_response_body @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_search( self, app, faker, mocker, pgdb_session, authorized_user ): search_term = faker.first_name() accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) pgdb_session.commit() mocked_call = mocker.patch.object(DNAAccountQuery, "search") mocked_call.return_value = pgdb_session.query(DNAAccount).filter( sqlalchemy.sql.false() ) with app.test_client() as client: resp = client.get( url_for("dna_accounts.list", search_term=search_term) ) assert resp.status_code == 200 assert mocked_call.call_args_list == [mocker.call(search_term)] mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get( url_for("dna_accounts.list", search_term=search_term) ) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term=search_term, accounts=accounts, pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, resource_groups=mocked_active, tags=mocked_tags, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_product_filter( self, app, faker, mocker, pgdb_session, authorized_user ): resource_group_id = faker.pyint() accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) pgdb_session.commit() mocked_call = mocker.patch.object( DNAAccountQuery, "by_resource_group_id" ) mocked_call.return_value = pgdb_session.query(DNAAccount).filter( sqlalchemy.sql.false() ) with app.test_client() as client: resp = client.get( url_for( "dna_accounts.list", resource_group_id=resource_group_id ) ) assert resp.status_code == 200 assert mocked_call.call_args_list == [mocker.call(resource_group_id)] mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get( url_for( "dna_accounts.list", resource_group_id=resource_group_id ) ) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=list(reversed(accounts)), pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, tags=mocked_tags, resource_groups=mocked_active, resource_group_id=resource_group_id, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_affected( self, app, faker, mocker, pgdb_session, authorized_user ): resource_group_id = faker.pyint() accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) claim_value = factories.ClaimValueFactory.build() pgdb_session.add(claim_value) pgdb_session.commit() mocked_call = mocker.patch.object( DNAAccountQuery, "by_resource_group_id" ) mocked_call.return_value = pgdb_session.query(DNAAccount).filter( sqlalchemy.sql.false() ) with app.test_client() as client: resp = client.get( url_for( "dna_accounts.list", resource_group_id=resource_group_id ) ) assert resp.status_code == 200 assert mocked_call.call_args_list == [mocker.call(resource_group_id)] mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get( url_for( "dna_accounts.list", affected=f"claim_value_id:{claim_value.id}", ) ) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=list(reversed(accounts)), pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, tags=mocked_tags, resource_groups=mocked_active, resource_group_id=None, tag_id=None, affecting_instance=claim_value, token_size_violation=False, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_token_size_violation( self, app, faker, mocker, pgdb_session, authorized_user ): accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) claim_value = factories.ClaimValueFactory.build() pgdb_session.add(claim_value) pgdb_session.commit() mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.spy(flask, "render_template") account_violates_limit_mock = mocker.patch( "atlas_um.pgdb.dna_account.DNAAccount.account_violates_limit", new_callable=mocker.PropertyMock, ) mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get( url_for("dna_accounts.list", token_size_violation=True) ) assert account_violates_limit_mock.called assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=accounts, pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, tags=mocked_tags, resource_groups=mocked_active, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=True, expire_soon=False, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_expire_soon( self, app, faker, mocker, pgdb_session, authorized_user ): accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) claim_value = factories.ClaimValueFactory.build() pgdb_session.add(claim_value) pgdb_session.commit() mocker.patch.object( QueryOrdering, "query", new_callable=mocker.PropertyMock ).return_value = accounts mocker.patch.object( QueryPagination, "items", new_callable=mocker.PropertyMock ).return_value = accounts mocker.spy(flask, "render_template") mocked_active = mocker.patch( "atlas_um.pgdb.ResourceGroup.query" ).active.return_value.order_by.return_value mocked_tags = mocker.patch( "atlas_um.pgdb.Tag.query" ).active.return_value with app.test_client() as client: resp = client.get(url_for("dna_accounts.list", expire_soon=True)) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/list_dna_accounts.html", search_term="", accounts=accounts, pagination=QueryPagination(), ordering=get_default_users_list_ordering(accounts), status="", DNAAccountStatuses=DNAAccountStatuses, tags=mocked_tags, resource_groups=mocked_active, resource_group_id=None, tag_id=None, affecting_instance=None, token_size_violation=False, expire_soon=True, ) assert flask.render_template.call_args_list == [render_expects] def test_create_account_failure_authentication(self, app): with app.test_client() as client: resp = client.get(url_for("dna_accounts.create")) assert resp.status_code == 302 with app.test_client() as client: resp = client.post(url_for("dna_accounts.create")) assert resp.status_code == 302 def test_create_account_failure_authorization(self, app, authenticated): with app.test_client() as client: resp = client.get(url_for("dna_accounts.create")) assert resp.status_code == 401 with app.test_client() as client: resp = client.post(url_for("dna_accounts.create")) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_create_account_no_access(self, app, authorized_user, status): with app.test_client() as client: resp = client.get(url_for("dna_accounts.create")) assert resp.status_code == status with app.test_client() as client: resp = client.post(url_for("dna_accounts.create")) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_create_account_get( self, mocker, app, pgdb_session, authorized_user ): mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get(url_for("dna_accounts.create")) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): form = DNAAccountForm() render_expects = mocker.call( "dna_accounts/create_dna_account.html", form=form ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_create_account_post_success( self, mocker, app, pgdb_session, faker, authorized_user ): mocker.spy(flask, "render_template") mocker.spy(tasks, "sync_dna_account_with_auth0") with app.test_request_context(self.url_for_this(app)): business_unit = factories.BusinessUnitFactory.build() job_category = factories.JobCategoryFactory.build() personnel_type = factories.PersonnelTypeFactory.build() pgdb_session.add(business_unit) pgdb_session.add(job_category) pgdb_session.add(personnel_type) pgdb_session.commit() expected_data = { "action": DNAAccountForm.Actions.SAVE.name, "given_name": faker.first_name(), "family_name": faker.last_name(), "email": faker.email(), "is_sony_employee": True, "is_vip": True, "job_category": job_category, "business_unit": business_unit, "personnel_type": personnel_type, "expiration_date": faker.future_date(), "supervisor_email": faker.email(), "supervisor_name": faker.name(), "job_title": faker.pystr(), "location": faker.pystr(), "preferred_username": faker.pystr(), "no_mfa": False, "tags": [], } form = DNAAccountForm(data=expected_data) assert form.validate(), "Initial form should be valid" mocked_account = mocker.MagicMock() mocked_service_execute = mocker.patch( "atlas_um.dna_accounts.services." "CreateDNAAccountService.execute" ) mocked_service_execute.return_value = either.Right(mocked_account) with app.test_client() as client: resp = client.post( url_for("dna_accounts.create"), data=form.dump() ) service_expects = mocker.call(**expected_data) assert mocked_service_execute.call_args_list == [service_expects] assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.products", account_id=mocked_account.id ) @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_create_account_post_failure( self, mocker, app, pgdb_session, faker, authorized_user ): with app.test_request_context(self.url_for_this(app)): blank_form_fata = DNAAccountForm().dump(cleanup=True) form = DNAAccountForm(formdata=blank_form_fata) assert not form.validate(), "Initial form should be invalid" mocker.spy(flask, "render_template") mocked_account = mocker.MagicMock() mocked_service_execute = mocker.patch( "atlas_um.dna_accounts.services." "CreateDNAAccountService.execute" ) mocked_service_execute.return_value = either.Right(mocked_account) with app.test_client() as client: resp = client.post( url_for("dna_accounts.create"), data=blank_form_fata ) render_expects = mocker.call( "dna_accounts/create_dna_account.html", form=form ) assert not mocked_service_execute.called assert resp.status_code == 200 assert flask.render_template.call_args_list == [render_expects] def test_create_account_sync_with_auth0( self, app, authorized_admin, mocker ): mocked_form = mocker.patch( "atlas_um.dna_accounts.views.DNAAccountForm" ) mocked_form.return_value.validate_on_submit.return_value = True mocker.spy(tasks, "sync_dna_account_with_auth0") mocked_account = mocker.MagicMock() mocked_service_execute = mocker.patch( "atlas_um.dna_accounts.services." "CreateDNAAccountService.execute" ) mocked_service_execute.return_value = either.Right(mocked_account) with app.test_client() as client: client.post(url_for("dna_accounts.create")) assert tasks.sync_dna_account_with_auth0.delay.call_args_list == [ mocker.call(mocked_account.id) ] def test_account_autocomplete_search_failure_authentication(self, app): with app.test_client() as client: resp = client.get(url_for("dna_accounts.search")) assert resp.status_code == 302 def test_account_autocomplete_search_failure_authorization( self, app, authenticated ): with app.test_client() as client: resp = client.get(url_for("dna_accounts.search")) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_autocomplete_search_no_access(self, app, authorized_user, status): with app.test_client() as client: resp = client.get(url_for("dna_accounts.search")) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_autocomplete_search_with_term( self, app, faker, mocker, pgdb_session, authorized_user ): search_term = faker.first_name() accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) pgdb_session.commit() mocked_call = mocker.patch.object(DNAAccountQuery, "search") mocked_call.return_value = pgdb_session.query(DNAAccount).filter() mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get( url_for("dna_accounts.search", search_term=search_term) ) assert resp.status_code == 200 assert mocked_call.call_args_list == [mocker.call(search_term)] with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/search.html", recent_searches=None, search_results=DNAAccount.query.search(search_term), ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_account_autocomplete_search_without_term( self, app, faker, mocker, pgdb_session, authorized_user ): accounts = DNAAccountFactory.build_batch(faker.pyint(max_value=5)) for account in accounts: pgdb_session.add(account) pgdb_session.commit() mocked_call = mocker.patch.object(DNAAccountQuery, "by_ids") mocked_call.return_value = pgdb_session.query(DNAAccount).filter() mocker.spy(flask, "render_template") ids = [a.id for a in accounts] with app.test_client() as client: with client.session_transaction() as session: session["recent_account_searches"] = ids resp = client.get(url_for("dna_accounts.search")) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/search.html", recent_searches=DNAAccount.query.by_ids(ids), search_results=None, ) assert flask.render_template.call_args_list == [render_expects] def test_show_account_failure_authentication(self, app, pgdb_session): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.show", account_id=account.id) ) assert resp.status_code == 302 def test_show_account_failure_authorization( self, app, authenticated, pgdb_session ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.show", account_id=account.id) ) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_show_account_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.show", account_id=account.id) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_show_account(self, app, mocker, pgdb_session, authorized_user): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get( url_for("dna_accounts.show", account_id=account.id) ) actual_recent_accounts = flask.session["recent_account_searches"] assert resp.status_code == 200 render_expects = mocker.call( "dna_accounts/show_dna_account.html", account=account, DNAAccountStatuses=DNAAccountStatuses, ) assert flask.render_template.call_args_list == [render_expects] assert actual_recent_accounts == [account.id] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_show_account_failure( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get(url_for("dna_accounts.show", account_id=-1)) assert resp.status_code == 404 assert "recent_account_searches" not in flask.session def test_edit_account_failure_authentication(self, app, pgdb_session): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == 302 with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == 302 def test_edit_account_failure_authorization( self, app, authenticated, pgdb_session ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == 401 with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_edit_account_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == status with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_account_get( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get( url_for("dna_accounts.edit", account_id=account.id) ) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): form = DNAAccountForm(obj=account) render_expects = mocker.call( "dna_accounts/edit_dna_account.html", account=account, form=form, statuses=DNAAccountStatuses, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_account_get_failure( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get(url_for("dna_accounts.edit", account_id=-1)) assert resp.status_code == 404 @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_account_post_save_success( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") form = DNAAccountForm(obj=account) assert form.validate(), "Initial form should be valid" mocked_service = mocker.patch( "atlas_um.dna_accounts.services." "UpdateDNAAccountService.execute" ) mocked_service.return_value = either.Right(account) with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id), data=form.dump(), ) assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.show", account_id=account.id ) service_expects = mocker.call(account, **form.data) assert mocked_service.call_args_list == [service_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_account_post_save_failure( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") blank_form_fata = DNAAccountForm().dump(cleanup=True) form = DNAAccountForm(formdata=blank_form_fata, obj=account) assert not form.validate(), "Initial form should be invalid" mocked_service = mocker.patch( "atlas_um.dna_accounts.services.UpdateDNAAccountService.execute" ) with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id), data=blank_form_fata, ) assert resp.status_code == 200 with app.test_request_context(self.url_for_this(app)): render_expects = mocker.call( "dna_accounts/edit_dna_account.html", account=account, form=form, statuses=DNAAccountStatuses, ) assert flask.render_template.call_args_list == [render_expects] assert not mocked_service.called @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_account_post_suspend_success( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "render_template") form = DNAAccountForm( formdata=ImmutableMultiDict( {"action": DNAAccountForm.Actions.SUSPEND.name} ), obj=account, ) mocked_service = mocker.patch( "atlas_um.dna_accounts.services." "SuspendDNAAccountService.execute" ) with app.test_client() as client: resp = client.post( url_for("dna_accounts.edit", account_id=account.id), data=form.dump(), ) assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.show", account_id=account.id ) service_expects = mocker.call(account) assert mocked_service.call_args_list == [service_expects] def test_products_failure_authentication(self, app, pgdb_session): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == 302 def test_products__failure_authorization( self, app, authenticated, pgdb_session ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_get_products_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_products_success( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_name.resource_group.id, ) @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_show_product_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_products_failure( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for("dna_accounts.products", account_id=account.id) ) assert resp.status_code == 404 def test_show_product_failure_authentication(self, app, pgdb_session): account = DNAAccountFactory.build() claim_value = ClaimValueFactory.build(components={"value1": 1}) pgdb_session.add(account) pgdb_session.add(claim_value) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_value.claim_name.resource_group.id, ) ) assert resp.status_code == 302 def test_show_product_failure_authorization( self, app, authenticated, pgdb_session ): account = DNAAccountFactory.build() claim_value = ClaimValueFactory.build(components={"value1": 1}) pgdb_session.add(account) pgdb_session.add(claim_value) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_value.claim_name.resource_group.id, ) ) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_show_product_success( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() product = Product( resource_group=claim_name.resource_group, account=account ) mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get( url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_name.resource_group.id, ) ) assert resp.status_code == 200 render_expects = mocker.call( "dna_accounts/show_product.html", account=account, product=product, DNAAccountStatuses=DNAAccountStatuses, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_show_product_failure( self, app, faker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() wrong_code = claim_name.resource_group.id + 1 with app.test_client() as client: resp = client.get( url_for( "dna_accounts.show_product", account_id=account.id, product_code=wrong_code, ) ) assert claim_name.resource_group.id != wrong_code assert resp.status_code == 404 def test_edit_product_failure_authentication(self, app, pgdb_session): account = DNAAccountFactory.build() claim_value = ClaimValueFactory.build(components={"value1": 1}) pgdb_session.add(account) pgdb_session.add(claim_value) pgdb_session.commit() url = url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_value.claim_name.resource_group.id, ) with app.test_client() as client: resp = client.get(url) assert resp.status_code == 302 with app.test_client() as client: resp = client.post(url) assert resp.status_code == 302 def test_edit_product_failure_authorization( self, app, authenticated, pgdb_session ): account = DNAAccountFactory.build() claim_value = ClaimValueFactory.build(components={"value1": 1}) pgdb_session.add(account) pgdb_session.add(claim_value) pgdb_session.commit() url = url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_value.claim_name.resource_group.id, ) with app.test_client() as client: resp = client.get(url) assert resp.status_code == 401 with app.test_client() as client: resp = client.post(url) assert resp.status_code == 401 @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_edit_product_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() claim_value = ClaimValueFactory.build(components={"value1": 1}) pgdb_session.add(claim_value) pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.get( url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_value.claim_name.resource_group.id, ) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_product_get( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() product = Product( resource_group=claim_name.resource_group, account=account ) form = product_form_factory(product) mocker.spy(flask, "render_template") with app.test_client() as client: resp = client.get( url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_name.resource_group.id, ) ) assert resp.status_code == 200 render_expects = mocker.call( "dna_accounts/edit_product.html", account=account, product=product, form=form, ) assert flask.render_template.call_args_list == [render_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_product_post_save_success( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() product = Product( resource_group=claim_name.resource_group, account=account ) form = product_form_factory( product, formdata=ImmutableMultiDict( { "action": BaseProductForm.Actions.SAVE.name, claim_name.internal_name: str(claim_value.id), } ), ) assert form.validate(), "Initial form should be valid" mocked_service = mocker.patch( "atlas_um.dna_accounts.services.UpdateDNAAccountClaimsService." "execute" ) with app.test_client() as client: resp = client.post( url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_name.resource_group.id, ), data=form.dump(), ) assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_name.resource_group.id, ) service_expects = mocker.call( account, form.claim_values, claim_name.resource_group ) assert mocked_service.call_args_list == [service_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_product_post_disable_success( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() product = Product( resource_group=claim_name.resource_group, account=account ) form = product_form_factory( product, formdata=ImmutableMultiDict( { "action": BaseProductForm.Actions.DISABLE.name, claim_name.internal_name: str(claim_value.id), } ), ) assert form.validate(), "Initial form should be valid" mocked_service = mocker.patch( "atlas_um.dna_accounts.services." "DisableDNAAccountClaimsService.execute" ) with app.test_client() as client: resp = client.post( url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_name.resource_group.id, ), data=form.dump(), ) assert resp.status_code == 302 assert resp.location == url_for( "dna_accounts.show_product", account_id=account.id, product_code=claim_name.resource_group.id, ) service_expects = mocker.call( account, account.claim_values, claim_name.resource_group ) assert mocked_service.call_args_list == [service_expects] @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_edit_product_post_failure( self, app, mocker, pgdb_session, authorized_user ): with app.test_request_context(self.url_for_this(app)): account = DNAAccountFactory.build() pgdb_session.add(account) claim_name = ClaimNameFactory.build( claim_values_serializer="BooleanAnd" ) claim_value = ClaimValueFactory.build( claim_name=claim_name, components={"value1": 1} ) pgdb_session.add(claim_value) pgdb_session.commit() product = Product( resource_group=claim_name.resource_group, account=account ) form = product_form_factory(product) assert not form.validate(), "Initial form should be invalid" mocker.spy(UpdateDNAAccountClaimsService, "execute") mocker.spy(DisableDNAAccountClaimsService, "execute") with app.test_client() as client: resp = client.post( url_for( "dna_accounts.edit_product", account_id=account.id, product_code=claim_name.resource_group.id, ), data=form.dump(cleanup=True), ) assert resp.status_code == 200 assert not UpdateDNAAccountClaimsService.execute.called assert not DisableDNAAccountClaimsService.execute.called @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_send_invitation_success( self, app, mocker, pgdb_session, authorized_user, faker ): resource_group = ResourceGroupFactory.build() pgdb_session.add(resource_group) account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(flask, "redirect") mocker.spy(tasks, "send_dna_invitation") assert not account.invitation_is_sent with app.test_client() as client: resp = client.post( url_for( "dna_accounts.send_invitation", account_id=account.id, resource_group_id=resource_group.id, ) ) assert resp.status_code == 302 assert flask.redirect.call_args_list == [ mocker.call( flask.url_for( "dna_accounts.show", account_id=account.id, _external=False ) ) ] assert tasks.send_dna_invitation.delay.call_args_list == [ mocker.call(account.id, None, str(resource_group.id)) ] @pytest.mark.parametrize( "authorized_user, status", [ (lazy_fixture("authorized_developer"), 401), ], ) def test_send_invitation_no_access( self, app, pgdb_session, authorized_user, status ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() with app.test_client() as client: resp = client.post( url_for( "dna_accounts.send_invitation", account_id=account.id, ) ) assert resp.status_code == status @pytest.mark.parametrize( "authorized_user", [ lazy_fixture("authorized_admin"), lazy_fixture("authorized_manager"), ], ) def test_send_invitation_failure( self, app, mocker, pgdb_session, authorized_user ): account = DNAAccountFactory.build() pgdb_session.add(account) pgdb_session.commit() mocker.spy(tasks, "send_dna_invitation") with app.test_client() as client: resp = client.post( url_for("dna_accounts.send_invitation", account_id=-1) ) assert resp.status_code == 404 assert not tasks.send_dna_invitation.delay.called