def test_reviewer_notification_on_create_review(self, _): """Reviewer should receive email notification""" reviewer = factories.PersonFactory() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id program = factories.ProgramFactory() email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.UNREVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() template_args = bodybuilder_mock.call_args[1] self.assertListEqual([], template_args["proposals"]) self.assertListEqual([], template_args["object_state_reverted_data"]) self.assertEqual(1, len(template_args["review_requested_data"])) self.assertEqual( program.id, template_args["review_requested_data"][0].reviewable.id ) self.assertEqual( email_message, template_args["review_requested_data"][0].email_message )
def test_notification_subject(self, send_mail_mock): """Test that emails are sent with proper subject.""" expected_subject = "GGRC Change requests review digest " \ "for 01/15/2019 04:00:00 PST" reviewer = factories.PersonFactory() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id with factories.single_commit(): program_manager = factories.PersonFactory() program = factories.ProgramFactory() program.add_person_with_role_name(program_manager, "Program managers") email_message = "email email_message" _, review = self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) self.api.modify_object(review.reviewable, {"title": "new title"}) with mock.patch.object(fast_digest.DIGEST_TMPL, "render"): fast_digest.send_notification() for call_item in send_mail_mock.call_args_list: self.assertEqual(expected_subject, call_item[1]["subject"])
def test_reviewer_notification_on_create_review(self, _): """Reviewer should receive email notification""" reviewer = factories.PersonFactory() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id program = factories.ProgramFactory() email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.UNREVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() template_args = bodybuilder_mock.call_args[1] self.assertListEqual([], template_args["proposals"]) self.assertListEqual([], template_args["review_owners"]) self.assertEqual(1, len(template_args["review_reviewers"])) self.assertEqual( program.id, template_args["review_reviewers"][0].reviewable.id ) self.assertEqual( email_message, template_args["review_reviewers"][0].email_message )
def test_self_reviewer_notification_on_create_review(self, _): """Auto assigned Reviewer should NOT receive email notification""" current_user = all_models.Person.query.filter_by( email="*****@*****.**" ).one() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewer", object_type="Review", ).one().id control = factories.ControlFactory() email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": control.type, "id": control.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [ { "ac_role_id": reviewer_role_id, "person": { "id": current_user.id }, } ], }, ) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() # assert no email sent bodybuilder_mock.assert_not_called()
def test_notification_subject(self, send_mail_mock): """Test that emails are sent with proper subject.""" expected_subject = "GGRC Change requests review digest " \ "for 01/15/2019 04:00:00 PST" reviewer = factories.PersonFactory() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id with factories.single_commit(): risk_admin = factories.PersonFactory() risk = factories.RiskFactory() risk.add_person_with_role_name(risk_admin, "Admin") email_message = "email email_message" _, review = self.generator.generate_object( all_models.Review, { "reviewable": { "type": risk.type, "id": risk.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) self.api.modify_object(review.reviewable, {"title": "new title"}) with mock.patch.object(fast_digest.DIGEST_TMPL, "render"): fast_digest.send_notification() for call_item in send_mail_mock.call_args_list: self.assertEqual(expected_subject, call_item[1]["subject"])
def test_self_reviewer_notification_on_create_review(self, _): """Auto assigned Reviewer should NOT receive email notification""" current_user = all_models.Person.query.filter_by( email="*****@*****.**" ).one() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id program = factories.ProgramFactory() email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [ { "ac_role_id": reviewer_role_id, "person": { "id": current_user.id }, } ], }, ) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() # assert no email sent bodybuilder_mock.assert_not_called()
def test_email_proposal_program(self, role_name): """Test sending email to Program manager/Editor/Primary Contacts""" from ggrc.models import all_models role_1 = all_models.AccessControlRole.query.filter( all_models.AccessControlRole.name == role_name, all_models.AccessControlRole.object_type == 'Program', ).one() with factories.single_commit(): program = factories.ProgramFactory() person_1 = factories.PersonFactory() # has 1 role factories.AccessControlPersonFactory( ac_list=program.acr_acl_map[role_1], person=person_1) proposal_1 = factories.ProposalFactory( instance=program, content={ "fields": { "title": "a" }, "access_control_list": {}, "custom_attribute_values": {}, "mapping_fields": {}, "mapping_list_fields": {}, }, agenda="agenda 1") self.assertIsNone(proposal_1.proposed_notified_datetime) with mock.patch( "ggrc.notifications.common.send_email") as send_email_mock: with mock.patch.object(fast_digest.DIGEST_TMPL, "render") as bodybuilder_mock: fast_digest.send_notification() self.assertIsNotNone(proposal_1.proposed_notified_datetime) self.assertEqual(1, len(bodybuilder_mock.call_args_list)) self.assertEqual(1, len(send_email_mock.call_args_list)) # email to each required person self.assertEqual( [person_1.email], [a[1]["user_email"] for a in send_email_mock.call_args_list])
def test_reviewer_owner_notification(self, _): """Object owners should receive notifications System should send notification(s) to object's managers, primary contacts, secondary contacts, if object is reverted to 'Unreviewed'. """ reviewer = factories.PersonFactory(name='reviewers') reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id with factories.single_commit(): program_primary_contact = factories.PersonFactory(name='primary') program_secondary_contact = factories.PersonFactory( name='secondary') program = factories.ProgramFactory() program.add_person_with_role_name(program_primary_contact, "Primary Contacts") program.add_person_with_role_name(program_secondary_contact, "Secondary Contacts") email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) self.api.put(program, {"title": "new title"}) with mock.patch.object(fast_digest.DIGEST_TMPL, "render") as bodybuilder_mock: fast_digest.send_notification() # 4 emails to each user self.assertEqual(3, bodybuilder_mock.call_count) call_count = _call_counter(bodybuilder_mock) # 1 email to reviewer -> need to review self.assertEqual(1, call_count["review_reviewers"]) # 1 emails to owners -> object state updated self.assertEqual(2, call_count["review_owners"])
def test_email_sending(self): """Test sending emails about proposals.""" role_1 = factories.AccessControlRoleFactory(object_type="Program", notify_about_proposal=True) role_2 = factories.AccessControlRoleFactory(object_type="Program", notify_about_proposal=True) role_3 = factories.AccessControlRoleFactory( object_type="Program", notify_about_proposal=False) with factories.single_commit(): program = factories.ProgramFactory() person_1 = factories.PersonFactory() # has 1 role person_2 = factories.PersonFactory() # has no roles person_3 = factories.PersonFactory() # has 2 roles factories.PersonFactory() # not related to program at all factories.AccessControlPersonFactory( ac_list=program.acr_acl_map[role_1], person=person_1) factories.AccessControlPersonFactory( ac_list=program.acr_acl_map[role_1], person=person_3) factories.AccessControlPersonFactory( ac_list=program.acr_acl_map[role_2], person=person_3) factories.AccessControlPersonFactory( ac_list=program.acr_acl_map[role_3], person=person_2) proposal_1 = factories.ProposalFactory( instance=program, content={ "fields": { "title": "a" }, "access_control_list": {}, "custom_attribute_values": {}, "mapping_fields": {}, "mapping_list_fields": {}, }, agenda="agenda 1") proposal_2 = factories.ProposalFactory( instance=program, content={ "fields": { "title": "b" }, "access_control_list": {}, "custom_attribute_values": {}, "mapping_fields": {}, "mapping_list_fields": {}, }, agenda="agenda 2") self.assertIsNone(proposal_1.proposed_notified_datetime) self.assertIsNone(proposal_2.proposed_notified_datetime) with mock.patch("google.appengine.api.mail.send_mail") as mailer_mock: with mock.patch.object(fast_digest.DIGEST_TMPL, "render") as bodybuilder_mock: fast_digest.send_notification() self.assertIsNotNone(proposal_1.proposed_notified_datetime) self.assertIsNotNone(proposal_2.proposed_notified_datetime) self.assertEqual(2, len(bodybuilder_mock.call_args_list)) self.assertEqual(2, len(mailer_mock.call_args_list)) # email to each required person self.assertListEqual( sorted([person_1.email, person_3.email]), sorted([a[1]["to"] for a in mailer_mock.call_args_list])) # no matter how many roles each proposal should be otified # only once for that person self.assertListEqual( [2] * 2, [len(a[1]["proposals"]) for a in bodybuilder_mock.call_args_list])
def test_reviewer_owner_notification(self, _): """Object owners should receive notifications System should send notification(s) to object's admins, primary contacts, secondary contacts, if object is reverted to 'Unreviewed'. """ reviewer = factories.PersonFactory() reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewer", object_type="Review", ).one().id control_admin = factories.PersonFactory() control_admin_role = all_models.AccessControlRole.query.filter_by( name="Admin", object_type="Control", ).one() control_primary_contact = factories.PersonFactory() control_prim_contact_role = all_models.AccessControlRole.query.filter_by( name="Primary Contacts", object_type="Control", ).one() control_secondary_contact = factories.PersonFactory() control_sec_contact_role = all_models.AccessControlRole.query.filter_by( name="Secondary Contacts", object_type="Control", ).one() control = factories.ControlFactory( access_control_list=[ { "ac_role": control_admin_role, "person": control_admin }, { "ac_role": control_prim_contact_role, "person": control_primary_contact }, { "ac_role": control_sec_contact_role, "person": control_secondary_contact } ] ) email_message = "email email_message" _, review = self.generator.generate_object( all_models.Review, { "reviewable": { "type": control.type, "id": control.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) self.api.modify_object(review.reviewable, {"title": "new title"}) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() # 4 emails to each user self.assertEqual(4, bodybuilder_mock.call_count) call_count = _call_counter(bodybuilder_mock) # 1 email to reviewer -> need to review self.assertEqual(1, call_count["review_reviewers"]) # 1 emails to owners -> object state updated self.assertEqual(3, call_count["review_owners"])
def test_email_sending(self): """Test sending emails about proposals.""" role_1 = factories.AccessControlRoleFactory(object_type="Risk", notify_about_proposal=True) role_2 = factories.AccessControlRoleFactory(object_type="Risk", notify_about_proposal=True) role_3 = factories.AccessControlRoleFactory(object_type="Risk", notify_about_proposal=False) with factories.single_commit(): risk = factories.RiskFactory() person_1 = factories.PersonFactory() # has 1 role person_2 = factories.PersonFactory() # has no roles person_3 = factories.PersonFactory() # has 2 roles factories.PersonFactory() # not related to risk at all factories.AccessControlPersonFactory( ac_list=risk.acr_acl_map[role_1], person=person_1 ) factories.AccessControlPersonFactory( ac_list=risk.acr_acl_map[role_1], person=person_3 ) factories.AccessControlPersonFactory( ac_list=risk.acr_acl_map[role_2], person=person_3 ) factories.AccessControlPersonFactory( ac_list=risk.acr_acl_map[role_3], person=person_2 ) proposal_1 = factories.ProposalFactory( instance=risk, content={ "fields": {"title": "a"}, "access_control_list": {}, "custom_attribute_values": {}, "mapping_fields": {}, "mapping_list_fields": {}, }, agenda="agenda 1") proposal_2 = factories.ProposalFactory( instance=risk, content={ "fields": {"title": "b"}, "access_control_list": {}, "custom_attribute_values": {}, "mapping_fields": {}, "mapping_list_fields": {}, }, agenda="agenda 2") self.assertIsNone(proposal_1.proposed_notified_datetime) self.assertIsNone(proposal_2.proposed_notified_datetime) with mock.patch("google.appengine.api.mail.send_mail") as mailer_mock: with mock.patch.object(fast_digest.DIGEST_TMPL, "render") as bodybuilder_mock: fast_digest.send_notification() self.assertIsNotNone(proposal_1.proposed_notified_datetime) self.assertIsNotNone(proposal_2.proposed_notified_datetime) self.assertEqual(2, len(bodybuilder_mock.call_args_list)) self.assertEqual(2, len(mailer_mock.call_args_list)) # email to each required person self.assertListEqual( sorted([person_1.email, person_3.email]), sorted([a[1]["to"] for a in mailer_mock.call_args_list])) # no matter how many roles each proposal should be otified # only once for that person self.assertListEqual( [2] * 2, [len(a[1]["proposals"]) for a in bodybuilder_mock.call_args_list])
def test_reviewer_owner_notification(self, _): """Object owners should receive notifications System should send notification(s) to object's managers, primary contacts, secondary contacts, if object is reverted to 'Unreviewed'. """ reviewer = factories.PersonFactory(name='reviewers') reviewer_role_id = all_models.AccessControlRole.query.filter_by( name="Reviewers", object_type="Review", ).one().id with factories.single_commit(): program_primary_contact = factories.PersonFactory(name='primary') program_secondary_contact = factories.PersonFactory(name='secondary') program = factories.ProgramFactory() program.add_person_with_role_name(program_primary_contact, "Primary Contacts") program.add_person_with_role_name(program_secondary_contact, "Secondary Contacts") email_message = "email email_message" self.generator.generate_object( all_models.Review, { "reviewable": { "type": program.type, "id": program.id, }, "context": None, "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE, "status": all_models.Review.STATES.REVIEWED, "email_message": email_message, "access_control_list": [{ "ac_role_id": reviewer_role_id, "person": { "id": reviewer.id }, }], }, ) self.api.put(program, {"title": "new title"}) with mock.patch.object( fast_digest.DIGEST_TMPL, "render" ) as bodybuilder_mock: fast_digest.send_notification() # 4 emails to each user self.assertEqual(3, bodybuilder_mock.call_count) call_count = _call_counter(bodybuilder_mock) # 1 email to reviewer -> need to review self.assertEqual(1, call_count["review_reviewers"]) # 1 emails to owners -> object state updated self.assertEqual(2, call_count["review_owners"])