atst/tests/domain/test_portfolios.py
dandds df06d1b62f Use application_role_id on environment_roles.
In the future, an `application_invitation1 will not refer to a `user` until
someone accepts the invitation; they'll only reference an
`application_role`. When a user is invited to an application, the
inviter can specify the environments the invitee should have access to.
For this to be possible, an `environment_role` should reference an
`application_role`, because no `user` entity will be known at that time.

In addition to updating all the models and domain methods necessary for
this change, this commit deletes unused code and tests that were
dependent on `environment_roles` having a `user_id` foreign key.
2019-05-31 11:21:20 -04:00

241 lines
7.7 KiB
Python

import pytest
from uuid import uuid4
from atst.domain.exceptions import NotFoundError, UnauthorizedError
from atst.domain.portfolios import Portfolios, PortfolioError
from atst.domain.portfolio_roles import PortfolioRoles
from atst.domain.applications import Applications
from atst.domain.environments import Environments
from atst.domain.permission_sets import PermissionSets, PORTFOLIO_PERMISSION_SETS
from atst.models.application_role import Status as ApplicationRoleStatus
from atst.models.portfolio_role import Status as PortfolioRoleStatus
from tests.factories import (
ApplicationFactory,
ApplicationRoleFactory,
UserFactory,
PortfolioRoleFactory,
PortfolioFactory,
get_all_portfolio_permission_sets,
)
@pytest.fixture(scope="function")
def portfolio_owner():
return UserFactory.create()
@pytest.fixture(scope="function")
def portfolio(portfolio_owner):
portfolio = PortfolioFactory.create(owner=portfolio_owner)
return portfolio
def test_can_create_portfolio():
portfolio = PortfolioFactory.create(name="frugal-whale")
assert portfolio.name == "frugal-whale"
def test_get_nonexistent_portfolio_raises():
with pytest.raises(NotFoundError):
Portfolios.get(UserFactory.build(), uuid4())
def test_creating_portfolio_adds_owner(portfolio, portfolio_owner):
assert portfolio.roles[0].user == portfolio_owner
def test_portfolio_has_timestamps(portfolio):
assert portfolio.time_created == portfolio.time_updated
def test_can_create_portfolio_role(portfolio, portfolio_owner):
user_data = {
"first_name": "New",
"last_name": "User",
"email": "new.user@mail.com",
"portfolio_role": "developer",
"dod_id": "1234567890",
}
new_member = Portfolios.create_member(portfolio, user_data)
assert new_member.portfolio == portfolio
assert new_member.user.provisional
def test_can_add_existing_user_to_portfolio(portfolio, portfolio_owner):
user = UserFactory.create()
user_data = {
"first_name": "New",
"last_name": "User",
"email": "new.user@mail.com",
"portfolio_role": "developer",
"dod_id": user.dod_id,
}
new_member = Portfolios.create_member(portfolio, user_data)
assert new_member.portfolio == portfolio
assert new_member.user.email == user.email
assert not new_member.user.provisional
def test_update_portfolio_role_role(portfolio, portfolio_owner):
user_data = {
"first_name": "New",
"last_name": "User",
"email": "new.user@mail.com",
"portfolio_role": "developer",
"dod_id": "1234567890",
}
PortfolioRoleFactory._meta.sqlalchemy_session_persistence = "flush"
member = PortfolioRoleFactory.create(portfolio=portfolio)
permission_sets = [PermissionSets.EDIT_PORTFOLIO_FUNDING]
updated_member = Portfolios.update_member(member, permission_sets=permission_sets)
assert updated_member.portfolio == portfolio
def test_scoped_portfolio_for_admin_missing_view_apps_perms(portfolio_owner, portfolio):
Applications.create(
portfolio, "My Application 2", "My application 2", ["dev", "staging", "prod"]
)
restricted_admin = UserFactory.create()
PortfolioRoleFactory.create(
portfolio=portfolio,
user=restricted_admin,
permission_sets=[PermissionSets.get(PermissionSets.VIEW_PORTFOLIO)],
)
scoped_portfolio = Portfolios.get(restricted_admin, portfolio.id)
assert scoped_portfolio.id == portfolio.id
assert len(portfolio.applications) == 1
assert len(scoped_portfolio.applications) == 0
def test_scoped_portfolio_returns_all_applications_for_portfolio_admin(
portfolio, portfolio_owner
):
for _ in range(5):
Applications.create(
portfolio, "My Application", "My application", ["dev", "staging", "prod"]
)
admin = UserFactory.create()
perm_sets = get_all_portfolio_permission_sets()
PortfolioRoleFactory.create(
user=admin, portfolio=portfolio, permission_sets=perm_sets
)
scoped_portfolio = Portfolios.get(admin, portfolio.id)
assert len(scoped_portfolio.applications) == 5
assert len(scoped_portfolio.applications[0].environments) == 3
def test_scoped_portfolio_returns_all_applications_for_portfolio_owner(
portfolio, portfolio_owner
):
for _ in range(5):
Applications.create(
portfolio, "My Application", "My application", ["dev", "staging", "prod"]
)
scoped_portfolio = Portfolios.get(portfolio_owner, portfolio.id)
assert len(scoped_portfolio.applications) == 5
assert len(scoped_portfolio.applications[0].environments) == 3
def test_for_user_returns_portfolios_for_applications_user_invited_to():
bob = UserFactory.create()
portfolio = PortfolioFactory.create()
application = ApplicationFactory.create(portfolio=portfolio)
ApplicationRoleFactory.create(
application=application, user=bob, status=ApplicationRoleStatus.ACTIVE
)
assert portfolio in Portfolios.for_user(user=bob)
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_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_all_portfolios_for_ccpo(portfolio, portfolio_owner):
sam = UserFactory.create_ccpo()
PortfolioFactory.create()
sams_portfolios = Portfolios.for_user(sam)
assert len(sams_portfolios) == 2
def test_can_create_portfolios_with_matching_names():
portfolio_name = "Great Portfolio"
PortfolioFactory.create(name=portfolio_name)
PortfolioFactory.create(name=portfolio_name)
def test_able_to_revoke_portfolio_access_for_active_member():
portfolio = PortfolioFactory.create()
portfolio_role = PortfolioRoleFactory.create(
portfolio=portfolio, status=PortfolioRoleStatus.ACTIVE
)
Portfolios.revoke_access(portfolio.id, portfolio_role.id)
assert Portfolios.for_user(portfolio_role.user) == []
def test_can_revoke_access():
portfolio = PortfolioFactory.create()
owner_role = portfolio.roles[0]
portfolio_role = PortfolioRoleFactory.create(
portfolio=portfolio, status=PortfolioRoleStatus.ACTIVE
)
assert Portfolios.can_revoke_access_for(portfolio, portfolio_role)
assert not Portfolios.can_revoke_access_for(portfolio, owner_role)
def test_unable_to_revoke_owner_portfolio_access():
portfolio = PortfolioFactory.create()
owner_portfolio_role = portfolio.roles[0]
with pytest.raises(PortfolioError):
Portfolios.revoke_access(portfolio.id, owner_portfolio_role.id)
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