def get_task_post_dict(task_group, people_roles, start_date, end_date): """Get TaskGroupTask JSON representation for POST API call. Args: task_group: TaskGroup instance which TaskGroupTask should belong to. people_roles: Mapping like {'ACR name': Person instance} start_date: String date representation. end_date: String date representation. Returns: TaskGroupTask object dict representation for using in POST request. """ access_control_list = [] for acr_name, person in people_roles.iteritems(): access_control_list.append( _get_acl_subdict(acr_name, person, all_models.TaskGroupTask) ) return { "task_group_task": { "response_options": [], "start_date": start_date, "end_date": end_date, "access_control_list": access_control_list, "custom_attributes": {}, "task_group": utils.create_stub(task_group), "context": utils.create_stub(task_group.context), "modal_title": "Create New Task", "title": factories.random_str(prefix="tgt_"), "task_type": "text", "description": factories.random_str(length=64), "slug": "" } }
def test_import_labels(self): """Test import of labels""" label_mapped = factories.LabelFactory( name=factories.random_str(prefix='label '), object_type='Assessment') label_unmapped = factories.LabelFactory( name=factories.random_str(prefix='label '), object_type='Assessment') factories.ObjectLabelFactory(labeled_object=self.assessment, label=label_mapped) response = self.import_data(collections.OrderedDict([ ('object_type', 'Assessment'), ('Code*', self.assessment.slug), ('labels', "newbie,{},{}".format(label_mapped.name, label_unmapped.name)) ])) self._check_csv_response(response, {}) labels_count = db.session.query(all_models.Label).count() self.assertEqual(labels_count, 3) assessment = all_models.Assessment.query.get(self.assessment.id) self.assertEqual(len(assessment.labels), 3) response = self.import_data(collections.OrderedDict([ ('object_type', 'Assessment'), ('Code*', self.assessment.slug), ('labels', "") ])) self._check_csv_response(response, {}) labels_count = db.session.query(all_models.Label).count() self.assertEqual(labels_count, 3) assessment = all_models.Assessment.query.get(self.assessment.id) self.assertEqual(len(assessment.labels), 0)
def test_import_labels(self): """Test import of labels""" label_mapped = factories.LabelFactory( name=factories.random_str(prefix='label '), object_type='Assessment') label_unmapped = factories.LabelFactory( name=factories.random_str(prefix='label '), object_type='Assessment') factories.ObjectLabelFactory(labeled_object=self.assessment, label=label_mapped) response = self.import_data( collections.OrderedDict([ ('object_type', 'Assessment'), ('Code*', self.assessment.slug), ('labels', "newbie,{},{}".format(label_mapped.name, label_unmapped.name)) ])) self._check_csv_response(response, {}) labels_count = db.session.query(all_models.Label).count() self.assertEqual(labels_count, 3) assessment = all_models.Assessment.query.get(self.assessment.id) self.assertEqual(len(assessment.labels), 3) response = self.import_data( collections.OrderedDict([('object_type', 'Assessment'), ('Code*', self.assessment.slug), ('labels', "")])) self._check_csv_response(response, {}) labels_count = db.session.query(all_models.Label).count() self.assertEqual(labels_count, 3) assessment = all_models.Assessment.query.get(self.assessment.id) self.assertEqual(len(assessment.labels), 0)
def test_map_label(self): """Test labels mapping.""" # map by id label = factories.LabelFactory(name=factories.random_str(prefix='label'), object_type='Assessment') response = self.api.put(self.assessment, {"labels": [{"id": label.id}]}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) # map by name label = factories.LabelFactory(name=factories.random_str(prefix='label'), object_type='Assessment') response = self.api.put(self.assessment, {"labels": self._get_labels_dict([label.name])}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) # map already mapped label response = self.api.put(self.assessment, {"labels": [{"id": label.id}]}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) response = self.api.put(self.assessment, {"labels": self._get_labels_dict([label.name])}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name])
def _post_control(self, acr_id, person_id, assertion, collection=False): """Helper function for posting a control""" title = factories.random_str(prefix="Control - ") control = { "control": { "title": title, "type": "Control", "context": None, "access_control_list": [acl_helper.get_acl_json(acr_id, person_id)], "assertions": '["{}"]'.format(assertion), "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", }, } with self.api.as_external(): response = self.api.post(all_models.Control, [control] if collection else control) self.assertTrue( response.status_code == 200 or response.status_code == 201, "Control not created successfully {}".format(response.status)) if collection: return response.json[0][1] return response.json
def create_and_map_document(self): """Create and map document object to parent.""" admin_acr_id = all_models.AccessControlRole.query.filter_by( name="Admin", object_type="Document", ).one().id _, document = self.objgen.generate_object( all_models.Document, { "link": factories.random_str(), "title": factories.random_str(), "context": None, "access_control_list": [ { "ac_role_id": admin_acr_id, "person": { "id": self.user_id, "type": "Person", } } ], } ) parent = db.session.query(self.parent.__class__).get(self.parent_id) return self.objgen.generate_relationship( source=document, destination=parent )[0]
def get_task_post_dict(task_group, people_roles, start_date, end_date): """Get TaskGroupTask JSON representation for POST API call. Args: task_group: TaskGroup instance which TaskGroupTask should belong to. people_roles: Mapping like {'ACR name': Person instance} start_date: String date representation. end_date: String date representation. Returns: TaskGroupTask object dict representation for using in POST request. """ response = { "task_group_task": { "response_options": [], "start_date": start_date, "end_date": end_date, "access_control_list": [], "custom_attributes": {}, "task_group": utils.create_stub(task_group), "context": utils.create_stub(task_group.context), "modal_title": "Create New Task", "title": factories.random_str(prefix="tgt_"), "task_type": "text", "description": factories.random_str(length=64), "slug": "" } } for acr_name, person in people_roles.iteritems(): response["task_group_task"]["access_control_list"].append( _get_acl_subdict(acr_name, person, all_models.TaskGroupTask) ) return response
def create_and_map_document(self): """Create and map document object to parent.""" admin_acr_id = all_models.AccessControlRole.query.filter_by( name="Admin", object_type="Document", ).one().id _, document = self.objgen.generate_object( all_models.Document, { "link": factories.random_str(), "title": factories.random_str(), "context": None, "access_control_list": [ { "ac_role_id": admin_acr_id, "person": { "id": self.user_id, "type": "Person", } } ], } ) parent = db.session.query(self.parent.__class__).get(self.parent_id) return self.objgen.generate_relationship( source=document, destination=parent )[0]
def test_map_label(self): """Test labels mapping.""" # map by id label = factories.LabelFactory(name=factories.random_str(prefix='label'), object_type='Assessment') response = self.api.put(self.assessment, {"labels": [{"id": label.id}]}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) # map by name label = factories.LabelFactory(name=factories.random_str(prefix='label'), object_type='Assessment') response = self.api.put(self.assessment, {"labels": self._get_labels_dict([label.name])}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) # map already mapped label response = self.api.put(self.assessment, {"labels": [{"id": label.id}]}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name]) response = self.api.put(self.assessment, {"labels": self._get_labels_dict([label.name])}) self.assert200(response) names = self._get_label_names(response, "assessment") self.assertItemsEqual(names, [label.name])
def generate_minimal_control_body(): """Generate minimal control body""" return { "title": factories.random_str(), "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "context": None, "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", }
def generate_minimal_control_body(): """Generate minimal control body""" return { "title": factories.random_str(), "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "context": None, "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", }
def test_post_modifier(self, model): """Test modifier of models when working as external user.""" model_plural = model._inflector.table_plural model_singular = model._inflector.table_singular model_data = { "title": "{}1".format(model_singular), "context": 0, } if model_plural == "risks": model_data["risk_type"] = "some text" model_data["external_id"] = factories.SynchronizableExternalId.next() model_data["external_slug"] = factories.random_str() model_data["review_status"] = all_models.Review.STATES.UNREVIEWED model_data["review_status_display_name"] = "some status" if model_plural == "controls": model_data["assertions"] = '["test assertion"]' model_data["external_id"] = factories.SynchronizableExternalId.next() model_data["external_slug"] = factories.random_str() model_data["review_status"] = all_models.Review.STATES.UNREVIEWED model_data["review_status_display_name"] = "some status" if model_plural == "issues": model_data["due_date"] = "10/10/2019" response = self._post( "api/{}".format(model_plural), data=json.dumps({ model_singular: model_data }), headers=self.headers) self.assertEqual(response.status_code, 201) ext_person = all_models.Person.query.filter_by( email="*****@*****.**" ).first() ext_person_id = ext_person.id # check model modifier model_json = response.json[model_singular] self.assertEqual(model_json['modified_by']['id'], ext_person_id) # check model revision modifier model_revision = all_models.Revision.query.filter( all_models.Revision.resource_type == model.__name__).order_by( all_models.Revision.id.desc()).first() self.assertEqual(model_revision.modified_by_id, ext_person_id) # check model event modifier event = all_models.Event.query.filter( all_models.Event.resource_type == model.__name__).order_by( all_models.Event.id.desc()).first() self.assertEqual(event.modified_by_id, ext_person_id)
def test_create_comments(self): """Test external comments creation for control.""" response = self.api.post( all_models.Control, { "control": { "id": 123, "title": "Control title", "context": None, "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "assertions": '["test assertion"]', "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", }, }) self.assertEqual(response.status_code, 201) response = self.api.post( all_models.ExternalComment, { "external_comment": { "id": 1, "external_id": 1, "external_slug": factories.random_str(), "description": "test comment", "context": None } }) self.assertEqual(response.status_code, 201) comments = db.session.query( all_models.ExternalComment.description).all() self.assertEqual(comments, [("test comment", )]) response = self.api.post( all_models.Relationship, { "relationship": { "source": { "id": 123, "type": "Control" }, "destination": { "id": 1, "type": "ExternalComment" }, "context": None, "is_external": True }, }) self.assertEqual(response.status_code, 201) rels = all_models.Relationship.query.filter_by( source_type="Control", source_id=123, destination_type="ExternalComment", destination_id=1) self.assertEqual(rels.count(), 1)
def setUp(self): with ggrc_factories.single_commit(): self.user_emails = [ ggrc_factories.PersonFactory().email for _ in xrange(8) ] self.wf_slug = ggrc_factories.random_str(chars=string.ascii_letters) self.tg_slug = ggrc_factories.random_str(chars=string.ascii_letters) self.wf_import_params = collections.OrderedDict([ ("object_type", "Workflow"), ("code", self.wf_slug), ("title", "SomeTitle"), ("Need Verification", 'True') ])
def setUp(self): with ggrc_factories.single_commit(): self.user_emails = [ ggrc_factories.PersonFactory().email for _ in xrange(8)] self.wf_slug = ggrc_factories.random_str(chars=string.ascii_letters) self.tg_slug = ggrc_factories.random_str(chars=string.ascii_letters) self.wf_import_params = collections.OrderedDict([ ("object_type", "Workflow"), ("code", self.wf_slug), ("title", "SomeTitle"), ("Need Verification", 'True') ])
def create_test_cases(self): def person_dict(person_id): return { "href": "/api/people/%d" % person_id, "id": person_id, "type": "Person" } self.quarterly_wf_forced = { "title": "quarterly wf forced notifications", "notify_on_change": True, "description": "", "owners": [person_dict(self.user.id)], "frequency": "quarterly", "task_groups": [{ "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [{ "contact": person_dict(self.user.id), "description": factories.random_str(100), "relative_start_day": 5, "relative_start_month": 2, "relative_end_day": 25, "relative_end_month": 2, }, ], }, ] } self.quarterly_wf = { "title": "quarterly wf 1", "description": "", "owners": [person_dict(self.user.id)], "frequency": "quarterly", "task_groups": [{ "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [{ "contact": person_dict(self.user.id), "description": factories.random_str(100), "relative_start_day": 5, "relative_start_month": 2, "relative_end_day": 25, "relative_end_month": 2, }, ], }, ] }
def map_evidence(self): """Map new evidence to assessment.""" assessment = all_models.Assessment.query.get(self.assessment_id) return self.api.put(assessment, { "actions": { "add_related": [{ "id": None, "type": "Evidence", "kind": "URL", "title": factories.random_str(), "link": factories.random_str(), }] } })
def map_evidence(self): """Map new evidence to assessment.""" assessment = all_models.Assessment.query.get(self.assessment_id) return self.api.put( assessment, { "actions": { "add_related": [{ "id": None, "type": "Evidence", "kind": "URL", "title": factories.random_str(), "link": factories.random_str(), }] } })
def create_test_cases(self): def person_dict(person_id): return { "href": "/api/people/%d" % person_id, "id": person_id, "type": "Person" } self.quarterly_wf = { "title": "quarterly wf forced notifications", "notify_on_change": True, "description": "", "owners": [person_dict(self.user.id)], "frequency": "quarterly", "task_groups": [{ "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [{ "contact": person_dict(self.user.id), "description": factories.random_str(100), "relative_start_day": 5, "relative_start_month": 2, "relative_end_day": 25, "relative_end_month": 2, }, ], }, ] } self.monthly = { "title": "monthly", "notify_on_change": True, "description": "", "owners": [person_dict(self.user.id)], "frequency": "monthly", "task_groups": [{ "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [{ "contact": person_dict(self.user.id), "description": factories.random_str(100), "relative_start_day": 14, "relative_end_day": 25, }, ], }, ] }
def generate_cycle(self, workflow=None): """Generate Cycle over api.""" if not workflow: _, workflow = self.generate_workflow() workflow = self._session_add(workflow) # this should be nicer obj_name = "cycle" obj_dict = { obj_name: { "title": factories.random_str(prefix="cycle - "), "workflow": { "id": workflow.id, "type": workflow.__class__.__name__, "href": "/api/workflows/%d" % workflow.id }, "context": { "id": workflow.context.id, "type": workflow.context.__class__.__name__, "href": "/api/workflows/%d" % workflow.context.id }, "autogenerate": "true" } } return self.generate(Cycle, obj_name, obj_dict)
def test_option_fields_export(self, field, alias): """Test export several controls with option fields.""" with factories.single_commit(): expected_values = [] for _ in range(3): obj = factories.ControlFactory() field_val = factories.random_str(prefix=field).title() setattr(obj, field, field_val) expected_values.append(field_val) data = [{ "object_name": "Control", "filters": { "expression": { "left": field, "op": { "name": "~" }, "right": field, } }, "fields": "all", }] response = self.export_csv(data) self.assert200(response) self.assertIn(alias, response.data) exported_values = helpers.parse_export_data(response.data) self.assertEqual(exported_values[alias], expected_values)
def generate_object(self, obj_class, data=None, add_fields=True): """Generate an object of `obj_class` with fields from `data`. This generator is used for creating objects with data. By default it will add the first user in the DB as the object owner and it will create a random title. Args: obj_class: Model that we want to generate. add_fields: Flag for adding owners and title default field values. If these are present in the data, default values will be overridden. data: Dict containing generation data for the object. Returns: Tuple containing server response and the generated object. """ # pylint: disable=protected-access if data is None: data = {} obj_name = obj_class._inflector.table_singular obj = obj_class() obj_dict = self.obj_to_dict(obj, obj_name) if add_fields: obj_dict[obj_name].update({ "owners": [self.create_stub(models.Person.query.first())], "title": factories.random_str(), }) obj_dict[obj_name].update(data) return self.generate(obj_class, obj_name, obj_dict)
def create_test_cases(self): def person_dict(person_id): return { "href": "/api/people/%d" % person_id, "id": person_id, "type": "Person" } self.quarterly_wf_1 = { "title": "quarterly wf 1", "notify_on_change": True, "description": "", "owners": [person_dict(self.user.id)], "unit": "month", "repeat_every": 3, "task_groups": [{ "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [{ "contact": person_dict(self.user.id), "description": factories.random_str(100), }, ], }, ] }
def test_autogen_verification_flag(self, flag): """Check is_verification_needed flag for activate WF action.""" with factories.single_commit(): workflow = wf_factories.WorkflowFactory( is_verification_needed=flag) group = wf_factories.TaskGroupFactory(workflow=workflow) wf_factories.TaskGroupTaskFactory(task_group=group) data = [{ "cycle": { "autogenerate": True, "isOverdue": False, "title": factories.random_str(prefix='cycle - '), "workflow": { "id": workflow.id, "type": "Workflow", }, "context": { "id": workflow.context_id, "type": "Context", }, } }] resp = self.api.send_request(self.api.client.post, api_link="/api/cycles", data=data) cycle_id = resp.json[0][1]["cycle"]["id"] self.assertEqual( flag, all_models.Cycle.query.get(cycle_id).is_verification_needed)
def update_mapped(self): """Update control mapped to Program.""" program = all_models.Program.query.get(self.program_id) with factories.single_commit(): control = factories.ControlFactory() factories.RelationshipFactory(source=control, destination=program) return self.api.put(control, {"title": factories.random_str()})
def test_autogen_verification_flag(self, flag): """Check is_verification_needed flag for activate WF action.""" with factories.single_commit(): workflow = wf_factories.WorkflowFactory(is_verification_needed=flag) group = wf_factories.TaskGroupFactory(workflow=workflow) wf_factories.TaskGroupTaskFactory(task_group=group) data = [{ "cycle": { "autogenerate": True, "isOverdue": False, "title": factories.random_str(prefix='cycle - '), "workflow": { "id": workflow.id, "type": "Workflow", }, "context": { "id": workflow.context_id, "type": "Context", }, } }] resp = self.api.send_request( self.api.client.post, api_link="/api/cycles", data=data) cycle_id = resp.json[0][1]["cycle"]["id"] self.assertEqual( flag, all_models.Cycle.query.get(cycle_id).is_verification_needed)
def _(self, obj_class, data=None, add_fields=True, with_background_tasks=False): """Handle generation of `Control` objects.""" data = data if data is not None else {} # pylint: disable=protected-access obj_name = models.Control._inflector.table_singular # pylint: enable=protected-access obj_dict = self.obj_to_dict(models.Control(), obj_name) defaults = { obj_name: { "title": factories.random_str(), "context": None, "recipients": "Admin,Control Operators,Control Owners", "send_by_default": 0, "assertions": '["test assertion"]', "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", } } obj_dict[obj_name].update(defaults[obj_name]) if issubclass(obj_class, Synchronizable): obj_dict[obj_name].update(self._get_synchronizable_obj_dict()) obj_dict[obj_name].update(data[obj_name] if obj_name in data else data) return self.generate(models.Control, obj_name=obj_name, data=obj_dict, with_background_tasks=with_background_tasks)
def _get_synchronizable_obj_dict(): """Return dict with fileds which extend Synchronizable object""" return { 'external_id': factories.SynchronizableExternalId.next(), 'external_slug': factories.random_str(), }
def test_external_comment_acl(self): """Test automatic assigning current user to ExternalComment Admin.""" response = self.api.post(all_models.ExternalComment, { "external_comment": { "id": 1, "external_id": 1, "external_slug": factories.random_str(), "description": "test comment", "context": None, "access_control_list": { "Admin": [ { "email": "*****@*****.**", "name": "user1", }, ], }, } }) self.assertEqual(response.status_code, 201) comment = all_models.ExternalComment.query.get(1) comment_admin = comment.get_persons_for_rolename("Admin") self.assertEqual( [i.email for i in comment_admin], ["*****@*****.**"] )
def update(self): """Update title of existing Cycle Task Entry object.""" cycle_task_entry = all_models.CycleTaskEntry.query.first() return self.api.put( cycle_task_entry, {"description": factories.random_str()} )
def test_asmnt_procedure_export(self, obj_factory): """Test export of Assessment Procedure.""" with factories.single_commit(): objects = [ obj_factory(test_plan=random_str(chars=string.ascii_letters)) for _ in range(10) ] obj_dicts = [{ "Code*": obj.slug, "Assessment Procedure": obj.test_plan if obj.test_plan else "" } for obj in objects] model_name = objects[0].type # All objects has same type as first search_request = [{ "object_name": model_name, "filters": { "expression": {}, "order_by": { "name": "id" } }, "fields": ["slug", "test_plan"], }] exported_data = self.export_parsed_csv(search_request)[model_name] self.assertEqual(exported_data, obj_dicts)
def generate_task_group(self, workflow=None, data=None): """Generates task group over api.""" if data is None: data = {} if not workflow: _, workflow = self.generate_workflow() data = copy.deepcopy(data) tgts = data.pop("task_group_tasks", []) tgos = data.pop("task_group_objects", []) obj_name = "task_group" workflow = self._session_add(workflow) wf_admin_id = Person.query.first().id task_group = TaskGroup( title="tg " + factories.random_str(), workflow_id=workflow.id, context_id=workflow.context.id, contact_id=wf_admin_id ) obj_dict = self.obj_to_dict(task_group, obj_name) obj_dict[obj_name].update(data) response, task_group = self.generate(TaskGroup, obj_name, obj_dict) for tgt in tgts: self.generate_task_group_task(task_group, tgt) for tgo in tgos: self.generate_task_group_object(task_group, tgo) return response, task_group
def update(self): """Update title of existing Cycle Task Entry object.""" cycle_task_entry = all_models.CycleTaskEntry.query.first() return self.api.put( cycle_task_entry, {"description": factories.random_str()} )
def test_query_by_label(self): """Test query by labels""" assessments = [factories.AssessmentFactory() for _ in range(2)] assessment_ids = [asmt.id for asmt in assessments] label_names = [factories.random_str(prefix='label{} '.format(i)) for i in range(2)] labels = [factories.LabelFactory(name=name, object_type='Assessment') for name in label_names] factories.ObjectLabelFactory(labeled_object=assessments[0], label=labels[0]) factories.ObjectLabelFactory(labeled_object=assessments[0], label=labels[1]) factories.ObjectLabelFactory(labeled_object=assessments[1], label=labels[1]) query_names = [labels[0].name.lower(), labels[1].name.upper()] queries = [self._make_query_dict('Assessment', expression=( 'Label', '=', name )) for name in query_names] by_label = self._get_first_result_set(queries[0], 'Assessment') self.assertEqual(by_label['count'], 1) self.assertEqual(by_label['values'][0]['id'], assessment_ids[0]) by_label = self._get_first_result_set(queries[1], 'Assessment') self.assertEqual(by_label['count'], 2) self.assertSetEqual({asmt['id'] for asmt in by_label['values']}, set(assessment_ids))
def create_test_cases(self): def person_dict(person_id): return { "href": "/api/people/%d" % person_id, "id": person_id, "type": "Person" } self.quarterly_wf_1 = { "title": "quarterly wf 1", "description": "", # admin will be current user with id == 1 "unit": "month", "repeat_every": 3, "notify_on_change": True, "task_groups": [{ "title": "tg_1", "contact": person_dict(self.assignee.id), "task_group_tasks": [{ "contact": person_dict(self.assignee.id), "description": factories.random_str(100), }, ], }, ] } self.all_workflows = [ self.quarterly_wf_1, ]
def _create_cycle_structure(self): """Create cycle structure. It will create workflow, cycle, group and 3 tasks in that group. Retruns tuple: workflow, cycle, group and list of tasks. """ wf_slug = "WF-SLUG-{}".format(factories.random_str( length=6, chars=string.ascii_letters)) with factories.single_commit(): workflow = wf_factories.WorkflowFactory(slug=wf_slug) task_group = wf_factories.TaskGroupFactory(workflow=workflow) for ind in xrange(3): wf_factories.TaskGroupTaskFactory( task_group=task_group, title='task{}'.format(ind), start_date=datetime.datetime.now(), end_date=datetime.datetime.now() + datetime.timedelta(7) ) data = workflow_api.get_cycle_post_dict(workflow) self.api.post(all_models.Cycle, data) workflow = all_models.Workflow.query.filter_by(slug=wf_slug).one() cycle = all_models.Cycle.query.filter_by(workflow_id=workflow.id).one() group = all_models.CycleTaskGroup.query.filter_by(cycle_id=cycle.id).one() tasks = all_models.CycleTaskGroupObjectTask.query.filter_by( cycle_id=cycle.id).all() return workflow, cycle, group, tasks
def _import_workflow(self, import_data, expected_resp_action): """Import Workflow with ACL parameters. After performing import, check that its response is equal expected one. Args: import_data: Dictionary contains 2 lists. 'admins': Test people data indexes who should get Admin role. 'members': Test people data indexes who should get Member role. expected_resp_action: Action which was performed on imported item. """ wf_title = ggrc_factories.random_str(chars=string.ascii_letters) wf_import_params = collections.OrderedDict([ ("object_type", "Workflow"), ("title", wf_title), ("Need Verification", 'True') ]) if import_data['members']: import_members = '\n'.join( self.user_emails[idx] for idx in import_data['members']) wf_import_params['workflow member'] = import_members if import_data['admins']: import_admins = '\n'.join( self.user_emails[idx] for idx in import_data['admins']) wf_import_params['admin'] = import_admins wf_import_params['code'] = self.wf_slug response = self.import_data(wf_import_params) if expected_resp_action != 'ignored': self._check_csv_response(response, {}) if not self.wf_slug and expected_resp_action != 'ignored': workflow = Workflow.query.filter(Workflow.title == wf_title).one() self.wf_slug = workflow.slug self.assertEqual(response[0][expected_resp_action], 1)
def generate_object(self, obj_class, data=None, add_fields=True): """Generate an object of `obj_class` with fields from `data`. This generator is used for creating objects with data. By default it will add the first user in the DB as the object owner and it will create a random title. Args: obj_class: Model that we want to generate. add_fields: Flag for adding owners and title default field values. If these are present in the data, default values will be overridden. data: Dict containing generation data for the object. Returns: Tuple containing server response and the generated object. """ # pylint: disable=protected-access if data is None: data = {} obj_name = obj_class._inflector.table_singular obj = obj_class() obj_dict = self.obj_to_dict(obj, obj_name) if add_fields: obj_dict[obj_name].update({ "owners": [self.create_stub(models.Person.query.first())], "title": factories.random_str(), }) obj_dict[obj_name].update(data) return self.generate(obj_class, obj_name, obj_dict)
def test_old_option_revision(self, field): """Test if old revision content is correct for Control '{0}' field.""" field_value = factories.random_str() control = factories.ControlFactory(**{field: field_value}) control_revision = all_models.Revision.query.filter_by( resource_type=control.type, resource_id=control.id ).one() revision_content = control_revision.content revision_content[field] = { "id": "123", "title": "some title", "type": "Option", } control_revision.content = revision_content db.session.commit() response = self.api.client.get( "/api/revisions" "?resource_type={}&resource_id={}".format(control.type, control.id) ) self.assert200(response) revisions = response.json["revisions_collection"]["revisions"] self.assertEqual(len(revisions), 1) self.assertEqual(revisions[0].get("content", {}).get(field), "some title")
def read_comments(self): """Read comments mapped to document""" document = all_models.Document.query.get(self.document_id) with factories.single_commit(): comment = factories.CommentFactory(description=factories.random_str()) factories.RelationshipFactory(source=document, destination=comment) query_request_data = [{ "fields": [], "filters": { "expression": { "object_name": "Document", "op": { "name": "relevant" }, "ids": [document.id] } }, "object_name": "Comment", }] response = self.api.send_request( self.api.client.post, data=query_request_data, api_link="/query" ) return response
def generate_task_group_task(self, task_group=None, data={}): if not task_group: _, task_group = self.generate_task_group() task_group = self._session_add(task_group) default_start = self.random_date() default_end = self.random_date(default_start, date.today()) day_range = 5 if task_group.workflow.frequency == "weekly" else 31 obj_name = "task_group_task" tgt = TaskGroupTask( task_group_id=task_group.id, context_id=task_group.context.id, title="tgt " + factories.random_str(), start_date=default_start, end_date=default_end, relative_start_day=random.randrange(1, day_range), relative_start_month=random.randrange(1, 12), relative_end_day=random.randrange(1, day_range), relative_end_month=random.randrange(1, 12), contact_id=1 ) obj_dict = self.obj_to_dict(tgt, obj_name) obj_dict[obj_name].update(data) return self.generate(TaskGroupTask, obj_name, obj_dict)
def _(self, obj_class, data=None, add_fields=True, with_background_tasks=False): """Handle generation of `Control` objects.""" data = data if data is not None else {} # pylint: disable=protected-access obj_name = models.Control._inflector.table_singular # pylint: enable=protected-access obj_dict = self.obj_to_dict(models.Control(), obj_name) defaults = { obj_name: { "title": factories.random_str(), "context": None, "recipients": "Admin,Control Operators,Control Owners", "send_by_default": 0, "assertions": '["test assertion"]', "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", } } obj_dict[obj_name].update(defaults[obj_name]) if issubclass(obj_class, Synchronizable): obj_dict[obj_name].update(self._get_synchronizable_obj_dict()) obj_dict[obj_name].update(data[obj_name] if obj_name in data else data) return self.generate(models.Control, obj_name=obj_name, data=obj_dict, with_background_tasks=with_background_tasks)
def generate_task_group(self, workflow=None, data={}): if not workflow: _, workflow = self.generate_workflow() data = copy.deepcopy(data) tgts = data.pop("task_group_tasks", []) tgos = data.pop("task_group_objects", []) obj_name = "task_group" workflow = self._session_add(workflow) tg = TaskGroup( title="tg " + factories.random_str(), workflow_id=workflow.id, context_id=workflow.context.id, contact_id=1 ) obj_dict = self.obj_to_dict(tg, obj_name) obj_dict[obj_name].update(data) response, task_group = self.generate(TaskGroup, obj_name, obj_dict) for tgt in tgts: self.generate_task_group_task(task_group, tgt) for tgo in tgos: self.generate_task_group_object(task_group, tgo) return response, task_group
def _get_synchronizable_obj_dict(): """Return dict with fileds which extend Synchronizable object""" return { 'external_id': factories.SynchronizableExternalId.next(), 'external_slug': factories.random_str(), }
def _post_control(self, acr_id, person_id, assertion_id, collection=False): """Helper function for posting a control""" title = factories.random_str(prefix="Control - ") control = { "control": { "title": title, "type": "Control", "context": None, "access_control_list": [acl_helper.get_acl_json(acr_id, person_id)], "assertions": [{ "id": assertion_id }] }, } response = self.api.post(all_models.Control, [control] if collection else control) self.assertTrue( response.status_code == 200 or response.status_code == 201, "Control not created successfully {}".format(response.status)) if collection: return response.json[0][1] return response.json
def read_comments(self): """Read comments mapped to evidence""" evidence = all_models.Evidence.query.get(self.evidence_id) with factories.single_commit(): comment = factories.CommentFactory( description=factories.random_str()) factories.RelationshipFactory(source=evidence, destination=comment) query_request_data = [{ "fields": [], "filters": { "expression": { "object_name": "Evidence", "op": { "name": "relevant" }, "ids": [evidence.id] } }, "object_name": "Comment", }] response = self.api.send_request(self.api.client.post, data=query_request_data, api_link="/query") return response
def test_category_fields_export(self, field, alias): """Test export several controls with category fields.""" with factories.single_commit(): expected_values = [] for _ in range(3): field_vals = [ factories.random_str(prefix=field) for _ in range(3) ] factories.ControlFactory(**{field: json.dumps(field_vals)}) expected_values.append("\n".join(field_vals)) data = [{ "object_name": "Control", "filters": { "expression": { "left": field, "op": { "name": "~" }, "right": field, } }, "fields": "all", }] response = self.export_csv(data) self.assert200(response) self.assertIn(alias, response.data) exported_values = helpers.parse_export_data(response.data) self.assertEqual(exported_values[alias], expected_values)
def test_external_comment_acl(self): """Test automatic assigning current user to ExternalComment Admin.""" response = self.api.post( all_models.ExternalComment, { "external_comment": { "id": 1, "external_id": 1, "external_slug": factories.random_str(), "description": "test comment", "context": None, "access_control_list": { "Admin": [ { "email": "*****@*****.**", "name": "user1", }, ], }, } }) self.assertEqual(response.status_code, 201) comment = all_models.ExternalComment.query.get(1) comment_admin = comment.get_persons_for_rolename("Admin") self.assertEqual([i.email for i in comment_admin], ["*****@*****.**"])
def create_test_cases(self): def person_dict(person_id): return { "href": "/api/people/%d" % person_id, "id": person_id, "type": "Person" } self.quarterly_wf_1 = { "title": "quarterly wf 1", "notify_on_change": True, "description": "", "owners": [person_dict(self.user.id)], "unit": "month", "repeat_every": 3, "task_groups": [ { "title": "tg_1", "contact": person_dict(self.user.id), "task_group_tasks": [ { "contact": person_dict(self.user.id), "description": factories.random_str(100), }, ], }, ] }
def read_document_comment(self): """Read comments mapped to document""" doc_id = self._setup_document() document = all_models.Document.query.get(doc_id) with factories.single_commit(): comment = factories.CommentFactory(description=factories.random_str()) factories.RelationshipFactory(source=document, destination=comment) query_request_data = [ { "fields": [], "filters": { "expression": { "object_name": "Document", "op": { "name": "relevant" }, "ids": [document.id] } }, "object_name": "Comment", } ] response = self.api.send_request( self.api.client.post, data=query_request_data, api_link="/query" ) return response
def generate_workflow(self, data=None): """ create a workflow with dict data return: wf if it was created, or response otherwise """ if data is None: data = {} obj_name = "workflow" data = copy.deepcopy(data) tgs = data.pop("task_groups", []) wf_instance = Workflow(title="wf " + factories.random_str()) obj_dict = self.obj_to_dict(wf_instance, obj_name) wf_admin_role_id = { n: i for (i, n) in role.get_custom_roles_for(Workflow.__name__).iteritems() }['Admin'] if "access_control_list" not in data: wf_admin_id = Person.query.first().id data["access_control_list"] = [ acl_helper.get_acl_json(wf_admin_role_id, wf_admin_id)] obj_dict[obj_name].update(data) response, workflow = self.generate(Workflow, obj_name, obj_dict) for task_group in tgs: self.generate_task_group(workflow, task_group) return response, workflow
def _create_obj_dict(obj, audit_id, context_id, assessment_id=None): """Create POST dicts for various object types.""" table_singular = obj._inflector.table_singular dicts = { "issue": { "title": "Issue Title " + factories.random_str(), "context": { "id": context_id, "type": "Context" }, "audit": { "id": audit_id, "type": "Audit" } }, "assessment": { "title": "Assessment Title", "context": { "id": context_id, "type": "Context" }, "audit": { "id": audit_id, "type": "Audit" } }, "assessment_template": { "title": "Assessment Template Title", "template_object_type": "Control", "default_people": { "verifiers": "Auditors", "assignees": "Audit Lead" }, "context": { "id": context_id, "type": "Context" }, "audit": { "id": audit_id, "type": "Audit" } }, "relationship": { "context": { "id": context_id, "type": "Context" }, "source": { "id": assessment_id, "type": "Assessment" }, "destination": { "id": audit_id, "type": "Audit" } } } return { table_singular: dicts[table_singular] }
def generate_task_group_task(self, task_group=None, data=None): """Generate task group task over api.""" if data is None: data = {} if not task_group: _, task_group = self.generate_task_group() task_group = self._session_add(task_group) default_start = self.random_date() default_end = self.random_date(default_start, date.today()) obj_name = "task_group_task" cycle_task_role_id = { v: k for (k, v) in role.get_custom_roles_for("TaskGroupTask").iteritems() }['Task Assignees'] tgt = TaskGroupTask( task_group_id=task_group.id, context_id=task_group.context.id, title="tgt " + factories.random_str(), start_date=default_start, end_date=default_end, ) obj_dict = self.obj_to_dict(tgt, obj_name) if "access_control_list" not in data: wf_admin_id = Person.query.first().id data["access_control_list"] = [ acl_helper.get_acl_json(cycle_task_role_id, wf_admin_id)] obj_dict[obj_name].update(data) return self.generate(TaskGroupTask, obj_name, obj_dict)
def test_last_comment_value(self): """Test proper value in last_comment field""" with factories.single_commit(): c_task = wf_factories.CycleTaskGroupObjectTaskFactory() c_task_id = c_task.id comment_1 = factories.CommentFactory(description=factories.random_str()) comment_2 = factories.CommentFactory(description=factories.random_str()) comment_2_id = comment_2.id factories.RelationshipFactory(source=c_task, destination=comment_1) factories.RelationshipFactory(source=c_task, destination=comment_2) self.compute_attributes() comment_2 = all_models.Comment.query.get(comment_2_id) c_task = all_models.CycleTaskGroupObjectTask.query.get(c_task_id) self.assertEqual(c_task.last_comment, comment_2.description)
def test_query_by_label(self): """Test query by labels""" assessments = [factories.AssessmentFactory() for _ in range(2)] assessment_ids = [asmt.id for asmt in assessments] label_names = [ factories.random_str(prefix='label{} '.format(i)) for i in range(2) ] labels = [ factories.LabelFactory(name=name, object_type='Assessment') for name in label_names ] factories.ObjectLabelFactory(labeled_object=assessments[0], label=labels[0]) factories.ObjectLabelFactory(labeled_object=assessments[0], label=labels[1]) factories.ObjectLabelFactory(labeled_object=assessments[1], label=labels[1]) query_names = [labels[0].name.lower(), labels[1].name.upper()] queries = [ self._make_query_dict('Assessment', expression=('Label', '=', name)) for name in query_names ] by_label = self._get_first_result_set(queries[0], 'Assessment') self.assertEqual(by_label['count'], 1) self.assertEqual(by_label['values'][0]['id'], assessment_ids[0]) by_label = self._get_first_result_set(queries[1], 'Assessment') self.assertEqual(by_label['count'], 2) self.assertSetEqual({asmt['id'] for asmt in by_label['values']}, set(assessment_ids))
def prepare_control_request_body(): """Create payload for control creation.""" return { "id": 123, "title": "new_control", "context": None, "created_at": datetime(2018, 1, 1), "updated_at": datetime(2018, 1, 2), "slug": "CONTROL-01", "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "kind": "test kind", "means": "test means", "verify_frequency": "test frequency", "assertions": '["test assertion"]', "categories": '["test category"]', "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", "due_date": datetime(2018, 1, 3), "created_by": { "email": "*****@*****.**", "name": "External Creator", }, "last_submitted_at": datetime(2018, 1, 4), "last_submitted_by": { "email": "*****@*****.**", "name": "External Owner", }, "last_verified_at": datetime(2018, 1, 5), "last_verified_by": { "email": "*****@*****.**", "name": "External Compliance", } }
def _create_cycle_structure(self): """Create cycle structure. It will create workflow, cycle, group and 3 tasks in that group. Retruns tuple: workflow, cycle, group and list of tasks. """ wf_slug = "WF-SLUG-{}".format( factories.random_str(length=6, chars=string.ascii_letters)) with factories.single_commit(): workflow = wf_factories.WorkflowFactory(slug=wf_slug) task_group = wf_factories.TaskGroupFactory(workflow=workflow) for ind in xrange(3): wf_factories.TaskGroupTaskFactory( task_group=task_group, title='task{}'.format(ind), start_date=datetime.datetime.now(), end_date=datetime.datetime.now() + datetime.timedelta(7)) data = workflow_api.get_cycle_post_dict(workflow) self.api.post(all_models.Cycle, data) workflow = all_models.Workflow.query.filter_by(slug=wf_slug).one() cycle = all_models.Cycle.query.filter_by(workflow_id=workflow.id).one() group = all_models.CycleTaskGroup.query.filter_by( cycle_id=cycle.id).one() tasks = all_models.CycleTaskGroupObjectTask.query.filter_by( cycle_id=cycle.id).all() return workflow, cycle, group, tasks
def prepare_control_request_body(): """Create payload for control creation.""" return { "id": 123, "title": "new_control", "context": None, "created_at": datetime(2018, 1, 1), "updated_at": datetime(2018, 1, 2), "slug": "CONTROL-01", "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "kind": "test kind", "means": "test means", "verify_frequency": "test frequency", "assertions": '["test assertion"]', "categories": '["test category"]', "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", "due_date": datetime(2018, 1, 3), "created_by": { "email": "*****@*****.**", "name": "External Creator", }, "last_submitted_at": datetime(2018, 1, 4), "last_submitted_by": { "email": "*****@*****.**", "name": "External Owner", }, "last_verified_at": datetime(2018, 1, 5), "last_verified_by": { "email": "*****@*****.**", "name": "External Compliance", } }
def update_mapped(self): """Update project mapped to Program.""" program = all_models.Program.query.get(self.program_id) with factories.single_commit(): project = factories.ProjectFactory() factories.RelationshipFactory(source=project, destination=program) return self.api.put(project, {"title": factories.random_str()})
def test_asmnt_procedure_export(self, obj_factory): """Test export of Assessment Procedure.""" with factories.single_commit(): objects = [ obj_factory(test_plan=random_str(chars=string.ascii_letters)) for _ in range(10) ] obj_dicts = [ { "Code*": obj.slug, "Assessment Procedure": obj.test_plan if obj.test_plan else "" } for obj in objects ] model_name = objects[0].type # All objects has same type as first search_request = [{ "object_name": model_name, "filters": { "expression": {}, "order_by": {"name": "id"} }, "fields": ["slug", "test_plan"], }] exported_data = self.export_parsed_csv(search_request)[model_name] self.assertEqual(exported_data, obj_dicts)