def format_err_msg_contains(cls, left, right): """Return customized and detailed error message after assert contains comparison. """ # comparison of entities assertion_error_msg = cls.err_contains.format(left, right) # processing of entity if (isinstance(left, Entity.all_entities_classes()) and isinstance(right, Entity.all_entities_classes())): if not cls.is_entities_have_err_info(left, right): cls.set_entities_diff_info(left, right) assertion_error_msg = cls.diff_error_msg(left, right) # processing list of entities if (isinstance(left, Entity.all_entities_classes()) and isinstance(right, list) and all(isinstance(_right, Entity.all_entities_classes()) for _right in right)): assertion_error_msg = "" for _right in right: left = copy.copy(left) if not cls.is_entities_have_err_info(left, _right): cls.set_entities_diff_info(left, _right) assertion_error_msg = (assertion_error_msg + cls.diff_error_msg(left, _right)) return assertion_error_msg
def format_err_msg_contains(cls, left, right): """Return customized and detailed error message after assert contains comparison. """ # comparison of entities assertion_error_msg = cls.err_contains.format(left, right) # processing of entity if (isinstance(left, Entity.all_entities_classes()) and isinstance(right, Entity.all_entities_classes())): if not cls.is_entities_have_err_info(left, right): cls.set_entities_diff_info(left, right) assertion_error_msg = cls.diff_error_msg(left, right) # processing list of entities if (isinstance(left, Entity.all_entities_classes()) and isinstance(right, list) and all( isinstance(_right, Entity.all_entities_classes()) for _right in right)): assertion_error_msg = "" for _right in right: left = copy.copy(left) if not cls.is_entities_have_err_info(left, _right): cls.set_entities_diff_info(left, _right) assertion_error_msg = (assertion_error_msg + cls.diff_error_msg(left, _right)) return assertion_error_msg
def is_entities_have_err_info(cls, left, right): """Check if entities are instances of entities and have needed attributes and keys to make result error comparison message. """ return (isinstance(left, Entity.all_entities_classes()) and isinstance(right, Entity.all_entities_classes()) and hasattr(left, "diff_info") and hasattr(right, "diff_info") and getattr(left, "diff_info") and getattr(right, "diff_info"))
def _create_list_objs(self, entity_factory, list_scopes): """Create and return list of objects used entity factory and UI data (list of scopes UI text elements {"header": "item", ...} remapped to list of dicts {"attr": "value", ...}). Return list of created objects. """ list_factory_objs = [ entity_factory.create_empty() for _ in xrange(len(list_scopes))] list_scopes_with_upper_keys = [ StringMethods.dict_keys_to_upper_case(scope) for scope in list_scopes] list_scopes_to_convert = StringMethods.exchange_dicts_items( transform_dict=Entity.items_of_remap_keys(), dicts=list_scopes_with_upper_keys, is_keys_not_values=True) # convert and represent values in scopes for scope in list_scopes_to_convert: # convert u'None', u'No person' to None type StringMethods.update_dicts_values(scope, ["None", "No person"], None) for key, val in scope.iteritems(): if val: if key in ["mandatory", "verified"]: # convert u'false', u'true' like to Boolean scope[key] = StringMethods.get_bool_value_from_arg(val) if key in ["updated_at", "created_at"]: # UI like u'08/20/2017' to date=2017-08-20, timetz=00:00:00 datetime_val = parser.parse(val) if str(datetime_val.time()) != "00:00:00": # UI like u'08/20/2017 07:30:45 AM +03:00' to date=2017-08-20, # timetz=04:30:45+00:00 if 'tzinfo', else: # CSV like u'08-20-2017 04:30:45' to date=2017-08-20, # timetz=04:30:45+00:00 datetime_val = ( datetime_val.astimezone(tz=tz.tzutc()) if datetime_val.tzinfo else datetime_val.replace(tzinfo=tz.tzutc())) scope[key] = datetime_val if (key == "comments" and isinstance(val, list) and all(isinstance(comment, dict) for comment in val)): # extract datetime from u'(Creator) 08/20/2017 07:30:45 AM +03:00' scope[key] = [ {k: (parser.parse(re.sub(regex.TEXT_W_PARENTHESES, Symbols.BLANK, v) ).astimezone(tz=tz.tzutc()) if k == "created_at" else v) for k, v in comment.iteritems()} for comment in val] # convert multiple values to list of strings and split if need it if (key in ["owners", "assignee", "creator", "verifier"] and not isinstance(val, list)): # split Tree View values if need 'Ex1, Ex2 F' to ['Ex1', 'Ex2 F'] # Info Widget values will be represent by internal methods scope[key] = val.split(", ") # convert 'slug' from CSV for snapshoted objects u'*23eb72ac-4d9d' if (key == "slug" and (self.obj_name in objects.ALL_SNAPSHOTABLE_OBJS) and Symbols.STAR in val): scope[key] = val.replace(Symbols.STAR, Symbols.BLANK) return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=factory_obj, is_allow_none_values=False, **scope) for scope, factory_obj in zip(list_scopes_to_convert, list_factory_objs)]
def create_list_objs(self, entity_factory, list_scopes): """Create and return list of objects used entity factory and UI data (list of scopes UI text elements {"header": "item", ...} remapped to list of dicts {"attr": "value", ...}). Return list of created objects. """ list_factory_objs = [ entity_factory.create_empty() for _ in xrange(len(list_scopes)) ] list_scopes_with_upper_keys = [ string_utils.dict_keys_to_upper_case(scope) for scope in list_scopes ] list_scopes_to_convert = string_utils.exchange_dicts_items( transform_dict=Entity.items_of_remap_keys(), dicts=list_scopes_with_upper_keys, is_keys_not_values=True) # convert and represent values in scopes for scope in list_scopes_to_convert: # convert u'None', u'No person' to None type string_utils.update_dicts_values(scope, ["None", "No person"], None) for key, val in scope.iteritems(): if val: if key in ["mandatory", "verified"]: # convert u'false', u'true' like to Boolean scope[key] = string_utils.get_bool_value_from_arg(val) # convert datetime attributes' directly if key in ["updated_at", "created_at"]: scope[key] = string_utils.convert_str_to_datetime(val) # convert datetime attributes' in 'comments' if (key == "comments" and isinstance(val, list) and all( isinstance(comment, dict) for comment in val)): # u'(Creator) 07/06/2017 05:47:14 AM UTC' # to u'07/06/2017 05:47:14 AM UTC' scope[key] = [{ k: (string_utils.convert_str_to_datetime( re.sub(regex.TEXT_WITHIN_PARENTHESES, "", v)) if k == "created_at" else v) for k, v in comment.iteritems() } for comment in val] # convert multiple values to list of strings and split if need it if key in ["owners", "assessor", "creator", "verifier"]: # convert CSV like u'*****@*****.**' to u'Example User' val = val if val != url.DEFAULT_USER_EMAIL else roles.DEFAULT_USER # split multiple values if need 'Ex1, Ex2 F' to ['Ex1', 'Ex2 F'] scope[key] = val.split(", ") # convert 'slug' from CSV for snapshoted objects u'*23eb72ac-4d9d' if (key == "slug" and (self.obj_name in objects.ALL_SNAPSHOTABLE_OBJS) and "*" in val): scope[key] = val.replace("*", "") return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=factory_obj, is_allow_none_values=False, **scope) for scope, factory_obj in zip(list_scopes_to_convert, list_factory_objs) ]
def is_entities_have_err_info(cls, left, right): """Check if entities are instances of entities and have needed attributes and keys to make result error comparison message. """ return ( isinstance(left, Entity.all_entities_classes()) and isinstance(right, Entity.all_entities_classes()) and hasattr(left, "diff_info") and hasattr(right, "diff_info") and getattr(left, "diff_info") and getattr(right, "diff_info"))
def _create_list_objs(self, entity_factory, list_scopes): """Create and return list of objects used entity factory and UI data (list of scopes UI text elements {"header": "item", ...} remapped to list of dicts {"attr": "value", ...}). Return list of created objects. """ list_factory_objs = [ entity_factory.create_empty() for _ in xrange(len(list_scopes))] list_scopes_with_upper_keys = [ string_utils.dict_keys_to_upper_case(scope) for scope in list_scopes] list_scopes_to_convert = string_utils.exchange_dicts_items( transform_dict=Entity.items_of_remap_keys(), dicts=list_scopes_with_upper_keys, is_keys_not_values=True) # convert and represent values in scopes for scope in list_scopes_to_convert: # convert u'None', u'No person' to None type string_utils.update_dicts_values(scope, ["None", "No person"], None) for key, val in scope.iteritems(): if val: if key in ["mandatory", "verified"]: # convert u'false', u'true' like to Boolean scope[key] = string_utils.get_bool_value_from_arg(val) if key in ["updated_at", "created_at"]: # UI like u'08/20/2017' to date=2017-08-20, timetz=00:00:00 datetime_val = parser.parse(val) if str(datetime_val.time()) != "00:00:00": # UI like u'08/20/2017 07:30:45 AM +03:00' to date=2017-08-20, # timetz=04:30:45+00:00 if 'tzinfo', else: # CSV like u'08-20-2017 04:30:45' to date=2017-08-20, # timetz=04:30:45+00:00 datetime_val = ( datetime_val.astimezone(tz=tz.tzutc()) if datetime_val.tzinfo else datetime_val.replace(tzinfo=tz.tzutc())) scope[key] = datetime_val if (key == "comments" and isinstance(val, list) and all(isinstance(comment, dict) for comment in val)): # extract datetime from u'(Creator) 08/20/2017 07:30:45 AM +03:00' scope[key] = [ {k: (parser.parse(re.sub(regex.TEXT_WITHIN_PARENTHESES, string_utils.BLANK, v) ).astimezone(tz=tz.tzutc()) if k == "created_at" else v) for k, v in comment.iteritems()} for comment in val] # convert multiple values to list of strings and split if need it if key in ["owners", "assessor", "creator", "verifier"]: # split multiple values if need 'Ex1, Ex2 F' to ['Ex1', 'Ex2 F'] scope[key] = val.split(", ") # convert 'slug' from CSV for snapshoted objects u'*23eb72ac-4d9d' if (key == "slug" and (self.obj_name in objects.ALL_SNAPSHOTABLE_OBJS) and string_utils.STAR in val): scope[key] = val.replace(string_utils.STAR, string_utils.BLANK) return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=factory_obj, is_allow_none_values=False, **scope) for scope, factory_obj in zip(list_scopes_to_convert, list_factory_objs)]
def general_contain_assert(expected_obj, actual_objs, *exclude_attrs): """Perform general contain assert for deepcopy converted expected object and actual objects according to '*exclude_attrs' tuple of excluding attributes' names (compare objects' collections w/ attributes' values set to None). """ expected_obj_wo_excluded_attrs = Entity.extract_objs_wo_excluded_attrs( help_utils.convert_to_list(expected_obj), *exclude_attrs)[0] actual_objs_wo_excluded_attrs = Entity.extract_objs_wo_excluded_attrs( help_utils.convert_to_list(actual_objs), *exclude_attrs) assert (expected_obj_wo_excluded_attrs in actual_objs_wo_excluded_attrs), ( messages.AssertionMessages.format_err_msg_contains( expected_obj_wo_excluded_attrs, actual_objs_wo_excluded_attrs))
def general_contain_assert(expected_obj, actual_objs, *exclude_attrs): """Perform general contain assert for deepcopy converted expected object and actual objects according to '*exclude_attrs' tuple of excluding attributes' names (compare objects' collections w/ attributes' values set to None). """ expected_obj_wo_excluded_attrs = Entity.extract_objs_wo_excluded_attrs( help_utils.convert_to_list(expected_obj), *exclude_attrs)[0] actual_objs_wo_excluded_attrs = Entity.extract_objs_wo_excluded_attrs( help_utils.convert_to_list(actual_objs), *exclude_attrs) assert (expected_obj_wo_excluded_attrs in actual_objs_wo_excluded_attrs), ( messages.AssertionMessages.format_err_msg_contains( expected_obj_wo_excluded_attrs, actual_objs_wo_excluded_attrs))
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, audit=None, recipients=None, assignees=None, verified=None, verifier=None, creator=None, assignee=None, updated_at=None, objects_under_assessment=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None): """Create Assessment object. Random values will be used for title and slug. Predictable values will be used for type, status, recipients, verified, owners. """ # pylint: disable=too-many-locals asmt_entity = cls._create_random_asmt() asmt_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, audit=audit, recipients=recipients, assignees=assignees, verified=verified, verifier=verifier, creator=creator, assignee=assignee, updated_at=updated_at, objects_under_assessment=objects_under_assessment, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by) if verifier: asmt_entity.access_control_list.append( ObjectPersonsFactory.get_acl_member(roles.ASMT_VERIFIER_ID, cls.default_person)) return asmt_entity
def get_obj(self, obj): """Get and return object according to 'obj.type' and 'obj.id'.""" obj_dict = (BaseRestService.get_items_from_resp(self.client.create_object( type=self.endpoint, object_name=unicode(obj.type), filters=query.Query.expression_get_obj_by_id(obj.id))).get( "values")[0]) return Entity.convert_dict_to_obj_repr(obj_dict)
def get_obj(self, obj): """Get and return object according to 'obj.type' and 'obj.id'.""" obj_dict = (BaseRestService.get_items_from_resp(self.client.create_object( type=self.endpoint, object_name=unicode(obj.type), filters=query.Query.expression_get_obj_by_id(obj.id))).get( "values")[0]) return Entity.convert_dict_to_obj_repr(obj_dict)
def _update_ca_attrs_values(cls, obj, **arguments): """Update CA's (obj) attributes values according to dictionary of arguments (key = value). Restrictions: 'multi_choice_options' is a mandatory attribute for Dropdown CA and 'placeholder' is a attribute that exists only for Text and Rich Text CA. Generated data - 'obj', entered data - '**arguments'. """ # fix generated data if arguments.get("attribute_type"): obj.title = cls.generate_string(arguments["attribute_type"]) if (obj.multi_choice_options and obj.attribute_type == AdminWidgetCustomAttributes.DROPDOWN and arguments.get("attribute_type") != AdminWidgetCustomAttributes.DROPDOWN): obj.multi_choice_options = None # fix entered data if (arguments.get("multi_choice_options") and arguments.get("attribute_type") != AdminWidgetCustomAttributes.DROPDOWN): arguments["multi_choice_options"] = None if (arguments.get("placeholder") and arguments.get("attribute_type") not in (AdminWidgetCustomAttributes.TEXT, AdminWidgetCustomAttributes.RICH_TEXT)): arguments["placeholder"] = None # extend entered data if (arguments.get("attribute_type") == AdminWidgetCustomAttributes.DROPDOWN and not obj.multi_choice_options): obj.multi_choice_options = random_list_strings() return Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=obj, **arguments)
def generate(cls, objs_under_asmt, audit, asmt_tmpl=None): """Generate Assessment objects according to objects under Assessment, Audit, Assessment Template. If 'asmt_tmpl' then generate with Assessment Template, if not 'asmt_tmpl' then generate without Assessment Template. Slug will not be predicted to avoid of rising errors in case of tests parallel running. Predictable values will be used for type, title, audit, objects_under_assessment custom_attribute_definitions and custom_attribute_values. """ # pylint: disable=too-many-locals cas_def = asmt_tmpl.custom_attribute_definitions if asmt_tmpl and getattr( asmt_tmpl, "custom_attribute_definitions") else None asmts_objs = [ cls.create(title=obj_under_asmt.title + " assessment for " + audit.title, audit=audit.title, objects_under_assessment=[obj_under_asmt], custom_attribute_definitions=cas_def, verifier=[audit.contact["name"]]) for obj_under_asmt in objs_under_asmt ] return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_obj, slug=None) for asmt_obj in asmts_objs ]
def get_filter_exprs_by_ca(self, ca_title, ca_val, ca_type, operator): """Return all possible filter expressions for CA according to CA type""" if ca_type == AdminWidgetCustomAttributes.CHECKBOX: values_to_filter = (string_utils.get_list_of_all_cases( alias.YES_VAL) if string_utils.get_bool_value_from_arg(ca_val) else string_utils.get_list_of_all_cases( alias.NO_VAL)) elif ca_type == AdminWidgetCustomAttributes.PERSON: from lib.service import rest_service person = rest_service.ObjectsInfoService().get_obj( obj=Entity.convert_dict_to_obj_repr( dict(zip(["type", "id"], ca_val.split(":"))))) values_to_filter = [person.name, person.email] elif ca_type == AdminWidgetCustomAttributes.DATE: date_formats = ["%m/%d/%Y", "%m/%Y", "%Y-%m-%d", "%Y-%m", "%Y"] date = parser.parse(ca_val).date() values_to_filter = [ date.strftime(_format) for _format in date_formats ] else: values_to_filter = [ca_val] return [ self.get_filter_exp(ca_title, operator, [val]) for val in values_to_filter ]
def create(cls, type=None, id=None, name=None, href=None, url=None, email=None, company=None, system_wide_role=None, updated_at=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None): """Create Person object. Random values will be used for name. Predictable values will be used for type, email and system_wide_role. """ person_entity = cls._create_random_person() person_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=person_entity, is_allow_none_values=False, type=type, id=id, name=name, href=href, url=url, email=email, company=company, system_wide_role=system_wide_role, updated_at=updated_at, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes) return person_entity
class CommentsFactory(EntitiesFactory): """Factory class for Comments entities.""" # pylint: disable=too-many-locals obj_attrs_names = Entity.get_attrs_names_for_entities(CommentEntity) @classmethod def create_empty(cls): """Create blank Comment object.""" empty_comment = CommentEntity() empty_comment.type = cls.obj_comment return empty_comment @classmethod def create(cls, type=None, id=None, href=None, modified_by=None, created_at=None, description=None): """Create Comment object. Random values will be used for description. Predictable values will be used for type, owners, modified_by. """ comment_entity = cls._create_random_comment() comment_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=comment_entity, is_allow_none_values=False, type=type, id=id, href=href, modified_by=modified_by, created_at=created_at, description=description) return comment_entity @classmethod def _create_random_comment(cls): """Create Comment entity with randomly and predictably filled fields.""" random_comment = CommentEntity() random_comment.type = cls.obj_comment random_comment.modified_by = ObjectPersonsFactory().default().__dict__ random_comment.description = cls.generate_string(cls.obj_comment) return random_comment
def _update_ca_attrs_values(cls, obj, **arguments): """Update CA's (obj) attributes values according to dictionary of arguments (key = value). Restrictions: 'multi_choice_options' is a mandatory attribute for Dropdown CA and 'placeholder' is a attribute that exists only for Text and Rich Text CA. Generated data - 'obj', entered data - '**arguments'. """ # fix generated data if arguments.get("attribute_type"): obj.title = cls.generate_string(arguments["attribute_type"]) if (obj.multi_choice_options and obj.attribute_type == AdminWidgetCustomAttributes.DROPDOWN and arguments.get("attribute_type") != AdminWidgetCustomAttributes.DROPDOWN): obj.multi_choice_options = None # fix entered data if (arguments.get("multi_choice_options") and arguments.get("attribute_type") != AdminWidgetCustomAttributes.DROPDOWN): arguments["multi_choice_options"] = None if (arguments.get("placeholder") and arguments.get("attribute_type") not in (AdminWidgetCustomAttributes.TEXT, AdminWidgetCustomAttributes.RICH_TEXT)): arguments["placeholder"] = None # extend entered data if (arguments.get("attribute_type") == AdminWidgetCustomAttributes.DROPDOWN and not obj.multi_choice_options): obj.multi_choice_options = random_list_strings() return Entity.update_objs_attrs_values_by_entered_data(obj_or_objs=obj, **arguments)
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, audit=None, recipients=None, assignees=None, verified=None, verifier=None, creator=None, assessor=None, updated_at=None, objects_under_assessment=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None): """Create Assessment object. Random values will be used for title and slug. Predictable values will be used for type, status, recipients, verified, owners. """ # pylint: disable=too-many-locals asmt_entity = cls._create_random_asmt() asmt_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, audit=audit, recipients=recipients, assignees=assignees, verified=verified, verifier=verifier, creator=creator, assessor=assessor, updated_at=updated_at, objects_under_assessment=objects_under_assessment, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by) return asmt_entity
class AssessmentTemplatesFactory(EntitiesFactory): """Factory class for Assessment Templates entities.""" obj_attrs_names = Entity.get_attrs_names_for_entities( AssessmentTemplateEntity) @classmethod def clone(cls, asmt_tmpl, count_to_clone=1): """Clone Assessment Template object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(asmt_tmpl), slug=None, updated_at=None, href=None, url=None, id=None) for _ in xrange(1, count_to_clone + 1) ] @classmethod def create_empty(cls): """Create blank Assessment Template object.""" empty_asmt_tmpl = AssessmentTemplateEntity() empty_asmt_tmpl.type = cls.obj_asmt_tmpl empty_asmt_tmpl.custom_attributes = {None: None} return empty_asmt_tmpl @classmethod def create(cls, **attrs): """Create Assessment Template object. Random values will be used for title and slug. Predictable values will be used for type, template_object_type and default_people {"verifiers": *, "assignees": *}. """ # pylint: disable=too-many-locals asmt_tmpl_entity = cls._create_random_asmt_tmpl() asmt_tmpl_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_tmpl_entity, is_allow_none_values=False, **attrs) return asmt_tmpl_entity @classmethod def _create_random_asmt_tmpl(cls): """Create Assessment Template entity with randomly and predictably filled fields. """ random_asmt_tmpl = AssessmentTemplateEntity() random_asmt_tmpl.type = cls.obj_asmt_tmpl random_asmt_tmpl.title = cls.generate_string(cls.obj_asmt_tmpl) random_asmt_tmpl.assignees = unicode(roles.AUDIT_LEAD) random_asmt_tmpl.slug = cls.generate_slug() random_asmt_tmpl.template_object_type = cls.obj_control.title() random_asmt_tmpl.status = unicode(element.ObjectStates.DRAFT) random_asmt_tmpl.default_people = { "verifiers": unicode(roles.AUDITORS), "assignees": unicode(roles.AUDIT_LEAD) } return random_asmt_tmpl
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, audit=None, recipients=None, assignees=None, verified=None, verifier=None, creator=None, assessor=None, updated_at=None, objects_under_assessment=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None): """Create Assessment object. Random values will be used for title and slug. Predictable values will be used for type, status, recipients, verified, owners. """ # pylint: disable=too-many-locals asmt_entity = cls._create_random_asmt() asmt_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, audit=audit, recipients=recipients, assignees=assignees, verified=verified, verifier=verifier, creator=creator, assessor=assessor, updated_at=updated_at, objects_under_assessment=objects_under_assessment, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by) return asmt_entity
class ObjectPersonsFactory(EntitiesFactory): """Factory class for Persons entities.""" obj_attrs_names = Entity().get_attrs_names_for_entities(PersonEntity) @classmethod def default(cls): """Create default system Person object.""" return cls.create(name=roles.DEFAULT_USER, id=1, href=const_url.DEFAULT_USER_HREF, email=const_url.DEFAULT_USER_EMAIL, system_wide_role=roles.SUPERUSER) @classmethod def create(cls, type=None, id=None, name=None, href=None, url=None, email=None, company=None, system_wide_role=None, updated_at=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None): """Create Person object. Random values will be used for name. Predictable values will be used for type, email and system_wide_role. """ person_entity = cls._create_random_person() person_entity = cls.update_objs_attrs_values_by_entered_data( objs=person_entity, is_allow_none_values=False, type=type, id=id, name=name, href=href, url=url, email=email, company=company, system_wide_role=system_wide_role, updated_at=updated_at, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes) return person_entity @classmethod def _create_random_person(cls): """Create Person entity with randomly filled fields.""" random_person = PersonEntity() random_person.type = cls.obj_person random_person.name = cls.generate_string(cls.obj_person) random_person.email = cls.generate_email() random_person.system_wide_role = unicode(roles.SUPERUSER) return random_person
class AuditsFactory(EntitiesFactory): """Factory class for Audit entity.""" obj_attrs_names = Entity.get_attrs_names_for_entities(AuditEntity) default_person = ObjectPersonsFactory().default() @classmethod def clone(cls, audit, count_to_clone=1): """Clone Audit object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [ Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(audit), title=audit.title + " - copy " + str(num), slug=None, created_at=None, updated_at=None, href=None, url=None, id=None) for num in xrange(1, count_to_clone + 1) ] @classmethod def create_empty(cls): """Create blank Audit object.""" empty_audit = AuditEntity() empty_audit.type = cls.obj_audit empty_audit.custom_attributes = {None: None} empty_audit.access_control_list = [] return empty_audit @classmethod def create(cls, **attrs): """Create Audit object. Random values will be used for title and slug. Predictable values will be used for type, status, contact. """ # pylint: disable=too-many-locals audit_entity = cls._create_random_audit() audit_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=audit_entity, is_allow_none_values=False, **attrs) return audit_entity @classmethod def _create_random_audit(cls): """Create Audit entity with randomly and predictably filled fields.""" random_audit = AuditEntity() random_audit.type = cls.obj_audit random_audit.title = cls.generate_string(cls.obj_audit) random_audit.slug = cls.generate_slug() random_audit.status = unicode(element.AuditStates().PLANNED) random_audit.contact = cls.default_person.__dict__ random_audit.access_control_list = [ ObjectPersonsFactory.get_acl_member(roles.AUDIT_CAPTAIN_ID, cls.default_person) ] return random_audit
def clone(cls, asmt_tmpl, count_to_clone=1): """Clone Assessment Template object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(asmt_tmpl), slug=None, updated_at=None, href=None, url=None, id=None) for _ in xrange(1, count_to_clone + 1)]
def _update_asmt_attrs_values(cls, obj, **arguments): """Update Assessments (obj) attributes values according to dictionary of arguments (key = value). Generated data-'obj', entered data-'**arguments'. """ if arguments.get("verifier"): obj.assignees['Verifier'] = [cls.default_person.__dict__] return Entity.update_objs_attrs_values_by_entered_data(obj_or_objs=obj, **arguments)
def clone(cls, asmt_tmpl, count_to_clone=1): """Clone Assessment Template object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(asmt_tmpl), slug=None, updated_at=None, href=None, url=None, id=None) for _ in xrange(1, count_to_clone + 1)]
def create(cls, **attrs): """Create Program object. Random values will be used for title and slug. Predictable values will be used for type, status, manager, contact. """ program_entity = cls._create_random_program() program_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=program_entity, is_allow_none_values=False, **attrs) return program_entity
def create(cls, **attrs): """Create Person object. Random values will be used for name. Predictable values will be used for type, email and system_wide_role. """ person_entity = cls._create_random_person() person_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=person_entity, is_allow_none_values=False, **attrs) return person_entity
def create(cls, **attrs): """Create Control object. Random values will be used for title and slug. Predictable values will be used for type, status, owners and contact. """ control_entity = cls._create_random_control() control_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=control_entity, is_allow_none_values=False, **attrs) return control_entity
def create(cls, **attrs): """Create Objective object. Random values will be used for title and slug. Predictable values will be used for type, status, owners. """ objective_entity = cls._create_random_objective() objective_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=objective_entity, is_allow_none_values=False, **attrs) return objective_entity
class IssuesFactory(EntitiesFactory): """Factory class for Issues entities.""" obj_attrs_names = Entity.get_attrs_names_for_entities(IssueEntity) default_person = ObjectPersonsFactory().default() @classmethod def create_empty(cls): """Create blank Issue object.""" empty_issue = IssueEntity() empty_issue.type = cls.obj_issue empty_issue.custom_attributes = {None: None} empty_issue.access_control_list = [] return empty_issue @classmethod def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, contact=None, secondary_contact=None, updated_at=None, os_state=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, access_control_list=None, created_at=None, modified_by=None): """Create Issue object. Random values will be used for title and slug. Predictable values will be used for type, status, owners and contact. """ # pylint: disable=too-many-locals issue_entity = cls._create_random_issue() issue_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=issue_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, contact=contact, secondary_contact=secondary_contact, updated_at=updated_at, os_state=os_state, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, access_control_list=access_control_list, created_at=created_at, modified_by=modified_by) return issue_entity @classmethod def _create_random_issue(cls): """Create Issue entity with randomly and predictably filled fields.""" random_issue = IssueEntity() random_issue.type = cls.obj_issue random_issue.title = cls.generate_string(cls.obj_issue) random_issue.slug = cls.generate_slug() random_issue.status = unicode(element.IssueStates.DRAFT) random_issue.owners = [ObjectPersonsFactory().default().__dict__] random_issue.contact = ObjectPersonsFactory().default().__dict__ random_issue.access_control_list = [ ObjectPersonsFactory().get_acl_member( roles.ISSUE_ADMIN_ID, random_issue.owners[0]), ObjectPersonsFactory().get_acl_member( roles.ISSUE_PRIMARY_CONTACT_ID, random_issue.contact)] random_issue.os_state = unicode(element.ReviewStates.UNREVIEWED) return random_issue
def clone(cls, audit, count_to_clone=1): """Clone Audit object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(audit), title=audit.title + " - copy " + str(num), slug=None, created_at=None, updated_at=None, href=None, url=None, id=None) for num in xrange(1, count_to_clone + 1)]
def create(cls, **attrs): """Create Audit object. Random values will be used for title and slug. Predictable values will be used for type, status, contact. """ # pylint: disable=too-many-locals audit_entity = cls._create_random_audit() audit_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=audit_entity, is_allow_none_values=False, **attrs) return audit_entity
def create_objs(self, count, factory_params=None, **attrs_for_template): """Create new objects via REST API and return list of created objects with filtered attributes. """ list_objs = self.create_list_objs( entity_factory=self.entities_factory_cls(), count=count, attrs_to_factory=factory_params, **attrs_for_template) return Entity.filter_objs_attrs( obj_or_objs=list_objs, attrs_to_include=self.entities_factory_cls().obj_attrs_names)
def create_objs(self, count, factory_params=None, **attrs_for_template): """Create new objects via REST API and return list of created objects with filtered attributes. """ list_objs = self.create_list_objs( entity_factory=self.entities_factory_cls(), count=count, attrs_to_factory=factory_params, **attrs_for_template) return Entity.filter_objs_attrs( obj_or_objs=list_objs, attrs_to_include=self.entities_factory_cls().obj_attrs_names)
def create(cls, **attrs): """Create Issue object. Random values will be used for title and slug. Predictable values will be used for type, status, owners and contact. """ # pylint: disable=too-many-locals issue_entity = cls._create_random_issue() issue_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=issue_entity, is_allow_none_values=False, **attrs) return issue_entity
def xfail_equal_assert(expected_objs, actual_objs, issue_msg, *exclude_attrs): """Perform xfail equal assert based on deepcopy converted to list expected and actual objects according to 'issue_msg' string and '*exclude_attrs' tuple of excluding attributes' names (compare simple' collections based on excluding attributes (attributes' names and values, if 'False' then rise pytest's xfail, else pytest's fail. """ expected_excluded_attrs, actual_excluded_attrs = ( Entity.extract_simple_collections( help_utils.convert_to_list(expected_objs), help_utils.convert_to_list(actual_objs), *exclude_attrs)) assert_msg = messages.AssertionMessages.format_err_msg_equal( expected_excluded_attrs, actual_excluded_attrs) is_list_excluded_attrs_equal = (Entity.is_list_of_attrs_equal( expected_excluded_attrs, actual_excluded_attrs)) Test.check_xfail_or_fail(is_condition=is_list_excluded_attrs_equal, issue_msg=issue_msg, assert_msg=assert_msg)
def clone(cls, audit, count_to_clone=1): """Clone Audit object. Predictable values will be used for type, title. """ # pylint: disable=anomalous-backslash-in-string return [Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=copy.deepcopy(audit), title=audit.title + " - copy " + str(num), slug=None, created_at=None, updated_at=None, href=None, url=None, id=None) for num in xrange(1, count_to_clone + 1)]
def xfail_equal_assert(expected_objs, actual_objs, issue_msg, *exclude_attrs): """Perform xfail equal assert based on deepcopy converted to list expected and actual objects according to 'issue_msg' string and '*exclude_attrs' tuple of excluding attributes' names (compare simple' collections based on excluding attributes (attributes' names and values, if 'False' then rise pytest's xfail, else pytest's fail. """ expected_excluded_attrs, actual_excluded_attrs = ( Entity.extract_simple_collections( help_utils.convert_to_list(expected_objs), help_utils.convert_to_list(actual_objs), *exclude_attrs)) assert_msg = messages.AssertionMessages.format_err_msg_equal( expected_excluded_attrs, actual_excluded_attrs) is_list_excluded_attrs_equal = ( Entity.is_list_of_attrs_equal( expected_excluded_attrs, actual_excluded_attrs)) Test.check_xfail_or_fail( is_condition=is_list_excluded_attrs_equal, issue_msg=issue_msg, assert_msg=assert_msg)
def update_objs(self, objs, factory_params=None, **attrs_for_template): """Update existing objects via REST API and return list of updated objects with filtered attributes. """ list_objs = self.update_list_objs( entity_factory=self.entities_factory_cls(), list_objs_to_update=help_utils.convert_to_list(objs), attrs_to_factory=factory_params, **attrs_for_template) return Entity.filter_objs_attrs( obj_or_objs=list_objs, attrs_to_include=self.entities_factory_cls().obj_attrs_names)
def create(cls, **attrs): """Create Assessment Template object. Random values will be used for title and slug. Predictable values will be used for type, template_object_type and default_people {"verifiers": *, "assignees": *}. """ # pylint: disable=too-many-locals asmt_tmpl_entity = cls._create_random_asmt_tmpl() asmt_tmpl_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_tmpl_entity, is_allow_none_values=False, **attrs) return asmt_tmpl_entity
def update_objs(self, objs, factory_params=None, **attrs_for_template): """Update existing objects via REST API and return list of updated objects with filtered attributes. """ list_objs = self.update_list_objs( entity_factory=self.entities_factory_cls(), list_objs_to_update=help_utils.convert_to_list(objs), attrs_to_factory=factory_params, **attrs_for_template) return Entity.filter_objs_attrs( obj_or_objs=list_objs, attrs_to_include=self.entities_factory_cls().obj_attrs_names)
def create(cls, type=None, id=None, href=None, modified_by=None, created_at=None, description=None): """Create Comment object. Random values will be used for description. Predictable values will be used for type, owners, modified_by. """ comment_entity = cls._create_random_comment() comment_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=comment_entity, is_allow_none_values=False, type=type, id=id, href=href, modified_by=modified_by, created_at=created_at, description=description) return comment_entity
def get_snapshoted_obj(self, origin_obj, paren_obj): """Get and return snapshoted object according to 'origin_obj' and 'paren_obj'. """ snapshoted_obj_dict = ( BaseRestService.get_items_from_resp(self.client.create_object( type=self.endpoint, object_name=EntitiesFactory.obj_snapshot, filters=query.Query.expression_get_snapshoted_obj( obj_type=origin_obj.type, obj_id=origin_obj.id, parent_type=paren_obj.type, parent_id=paren_obj.id))).get("values")[0]) return Entity.convert_dict_to_obj_repr(snapshoted_obj_dict)
def general_equal_assert(expected_objs, actual_objs, *exclude_attrs): """Perform general equal assert for deepcopy converted to list expected and actual objects according to '*exclude_attrs' tuple of excluding attributes' names (compare objects' collections w/ attributes' values set to None). """ expected_objs_wo_excluded_attrs, actual_objs_wo_excluded_attrs = ( Entity.extract_objs(help_utils.convert_to_list(expected_objs), help_utils.convert_to_list(actual_objs), *exclude_attrs)) assert (expected_objs_wo_excluded_attrs == actual_objs_wo_excluded_attrs), ( messages.AssertionMessages.format_err_msg_equal( expected_objs_wo_excluded_attrs, actual_objs_wo_excluded_attrs))
def format_err_msg_equal(cls, left, right): """Return customized and detailed error message after assert equal comparison. """ # comparison of entities assertion_error_msg = cls.err_common.format(left, right) # processing of entity if isinstance(left and right, Entity.all_entities_classes()): if not cls.is_entities_have_err_info(left, right): cls.set_entities_diff_info(left, right) assertion_error_msg = cls.diff_error_msg(left, right) # processing list of entities if (isinstance(left and right, list) and all(isinstance(_left and _right, Entity.all_entities_classes()) for _left, _right in zip(left, right))): assertion_error_msg = "" for _left, _right in zip(sorted(left), sorted(right)): if not cls.is_entities_have_err_info(_left, _right): cls.set_entities_diff_info(_left, _right) assertion_error_msg = (assertion_error_msg + cls.diff_error_msg(_left, _right)) return assertion_error_msg
def get_comment_obj(self, paren_obj, comment_description): """Get and return comment object according to 'paren_obj' type) and comment_description 'paren_obj'. As default 'is_sort_by_created_at' and if even comments have the same descriptions query return selection w/ latest created datetime. """ comment_obj_dict = ( BaseRestService.get_items_from_resp(self.client.create_object( type=self.endpoint, object_name=EntitiesFactory.obj_comment, filters=query.Query.expression_get_comment_by_desc( parent_type=paren_obj.type, parent_id=paren_obj.id, comment_desc=comment_description), order_by=[{"name": "created_at", "desc": True}])).get("values")[0]) return Entity.convert_dict_to_obj_repr(comment_obj_dict)
def _get_fixture_from_dict_fixtures(fixture): """Get value of fixture by key (fixture name) from dictionary of executed fixtures.""" global dict_executed_fixtures # extend executed fixtures using exist fixture in snapshot representation if fixture.endswith("_snapshot"): origin_obj = _get_fixture_from_dict_fixtures( fixture.replace("_snapshot", "")) parent_obj = _get_fixture_from_dict_fixtures("new_audit_rest")[0] dict_executed_fixtures.update( {fixture: Entity.convert_objs_repr_to_snapshot( obj_or_objs=origin_obj, parent_obj=parent_obj)}) return {k: v for k, v in dict_executed_fixtures.iteritems() if k == fixture}[fixture]
def create(cls, type=None, id=None, name=None, href=None, url=None, email=None, company=None, system_wide_role=None, updated_at=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None): """Create Person object. Random values will be used for name. Predictable values will be used for type, email and system_wide_role. """ person_entity = cls._create_random_person() person_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=person_entity, is_allow_none_values=False, type=type, id=id, name=name, href=href, url=url, email=email, company=company, system_wide_role=system_wide_role, updated_at=updated_at, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at) return person_entity
def generate(cls, objs_under_asmt, audit, asmt_tmpl=None): """Generate Assessment objects according to objects under Assessment, Audit, Assessment Template. If 'asmt_tmpl' then generate with Assessment Template, if not 'asmt_tmpl' then generate without Assessment Template. Slug will not be predicted to avoid of rising errors in case of tests parallel running. Predictable values will be used for type, title, audit, objects_under_assessment custom_attribute_definitions and custom_attribute_values. """ # pylint: disable=too-many-locals cas_def = asmt_tmpl.custom_attribute_definitions if asmt_tmpl and getattr( asmt_tmpl, "custom_attribute_definitions") else None asmts_objs = [cls.create( title=obj_under_asmt.title + " assessment for " + audit.title, audit=audit.title, objects_under_assessment=[obj_under_asmt], custom_attribute_definitions=cas_def) for obj_under_asmt in objs_under_asmt] return [Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_obj, slug=None) for asmt_obj in asmts_objs]
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, contact=None, secondary_contact=None, updated_at=None, os_state=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None): """Create Objective object. Random values will be used for title and slug. Predictable values will be used for type, status, owners. """ objective_entity = cls._create_random_objective() objective_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=objective_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, contact=contact, secondary_contact=secondary_contact, updated_at=updated_at, os_state=os_state, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by) return objective_entity
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, program=None, contact=None, updated_at=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None): """Create Audit object. Random values will be used for title and slug. Predictable values will be used for type, status, contact. """ # pylint: disable=too-many-locals audit_entity = cls._create_random_audit() audit_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=audit_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, program=program, contact=contact, updated_at=updated_at, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by) return audit_entity
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, status=None, owners=None, contact=None, secondary_contact=None, updated_at=None, os_state=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, access_control_list=None, created_at=None, modified_by=None): """Create Issue object. Random values will be used for title and slug. Predictable values will be used for type, status, owners and contact. """ # pylint: disable=too-many-locals issue_entity = cls._create_random_issue() issue_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=issue_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, status=status, owners=owners, contact=contact, secondary_contact=secondary_contact, updated_at=updated_at, os_state=os_state, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, access_control_list=access_control_list, created_at=created_at, modified_by=modified_by) return issue_entity
def create(cls, type=None, id=None, title=None, href=None, url=None, slug=None, audit=None, default_people=None, template_object_type=None, updated_at=None, custom_attribute_definitions=None, custom_attribute_values=None, custom_attributes=None, created_at=None, modified_by=None, status=None): """Create Assessment Template object. Random values will be used for title and slug. Predictable values will be used for type, template_object_type and default_people {"verifiers": *, "assessors": *}. """ # pylint: disable=too-many-locals asmt_tmpl_entity = cls._create_random_asmt_tmpl() asmt_tmpl_entity = Entity.update_objs_attrs_values_by_entered_data( obj_or_objs=asmt_tmpl_entity, is_allow_none_values=False, type=type, id=id, title=title, href=href, url=url, slug=slug, audit=audit, default_people=default_people, template_object_type=template_object_type, updated_at=updated_at, custom_attribute_definitions=custom_attribute_definitions, custom_attribute_values=custom_attribute_values, custom_attributes=custom_attributes, created_at=created_at, modified_by=modified_by, status=status) return asmt_tmpl_entity
def create_list_objs(self, entity_factory, list_scopes): """Create and return list of objects used entity factory and UI data (list of scopes UI text elements {"header": "item", ...} remapped to list of dicts {"attr": "value", ...}). Return list of created objects. """ list_factory_objs = [ entity_factory.create_empty() for _ in xrange(len(list_scopes))] list_scopes_with_upper_keys = [ string_utils.dict_keys_to_upper_case(scope) for scope in list_scopes] list_scopes_remapped = string_utils.remap_keys_for_list_dicts( dict_of_transform_keys=Entity.items_of_remap_keys(), list_dicts=list_scopes_with_upper_keys) # add extra 'owners' attribute name and value if 'creator' in scopes list_extra_scopes = [ dict(scope_remapped.items() + [("owners", scope_remapped.get("creator"))]) if "creator" in scope_remapped.keys() else scope_remapped for scope_remapped in list_scopes_remapped] # convert and represent values in scopes for scope in list_extra_scopes: for key, val in scope.iteritems(): # convert u'false' and u'true' to boolean scope[key] = string_utils.get_bool_from_string(val) # convert multiple values to list of strings if key in ["owners", "assessor", "creator"]: # convert CSV like u'*****@*****.**' to u'Example User' val = val if val != url.DEFAULT_USER_EMAIL else roles.DEFAULT_USER scope[key] = string_utils.convert_to_list(val) # convert 'slug' from CSV for snapshoted objects u'*23eb72ac-4d9d' if (key == "slug" and self.obj_name in objects.ALL_SNAPSHOTABLE_OBJS and "*" in val): scope[key] = val.replace("*", "") return [ EntitiesFactory.update_objs_attrs_values_by_entered_data( objs=factory_obj, is_allow_none_values=False, **scope) for scope, factory_obj in zip(list_extra_scopes, list_factory_objs)]
def set_entities_diff_info(cls, left, right): """Get and set entities diff info attributes info.""" comparison = Entity.compare_entities(left, right) left.diff_info = comparison["self_diff"] right.diff_info = comparison["other_diff"]