Пример #1
0
def prepare_post_body_data(request, adcm_api_fs: ADCMTestApiWrapper):
    """
    Fixture for preparing test data for POST request, depending on generated test datasets
    """
    test_data_list: List[TestDataWithPreparedBody] = request.param
    valid_request_data = DbFiller(
        adcm=adcm_api_fs).generate_valid_request_data(
            endpoint=test_data_list[0].test_data.request.endpoint,
            method=Methods.POST)
    final_test_data_list: List[TestDataWithPreparedBody] = []
    for test_data_with_prepared_values in test_data_list:
        test_data, prepared_field_values = test_data_with_prepared_values
        test_data.request.data = deepcopy(valid_request_data["data"])
        for field in get_fields(test_data.request.endpoint.data_class):
            if field.name in prepared_field_values:
                if not prepared_field_values[field.name].drop_key:

                    valid_field_value = None
                    if field.name in test_data.request.data:
                        valid_field_value = test_data.request.data[field.name]
                    test_data.request.data[field.name] = prepared_field_values[
                        field.name].return_value(valid_field_value)

                else:
                    if field.name in test_data.request.data:
                        del test_data.request.data[field.name]
        final_test_data_list.append(
            TestDataWithPreparedBody(test_data, prepared_field_values))

    return adcm_api_fs, final_test_data_list
Пример #2
0
def generate_body_for_checks(test_data: TestDataWithPreparedBody):
    """
    Generate expected response fields values by test data
    """
    test_data, prepared_field_values = test_data
    body = ExpectedBody()
    for field in get_fields(test_data.request.endpoint.data_class):
        body.fields[field.name] = not_set
        if is_fk_field(field):
            # TODO add fk field check
            continue
        if field.default_value == AUTO_VALUE:
            continue
        if test_data.request.method == Methods.POST:
            continue
        if isinstance(body.fields[field.name], list):
            # TODO implement list checks with sorting
            continue
        if (test_data.request.method == Methods.PATCH and not field.changeable
                and field.name in prepared_field_values
                and prepared_field_values[field.name].generated_value):
            body.fields[field.name] = NotEqual(
                test_data.request.data.get(field.name))
        elif is_password_field(field):
            body.fields[field.name] = field.f_type.placeholder
        elif expected_field_value := test_data.request.data.get(field.name):
            body.fields[field.name] = expected_field_value
Пример #3
0
def prepare_patch_body_data(request, adcm_api_fs: ADCMTestApiWrapper):
    """
    Fixture for preparing test data for PATCH request, depending on generated test datasets
    """
    test_data_list: List[TestDataWithPreparedBody] = request.param
    dbfiller = DbFiller(adcm=adcm_api_fs)
    valid_data = dbfiller.generate_valid_request_data(
        endpoint=test_data_list[0].test_data.request.endpoint,
        method=Methods.PATCH)
    full_item = deepcopy(valid_data["full_item"])
    changed_fields = deepcopy(valid_data["changed_fields"])
    final_test_data_list: List[TestDataWithPreparedBody] = []
    for test_data_with_prepared_values in test_data_list:
        test_data, prepared_field_values = deepcopy(
            test_data_with_prepared_values)
        for field in get_fields(test_data.request.endpoint.data_class):
            if (field.name in prepared_field_values
                ) and not prepared_field_values[field.name].drop_key:
                current_field_value = full_item[field.name]
                if prepared_field_values[field.name].unchanged_value is False:
                    changed_field_value = changed_fields.get(field.name, None)
                    test_data.request.data[field.name] = prepared_field_values[
                        field.name].return_value(dbfiller, current_field_value,
                                                 changed_field_value)
                else:
                    test_data.request.data[field.name] = current_field_value

        test_data.request.object_id = valid_data["object_id"]
        final_test_data_list.append(
            TestDataWithPreparedBody(test_data, prepared_field_values))

    return adcm_api_fs, final_test_data_list
Пример #4
0
    def generate_valid_request_data(self, endpoint: Endpoints, method: Methods) -> dict:
        """
        Return valid request body and url params for endpoint and method combination
        """
        if method == Methods.POST:
            return {
                "data": self._get_or_create_data_for_endpoint(
                    endpoint=endpoint,
                    force=True,
                    prepare_data_only=True,
                )[0],
                "url_params": {},
            }

        if method == Methods.LIST:
            self._get_or_create_multiple_data_for_endpoint(endpoint=endpoint, count=3)
            return {"data": None, "url_params": {}}

        full_item = get_object_data(
            adcm=self.adcm,
            endpoint=endpoint,
            object_id=self._get_or_create_data_for_endpoint(endpoint=endpoint)[0]['id'],
        )

        if method in (Methods.GET, Methods.DELETE):
            return {"data": None, "url_params": {}, "object_id": full_item["id"]}

        if method in (Methods.PUT, Methods.PATCH):
            changed_fields = {}
            for field in get_fields(endpoint.data_class, predicate=lambda x: x.changeable):
                if isinstance(field.f_type, ForeignKey):
                    fk_data = self._get_or_create_data_for_endpoint(
                        endpoint=Endpoints.get_by_data_class(field.f_type.fk_link), force=True
                    )
                    if isinstance(field.f_type, ForeignKeyM2M):
                        changed_fields[field.name] = [{"id": el["id"]} for el in fk_data]
                    elif isinstance(field.f_type, ObjectForeignKey):
                        changed_fields[field.name] = {"id": fk_data[0]["id"]}
                    else:
                        changed_fields[field.name] = fk_data[0]["id"]
                elif field.name != "id":
                    changed_fields[field.name] = self._generate_field_value(
                        field=field, old_value=full_item[field.name]
                    )
            if getattr(endpoint.data_class, 'dependable_fields_sync', None):
                changed_fields = endpoint.data_class.dependable_fields_sync(self.adcm, changed_fields)
            result = {
                "full_item": full_item.copy(),
                "changed_fields": changed_fields,
                "url_params": {},
                "object_id": full_item["id"],
            }
            full_item.update(changed_fields)
            result["data"] = full_item
            return result
        raise ValueError(f"No such method {method}")
Пример #5
0
 def _prepare_data_for_object_creation(self, endpoint: Endpoints = None, force=False):
     data = {}
     for field in get_fields(data_class=endpoint.data_class, predicate=lambda x: x.postable):
         if field.name in data:
             continue
         if field.f_type.relates_on:
             data_with_relates, field = self._solve_field_relations(endpoint, data, field, force)
             data.update(data_with_relates)
         data[field.name] = self._prepare_field_value_for_object_creation(field, force)
     return data
Пример #6
0
 def get_child_endpoint_by_fk_name(
         self, field_name: str) -> Optional["Endpoints"]:
     """Get child endpoint instance by data class"""
     for field in get_fields(self.value.data_class):  # pylint: disable=no-member
         if field.name == field_name:
             try:
                 return self.get_by_data_class(field.f_type.fk_link)
             except AttributeError:
                 raise ValueError(
                     f"Field {field_name} must be a Foreign Key field type"
                 ) from AttributeError
     return None
Пример #7
0
def _get_special_body_datasets(endpoint: Endpoints, desc, method: Methods,
                               positive_case: bool) -> (list, str):
    """Get datasets with based on special values for fields"""
    datasets = []
    special_values = {}
    field_condition = False
    for field in get_fields(endpoint.data_class):
        if method == Methods.POST:
            field_condition = field.postable
        if method in [Methods.PATCH, Methods.PUT]:
            field_condition = field.changeable
        if field_condition:
            if positive_case:
                special_values[field.name] = field.f_type.get_positive_values()
            else:
                # Since Json does not have an invalid value,
                # in case when this is the only field in a negative case,
                # we do not include it in the tests.
                # For example: PATCH and PUT methods in MountPoint
                negative_values = get_fields(
                    endpoint.data_class,
                    predicate=lambda x: x.f_type.get_negative_values() and
                    (x.changeable if method in [Methods.PATCH, Methods.PUT]
                     else x.postable),  # noqa: W504
                )
                if negative_values:
                    special_values[field.name] = (
                        field.f_type.get_negative_values()
                        if field.f_type.get_negative_values() else [
                            PreparedFieldValue(generated_value=True,
                                               f_type=field.f_type)
                        ])
    if special_values:
        fill_lists_by_longest(special_values.values())
        for name, values in special_values.copy().items():
            special_values[name] = [{name: value} for value in values]
        for values in zip(*special_values.values()):
            datasets.append(dict(ChainMap(*values)))
    return datasets, desc
Пример #8
0
def prepare_put_body_data(request, adcm_api_fs: ADCMTestApiWrapper):
    """
    Fixture for preparing test data for PUT request, depending on generated test datasets
    """
    test_data_list: List[TestDataWithPreparedBody] = request.param
    dbfiller = DbFiller(adcm=adcm_api_fs)
    endpoint = test_data_list[0].test_data.request.endpoint
    valid_data = dbfiller.generate_valid_request_data(endpoint=endpoint,
                                                      method=Methods.PUT)
    full_item = deepcopy(valid_data["full_item"])
    changed_fields = deepcopy(valid_data["changed_fields"])
    final_test_data_list: List[TestDataWithPreparedBody] = []
    for test_data_with_prepared_values in test_data_list:
        test_data, prepared_field_values = deepcopy(
            test_data_with_prepared_values)
        test_data.request.data = deepcopy(full_item)
        for field in get_fields(test_data.request.endpoint.data_class):
            if field.name in prepared_field_values:
                if not prepared_field_values[field.name].drop_key:

                    if prepared_field_values[
                            field.name].unchanged_value is False:
                        current_field_value = full_item[field.name]
                        changed_field_value = changed_fields.get(
                            field.name, None)
                        test_data.request.data[
                            field.name] = prepared_field_values[
                                field.name].return_value(
                                    dbfiller, current_field_value,
                                    changed_field_value)

                else:
                    if field.name in test_data.request.data:
                        del test_data.request.data[field.name]
            else:
                # When we want to drop some fields, but leave others with:
                #  - changed value if fields are changeable
                #  - value as is
                if field.name in changed_fields:
                    test_data.request.data[field.name] = changed_fields[
                        field.name]

        test_data.request.object_id = valid_data["object_id"]
        if getattr(endpoint.data_class, 'dependable_fields_sync', None):
            test_data.request.data = endpoint.data_class.dependable_fields_sync(
                adcm_api_fs, test_data.request.data)
        final_test_data_list.append(
            TestDataWithPreparedBody(test_data, prepared_field_values))

    return adcm_api_fs, final_test_data_list
Пример #9
0
 def _add_child_fk_values_to_available_fkeys(self, fk_ids: list, fk_data_class):
     """Add information about child FK values to metadata for further consistency"""
     for child_fk_field in get_fields(data_class=fk_data_class, predicate=is_fk_field):
         fk_field_name = get_field_name_by_fk_dataclass(
             data_class=fk_data_class, fk_data_class=child_fk_field.f_type.fk_link
         )
         for fk_id in fk_ids:
             fk_data = get_object_data(
                 adcm=self.adcm,
                 endpoint=Endpoints.get_by_data_class(fk_data_class),
                 object_id=fk_id,
             )
             if isinstance(child_fk_field.f_type, ForeignKeyM2M):
                 self._available_fkeys[child_fk_field.f_type.fk_link.__name__].update(
                     [el["id"] for el in fk_data[fk_field_name]]
                 )
             elif isinstance(child_fk_field.f_type, ForeignKey):
                 self._available_fkeys[child_fk_field.f_type.fk_link.__name__].add(fk_data[fk_field_name])
Пример #10
0
def _get_datasets(
    endpoint: Endpoints,
    desc,
    field_conditions,
    value_properties: dict,
) -> (list, str):
    """Generic dataset creator for editing request data later"""
    dataset = {}
    if "generated_value" in value_properties and "value" in value_properties:
        raise ValueError(
            "'generated_value', 'value' properties are not compatible")
    for field in get_fields(endpoint.data_class):
        if field_conditions(field):
            dataset[field.name] = PreparedFieldValue(
                value=value_properties.get("value", None),
                unchanged_value=value_properties.get("unchanged_value", False),
                generated_value=value_properties.get("generated_value", False),
                error_messages=[value_properties.get("error_message", None)],
                drop_key=value_properties.get("drop_key", False),
                f_type=field.f_type,
            )
    return [dataset] if dataset else [], desc
Пример #11
0
def get_data_for_params_check(method=Methods.GET, fields_predicate=None):
    """
    Get test data for GET-request params check, such as flex fields, filtering and ordering
    """
    test_data = []
    for endpoint in Endpoints:
        if endpoint.technical:
            continue
        if method not in endpoint.methods:
            continue
        if not get_fields(endpoint.data_class, predicate=fields_predicate):
            continue
        request = Request(method=method, endpoint=endpoint)
        response = ExpectedResponse(status_code=method.default_success_code)
        test_data.append(
            _fill_pytest_param(
                [TestData(request=request, response=response)],
                endpoint=endpoint,
                method=method,
                positive=True,
            ))
    return test_data