0.4.10-a
All checks were successful
Deploy on push / deploy (push) Successful in 44s

This commit is contained in:
2025-02-11 12:00:35 +03:00
parent 25b61c6b29
commit 5d87035885
27 changed files with 299 additions and 536 deletions

View File

@@ -1,5 +1,6 @@
import asyncio
import os
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
@@ -13,6 +14,7 @@ from settings import DB_URL
# Use SQLite for testing
TEST_DB_URL = "sqlite:///test.db"
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
@@ -20,6 +22,7 @@ def event_loop():
yield loop
loop.close()
@pytest.fixture(scope="session")
def test_engine():
"""Create a test database engine."""
@@ -29,19 +32,21 @@ def test_engine():
Base.metadata.drop_all(engine)
os.remove("test.db")
@pytest.fixture
def db_session(test_engine):
"""Create a new database session for a test."""
connection = test_engine.connect()
transaction = connection.begin()
session = Session(bind=connection)
yield session
session.close()
transaction.rollback()
connection.close()
@pytest.fixture
async def redis_client():
"""Create a test Redis client."""
@@ -49,7 +54,8 @@ async def redis_client():
yield redis
await redis.disconnect()
@pytest.fixture
def test_client():
"""Create a TestClient instance."""
return TestClient(app)
return TestClient(app)

View File

@@ -1,19 +1,18 @@
import pytest
from orm.shout import Shout
from orm.author import Author
from orm.shout import Shout
@pytest.fixture
def test_author(db_session):
"""Create a test author."""
author = Author(
name="Test Author",
slug="test-author",
user="test-user-id"
)
author = Author(name="Test Author", slug="test-author", user="test-user-id")
db_session.add(author)
db_session.commit()
return author
@pytest.fixture
def test_shout(db_session):
"""Create test shout with required fields."""
@@ -27,12 +26,13 @@ def test_shout(db_session):
created_by=author.id, # Обязательное поле
body="Test body",
layout="article",
lang="ru"
lang="ru",
)
db_session.add(shout)
db_session.commit()
return shout
@pytest.mark.asyncio
async def test_create_shout(test_client, db_session, test_author):
"""Test creating a new shout."""
@@ -40,8 +40,8 @@ async def test_create_shout(test_client, db_session, test_author):
"/",
json={
"query": """
mutation CreateDraft($input: DraftInput!) {
create_draft(input: $input) {
mutation CreateDraft($draft_input: DraftInput!) {
create_draft(draft_input: $draft_input) {
error
draft {
id
@@ -56,15 +56,16 @@ async def test_create_shout(test_client, db_session, test_author):
"title": "Test Shout",
"body": "This is a test shout",
}
}
}
},
},
)
assert response.status_code == 200
data = response.json()
assert "errors" not in data
assert data["data"]["create_draft"]["draft"]["title"] == "Test Shout"
@pytest.mark.asyncio
async def test_load_drafts(test_client, db_session):
"""Test retrieving a shout."""
@@ -83,13 +84,11 @@ async def test_load_drafts(test_client, db_session):
}
}
""",
"variables": {
"slug": "test-shout"
}
}
"variables": {"slug": "test-shout"},
},
)
assert response.status_code == 200
data = response.json()
assert "errors" not in data
assert data["data"]["load_drafts"]["drafts"] == []
assert data["data"]["load_drafts"]["drafts"] == []

View File

@@ -1,8 +1,11 @@
from datetime import datetime
import pytest
from orm.author import Author
from orm.reaction import Reaction, ReactionKind
from orm.shout import Shout
from orm.author import Author
from datetime import datetime
@pytest.fixture
def test_setup(db_session):
@@ -11,9 +14,9 @@ def test_setup(db_session):
author = Author(name="Test Author", slug="test-author", user="test-user-id")
db_session.add(author)
db_session.flush()
shout = Shout(
title="Test Shout",
title="Test Shout",
slug="test-shout",
created_by=author.id,
body="This is a test shout",
@@ -21,12 +24,13 @@ def test_setup(db_session):
lang="ru",
community=1,
created_at=now,
updated_at=now
updated_at=now,
)
db_session.add_all([author, shout])
db_session.commit()
return {"author": author, "shout": shout}
@pytest.mark.asyncio
async def test_create_reaction(test_client, db_session, test_setup):
"""Test creating a reaction on a shout."""
@@ -49,16 +53,12 @@ async def test_create_reaction(test_client, db_session, test_setup):
}
""",
"variables": {
"reaction": {
"shout": test_setup["shout"].id,
"kind": ReactionKind.LIKE.value,
"body": "Great post!"
}
}
}
"reaction": {"shout": test_setup["shout"].id, "kind": ReactionKind.LIKE.value, "body": "Great post!"}
},
},
)
assert response.status_code == 200
data = response.json()
assert "error" not in data
assert data["data"]["create_reaction"]["reaction"]["kind"] == ReactionKind.LIKE.value
assert data["data"]["create_reaction"]["reaction"]["kind"] == ReactionKind.LIKE.value

View File

@@ -1,7 +1,10 @@
from datetime import datetime
import pytest
from orm.author import Author
from orm.shout import Shout
from datetime import datetime
@pytest.fixture
def test_shout(db_session):
@@ -10,7 +13,7 @@ def test_shout(db_session):
author = Author(name="Test Author", slug="test-author", user="test-user-id")
db_session.add(author)
db_session.flush()
now = int(datetime.now().timestamp())
shout = Shout(
@@ -22,12 +25,13 @@ def test_shout(db_session):
lang="ru",
community=1,
created_at=now,
updated_at=now
updated_at=now,
)
db_session.add(shout)
db_session.commit()
return shout
@pytest.mark.asyncio
async def test_get_shout(test_client, db_session):
"""Test retrieving a shout."""
@@ -36,7 +40,7 @@ async def test_get_shout(test_client, db_session):
db_session.add(author)
db_session.flush()
now = int(datetime.now().timestamp())
# Создаем публикацию со всеми обязательными полями
shout = Shout(
title="Test Shout",
@@ -47,11 +51,11 @@ async def test_get_shout(test_client, db_session):
lang="ru",
community=1,
created_at=now,
updated_at=now
updated_at=now,
)
db_session.add(shout)
db_session.commit()
response = test_client.post(
"/",
json={
@@ -71,13 +75,11 @@ async def test_get_shout(test_client, db_session):
}
}
""",
"variables": {
"slug": "test-shout"
}
}
"variables": {"slug": "test-shout"},
},
)
data = response.json()
assert response.status_code == 200
assert "errors" not in data
assert data["data"]["get_shout"]["title"] == "Test Shout"
assert data["data"]["get_shout"]["title"] == "Test Shout"

View File

@@ -1,75 +1,56 @@
import pytest
from datetime import datetime, timedelta
import pytest
from pydantic import ValidationError
from auth.validations import (
AuthInput,
UserRegistrationInput,
UserLoginInput,
TokenPayload,
AuthResponse,
OAuthInput,
AuthResponse
TokenPayload,
UserLoginInput,
UserRegistrationInput,
)
class TestAuthValidations:
def test_auth_input(self):
"""Test basic auth input validation"""
# Valid case
auth = AuthInput(
user_id="123",
username="testuser",
token="1234567890abcdef1234567890abcdef"
)
auth = AuthInput(user_id="123", username="testuser", token="1234567890abcdef1234567890abcdef")
assert auth.user_id == "123"
assert auth.username == "testuser"
# Invalid cases
with pytest.raises(ValidationError):
AuthInput(user_id="", username="test", token="x" * 32)
with pytest.raises(ValidationError):
AuthInput(user_id="123", username="t", token="x" * 32)
def test_user_registration(self):
"""Test user registration validation"""
# Valid case
user = UserRegistrationInput(
email="test@example.com",
password="SecurePass123!",
name="Test User"
)
user = UserRegistrationInput(email="test@example.com", password="SecurePass123!", name="Test User")
assert user.email == "test@example.com"
assert user.name == "Test User"
# Test email validation
with pytest.raises(ValidationError) as exc:
UserRegistrationInput(
email="invalid-email",
password="SecurePass123!",
name="Test"
)
UserRegistrationInput(email="invalid-email", password="SecurePass123!", name="Test")
assert "Invalid email format" in str(exc.value)
# Test password validation
with pytest.raises(ValidationError) as exc:
UserRegistrationInput(
email="test@example.com",
password="weak",
name="Test"
)
UserRegistrationInput(email="test@example.com", password="weak", name="Test")
assert "String should have at least 8 characters" in str(exc.value)
def test_token_payload(self):
"""Test token payload validation"""
now = datetime.utcnow()
exp = now + timedelta(hours=1)
payload = TokenPayload(
user_id="123",
username="testuser",
exp=exp,
iat=now
)
payload = TokenPayload(user_id="123", username="testuser", exp=exp, iat=now)
assert payload.user_id == "123"
assert payload.username == "testuser"
assert payload.scopes == [] # Default empty list
@@ -77,25 +58,15 @@ class TestAuthValidations:
def test_auth_response(self):
"""Test auth response validation"""
# Success case
success_resp = AuthResponse(
success=True,
token="valid_token",
user={"id": "123", "name": "Test"}
)
success_resp = AuthResponse(success=True, token="valid_token", user={"id": "123", "name": "Test"})
assert success_resp.success is True
assert success_resp.token == "valid_token"
# Error case
error_resp = AuthResponse(
success=False,
error="Invalid credentials"
)
error_resp = AuthResponse(success=False, error="Invalid credentials")
assert error_resp.success is False
assert error_resp.error == "Invalid credentials"
# Invalid case - отсутствует обязательное поле token при success=True
with pytest.raises(ValidationError):
AuthResponse(
success=True,
user={"id": "123", "name": "Test"}
)
AuthResponse(success=True, user={"id": "123", "name": "Test"})