testit-python-commons 5.2.0__tar.gz → 5.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/PKG-INFO +1 -1
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/setup.py +1 -1
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/api_client.py +4 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/helpers/bulk_autotest_helper.py +3 -3
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/test_result.py +1 -1
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/utils/html_escape_utils.py +63 -35
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons.egg-info/PKG-INFO +1 -1
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons.egg-info/SOURCES.txt +2 -1
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/tests/test_html_escape_utils.py +45 -0
- testit_python_commons-5.2.1/tests/test_xss_parameters_escape.py +72 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/README.md +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/setup.cfg +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/attachments_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/auto_tests_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/configurations_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/custom_attributes_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/parameters_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/project_attributes_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/project_sections_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/project_work_items_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/projects_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/sections_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/test_results_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/test_runs_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/work_items_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/workflows_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api_client.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/apis/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/configuration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/exceptions.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_auto_tests_id_work_items_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_auto_tests_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_auto_tests_put_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_auto_tests_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_configurations_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_custom_attributes_global_id_put_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_custom_attributes_global_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_custom_attributes_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_parameters_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_parameters_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_projects_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_projects_project_id_attributes_put_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_projects_project_id_attributes_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_projects_project_id_work_items_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_projects_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_sections_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_test_results_id_put_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_test_results_search_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_test_runs_id_reruns_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_test_runs_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_test_runs_put_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/adapters_work_items_post_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/assign_attachment_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/assign_auto_test_case_id_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/assign_iteration_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/attachment_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/attachment_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/attachment_put_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/attachment_put_model_auto_test_step_results_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/attachment_update_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_api_result_layer.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_case_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_create_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_create_api_model_layer.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_filter_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_id_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_model_last_test_result_configuration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_model_last_test_result_status.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_result_reason_short.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_results_for_test_run_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_search_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_search_api_model_filter.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_search_api_model_includes.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_search_include_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step_result_update_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_update_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_work_item_identifier_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/available_test_result_outcome.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/configuration_filter_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/configuration_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/configuration_short_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_empty_test_run_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_link_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_parameter_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_project_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_step_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/create_work_item_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_option_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_option_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_option_post_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_option_update_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_put_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_search_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_search_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/custom_attribute_types_enum.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/date_time_range_selector_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/deletion_state.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/detailed_project_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/detailed_project_api_result_workflow.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/failure_category_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/global_custom_attribute_post_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/global_custom_attribute_update_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/guid_extraction_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/image_resize_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/int32_range_selector_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/int64_range_selector_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/iteration_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/iteration_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/label_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/label_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/label_short_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/layer_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/layer_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/layer_source.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_create_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_post_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_put_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_short_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/link_update_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_select_test_results_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_select_test_results_api_model_extraction_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_select_test_results_api_model_filter.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_test_result_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/manual_rerun_test_result_api_model_test_result_ids.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/operation.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/parameter_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/parameter_iteration_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/parameter_short_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/parameter_short_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/parameters_filter_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/problem_details.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/project_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/project_attributes_filter_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/project_shortest_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/project_type_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model_autotests_count.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model_checklists_count.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model_created_date.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model_shared_steps_count.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/projects_filter_model_test_cases_count.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/section_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/section_post_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/section_shared_step.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/section_with_steps_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/shared_step_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/shared_step_result_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/step_comment_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/step_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/step_post_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/step_result_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/tag_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_link_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_outcome.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_short_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_short_response_status.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_step_comment_update_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_result_update_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_results_filter_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_results_filter_api_model_duration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_run_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_run_api_result_status.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_run_state.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_status_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_status_api_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_status_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/test_status_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/update_empty_test_run_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/update_link_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/validation_problem_details.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_entity_type_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_filter_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_filter_api_model_duration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_id_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_parameter_key_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_parameter_key_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_priority_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_priority_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_select_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_select_api_model_filter.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_short_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_source_type_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_state_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_states.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/work_item_type_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/workflow_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/workflow_status_api_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model_utils.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/models/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/rest.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/completion_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/health_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/system_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/test_results_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api/workers_api.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/api_client.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/apis/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/configuration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/exceptions.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/completion_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/health_status_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/register_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/register_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/set_worker_status_request.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/set_worker_status_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/shutdown_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/test_result_cut_api_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model/test_result_save_response.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/model_utils.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/models/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/api_client_syncstorage/rest.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/app_properties.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/client_configuration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/converter.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/helpers/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/helpers/test_result_matching.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/helpers/threads_manager.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/models/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/models/threads_for_create_and_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/client/models/threads_for_update_and_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/configurations/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/configurations/properties_names.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/decorators.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/dynamic_methods.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/adapter_mode.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/fixture.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/link.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/link_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/outcome_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/status_type.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/step_result.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/test_layers.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/adapter_manager.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/adapter_manager_configuration.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/fixture_manager.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/fixture_storage.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/logger.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/plugin_manager.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/retry.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/step_manager.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/step_result_storage.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/sync_storage/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/sync_storage/sync_storage_runner.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/test_run_metadata.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/services/utils.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/step.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons/utils/__init__.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons.egg-info/dependency_links.txt +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons.egg-info/requires.txt +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/testit_python_commons.egg-info/top_level.txt +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/tests/test_app_properties.py +0 -0
- {testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/tests/test_dynamic_methods.py +0 -0
|
@@ -41,6 +41,7 @@ from testit_python_commons.services.retry import (
|
|
|
41
41
|
retry,
|
|
42
42
|
retry_on_connection_error,
|
|
43
43
|
)
|
|
44
|
+
from testit_python_commons.utils.html_escape_utils import HtmlEscapeUtils
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class ApiClientWorker:
|
|
@@ -469,6 +470,7 @@ class ApiClientWorker:
|
|
|
469
470
|
test_result,
|
|
470
471
|
self.__config.get_project_id())
|
|
471
472
|
|
|
473
|
+
HtmlEscapeUtils.escape_html_in_object(model)
|
|
472
474
|
autotest_response = self.__autotest_api.adapters_auto_tests_post(
|
|
473
475
|
adapters_auto_tests_post_request=model)
|
|
474
476
|
|
|
@@ -496,6 +498,7 @@ class ApiClientWorker:
|
|
|
496
498
|
model = Converter.prepare_to_update_autotest(test_result, autotest, self.__config.get_project_id())
|
|
497
499
|
|
|
498
500
|
try:
|
|
501
|
+
HtmlEscapeUtils.escape_html_in_object(model)
|
|
499
502
|
self.__autotest_api.adapters_auto_tests_put(adapters_auto_tests_put_request=model)
|
|
500
503
|
except Exception as exc:
|
|
501
504
|
if is_retriable_connection_error(exc):
|
|
@@ -562,6 +565,7 @@ class ApiClientWorker:
|
|
|
562
565
|
self.__config.get_configuration_id(),
|
|
563
566
|
self.__status_codes)
|
|
564
567
|
|
|
568
|
+
HtmlEscapeUtils.escape_html_in_object(model)
|
|
565
569
|
response = self.__test_run_api.adapters_test_runs_id_test_results_post(
|
|
566
570
|
id=self.__config.get_test_run_id(),
|
|
567
571
|
auto_test_results_for_test_run_model=[model])
|
|
@@ -156,7 +156,7 @@ class BulkAutotestHelper:
|
|
|
156
156
|
def __create_tests(self, autotests_for_create: List[AutoTestCreateApiModel]):
|
|
157
157
|
# logging.debug(f'Creating autotests: "{autotests_for_create}')
|
|
158
158
|
|
|
159
|
-
autotests_for_create = HtmlEscapeUtils.
|
|
159
|
+
autotests_for_create = HtmlEscapeUtils.escape_html_in_object_list(autotests_for_create)
|
|
160
160
|
self.__autotests_api.adapters_auto_tests_bulk_post(auto_test_create_api_model=autotests_for_create)
|
|
161
161
|
|
|
162
162
|
logging.debug(f'Autotests were created')
|
|
@@ -165,7 +165,7 @@ class BulkAutotestHelper:
|
|
|
165
165
|
def __update_tests(self, autotests_for_update: List[AutoTestUpdateApiModel]):
|
|
166
166
|
# logging.debug(f'Updating autotests: {autotests_for_update}')
|
|
167
167
|
|
|
168
|
-
autotests_for_update = HtmlEscapeUtils.
|
|
168
|
+
autotests_for_update = HtmlEscapeUtils.escape_html_in_object_list(autotests_for_update)
|
|
169
169
|
self.__autotests_api.adapters_auto_tests_bulk_put(auto_test_update_api_model=autotests_for_update)
|
|
170
170
|
|
|
171
171
|
logging.debug(f'Autotests were updated')
|
|
@@ -174,7 +174,7 @@ class BulkAutotestHelper:
|
|
|
174
174
|
def __load_test_results(self, test_results: List[AutoTestResultsForTestRunModel]):
|
|
175
175
|
# logging.debug(f'Loading test results: {test_results}')
|
|
176
176
|
|
|
177
|
-
test_results = HtmlEscapeUtils.
|
|
177
|
+
test_results = HtmlEscapeUtils.escape_html_in_object_list(test_results)
|
|
178
178
|
self.__test_runs_api.adapters_test_runs_id_test_results_post(
|
|
179
179
|
id=self.__test_run_id,
|
|
180
180
|
auto_test_results_for_test_run_model=test_results)
|
|
@@ -80,7 +80,12 @@ class HtmlEscapeUtils:
|
|
|
80
80
|
return obj
|
|
81
81
|
|
|
82
82
|
try:
|
|
83
|
-
|
|
83
|
+
if isinstance(obj, list):
|
|
84
|
+
HtmlEscapeUtils._process_list(obj)
|
|
85
|
+
elif isinstance(obj, dict):
|
|
86
|
+
HtmlEscapeUtils._process_dict(obj)
|
|
87
|
+
else:
|
|
88
|
+
HtmlEscapeUtils._process_object_attributes(obj)
|
|
84
89
|
except Exception as e:
|
|
85
90
|
# Silently ignore reflection errors
|
|
86
91
|
logging.debug(f"Error processing object attributes: {e}")
|
|
@@ -90,7 +95,7 @@ class HtmlEscapeUtils:
|
|
|
90
95
|
@staticmethod
|
|
91
96
|
def escape_html_in_object_list(obj_list: Optional[List[Any]]) -> Optional[List[Any]]:
|
|
92
97
|
"""
|
|
93
|
-
Escapes HTML tags in
|
|
98
|
+
Escapes HTML tags in list items: strings in-place, objects via reflection.
|
|
94
99
|
Can be disabled by setting NO_ESCAPE_HTML environment variable to "true".
|
|
95
100
|
|
|
96
101
|
Args:
|
|
@@ -106,47 +111,68 @@ class HtmlEscapeUtils:
|
|
|
106
111
|
no_escape_html = os.environ.get(HtmlEscapeUtils.NO_ESCAPE_HTML_ENV_VAR, "").lower()
|
|
107
112
|
if no_escape_html == "true":
|
|
108
113
|
return obj_list
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
HtmlEscapeUtils.escape_html_in_object(obj)
|
|
112
|
-
|
|
114
|
+
|
|
115
|
+
HtmlEscapeUtils._process_list(obj_list)
|
|
113
116
|
return obj_list
|
|
114
117
|
|
|
118
|
+
@staticmethod
|
|
119
|
+
def _process_dict(obj: dict) -> None:
|
|
120
|
+
for key, value in obj.items():
|
|
121
|
+
if isinstance(value, str):
|
|
122
|
+
obj[key] = HtmlEscapeUtils.escape_html_tags(value)
|
|
123
|
+
elif isinstance(value, list):
|
|
124
|
+
HtmlEscapeUtils._process_list(value)
|
|
125
|
+
elif isinstance(value, dict):
|
|
126
|
+
HtmlEscapeUtils._process_dict(value)
|
|
127
|
+
elif value is not None and not HtmlEscapeUtils._is_simple_type(type(value)):
|
|
128
|
+
HtmlEscapeUtils.escape_html_in_object(value)
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def _iter_object_attr_names(obj: Any):
|
|
132
|
+
"""
|
|
133
|
+
OpenAPI models store fields in attribute_map/_data_store; they are not listed by dir().
|
|
134
|
+
Prefer those maps, fall back to public dir() attributes for plain objects.
|
|
135
|
+
"""
|
|
136
|
+
attribute_map = getattr(obj, 'attribute_map', None)
|
|
137
|
+
if isinstance(attribute_map, dict) and attribute_map:
|
|
138
|
+
return attribute_map.keys()
|
|
139
|
+
|
|
140
|
+
data_store = getattr(obj, '_data_store', None)
|
|
141
|
+
if isinstance(data_store, dict) and data_store:
|
|
142
|
+
return data_store.keys()
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
attr_name for attr_name in dir(obj)
|
|
146
|
+
if not attr_name.startswith('_') and not callable(getattr(obj, attr_name, None))
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
@staticmethod
|
|
150
|
+
def _should_skip_attr(attr_name: str) -> bool:
|
|
151
|
+
return (
|
|
152
|
+
attr_name.startswith('_')
|
|
153
|
+
or attr_name.startswith("external_id")
|
|
154
|
+
or attr_name.startswith("externalId")
|
|
155
|
+
or attr_name.startswith("auto_test_external_id")
|
|
156
|
+
or attr_name.startswith("autoTestExternalId")
|
|
157
|
+
)
|
|
158
|
+
|
|
115
159
|
@staticmethod
|
|
116
160
|
def _process_object_attributes(obj: Any) -> None:
|
|
117
161
|
"""
|
|
118
162
|
Process all attributes of an object for HTML escaping.
|
|
119
163
|
"""
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
attr_name.startswith("external_id")
|
|
128
|
-
or attr_name.startswith("externalId")
|
|
129
|
-
or attr_name.startswith("auto_test_external_id")
|
|
130
|
-
or attr_name.startswith("autoTestExternalId")
|
|
131
|
-
):
|
|
164
|
+
for attr_name in HtmlEscapeUtils._iter_object_attr_names(obj):
|
|
165
|
+
if HtmlEscapeUtils._should_skip_attr(attr_name):
|
|
166
|
+
continue
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
value = getattr(obj, attr_name, None)
|
|
170
|
+
if callable(value):
|
|
132
171
|
continue
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
except Exception as e:
|
|
138
|
-
# Silently ignore attribute errors
|
|
139
|
-
logging.debug(f"Error processing attribute {attr_name}: {e}")
|
|
140
|
-
|
|
141
|
-
# Handle dictionary objects
|
|
142
|
-
elif isinstance(obj, dict):
|
|
143
|
-
for key, value in obj.items():
|
|
144
|
-
if isinstance(value, str):
|
|
145
|
-
obj[key] = HtmlEscapeUtils.escape_html_tags(value)
|
|
146
|
-
elif isinstance(value, list):
|
|
147
|
-
HtmlEscapeUtils._process_list(value)
|
|
148
|
-
elif not HtmlEscapeUtils._is_simple_type(type(value)):
|
|
149
|
-
HtmlEscapeUtils.escape_html_in_object(value)
|
|
172
|
+
HtmlEscapeUtils._process_attribute_value(obj, attr_name, value)
|
|
173
|
+
except Exception as e:
|
|
174
|
+
# Silently ignore attribute errors
|
|
175
|
+
logging.debug(f"Error processing attribute {attr_name}: {e}")
|
|
150
176
|
|
|
151
177
|
@staticmethod
|
|
152
178
|
def _process_attribute_value(obj: Any, attr_name: str, value: Any) -> None:
|
|
@@ -162,6 +188,8 @@ class HtmlEscapeUtils:
|
|
|
162
188
|
pass
|
|
163
189
|
elif isinstance(value, list):
|
|
164
190
|
HtmlEscapeUtils._process_list(value)
|
|
191
|
+
elif isinstance(value, dict):
|
|
192
|
+
HtmlEscapeUtils._process_dict(value)
|
|
165
193
|
elif value is not None and not HtmlEscapeUtils._is_simple_type(type(value)):
|
|
166
194
|
# Process nested objects (but not simple types)
|
|
167
195
|
HtmlEscapeUtils.escape_html_in_object(value)
|
|
@@ -275,4 +275,5 @@ src/testit_python_commons/utils/__init__.py
|
|
|
275
275
|
src/testit_python_commons/utils/html_escape_utils.py
|
|
276
276
|
tests/test_app_properties.py
|
|
277
277
|
tests/test_dynamic_methods.py
|
|
278
|
-
tests/test_html_escape_utils.py
|
|
278
|
+
tests/test_html_escape_utils.py
|
|
279
|
+
tests/test_xss_parameters_escape.py
|
|
@@ -101,6 +101,32 @@ class TestHtmlEscapeUtils(unittest.TestCase):
|
|
|
101
101
|
self.assertEqual(result[0].description, "<div>content</div>")
|
|
102
102
|
self.assertEqual(result[1].description, "<span>more</span>")
|
|
103
103
|
|
|
104
|
+
def test_escape_html_in_object_accepts_list(self):
|
|
105
|
+
"""Bulk send path passes a list — must escape each item, not no-op."""
|
|
106
|
+
test_list = [
|
|
107
|
+
SampleData("First", "<script>alert(1)</script>"),
|
|
108
|
+
SampleData("Second", "<img src=x onerror=alert(1)>"),
|
|
109
|
+
]
|
|
110
|
+
result = HtmlEscapeUtils.escape_html_in_object(test_list)
|
|
111
|
+
|
|
112
|
+
self.assertEqual(result[0].description, "<script>alert(1)</script>")
|
|
113
|
+
self.assertEqual(result[1].description, "<img src=x onerror=alert(1)>")
|
|
114
|
+
|
|
115
|
+
def test_escape_html_in_list_of_strings(self):
|
|
116
|
+
tags = ["<script>alert(1)</script>", "safe", "<b>x</b>"]
|
|
117
|
+
result = HtmlEscapeUtils.escape_html_in_object(tags)
|
|
118
|
+
|
|
119
|
+
self.assertEqual(result[0], "<script>alert(1)</script>")
|
|
120
|
+
self.assertEqual(result[1], "safe")
|
|
121
|
+
self.assertEqual(result[2], "<b>x</b>")
|
|
122
|
+
|
|
123
|
+
def test_escape_html_in_list_of_dicts(self):
|
|
124
|
+
labels = [{"name": "<script>alert(1)</script>"}, {"name": "ok"}]
|
|
125
|
+
result = HtmlEscapeUtils.escape_html_in_object(labels)
|
|
126
|
+
|
|
127
|
+
self.assertEqual(result[0]["name"], "<script>alert(1)</script>")
|
|
128
|
+
self.assertEqual(result[1]["name"], "ok")
|
|
129
|
+
|
|
104
130
|
def test_escape_disabled_by_env_var(self):
|
|
105
131
|
"""Test that escaping can be disabled via environment variable"""
|
|
106
132
|
os.environ[HtmlEscapeUtils.NO_ESCAPE_HTML_ENV_VAR] = "true"
|
|
@@ -131,6 +157,25 @@ class TestHtmlEscapeUtils(unittest.TestCase):
|
|
|
131
157
|
self.assertEqual(result["tags"][0], "<tag>")
|
|
132
158
|
self.assertEqual(result["tags"][1], "normal_tag")
|
|
133
159
|
|
|
160
|
+
def test_escape_openapi_model_parameters(self):
|
|
161
|
+
"""OpenAPI models hide fields from dir(); parameters must still be escaped."""
|
|
162
|
+
from adapters_api.models import AutoTestResultsForTestRunModel, TestStatusType
|
|
163
|
+
|
|
164
|
+
model = AutoTestResultsForTestRunModel(
|
|
165
|
+
configuration_id="cfg",
|
|
166
|
+
auto_test_external_id="ext",
|
|
167
|
+
status_type=TestStatusType("Succeeded"),
|
|
168
|
+
parameters={"description": '<script>alert("1")</script>'},
|
|
169
|
+
message='<img src=x onerror=alert(1)>',
|
|
170
|
+
)
|
|
171
|
+
HtmlEscapeUtils.escape_html_in_object(model)
|
|
172
|
+
|
|
173
|
+
self.assertEqual(
|
|
174
|
+
model.parameters["description"],
|
|
175
|
+
'<script>alert("1")</script>',
|
|
176
|
+
)
|
|
177
|
+
self.assertEqual(model.message, "<img src=x onerror=alert(1)>")
|
|
178
|
+
|
|
134
179
|
|
|
135
180
|
if __name__ == '__main__':
|
|
136
181
|
unittest.main()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Regression: XSS in pytest params must be escaped before TMS API payloads."""
|
|
2
|
+
|
|
3
|
+
import importlib.util
|
|
4
|
+
import unittest
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from adapters_api import ApiClient
|
|
8
|
+
from testit_python_commons.client.converter import Converter
|
|
9
|
+
from testit_python_commons.models.test_result import TestResult
|
|
10
|
+
from testit_python_commons.utils.html_escape_utils import HtmlEscapeUtils
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _load_xss_payloads():
|
|
14
|
+
path = Path(__file__).resolve().parents[2] / "test_files" / "test_xss_parametrize.py"
|
|
15
|
+
spec = importlib.util.spec_from_file_location("test_xss_parametrize", path)
|
|
16
|
+
module = importlib.util.module_from_spec(spec)
|
|
17
|
+
spec.loader.exec_module(module)
|
|
18
|
+
return module.XSS_PAYLOADS
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestXssParametersEscape(unittest.TestCase):
|
|
22
|
+
@classmethod
|
|
23
|
+
def setUpClass(cls):
|
|
24
|
+
cls.payloads = _load_xss_payloads()
|
|
25
|
+
|
|
26
|
+
def test_test_result_parameters_escaped_for_all_payloads(self):
|
|
27
|
+
for payload in self.payloads:
|
|
28
|
+
with self.subTest(payload=payload):
|
|
29
|
+
result = TestResult().set_parameters({"description": payload})
|
|
30
|
+
value = result.get_parameters()["description"]
|
|
31
|
+
if HtmlEscapeUtils._HTML_TAG_PATTERN.search(payload):
|
|
32
|
+
self.assertNotIn("<script", value.lower().replace("<", ""))
|
|
33
|
+
self.assertIn("<", value)
|
|
34
|
+
self.assertNotEqual(value, payload)
|
|
35
|
+
# API model must keep escaped value
|
|
36
|
+
model = Converter.test_result_to_testrun_result_post_model(
|
|
37
|
+
result.set_external_id("ext").set_outcome("Passed").set_status_type("Succeeded").set_duration(1),
|
|
38
|
+
"cfg",
|
|
39
|
+
["PASSED"],
|
|
40
|
+
)
|
|
41
|
+
self.assertEqual(model.parameters["description"], value)
|
|
42
|
+
serialized = ApiClient.sanitize_for_serialization(model)
|
|
43
|
+
self.assertEqual(serialized["parameters"]["description"], value)
|
|
44
|
+
|
|
45
|
+
def test_external_key_with_nodeid_xss_is_escaped(self):
|
|
46
|
+
payload = '<script>alert("1")</script>'
|
|
47
|
+
node_key = f"tests and test_xss_parametrize.py and test_05_with_chg_xss[{payload}]"
|
|
48
|
+
result = TestResult().set_external_key(node_key)
|
|
49
|
+
escaped = result.get_external_key()
|
|
50
|
+
self.assertIn("<script>", escaped)
|
|
51
|
+
self.assertNotIn("<script>", escaped)
|
|
52
|
+
|
|
53
|
+
def test_bulk_list_escape_mutates_result_models(self):
|
|
54
|
+
payload = '<script>alert("1")</script>'
|
|
55
|
+
# Simulate model built WITHOUT going through TestResult setters (raw params)
|
|
56
|
+
class FakeResult:
|
|
57
|
+
def __init__(self):
|
|
58
|
+
self.parameters = {"description": payload}
|
|
59
|
+
self.message = payload
|
|
60
|
+
|
|
61
|
+
models = [FakeResult(), FakeResult()]
|
|
62
|
+
HtmlEscapeUtils.escape_html_in_object(models)
|
|
63
|
+
for model in models:
|
|
64
|
+
self.assertEqual(
|
|
65
|
+
model.parameters["description"],
|
|
66
|
+
'<script>alert("1")</script>',
|
|
67
|
+
)
|
|
68
|
+
self.assertEqual(model.message, '<script>alert("1")</script>')
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/__init__.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/attachments_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/auto_tests_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/parameters_api.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/projects_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/sections_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/test_results_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/test_runs_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/work_items_api.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/api/workflows_api.py
RENAMED
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/apis/__init__.py
RENAMED
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{testit_python_commons-5.2.0 → testit_python_commons-5.2.1}/src/adapters_api/model/auto_test_step.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|