Applications users were invited to were not showing in the portfolios

sidebar
This commit is contained in:
George Drummond 2019-05-20 15:18:26 -04:00
parent 42900a20a6
commit 6487fe91ba
No known key found for this signature in database
GPG Key ID: 296DD6077123BF17
7 changed files with 41 additions and 28 deletions

View File

@ -2,6 +2,11 @@ from atst.database import db
from atst.domain.common import Query from atst.domain.common import Query
from atst.models.portfolio import Portfolio from atst.models.portfolio import Portfolio
from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus
from atst.models.application_role import (
ApplicationRole,
Status as ApplicationRoleStatus,
)
from atst.models.application import Application
class PortfoliosQuery(Query): class PortfoliosQuery(Query):
@ -9,7 +14,24 @@ class PortfoliosQuery(Query):
@classmethod @classmethod
def get_for_user(cls, user): def get_for_user(cls, user):
return ( granted_applications = (
db.session.query(Application)
.join(ApplicationRole)
.filter(ApplicationRole.application_id == Application.id)
.filter(ApplicationRole.user_id == user.id)
.filter(ApplicationRole.status == ApplicationRoleStatus.ACTIVE)
.subquery()
)
application_portfolios = (
db.session.query(Portfolio)
.join(Application)
.filter(Portfolio.id == Application.portfolio_id)
.filter(Application.id == granted_applications.c.id)
.all()
)
portfolios = (
db.session.query(Portfolio) db.session.query(Portfolio)
.join(PortfolioRole) .join(PortfolioRole)
.filter(PortfolioRole.user == user) .filter(PortfolioRole.user == user)
@ -17,6 +39,18 @@ class PortfoliosQuery(Query):
.all() .all()
) )
portfolio_ids = []
[portfolio_ids.append(p.id) for p in portfolios]
[portfolio_ids.append(p.id) for p in application_portfolios]
return (
db.session.query(Portfolio)
.filter(Portfolio.id.in_(portfolio_ids))
.order_by(Portfolio.name.desc())
.all()
)
@classmethod @classmethod
def create_portfolio_role(cls, user, portfolio, **kwargs): def create_portfolio_role(cls, user, portfolio, **kwargs):
return PortfolioRole(user=user, portfolio=portfolio, **kwargs) return PortfolioRole(user=user, portfolio=portfolio, **kwargs)

View File

@ -1,6 +1,6 @@
from datetime import date, timedelta from datetime import date, timedelta
from flask import render_template, request as http_request, g, redirect, url_for from flask import render_template, request as http_request, g
from . import portfolios_bp from . import portfolios_bp
from atst.domain.reports import Reports from atst.domain.reports import Reports
@ -19,14 +19,6 @@ def portfolios():
return render_template("portfolios/blank_slate.html") return render_template("portfolios/blank_slate.html")
@portfolios_bp.route("/portfolios/<portfolio_id>")
@user_can(Permissions.VIEW_PORTFOLIO, message="view portfolio")
def show_portfolio(portfolio_id):
return redirect(
url_for("applications.portfolio_applications", portfolio_id=portfolio_id)
)
@portfolios_bp.route("/portfolios/<portfolio_id>/reports") @portfolios_bp.route("/portfolios/<portfolio_id>/reports")
@user_can(Permissions.VIEW_PORTFOLIO_REPORTS, message="view portfolio reports") @user_can(Permissions.VIEW_PORTFOLIO_REPORTS, message="view portfolio reports")
def reports(portfolio_id): def reports(portfolio_id):

View File

@ -30,7 +30,7 @@ def accept_invitation(portfolio_token):
) )
return redirect( return redirect(
url_for("portfolios.show_portfolio", portfolio_id=invite.portfolio.id) url_for("applications.portfolio_applications", portfolio_id=invite.portfolio.id)
) )

View File

@ -145,7 +145,7 @@ MESSAGES = {
"actions": """ "actions": """
{% from "components/icon.html" import Icon %} {% from "components/icon.html" import Icon %}
<div class='alert__actions'> <div class='alert__actions'>
<a href='{{ url_for("portfolios.show_portfolio", portfolio_id=portfolio.id) }}' class='icon-link'> <a href='{{ url_for("applications.portfolio_applications", portfolio_id=portfolio.id) }}' class='icon-link'>
{{ Icon('shield') }} {{ Icon('shield') }}
<span>{{ "flash.portfolio_home" | translate }}</span> <span>{{ "flash.portfolio_home" | translate }}</span>
</a> </a>

View File

@ -21,7 +21,7 @@
{% if portfolios %} {% if portfolios %}
{% for other_portfolio in portfolios|sort(attribute='name') %} {% for other_portfolio in portfolios|sort(attribute='name') %}
{{ SidenavItem(other_portfolio.name, {{ SidenavItem(other_portfolio.name,
href=url_for("portfolios.show_portfolio", portfolio_id=other_portfolio.id), href=url_for("applications.portfolio_applications", portfolio_id=other_portfolio.id),
active=(other_portfolio.id | string) == request.view_args.get('portfolio_id') active=(other_portfolio.id | string) == request.view_args.get('portfolio_id')
) }} ) }}
{% endfor %} {% endfor %}

View File

@ -34,7 +34,7 @@ def test_existing_member_accepts_valid_invite(client, user_session):
# user is redirected to the portfolio view # user is redirected to the portfolio view
assert response.status_code == 302 assert response.status_code == 302
assert ( assert (
url_for("portfolios.show_portfolio", portfolio_id=invite.portfolio.id) url_for("applications.portfolio_applications", portfolio_id=invite.portfolio.id)
in response.headers["Location"] in response.headers["Location"]
) )
# the one-time use invite is no longer usable # the one-time use invite is no longer usable
@ -77,7 +77,7 @@ def test_new_member_accepts_valid_invite(monkeypatch, client, user_session):
# user is redirected to the portfolio view # user is redirected to the portfolio view
assert response.status_code == 302 assert response.status_code == 302
assert ( assert (
url_for("portfolios.show_portfolio", portfolio_id=portfolio.id) url_for("applications.portfolio_applications", portfolio_id=portfolio.id)
in response.headers["Location"] in response.headers["Location"]
) )
# the user has access to the portfolio # the user has access to the portfolio

View File

@ -466,19 +466,6 @@ def test_portfolios_revoke_invitation_access(post_url_assert_status):
post_url_assert_status(user, url, status) post_url_assert_status(user, url, status)
# portfolios.show_portfolio
def test_portfolios_show_portfolio_access(get_url_assert_status):
ccpo = user_with(PermissionSets.VIEW_PORTFOLIO)
owner = user_with()
rando = user_with()
portfolio = PortfolioFactory.create(owner=owner)
url = url_for("portfolios.show_portfolio", portfolio_id=portfolio.id)
get_url_assert_status(ccpo, url, 302)
get_url_assert_status(owner, url, 302)
get_url_assert_status(rando, url, 404)
# task_orders.so_review # task_orders.so_review
def test_task_orders_so_review_access(get_url_assert_status): def test_task_orders_so_review_access(get_url_assert_status):
ccpo = UserFactory.create_ccpo() ccpo = UserFactory.create_ccpo()