def test_apply_empty_mapping(self): """Test apply empty mapping proposal.""" setuped_kind = all_models.Option.query.filter( all_models.Option.role == "control_kind").first() with factories.single_commit(): control = factories.ControlFactory(title="1", kind=setuped_kind) proposal = factories.ProposalFactory( instance=control, content={"mapping_fields": { "kind": None }}, agenda="agenda content") control_id = control.id proposal_id = proposal.id self.assertEqual(0, len(control.comments)) with self.number_obj_revisions_for(control): self.apply_proposal(proposal, apply_reason="approved") control = all_models.Control.query.get(control_id) self.assertIsNone(control.kind) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.APPLIED, proposal.status) latest_revision = self.latest_revision_for(control) self.assertIn("kind", latest_revision.content) self.assertIsNone(latest_revision.content["kind"]) self.assertEqual(1, len(control.comments))
def test_simple_decline_status(self): """Test simple decline status.""" with factories.single_commit(): control = factories.ControlFactory(title="1") proposal = factories.ProposalFactory( instance=control, content={"fields": { "title": "2" }}, agenda="agenda content") control_id = control.id proposal_id = proposal.id revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(proposal.STATES.PROPOSED, proposal.status) self.assertEqual(1, len(revisions)) self.assertEqual(0, len(control.comments)) resp = self.api.put( proposal, { "proposal": { "status": proposal.STATES.DECLINED, "decline_reason": "declined bla", } }) self.assert200(resp) control = all_models.Control.query.get(control_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.DECLINED, proposal.status) self.assertEqual("1", control.title) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(1, len(revisions)) self.assertEqual(1, len(control.comments))
def test_apply_mapping_list(self): """Test apply mapping list proposal.""" with factories.single_commit(): category = factories.ControlCategoryFactory() control = factories.ControlFactory() control_id = control.id category_id = category.id with factories.single_commit(): proposal = factories.ProposalFactory( instance=control, content={ "mapping_list_fields": { "categories": { "deleted": [], "added": [ {"id": category_id, "type": "ControlCategory"}, ] } } }, agenda="agenda content") proposal_id = proposal.id with self.number_obj_revisions_for(control): self.apply_proposal(proposal, apply_reason="approved") control = all_models.Control.query.get(control_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.APPLIED, proposal.status) control = all_models.Control.query.get(control_id) self.assertEqual([all_models.ControlCategory.query.get(category_id)], control.categories) self.assertEqual(1, len(control.comments)) comment = control.comments[0] self.assertEqual(proposal, comment.initiator_instance)
def test_proposal_acl_poulation(self, read, update): """Test proposal perms with read {read} and update {update}.""" with factories.single_commit(): control = factories.ControlFactory(title="1") role = factories.AccessControlRoleFactory(object_type=control.type, name="role", read=read, update=update) proposal = factories.ProposalFactory(instance=control, content={"field": "a"}, agenda="agenda content") person = factories.PersonFactory() self.assertFalse(proposal.access_control_list) role_id = role.id control_id = control.id proposal_id = proposal.id control_content = control.log_json() control_content["access_control_list"] = [ {"ac_role_id": role_id, "person": {"type": "Person", "id": person.id}} ] resp = self.api.put(control, {"control": control_content}) self.assertEqual(200, resp.status_code) control = all_models.Control.query.get(control_id) proposal = all_models.Proposal.query.get(proposal_id) full_proposal_acls = all_models.AccessControlList.query.filter( all_models.AccessControlList.object_type == proposal.type, all_models.AccessControlList.object_id == proposal.id, ).all() self.assertEqual(int(read or update), len(full_proposal_acls))
def test_apply_mapping_cad(self): """Test apply mapping CAVs proposal.""" with factories.single_commit(): risk = factories.RiskFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="risk", attribute_type="Map:Person") person = factories.PersonFactory() cav = factories.CustomAttributeValueFactory( custom_attribute=cad, attributable=risk, attribute_object_id=person.id, attribute_value="Person", ) self.assertEqual(person, risk.custom_attribute_values[0].attribute_object) risk_id = risk.id proposal = factories.ProposalFactory(instance=risk, content={ "custom_attribute_values": { cad.id: { "attribute_value": "Person", "attribute_object": None, }, }, }, agenda="agenda content") with self.number_obj_revisions_for(risk): self.apply_proposal(proposal) risk = all_models.Risk.query.get(risk_id) cav = risk.custom_attribute_values[0] self.assertEqual("Person", cav.attribute_value) self.assertIsNone(cav.attribute_object_id)
def test_proposal_acl_poulation(self, read, update): """Test proposal perms with read {read} and update {update}.""" with factories.single_commit(): control = factories.ControlFactory(title="1") role = factories.AccessControlRoleFactory(object_type=control.type, name="role", read=read, update=update) proposal = factories.ProposalFactory(instance=control, content={"field": "a"}, agenda="agenda content") person = factories.PersonFactory() self.assertFalse(proposal.access_control_list) role_id = role.id control_id = control.id proposal_id = proposal.id control_content = control.log_json() control_content["access_control_list"] = [ {"ac_role_id": role_id, "person": {"type": "Person", "id": person.id}} ] resp = self.api.put(control, {"control": control_content}) self.assertEqual(200, resp.status_code) control = all_models.Control.query.get(control_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(int(read or update), len(proposal.access_control_list)) expected_roles = [] if update: expected_roles.append(all_models.Proposal.ACRoles.EDITOR) elif read: expected_roles.append(all_models.Proposal.ACRoles.READER) self.assertEqual( sorted(expected_roles), sorted([a.ac_role.name for a in proposal.access_control_list]))
def test_apply_mapping_cad(self): """Test apply mapping CAVs proposal.""" with factories.single_commit(): program = factories.ProgramFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="program", attribute_type="Text") cav = factories.CustomAttributeValueFactory( custom_attribute=cad, attributable=program, attribute_value="Person", ) self.assertEqual("Person", program.custom_attribute_values[0].attribute_value) program_id = program.id proposal = factories.ProposalFactory(instance=program, content={ "custom_attribute_values": { cad.id: { "attribute_value": "Person123", "attribute_object": None, }, }, }, agenda="agenda content") with self.number_obj_revisions_for(program): self.apply_proposal(proposal) program = all_models.Program.query.get(program_id) cav = program.custom_attribute_values[0] self.assertEqual("Person123", cav.attribute_value)
def test_change_status(self, agenda, comment_agenda, status, tmpl): """Test comment proposal status move to {status} with agenda {agenda}.""" test_email = "*****@*****.**" with factories.single_commit(): control = factories.ControlFactory() proposer = factories.PersonFactory(email=test_email) with factories.single_commit(): proposal = factories.ProposalFactory(instance=control, content={"field": "a"}, agenda="agenda content", proposed_by=proposer) control_id = control.id if status == all_models.Proposal.STATES.APPLIED: resp = self.api.put( proposal, {"proposal": { "status": status, "apply_reason": agenda }}) else: resp = self.api.put( proposal, {"proposal": { "status": status, "decline_reason": agenda }}) self.assertEqual(200, resp.status_code) control = all_models.Control.query.get(control_id) self.assertEqual(1, len(control.comments)) comment = tmpl.format(user=test_email, text=comment_agenda) self.assertEqual(comment, control.comments[0].description)
def test_proposal_apply_notification(self, notification_type, expected_notifications): """Reviewable object changed via proposal -> notification created""" with factories.single_commit(): program = factories.ProgramFactory() review = factories.ReviewFactory( status=all_models.Review.STATES.REVIEWED, reviewable=program, notification_type=notification_type) review_id = review.id proposal_content = { "fields": { "title": "new title" }, } proposal = factories.ProposalFactory(instance=program, content=proposal_content, agenda="agenda content") self.api.modify_object(proposal, {"status": proposal.STATES.APPLIED}) review = all_models.Review.query.get(review_id) self.assertEqual(review.status, all_models.Review.STATES.UNREVIEWED) review_notif_types = all_models.Review.NotificationObjectTypes notyf_unreviewed_type = all_models.Notification.query.join( all_models.NotificationType).filter( all_models.NotificationType.name == review_notif_types.STATUS_UNREVIEWED).all() self.assertEqual(expected_notifications, len(notyf_unreviewed_type))
def test_apply_cad(self, remove_cav): """Test apply proposal with change CAVs.""" with factories.single_commit(): control = factories.ControlFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="control") control_id = control.id proposal = factories.ProposalFactory(instance=control, content={ "custom_attribute_values": { cad.id: { "attribute_value": "321", "attribute_object": None, "remove_cav": remove_cav, }, }, }, agenda="agenda content") with self.number_obj_revisions_for(control): self.apply_proposal(proposal) control = all_models.Control.query.get(control_id) self.assertEqual("321", control.custom_attribute_values[0].attribute_value)
def test_proposal_apply(self): """Reviewable object changed via proposal -> review.state-> UNREVIEWED""" control = factories.ControlFactory() _, review = self.generator.generate_object( all_models.Review, { "reviewable": { "type": control.type, "id": control.id, }, "context": None, "status": all_models.Review.STATES.UNREVIEWED, "access_control_list": build_reviewer_acl(), "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE }, ) review_id = review.id proposal_content = { "fields": { "title": "new title" }, } proposal = factories.ProposalFactory(instance=control, content=proposal_content, agenda="agenda content") self.api.modify_object(proposal, {"status": proposal.STATES.APPLIED}) review = all_models.Review.query.get(review_id) self.assertEqual(review.status, all_models.Review.STATES.UNREVIEWED)
def test_update_field(self, field_name, value): """Test that fields are changeable""" program = factories.ProgramFactory() proposal = factories.ProposalFactory( instance=program, content={"fields": { field_name: value }}, agenda="agenda content") program_id = program.id self.apply_proposal(proposal) program = all_models.Program.query.get(program_id) self.assertEqual(value, getattr(program, field_name))
def test_apply_mapping(self): """Test apply mapping proposal.""" setuped_kind, update_kind = all_models.Option.query.filter( all_models.Option.role == "control_kind" )[:2] with factories.single_commit(): control = factories.ControlFactory(title="1", kind=setuped_kind) proposal = factories.ProposalFactory( instance=control, content={ "mapping_fields": { "kind": { "id": update_kind.id, "type": update_kind.type, }, }, }, agenda="agenda content") control_id = control.id proposal_id = proposal.id update_kind_id = update_kind.id self.assertEqual(proposal.STATES.PROPOSED, proposal.status) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id ).all() self.assertEqual(1, len(revisions)) self.assertEqual(0, len(control.comments)) resp = self.api.put( proposal, { "proposal": { "status": proposal.STATES.APPLIED, "apply_reason": "approved", } }) self.assert200(resp) control = all_models.Control.query.get(control_id) self.assertEqual(all_models.Option.query.get(update_kind_id), control.kind) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.APPLIED, proposal.status) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id ).all() self.assertEqual(2, len(revisions)) self.assertIn("kind", revisions[-1].content) self.assertIn("id", revisions[-1].content["kind"]) self.assertEqual(update_kind_id, revisions[-1].content["kind"]["id"]) self.assertEqual(1, len(control.comments))
def test_apply_mapping_list(self): """Test apply mapping list proposal.""" with factories.single_commit(): category = factories.ControlCategoryFactory() control = factories.ControlFactory() control_id = control.id category_id = category.id with factories.single_commit(): proposal = factories.ProposalFactory( instance=control, content={ "mapping_list_fields": { "categories": { "deleted": [], "added": [ { "id": category_id, "type": "ControlCategory" }, ] } } }, agenda="agenda content") proposal_id = proposal.id revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(1, len(revisions)) resp = self.api.put( proposal, { "proposal": { "status": proposal.STATES.APPLIED, "apply_reason": "approved", } }) self.assertEqual(200, resp.status_code) control = all_models.Control.query.get(control_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.APPLIED, proposal.status) control = all_models.Control.query.get(control_id) self.assertEqual([all_models.ControlCategory.query.get(category_id)], control.categories) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(2, len(revisions)) self.assertEqual(1, len(control.comments)) comment = control.comments[0] self.assertEqual(proposal, comment.initiator_instance)
def test_proposal_apply_review_status(self, notification_type, num_notifications_expected): """Change via proposal with ignorable attrs review status not change""" with factories.single_commit(): risk = factories.RiskFactory() review = factories.ReviewFactory( status=all_models.Review.STATES.REVIEWED, reviewable=risk, notification_type=notification_type ) review_id = review.id user = factories.PersonFactory() acl = factories.AccessControlListFactory( ac_role=factories.AccessControlRoleFactory(object_type="Risk"), object=risk ) proposal_content = { "access_control_list": { acl.ac_role_id: { "added": [{"id": user.id, "email": user.email}], "deleted": [] } } } proposal = factories.ProposalFactory( instance=risk, content=proposal_content, agenda="agenda content" ) self.api.modify_object(proposal, {"status": proposal.STATES.APPLIED}) review = all_models.Review.query.get(review_id) self.assertEqual(review.status, all_models.Review.STATES.REVIEWED) review_notif_types = all_models.Review.NotificationObjectTypes notif_unreviewed_type = all_models.Notification.query.join( all_models.NotificationType ).filter( all_models.NotificationType.name == review_notif_types.STATUS_UNREVIEWED ).all() self.assertEqual(num_notifications_expected, len(notif_unreviewed_type))
def test_simple_get_proposal(self): """Test simple get proposal.""" with factories.single_commit(): program = factories.ProgramFactory() proposal = factories.ProposalFactory(instance=program, content={"field": "a"}, agenda="agenda content") instance_dict = {"id": program.id, "type": program.type} resp = self.api.get(all_models.Proposal, proposal.id) self.assert200(resp) self.assertIn("proposal", resp.json) data = resp.json["proposal"] self.assertIn("content", data) self.assertIn("instance", data) self.assertIn("agenda", data) self.assertDictEqual(instance_dict, data["instance"]) self.assertDictEqual({"field": "a"}, data["content"]) self.assertEqual("agenda content", data["agenda"])
def test_proposal_apply(self): """Reviewable object changed via proposal -> review.state-> UNREVIEWED""" control = factories.ControlFactory() _, review = generate_review_object(control) review_id = review.id proposal_content = { "fields": { "title": "new title" }, } proposal = factories.ProposalFactory(instance=control, content=proposal_content, agenda="agenda content") self.api.modify_object(proposal, {"status": proposal.STATES.APPLIED}) review = all_models.Review.query.get(review_id) self.assertEqual(review.status, all_models.Review.STATES.UNREVIEWED)
def test_proposal_put(self, send_email_mock): """Test sending mention email after a change of proposal.""" with factories.single_commit(): author_person = factories.PersonFactory(email="*****@*****.**") factories.PersonFactory(email="*****@*****.**") risk = factories.RiskFactory(title="Risk2") proposal = factories.ProposalFactory( instance=risk, content={"fields": { "title": "Risk3" }}, agenda=u'some agenda', proposed_by=author_person, ) url = urljoin(get_url_root(), utils.view_url_for(risk)) proposal_id = proposal.id proposal = all_models.Proposal.query.get(proposal_id) api = api_helper.Api() with freeze_time("2018-01-10 07:31:42"): data = { "status": proposal.STATES.APPLIED, "apply_reason": u'<a href=\"mailto:[email protected]\"></a>', } response = api.put(proposal, {"proposal": data}) self.assertEqual(200, response.status_code) expected_title = (u"[email protected] mentioned you on " u"a comment within Risk3") expected_body = ( u"[email protected] mentioned you on a comment within Risk3 " u"at 01/09/2018 23:31:42 PST:\n" u"<p>Proposal created by [email protected] has been applied" u" with a comment: " u'<a href="mailto:[email protected]"></a></p>\n') body = settings.EMAIL_MENTIONED_PERSON.render( person_mention={ "comments": [expected_body], "url": url, }) send_email_mock.assert_called_once_with(u"*****@*****.**", expected_title, body)
def test_apply_mapping_cad(self, remove_cav): """Test apply mapping CAVs proposal.""" with factories.single_commit(): control = factories.ControlFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="control", attribute_type="Map:Person") person = factories.PersonFactory() cav = factories.CustomAttributeValueFactory( custom_attribute=cad, attributable=control, attribute_object_id=person.id, attribute_value="Person", ) self.assertEqual(person, control.custom_attribute_values[0].attribute_object) control_id = control.id proposal = factories.ProposalFactory(instance=control, content={ "custom_attribute_values": { cad.id: { "attribute_value": "Person", "attribute_object": None, "remove_cav": remove_cav, }, }, }, agenda="agenda content") resp = self.api.put(proposal, {"proposal": { "status": proposal.STATES.APPLIED }}) self.assert200(resp) control = all_models.Control.query.get(control_id) if remove_cav: self.assertFalse(control.custom_attribute_values) else: cav = control.custom_attribute_values[0] self.assertEqual("Person", cav.attribute_value) self.assertIsNone(cav.attribute_object_id)
def test_simple_decline_status(self): """Test simple decline status.""" with factories.single_commit(): program = factories.ProgramFactory(title="1") proposal = factories.ProposalFactory( instance=program, content={"fields": { "title": "2" }}, agenda="agenda content") program_id = program.id proposal_id = proposal.id self.assertEqual(proposal.STATES.PROPOSED, proposal.status) self.assertEqual(0, len(program.comments)) with self.number_obj_revisions_for(program, increase_on=0): self.decline_proposal(proposal, decline_reason="declined bla") program = all_models.Program.query.get(program_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.DECLINED, proposal.status) self.assertEqual("1", program.title) self.assertEqual(1, len(program.comments))
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_simple_apply_status(self): """Test simple apply status.""" with factories.single_commit(): risk = factories.RiskFactory(title="1") proposal = factories.ProposalFactory( instance=risk, content={"fields": { "title": "2" }}, agenda="agenda content") risk_id = risk.id proposal_id = proposal.id self.assertEqual(proposal.STATES.PROPOSED, proposal.status) self.assertEqual(0, len(risk.comments)) with self.number_obj_revisions_for(risk): self.apply_proposal(proposal, apply_reason="approved") risk = all_models.Risk.query.get(risk_id) proposal = all_models.Proposal.query.get(proposal_id) self.assertEqual(proposal.STATES.APPLIED, proposal.status) self.assertEqual("2", risk.title) self.assertEqual("2", self.latest_revision_for(risk).content['title']) self.assertEqual(1, len(risk.comments))
def test_apply_cad(self, remove_cav): """Test apply proposal with change CAVs.""" with factories.single_commit(): control = factories.ControlFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="control") control_id = control.id proposal = factories.ProposalFactory(instance=control, content={ "custom_attribute_values": { cad.id: { "attribute_value": "321", "attribute_object": None, "remove_cav": remove_cav, }, }, }, agenda="agenda content") revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(1, len(revisions)) resp = self.api.put(proposal, {"proposal": { "status": proposal.STATES.APPLIED }}) self.assert200(resp) control = all_models.Control.query.get(control_id) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id).all() self.assertEqual(2, len(revisions)) self.assertEqual("321", control.custom_attribute_values[0].attribute_value)
def test_apply_cad(self): """Test apply proposal with change CAVs.""" with factories.single_commit(): program = factories.ProgramFactory(title="1") cad = factories.CustomAttributeDefinitionFactory( definition_type="program") program_id = program.id proposal = factories.ProposalFactory(instance=program, content={ "custom_attribute_values": { cad.id: { "attribute_value": "321", "attribute_object": None, }, }, }, agenda="agenda content") with self.number_obj_revisions_for(program): self.apply_proposal(proposal) program = all_models.Program.query.get(program_id) self.assertEqual("321", program.custom_attribute_values[0].attribute_value)
def test_apply_acl(self): # pylint: disable=too-many-locals """Test simple apply acl proposal.""" with factories.single_commit(): control = factories.ControlFactory(title="1") role_1 = factories.AccessControlRoleFactory(name="role_1", object_type="Control") role_2 = factories.AccessControlRoleFactory(name="role_2", object_type="Control") role_3 = factories.AccessControlRoleFactory(name="role_3", object_type="Control") role_4 = factories.AccessControlRoleFactory(name="role_4", object_type="Control") role_5 = factories.AccessControlRoleFactory(name="role_5", object_type="Control") person_1 = factories.PersonFactory() person_2 = factories.PersonFactory() person_3 = factories.PersonFactory() factories.AccessControlListFactory( person=person_1, ac_role=role_1, object=control, ) factories.AccessControlListFactory( person=person_2, ac_role=role_2, object=control, ) factories.AccessControlListFactory( person=person_3, ac_role=role_3, object=control, ) for person in [person_1, person_2, person_3]: factories.AccessControlListFactory( person=person, ac_role=role_4, object=control, ) with factories.single_commit(): proposal = factories.ProposalFactory(instance=control, content={ "access_control_list": { role_1.id: { "added": [{ "id": person_2.id, "email": person_2.email }], "deleted": [] }, role_2.id: { "added": [{ "id": person_1.id, "email": person_1.email }], "deleted": [{ "id": person_2.id, "email": person_2.email }] }, role_3.id: { "added": [{ "id": person_3.id, "email": person_3.email }], "deleted": [{ "id": person_2.id, "email": person_2.email }] }, role_4.id: { "added": [], "deleted": [{ "id": person_1.id, "email": person_1.email }, { "id": person_2.id, "email": person_2.email }, { "id": person_3.id, "email": person_3.email }] }, role_5.id: { "added": [{ "id": person_1.id, "email": person_1.email }, { "id": person_2.id, "email": person_2.email }, { "id": person_3.id, "email": person_3.email }], "deleted": [], }, } }, agenda="agenda content") control_id = control.id person_1_id = person_1.id person_2_id = person_2.id person_3_id = person_3.id role_1_id = role_1.id role_2_id = role_2.id role_3_id = role_3.id role_4_id = role_4.id role_5_id = role_5.id self.assertEqual(proposal.STATES.PROPOSED, proposal.status) with self.number_obj_revisions_for(control): self.apply_proposal(proposal) control = all_models.Control.query.get(control_id) result_dict = collections.defaultdict(set) for acl in control.access_control_list: result_dict[acl.ac_role_id].add(acl.person_id) self.assertEqual({person_1_id, person_2_id}, result_dict[role_1_id]) self.assertEqual({person_1_id}, result_dict[role_2_id]) self.assertEqual({person_3_id}, result_dict[role_3_id]) self.assertEqual(set([]), result_dict[role_4_id]) self.assertEqual({person_1_id, person_2_id, person_3_id}, result_dict[role_5_id])
def setUp(self): super(TestPermissions, self).setUp() self.api = Api() roles = {r.name: r for r in all_models.Role.query.all()} ac_roles = { r.name: r for r in all_models.AccessControlRole.query.all() } with factories.single_commit(): self.control = factories.ControlFactory() acrs = { "ACL_Reader": factories.AccessControlRoleFactory(name="ACL_Reader", object_type="Control", update=0), "ACL_Editor": factories.AccessControlRoleFactory(name="ACL_Editor", object_type="Control"), "ACL_Nobody": factories.AccessControlRoleFactory( name="ACL_Nobody", object_type="Control", read=0, update=0, delete=0, ), } self.program = factories.ProgramFactory() self.program.context.related_object = self.program self.relationship = factories.RelationshipFactory( source=self.program, destination=self.control, context=self.program.context, ) self.people = { "Creator": factories.PersonFactory(), "Reader": factories.PersonFactory(), "Editor": factories.PersonFactory(), "Administrator": factories.PersonFactory(), "ACL_Reader": factories.PersonFactory(), "ACL_Editor": factories.PersonFactory(), "ACL_Nobody": factories.PersonFactory(), "Program Editors": factories.PersonFactory(), "Program Managers": factories.PersonFactory(), "Program Readers": factories.PersonFactory(), } for role_name in ["Creator", "Reader", "Editor", "Administrator"]: rbac_factories.UserRoleFactory(role=roles[role_name], person=self.people[role_name]) for role_name in [ "Program Editors", "Program Managers", "Program Readers" ]: person = self.people[role_name] rbac_factories.UserRoleFactory(role=roles["Creator"], person=person) factories.AccessControlListFactory(ac_role=ac_roles[role_name], object=self.program, person=person) self.proposal = factories.ProposalFactory( instance=self.control, content={ "access_control_list": {}, "custom_attribute_values": {}, "fields": {}, "mapping_fields": {}, "mapping_list_fields": {}, }) for role_name in ["ACL_Reader", "ACL_Editor", "ACL_Nobody"]: person = self.people[role_name] rbac_factories.UserRoleFactory(role=roles["Creator"], person=person) factories.AccessControlListFactory(ac_role=acrs[role_name], object=self.control, person=person) with factories.single_commit(): proposal_model.set_acl_to_all_proposals_for(self.control)
def test_apply_acl(self): # pylint: disable=too-many-locals """Test simple apply acl proposal.""" with factories.single_commit(): role_1 = factories.AccessControlRoleFactory( name="role_1", object_type="Control") role_2 = factories.AccessControlRoleFactory( name="role_2", object_type="Control") role_3 = factories.AccessControlRoleFactory( name="role_3", object_type="Control") role_4 = factories.AccessControlRoleFactory( name="role_4", object_type="Control") role_5 = factories.AccessControlRoleFactory( name="role_5", object_type="Control") with factories.single_commit(): control = factories.ControlFactory(title="1") person_1 = factories.PersonFactory() person_2 = factories.PersonFactory() person_3 = factories.PersonFactory() acl_1 = control.acr_acl_map[role_1] acl_2 = control.acr_acl_map[role_2] acl_3 = control.acr_acl_map[role_3] acl_4 = control.acr_acl_map[role_4] factories.AccessControlPersonFactory( ac_list=acl_1, person=person_1, ) factories.AccessControlPersonFactory( ac_list=acl_2, person=person_2, ) factories.AccessControlPersonFactory( ac_list=acl_3, person=person_3, ) for person in [person_1, person_2, person_3]: factories.AccessControlPersonFactory( ac_list=acl_4, person=person, ) with factories.single_commit(): proposal = factories.ProposalFactory( instance=control, content={ "access_control_list": { role_1.id: { "added": [{"id": person_2.id, "email": person_2.email}], "deleted": [] }, role_2.id: { "added": [{"id": person_1.id, "email": person_1.email}], "deleted": [{"id": person_2.id, "email": person_2.email}] }, role_3.id: { "added": [{"id": person_3.id, "email": person_3.email}], "deleted": [{"id": person_2.id, "email": person_2.email}] }, role_4.id: { "added": [], "deleted": [{"id": person_1.id, "email": person_1.email}, {"id": person_2.id, "email": person_2.email}, {"id": person_3.id, "email": person_3.email}] }, role_5.id: { "added": [{"id": person_1.id, "email": person_1.email}, {"id": person_2.id, "email": person_2.email}, {"id": person_3.id, "email": person_3.email}], "deleted": [], }, } }, agenda="agenda content") control_id = control.id person_1_id = person_1.id person_2_id = person_2.id person_3_id = person_3.id role_1_id = role_1.id role_2_id = role_2.id role_3_id = role_3.id role_4_id = role_4.id role_5_id = role_5.id self.assertEqual(proposal.STATES.PROPOSED, proposal.status) revisions = all_models.Revision.query.filter( all_models.Revision.resource_type == control.type, all_models.Revision.resource_id == control.id ).all() self.assertEqual(1, len(revisions)) resp = self.api.put( proposal, {"proposal": {"status": proposal.STATES.APPLIED}}) self.assert200(resp) control = all_models.Control.query.get(control_id) result_dict = collections.defaultdict(set) for person, acl in control.access_control_list: result_dict[acl.ac_role_id].add(person.id) self.assertEqual({person_1_id, person_2_id}, result_dict[role_1_id]) self.assertEqual({person_1_id}, result_dict[role_2_id]) self.assertEqual({person_3_id}, result_dict[role_3_id]) self.assertEqual(set([]), result_dict[role_4_id]) self.assertEqual({person_1_id, person_2_id, person_3_id}, result_dict[role_5_id])
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])