mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 20:18:38 +02:00
Fix portfolio transfer
This commit is contained in:
parent
6a196665dd
commit
e1e812c5c7
4 changed files with 60 additions and 51 deletions
|
@ -6,7 +6,7 @@ from django.db.models import Q
|
|||
from django.http import HttpRequest
|
||||
|
||||
from registrar.models import DomainInformation, UserDomainRole
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices
|
||||
|
||||
from .domain_invitation import DomainInvitation
|
||||
from .portfolio_invitation import PortfolioInvitation
|
||||
|
@ -64,32 +64,6 @@ class User(AbstractUser):
|
|||
# after they login.
|
||||
FIXTURE_USER = "fixture_user", "Created by fixtures"
|
||||
|
||||
PORTFOLIO_ROLE_PERMISSIONS = {
|
||||
UserPortfolioRoleChoices.ORGANIZATION_ADMIN: [
|
||||
UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS,
|
||||
UserPortfolioPermissionChoices.VIEW_MEMBER,
|
||||
UserPortfolioPermissionChoices.EDIT_MEMBER,
|
||||
UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS,
|
||||
UserPortfolioPermissionChoices.EDIT_REQUESTS,
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
# Domain: field specific permissions
|
||||
UserPortfolioPermissionChoices.VIEW_SUBORGANIZATION,
|
||||
UserPortfolioPermissionChoices.EDIT_SUBORGANIZATION,
|
||||
],
|
||||
UserPortfolioRoleChoices.ORGANIZATION_ADMIN_READ_ONLY: [
|
||||
UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS,
|
||||
UserPortfolioPermissionChoices.VIEW_MEMBER,
|
||||
UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS,
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
# Domain: field specific permissions
|
||||
UserPortfolioPermissionChoices.VIEW_SUBORGANIZATION,
|
||||
],
|
||||
UserPortfolioRoleChoices.ORGANIZATION_MEMBER: [
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
],
|
||||
}
|
||||
|
||||
# #### Constants for choice fields ####
|
||||
RESTRICTED = "restricted"
|
||||
STATUS_CHOICES = ((RESTRICTED, RESTRICTED),)
|
||||
|
|
|
@ -111,6 +111,18 @@
|
|||
None
|
||||
{% endif %}
|
||||
</dd>
|
||||
<dt>Portfolios:</dt>
|
||||
<dd>
|
||||
{% if selected_user_portfolios %}
|
||||
<ul>
|
||||
{% for portfolio in selected_user_portfolios %}
|
||||
<li>{{ portfolio.portfolio }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
None
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
||||
{% else %}
|
||||
<p>No user selected yet.</p>
|
||||
|
@ -167,6 +179,18 @@
|
|||
None
|
||||
{% endif %}
|
||||
</dd>
|
||||
<dt>Portfolios:</dt>
|
||||
<dd>
|
||||
{% if current_user_portfolios %}
|
||||
<ul>
|
||||
{% for portfolio in current_user_portfolios %}
|
||||
<li>{{ portfolio.portfolio }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
None
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -45,7 +45,8 @@ from registrar.models import (
|
|||
from registrar.models.portfolio_invitation import PortfolioInvitation
|
||||
from registrar.models.senior_official import SeniorOfficial
|
||||
from registrar.models.user_domain_role import UserDomainRole
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
|
||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||
from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
|
||||
from registrar.models.verified_by_staff import VerifiedByStaff
|
||||
from .common import (
|
||||
MockDbForSharedTests,
|
||||
|
@ -2162,6 +2163,14 @@ class TestTransferUser(WebTest):
|
|||
)
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.APPROVED
|
||||
domain_request.save()
|
||||
portfolio1 = Portfolio.objects.create(organization_name="Hotel California", creator=self.user2)
|
||||
UserPortfolioPermission.objects.create(
|
||||
user=self.user1, portfolio=portfolio1, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||
)
|
||||
portfolio2 = Portfolio.objects.create(organization_name="Tokyo Hotel", creator=self.user2)
|
||||
UserPortfolioPermission.objects.create(
|
||||
user=self.user2, portfolio=portfolio2, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||
)
|
||||
|
||||
user_transfer_page = self.app.get(reverse("transfer_user", args=[self.user1.pk]))
|
||||
|
||||
|
@ -2171,6 +2180,7 @@ class TestTransferUser(WebTest):
|
|||
self.assertContains(user_transfer_page, "Road warrior")
|
||||
self.assertContains(user_transfer_page, "wasteland.gov")
|
||||
self.assertContains(user_transfer_page, "citadel.gov")
|
||||
self.assertContains(user_transfer_page, "Hotel California")
|
||||
|
||||
select_form = user_transfer_page.forms[0]
|
||||
select_form["selected_user"] = str(self.user2.id)
|
||||
|
@ -2180,19 +2190,15 @@ class TestTransferUser(WebTest):
|
|||
self.assertContains(preview_result, "Furiosa")
|
||||
self.assertContains(preview_result, "Jabassa")
|
||||
self.assertContains(preview_result, "Imperator")
|
||||
self.assertContains(preview_result, "Tokyo Hotel")
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_transfer_user_transfers_portfolio_roles_and_permissions_and_portfolio_creator(self):
|
||||
"""Assert that a portfolio gets copied over
|
||||
NOTE: Should be revised for #2644"""
|
||||
portfolio = Portfolio.objects.create(organization_name="Citadel", creator=self.user2)
|
||||
self.user2.portfolio = portfolio
|
||||
self.user2.portfolio_roles = [UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||
self.user2.portfolio_additional_permissions = [
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
]
|
||||
self.user2.save()
|
||||
def test_transfer_user_transfers_user_portfolio_roles(self):
|
||||
"""Assert that a portfolio user role gets transferred"""
|
||||
portfolio = Portfolio.objects.create(organization_name="Hotel California", creator=self.user2)
|
||||
user_portfolio_permission = UserPortfolioPermission.objects.create(
|
||||
user=self.user2, portfolio=portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
||||
)
|
||||
|
||||
user_transfer_page = self.app.get(reverse("transfer_user", args=[self.user1.pk]))
|
||||
|
||||
|
@ -2200,16 +2206,9 @@ class TestTransferUser(WebTest):
|
|||
submit_form["selected_user"] = self.user2.pk
|
||||
submit_form.submit()
|
||||
|
||||
self.user1.refresh_from_db()
|
||||
portfolio.refresh_from_db()
|
||||
user_portfolio_permission.refresh_from_db()
|
||||
|
||||
self.assertEquals(portfolio.creator, self.user1)
|
||||
self.assertEquals(self.user1.portfolio, portfolio)
|
||||
self.assertEquals(self.user1.portfolio_roles, [UserPortfolioRoleChoices.ORGANIZATION_ADMIN])
|
||||
self.assertEquals(
|
||||
self.user1.portfolio_additional_permissions,
|
||||
[UserPortfolioPermissionChoices.VIEW_PORTFOLIO, UserPortfolioPermissionChoices.EDIT_PORTFOLIO],
|
||||
)
|
||||
self.assertEquals(user_portfolio_permission.user, self.user1)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_transfer_user_transfers_domain_request_creator_and_investigator(self):
|
||||
|
|
|
@ -11,7 +11,9 @@ from django.contrib.admin import site
|
|||
from django.contrib import messages
|
||||
|
||||
from registrar.models.user_domain_role import UserDomainRole
|
||||
from registrar.models.user_portfolio_permission import UserPortfolioPermission
|
||||
from registrar.models.verified_by_staff import VerifiedByStaff
|
||||
from typing import Any, List
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -26,9 +28,12 @@ class TransferUserView(View):
|
|||
(DomainRequest, "investigator"),
|
||||
(UserDomainRole, "user"),
|
||||
(VerifiedByStaff, "requestor"),
|
||||
(UserPortfolioPermission, "user"),
|
||||
]
|
||||
|
||||
USER_FIELDS = ["portfolio", "portfolio_roles", "portfolio_additional_permissions"]
|
||||
# Future-proofing in case joined fields get added on the user model side
|
||||
# This was tested in the first portfolio model iteration and works
|
||||
USER_FIELDS: List[Any] = []
|
||||
|
||||
def get(self, request, user_id):
|
||||
"""current_user referes to the 'source' user where the button that redirects to this view was clicked.
|
||||
|
@ -51,6 +56,7 @@ class TransferUserView(View):
|
|||
**admin_context, # Include the admin context
|
||||
"current_user_domains": self.get_domains(current_user),
|
||||
"current_user_domain_requests": self.get_domain_requests(current_user),
|
||||
"current_user_portfolios": self.get_portfolios(current_user),
|
||||
}
|
||||
|
||||
selected_user_id = request.GET.get("selected_user")
|
||||
|
@ -59,6 +65,7 @@ class TransferUserView(View):
|
|||
context["selected_user"] = selected_user
|
||||
context["selected_user_domains"] = self.get_domains(selected_user)
|
||||
context["selected_user_domain_requests"] = self.get_domain_requests(selected_user)
|
||||
context["selected_user_portfolios"] = self.get_portfolios(selected_user)
|
||||
|
||||
return render(request, "admin/transfer_user.html", context)
|
||||
|
||||
|
@ -121,8 +128,6 @@ class TransferUserView(View):
|
|||
"""
|
||||
Transfers portfolio fields from the selected_user to the current_user.
|
||||
Logs the changes for each transferred field.
|
||||
|
||||
NOTE: This will be refactored in #2644
|
||||
"""
|
||||
for field in cls.USER_FIELDS:
|
||||
field_value = getattr(selected_user, field, None)
|
||||
|
@ -158,3 +163,10 @@ class TransferUserView(View):
|
|||
domain_requests = DomainRequest.objects.filter(creator=user)
|
||||
|
||||
return domain_requests
|
||||
|
||||
@classmethod
|
||||
def get_portfolios(cls, user):
|
||||
"""Get portfolios"""
|
||||
portfolios = UserPortfolioPermission.objects.filter(user=user)
|
||||
|
||||
return portfolios
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue