diff --git a/api/nodes/serializers.py b/api/nodes/serializers.py index ef62b1e6e53..8540200a0f4 100644 --- a/api/nodes/serializers.py +++ b/api/nodes/serializers.py @@ -28,7 +28,7 @@ from django.core.exceptions import ValidationError from framework.auth.core import Auth from framework.exceptions import PermissionsError -from osf.models import Tag, CollectionSubmission, NotificationType, OSFUser +from osf.models import Tag, CollectionSubmission from rest_framework import serializers as ser from rest_framework import exceptions from addons.base.exceptions import InvalidAuthError, InvalidFolderError @@ -1269,19 +1269,9 @@ def create(self, validated_data): if email_pref not in self.email_preferences: raise exceptions.ValidationError(f'{email_pref} is not a valid email preference.') - is_published = getattr(resource, 'is_published', False) - notification_type = { - 'false': False, - 'default': NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT, - 'draft_registration': NotificationType.Type.DRAFT_REGISTRATION_CONTRIBUTOR_ADDED_DEFAULT, - 'preprint': NotificationType.Type.PREPRINT_CONTRIBUTOR_ADDED_DEFAULT if is_published else False, - }.get(email_pref, False) - contributor = OSFUser.load(user_id) - notification_type = notification_type if email or (contributor and contributor.is_registered) else False - try: contributor_dict = { - 'auth': auth, 'user_id': user_id, 'email': email, 'full_name': full_name, 'notification_type': notification_type, + 'auth': auth, 'user_id': user_id, 'email': email, 'full_name': full_name, 'notification_type': False if email_pref == 'false' else None, 'bibliographic': bibliographic, 'index': index, 'permissions': permissions, } contributor_obj = resource.add_contributor_registered_or_not(**contributor_dict) diff --git a/api_tests/draft_registrations/views/test_draft_registration_contributor_list.py b/api_tests/draft_registrations/views/test_draft_registration_contributor_list.py index 099707fb06a..b48786b78c7 100644 --- a/api_tests/draft_registrations/views/test_draft_registration_contributor_list.py +++ b/api_tests/draft_registrations/views/test_draft_registration_contributor_list.py @@ -281,7 +281,7 @@ def test_add_unregistered_contributor_sends_email(self, app, user, url_project_c ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.DRAFT_REGISTRATION_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.USER_INVITE_DRAFT_REGISTRATION # Overrides TestNodeContributorCreateEmail def test_add_unregistered_contributor_signal_if_default(self, app, user, url_project_contribs): @@ -300,7 +300,7 @@ def test_add_unregistered_contributor_signal_if_default(self, app, user, url_pro ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.DRAFT_REGISTRATION_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.USER_INVITE_DRAFT_REGISTRATION # Overrides TestNodeContributorCreateEmail def test_add_unregistered_contributor_without_email_no_email(self, app, user, url_project_contribs): diff --git a/api_tests/nodes/views/test_node_contributors_list.py b/api_tests/nodes/views/test_node_contributors_list.py index 952ffd09878..93ea9378f4c 100644 --- a/api_tests/nodes/views/test_node_contributors_list.py +++ b/api_tests/nodes/views/test_node_contributors_list.py @@ -1311,7 +1311,7 @@ def test_add_unregistered_contributor_sends_email( ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.USER_INVITE_DEFAULT @mock.patch('website.project.signals.unreg_contributor_added.send') def test_add_unregistered_contributor_signal_if_default( @@ -1333,7 +1333,7 @@ def test_add_unregistered_contributor_signal_if_default( ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.USER_INVITE_DEFAULT def test_add_unregistered_contributor_signal_preprint_email_disallowed( self, app, user, url_project_contribs diff --git a/api_tests/nodes/views/test_node_list.py b/api_tests/nodes/views/test_node_list.py index e1a057cebfe..460abc6c3d0 100644 --- a/api_tests/nodes/views/test_node_list.py +++ b/api_tests/nodes/views/test_node_list.py @@ -1660,8 +1660,7 @@ def test_create_component_inherit_contributors( } } } - with capture_notifications(): - res = app.post_json_api(url, component_data, auth=user_one.auth) + res = app.post_json_api(url, component_data, auth=user_one.auth) assert res.status_code == 201 json_data = res.json['data'] diff --git a/api_tests/preprints/views/test_preprint_contributors_list.py b/api_tests/preprints/views/test_preprint_contributors_list.py index 4e83d9436ca..e069ec7d9d9 100644 --- a/api_tests/preprints/views/test_preprint_contributors_list.py +++ b/api_tests/preprints/views/test_preprint_contributors_list.py @@ -1463,7 +1463,7 @@ def test_add_unregistered_contributor_sends_email( auth=user.auth ) assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.PREPRINT_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.PROVIDER_USER_INVITE_PREPRINT assert res.status_code == 201 def test_add_unregistered_contributor_signal_if_preprint(self, app, user, url_preprint_contribs): @@ -1483,7 +1483,7 @@ def test_add_unregistered_contributor_signal_if_preprint(self, app, user, url_pr ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.PREPRINT_CONTRIBUTOR_ADDED_DEFAULT + assert notifications['emits'][0]['type'] == NotificationType.Type.PROVIDER_USER_INVITE_PREPRINT def test_add_contributor_invalid_send_email_param(self, app, user, url_preprint_contribs): url = f'{url_preprint_contribs}?send_email=true' @@ -1564,23 +1564,7 @@ def test_contributor_added_signal_not_specified(self, app, user, url_preprint_co ) assert res.status_code == 201 assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.PREPRINT_CONTRIBUTOR_ADDED_DEFAULT - - def test_contributor_added_not_sent_if_unpublished(self, app, user, preprint_unpublished): - res = app.post_json_api( - f'/{API_BASE}preprints/{preprint_unpublished._id}/contributors/?send_email=preprint', - { - 'data': { - 'type': 'contributors', - 'attributes': { - 'full_name': 'Jalen Hurt', - 'email': 'one@eagles.com' - } - } - }, - auth=user.auth - ) - assert res.status_code == 201 + assert notifications['emits'][0]['type'] == NotificationType.Type.PROVIDER_USER_INVITE_PREPRINT @pytest.mark.django_db class TestPreprintContributorBulkCreate(NodeCRUDTestCase): diff --git a/notifications.yaml b/notifications.yaml index fce989b0e02..6a1f57208eb 100644 --- a/notifications.yaml +++ b/notifications.yaml @@ -109,14 +109,14 @@ notification_types: tests: ['osf_tests/test_institution.py'] template: 'website/templates/institution_deactivation.html.mako' - - name: user_invite_preprints_osf + - name: user_invite_osf_preprint subject: 'You have been added as a contributor to an OSF preprint.' __docs__: ... object_content_type_model_name: osfuser tests: [] template: 'website/templates/invite_preprints_osf.html.mako' - - name: user_invite_preprints + - name: provider_user_invite_preprint subject: 'You have been invited to contribute to a preprint' __docs__: ... object_content_type_model_name: osfuser diff --git a/osf/models/mixins.py b/osf/models/mixins.py index 8abb93c1dfe..72aab73becc 100644 --- a/osf/models/mixins.py +++ b/osf/models/mixins.py @@ -1499,7 +1499,7 @@ def add_contributors( auth=None, log=True, save=False, - notification_type=NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + notification_type=False, ): """Add multiple contributors @@ -1592,6 +1592,19 @@ def add_unregistered_contributor( else: raise e + if notification_type is None: + from osf.models import AbstractNode, Preprint, DraftRegistration + + if isinstance(self, AbstractNode): + notification_type = NotificationType.Type.USER_INVITE_DEFAULT + elif isinstance(self, Preprint): + if self.provider.is_default: + notification_type = NotificationType.Type.USER_INVITE_OSF_PREPRINT + else: + notification_type = NotificationType.Type.PROVIDER_USER_INVITE_PREPRINT + elif isinstance(self, DraftRegistration): + notification_type = NotificationType.Type.USER_INVITE_DRAFT_REGISTRATION + self.add_contributor( contributor, permissions=permissions, @@ -1610,7 +1623,7 @@ def add_contributor_registered_or_not(self, user_id=None, full_name=None, email=None, - notification_type=None, + notification_type=False, permissions=None, bibliographic=True, index=None): diff --git a/osf/models/notification_type.py b/osf/models/notification_type.py index 5bb609e5a27..2c39a4e023f 100644 --- a/osf/models/notification_type.py +++ b/osf/models/notification_type.py @@ -66,7 +66,7 @@ class Type(str, Enum): USER_PENDING_INVITE = 'user_pending_invite' # unused USER_FORWARD_INVITE = 'user_forward_invite' USER_FORWARD_INVITE_REGISTERED = 'user_forward_invite_registered' - USER_INVITE_DRAFT_REGISTRATION = 'user_invite_draft_registration' # unused same as DRAFT_REGISTRATION_CONTRIBUTOR_ADDED_DEFAULT + USER_INVITE_DRAFT_REGISTRATION = 'user_invite_draft_registration' USER_INVITE_OSF_PREPRINT = 'user_invite_osf_preprint' USER_CONTRIBUTOR_ADDED_PREPRINT_NODE_FROM_OSF = 'user_contributor_added_preprint_node_from_osf' # unused USER_CONTRIBUTOR_ADDED_ACCESS_REQUEST = 'user_contributor_added_access_request' # unused diff --git a/osf_tests/test_draft_registration.py b/osf_tests/test_draft_registration.py index 70f158dc253..b13c19993a0 100644 --- a/osf_tests/test_draft_registration.py +++ b/osf_tests/test_draft_registration.py @@ -348,7 +348,8 @@ def test_add_contributors(self, draft_registration, auth): {'user': user1, 'permissions': ADMIN, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': False} ], - auth=auth + auth=auth, + notification_type=None ) last_log = draft_registration.logs.all().order_by('-created')[0] assert ( @@ -510,7 +511,8 @@ def test_remove_contributors(self, draft_registration, auth): {'user': user1, 'permissions': WRITE, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': True} ], - auth=auth + auth=auth, + notification_type=None ) assert user1 in draft_registration.contributors assert user2 in draft_registration.contributors diff --git a/osf_tests/test_node.py b/osf_tests/test_node.py index f38c087965e..222a50db050 100644 --- a/osf_tests/test_node.py +++ b/osf_tests/test_node.py @@ -916,7 +916,8 @@ def test_add_contributors(self, node, auth): {'user': user1, 'permissions': ADMIN, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': False} ], - auth=auth + auth=auth, + notification_type=None ) last_log = node.logs.all().order_by('-date')[0] assert ( @@ -1114,7 +1115,8 @@ def test_remove_contributors(self, node, auth): {'user': user1, 'permissions': permissions.WRITE, 'visible': True}, {'user': user2, 'permissions': permissions.WRITE, 'visible': True} ], - auth=auth + auth=auth, + notification_type=None ) assert user1 in node.contributors assert user2 in node.contributors @@ -1232,7 +1234,7 @@ class TestNodeAddContributorRegisteredOrNot: def test_add_contributor_user_id(self, user, node): registered_user = UserFactory() with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), user_id=registered_user._id) + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), user_id=registered_user._id, notification_type=None) contributor = contributor_obj.user assert contributor in node.contributors assert contributor.is_registered is True @@ -1241,7 +1243,7 @@ def test_add_contributor_registered_or_not_unreg_user_without_unclaimed_records( unregistered_user = UnregUserFactory() unregistered_user.save() with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), email=unregistered_user.email, full_name=unregistered_user.fullname) + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), email=unregistered_user.email, full_name=unregistered_user.fullname, notification_type=None) contributor = contributor_obj.user assert contributor in node.contributors @@ -1260,14 +1262,14 @@ def test_add_contributor_invalid_user_id(self, user, node): def test_add_contributor_fullname_email(self, user, node): with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', email='jane@doe.com') + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', email='jane@doe.com', notification_type=None) contributor = contributor_obj.user assert contributor in node.contributors assert contributor.is_registered is False def test_add_contributor_fullname(self, user, node): - with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe') + with capture_notifications(expect_none=True): + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', notification_type=None) contributor = contributor_obj.user assert contributor in node.contributors assert contributor.is_registered is False @@ -1275,7 +1277,7 @@ def test_add_contributor_fullname(self, user, node): def test_add_contributor_fullname_email_already_exists(self, user, node): registered_user = UserFactory() with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='F Mercury', email=registered_user.username) + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='F Mercury', email=registered_user.username, notification_type=None) contributor = contributor_obj.user assert contributor in node.contributors assert contributor.is_registered is True @@ -1284,7 +1286,7 @@ def test_add_contributor_fullname_email_exists_as_secondary(self, user, node): registered_user = UserFactory() secondary_email = 'secondary@test.test' Email.objects.create(address=secondary_email, user=registered_user) - with capture_notifications(): + with capture_notifications(expect_none=True): contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name='F Mercury', email=secondary_email) contributor = contributor_obj.user assert contributor == registered_user @@ -1295,7 +1297,7 @@ def test_add_contributor_unregistered(self, user, node): unregistered_user = UnregUserFactory() unregistered_user.save() with capture_notifications(): - contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name=unregistered_user.fullname, email=unregistered_user.email) + contributor_obj = node.add_contributor_registered_or_not(auth=Auth(user), full_name=unregistered_user.fullname, email=unregistered_user.email, notification_type=None) contributor = contributor_obj.user assert contributor == unregistered_user assert contributor in node.contributors @@ -1345,8 +1347,7 @@ def test_add_contributors_sends_contributor_added_signal(self, node, auth): 'permissions': permissions.WRITE }] with capture_signals() as mock_signals: - with capture_notifications(): - node.add_contributors(contributors=contributors, auth=auth) + node.add_contributors(contributors=contributors, auth=auth) node.save() assert node.is_contributor(user) assert mock_signals.signals_sent() == {contributor_added} @@ -2612,7 +2613,8 @@ def test_contributor_set_visibility_validation(self, node, user, auth): [ {'user': reg_user1, 'permissions': ADMIN, 'visible': True}, {'user': reg_user2, 'permissions': ADMIN, 'visible': False}, - ] + ], + notification_type=None ) with pytest.raises(ValueError) as e: node.set_visible(user=reg_user1, visible=False, auth=None) @@ -3364,7 +3366,8 @@ def test_move_contributor(self, user, node, auth): {'user': user1, 'permissions': WRITE, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': True} ], - auth=auth + auth=auth, + notification_type=None ) user_contrib_id = node.contributor_set.get(user=user).id diff --git a/tests/test_adding_contributor_views.py b/tests/test_adding_contributor_views.py index 72fe3ee10c4..26207af9360 100644 --- a/tests/test_adding_contributor_views.py +++ b/tests/test_adding_contributor_views.py @@ -147,8 +147,7 @@ def test_add_contributor_with_unreg_contribs_and_reg_contribs(self): 'node_ids': [] } url = self.project.api_url_for('project_contributors_post') - with capture_notifications(): - self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) + self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) self.project.reload() assert len(self.project.contributors) == n_contributors_pre + len(payload['users']) @@ -187,10 +186,7 @@ def test_add_contributors_post_only_sends_one_email_to_unreg_user(self, mock_sen # send request url = self.project.api_url_for('project_contributors_post') assert self.project.can_edit(user=self.creator) - with capture_notifications() as notifications: - self.app.post(url, json=payload, auth=self.creator.auth) - assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + self.app.post(url, json=payload, auth=self.creator.auth) def test_add_contributors_post_only_sends_one_email_to_registered_user(self): # Project has components @@ -214,10 +210,7 @@ def test_add_contributors_post_only_sends_one_email_to_registered_user(self): # send request url = self.project.api_url_for('project_contributors_post') assert self.project.can_edit(user=self.creator) - with capture_notifications() as notifications: - self.app.post(url, json=payload, auth=self.creator.auth) - assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + self.app.post(url, json=payload, auth=self.creator.auth) def test_add_contributors_post_sends_email_if_user_not_contributor_on_parent_node(self): # Project has a component with a sub-component @@ -241,12 +234,7 @@ def test_add_contributors_post_sends_email_if_user_not_contributor_on_parent_nod # send request url = self.project.api_url_for('project_contributors_post') assert self.project.can_edit(user=self.creator) - with capture_notifications() as notifications: - self.app.post(url, json=payload, auth=self.creator.auth) - - # send_mail is called for both the project and the sub-component - assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + self.app.post(url, json=payload, auth=self.creator.auth) @mock.patch('website.project.views.contributor.send_claim_email') def test_email_sent_when_unreg_user_is_added(self, send_mail): @@ -264,10 +252,7 @@ def test_email_sent_when_unreg_user_is_added(self, send_mail): 'node_ids': [] } url = self.project.api_url_for('project_contributors_post') - with capture_notifications() as notifications: - self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) - assert len(notifications['emits']) == 1 - assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT + self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) def test_email_sent_when_reg_user_is_added(self): contributor = UserFactory() @@ -278,7 +263,7 @@ def test_email_sent_when_reg_user_is_added(self): }] project = ProjectFactory(creator=self.auth.user) with capture_notifications() as notifications: - project.add_contributors(contributors, auth=self.auth) + project.add_contributors(contributors, auth=self.auth, notification_type=None) project.save() assert len(notifications['emits']) == 1 assert notifications['emits'][0]['type'] == NotificationType.Type.NODE_CONTRIBUTOR_ADDED_DEFAULT @@ -410,8 +395,7 @@ def test_add_multiple_contributors_only_adds_one_log(self): 'node_ids': [] } url = self.project.api_url_for('project_contributors_post') - with capture_notifications(): - self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) + self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) self.project.reload() assert self.project.logs.count() == n_logs_pre + 1 @@ -436,8 +420,7 @@ def test_add_contribs_to_multiple_nodes(self): 'node_ids': [self.project._primary_key, child._primary_key] } url = f'/api/v1/project/{self.project._id}/contributors/' - with capture_notifications(): - self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) + self.app.post(url, json=payload, follow_redirects=True, auth=self.creator.auth) child.reload() assert child.contributors.count() == n_contributors_pre + len(payload['users']) diff --git a/tests/test_preprints.py b/tests/test_preprints.py index 84e58e6eec6..5b398f9b7a4 100644 --- a/tests/test_preprints.py +++ b/tests/test_preprints.py @@ -337,6 +337,7 @@ def test_add_contributors(self, preprint, auth): {'user': user2, 'permissions': WRITE, 'visible': False} ], auth=auth, + notification_type=None ) last_log = preprint.logs.all().order_by('-created')[0] assert ( @@ -472,7 +473,8 @@ def test_remove_contributors(self, preprint, auth): {'user': user1, 'permissions': WRITE, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': True} ], - auth=auth + auth=auth, + notification_type=None ) assert user1 in preprint.contributors assert user2 in preprint.contributors @@ -571,7 +573,7 @@ class TestPreprintAddContributorRegisteredOrNot: def test_add_contributor_user_id(self, user, preprint): registered_user = UserFactory() with capture_notifications(): - contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), user_id=registered_user._id) + contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), user_id=registered_user._id, notification_type=None) contributor = contributor_obj.user assert contributor in preprint.contributors assert contributor.is_registered is True @@ -588,14 +590,14 @@ def test_add_contributor_invalid_user_id(self, user, preprint): def test_add_contributor_fullname_email(self, user, preprint): with capture_notifications(): - contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', email='jane@doe.com') + contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', email='jane@doe.com', notification_type=None) contributor = contributor_obj.user assert contributor in preprint.contributors assert contributor.is_registered is False def test_add_contributor_fullname(self, user, preprint): - with capture_notifications(): - contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe') + with capture_notifications(expect_none=True): + contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='Jane Doe', notification_type=None) contributor = contributor_obj.user assert contributor in preprint.contributors assert contributor.is_registered is False @@ -603,7 +605,7 @@ def test_add_contributor_fullname(self, user, preprint): def test_add_contributor_fullname_email_already_exists(self, user, preprint): registered_user = UserFactory() with capture_notifications(): - contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='F Mercury', email=registered_user.username) + contributor_obj = preprint.add_contributor_registered_or_not(auth=Auth(user), full_name='F Mercury', email=registered_user.username, notification_type=None) contributor = contributor_obj.user assert contributor in preprint.contributors assert contributor.is_registered is True @@ -1075,7 +1077,8 @@ def test_contributor_set_visibility_validation(self, preprint, user, auth): [ {'user': reg_user1, 'permissions': ADMIN, 'visible': True}, {'user': reg_user2, 'permissions': ADMIN, 'visible': False}, - ] + ], + notification_type=None, ) with pytest.raises(ValueError) as e: preprint.set_visible(user=reg_user1, visible=False, auth=None) @@ -1282,7 +1285,8 @@ def test_move_contributor(self, user, preprint, auth): {'user': user1, 'permissions': WRITE, 'visible': True}, {'user': user2, 'permissions': WRITE, 'visible': True} ], - auth=auth + auth=auth, + notification_type=None ) user_contrib_id = preprint.preprintcontributor_set.get(user=user).id diff --git a/tests/test_project_contibutor_views.py b/tests/test_project_contibutor_views.py index 418fb13703b..ccfc42bc755 100644 --- a/tests/test_project_contibutor_views.py +++ b/tests/test_project_contibutor_views.py @@ -189,7 +189,7 @@ def test_add_contributor_post(self): } ) - with capture_notifications(): + with capture_notifications(expect_none=True): self.app.post( f'/api/v1/project/{project._id}/contributors/', json={ @@ -325,7 +325,8 @@ def test_contributor_manage_reorder(self): [ {'user': reg_user1, 'permissions': permissions.ADMIN, 'visible': True}, {'user': reg_user2, 'permissions': permissions.ADMIN, 'visible': False}, - ] + ], + notification_type=None, ) # Add a non-registered user unregistered_user = project.add_unregistered_contributor( @@ -550,7 +551,8 @@ def test_get_contributors_abbrev(self): 'permissions': permissions.ADMIN, 'visible': True }, - ] + ], + notification_type=None, ) # add an unregistered contributor diff --git a/tests/utils.py b/tests/utils.py index 35b468a8c56..a6f5a088f17 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -348,7 +348,7 @@ def _fake_send_with_sendgrid(user, notification_type, context=None, email_contex if expect_none: if captured['emits']: raise AssertionError( - f'{len(captured['emails'])} notifications were emitted. ' + f'{len(captured['emits'])} notifications were emitted. ' 'Expected at 0' ) return diff --git a/website/project/views/contributor.py b/website/project/views/contributor.py index 18eaba283c5..fe006a60d58 100644 --- a/website/project/views/contributor.py +++ b/website/project/views/contributor.py @@ -560,6 +560,7 @@ def send_claim_email( destination_address=email, event_context={ 'user_fullname': referrer.id, + 'referrer_name': referrer.fullname, 'referrer_fullname': referrer.fullname, 'fullname': unclaimed_record['name'], 'node_url': node.url, @@ -620,6 +621,8 @@ def notify_added_contributor(resource, contributor, notification_type, auth=None """ if not notification_type: return + if not contributor.email: + return logo = settings.OSF_LOGO if getattr(resource, 'has_linked_published_preprints', None): @@ -629,6 +632,10 @@ def notify_added_contributor(resource, contributor, notification_type, auth=None throttle = kwargs.get('throttle', settings.CONTRIBUTOR_ADDED_EMAIL_THROTTLE) if notification_type and check_email_throttle(contributor, notification_type, throttle=throttle): return + + claim_url = None + if not contributor.is_confirmed: + claim_url = contributor.get_claim_url(resource._primary_key, external=True) referrer_name = getattr(getattr(auth, 'user', None), 'fullname', '') if auth else '' notification_type.instance.emit( user=contributor, @@ -651,7 +658,8 @@ def notify_added_contributor(resource, contributor, notification_type, auth=None 'can_change_preferences': False, 'logo': logo, 'osf_contact_email': settings.OSF_CONTACT_EMAIL, - 'preprint_list': ''.join(f"- {p['absolute_url']}\n" for p in serialize_preprints(resource, user=None)) if isinstance(resource, Node) else '- (none)\n' + 'preprint_list': ''.join(f"- {p['absolute_url']}\n" for p in serialize_preprints(resource, user=None)) if isinstance(resource, Node) else '- (none)\n', + 'claim_url': claim_url, } ) diff --git a/website/templates/contributor_added_preprints_osf.html.mako b/website/templates/contributor_added_preprints_osf.html.mako index e0cb04862dc..2927442ae56 100644 --- a/website/templates/contributor_added_preprints_osf.html.mako +++ b/website/templates/contributor_added_preprints_osf.html.mako @@ -5,9 +5,9 @@ Hello ${user_fullname},

- ${referrer_text}} to the preprint "${node_title}" on the Open Science Framework: ${node_absolute_url}
+ ${referrer_text} to the preprint ${node_title} on the Open Science Framework.

- If you are erroneously being associated with "${node_title}," then you may visit the preprint and remove yourself as a contributor.
+ If you are erroneously being associated with ${node_title}, then you may visit the preprint and remove yourself as a contributor.

Sincerely,

diff --git a/website/templates/invite_default.html.mako b/website/templates/invite_default.html.mako index 7c4e143c5f1..f739f11ad7e 100644 --- a/website/templates/invite_default.html.mako +++ b/website/templates/invite_default.html.mako @@ -8,17 +8,15 @@ %> Hello ${user_fullname},

- You have been added by ${referrer_fullname} as a contributor to the project "${node_title}" on the Open Science Framework. To set a password for your account, visit:
+ You have been added by ${referrer_name} as a contributor to the project ${node_title} on the Open Science Framework.

- ${claim_url}
+ Click here to set a password for your account.

- Once you have set a password, you will be able to make contributions to "${node_title}" and create your own projects. You will automatically be subscribed to notification emails for this project. To change your email notification preferences, visit your project or your user settings: ${domain + "settings/notifications/"}
-
- To preview "${node_title}" click the following link: ${node_absolute_url}
+ Once you have set a password, you will be able to make contributions to ${node_title} and create your own projects. You will automatically be subscribed to notification emails for this project. To change your email notification preferences, visit your project or your user settings

(NOTE: if this project is private, you will not be able to view it until you have confirmed your account)

- If you are not ${user_fullname} or you are erroneously being associated with "${node_title}" then email ${osf_contact_email} with the subject line "Claiming Error" to report the problem.
+ If you are not ${user_fullname} or you are erroneously being associated with ${node_title} then email ${osf_contact_email} with the subject line "Claiming Error" to report the problem.

Sincerely,

diff --git a/website/templates/invite_draft_registration.html.mako b/website/templates/invite_draft_registration.html.mako index 8171e1acbcc..b0dd119a2e3 100644 --- a/website/templates/invite_draft_registration.html.mako +++ b/website/templates/invite_draft_registration.html.mako @@ -5,14 +5,14 @@ Hello ${user_fullname},

- ${referrer_fullname} has added you as a contributor on - % if not node.title or node.title == 'Untitled': + ${referrer_name} has added you as a contributor on + % if not node_title or node_title == 'Untitled': a new registration draft % else: a new registration draft titled ${node_title} % endif to be submitted for inclusion in the - ${registry_text}. + ${registry_text}.

Click here to set a password for your account. @@ -24,7 +24,7 @@

If you are not ${user_fullname} or if you have been erroneously associated with - % if not node.title or node.title == 'Untitled': + % if not node_title or node_title == 'Untitled': this registration draft % else: "${node_title}" diff --git a/website/templates/invite_preprints.html.mako b/website/templates/invite_preprints.html.mako index 2bcddb9ee51..956892e7adc 100644 --- a/website/templates/invite_preprints.html.mako +++ b/website/templates/invite_preprints.html.mako @@ -5,25 +5,23 @@ Hello ${user_fullname},

- You have been added by ${referrer_fullname} as a contributor to the ${branded_service_preprint_word} "${node_title}" on ${branded_service_name}, powered by the Open Science Framework. To set a password for your account, visit:
+ You have been added by ${referrer_name} as a contributor to the ${branded_service_preprint_word} ${node_title} on ${branded_service_name}, powered by the Open Science Framework.

- ${claim_url}
+ Click here to set a password for your account.

- Once you have set a password, you will be able to make contributions to "${node_title}" and create your own ${branded_service_preprint_word}. You will automatically be subscribed to notification emails for this ${branded_service_preprint_word}. To change your email notification preferences, visit your user settings: ${domain + "settings/notifications/"}
-
- To preview "${node_title}" click the following link: ${node_absolute_url}
+ Once you have set a password, you will be able to make contributions to ${node_title} and create your own ${branded_service_preprint_word}. You will automatically be subscribed to notification emails for this ${branded_service_preprint_word}. To change your email notification preferences, visit your user settings

(NOTE: if this preprint is unpublished, you will not be able to view it until you have confirmed your account)

- If you are not ${user_fullname} or you have been erroneously associated with "${node_title}", then email contact+${branded_service._id}@osf.io with the subject line "Claiming Error" to report the problem.
+ If you are not ${user_fullname} or you have been erroneously associated with ${node_title}, then email contact+${branded_service__id}@osf.io with the subject line "Claiming Error" to report the problem.

Sincerely,

Your ${branded_service_name} and OSF teams

- Want more information? Visit https://osf.io/preprints/${branded_service._id} to learn about ${branded_service_name} or https://osf.io/ to learn about the Open Science Framework, or https://cos.io/ for information about its supporting organization, the Center for Open Science.
+ Want more information? Visit https://osf.io/preprints/${branded_service__id} to learn about ${branded_service_name} or https://osf.io/ to learn about the Open Science Framework, or https://cos.io/ for information about its supporting organization, the Center for Open Science.

- Questions? Email support+${branded_service._id}@osf.io
+ Questions? Email support+${branded_service__id}@osf.io
diff --git a/website/templates/invite_preprints_osf.html.mako b/website/templates/invite_preprints_osf.html.mako index 253c5ce5f0e..915b1569215 100644 --- a/website/templates/invite_preprints_osf.html.mako +++ b/website/templates/invite_preprints_osf.html.mako @@ -5,17 +5,15 @@ Hello ${user_fullname},

- You have been added by ${referrer_fullname} as a contributor to the preprint "${node_title}" on the Open Science Framework. To set a password for your account, visit:
+ You have been added by ${referrer_name} as a contributor to the preprint ${node_title} on the Open Science Framework.

- ${claim_url}
+ Click here to set a password for your account.

- Once you have set a password, you will be able to make contributions to "${node_title}" and create your own preprints and projects. You will automatically be subscribed to notification emails for this preprint. To change your email notification preferences, visit your user settings: ${domain + "settings/notifications/"}
-
- To preview "${node_title}" click the following link: ${node_absolute_url}
+ Once you have set a password, you will be able to make contributions to ${node_title} and create your own preprints and projects. You will automatically be subscribed to notification emails for this preprint. To change your email notification preferences, visit your user settings

(NOTE: if this preprint is unpublished, you will not be able to view it until you have confirmed your account)

- If you are not ${user_fullname} or you are erroneously being associated with "${node_title}" then email ${osf_contact_email} with the subject line "Claiming Error" to report the problem.
+ If you are not ${user_fullname} or you are erroneously being associated with ${node_title} then email ${osf_contact_email} with the subject line "Claiming Error" to report the problem.

Sincerely,