kin: KIN-FIX-007 Убрать --reload из uvicorn в продакшне
This commit is contained in:
parent
4a65d90218
commit
47cb4ac91f
3 changed files with 171 additions and 4 deletions
156
tests/test_kin_fix_006_regression.py
Normal file
156
tests/test_kin_fix_006_regression.py
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
"""Regression tests for KIN-FIX-006: 'ssh_key' must be a valid auth_type.
|
||||
|
||||
Root cause: VALID_AUTH_TYPES did not include 'ssh_key', causing 422 on POST credentials.
|
||||
Fix: VALID_AUTH_TYPES = {"password", "key", "ssh_key"} (web/api.py line 1028).
|
||||
|
||||
Acceptance criteria:
|
||||
1. POST /projects/{id}/environments with auth_type='ssh_key' returns 201 (not 422)
|
||||
2. auth_type='key' still returns 201
|
||||
3. auth_type='password' still returns 201
|
||||
4. auth_type='ftp' (invalid) returns 422
|
||||
"""
|
||||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fixture
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@pytest.fixture
|
||||
def client(tmp_path):
|
||||
import web.api as api_module
|
||||
api_module.DB_PATH = tmp_path / "test_fix006.db"
|
||||
# Re-import app after setting DB_PATH so init_db uses the new path
|
||||
from importlib import reload
|
||||
import web.api
|
||||
reload(web.api)
|
||||
api_module.DB_PATH = tmp_path / "test_fix006.db"
|
||||
from web.api import app
|
||||
from fastapi.testclient import TestClient
|
||||
c = TestClient(app)
|
||||
c.post("/api/projects", json={"id": "testproj", "name": "Test Project", "path": "/testproj"})
|
||||
return c
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: VALID_AUTH_TYPES validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_create_environment_ssh_key_auth_type_returns_201(client):
|
||||
"""Regression KIN-FIX-006: auth_type='ssh_key' must return 201, not 422."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-ssh",
|
||||
"host": "10.0.0.1",
|
||||
"username": "deploy",
|
||||
"auth_type": "ssh_key",
|
||||
"auth_value": "-----BEGIN RSA PRIVATE KEY-----",
|
||||
})
|
||||
assert r.status_code == 201, (
|
||||
f"auth_type='ssh_key' must be accepted (201), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_environment_key_auth_type_still_valid(client):
|
||||
"""auth_type='key' must still return 201 after the fix."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-key",
|
||||
"host": "10.0.0.2",
|
||||
"username": "deploy",
|
||||
"auth_type": "key",
|
||||
"auth_value": "keydata",
|
||||
})
|
||||
assert r.status_code == 201, (
|
||||
f"auth_type='key' must still be valid (201), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_environment_password_auth_type_still_valid(client):
|
||||
"""auth_type='password' must still return 201 after the fix."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-pass",
|
||||
"host": "10.0.0.3",
|
||||
"username": "root",
|
||||
"auth_type": "password",
|
||||
"auth_value": "s3cr3t",
|
||||
})
|
||||
assert r.status_code == 201, (
|
||||
f"auth_type='password' must still be valid (201), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_environment_invalid_auth_type_returns_422(client):
|
||||
"""Invalid auth_type (e.g. 'ftp') must return 422 Unprocessable Entity."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-ftp",
|
||||
"host": "10.0.0.4",
|
||||
"username": "ftpuser",
|
||||
"auth_type": "ftp",
|
||||
"auth_value": "password123",
|
||||
})
|
||||
assert r.status_code == 422, (
|
||||
f"auth_type='ftp' must be rejected (422), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_environment_empty_auth_type_returns_422(client):
|
||||
"""Empty string auth_type must return 422."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-empty",
|
||||
"host": "10.0.0.5",
|
||||
"username": "root",
|
||||
"auth_type": "",
|
||||
})
|
||||
assert r.status_code == 422, (
|
||||
f"auth_type='' must be rejected (422), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_environment_default_auth_type_is_password(client):
|
||||
"""Default auth_type (omitted) must be 'password' and return 201."""
|
||||
r = client.post("/api/projects/testproj/environments", json={
|
||||
"name": "prod-default",
|
||||
"host": "10.0.0.6",
|
||||
"username": "root",
|
||||
"auth_value": "pass",
|
||||
# auth_type intentionally omitted — defaults to 'password'
|
||||
})
|
||||
assert r.status_code == 201, (
|
||||
f"Default auth_type must be accepted (201), got {r.status_code}: {r.text}"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test: VALID_AUTH_TYPES content (unit-level)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def test_valid_auth_types_contains_ssh_key():
|
||||
"""Unit: VALID_AUTH_TYPES set must include 'ssh_key'."""
|
||||
from web.api import VALID_AUTH_TYPES
|
||||
assert "ssh_key" in VALID_AUTH_TYPES, (
|
||||
f"VALID_AUTH_TYPES must contain 'ssh_key', got: {VALID_AUTH_TYPES}"
|
||||
)
|
||||
|
||||
|
||||
def test_valid_auth_types_contains_key():
|
||||
"""Unit: VALID_AUTH_TYPES set must include 'key'."""
|
||||
from web.api import VALID_AUTH_TYPES
|
||||
assert "key" in VALID_AUTH_TYPES, (
|
||||
f"VALID_AUTH_TYPES must contain 'key', got: {VALID_AUTH_TYPES}"
|
||||
)
|
||||
|
||||
|
||||
def test_valid_auth_types_contains_password():
|
||||
"""Unit: VALID_AUTH_TYPES set must include 'password'."""
|
||||
from web.api import VALID_AUTH_TYPES
|
||||
assert "password" in VALID_AUTH_TYPES, (
|
||||
f"VALID_AUTH_TYPES must contain 'password', got: {VALID_AUTH_TYPES}"
|
||||
)
|
||||
|
||||
|
||||
def test_valid_auth_types_excludes_ftp():
|
||||
"""Unit: VALID_AUTH_TYPES must NOT include 'ftp'."""
|
||||
from web.api import VALID_AUTH_TYPES
|
||||
assert "ftp" not in VALID_AUTH_TYPES, (
|
||||
f"VALID_AUTH_TYPES must not contain 'ftp', got: {VALID_AUTH_TYPES}"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue