From 30f8a79e81cb884de3284e1e67adff0013cebb2c Mon Sep 17 00:00:00 2001 From: Dmitrii Gridnev Date: Thu, 3 Jul 2025 15:30:05 +0300 Subject: [PATCH] chore: update version to 1.2.3 and add new models for external issues - Updated version to 1.2.3 in pyproject.toml. - Added new models: RunExternalIssue, RunexternalIssues, RunexternalIssuesLinksInner, and Runupdate to support external issue linking. - Enhanced Run model to include configurations and external issue properties. - Updated documentation for new models and their usage in the API. --- .../docs/AttachmentListResponseAllOfResult.md | 3 +- qase-api-client/docs/Run.md | 2 + qase-api-client/docs/RunExternalIssue.md | 31 + qase-api-client/docs/RunexternalIssues.md | 30 + .../docs/RunexternalIssuesLinksInner.md | 30 + qase-api-client/docs/RunsApi.md | 183 ++++- qase-api-client/docs/Runupdate.md | 36 + qase-api-client/docs/TestCaseCreate.md | 1 - .../docs/TestCasebulkCasesInner.md | 1 - qase-api-client/pyproject.toml | 2 +- .../src/qase/api_client_v1/__init__.py | 4 + .../src/qase/api_client_v1/api/runs_api.py | 637 +++++++++++++++++- .../src/qase/api_client_v1/models/__init__.py | 4 + .../src/qase/api_client_v1/models/run.py | 17 +- .../models/run_external_issue.py | 92 +++ .../models/runexternal_issues.py | 105 +++ .../models/runexternal_issues_links_inner.py | 96 +++ .../qase/api_client_v1/models/runupdate.py | 138 ++++ .../api_client_v1/models/test_case_create.py | 4 +- .../models/test_casebulk_cases_inner.py | 4 +- 20 files changed, 1391 insertions(+), 29 deletions(-) create mode 100644 qase-api-client/docs/RunExternalIssue.md create mode 100644 qase-api-client/docs/RunexternalIssues.md create mode 100644 qase-api-client/docs/RunexternalIssuesLinksInner.md create mode 100644 qase-api-client/docs/Runupdate.md create mode 100644 qase-api-client/src/qase/api_client_v1/models/run_external_issue.py create mode 100644 qase-api-client/src/qase/api_client_v1/models/runexternal_issues.py create mode 100644 qase-api-client/src/qase/api_client_v1/models/runexternal_issues_links_inner.py create mode 100644 qase-api-client/src/qase/api_client_v1/models/runupdate.py diff --git a/qase-api-client/docs/AttachmentListResponseAllOfResult.md b/qase-api-client/docs/AttachmentListResponseAllOfResult.md index 7d6a7583..20fe2718 100644 --- a/qase-api-client/docs/AttachmentListResponseAllOfResult.md +++ b/qase-api-client/docs/AttachmentListResponseAllOfResult.md @@ -25,8 +25,7 @@ print(AttachmentListResponseAllOfResult.to_json()) # convert the object into a dict attachment_list_response_all_of_result_dict = attachment_list_response_all_of_result_instance.to_dict() # create an instance of AttachmentListResponseAllOfResult from a dict -attachment_list_response_all_of_result_form_dict = attachment_list_response_all_of_result.from_dict( - attachment_list_response_all_of_result_dict) +attachment_list_response_all_of_result_form_dict = attachment_list_response_all_of_result.from_dict(attachment_list_response_all_of_result_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/qase-api-client/docs/Run.md b/qase-api-client/docs/Run.md index f3c7c35f..81d9b443 100644 --- a/qase-api-client/docs/Run.md +++ b/qase-api-client/docs/Run.md @@ -23,6 +23,8 @@ Name | Type | Description | Notes **tags** | [**List[TagValue]**](TagValue.md) | | [optional] **cases** | **List[int]** | | [optional] **plan_id** | **int** | | [optional] +**configurations** | **List[int]** | | [optional] +**external_issue** | [**RunExternalIssue**](RunExternalIssue.md) | | [optional] ## Example diff --git a/qase-api-client/docs/RunExternalIssue.md b/qase-api-client/docs/RunExternalIssue.md new file mode 100644 index 00000000..dfc9a581 --- /dev/null +++ b/qase-api-client/docs/RunExternalIssue.md @@ -0,0 +1,31 @@ +# RunExternalIssue + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**id** | **str** | | [optional] +**type** | **str** | | [optional] +**link** | **str** | | [optional] + +## Example + +```python +from qase.api_client_v1.models.run_external_issue import RunExternalIssue + +# TODO update the JSON string below +json = "{}" +# create an instance of RunExternalIssue from a JSON string +run_external_issue_instance = RunExternalIssue.from_json(json) +# print the JSON string representation of the object +print(RunExternalIssue.to_json()) + +# convert the object into a dict +run_external_issue_dict = run_external_issue_instance.to_dict() +# create an instance of RunExternalIssue from a dict +run_external_issue_form_dict = run_external_issue.from_dict(run_external_issue_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/qase-api-client/docs/RunexternalIssues.md b/qase-api-client/docs/RunexternalIssues.md new file mode 100644 index 00000000..5f3836a3 --- /dev/null +++ b/qase-api-client/docs/RunexternalIssues.md @@ -0,0 +1,30 @@ +# RunexternalIssues + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**type** | **str** | | +**links** | [**List[RunexternalIssuesLinksInner]**](RunexternalIssuesLinksInner.md) | Array of external issue links. Each test run (run_id) can have only one external issue link. | + +## Example + +```python +from qase.api_client_v1.models.runexternal_issues import RunexternalIssues + +# TODO update the JSON string below +json = "{}" +# create an instance of RunexternalIssues from a JSON string +runexternal_issues_instance = RunexternalIssues.from_json(json) +# print the JSON string representation of the object +print(RunexternalIssues.to_json()) + +# convert the object into a dict +runexternal_issues_dict = runexternal_issues_instance.to_dict() +# create an instance of RunexternalIssues from a dict +runexternal_issues_form_dict = runexternal_issues.from_dict(runexternal_issues_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/qase-api-client/docs/RunexternalIssuesLinksInner.md b/qase-api-client/docs/RunexternalIssuesLinksInner.md new file mode 100644 index 00000000..8d5cfc21 --- /dev/null +++ b/qase-api-client/docs/RunexternalIssuesLinksInner.md @@ -0,0 +1,30 @@ +# RunexternalIssuesLinksInner + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**run_id** | **int** | | +**external_issue** | **str** | An external issue identifier, e.g. \"PROJ-1234\". Or null if you want to remove the link. | [optional] + +## Example + +```python +from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner + +# TODO update the JSON string below +json = "{}" +# create an instance of RunexternalIssuesLinksInner from a JSON string +runexternal_issues_links_inner_instance = RunexternalIssuesLinksInner.from_json(json) +# print the JSON string representation of the object +print(RunexternalIssuesLinksInner.to_json()) + +# convert the object into a dict +runexternal_issues_links_inner_dict = runexternal_issues_links_inner_instance.to_dict() +# create an instance of RunexternalIssuesLinksInner from a dict +runexternal_issues_links_inner_form_dict = runexternal_issues_links_inner.from_dict(runexternal_issues_links_inner_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/qase-api-client/docs/RunsApi.md b/qase-api-client/docs/RunsApi.md index 2ac790e8..402665bc 100644 --- a/qase-api-client/docs/RunsApi.md +++ b/qase-api-client/docs/RunsApi.md @@ -9,6 +9,8 @@ Method | HTTP request | Description [**delete_run**](RunsApi.md#delete_run) | **DELETE** /run/{code}/{id} | Delete run [**get_run**](RunsApi.md#get_run) | **GET** /run/{code}/{id} | Get a specific run [**get_runs**](RunsApi.md#get_runs) | **GET** /run/{code} | Get all runs +[**run_update_external_issue**](RunsApi.md#run_update_external_issue) | **POST** /run/{code}/external-issue | Update external issues for runs +[**update_run**](RunsApi.md#update_run) | **PATCH** /run/{code}/{id} | Update a specific run [**update_run_publicity**](RunsApi.md#update_run_publicity) | **PATCH** /run/{code}/{id}/public | Update publicity of a specific run @@ -313,7 +315,7 @@ with qase.api_client_v1.ApiClient(configuration) as api_client: api_instance = qase.api_client_v1.RunsApi(api_client) code = 'code_example' # str | Code of project, where to search entities. id = 56 # int | Identifier. - include = 'include_example' # str | Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects (optional) + include = 'include_example' # str | Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue (optional) try: # Get a specific run @@ -333,7 +335,7 @@ Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **code** | **str**| Code of project, where to search entities. | **id** | **int**| Identifier. | - **include** | **str**| Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects | [optional] + **include** | **str**| Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue | [optional] ### Return type @@ -408,7 +410,7 @@ with qase.api_client_v1.ApiClient(configuration) as api_client: to_start_time = 56 # int | (optional) limit = 10 # int | A number of entities in result set. (optional) (default to 10) offset = 0 # int | How many entities should be skipped. (optional) (default to 0) - include = 'include_example' # str | Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects (optional) + include = 'include_example' # str | Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue (optional) try: # Get all runs @@ -435,7 +437,7 @@ Name | Type | Description | Notes **to_start_time** | **int**| | [optional] **limit** | **int**| A number of entities in result set. | [optional] [default to 10] **offset** | **int**| How many entities should be skipped. | [optional] [default to 0] - **include** | **str**| Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects | [optional] + **include** | **str**| Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue | [optional] ### Return type @@ -463,6 +465,179 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) +# **run_update_external_issue** +> run_update_external_issue(code, runexternal_issues) + +Update external issues for runs + +This method allows you to update links between test runs and external issues (such as Jira tickets). You can use this endpoint to: - Link test runs to external issues by providing the external issue identifier (e.g., \"PROJ-1234\") - Update existing links by providing a new external issue identifier - Remove existing links by setting the external_issue field to null **Important**: Each test run can have only one link with an external issue. If a test run already has an external issue link, providing a new external_issue value will replace the existing link. The endpoint supports both Jira Cloud and Jira Server integrations. Each request can update multiple test run links in a single operation. + +### Example + +* Api Key Authentication (TokenAuth): + +```python +import qase.api_client_v1 +from qase.api_client_v1.models.runexternal_issues import RunexternalIssues +from qase.api_client_v1.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.qase.io/v1 +# See configuration.py for a list of all supported configuration parameters. +configuration = qase.api_client_v1.Configuration( + host = "https://api.qase.io/v1" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: TokenAuth +configuration.api_key['TokenAuth'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['TokenAuth'] = 'Bearer' + +# Enter a context with an instance of the API client +with qase.api_client_v1.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = qase.api_client_v1.RunsApi(api_client) + code = 'code_example' # str | Code of project, where to search entities. + runexternal_issues = qase.api_client_v1.RunexternalIssues() # RunexternalIssues | + + try: + # Update external issues for runs + api_instance.run_update_external_issue(code, runexternal_issues) + except Exception as e: + print("Exception when calling RunsApi->run_update_external_issue: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **code** | **str**| Code of project, where to search entities. | + **runexternal_issues** | [**RunexternalIssues**](RunexternalIssues.md)| | + +### Return type + +void (empty response body) + +### Authorization + +[TokenAuth](../README.md#TokenAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | OK. | - | +**400** | Bad Request. | - | +**401** | Unauthorized. | - | +**403** | Forbidden. | - | +**404** | Not Found. | - | +**429** | Too Many Requests. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **update_run** +> BaseResponse update_run(code, id, runupdate) + +Update a specific run + +This method allows to update a specific run. + +### Example + +* Api Key Authentication (TokenAuth): + +```python +import qase.api_client_v1 +from qase.api_client_v1.models.base_response import BaseResponse +from qase.api_client_v1.models.runupdate import Runupdate +from qase.api_client_v1.rest import ApiException +from pprint import pprint + +# Defining the host is optional and defaults to https://api.qase.io/v1 +# See configuration.py for a list of all supported configuration parameters. +configuration = qase.api_client_v1.Configuration( + host = "https://api.qase.io/v1" +) + +# The client must configure the authentication and authorization parameters +# in accordance with the API server security policy. +# Examples for each auth method are provided below, use the example that +# satisfies your auth use case. + +# Configure API key authorization: TokenAuth +configuration.api_key['TokenAuth'] = os.environ["API_KEY"] + +# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed +# configuration.api_key_prefix['TokenAuth'] = 'Bearer' + +# Enter a context with an instance of the API client +with qase.api_client_v1.ApiClient(configuration) as api_client: + # Create an instance of the API class + api_instance = qase.api_client_v1.RunsApi(api_client) + code = 'code_example' # str | Code of project, where to search entities. + id = 56 # int | Identifier. + runupdate = qase.api_client_v1.Runupdate() # Runupdate | + + try: + # Update a specific run + api_response = api_instance.update_run(code, id, runupdate) + print("The response of RunsApi->update_run:\n") + pprint(api_response) + except Exception as e: + print("Exception when calling RunsApi->update_run: %s\n" % e) +``` + + + +### Parameters + + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **code** | **str**| Code of project, where to search entities. | + **id** | **int**| Identifier. | + **runupdate** | [**Runupdate**](Runupdate.md)| | + +### Return type + +[**BaseResponse**](BaseResponse.md) + +### Authorization + +[TokenAuth](../README.md#TokenAuth) + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: application/json + +### HTTP response details + +| Status code | Description | Response headers | +|-------------|-------------|------------------| +**200** | A result. | - | +**400** | Bad Request. | - | +**401** | Unauthorized. | - | +**403** | Forbidden. | - | +**404** | Not Found. | - | +**429** | Too Many Requests. | - | + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + # **update_run_publicity** > RunPublicResponse update_run_publicity(code, id, run_public) diff --git a/qase-api-client/docs/Runupdate.md b/qase-api-client/docs/Runupdate.md new file mode 100644 index 00000000..5b876ae9 --- /dev/null +++ b/qase-api-client/docs/Runupdate.md @@ -0,0 +1,36 @@ +# Runupdate + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**title** | **str** | | [optional] +**description** | **str** | | [optional] +**environment_id** | **int** | | [optional] +**environment_slug** | **str** | | [optional] +**milestone_id** | **int** | | [optional] +**tags** | **List[str]** | | [optional] +**configurations** | **List[int]** | | [optional] +**custom_field** | **Dict[str, str]** | A map of custom fields values (id => value) | [optional] + +## Example + +```python +from qase.api_client_v1.models.runupdate import Runupdate + +# TODO update the JSON string below +json = "{}" +# create an instance of Runupdate from a JSON string +runupdate_instance = Runupdate.from_json(json) +# print the JSON string representation of the object +print(Runupdate.to_json()) + +# convert the object into a dict +runupdate_dict = runupdate_instance.to_dict() +# create an instance of Runupdate from a dict +runupdate_form_dict = runupdate.from_dict(runupdate_dict) +``` +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/qase-api-client/docs/TestCaseCreate.md b/qase-api-client/docs/TestCaseCreate.md index 832f95eb..fc57290d 100644 --- a/qase-api-client/docs/TestCaseCreate.md +++ b/qase-api-client/docs/TestCaseCreate.md @@ -15,7 +15,6 @@ Name | Type | Description | Notes **type** | **int** | | [optional] **layer** | **int** | | [optional] **is_flaky** | **int** | | [optional] -**author_id** | **int** | | [optional] **suite_id** | **int** | | [optional] **milestone_id** | **int** | | [optional] **automation** | **int** | | [optional] diff --git a/qase-api-client/docs/TestCasebulkCasesInner.md b/qase-api-client/docs/TestCasebulkCasesInner.md index 9d4c566f..59af566b 100644 --- a/qase-api-client/docs/TestCasebulkCasesInner.md +++ b/qase-api-client/docs/TestCasebulkCasesInner.md @@ -15,7 +15,6 @@ Name | Type | Description | Notes **type** | **int** | | [optional] **layer** | **int** | | [optional] **is_flaky** | **int** | | [optional] -**author_id** | **int** | | [optional] **suite_id** | **int** | | [optional] **milestone_id** | **int** | | [optional] **automation** | **int** | | [optional] diff --git a/qase-api-client/pyproject.toml b/qase-api-client/pyproject.toml index 4bb34614..edb5794c 100644 --- a/qase-api-client/pyproject.toml +++ b/qase-api-client/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "qase-api-client" -version = "1.2.2" +version = "1.2.3" description = "Qase TestOps API V1 client for Python" readme = "README.md" authors = [{name = "Qase Team", email = "support@qase.io"}] diff --git a/qase-api-client/src/qase/api_client_v1/__init__.py b/qase-api-client/src/qase/api_client_v1/__init__.py index 5749c3ab..6f966510 100644 --- a/qase-api-client/src/qase/api_client_v1/__init__.py +++ b/qase-api-client/src/qase/api_client_v1/__init__.py @@ -144,6 +144,7 @@ from qase.api_client_v1.models.run import Run from qase.api_client_v1.models.run_create import RunCreate from qase.api_client_v1.models.run_environment import RunEnvironment +from qase.api_client_v1.models.run_external_issue import RunExternalIssue from qase.api_client_v1.models.run_list_response import RunListResponse from qase.api_client_v1.models.run_list_response_all_of_result import RunListResponseAllOfResult from qase.api_client_v1.models.run_milestone import RunMilestone @@ -153,6 +154,9 @@ from qase.api_client_v1.models.run_query import RunQuery from qase.api_client_v1.models.run_response import RunResponse from qase.api_client_v1.models.run_stats import RunStats +from qase.api_client_v1.models.runexternal_issues import RunexternalIssues +from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner +from qase.api_client_v1.models.runupdate import Runupdate from qase.api_client_v1.models.search_response import SearchResponse from qase.api_client_v1.models.search_response_all_of_result import SearchResponseAllOfResult from qase.api_client_v1.models.search_response_all_of_result_entities import SearchResponseAllOfResultEntities diff --git a/qase-api-client/src/qase/api_client_v1/api/runs_api.py b/qase-api-client/src/qase/api_client_v1/api/runs_api.py index c3e17769..b1b73218 100644 --- a/qase-api-client/src/qase/api_client_v1/api/runs_api.py +++ b/qase-api-client/src/qase/api_client_v1/api/runs_api.py @@ -27,6 +27,8 @@ from qase.api_client_v1.models.run_public import RunPublic from qase.api_client_v1.models.run_public_response import RunPublicResponse from qase.api_client_v1.models.run_response import RunResponse +from qase.api_client_v1.models.runexternal_issues import RunexternalIssues +from qase.api_client_v1.models.runupdate import Runupdate from qase.api_client_v1.api_client import ApiClient, RequestSerialized from qase.api_client_v1.api_response import ApiResponse @@ -934,7 +936,7 @@ def get_run( self, code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], id: Annotated[StrictInt, Field(description="Identifier.")], - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -956,7 +958,7 @@ def get_run( :type code: str :param id: Identifier. (required) :type id: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1014,7 +1016,7 @@ def get_run_with_http_info( self, code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], id: Annotated[StrictInt, Field(description="Identifier.")], - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1036,7 +1038,7 @@ def get_run_with_http_info( :type code: str :param id: Identifier. (required) :type id: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1094,7 +1096,7 @@ def get_run_without_preload_content( self, code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], id: Annotated[StrictInt, Field(description="Identifier.")], - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1116,7 +1118,7 @@ def get_run_without_preload_content( :type code: str :param id: Identifier. (required) :type id: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1246,7 +1248,7 @@ def get_runs( to_start_time: Optional[StrictInt] = None, limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="A number of entities in result set.")] = None, offset: Annotated[Optional[Annotated[int, Field(le=100000, strict=True, ge=0)]], Field(description="How many entities should be skipped.")] = None, - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1282,7 +1284,7 @@ def get_runs( :type limit: int :param offset: How many entities should be skipped. :type offset: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1354,7 +1356,7 @@ def get_runs_with_http_info( to_start_time: Optional[StrictInt] = None, limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="A number of entities in result set.")] = None, offset: Annotated[Optional[Annotated[int, Field(le=100000, strict=True, ge=0)]], Field(description="How many entities should be skipped.")] = None, - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1390,7 +1392,7 @@ def get_runs_with_http_info( :type limit: int :param offset: How many entities should be skipped. :type offset: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1462,7 +1464,7 @@ def get_runs_without_preload_content( to_start_time: Optional[StrictInt] = None, limit: Annotated[Optional[Annotated[int, Field(le=100, strict=True, ge=1)]], Field(description="A number of entities in result set.")] = None, offset: Annotated[Optional[Annotated[int, Field(le=100000, strict=True, ge=0)]], Field(description="How many entities should be skipped.")] = None, - include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects ")] = None, + include: Annotated[Optional[StrictStr], Field(description="Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue ")] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -1498,7 +1500,7 @@ def get_runs_without_preload_content( :type limit: int :param offset: How many entities should be skipped. :type offset: int - :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects + :param include: Include a list of related entities IDs into response. Should be separated by comma. Possible values: cases, defects, external_issue :type include: str :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -1660,6 +1662,617 @@ def _get_runs_serialize( + @validate_call + def run_update_external_issue( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + runexternal_issues: RunexternalIssues, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Update external issues for runs + + This method allows you to update links between test runs and external issues (such as Jira tickets). You can use this endpoint to: - Link test runs to external issues by providing the external issue identifier (e.g., \"PROJ-1234\") - Update existing links by providing a new external issue identifier - Remove existing links by setting the external_issue field to null **Important**: Each test run can have only one link with an external issue. If a test run already has an external issue link, providing a new external_issue value will replace the existing link. The endpoint supports both Jira Cloud and Jira Server integrations. Each request can update multiple test run links in a single operation. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param runexternal_issues: (required) + :type runexternal_issues: RunexternalIssues + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._run_update_external_issue_serialize( + code=code, + runexternal_issues=runexternal_issues, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': None, + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def run_update_external_issue_with_http_info( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + runexternal_issues: RunexternalIssues, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Update external issues for runs + + This method allows you to update links between test runs and external issues (such as Jira tickets). You can use this endpoint to: - Link test runs to external issues by providing the external issue identifier (e.g., \"PROJ-1234\") - Update existing links by providing a new external issue identifier - Remove existing links by setting the external_issue field to null **Important**: Each test run can have only one link with an external issue. If a test run already has an external issue link, providing a new external_issue value will replace the existing link. The endpoint supports both Jira Cloud and Jira Server integrations. Each request can update multiple test run links in a single operation. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param runexternal_issues: (required) + :type runexternal_issues: RunexternalIssues + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._run_update_external_issue_serialize( + code=code, + runexternal_issues=runexternal_issues, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': None, + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def run_update_external_issue_without_preload_content( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + runexternal_issues: RunexternalIssues, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update external issues for runs + + This method allows you to update links between test runs and external issues (such as Jira tickets). You can use this endpoint to: - Link test runs to external issues by providing the external issue identifier (e.g., \"PROJ-1234\") - Update existing links by providing a new external issue identifier - Remove existing links by setting the external_issue field to null **Important**: Each test run can have only one link with an external issue. If a test run already has an external issue link, providing a new external_issue value will replace the existing link. The endpoint supports both Jira Cloud and Jira Server integrations. Each request can update multiple test run links in a single operation. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param runexternal_issues: (required) + :type runexternal_issues: RunexternalIssues + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._run_update_external_issue_serialize( + code=code, + runexternal_issues=runexternal_issues, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': None, + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _run_update_external_issue_serialize( + self, + code, + runexternal_issues, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, str] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if code is not None: + _path_params['code'] = code + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if runexternal_issues is not None: + _body_params = runexternal_issues + + + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'TokenAuth' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/run/{code}/external-issue', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def update_run( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + id: Annotated[StrictInt, Field(description="Identifier.")], + runupdate: Runupdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> BaseResponse: + """Update a specific run + + This method allows to update a specific run. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param id: Identifier. (required) + :type id: int + :param runupdate: (required) + :type runupdate: Runupdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_run_serialize( + code=code, + id=id, + runupdate=runupdate, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BaseResponse", + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def update_run_with_http_info( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + id: Annotated[StrictInt, Field(description="Identifier.")], + runupdate: Runupdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[BaseResponse]: + """Update a specific run + + This method allows to update a specific run. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param id: Identifier. (required) + :type id: int + :param runupdate: (required) + :type runupdate: Runupdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_run_serialize( + code=code, + id=id, + runupdate=runupdate, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BaseResponse", + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def update_run_without_preload_content( + self, + code: Annotated[str, Field(min_length=2, strict=True, max_length=10, description="Code of project, where to search entities.")], + id: Annotated[StrictInt, Field(description="Identifier.")], + runupdate: Runupdate, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Update a specific run + + This method allows to update a specific run. + + :param code: Code of project, where to search entities. (required) + :type code: str + :param id: Identifier. (required) + :type id: int + :param runupdate: (required) + :type runupdate: Runupdate + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._update_run_serialize( + code=code, + id=id, + runupdate=runupdate, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "BaseResponse", + '400': None, + '401': None, + '403': None, + '404': None, + '429': None, + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _update_run_serialize( + self, + code, + id, + runupdate, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[str, str] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if code is not None: + _path_params['code'] = code + if id is not None: + _path_params['id'] = id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if runupdate is not None: + _body_params = runupdate + + + # set the HTTP header `Accept` + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'TokenAuth' + ] + + return self.api_client.param_serialize( + method='PATCH', + resource_path='/run/{code}/{id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + @validate_call def update_run_publicity( self, diff --git a/qase-api-client/src/qase/api_client_v1/models/__init__.py b/qase-api-client/src/qase/api_client_v1/models/__init__.py index f0f7f816..5fe948f7 100644 --- a/qase-api-client/src/qase/api_client_v1/models/__init__.py +++ b/qase-api-client/src/qase/api_client_v1/models/__init__.py @@ -112,6 +112,7 @@ from qase.api_client_v1.models.run import Run from qase.api_client_v1.models.run_create import RunCreate from qase.api_client_v1.models.run_environment import RunEnvironment +from qase.api_client_v1.models.run_external_issue import RunExternalIssue from qase.api_client_v1.models.run_list_response import RunListResponse from qase.api_client_v1.models.run_list_response_all_of_result import RunListResponseAllOfResult from qase.api_client_v1.models.run_milestone import RunMilestone @@ -121,6 +122,9 @@ from qase.api_client_v1.models.run_query import RunQuery from qase.api_client_v1.models.run_response import RunResponse from qase.api_client_v1.models.run_stats import RunStats +from qase.api_client_v1.models.runexternal_issues import RunexternalIssues +from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner +from qase.api_client_v1.models.runupdate import Runupdate from qase.api_client_v1.models.search_response import SearchResponse from qase.api_client_v1.models.search_response_all_of_result import SearchResponseAllOfResult from qase.api_client_v1.models.search_response_all_of_result_entities import SearchResponseAllOfResultEntities diff --git a/qase-api-client/src/qase/api_client_v1/models/run.py b/qase-api-client/src/qase/api_client_v1/models/run.py index 69de454a..32bb79ea 100644 --- a/qase-api-client/src/qase/api_client_v1/models/run.py +++ b/qase-api-client/src/qase/api_client_v1/models/run.py @@ -23,6 +23,7 @@ from typing import Any, ClassVar, Dict, List, Optional from qase.api_client_v1.models.custom_field_value import CustomFieldValue from qase.api_client_v1.models.run_environment import RunEnvironment +from qase.api_client_v1.models.run_external_issue import RunExternalIssue from qase.api_client_v1.models.run_milestone import RunMilestone from qase.api_client_v1.models.run_stats import RunStats from qase.api_client_v1.models.tag_value import TagValue @@ -51,7 +52,9 @@ class Run(BaseModel): tags: Optional[List[TagValue]] = None cases: Optional[List[StrictInt]] = None plan_id: Optional[StrictInt] = None - __properties: ClassVar[List[str]] = ["id", "run_id", "title", "description", "status", "status_text", "start_time", "end_time", "public", "stats", "time_spent", "elapsed_time", "environment", "milestone", "custom_fields", "tags", "cases", "plan_id"] + configurations: Optional[List[StrictInt]] = None + external_issue: Optional[RunExternalIssue] = None + __properties: ClassVar[List[str]] = ["id", "run_id", "title", "description", "status", "status_text", "start_time", "end_time", "public", "stats", "time_spent", "elapsed_time", "environment", "milestone", "custom_fields", "tags", "cases", "plan_id", "configurations", "external_issue"] model_config = ConfigDict( populate_by_name=True, @@ -115,6 +118,9 @@ def to_dict(self) -> Dict[str, Any]: if _item: _items.append(_item.to_dict()) _dict['tags'] = _items + # override the default output from pydantic by calling `to_dict()` of external_issue + if self.external_issue: + _dict['external_issue'] = self.external_issue.to_dict() # set to None if description (nullable) is None # and model_fields_set contains the field if self.description is None and "description" in self.model_fields_set: @@ -145,6 +151,11 @@ def to_dict(self) -> Dict[str, Any]: if self.plan_id is None and "plan_id" in self.model_fields_set: _dict['plan_id'] = None + # set to None if external_issue (nullable) is None + # and model_fields_set contains the field + if self.external_issue is None and "external_issue" in self.model_fields_set: + _dict['external_issue'] = None + return _dict @classmethod @@ -174,7 +185,9 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "custom_fields": [CustomFieldValue.from_dict(_item) for _item in obj["custom_fields"]] if obj.get("custom_fields") is not None else None, "tags": [TagValue.from_dict(_item) for _item in obj["tags"]] if obj.get("tags") is not None else None, "cases": obj.get("cases"), - "plan_id": obj.get("plan_id") + "plan_id": obj.get("plan_id"), + "configurations": obj.get("configurations"), + "external_issue": RunExternalIssue.from_dict(obj["external_issue"]) if obj.get("external_issue") is not None else None }) return _obj diff --git a/qase-api-client/src/qase/api_client_v1/models/run_external_issue.py b/qase-api-client/src/qase/api_client_v1/models/run_external_issue.py new file mode 100644 index 00000000..e3a38db3 --- /dev/null +++ b/qase-api-client/src/qase/api_client_v1/models/run_external_issue.py @@ -0,0 +1,92 @@ +# coding: utf-8 + +""" + Qase.io TestOps API v1 + + Qase TestOps API v1 Specification. + + The version of the OpenAPI document: 1.0.0 + Contact: support@qase.io + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing import Optional, Set +from typing_extensions import Self + +class RunExternalIssue(BaseModel): + """ + RunExternalIssue + """ # noqa: E501 + id: Optional[StrictStr] = None + type: Optional[StrictStr] = None + link: Optional[StrictStr] = None + __properties: ClassVar[List[str]] = ["id", "type", "link"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RunExternalIssue from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RunExternalIssue from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "type": obj.get("type"), + "link": obj.get("link") + }) + return _obj + + diff --git a/qase-api-client/src/qase/api_client_v1/models/runexternal_issues.py b/qase-api-client/src/qase/api_client_v1/models/runexternal_issues.py new file mode 100644 index 00000000..e6245206 --- /dev/null +++ b/qase-api-client/src/qase/api_client_v1/models/runexternal_issues.py @@ -0,0 +1,105 @@ +# coding: utf-8 + +""" + Qase.io TestOps API v1 + + Qase TestOps API v1 Specification. + + The version of the OpenAPI document: 1.0.0 + Contact: support@qase.io + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr, field_validator +from typing import Any, ClassVar, Dict, List +from qase.api_client_v1.models.runexternal_issues_links_inner import RunexternalIssuesLinksInner +from typing import Optional, Set +from typing_extensions import Self + +class RunexternalIssues(BaseModel): + """ + RunexternalIssues + """ # noqa: E501 + type: StrictStr + links: List[RunexternalIssuesLinksInner] = Field(description="Array of external issue links. Each test run (run_id) can have only one external issue link.") + __properties: ClassVar[List[str]] = ["type", "links"] + + @field_validator('type') + def type_validate_enum(cls, value): + """Validates the enum""" + if value not in set(['jira-cloud', 'jira-server']): + raise ValueError("must be one of enum values ('jira-cloud', 'jira-server')") + return value + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RunexternalIssues from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in links (list) + _items = [] + if self.links: + for _item in self.links: + if _item: + _items.append(_item.to_dict()) + _dict['links'] = _items + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RunexternalIssues from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "type": obj.get("type"), + "links": [RunexternalIssuesLinksInner.from_dict(_item) for _item in obj["links"]] if obj.get("links") is not None else None + }) + return _obj + + diff --git a/qase-api-client/src/qase/api_client_v1/models/runexternal_issues_links_inner.py b/qase-api-client/src/qase/api_client_v1/models/runexternal_issues_links_inner.py new file mode 100644 index 00000000..b10e9740 --- /dev/null +++ b/qase-api-client/src/qase/api_client_v1/models/runexternal_issues_links_inner.py @@ -0,0 +1,96 @@ +# coding: utf-8 + +""" + Qase.io TestOps API v1 + + Qase TestOps API v1 Specification. + + The version of the OpenAPI document: 1.0.0 + Contact: support@qase.io + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class RunexternalIssuesLinksInner(BaseModel): + """ + RunexternalIssuesLinksInner + """ # noqa: E501 + run_id: StrictInt + external_issue: Optional[Annotated[str, Field(min_length=1, strict=True)]] = Field(default=None, description="An external issue identifier, e.g. \"PROJ-1234\". Or null if you want to remove the link.") + __properties: ClassVar[List[str]] = ["run_id", "external_issue"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of RunexternalIssuesLinksInner from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if external_issue (nullable) is None + # and model_fields_set contains the field + if self.external_issue is None and "external_issue" in self.model_fields_set: + _dict['external_issue'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of RunexternalIssuesLinksInner from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "run_id": obj.get("run_id"), + "external_issue": obj.get("external_issue") + }) + return _obj + + diff --git a/qase-api-client/src/qase/api_client_v1/models/runupdate.py b/qase-api-client/src/qase/api_client_v1/models/runupdate.py new file mode 100644 index 00000000..96bb0428 --- /dev/null +++ b/qase-api-client/src/qase/api_client_v1/models/runupdate.py @@ -0,0 +1,138 @@ +# coding: utf-8 + +""" + Qase.io TestOps API v1 + + Qase TestOps API v1 Specification. + + The version of the OpenAPI document: 1.0.0 + Contact: support@qase.io + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from typing_extensions import Annotated +from typing import Optional, Set +from typing_extensions import Self + +class Runupdate(BaseModel): + """ + Runupdate + """ # noqa: E501 + title: Optional[Annotated[str, Field(strict=True, max_length=255)]] = None + description: Optional[Annotated[str, Field(strict=True, max_length=10000)]] = None + environment_id: Optional[Annotated[int, Field(strict=True, ge=1)]] = None + environment_slug: Optional[Annotated[str, Field(strict=True, max_length=255)]] = None + milestone_id: Optional[Annotated[int, Field(strict=True, ge=1)]] = None + tags: Optional[List[StrictStr]] = None + configurations: Optional[List[StrictInt]] = None + custom_field: Optional[Dict[str, StrictStr]] = Field(default=None, description="A map of custom fields values (id => value)") + __properties: ClassVar[List[str]] = ["title", "description", "environment_id", "environment_slug", "milestone_id", "tags", "configurations", "custom_field"] + + model_config = ConfigDict( + populate_by_name=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead + return json.dumps(self.to_dict()) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Runupdate from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # set to None if description (nullable) is None + # and model_fields_set contains the field + if self.description is None and "description" in self.model_fields_set: + _dict['description'] = None + + # set to None if environment_id (nullable) is None + # and model_fields_set contains the field + if self.environment_id is None and "environment_id" in self.model_fields_set: + _dict['environment_id'] = None + + # set to None if environment_slug (nullable) is None + # and model_fields_set contains the field + if self.environment_slug is None and "environment_slug" in self.model_fields_set: + _dict['environment_slug'] = None + + # set to None if milestone_id (nullable) is None + # and model_fields_set contains the field + if self.milestone_id is None and "milestone_id" in self.model_fields_set: + _dict['milestone_id'] = None + + # set to None if tags (nullable) is None + # and model_fields_set contains the field + if self.tags is None and "tags" in self.model_fields_set: + _dict['tags'] = None + + # set to None if configurations (nullable) is None + # and model_fields_set contains the field + if self.configurations is None and "configurations" in self.model_fields_set: + _dict['configurations'] = None + + # set to None if custom_field (nullable) is None + # and model_fields_set contains the field + if self.custom_field is None and "custom_field" in self.model_fields_set: + _dict['custom_field'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Runupdate from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "title": obj.get("title"), + "description": obj.get("description"), + "environment_id": obj.get("environment_id"), + "environment_slug": obj.get("environment_slug"), + "milestone_id": obj.get("milestone_id"), + "tags": obj.get("tags"), + "configurations": obj.get("configurations"), + "custom_field": obj.get("custom_field") + }) + return _obj + + diff --git a/qase-api-client/src/qase/api_client_v1/models/test_case_create.py b/qase-api-client/src/qase/api_client_v1/models/test_case_create.py index 18e7cbb3..9a9229c0 100644 --- a/qase-api-client/src/qase/api_client_v1/models/test_case_create.py +++ b/qase-api-client/src/qase/api_client_v1/models/test_case_create.py @@ -39,7 +39,6 @@ class TestCaseCreate(BaseModel): type: Optional[StrictInt] = None layer: Optional[StrictInt] = None is_flaky: Optional[StrictInt] = None - author_id: Optional[StrictInt] = None suite_id: Optional[StrictInt] = None milestone_id: Optional[StrictInt] = None automation: Optional[StrictInt] = None @@ -51,7 +50,7 @@ class TestCaseCreate(BaseModel): custom_field: Optional[Dict[str, StrictStr]] = Field(default=None, description="A map of custom fields values (id => value)") created_at: Optional[StrictStr] = None updated_at: Optional[StrictStr] = None - __properties: ClassVar[List[str]] = ["description", "preconditions", "postconditions", "title", "severity", "priority", "behavior", "type", "layer", "is_flaky", "author_id", "suite_id", "milestone_id", "automation", "status", "attachments", "steps", "tags", "params", "custom_field", "created_at", "updated_at"] + __properties: ClassVar[List[str]] = ["description", "preconditions", "postconditions", "title", "severity", "priority", "behavior", "type", "layer", "is_flaky", "suite_id", "milestone_id", "automation", "status", "attachments", "steps", "tags", "params", "custom_field", "created_at", "updated_at"] model_config = ConfigDict( populate_by_name=True, @@ -126,7 +125,6 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "type": obj.get("type"), "layer": obj.get("layer"), "is_flaky": obj.get("is_flaky"), - "author_id": obj.get("author_id"), "suite_id": obj.get("suite_id"), "milestone_id": obj.get("milestone_id"), "automation": obj.get("automation"), diff --git a/qase-api-client/src/qase/api_client_v1/models/test_casebulk_cases_inner.py b/qase-api-client/src/qase/api_client_v1/models/test_casebulk_cases_inner.py index c1024513..37481fe8 100644 --- a/qase-api-client/src/qase/api_client_v1/models/test_casebulk_cases_inner.py +++ b/qase-api-client/src/qase/api_client_v1/models/test_casebulk_cases_inner.py @@ -39,7 +39,6 @@ class TestCasebulkCasesInner(BaseModel): type: Optional[StrictInt] = None layer: Optional[StrictInt] = None is_flaky: Optional[StrictInt] = None - author_id: Optional[StrictInt] = None suite_id: Optional[StrictInt] = None milestone_id: Optional[StrictInt] = None automation: Optional[StrictInt] = None @@ -52,7 +51,7 @@ class TestCasebulkCasesInner(BaseModel): created_at: Optional[StrictStr] = None updated_at: Optional[StrictStr] = None id: Optional[StrictInt] = None - __properties: ClassVar[List[str]] = ["description", "preconditions", "postconditions", "title", "severity", "priority", "behavior", "type", "layer", "is_flaky", "author_id", "suite_id", "milestone_id", "automation", "status", "attachments", "steps", "tags", "params", "custom_field", "created_at", "updated_at", "id"] + __properties: ClassVar[List[str]] = ["description", "preconditions", "postconditions", "title", "severity", "priority", "behavior", "type", "layer", "is_flaky", "suite_id", "milestone_id", "automation", "status", "attachments", "steps", "tags", "params", "custom_field", "created_at", "updated_at", "id"] model_config = ConfigDict( populate_by_name=True, @@ -132,7 +131,6 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: "type": obj.get("type"), "layer": obj.get("layer"), "is_flaky": obj.get("is_flaky"), - "author_id": obj.get("author_id"), "suite_id": obj.get("suite_id"), "milestone_id": obj.get("milestone_id"), "automation": obj.get("automation"),