def test_for_user_does_not_return_inactive_portfolios(portfolio, portfolio_owner): bob = UserFactory.create() Portfolios.add_member(portfolio, bob) PortfolioFactory.create() bobs_portfolios = Portfolios.for_user(bob) assert len(bobs_portfolios) == 0
def test_for_user_returns_active_portfolios_for_user(portfolio, portfolio_owner): bob = UserFactory.create() PortfolioRoleFactory.create(user=bob, portfolio=portfolio, status=PortfolioRoleStatus.ACTIVE) PortfolioFactory.create() bobs_portfolios = Portfolios.for_user(bob) assert len(bobs_portfolios) == 1
def test_portfolio_audit_log_only_includes_current_portfolio_events(): owner = UserFactory.create() portfolio = PortfolioFactory.create(owner=owner) other_portfolio = PortfolioFactory.create(owner=owner) # Add some audit events application_1 = ApplicationFactory.create(portfolio=portfolio) application_2 = ApplicationFactory.create(portfolio=other_portfolio) events = AuditLog.get_portfolio_events(portfolio) for event in events: assert event.portfolio_id == portfolio.id assert (not event.portfolio_id == other_portfolio.id or event.resource_id == other_portfolio.id)
def test_unexpired_invite_is_revokable(): portfolio = PortfolioFactory.create() user = UserFactory.create() portfolio_role = PortfolioRoleFactory.create( portfolio=portfolio, user=user, status=PortfolioRoleStatus.PENDING) invite = PortfolioInvitationFactory.create(role=portfolio_role) assert invite.is_revokable
def test_create_does_not_duplicate_names_within_portfolio(): portfolio = PortfolioFactory.create() name = "An Awesome Application" assert Applications.create(portfolio.owner, portfolio, name, "") with pytest.raises(AlreadyExistsError): Applications.create(portfolio.owner, portfolio, name, "")
def test_portfolio_admin_screen_when_ppoc(client, user_session): portfolio = PortfolioFactory.create() user_session(portfolio.owner) response = client.get(url_for("portfolios.admin", portfolio_id=portfolio.id)) assert response.status_code == 200 assert portfolio.name in response.data.decode() assert translate("fragments.ppoc.update_btn").encode("utf8") in response.data
def test_cannot_update_portfolio_ppoc_perms(client, user_session): portfolio = PortfolioFactory.create() ppoc = portfolio.owner ppoc_pf_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=ppoc.id) user = UserFactory.create() PortfolioRoleFactory.create(portfolio=portfolio, user=user) user_session(user) assert ppoc_pf_role.has_permission_set(PermissionSets.PORTFOLIO_POC) member_perms_data = { "members_permissions-0-member_id": ppoc_pf_role.id, "members_permissions-0-perms_app_mgmt": "view_portfolio_application_management", "members_permissions-0-perms_funding": "view_portfolio_funding", "members_permissions-0-perms_reporting": "view_portfolio_reports", "members_permissions-0-perms_portfolio_mgmt": "view_portfolio_admin", } response = client.post( url_for("portfolios.edit_members", portfolio_id=portfolio.id), data=member_perms_data, follow_redirects=True, ) assert response.status_code == 404 assert ppoc_pf_role.has_permission_set(PermissionSets.PORTFOLIO_POC)
def test_user_can_access_decorator_application_level(set_current_user, request_ctx): ccpo = UserFactory.create_ccpo() port_admin = UserFactory.create() app_user = UserFactory.create() rando = UserFactory.create() portfolio = PortfolioFactory.create(owner=port_admin, applications=[{ "name": "Mos Eisley" }]) app = portfolio.applications[0] ApplicationRoleFactory.create(application=app, user=app_user) request_ctx.g.portfolio = portfolio request_ctx.g.application = app @user_can_access_decorator(Permissions.VIEW_APPLICATION) def _stroll_into_mos_eisley(*args, **kwargs): return True set_current_user(ccpo) assert _stroll_into_mos_eisley(application_id=app.id) set_current_user(port_admin) assert _stroll_into_mos_eisley(application_id=app.id) set_current_user(app_user) assert _stroll_into_mos_eisley(application_id=app.id) set_current_user(rando) with pytest.raises(UnauthorizedError): _stroll_into_mos_eisley(application_id=app.id)
def test_portfolio_reports_with_mock_portfolio(client, user_session): portfolio = PortfolioFactory.create(name="A-Wing") user_session(portfolio.owner) response = client.get( url_for("portfolios.reports", portfolio_id=portfolio.id)) assert response.status_code == 200 assert portfolio.name in response.data.decode()
def test_monthly_totals(): portfolio = PortfolioFactory.create() monthly = Reports.monthly_totals(portfolio) assert not monthly["environments"] assert not monthly["applications"] assert not monthly["portfolio"]
def test_create_adds_clins(): portfolio = PortfolioFactory.create() clins = [ { "jedi_clin_type": "JEDI_CLIN_1", "number": "12312", "start_date": date(2020, 1, 1), "end_date": date(2021, 1, 1), "obligated_amount": Decimal("5000"), "total_amount": Decimal("10000"), }, { "jedi_clin_type": "JEDI_CLIN_1", "number": "12312", "start_date": date(2020, 1, 1), "end_date": date(2021, 1, 1), "obligated_amount": Decimal("5000"), "total_amount": Decimal("10000"), }, ] task_order = TaskOrders.create( creator=portfolio.owner, portfolio_id=portfolio.id, number="0123456789", clins=clins, pdf={ "filename": "sample.pdf", "object_name": "1234567" }, ) assert len(task_order.clins) == 2
def test_can_only_update_name_and_description(): owner = UserFactory.create() portfolio = PortfolioFactory.create( owner=owner, applications=[{ "name": "Application 1", "description": "a application", "environments": [{ "name": "dev" }], }], ) application = Applications.get(portfolio.applications[0].id) env_name = application.environments[0].name Applications.update( application, { "name": "New Name", "description": "a new application", "environment_name": "prod", }, ) assert application.name == "New Name" assert application.description == "a new application" assert len(application.environments) == 1 assert application.environments[0].name == env_name
def test_dispatch_create_environment(session, monkeypatch): # Given that I have a portfolio with an active CLIN and two environments, # one of which is deleted portfolio = PortfolioFactory.create( applications=[{ "environments": [{}, {}] }], task_orders=[{ "create_clins": [{ "start_date": pendulum.now().subtract(days=1), "end_date": pendulum.now().add(days=1), }] }], ) [e1, e2] = portfolio.applications[0].environments e2.deleted = True session.add(e2) session.commit() mock = Mock() monkeypatch.setattr("atst.jobs.create_environment", mock) # When dispatch_create_environment is called dispatch_create_environment.run() # It should cause the create_environment task to be called once with the # non-deleted environment mock.delay.assert_called_once_with(environment_id=e1.id)
def test_user_can_access_decorator_portfolio_level(set_current_user, request_ctx): ccpo = UserFactory.create_ccpo() edit_admin = UserFactory.create() view_admin = UserFactory.create() portfolio = PortfolioFactory.create(owner=edit_admin) # factory gives view perms by default PortfolioRoleFactory.create(user=view_admin, portfolio=portfolio) request_ctx.g.portfolio = portfolio request_ctx.g.application = None @user_can_access_decorator(Permissions.EDIT_PORTFOLIO_NAME) def _edit_portfolio_name(*args, **kwargs): return True set_current_user(ccpo) assert _edit_portfolio_name(portfolio_id=portfolio.id) set_current_user(edit_admin) assert _edit_portfolio_name(portfolio_id=portfolio.id) set_current_user(view_admin) with pytest.raises(UnauthorizedError): _edit_portfolio_name(portfolio_id=portfolio.id)
def test_create_environment_no_dupes(session, celery_app, celery_worker): portfolio = PortfolioFactory.create( applications=[{ "environments": [{ "cloud_id": uuid4().hex, "root_user_info": {}, "baseline_info": None, }] }], task_orders=[{ "create_clins": [{ "start_date": pendulum.now().subtract(days=1), "end_date": pendulum.now().add(days=1), }] }], ) environment = portfolio.applications[0].environments[0] # create_environment is run twice on the same environment create_environment.run(environment_id=environment.id) session.refresh(environment) first_cloud_id = environment.cloud_id create_environment.run(environment_id=environment.id) session.refresh(environment) # The environment's cloud_id was not overwritten in the second run assert environment.cloud_id == first_cloud_id # The environment's claim was released assert environment.claimed_until == None
def test_remove_portfolio_member_ppoc(client, user_session): portfolio = PortfolioFactory.create() user = UserFactory.create() PortfolioRoleFactory.create( portfolio=portfolio, user=user, permission_sets=[ PermissionSets.get(PermissionSets.EDIT_PORTFOLIO_ADMIN) ], ) ppoc_port_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=portfolio.owner.id) user_session(user) response = client.post( url_for( "portfolios.remove_member", portfolio_id=portfolio.id, portfolio_role_id=ppoc_port_role.id, ), follow_redirects=False, ) assert response.status_code == 404 assert (PortfolioRoles.get( portfolio_id=portfolio.id, user_id=portfolio.owner.id).status == PortfolioRoleStatus.ACTIVE)
def task_order(): user = UserFactory.create() portfolio = PortfolioFactory.create(owner=user) task_order = TaskOrderFactory.create(portfolio=portfolio) CLINFactory.create(task_order=task_order) return task_order
def test_rerender_admin_page_if_member_perms_form_does_not_validate( client, user_session, monkeypatch): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create( user=user, portfolio=portfolio, permission_sets=[ PermissionSets.get(PermissionSets.EDIT_PORTFOLIO_ADMIN) ], ) user_session(user) form_data = { "members_permissions-0-member_id": role.id, "members_permissions-0-perms_app_mgmt": "bad input", "members_permissions-0-perms_funding": "view_portfolio_funding", "members_permissions-0-perms_reporting": "view_portfolio_reports", "members_permissions-0-perms_portfolio_mgmt": "view_portfolio_admin", } 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) mock_route.assert_called()
def test_remove_portfolio_member(client, user_session): portfolio = PortfolioFactory.create() user = UserFactory.create() member = PortfolioRoleFactory.create(portfolio=portfolio, user=user) user_session(portfolio.owner) response = client.post( url_for( "portfolios.remove_member", portfolio_id=portfolio.id, portfolio_role_id=member.id, ), follow_redirects=False, ) assert response.status_code == 302 assert response.headers["Location"] == url_for( "portfolios.admin", portfolio_id=portfolio.id, _anchor="portfolio-members", fragment="portfolio-members", _external=True, ) assert (PortfolioRoles.get( portfolio_id=portfolio.id, user_id=user.id).status == PortfolioRoleStatus.DISABLED)
def test_get_name_and_description_form(client, user_session): portfolio = PortfolioFactory.create() user_session(portfolio.owner) response = client.get( url_for("applications.view_new_application_step_1", portfolio_id=portfolio.id)) assert response.status_code == 200
def test_get_portfolio_events_includes_app_and_env_events(): owner = UserFactory.create() # add portfolio level events portfolio = PortfolioFactory.create(owner=owner) portfolio_events = AuditLog.get_portfolio_events(portfolio) # add application level events application = ApplicationFactory.create(portfolio=portfolio) Applications.update(application, {"name": "Star Cruiser"}) app_role = ApplicationRoleFactory.create(application=application) app_invite = ApplicationInvitationFactory.create(role=app_role) portfolio_and_app_events = AuditLog.get_portfolio_events(portfolio) assert len(portfolio_events) < len(portfolio_and_app_events) # add environment level events env = EnvironmentFactory.create(application=application) env_role = EnvironmentRoleFactory.create(environment=env, application_role=app_role) portfolio_app_and_env_events = AuditLog.get_portfolio_events(portfolio) assert len(portfolio_and_app_events) < len(portfolio_app_and_env_events) resource_types = [event.resource_type for event in portfolio_app_and_env_events] assert "application" in resource_types assert "application_role" in resource_types assert "application_invitation" in resource_types assert "environment" in resource_types assert "environment_role" in resource_types
def test_for_user(): user = UserFactory.create() portfolio = PortfolioFactory.create() for _x in range(4): ApplicationFactory.create(portfolio=portfolio) ApplicationRoleFactory.create( application=portfolio.applications[0], user=user, status=ApplicationRoleStatus.ACTIVE, ) ApplicationRoleFactory.create( application=portfolio.applications[1], user=user, status=ApplicationRoleStatus.ACTIVE, ) ApplicationRoleFactory.create( application=portfolio.applications[2], user=user, status=ApplicationRoleStatus.PENDING, ) assert len(portfolio.applications) == 4 user_applications = Applications.for_user(user, portfolio) assert len(user_applications) == 2
def test_update_does_not_duplicate_names_within_portfolio(): portfolio = PortfolioFactory.create() name = "An Awesome Application" application = ApplicationFactory.create(portfolio=portfolio, name=name) dupe_application = ApplicationFactory.create(portfolio=portfolio) with pytest.raises(AlreadyExistsError): Applications.update(dupe_application, {"name": name})
def test_delete_success(): portfolio = PortfolioFactory.create() assert not portfolio.deleted Portfolios.delete(portfolio=portfolio) assert portfolio.deleted
def test_invite_is_not_revokable_if_invite_is_not_pending(): portfolio = PortfolioFactory.create() user = UserFactory.create() portfolio_role = PortfolioRoleFactory.create( portfolio=portfolio, user=user, status=PortfolioRoleStatus.PENDING) invite = PortfolioInvitationFactory.create( role=portfolio_role, status=InvitationStatus.ACCEPTED) assert not invite.is_revokable
def test_get_application_monthly_totals(): portfolio = PortfolioFactory.create(applications=[{ "name": "Test Application", "environments": [{ "name": "Z" }, { "name": "A" }] }], ) application = { "name": "Test Application", "environments": [ { "name": "Z", "spending": { "this_month": { "JEDI_CLIN_1": 50, "JEDI_CLIN_2": 50 }, "last_month": { "JEDI_CLIN_1": 150, "JEDI_CLIN_2": 150 }, "total": { "JEDI_CLIN_1": 250, "JEDI_CLIN_2": 250 }, }, }, { "name": "A", "spending": { "this_month": { "JEDI_CLIN_1": 100, "JEDI_CLIN_2": 100 }, "last_month": { "JEDI_CLIN_1": 200, "JEDI_CLIN_2": 200 }, "total": { "JEDI_CLIN_1": 1000, "JEDI_CLIN_2": 1000 }, }, }, ], } totals = MockReportingProvider._get_application_monthly_totals( portfolio, application) assert totals["name"] == "Test Application" assert totals["this_month"] == 300 assert totals["last_month"] == 700 assert totals["total"] == 2500 assert [env["name"] for env in totals["environments"]] == ["A", "Z"]
def test_claim_for_update(session): portfolio = PortfolioFactory.create( applications=[{ "environments": [{ "cloud_id": uuid4().hex, "root_user_info": {}, "baseline_info": None, }] }], task_orders=[{ "create_clins": [{ "start_date": pendulum.now().subtract(days=1), "end_date": pendulum.now().add(days=1), }] }], ) environment = portfolio.applications[0].environments[0] satisfied_claims = [] exceptions = [] # Two threads race to do work on environment and check out the lock class FirstThread(Thread): def run(self): try: with claim_for_update(environment): satisfied_claims.append("FirstThread") except ClaimFailedException: exceptions.append("FirstThread") class SecondThread(Thread): def run(self): try: with claim_for_update(environment): satisfied_claims.append("SecondThread") except ClaimFailedException: exceptions.append("SecondThread") t1 = FirstThread() t2 = SecondThread() t1.start() t2.start() t1.join() t2.join() session.refresh(environment) assert len(satisfied_claims) == 1 assert len(exceptions) == 1 if satisfied_claims == ["FirstThread"]: assert exceptions == ["SecondThread"] else: assert satisfied_claims == ["SecondThread"] assert exceptions == ["FirstThread"] # The claim is released assert environment.claimed_until is None
def test_disabled_members_dont_show_up(session): portfolio = PortfolioFactory.create() PortfolioRoleFactory.create(portfolio=portfolio, status=PortfolioRoleStatus.ACTIVE) PortfolioRoleFactory.create(portfolio=portfolio, status=PortfolioRoleStatus.DISABLED) # should only return portfolio owner and ACTIVE member assert len(portfolio.members) == 2
def test_does_not_count_disabled_members(session): portfolio = PortfolioFactory.create() PortfolioRoleFactory.create(portfolio=portfolio, status=PortfolioRoleStatus.ACTIVE) PortfolioRoleFactory.create(portfolio=portfolio) PortfolioRoleFactory.create(portfolio=portfolio, status=PortfolioRoleStatus.DISABLED) assert portfolio.user_count == 3
def test_revoke_ppoc_permissions(): portfolio = PortfolioFactory.create() portfolio_role = PortfolioRoles.get(portfolio_id=portfolio.id, user_id=portfolio.owner.id) assert Permissions.EDIT_PORTFOLIO_POC in portfolio_role.permissions PortfolioRoles.revoke_ppoc_permissions(portfolio_role=portfolio_role) assert Permissions.EDIT_PORTFOLIO_POC not in portfolio_role.permissions