Example #1
0
def test_funding_duration(session):
    # portfolio with active task orders
    portfolio = PortfolioFactory()

    funding_start_date = random_past_date()
    funding_end_date = random_future_date(year_min=2)

    TaskOrderFactory.create(
        signed_at=random_past_date(),
        portfolio=portfolio,
        create_clins=[{
            "start_date": funding_start_date,
            "end_date": random_future_date(year_max=1),
        }],
    )
    TaskOrderFactory.create(
        portfolio=portfolio,
        signed_at=random_past_date(),
        create_clins=[{
            "start_date": datetime.datetime.now(),
            "end_date": funding_end_date,
        }],
    )

    assert portfolio.funding_duration == (funding_start_date, funding_end_date)

    # empty portfolio
    empty_portfolio = PortfolioFactory()
    assert empty_portfolio.funding_duration == (None, None)
Example #2
0
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
Example #3
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
Example #4
0
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)
Example #5
0
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
Example #6
0
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, "")
Example #7
0
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
Example #8
0
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)
Example #9
0
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)
Example #10
0
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()
Example #11
0
def test_monthly_totals():
    portfolio = PortfolioFactory.create()
    monthly = Reports.monthly_totals(portfolio)

    assert not monthly["environments"]
    assert not monthly["applications"]
    assert not monthly["portfolio"]
Example #12
0
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
Example #13
0
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
Example #14
0
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
Example #15
0
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
Example #16
0
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
Example #17
0
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)
Example #18
0
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)
Example #19
0
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)
Example #20
0
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()
Example #21
0
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
Example #22
0
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)
Example #23
0
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
Example #24
0
def test_delete_success():
    portfolio = PortfolioFactory.create()

    assert not portfolio.deleted

    Portfolios.delete(portfolio=portfolio)

    assert portfolio.deleted
Example #25
0
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})
Example #26
0
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
Example #27
0
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
Example #28
0
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"]
Example #29
0
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
Example #30
0
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