-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f2bd0ad
commit d36e2e2
Showing
5 changed files
with
218 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,11 @@ | |
AboutYourOrganizationForm, | ||
) | ||
from registrar.forms.domain import ContactForm | ||
from registrar.forms.portfolio import BasePortfolioMemberForm, PortfolioInvitedMemberForm, PortfolioMemberForm, PortfolioNewMemberForm | ||
from registrar.forms.portfolio import ( | ||
PortfolioInvitedMemberForm, | ||
PortfolioMemberForm, | ||
PortfolioNewMemberForm, | ||
) | ||
from registrar.models.portfolio import Portfolio | ||
from registrar.models.portfolio_invitation import PortfolioInvitation | ||
from registrar.models.user import User | ||
|
@@ -423,7 +427,9 @@ class TestBasePortfolioMemberForms(TestCase): | |
def setUp(self): | ||
super().setUp() | ||
self.user = create_user() | ||
self.portfolio, _ = Portfolio.objects.get_or_create(creator_id=self.user.id, organization_name="Hotel California") | ||
self.portfolio, _ = Portfolio.objects.get_or_create( | ||
creator_id=self.user.id, organization_name="Hotel California" | ||
) | ||
|
||
def tearDown(self): | ||
super().tearDown() | ||
|
@@ -433,10 +439,10 @@ def tearDown(self): | |
User.objects.all().delete() | ||
|
||
def _assert_form_is_valid(self, form_class, data, instance=None): | ||
if instance != None: | ||
if instance is not None: | ||
form = form_class(data=data, instance=instance) | ||
else: | ||
print('no instance') | ||
print("no instance") | ||
form = form_class(data=data) | ||
self.assertTrue(form.is_valid(), f"Form {form_class.__name__} failed validation with data: {data}") | ||
return form | ||
|
@@ -491,13 +497,15 @@ def test_required_field_for_member(self): | |
|
||
def test_clean_validates_required_fields_for_role(self): | ||
"""Test that the `clean` method validates the correct fields for each role. | ||
For PortfolioMemberForm and PortfolioInvitedMemberForm, we pass an object as the instance to the form. | ||
For UserPortfolioPermissionChoices, we add a portfolio and an email to the POST data. | ||
These things are handled in the views.""" | ||
|
||
user_portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(portfolio=self.portfolio, user=self.user) | ||
user_portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( | ||
portfolio=self.portfolio, user=self.user | ||
) | ||
portfolio_invitation, _ = PortfolioInvitation.objects.get_or_create(portfolio=self.portfolio, email="hi@ho") | ||
|
||
data = { | ||
|
@@ -519,7 +527,7 @@ def test_clean_validates_required_fields_for_role(self): | |
|
||
data = { | ||
"email": "[email protected]", | ||
"portfolio": self.portfolio.id, | ||
"portfolio": self.portfolio.id, | ||
"role": UserPortfolioRoleChoices.ORGANIZATION_ADMIN.value, | ||
"domain_request_permission_admin": UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS.value, | ||
"member_permission_admin": UserPortfolioPermissionChoices.EDIT_MEMBERS.value, | ||
|
@@ -534,7 +542,9 @@ def test_clean_member_permission_edgecase(self): | |
"""Test that the clean method correctly handles the special "no_access" value for members. | ||
We'll need to add a portfolio, which in the app is handled by the view post.""" | ||
|
||
user_portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(portfolio=self.portfolio, user=self.user) | ||
user_portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create( | ||
portfolio=self.portfolio, user=self.user | ||
) | ||
portfolio_invitation, _ = PortfolioInvitation.objects.get_or_create(portfolio=self.portfolio, email="hi@ho") | ||
|
||
data = { | ||
|
@@ -550,15 +560,14 @@ def test_clean_member_permission_edgecase(self): | |
cleaned_data = form.cleaned_data | ||
self.assertEqual(cleaned_data["domain_request_permission_member"], None) | ||
|
||
|
||
def test_map_instance_to_initial_admin_role(self): | ||
"""Test that instance data is correctly mapped to the initial form values for an admin role.""" | ||
user_portfolio_permission = UserPortfolioPermission( | ||
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN], | ||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_MEMBERS], | ||
) | ||
portfolio_invitation, _ = PortfolioInvitation.objects.get_or_create( | ||
portfolio=self.portfolio, | ||
portfolio=self.portfolio, | ||
email="hi@ho", | ||
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN], | ||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_MEMBERS], | ||
|
@@ -579,7 +588,7 @@ def test_map_instance_to_initial_member_role(self): | |
additional_permissions=[UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS], | ||
) | ||
portfolio_invitation, _ = PortfolioInvitation.objects.get_or_create( | ||
portfolio=self.portfolio, | ||
portfolio=self.portfolio, | ||
email="hi@ho", | ||
roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER], | ||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS], | ||
|
@@ -595,7 +604,7 @@ def test_invalid_data_for_admin(self): | |
"""Test invalid form submission for an admin role with missing permissions.""" | ||
data = { | ||
"email": "[email protected]", | ||
"portfolio": self.portfolio.id, | ||
"portfolio": self.portfolio.id, | ||
"role": UserPortfolioRoleChoices.ORGANIZATION_ADMIN.value, | ||
"domain_request_permission_admin": "", # Missing field | ||
"member_permission_admin": "", # Missing field | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
from django.conf import settings | ||
from django.urls import reverse | ||
from django.contrib.auth import get_user_model | ||
from registrar.models.portfolio_invitation import PortfolioInvitation | ||
from registrar.utility.email import EmailSendingError | ||
from waffle.testutils import override_flag | ||
from api.tests.common import less_console_noise_decorator | ||
from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices | ||
|
@@ -454,6 +456,7 @@ def tearDownClass(cls): | |
|
||
def tearDown(self): | ||
"""Ensure that the user has its original permissions""" | ||
PortfolioInvitation.objects.all().delete() | ||
super().tearDown() | ||
|
||
@less_console_noise_decorator | ||
|
@@ -486,7 +489,7 @@ def test_domain_user_add(self): | |
@less_console_noise_decorator | ||
def test_domain_user_add_form(self): | ||
"""Adding an existing user works.""" | ||
other_user, _ = get_user_model().objects.get_or_create(email="[email protected]") | ||
get_user_model().objects.get_or_create(email="[email protected]") | ||
add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id})) | ||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] | ||
|
||
|
@@ -509,6 +512,148 @@ def test_domain_user_add_form(self): | |
success_page = success_result.follow() | ||
self.assertContains(success_page, "[email protected]") | ||
|
||
@boto3_mocking.patching | ||
@override_flag("organization_feature", active=True) | ||
@less_console_noise_decorator | ||
@patch("registrar.views.domain.send_portfolio_invitation_email") | ||
@patch("registrar.views.domain.send_domain_invitation_email") | ||
def test_domain_user_add_form_sends_portfolio_invitation(self, mock_send_domain_email, mock_send_portfolio_email): | ||
"""Adding an existing user works and sends portfolio invitation when | ||
user is not member of portfolio.""" | ||
get_user_model().objects.get_or_create(email="[email protected]") | ||
add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id})) | ||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] | ||
|
||
add_page.form["email"] = "[email protected]" | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
|
||
success_result = add_page.form.submit() | ||
|
||
self.assertEqual(success_result.status_code, 302) | ||
self.assertEqual( | ||
success_result["Location"], | ||
reverse("domain-users", kwargs={"pk": self.domain.id}), | ||
) | ||
|
||
# Verify that the invitation emails were sent | ||
mock_send_portfolio_email.assert_called_once_with( | ||
email="[email protected]", requestor=self.user, portfolio=self.portfolio | ||
) | ||
mock_send_domain_email.assert_called_once() | ||
call_args = mock_send_domain_email.call_args.kwargs | ||
self.assertEqual(call_args["email"], "[email protected]") | ||
self.assertEqual(call_args["requestor"], self.user) | ||
self.assertEqual(call_args["domain"], self.domain) | ||
self.assertIsNone(call_args.get("is_member_of_different_org")) | ||
|
||
# Assert that the PortfolioInvitation is created | ||
portfolio_invitation = PortfolioInvitation.objects.filter( | ||
email="[email protected]", portfolio=self.portfolio | ||
).first() | ||
self.assertIsNotNone(portfolio_invitation, "Portfolio invitation should be created.") | ||
self.assertEqual(portfolio_invitation.email, "[email protected]") | ||
self.assertEqual(portfolio_invitation.portfolio, self.portfolio) | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
success_page = success_result.follow() | ||
self.assertContains(success_page, "[email protected]") | ||
|
||
@boto3_mocking.patching | ||
@override_flag("organization_feature", active=True) | ||
@less_console_noise_decorator | ||
@patch("registrar.views.domain.send_portfolio_invitation_email") | ||
@patch("registrar.views.domain.send_domain_invitation_email") | ||
def test_domain_user_add_form_doesnt_send_portfolio_invitation_if_already_member( | ||
self, mock_send_domain_email, mock_send_portfolio_email | ||
): | ||
"""Adding an existing user works and sends portfolio invitation when | ||
user is not member of portfolio.""" | ||
other_user, _ = get_user_model().objects.get_or_create(email="[email protected]") | ||
UserPortfolioPermission.objects.get_or_create( | ||
user=other_user, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN] | ||
) | ||
add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id})) | ||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] | ||
|
||
add_page.form["email"] = "[email protected]" | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
|
||
success_result = add_page.form.submit() | ||
|
||
self.assertEqual(success_result.status_code, 302) | ||
self.assertEqual( | ||
success_result["Location"], | ||
reverse("domain-users", kwargs={"pk": self.domain.id}), | ||
) | ||
|
||
# Verify that the invitation emails were sent | ||
mock_send_portfolio_email.assert_not_called() | ||
mock_send_domain_email.assert_called_once() | ||
call_args = mock_send_domain_email.call_args.kwargs | ||
self.assertEqual(call_args["email"], "[email protected]") | ||
self.assertEqual(call_args["requestor"], self.user) | ||
self.assertEqual(call_args["domain"], self.domain) | ||
self.assertIsNone(call_args.get("is_member_of_different_org")) | ||
|
||
# Assert that no PortfolioInvitation is created | ||
portfolio_invitation_exists = PortfolioInvitation.objects.filter( | ||
email="[email protected]", portfolio=self.portfolio | ||
).exists() | ||
self.assertFalse( | ||
portfolio_invitation_exists, "Portfolio invitation should not be created when the user is already a member." | ||
) | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
success_page = success_result.follow() | ||
self.assertContains(success_page, "[email protected]") | ||
|
||
@boto3_mocking.patching | ||
@override_flag("organization_feature", active=True) | ||
@less_console_noise_decorator | ||
@patch("registrar.views.domain.send_portfolio_invitation_email") | ||
@patch("registrar.views.domain.send_domain_invitation_email") | ||
def test_domain_user_add_form_sends_portfolio_invitation_raises_email_sending_error( | ||
self, mock_send_domain_email, mock_send_portfolio_email | ||
): | ||
"""Adding an existing user works and attempts to send portfolio invitation when | ||
user is not member of portfolio and send raises an error.""" | ||
mock_send_portfolio_email.side_effect = EmailSendingError("Failed to send email.") | ||
get_user_model().objects.get_or_create(email="[email protected]") | ||
add_page = self.app.get(reverse("domain-users-add", kwargs={"pk": self.domain.id})) | ||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] | ||
|
||
add_page.form["email"] = "[email protected]" | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
|
||
success_result = add_page.form.submit() | ||
|
||
self.assertEqual(success_result.status_code, 302) | ||
self.assertEqual( | ||
success_result["Location"], | ||
reverse("domain-users", kwargs={"pk": self.domain.id}), | ||
) | ||
|
||
# Verify that the invitation emails were sent | ||
mock_send_portfolio_email.assert_called_once_with( | ||
email="[email protected]", requestor=self.user, portfolio=self.portfolio | ||
) | ||
mock_send_domain_email.assert_not_called() | ||
|
||
# Assert that no PortfolioInvitation is created | ||
portfolio_invitation_exists = PortfolioInvitation.objects.filter( | ||
email="[email protected]", portfolio=self.portfolio | ||
).exists() | ||
self.assertFalse( | ||
portfolio_invitation_exists, "Portfolio invitation should not be created when email fails to send." | ||
) | ||
|
||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
success_page = success_result.follow() | ||
self.assertContains(success_page, "Could not send email invitation.") | ||
|
||
@boto3_mocking.patching | ||
@less_console_noise_decorator | ||
def test_domain_invitation_created(self): | ||
|
@@ -757,7 +902,9 @@ def test_domain_invitation_email_displays_error(self): | |
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) | ||
add_page.form.submit() | ||
|
||
expected_message_content = f"Can't send invitation email. No email is associated with the account for 'test_user'." | ||
expected_message_content = ( | ||
"Can't send invitation email. No email is associated with the account for 'test_user'." | ||
) | ||
|
||
# Assert that the error message was called with the correct argument | ||
mock_error.assert_called_once_with( | ||
|
Oops, something went wrong.