"""End-to-end integration tests for the full validation flow.""" import json import os import tempfile import pytest from click.testing import CliRunner from envschema.cli import cli from envschema.core import validate_environment from envschema.generator import generate_env_example class TestFullValidationFlow: """Integration tests for complete validation workflows.""" def test_json_schema_with_valid_env(self): """Test validating a valid .env against a JSON schema.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") env_path = os.path.join(tmpdir, ".env") schema_data = { "version": "1.0", "envVars": [ {"name": "DATABASE_URL", "type": "str", "required": True}, {"name": "DEBUG", "type": "bool", "required": False, "default": "false"}, {"name": "PORT", "type": "int", "required": False, "default": "8080"}, {"name": "ALLOWED_HOSTS", "type": "list", "required": False}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) with open(env_path, "w") as f: f.write("DATABASE_URL=postgres://localhost/mydb\n") f.write("DEBUG=true\n") f.write("PORT=3000\n") f.write("ALLOWED_HOSTS=localhost,127.0.0.1\n") runner = CliRunner() result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"]) assert result.exit_code == 0 def test_json_schema_with_invalid_types(self): """Test that type mismatches are caught.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") env_path = os.path.join(tmpdir, ".env") schema_data = { "version": "1.0", "envVars": [ {"name": "PORT", "type": "int", "required": True}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) with open(env_path, "w") as f: f.write("PORT=not_a_number\n") runner = CliRunner() result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"]) assert result.exit_code == 1 assert "PORT" in result.output def test_missing_required_variables(self): """Test that missing required variables are reported.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") env_path = os.path.join(tmpdir, ".env") schema_data = { "version": "1.0", "envVars": [ {"name": "REQUIRED_VAR1", "type": "str", "required": True}, {"name": "REQUIRED_VAR2", "type": "str", "required": True}, {"name": "OPTIONAL_VAR", "type": "str", "required": False}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) with open(env_path, "w") as f: f.write("REQUIRED_VAR1=value1\n") runner = CliRunner() result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env"]) assert result.exit_code == 1 assert "REQUIRED_VAR2" in result.output def test_generate_and_validate_flow(self): """Test generating .env.example and then validating it.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") example_path = os.path.join(tmpdir, ".env.example") schema_data = { "version": "1.0", "envVars": [ {"name": "DATABASE_URL", "type": "str", "required": True, "description": "Database connection string"}, {"name": "DEBUG", "type": "bool", "required": False, "default": "false", "description": "Enable debug mode"}, {"name": "PORT", "type": "int", "required": False, "default": "8080", "description": "Server port"}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) runner = CliRunner() result = runner.invoke(cli, ["generate", schema_path, "--output", example_path]) assert result.exit_code == 0 with open(example_path, "r") as f: content = f.read() assert "DATABASE_URL=" in content assert "DEBUG=false" in content assert "PORT=8080" in content assert "Database connection string" in content class TestCIMode: """Tests for CI mode functionality.""" def test_ci_mode_clean_output(self): """Test that CI mode produces cleaner output.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") env_path = os.path.join(tmpdir, ".env") schema_data = { "version": "1.0", "envVars": [ {"name": "DATABASE_URL", "type": "str", "required": True}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) with open(env_path, "w") as f: f.write("DATABASE_URL=postgres://localhost/mydb\n") runner = CliRunner() result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env", "--ci"]) assert result.exit_code == 0 assert "✓" not in result.output assert "✗" not in result.output def test_ci_mode_json_output(self): """Test CI mode with JSON output.""" with tempfile.TemporaryDirectory() as tmpdir: schema_path = os.path.join(tmpdir, "schema.json") env_path = os.path.join(tmpdir, ".env") schema_data = { "version": "1.0", "envVars": [ {"name": "DATABASE_URL", "type": "str", "required": True}, ] } with open(schema_path, "w") as f: json.dump(schema_data, f) with open(env_path, "w") as f: f.write("DATABASE_URL=postgres://localhost/mydb\n") runner = CliRunner() result = runner.invoke(cli, ["validate", schema_path, "--file", env_path, "--no-env", "--ci", "--format", "json"]) assert result.exit_code == 0 data = json.loads(result.output) assert data["is_valid"] is True