Files
GitMa/tests/test_schemas.py
panw 44921c5646 feat: complete Git Repo Manager MVP implementation
Backend (Phase 1-6):
- Pydantic schemas for request/response validation
- Service layer (SSH Key, Server, Repo, Sync)
- API routes with authentication
- FastAPI main application with lifespan management
- ORM models (SshKey, Server, Repo, SyncLog)

Frontend (Phase 7):
- Vue 3 + Element Plus + Pinia + Vue Router
- API client with Axios and interceptors
- State management stores
- All page components (Dashboard, Servers, Repos, SyncLogs, SshKeys, Settings)

Deployment (Phase 8):
- README with quick start guide
- Startup script (start.sh)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 16:30:13 +08:00

252 lines
8.1 KiB
Python

"""
Tests for all Pydantic schemas.
"""
import pytest
from datetime import datetime
from app.schemas.common import SuccessResponse, ErrorResponse
from app.schemas.ssh_key import SshKeyCreate, SshKeyResponse
from app.schemas.server import ServerCreate, ServerUpdate, ServerResponse
from app.schemas.repo import RepoResponse, CommitInfo
from app.schemas.sync_log import SyncLogResponse
class TestCommonSchemas:
"""Test common response schemas."""
def test_success_response_with_data(self):
"""Test SuccessResponse with data."""
response = SuccessResponse(code=0, data={"id": 1}, message="success")
assert response.code == 0
assert response.data == {"id": 1}
assert response.message == "success"
def test_success_response_default_values(self):
"""Test SuccessResponse with default values."""
response = SuccessResponse(data={"test": "value"})
assert response.code == 0
assert response.message == "success"
def test_error_response(self):
"""Test ErrorResponse."""
response = ErrorResponse(code=404, message="Not found")
assert response.code == 404
assert response.message == "Not found"
assert response.data is None
def test_error_response_with_data(self):
"""Test ErrorResponse with additional data."""
response = ErrorResponse(
code=400,
message="Validation error",
data={"field": "name", "error": "required"}
)
assert response.code == 400
assert response.data == {"field": "name", "error": "required"}
class TestSshKeySchemas:
"""Test SSH key schemas."""
def test_ssh_key_create_valid(self):
"""Test SshKeyCreate with valid data."""
key = SshKeyCreate(
name="test-key",
private_key="-----BEGIN OPENSSH PRIVATE KEY-----\ntest\ntest\n-----END OPENSSH PRIVATE KEY-----"
)
assert key.name == "test-key"
assert "private_key" in key.model_dump()
def test_ssh_key_create_empty_name_fails(self):
"""Test SshKeyCreate fails with empty name."""
with pytest.raises(ValueError):
SshKeyCreate(
name=" ",
private_key="some-key"
)
def test_ssh_key_create_empty_private_key_fails(self):
"""Test SshKeyCreate fails with empty private_key."""
with pytest.raises(ValueError):
SshKeyCreate(
name="test-key",
private_key=""
)
def test_ssh_key_response(self):
"""Test SshKeyResponse."""
timestamp = int(datetime.utcnow().timestamp())
response = SshKeyResponse(
id=1,
name="test-key",
fingerprint="SHA256:abc123",
created_at=timestamp
)
assert response.id == 1
assert response.name == "test-key"
assert response.fingerprint == "SHA256:abc123"
assert response.created_at == timestamp
class TestServerSchemas:
"""Test server schemas."""
def test_server_create_valid(self):
"""Test ServerCreate with valid data."""
server = ServerCreate(
name="test-server",
url="https://gitea.example.com",
api_token="test-token",
ssh_key_id=1,
local_path="/data/test"
)
assert server.name == "test-server"
assert server.sync_enabled is False
assert server.schedule_cron is None
def test_server_create_with_sync(self):
"""Test ServerCreate with sync enabled."""
server = ServerCreate(
name="test-server",
url="https://gitea.example.com",
api_token="test-token",
ssh_key_id=1,
local_path="/data/test",
sync_enabled=True,
schedule_cron="0 */6 * * *"
)
assert server.sync_enabled is True
assert server.schedule_cron == "0 */6 * * *"
def test_server_create_invalid_ssh_key_id(self):
"""Test ServerCreate fails with invalid ssh_key_id."""
with pytest.raises(ValueError):
ServerCreate(
name="test-server",
url="https://gitea.example.com",
api_token="test-token",
ssh_key_id=0, # Must be > 0
local_path="/data/test"
)
def test_server_update_partial(self):
"""Test ServerUpdate with partial data."""
update = ServerUpdate(name="updated-name")
assert update.name == "updated-name"
assert update.url is None
assert update.api_token is None
def test_server_response(self):
"""Test ServerResponse."""
timestamp = int(datetime.utcnow().timestamp())
response = ServerResponse(
id=1,
name="test-server",
url="https://gitea.example.com",
ssh_key_id=1,
sync_enabled=True,
schedule_cron="0 */6 * * *",
local_path="/data/test",
status="success",
created_at=timestamp,
updated_at=timestamp
)
assert response.id == 1
assert response.status == "success"
assert response.sync_enabled is True
class TestRepoSchemas:
"""Test repository schemas."""
def test_commit_info(self):
"""Test CommitInfo schema."""
timestamp = int(datetime.utcnow().timestamp())
commit = CommitInfo(
hash="a1b2c3d4",
author="Test Author <test@example.com>",
message="Test commit",
timestamp=timestamp
)
assert commit.hash == "a1b2c3d4"
assert commit.author == "Test Author <test@example.com>"
assert commit.timestamp == timestamp
def test_repo_response(self):
"""Test RepoResponse schema."""
timestamp = int(datetime.utcnow().timestamp())
repo = RepoResponse(
id=1,
server_id=1,
name="test-repo",
full_name="org/test-repo",
clone_url="https://gitea.example.com/org/test-repo.git",
local_path="/data/test/org/test-repo",
last_sync_at=timestamp,
status="success",
created_at=timestamp
)
assert repo.id == 1
assert repo.name == "test-repo"
assert repo.last_sync_at == timestamp
assert repo.status == "success"
class TestSyncLogSchemas:
"""Test sync log schemas."""
def test_sync_log_response_success(self):
"""Test SyncLogResponse for successful sync."""
timestamp = int(datetime.utcnow().timestamp())
log = SyncLogResponse(
id=1,
repo_id=1,
status="success",
started_at=timestamp,
finished_at=timestamp + 300,
commits_count=5,
error_msg=None,
created_at=timestamp
)
assert log.id == 1
assert log.status == "success"
assert log.commits_count == 5
assert log.error_msg is None
def test_sync_log_response_error(self):
"""Test SyncLogResponse for failed sync."""
timestamp = int(datetime.utcnow().timestamp())
log = SyncLogResponse(
id=2,
repo_id=1,
status="error",
started_at=timestamp,
finished_at=timestamp + 60,
commits_count=None,
error_msg="Connection timeout",
created_at=timestamp
)
assert log.status == "error"
assert log.commits_count is None
assert log.error_msg == "Connection timeout"
class TestSchemaExports:
"""Test that all schemas are properly exported."""
def test_all_schemas_importable(self):
"""Test that all schemas can be imported from app.schemas."""
from app.schemas import (
SuccessResponse,
ErrorResponse,
SshKeyCreate,
SshKeyResponse,
ServerCreate,
ServerUpdate,
ServerResponse,
RepoResponse,
CommitInfo,
SyncLogResponse
)
# If we got here, all imports succeeded
assert True