diff --git a/server/features/assignments.feature b/server/features/assignments.feature index 664049bfa..67ad25d85 100644 --- a/server/features/assignments.feature +++ b/server/features/assignments.feature @@ -21,6 +21,10 @@ Feature: Assignments """ [{"name": "Sports", "content_expiry": 60, "members": [{"user": "#CONTEXT_USER_ID#"}]}] """ + And "users" + """ + [{"_id": "507f191e810c19729de87034", "name":"testfoo", "email":"foo@122d.com", "username":"johnfoo"}] + """ @auth Scenario: Empty planning list diff --git a/server/features/planning.feature b/server/features/planning.feature index d2df9c862..ee60b96c9 100644 --- a/server/features/planning.feature +++ b/server/features/planning.feature @@ -625,6 +625,10 @@ Feature: Planning """ [{"_id": "desk_123", "name": "Politic Desk"}] """ + Given "users" + """ + [{"_id": "507f191e810c19729de871eb", "name":"testfoo", "email":"foo@122d.com", "username":"johnfoo"}] + """ Given "vocabularies" """ [{ diff --git a/server/planning/assignments/__init__.py b/server/planning/assignments/__init__.py index 9d1606a40..f6d686621 100644 --- a/server/planning/assignments/__init__.py +++ b/server/planning/assignments/__init__.py @@ -137,3 +137,14 @@ def init_app(app): label=lazy_gettext("Default sort preferences for Assignment lists"), category=lazy_gettext("Assignments"), ) + + superdesk.register_default_user_preference( + "assignment:notification", + { + "type": "bool", + "enabled": True, + "default": True, + }, + label=lazy_gettext("Send Assignment notifications via email"), + category=lazy_gettext("notifications"), + ) diff --git a/server/planning/assignments/assignments.py b/server/planning/assignments/assignments.py index 71d4f0542..d227606b7 100644 --- a/server/planning/assignments/assignments.py +++ b/server/planning/assignments/assignments.py @@ -345,6 +345,13 @@ def send_assignment_notification(self, updates, original=None, force=False): return assigned_to = updates.get("assigned_to", {}) + + # No assignment notification sent, if user is not enabled assignment notification + if assigned_to.get("user") and not superdesk.get_resource_service( + "preferences" + ).assignment_notification_is_enabled(user_id=assigned_to.get("user")): + return + assignment_id = updates.get("_id") or assigned_to.get("assignment_id", "Unknown") if not original: original = {} diff --git a/server/planning/assignments/assignments_link_tests.py b/server/planning/assignments/assignments_link_tests.py index 29cbdd503..a13fcd341 100644 --- a/server/planning/assignments/assignments_link_tests.py +++ b/server/planning/assignments/assignments_link_tests.py @@ -4,6 +4,7 @@ assignment_id = "5b20652a1d41c812e24aa49e" +USER_ID = ObjectId("5d385f31fe985ec67a0ca583") class AssignmentLinkTestCase(TestCase): @@ -81,12 +82,33 @@ def test_updates_creates_new_record(self): "coverage_item": "cov1", "assigned_to": { "state": "assigned", - "user": "test", + "user": USER_ID, "desk": "test", }, } ], ) + self.app.data.insert( + "users", + [ + { + "_id": USER_ID, + "username": "admin", + "password": "blabla", + "email": "admin@example.com", + "user_type": "administrator", + "is_active": True, + "needs_activation": False, + "is_author": True, + "is_enabled": True, + "display_name": "John Smith", + "sign_off": "ADM", + "first_name": "John", + "last_name": "Smith", + "role": ObjectId("5d542206c04280bc6d6157f9"), + } + ], + ) get_resource_service("assignments_link").post( [{"assignment_id": assignment_id, "item_id": "item1", "reassign": True}] diff --git a/server/planning/assignments/assignments_unlink_test.py b/server/planning/assignments/assignments_unlink_test.py index fdfe94f2a..c54d9beca 100644 --- a/server/planning/assignments/assignments_unlink_test.py +++ b/server/planning/assignments/assignments_unlink_test.py @@ -5,9 +5,34 @@ class AssignmentUnlinkTestCase(TestCase): + USER_ID = ObjectId("5d385f31fe985ec67a0ca583") + + def setUp(self): + super().setUp() + with self.app.app_context(): + users = [ + { + "_id": self.USER_ID, + "username": "admin", + "password": "blabla", + "email": "admin@example.com", + "user_type": "administrator", + "is_active": True, + "needs_activation": False, + "is_author": True, + "is_enabled": True, + "display_name": "John Smith", + "sign_off": "ADM", + "first_name": "John", + "last_name": "Smith", + "role": ObjectId("5d542206c04280bc6d6157f9"), + } + ] + self.app.data.insert("users", users) + def test_delivery_record(self): with self.app.app_context(): - flask.g.user = {"_id": ObjectId()} + flask.g.user = {"_id": self.USER_ID} self.app.data.insert( "vocabularies", [ @@ -105,8 +130,8 @@ def test_delivery_record(self): def test_unlinks_all_content_updates(self): with self.app.app_context(): self.app.config.update({"PLANNING_LINK_UPDATES_TO_COVERAGES": True}) - flask.g.user = {"_id": ObjectId()} - user_id = ObjectId() + flask.g.user = {"_id": self.USER_ID} + user_id = self.USER_ID desk_id = ObjectId() # Make sure users a members of the desks @@ -218,8 +243,8 @@ def test_unlinks_all_content_updates(self): def test_unlinks_properly_on_unlinking_any_update_in_chain(self): with self.app.app_context(): self.app.config.update({"PLANNING_LINK_UPDATES_TO_COVERAGES": True}) - flask.g.user = {"_id": ObjectId()} - user_id = ObjectId() + flask.g.user = {"_id": self.USER_ID} + user_id = self.USER_ID desk_id = ObjectId() # Make sure users a members of the desks @@ -336,8 +361,8 @@ def test_unlinks_properly_on_unlinking_any_update_in_chain(self): def test_unlinks_archived_content(self): with self.app.app_context(): self.app.config.update({"PLANNING_LINK_UPDATES_TO_COVERAGES": True}) - flask.g.user = {"_id": ObjectId()} - user_id = ObjectId() + flask.g.user = {"_id": self.USER_ID} + user_id = self.USER_ID desk_id = ObjectId() self.app.data.insert( "vocabularies", diff --git a/server/planning/planning/planning_tests.py b/server/planning/planning/planning_tests.py index 1ae04c00a..64664cf01 100644 --- a/server/planning/planning/planning_tests.py +++ b/server/planning/planning/planning_tests.py @@ -3,6 +3,9 @@ from planning.tests import TestCase from superdesk import get_resource_service from superdesk.errors import SuperdeskApiError +from bson import ObjectId + +USER_ID = ObjectId("5d385f31fe985ec67a0ca583") class DuplicateCoverageTestCase(TestCase): @@ -28,7 +31,7 @@ def setUp(self): }, "news_coverage_status": {"qcode": "ncostat:int"}, "assigned_to": { - "user": "59f7f0881d41c88cab3f2a99", + "user": USER_ID, "desk": "desk1", "state": "in_progress", }, @@ -37,6 +40,27 @@ def setUp(self): } ], ) + self.app.data.insert( + "users", + [ + { + "_id": USER_ID, + "username": "admin", + "password": "blabla", + "email": "admin@example.com", + "user_type": "administrator", + "is_active": True, + "needs_activation": False, + "is_author": True, + "is_enabled": True, + "display_name": "John Smith", + "sign_off": "ADM", + "first_name": "John", + "last_name": "Smith", + "role": ObjectId("5d542206c04280bc6d6157f9"), + } + ], + ) def test_duplicate(self): with self.app.app_context(): @@ -49,7 +73,7 @@ def test_duplicate(self): "scheduled": datetime(2029, 10, 13, 15, 00, tzinfo=pytz.UTC), }, "assigned_to": { - "user": "562435231d41c835d7b5fb55", + "user": USER_ID, "desk": "desk2", "state": "in_progress", }, @@ -63,7 +87,7 @@ def test_duplicate(self): self.assertEqual(new_coverage["planning"]["slugline"], "new slugline") self.assertEqual(new_coverage["planning"]["scheduled"], datetime(2029, 10, 13, 15, 00, tzinfo=pytz.UTC)) - self.assertEqual(new_coverage["assigned_to"]["user"], "562435231d41c835d7b5fb55") + self.assertEqual(new_coverage["assigned_to"]["user"], USER_ID) self.assertEqual(new_coverage["assigned_to"]["desk"], "desk2") self.assertEqual(new_coverage["assigned_to"]["state"], "in_progress") self.assertEqual(new_coverage["news_coverage_status"], {"qcode": "ncostat:onreq"})