diff --git a/tests/test_cli.py b/tests/test_cli.py new file mode 100644 index 0000000..8331227 --- /dev/null +++ b/tests/test_cli.py @@ -0,0 +1,191 @@ +"""Tests for CLI interface.""" +import pytest +import json +from click.testing import CliRunner +from unittest.mock import patch + + +class TestCLI: + """Test cases for CLI commands.""" + + @pytest.fixture + def runner(self): + return CliRunner() + + @pytest.fixture + def sample_json_file(self, tmp_path): + data = {"name": "Test", "value": 42} + file_path = tmp_path / "sample.json" + file_path.write_text(json.dumps(data)) + return file_path + + @pytest.fixture + def invalid_json_file(self, tmp_path): + file_path = tmp_path / "invalid.json" + file_path.write_text("{invalid json}") + return file_path + + def test_cli_main_help(self, runner): + from json_to_openapi.cli import main + result = runner.invoke(main, ["--help"]) + assert result.exit_code == 0 + assert "JSON to OpenAPI Generator" in result.output + + def test_cli_convert_basic(self, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + output_file = tmp_path / "output.yaml" + + result = runner.invoke(main, [ + "convert", + str(sample_json_file), + "-o", str(output_file), + "-f", "yaml", + "-t", "Test API", + "-v", "1.0.0" + ]) + + assert result.exit_code == 0 + assert output_file.exists() + + def test_cli_convert_invalid_file(self, runner, tmp_path): + from json_to_openapi.cli import main + non_existent = tmp_path / "nonexistent.json" + + result = runner.invoke(main, [ + "convert", + str(non_existent) + ]) + + assert result.exit_code != 0 + assert "Error" in result.output + + def test_cli_info(self, runner): + from json_to_openapi.cli import main + result = runner.invoke(main, ["info"]) + assert result.exit_code == 0 + assert "JSON to OpenAPI Generator" in result.output + + @patch('json_to_openapi.cli.click.prompt') + def test_cli_validate_valid_spec(self, mock_prompt, runner, tmp_path): + from json_to_openapi.cli import main + + spec_content = """ +openapi: 3.0.3 +info: + title: Test API + version: 1.0.0 +paths: {} +""" + spec_file = tmp_path / "valid.yaml" + spec_file.write_text(spec_content) + + result = runner.invoke(main, ["validate", str(spec_file)]) + + assert result.exit_code == 0 + assert "Validation passed" in result.output + + @patch('json_to_openapi.cli.click.prompt') + def test_cli_validate_invalid_spec(self, mock_prompt, runner, tmp_path): + from json_to_openapi.cli import main + + spec_content = """ +invalid: content +""" + spec_file = tmp_path / "invalid.yaml" + spec_file.write_text(spec_content) + + result = runner.invoke(main, ["validate", str(spec_file)]) + + assert result.exit_code != 0 + assert "Validation failed" in result.output + + def test_cli_batch_no_files(self, runner, tmp_path): + from json_to_openapi.cli import main + + result = runner.invoke(main, [ + "batch", + str(tmp_path / "*.json") + ]) + + assert result.exit_code != 0 + assert "No files found" in result.output + + def test_cli_batch_single_file(self, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + output_dir = tmp_path / "output" + output_dir.mkdir() + + result = runner.invoke(main, [ + "batch", + str(sample_json_file), + "-o", str(output_dir), + "-f", "yaml" + ]) + + assert result.exit_code == 0 + assert "Successfully processed" in result.output + + @patch('json_to_openapi.cli.click.prompt') + @patch('json_to_openapi.cli.click.confirm') + def test_cli_interactive(self, mock_confirm, mock_prompt, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + + mock_confirm.return_value = False + + mock_prompt.side_effect = [ + str(sample_json_file), + "/items", + "get", + "Get Items", + "", + "yaml", + str(tmp_path / "output.yaml") + ] + + result = runner.invoke(main, ["interactive"]) + + assert result.exit_code == 0 + + def test_cli_verbose_flag(self, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + output_file = tmp_path / "output.yaml" + + result = runner.invoke(main, [ + "-v", + "convert", + str(sample_json_file), + "-o", str(output_file) + ]) + + assert result.exit_code == 0 + assert "[DEBUG]" in result.output + + def test_cli_quiet_flag(self, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + output_file = tmp_path / "output.yaml" + + result = runner.invoke(main, [ + "-q", + "convert", + str(sample_json_file), + "-o", str(output_file) + ]) + + assert result.exit_code == 0 + assert "Generated:" not in result.output + + def test_cli_convert_json_format(self, runner, sample_json_file, tmp_path): + from json_to_openapi.cli import main + output_file = tmp_path / "output.json" + + result = runner.invoke(main, [ + "convert", + str(sample_json_file), + "-o", str(output_file), + "-f", "json" + ]) + + assert result.exit_code == 0 + content = output_file.read_text() + parsed = json.loads(content) + assert parsed["openapi"] == "3.0.3"