Files
openapi-mock-generator/tests/test_cli.py
7000pctAUTO e23a973337
Some checks failed
CI / test (push) Failing after 13s
Add CLI test file
2026-02-02 20:00:09 +00:00

396 lines
12 KiB
Python

"""Tests for CLI commands."""
import pytest
import json
import tempfile
from pathlib import Path
from click.testing import CliRunner
from src.cli.commands import cli
@pytest.fixture
def runner():
"""Create a Click CLI runner."""
return CliRunner()
@pytest.fixture
def sample_openapi_yaml():
"""Sample OpenAPI specification in YAML format."""
return """
openapi: \"3.0.0\"
info:
title: Sample API
version: \"1.0.0\"
paths:
/users:
get:
summary: Get all users
parameters:
- name: page
in: query
schema:
type: integer
- name: limit
in: query
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
createdAt:
type: string
format: date-time
/users/{userId}:
get:
summary: Get user by ID
parameters:
- name: userId
in: path
required: true
schema:
type: integer
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
'404':
description: User not found
content:
application/json:
schema:
type: object
properties:
error:
type: string
message:
type: string
put:
summary: Update user
parameters:
- name: userId
in: path
required: true
schema:
type: integer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
email:
type: string
format: email
required:
- name
responses:
'200':
description: User updated
content:
application/json:
schema:
type: object
properties:
id:
type: integer
name:
type: string
/posts:
post:
summary: Create a post
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
title:
type: string
content:
type: string
authorId:
type: integer
responses:
'201':
description: Post created
content:
application/json:
schema:
type: object
properties:
id:
type: integer
title:
type: string
content:
type: string
authorId:
type: integer
publishedAt:
type: string
format: date-time
components:
schemas:
User:
type: object
properties:
id:
type: integer
name:
type: string
email:
type: string
format: email
createdAt:
type: string
format: date-time
Post:
type: object
properties:
id:
type: integer
title:
type: string
content:
type: string
authorId:
type: integer
publishedAt:
type: string
format: date-time
Error:
type: object
properties:
error:
type: string
message:
type: string
"""
@pytest.fixture
def temp_spec_file(sample_openapi_yaml, tmp_path):
"""Create a temporary OpenAPI spec file."""
spec_file = tmp_path / "openapi.yaml"
spec_file.write_text(sample_openapi_yaml)
return str(spec_file)
class TestCLIServe:
"""Tests for serve command."""
def test_serve_validate_only(self, temp_spec_file, runner):
"""Test serve command with validate-only option."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "serve", "--validate-only"])
assert result.exit_code == 0
assert "valid" in result.output.lower() or "success" in result.output.lower()
def test_serve_missing_spec_file(self, tmp_path, runner):
"""Test serve command with missing spec file."""
result = runner.invoke(cli, ["--spec-file", str(tmp_path / "nonexistent.yaml"), "serve", "--validate-only"])
assert result.exit_code != 0
assert "not found" in result.output.lower()
def test_serve_with_port(self, temp_spec_file, runner):
"""Test serve command with custom port."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "serve", "--validate-only", "--port", "3000"])
assert result.exit_code == 0
def test_serve_with_delay(self, temp_spec_file, runner):
"""Test serve command with delay."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "serve", "--validate-only", "--delay", "100"])
assert result.exit_code == 0
class TestCLIGenerate:
"""Tests for generate command."""
def test_generate_lists_endpoints(self, temp_spec_file, runner):
"""Test generate command without path lists endpoints."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "generate"])
assert result.exit_code == 0
assert "/users" in result.output
def test_generate_specific_endpoint(self, temp_spec_file, runner):
"""Test generate command for specific endpoint."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "generate", "/users", "get"])
assert result.exit_code == 0
assert "status_code" in result.output or "200" in result.output
def test_generate_with_format_json(self, temp_spec_file, runner):
"""Test generate command with JSON output format."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "generate", "/users", "get", "--format", "json"])
assert result.exit_code == 0
assert "{" in result.output
def test_generate_with_format_yaml(self, temp_spec_file, runner):
"""Test generate command with YAML output format."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "generate", "/users", "get", "--format", "yaml"])
assert result.exit_code == 0
def test_generate_path_not_found(self, temp_spec_file, runner):
"""Test generate command with invalid path."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "generate", "/nonexistent", "get"])
assert result.exit_code != 0
assert "not found" in result.output.lower()
class TestCLIValidate:
"""Tests for validate command."""
def test_validate_spec(self, temp_spec_file, runner):
"""Test validate command for valid spec."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "validate"])
assert result.exit_code == 0
assert "valid" in result.output.lower()
def test_validate_missing_file(self, tmp_path, runner):
"""Test validate command with missing file."""
result = runner.invoke(cli, ["--spec-file", str(tmp_path / "nonexistent.yaml"), "validate"])
assert result.exit_code != 0
class TestCLIRoutes:
"""Tests for routes command."""
def test_routes_lists_all(self, temp_spec_file, runner):
"""Test routes command lists all routes."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "routes"])
assert result.exit_code == 0
assert "/users" in result.output
assert "/posts" in result.output
class TestCLIInfo:
"""Tests for info command."""
def test_info_displays_spec_info(self, temp_spec_file, runner):
"""Test info command displays spec information."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "info"])
assert result.exit_code == 0
assert "Sample API" in result.output
assert "1.0.0" in result.output
assert "Paths" in result.output
class TestCLITest:
"""Tests for test command."""
def test_test_endpoint(self, temp_spec_file, runner):
"""Test test command for specific endpoint."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "test", "/users", "--method", "get"])
assert result.exit_code == 0
assert "Status" in result.output or "200" in result.output
def test_test_with_query_params(self, temp_spec_file, runner):
"""Test test command with query parameters."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "test", "/users", "--method", "get", "--query", "page=1"])
assert result.exit_code == 0
def test_test_with_body(self, temp_spec_file, runner):
"""Test test command with request body."""
body = json.dumps({"title": "Test Post", "content": "Content"})
result = runner.invoke(cli, [
"--spec-file", temp_spec_file, "test", "/posts", "--method", "post",
"--body", body
])
assert result.exit_code == 0
def test_test_missing_path(self, temp_spec_file, runner):
"""Test test command without path."""
result = runner.invoke(cli, ["--spec-file", temp_spec_file, "test"])
assert result.exit_code != 0
assert "path" in result.output.lower()
class TestCLIDocker:
"""Tests for docker command."""
def test_docker_builds_image(self, runner):
"""Test docker command builds image."""
result = runner.invoke(cli, ["docker", "--no-build"])
assert result.exit_code == 0
assert "docker run" in result.output
def test_docker_with_custom_image_name(self, runner):
"""Test docker command with custom image name."""
result = runner.invoke(cli, ["docker", "--no-build", "--image-name", "my-mock-server"])
assert result.exit_code == 0
assert "my-mock-server" in result.output
class TestCLIVersion:
"""Tests for version option."""
def test_version_flag(self, runner):
"""Test --version flag displays version."""
result = runner.invoke(cli, ["--version"])
assert result.exit_code == 0
assert "0.1.0" in result.output or "openapi-mock-generator" in result.output
class TestCLIHelp:
"""Tests for help option."""
def test_help_displays_commands(self, runner):
"""Test --help displays available commands."""
result = runner.invoke(cli, ["--help"])
assert result.exit_code == 0
assert "serve" in result.output
assert "generate" in result.output
assert "validate" in result.output
assert "routes" in result.output
assert "info" in result.output