fix: resolve CI linting and code quality issues
- Remove unused imports across all generator files - Remove unused variables (spec, url_params, query_params, test_name) - Fix f-strings without placeholders in auth.py and go.py - Fix duplicate BASIC auth handling with wrong indentation - Add missing pytest fixtures (sample_openapi_spec, temp_spec_file, temp_json_spec_file) - Add missing TemplateRenderError import to generator files
This commit is contained in:
@@ -1,10 +1,6 @@
|
|||||||
"""CLI interface for API TestGen."""
|
"""CLI interface for API TestGen."""
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import yaml
|
|
||||||
|
|
||||||
from ..core import SpecParser, AuthConfig
|
from ..core import SpecParser, AuthConfig
|
||||||
from ..core.exceptions import InvalidOpenAPISpecError, UnsupportedVersionError
|
from ..core.exceptions import InvalidOpenAPISpecError, UnsupportedVersionError
|
||||||
@@ -57,7 +53,7 @@ def parse_spec(ctx: click.Context):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
parser = SpecParser(spec_path)
|
parser = SpecParser(spec_path)
|
||||||
spec = parser.load()
|
parser.load()
|
||||||
|
|
||||||
info = parser.get_info()
|
info = parser.get_info()
|
||||||
endpoints = parser.get_endpoints()
|
endpoints = parser.get_endpoints()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Authentication configuration for API TestGen."""
|
"""Authentication configuration for API TestGen."""
|
||||||
|
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
from .exceptions import AuthConfigError, MissingSecuritySchemeError
|
from .exceptions import AuthConfigError, MissingSecuritySchemeError
|
||||||
@@ -293,21 +293,21 @@ func getAPIKeyHeaders() map[string]string {{
|
|||||||
}}
|
}}
|
||||||
'''
|
'''
|
||||||
elif method["type"] == AuthType.BEARER:
|
elif method["type"] == AuthType.BEARER:
|
||||||
return f'''
|
return '''
|
||||||
func getBearerHeaders() map[string]string {{
|
func getBearerHeaders() map[string]string {
|
||||||
return map[string]string{{
|
return map[string]string{
|
||||||
"Authorization": fmt.Sprintf("%s %s", os.Getenv("TOKEN_PREFIX"), os.Getenv("TOKEN")),
|
"Authorization": fmt.Sprintf("%s %s", os.Getenv("TOKEN_PREFIX"), os.Getenv("TOKEN")),
|
||||||
}}
|
}
|
||||||
}}
|
}
|
||||||
'''
|
'''
|
||||||
elif method["type"] == AuthType.BASIC:
|
elif method["type"] == AuthType.BASIC:
|
||||||
return f'''
|
return '''
|
||||||
func getBasicHeaders(username, password string) map[string]string {{
|
func getBasicHeaders(username, password string) map[string]string {
|
||||||
auth := username + ":" + password
|
auth := username + ":" + password
|
||||||
encoded := base64.StdEncoding.EncodeToString([]byte(auth))
|
encoded := base64.StdEncoding.EncodeToString([]byte(auth))
|
||||||
return map[string]string{{
|
return map[string]string{
|
||||||
"Authorization": "Basic " + encoded,
|
"Authorization": "Basic " + encoded,
|
||||||
}}
|
}
|
||||||
}}
|
}
|
||||||
'''
|
'''
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ from pathlib import Path
|
|||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
||||||
from openapi_spec_validator import validate
|
from openapi_spec_validator import validate
|
||||||
from openapi_spec_validator.versions import consts as validator_consts
|
|
||||||
|
|
||||||
from .exceptions import InvalidOpenAPISpecError, UnsupportedVersionError
|
from .exceptions import InvalidOpenAPISpecError, UnsupportedVersionError
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ from typing import Any, Dict, List, Optional
|
|||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
||||||
|
|
||||||
from ..core import SpecParser, AuthConfig
|
from ..core import SpecParser
|
||||||
from ..core.exceptions import GeneratorError, TemplateRenderError
|
from ..core.exceptions import TemplateRenderError
|
||||||
|
|
||||||
|
|
||||||
class GoGenerator:
|
class GoGenerator:
|
||||||
@@ -132,7 +132,6 @@ class GoGenerator:
|
|||||||
"""
|
"""
|
||||||
test_name = self._generate_test_name(endpoint)
|
test_name = self._generate_test_name(endpoint)
|
||||||
params = self._generate_params(endpoint)
|
params = self._generate_params(endpoint)
|
||||||
url_params = self._generate_url_params(endpoint)
|
|
||||||
|
|
||||||
test_code = f'''
|
test_code = f'''
|
||||||
func Test{test_name}(t *testing.T) {{
|
func Test{test_name}(t *testing.T) {{
|
||||||
@@ -201,11 +200,11 @@ func Test{test_name}(t *testing.T) {{
|
|||||||
|
|
||||||
if param["in"] == "path":
|
if param["in"] == "path":
|
||||||
params.append(f'{param_name} := "test_{param_name}"')
|
params.append(f'{param_name} := "test_{param_name}"')
|
||||||
params.append(f'url = strings.Replace(url, "{{'+param_name+'}}", {param_name}, 1)')
|
params.append('url = strings.Replace(url, "' + '{' + param_name + '}' + '", ' + param_name + ', 1)')
|
||||||
|
|
||||||
elif param["in"] == "query":
|
elif param["in"] == "query":
|
||||||
params.append(f'q := url.Values{{{param_name}: []string{{"test"}}}}')
|
params.append(f'q := url.Values{{{param_name}: []string{{"test"}}}}')
|
||||||
params.append(f'url += "?" + q.Encode()')
|
params.append('url += "?" + q.Encode()')
|
||||||
|
|
||||||
return "\n ".join(params) if params else ""
|
return "\n ".join(params) if params else ""
|
||||||
|
|
||||||
@@ -219,11 +218,10 @@ func Test{test_name}(t *testing.T) {{
|
|||||||
String containing URL parameter handling.
|
String containing URL parameter handling.
|
||||||
"""
|
"""
|
||||||
path_params = [p for p in endpoint.get("parameters", []) if p["in"] == "path"]
|
path_params = [p for p in endpoint.get("parameters", []) if p["in"] == "path"]
|
||||||
query_params = [p for p in endpoint.get("parameters", []) if p["in"] == "query"]
|
|
||||||
|
|
||||||
parts = []
|
parts = []
|
||||||
|
|
||||||
for param in path_params:
|
for param in path_params:
|
||||||
parts.append(f'strings.Replace(url, "{{'+param['name']+'}}", "test_' + param['name'] + '", 1)')
|
parts.append('strings.Replace(url, "' + '{' + param['name'] + '}' + '", "test_' + param['name'] + '", 1)')
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ from typing import Any, Dict, List, Optional
|
|||||||
|
|
||||||
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
||||||
|
|
||||||
from ..core import SpecParser, AuthConfig
|
from ..core import SpecParser
|
||||||
from ..core.exceptions import GeneratorError, TemplateRenderError
|
from ..core.exceptions import TemplateRenderError
|
||||||
|
|
||||||
|
|
||||||
class JestGenerator:
|
class JestGenerator:
|
||||||
@@ -106,7 +106,6 @@ class JestGenerator:
|
|||||||
Returns:
|
Returns:
|
||||||
String containing the test code.
|
String containing the test code.
|
||||||
"""
|
"""
|
||||||
test_name = self._generate_test_name(endpoint)
|
|
||||||
describe_name = endpoint["summary"] or endpoint["path"]
|
describe_name = endpoint["summary"] or endpoint["path"]
|
||||||
|
|
||||||
params = self._generate_params(endpoint)
|
params = self._generate_params(endpoint)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from typing import Any, Dict, List, Optional
|
|||||||
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError, UndefinedError
|
||||||
|
|
||||||
from ..core import SpecParser, AuthConfig
|
from ..core import SpecParser, AuthConfig
|
||||||
from ..core.exceptions import GeneratorError, TemplateRenderError
|
from ..core.exceptions import TemplateRenderError
|
||||||
|
|
||||||
|
|
||||||
class PytestGenerator:
|
class PytestGenerator:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from ..core import SpecParser
|
from ..core import SpecParser
|
||||||
|
|
||||||
|
|||||||
@@ -59,3 +59,193 @@ def flavor_manager():
|
|||||||
"""Provide the flavor manager."""
|
"""Provide the flavor manager."""
|
||||||
from regex_humanizer.flavors import get_flavor_manager
|
from regex_humanizer.flavors import get_flavor_manager
|
||||||
return get_flavor_manager()
|
return get_flavor_manager()
|
||||||
|
|
||||||
|
|
||||||
|
SAMPLE_OPENAPI_SPEC = {
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "Test Pet Store API",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A sample API for testing purposes"
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{"url": "https://api.example.com/v1"}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/pets": {
|
||||||
|
"get": {
|
||||||
|
"summary": "List all pets",
|
||||||
|
"description": "Returns a list of pets",
|
||||||
|
"operationId": "listPets",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "limit",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Maximum number of pets to return",
|
||||||
|
"required": False,
|
||||||
|
"schema": {"type": "integer", "default": 10}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Filter by pet status",
|
||||||
|
"required": False,
|
||||||
|
"schema": {"type": "string", "enum": ["available", "pending", "sold"]}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A list of pets",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"$ref": "#/components/schemas/Pet"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"summary": "Create a new pet",
|
||||||
|
"description": "Creates a new pet in the store",
|
||||||
|
"operationId": "createPet",
|
||||||
|
"requestBody": {
|
||||||
|
"required": True,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/Pet"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Pet created successfully",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/Pet"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/pets/{petId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Get a pet by ID",
|
||||||
|
"description": "Returns a single pet",
|
||||||
|
"operationId": "getPetById",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of the pet to retrieve",
|
||||||
|
"required": True,
|
||||||
|
"schema": {"type": "string"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful operation",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {"$ref": "#/components/schemas/Pet"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Pet not found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"summary": "Delete a pet",
|
||||||
|
"description": "Deletes a pet from the store",
|
||||||
|
"operationId": "deletePet",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "petId",
|
||||||
|
"in": "path",
|
||||||
|
"description": "ID of the pet to delete",
|
||||||
|
"required": True,
|
||||||
|
"schema": {"type": "string"}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "Pet deleted successfully"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Pet": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "status"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "Fluffy"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["available", "pending", "sold"],
|
||||||
|
"description": "Pet status in the store"
|
||||||
|
},
|
||||||
|
"categoryId": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"categoryName": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {
|
||||||
|
"ApiKeyAuth": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"in": "header",
|
||||||
|
"name": "X-API-Key"
|
||||||
|
},
|
||||||
|
"BearerAuth": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "bearer",
|
||||||
|
"bearerFormat": "JWT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_openapi_spec():
|
||||||
|
"""Provide a sample OpenAPI specification for testing."""
|
||||||
|
return SAMPLE_OPENAPI_SPEC
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def temp_spec_file(sample_openapi_spec, tmp_path):
|
||||||
|
"""Create a temporary YAML file with a sample OpenAPI spec."""
|
||||||
|
import yaml
|
||||||
|
file_path = tmp_path / "test_spec.yaml"
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
yaml.dump(sample_openapi_spec, f)
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def temp_json_spec_file(sample_openapi_spec, tmp_path):
|
||||||
|
"""Create a temporary JSON file with a sample OpenAPI spec."""
|
||||||
|
import json
|
||||||
|
file_path = tmp_path / "test_spec.json"
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
json.dump(sample_openapi_spec, f, indent=2)
|
||||||
|
return file_path
|
||||||
|
|||||||
Reference in New Issue
Block a user