Core Features: - Async API client for Kwork.ru (45+ endpoints) - Pydantic models for type-safe responses - Comprehensive error handling (KworkAuthError, KworkApiError, etc.) - 93% test coverage (57 unit tests) CI/CD Pipeline: - 3 parallel jobs: lint, test, security - Ruff for linting/formatting (150x faster than flake8) - MyPy for static type checking - pip-audit for security scanning - Pre-commit hooks for code quality E2E Testing: - Login/logout authentication - Session restoration - All endpoints tested against real API Documentation: - API reference with examples - Usage guide - Contributing guidelines Based on HAR analysis (mitmproxy + har-analyzer skill): - Correct endpoints: api.kwork.ru - Proper authentication: Basic auth + cookies - Form-urlencoded login payload
52 lines
1.4 KiB
Python
52 lines
1.4 KiB
Python
"""
|
|
E2E тесты аутентификации.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from kwork_api import KworkClient
|
|
from kwork_api.errors import KworkAuthError
|
|
|
|
|
|
@pytest.mark.e2e
|
|
async def test_login_success(require_credentials):
|
|
"""E2E: Успешная аутентификация."""
|
|
client = await KworkClient.login(
|
|
username=require_credentials["username"], password=require_credentials["password"]
|
|
)
|
|
|
|
try:
|
|
assert client.token is not None
|
|
assert len(client.token) > 0
|
|
finally:
|
|
await client.close()
|
|
|
|
|
|
@pytest.mark.e2e
|
|
async def test_login_invalid_credentials():
|
|
"""E2E: Неверные credentials."""
|
|
with pytest.raises(KworkAuthError):
|
|
await KworkClient.login(username="invalid_user_12345", password="invalid_pass_12345")
|
|
|
|
|
|
@pytest.mark.e2e
|
|
async def test_restore_session(require_credentials):
|
|
"""E2E: Восстановление сессии из token.
|
|
|
|
HAR shows: POST /user endpoint works with proper auth token.
|
|
"""
|
|
# First login
|
|
client1 = await KworkClient.login(
|
|
username=require_credentials["username"], password=require_credentials["password"]
|
|
)
|
|
token = client1.token # Get web_auth_token
|
|
await client1.close()
|
|
|
|
# Restore from token
|
|
client2 = KworkClient(token=token)
|
|
try:
|
|
user = await client2.user.get_info()
|
|
assert user is not None
|
|
finally:
|
|
await client2.close()
|