# from typing import Dict, Any, Optional, List # from ddms_compliance_suite.test_framework_core import BaseAPITestCase, TestSeverity, ValidationResult, APIRequestContext, APIResponseContext # class BasicAPISanityCheckCase(BaseAPITestCase): # id = "TC-FRAMEWORK-SANITY-001" # name = "Basic API Sanity Check" # description = ("Performs a basic API call with default generated data and expects a generally successful " # "response (e.g., 200, 201, 204). If a response schema is defined for success, " # "it also validates the response body against it. " # "If this test case fails, subsequent test cases for this endpoint may be skipped.") # severity = TestSeverity.CRITICAL # tags = ["sanity", "framework-setup"] # # This flag indicates to the orchestrator that if this test fails, # # subsequent tests for THIS ENDPOINT should be skipped. # is_critical_setup_test: bool = True # execution_order = 1 # Ensures this runs first for an endpoint # # Expected successful HTTP status codes # EXPECTED_SUCCESS_STATUS_CODES: List[int] = [200, 201, 202, 204] # def __init__(self, endpoint_spec: Dict[str, Any], global_api_spec: Dict[str, Any], json_schema_validator: Optional[Any] = None, llm_service: Optional[Any] = None): # super().__init__(endpoint_spec, global_api_spec, json_schema_validator, llm_service) # self.target_success_schema: Optional[Dict[str, Any]] = None # # Try to find a schema for a successful response (e.g., 200 or 201) # responses_spec = self.endpoint_spec.get("responses", {}) # if isinstance(responses_spec, dict): # for status_code_str in map(str, self.EXPECTED_SUCCESS_STATUS_CODES): # if status_code_str in responses_spec: # response_def = responses_spec[status_code_str] # if isinstance(response_def, dict): # content = response_def.get("content", {}) # for ct in ["application/json", "application/*+json", "*/*"]: # if ct in content: # media_type_obj = content[ct] # if isinstance(media_type_obj, dict) and isinstance(media_type_obj.get("schema"), dict): # self.target_success_schema = media_type_obj["schema"] # self.logger.info(f"[{self.id}] Found success response schema for status {status_code_str} under content type {ct}.") # break # Found a schema for this content type # if self.target_success_schema: # break # Found a schema for this status code # if not self.target_success_schema: # self.logger.info(f"[{self.id}] No specific success response JSON schema found to validate against for this endpoint.") # # No need to override generate_* methods, as we want the default behavior. # def validate_response(self, response_context: APIResponseContext, request_context: APIRequestContext) -> List[ValidationResult]: # results = [] # status_code = response_context.status_code # if status_code in self.EXPECTED_SUCCESS_STATUS_CODES: # msg = f"Basic sanity check: Received expected success status code {status_code}." # results.append(self.passed(msg)) # # If we have a schema for successful responses, validate the body # if self.target_success_schema: # if response_context.json_content is not None: # results.extend(self.validate_data_against_schema( # data_to_validate=response_context.json_content, # schema_definition=self.target_success_schema, # context_message_prefix="Successful response body" # )) # elif response_context.text_content and not response_context.text_content.strip() and status_code == 204: # # HTTP 204 No Content, body is expected to be empty, so schema validation is not applicable. # results.append(self.passed("Response is 204 No Content, body is correctly empty.")) # elif status_code != 204 : # For 200, 201, 202, if schema is present, content is expected # results.append(self.failed( # message="Basic sanity check: Response body is empty or not JSON, but a success schema was defined.", # details={"status_code": status_code, "content_type": response_context.headers.get("Content-Type")} # )) # else: # results.append(self.failed( # message=f"Basic sanity check: Expected a success status code (one of {self.EXPECTED_SUCCESS_STATUS_CODES}), but received {status_code}.", # details={"status_code": status_code, "response_body": response_context.json_content if response_context.json_content else response_context.text_content} # )) # return results