def setUp(self): super(TestPermissionsOnAssessmentRelatedAssignables, self).setUp() self.api = Api() self.generator = ObjectGenerator() _, self.reader = self.generator.generate_person(user_role="Reader") audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) object_person_rel = factories.RelationshipFactory( source=assessment, destination=self.reader) factories.RelationshipAttrFactory(relationship_id=object_person_rel.id, attr_name="AssigneeType", attr_value="Assessor") factories.RelationshipFactory(source=audit, destination=assessment) document = factories.DocumentFactory() document_id = document.id doc_rel = factories.RelationshipFactory(source=assessment, destination=document) doc_rel_id = doc_rel.id self.api.set_user(self.reader) self.document = all_models.Document.query.get(document_id) self.doc_relationship = all_models.Relationship.query.get(doc_rel_id)
def test_asmnt_cads_update_completed(self): """Test update of assessment without cads.""" with factories.single_commit(): audit = factories.AuditFactory() asmnt = factories.AssessmentFactory(audit=audit) factories.CustomAttributeDefinitionFactory( title="CAD", definition_type="assessment", definition_id=asmnt.id, attribute_type="Text", mandatory=True, ) data = OrderedDict([ ("object_type", "Assessment"), ("Code*", asmnt.slug), ("Audit", audit.slug), ("Assignees", "*****@*****.**"), ("Creators", "*****@*****.**"), ("Title", "Test title"), ("State", "Completed"), ("CAD", "Some value"), ]) response = self.import_data(data) self._check_csv_response(response, {})
def test_audit_clone_custom_attributes(self): """Test if custom attributes were copied correctly""" audit = factories.AuditFactory() ca_def_text = factories.CustomAttributeDefinitionFactory( title="test audit CA def 1", definition_type="audit", attribute_type="Text" ) factories.CustomAttributeValueFactory( custom_attribute=ca_def_text, attributable=audit, attribute_value="CA 1 value" ) self.clone_object(audit) audit_copy = db.session.query(models.Audit).filter( models.Audit.title.like("%copy%")).first() self.assertEqual( models.CustomAttributeValue.query.filter_by( attributable_type="Audit", attributable_id=audit_copy.id ).count(), 1, "Custom Attribute weren't copied.")
def test_error_ca_import_states(self, dry_run, has_error): """Test changing state of Assessment with unfilled mandatory CA""" with factories.single_commit(): audit = factories.AuditFactory() asmnt = factories.AssessmentFactory(audit=audit) factories.CustomAttributeDefinitionFactory( title="def1", definition_type="assessment", definition_id=asmnt.id, attribute_type="Date", mandatory=True, ) response = self.import_data(OrderedDict([ ("object_type", "Assessment"), ("Code*", asmnt.slug), ("Audit", audit.slug), ("Assignees", "*****@*****.**"), ("Creators", "*****@*****.**"), ("Title", "Test title"), ("State", "Completed"), ]), dry_run=dry_run) expected_errors = { "Assessment": { "row_errors": { errors.VALIDATION_ERROR.format( line=3, column_name="State", message="CA-introduced completion preconditions are not " "satisfied. Check preconditions_failed of items " "of self.custom_attribute_values") } } } self._check_csv_response(response, expected_errors if has_error else {})
def test_put_mapped_roles(self): """Test mapped roles creation when assessment updated""" with factories.single_commit(): person = factories.PersonFactory() person_email = person.email audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) audit.add_person_with_role_name(person, "Assignees") assessment.add_person_with_role_name(person, "Creators") factories.RelationshipFactory(source=audit, destination=assessment) # Add verifier to Assessment response = self.api.put( assessment, { "access_control_list": [ acl_helper.get_acl_json(role_id, person.id) for role_id in self.assignee_roles.values() ] }) self.assertEqual(response.status_code, 200) db.session.add_all([audit, assessment]) self.assert_mapped_role("Verifiers", person_email, assessment) self.assert_propagated_role("Verifiers", person_email, audit)
def test_complete_assessment_create_issue(self, mock_create_issue): """Test the creation of issue for completed assessment.""" audit = factories.AuditFactory() self.api.post(all_models.Assessment, { 'assessment': { 'title': 'Assessment1', 'context': None, 'audit': { 'id': audit.id, 'type': audit.type, }, 'status': 'Completed', } }) asmt = all_models.Assessment.query.filter_by(title='Assessment1').one() with mock.patch.object( assessment_integration.AssessmentTrackerHandler, '_is_tracker_enabled', return_value=True ): issue_params = { 'enabled': True, 'component_id': 123123, 'hotlist_id': 123123, 'issue_type': 'PROCESS', 'issue_priority': 'P2', 'issue_severity': 'S2', 'title': 'Default Title' } self.api.put(asmt, {'issue_tracker': issue_params}) mock_create_issue.assert_called_once() # pylint: disable=W0212 self.assertEqual(mock_create_issue._mock_call_args[0][0]['status'], 'VERIFIED')
def test_local_ca_update_change_status(self, from_status, expected_status): """Move Assessment from '{0}' to '{1}' update 'local custom attribute'""" with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit, status=from_status) factories.RelationshipFactory(source=audit, destination=assessment) cad = factories.CustomAttributeDefinitionFactory( definition_id=assessment.id, definition_type='assessment', attribute_type='Rich Text', title='rich_test_gca', multi_choice_options='', ) self.api.modify_object( assessment, { 'custom_attribute_values': [{ 'custom_attribute_id': cad.id, 'attribute_value': 'new value', }] }) assessment = self.refresh_object(assessment) self.assertEqual(expected_status, assessment.status)
def test_import_view_only_field(self, value): "Test import view only fields" with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory(source=audit, destination=assessment) resp = self.import_data( OrderedDict([ ("object_type", "Assessment"), ("Code*", assessment.slug), ("archived", value), ])) self.assertEqual([{ u'ignored': 0, u'updated': 1, u'block_errors': [], u'name': u'Assessment', u'created': 0, u'deleted': 0, u'row_warnings': [], u'rows': 1, u'block_warnings': [], u'row_errors': [], }], resp)
def test_asmt_state_after_updating_verifiers(self, new_verifier): """Test that after updating Verifiers assessment became In Progress""" audit = factories.AuditFactory() assessment = \ factories.AssessmentFactory(audit=audit, status=all_models.Assessment.DONE_STATE, ) person = factories.PersonFactory(email="*****@*****.**") factories.AccessControlPersonFactory( ac_list=assessment.acr_name_acl_map["Verifiers"], person=person, ) self.assertEqual( all_models.Assessment.query.get(assessment.id).status, all_models.Assessment.DONE_STATE) self.import_data( OrderedDict([ ("object_type", "Assessment"), ("Code", assessment.slug), ("Verifiers", new_verifier), ])) self.assertEqual( all_models.Assessment.query.get(assessment.id).status, all_models.Assessment.PROGRESS_STATE)
def test_assignee_deletion_unmap(self): """Test deletion of assignee roles when snapshot is unmapped.""" with factories.single_commit(): person = factories.PersonFactory() person_email = person.email audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) for ac_role_id in self.assignee_roles.values(): factories.AccessControlListFactory(ac_role_id=ac_role_id, person=person, object=assessment) factories.RelationshipFactory(source=audit, destination=assessment) snapshot = self._create_snapshots(audit, [factories.ControlFactory()])[0] rel = factories.RelationshipFactory(source=assessment, destination=snapshot) for ac_role in self.assignee_roles.keys(): self.assert_propagated_role("{}".format(ac_role), person_email, snapshot) response = self.api.delete(rel) self.assertEqual(response.status_code, 200) snap_acls = all_models.AccessControlList.query.filter_by( object_type="Snapshot") self.assertEqual(snap_acls.count(), 0)
def test_audit_roles_saving(self): """Test that snapshot unmapping will not affect audit""" with factories.single_commit(): person = factories.PersonFactory() person_email = person.email audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) snapshot = self._create_snapshots(audit, [factories.ControlFactory()])[0] for ac_role_id in self.assignee_roles.values(): factories.AccessControlListFactory(ac_role_id=ac_role_id, person=person, object=assessment) factories.RelationshipFactory(source=audit, destination=assessment) snap_rel = factories.RelationshipFactory(source=assessment, destination=snapshot) response = self.api.delete(snap_rel) self.assertEqual(response.status_code, 200) db.session.add(audit) for ac_role in self.assignee_roles.keys(): self.assert_propagated_role("{}".format(ac_role), person_email, audit)
def test_import_permissions(self): """Test that permissions aren't recalculated during import new objects.""" with factories.single_commit(): audit = factories.AuditFactory(slug="audit-1") market = factories.MarketFactory() user = factories.PersonFactory() system_role = all_models.Role.query.filter( all_models.Role.name == "Creator").one() rbac_factories.UserRoleFactory(role=system_role, person=user) audit.add_person_with_role_name(user, "Audit Captains") market.add_person_with_role_name(user, "Admin") self._create_snapshots(audit, [market]) data = [ collections.OrderedDict([ ("Code*", ""), ("Audit*", "audit-1"), ("Title*", "assessment{}".format(i)), ("State", "Not Started"), ("Assignees*", "*****@*****.**"), ("Creators*", "*****@*****.**"), ("map:market versions", market.slug), ]) for i in range(10) ] self.api.set_user(user) with mock.patch("ggrc_basic_permissions.load_access_control_list", side_effect=ggrc_basic_permissions. load_access_control_list) as acl_loader: response = self.api.run_import_job(user, "Assessment", data) self.assert200(response) # 10 Assessments should be created in import self.assertEqual(all_models.Assessment.query.count(), 10) # Permissions were loaded once on dry run and once on real run self.assertEqual(acl_loader.call_count, 2)
def setUp(self): """Setup tests data""" super(TestIssueUnmap, self).setUp() self.generator = generator.ObjectGenerator(fail_no_json=False) with factories.single_commit(): audit = factories.AuditFactory() self.audit_id = audit.id assessments = [ factories.AssessmentFactory(audit=audit) for _ in range(2) ] objectives = [factories.ObjectiveFactory() for _ in range(2)] snapshots = self._create_snapshots(audit, objectives) self.snapshot_ids = [s.id for s in snapshots] issue = factories.IssueFactory() self.issue_id = issue.id factories.RelationshipFactory(source=audit, destination=assessments[0]) factories.RelationshipFactory(source=audit, destination=assessments[1]) factories.RelationshipFactory( source=assessments[0], destination=snapshots[0] ) factories.RelationshipFactory( source=assessments[0], destination=snapshots[1] ) factories.RelationshipFactory( source=assessments[1], destination=snapshots[1] ) self.unmap_rel_id1 = factories.RelationshipFactory( source=issue, destination=assessments[0] ).id self.unmap_rel_id2 = factories.RelationshipFactory( source=issue, destination=assessments[1] ).id
def test_post_mapped_roles(self): """Test mapped roles creation when new assessment created""" audit = factories.AuditFactory() person = factories.PersonFactory() person_email = person.email response = self.api.post( all_models.Assessment, { "assessment": { "audit": { "id": audit.id, "type": "Audit" }, "access_control_list": [{ "ac_role_id": role_id, "person": { "id": person.id } } for role_id in self.assignee_roles.values()], "context": { "id": audit.context.id, "type": "Context" }, "title": "Some title" } }) self.assertEqual(response.status_code, 201) db.session.add(audit) assessment = all_models.Assessment.query.get( response.json["assessment"]["id"]) for role in self.assignee_roles: self.assert_mapped_role(role, person_email, assessment) self.assert_mapped_role("{} Mapped".format(role), person_email, audit)
def test_asmt_verified_date_readonly(self): """Test that Verified Date is readonly""" audit = factories.AuditFactory() date = datetime.datetime(2019, 05, 22) assessment = \ factories.AssessmentFactory(audit=audit, verified_date=date) expected_warnings = { 'Assessment': { 'row_warnings': { errors.UNMODIFIABLE_COLUMN.format( line=3, column_name="Verified Date" )}}} response = self.import_data(OrderedDict([ ("object_type", "Assessment"), ("Code", assessment.slug), ("Verifiers", "*****@*****.**"), ("Verified Date", "01/21/2019"), ])) self._check_csv_response(response, expected_warnings) self.assertEqual( all_models.Assessment.query.get(assessment.id).verified_date, date)
def test_mapping_snapshot_not_assessment_type(self, from_status, expected_status): """Move Assessment form '{0}' to '{1}' when map snapshot. Snapshot type != assessment type """ with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit, status=from_status, assessment_type='Contract') factories.RelationshipFactory(source=audit, destination=assessment) control = factories.ControlFactory(title='test control') snapshot = self._create_snapshots(audit, [control])[0] response, _ = self.objgen.generate_relationship( source=assessment, destination=snapshot, context=None, ) assessment = self.refresh_object(assessment) self.assertStatus(response, 201) self.assertEqual(expected_status, assessment.status)
def test_import_assessment_with_template(self): """If assessment exist and import with template and lca""" with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory() template = factories.AssessmentTemplateFactory() factories.RelationshipFactory(source=audit, destination=assessment) factories.CustomAttributeDefinitionFactory( title="Test LCA", definition_type="assessment", attribute_type="Text", definition_id=assessment.id ) response = self.import_data(OrderedDict([ ("object_type", "Assessment"), ("Code*", assessment.slug), ("Template", template.slug), ])) self.assertEquals([], response[0]["row_warnings"]) self.assertEquals([], response[0]["row_errors"])
def test_ticket_generation_assmt_allowed_on_create(self, status): """Test ticket generation allowed for Assessment in {} status on create""" with factories.single_commit(): audit = factories.AuditFactory() factories.IssueTrackerIssueFactory( issue_tracked_obj=audit, enabled=True, ) response = self.import_data( OrderedDict([ ("object_type", "Assessment"), ("Code*", "OBJ-1"), ("Audit*", audit.slug), ("Assignees*", "*****@*****.**"), ("Creators", "*****@*****.**"), ("Verifiers", "*****@*****.**"), ("Title", "Object Title"), ("State", status), ("Ticket Tracker Integration", "On"), ])) self._check_csv_response(response, {}) obj = all_models.Assessment.query.one() self.assertTrue(obj.issue_tracker["enabled"])
def test_create_new_assessment_with_mapped_control(self): "Test for creation assessment with mapped controls" audit = factories.AuditFactory() control = factories.ControlFactory() revision = models.Revision.query.filter( models.Revision.resource_id == control.id, models.Revision.resource_type == control.__class__.__name__).order_by( models.Revision.id.desc()).first() factories.SnapshotFactory(parent=audit, child_id=control.id, child_type=control.__class__.__name__, revision_id=revision.id) db.session.commit() self.assertFalse( db.session.query( models.Relationship.get_related_query( models.Assessment(), models.Snapshot()).exists()).first()[0]) slug = "TestAssessment" self.import_data( OrderedDict([ ("object_type", "Assessment"), ("Code*", slug), ("Audit*", audit.slug), ("Assignees*", models.Person.query.all()[0].email), ("Creators", models.Person.query.all()[0].email), ("Title", "Strange title"), ("map:control", control.slug), ])) assessment = models.Assessment.query.filter( models.Assessment.slug == slug).first() self.assertTrue( db.session.query( models.Relationship.get_related_query( assessment, models.Snapshot()).exists()).first()[0])
def test_enabled_state_assmt_tmpl_create_succeed(self, audit_value, tmpl_value, expected): """Test Template set integr state={2} if audit integr={0} and csv={1}""" audit = factories.AuditFactory() if audit_value is not None: factories.IssueTrackerIssueFactory( issue_tracked_obj=audit, enabled=audit_value, ) response = self.import_data( OrderedDict([ ("object_type", "Assessment Template"), ("Code*", "OBJ-1"), ("Audit*", audit.slug), ("Default Assignees*", "*****@*****.**"), ("Object Under Assessment", "Control"), ("Title", "Object Title"), ("Ticket Tracker Integration", tmpl_value), ])) self._check_csv_response(response, {}) obj = all_models.AssessmentTemplate.query.one() self._assert_integration_state(obj, expected)
def test_archived_assessments(self, archived_audits): """Test filtration by Archived Assessments.""" # Create 5 Audits, each of them has 3 Assessment with factories.single_commit(): audit_ids = [] for _ in range(5): audit = factories.AuditFactory() audit_ids.append(audit.id) for _ in range(3): factories.AssessmentFactory(audit=audit) # This list contain ids of assessments from audits in archived_audits expected_ids = [] for i in archived_audits: audit = all_models.Audit.query.get(audit_ids[i]) expected_ids += [a.id for a in audit.assessments] response = self.api.put(audit, {"archived": True}) self.assert200(response) ids = self.simple_query("Assessment", expression=["archived", "=", "true"], type_="ids", field="ids") self.assertItemsEqual(ids, expected_ids)
def test_single_acl(self, rel_order): """Test propagation for a single relationship with {}. Test propagation of program role to audit through a relationship with both options for source and destination. """ with factories.single_commit(): person = factories.PersonFactory() audit = factories.AuditFactory() rel_data = { rel_order[0]: audit, rel_order[1]: audit.program, } factories.RelationshipFactory(**rel_data) acl_entry = factories.AccessControlListFactory( ac_role=self.roles["Program"]["Program Editors"], object=audit.program, person=person, ) self.assertEqual(all_models.AccessControlList.query.count(), 1) propagation._handle_acl_step([acl_entry.id]) db.session.commit() self.assertEqual(all_models.AccessControlList.query.count(), 3)
def test_deletion_multiple_assignee(self): """Test deletion of multiple mapped roles.""" with factories.single_commit(): persons = [factories.PersonFactory() for _ in range(2)] person_ids = [p.id for p in persons] person_email = persons[1].email audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) for ac_role_id in self.assignee_roles.values(): for person in persons: factories.AccessControlListFactory( ac_role_id=ac_role_id, person=person, object=assessment ) factories.RelationshipFactory(source=audit, destination=assessment) # Remove assignee roles for first person response = self.api.put(assessment, { "access_control_list": [ acl_helper.get_acl_json(role_id, person_ids[1]) for role_id in self.assignee_roles.values() ] }) self.assertEqual(response.status_code, 200) assignee_acl = all_models.AccessControlList.query.filter_by( person_id=person_ids[0] ) # All roles for first person should be removed self.assertEqual(assignee_acl.count(), 0) db.session.add(audit) for ac_role in self.assignee_roles.keys(): self.assert_mapped_role(ac_role, person_email, assessment) self.assert_propagated_role( "{}".format(ac_role), person_email, audit )
def test_invalid_email_import(self, _): """Test import of invalid email.""" wrong_email = "some_wrong_email" audit = factories.AuditFactory() response = self.import_data(OrderedDict([ ("object_type", "Assessment"), ("Code*", "Test Assessment"), ("Audit*", audit.slug), ("Assignees*", wrong_email), ("Title", "Some title"), ])) expected_errors = { "Assessment": { "row_errors": { errors.VALIDATION_ERROR.format( line=3, column_name="Assignees", message="Email address '{}' is invalid." " Valid email must be provided".format(wrong_email) ) }, "row_warnings": { errors.UNKNOWN_USER_WARNING.format( line=3, email=wrong_email ), errors.OWNER_MISSING.format( line=3, column_name="Assignees" ), } } } self._check_csv_response(response, expected_errors) # checks person profile restrictions self.assert_profiles_restrictions()
def test_import_archived_assessment(self, is_archived, value, ignored, updated, row_errors): """Test archived assessment import procedure""" with factories.single_commit(): audit = factories.AuditFactory(archived=is_archived) assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory(source=audit, destination=assessment) resp = self.import_data( OrderedDict([("object_type", "Assessment"), ("Code*", assessment.slug), ("archived", value), ("description", "archived assessment description")])) self.assertEqual([{ u'ignored': ignored, u'updated': updated, u'block_errors': [], u'name': u'Assessment', u'created': 0, u'deleted': 0, u'deprecated': 0, u'row_warnings': [], u'rows': 1, u'block_warnings': [], u'row_errors': row_errors }], resp)
def test_evidence_postfix_one_control(self): """Test evidence postfix for assessment with one control.""" with factories.single_commit(): audit = factories.AuditFactory() control = factories.ControlFactory() snapshot = self._create_snapshots(audit, [control])[0] assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory(source=assessment, destination=snapshot) evidence = factories.EvidenceFactory(title='Simple title', kind=all_models.Evidence.FILE, link='some link', parent_obj={ 'id': assessment.id, 'type': 'Assessment' }) expected = '_ggrc_assessment-{}_control-{}'.format( assessment.id, control.id) # pylint: disable=protected-access result = evidence._build_file_name_postfix(assessment) self.assertEqual(expected, result)
def test_export_assesments_with_map_control_mirror_relation(self): """Test export assesment with related control instance relation assessment -> snapshot """ with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory(source=audit, destination=assessment) control = factories.ControlFactory() revision = all_models.Revision.query.filter( all_models.Revision.resource_id == control.id, all_models.Revision.resource_type == control.__class__.__name__).order_by( all_models.Revision.id.desc()).first() snapshot = factories.SnapshotFactory( parent=audit, child_id=control.id, child_type=control.__class__.__name__, revision_id=revision.id) db.session.commit() factories.RelationshipFactory(destination=snapshot, source=assessment) self.assertColumnExportedValue(control.slug, assessment, "map:control versions")
def test_create_evidence_gdrive_type(self): """Test create evidence.FILE via POST""" with factories.single_commit(): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) evidence = factories.EvidenceFactory( title='Simple title', kind=all_models.Evidence.FILE, description='mega description', source_gdrive_id='gdrive_file_id', parent_obj={ 'id': assessment.id, 'type': 'Assessment' }) result = all_models.Evidence.query.filter( all_models.Evidence.id == evidence.id).one() self.assertEqual(result.title, COPIED_TITLE) self.assertEqual(result.kind, all_models.Evidence.FILE) self.assertFalse(result.archived) self.assertEqual(result.link, COPIED_LINK) self.assertEqual(result.description, 'mega description') self.assertEqual(result.source_gdrive_id, 'gdrive_file_id')
def test_changelog_access(self, link, revision_count): """Test accessing changelog under GC user who is assigned to object""" with factories.single_commit(): audit = factories.AuditFactory() asmnt = factories.AssessmentFactory(audit=audit) asmnt_id = asmnt.id factories.RelationshipFactory(source=audit, destination=asmnt) verifier_role = all_models.AccessControlRole.query.filter_by( object_type="Assessment", name="Verifiers", ).first() factories.AccessControlListFactory( person=self.users["creator"], ac_role=verifier_role, object=asmnt, ) self.api.set_user(self.users["creator"]) response = self.api.client.get(link.format("Assessment", asmnt_id)) self.assert200(response) self.assertEqual( len( response.json.get("revisions_collection", {}).get("revisions")), revision_count)
def test_snapshot_automapping(self): """Test automapping after Snapshot to Audit mapping""" with factories.single_commit(): program = factories.ProgramFactory() program_id = program.id parent_program = factories.ProgramFactory() parent_program_id = parent_program.id factories.RelationshipFactory(source=parent_program, destination=program) audit = factories.AuditFactory(program=program) standard = factories.StandardFactory() requirement = factories.RequirementFactory() factories.RelationshipFactory(source=standard, destination=requirement) self.gen.generate_relationship(audit, standard) program = all_models.Program.query.get(program_id) program_related = program.related_objects() parent_program = all_models.Program.query.get(parent_program_id) parent_program_related = parent_program.related_objects() self.assertEqual(len(program_related), 3) self.assertEqual(len(parent_program_related), 3) self.assertEqual({o.type for o in parent_program_related}, {"Program", "Standard", "Requirement"})