This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
import time
|
||||
from typing import Any
|
||||
from unittest.mock import patch, AsyncMock
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -18,36 +19,69 @@ from orm.shout import Shout
|
||||
from resolvers.draft import publish_draft
|
||||
from resolvers.reader import get_shout, load_shouts_by
|
||||
from storage.db import local_session
|
||||
from tests.conftest import GraphQLResolveInfoMock
|
||||
# from tests.conftest import GraphQLResolveInfoMock
|
||||
|
||||
class GraphQLResolveInfoMock:
|
||||
"""Mock объект для GraphQLResolveInfo в тестах"""
|
||||
|
||||
def __init__(self, context: dict | None = None):
|
||||
from unittest.mock import MagicMock
|
||||
self.context = context or {}
|
||||
self.field_nodes = [MagicMock()]
|
||||
self.field_nodes[0].selection_set = None
|
||||
self.field_name = "test_field"
|
||||
self.return_type = MagicMock()
|
||||
self.parent_type = MagicMock()
|
||||
self.path = MagicMock()
|
||||
self.schema = MagicMock()
|
||||
self.fragments = {}
|
||||
self.root_value = None
|
||||
self.operation = MagicMock()
|
||||
self.variable_values = {}
|
||||
self.is_awaitable = False
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.fixture(scope="function")
|
||||
def test_data() -> dict[str, Any]:
|
||||
"""Создает тестовые данные для проверки публикации"""
|
||||
with local_session() as session:
|
||||
# Создаем автора
|
||||
# 🔍 Отладка: проверяем схему таблицы draft и добавляем недостающую колонку
|
||||
from sqlalchemy import inspect, text
|
||||
inspector = inspect(session.bind)
|
||||
draft_columns = [col['name'] for col in inspector.get_columns('draft')]
|
||||
print(f"🔍 Draft table columns in test: {draft_columns}")
|
||||
|
||||
if 'shout' not in draft_columns:
|
||||
print("🔧 Adding missing 'shout' column to draft table")
|
||||
session.execute(text("ALTER TABLE draft ADD COLUMN shout INTEGER"))
|
||||
session.commit()
|
||||
|
||||
# Создаем автора с уникальным email
|
||||
import time
|
||||
import random
|
||||
timestamp = int(time.time()) + random.randint(1, 10000)
|
||||
author = Author(
|
||||
name="Test Author",
|
||||
slug="test-author",
|
||||
email="test@example.com",
|
||||
slug=f"test-author-{timestamp}",
|
||||
email=f"test-{timestamp}@example.com",
|
||||
)
|
||||
session.add(author)
|
||||
session.flush()
|
||||
|
||||
# Создаем сообщество
|
||||
# Создаем сообщество с уникальным slug
|
||||
community = Community(
|
||||
name="Test Community",
|
||||
slug="test-community",
|
||||
slug=f"test-community-{timestamp}",
|
||||
created_by=author.id,
|
||||
)
|
||||
session.add(community)
|
||||
session.flush()
|
||||
|
||||
# Создаем черновик
|
||||
# Создаем черновик с уникальным slug
|
||||
draft = Draft(
|
||||
title="Test Draft Title",
|
||||
body="<p>Test draft content</p>",
|
||||
slug="test-draft-slug",
|
||||
slug=f"test-draft-slug-{timestamp}",
|
||||
created_by=author.id,
|
||||
community=community.id,
|
||||
)
|
||||
@@ -58,7 +92,7 @@ def test_data() -> dict[str, Any]:
|
||||
existing_shout = Shout(
|
||||
title="Old Title",
|
||||
body="<p>Old content</p>",
|
||||
slug="existing-shout-slug",
|
||||
slug=f"existing-shout-slug-{timestamp}",
|
||||
created_by=author.id,
|
||||
community=community.id,
|
||||
created_at=int(time.time()),
|
||||
@@ -71,7 +105,7 @@ def test_data() -> dict[str, Any]:
|
||||
draft_with_shout = Draft(
|
||||
title="Updated Draft Title",
|
||||
body="<p>Updated draft content</p>",
|
||||
slug="updated-draft-slug",
|
||||
slug=f"updated-draft-slug-{timestamp}",
|
||||
created_by=author.id,
|
||||
community=community.id,
|
||||
shout=existing_shout.id, # Связываем с существующим shout
|
||||
@@ -91,6 +125,9 @@ def test_data() -> dict[str, Any]:
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('resolvers.draft.notify_shout', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shouts_cache', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shout_related_cache', new=AsyncMock())
|
||||
async def test_new_draft_publication_visibility(test_data: dict[str, Any]) -> None:
|
||||
"""
|
||||
🧪 Тест публикации нового черновика
|
||||
@@ -100,7 +137,10 @@ async def test_new_draft_publication_visibility(test_data: dict[str, Any]) -> No
|
||||
"""
|
||||
# Подготавливаем контекст
|
||||
info = GraphQLResolveInfoMock()
|
||||
info.context = {"author": {"id": test_data["author_id"]}}
|
||||
info.context = {
|
||||
"author": {"id": test_data["author_id"]},
|
||||
"roles": ["author", "reader"]
|
||||
}
|
||||
|
||||
# Публикуем черновик
|
||||
result = await publish_draft(None, info, test_data["draft_id"])
|
||||
@@ -127,6 +167,9 @@ async def test_new_draft_publication_visibility(test_data: dict[str, Any]) -> No
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('resolvers.draft.notify_shout', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shouts_cache', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shout_related_cache', new=AsyncMock())
|
||||
async def test_existing_shout_update_visibility(test_data: dict[str, Any]) -> None:
|
||||
"""
|
||||
🧪 Тест обновления существующего shout через черновик
|
||||
@@ -136,7 +179,10 @@ async def test_existing_shout_update_visibility(test_data: dict[str, Any]) -> No
|
||||
"""
|
||||
# Подготавливаем контекст
|
||||
info = GraphQLResolveInfoMock()
|
||||
info.context = {"author": {"id": test_data["author_id"]}}
|
||||
info.context = {
|
||||
"author": {"id": test_data["author_id"]},
|
||||
"roles": ["author", "reader"]
|
||||
}
|
||||
|
||||
# Проверяем, что изначально shout не виден в списках (published_at = None)
|
||||
with local_session() as session:
|
||||
@@ -178,6 +224,9 @@ async def test_existing_shout_update_visibility(test_data: dict[str, Any]) -> No
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@patch('resolvers.draft.notify_shout', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shouts_cache', new=AsyncMock())
|
||||
@patch('resolvers.draft.invalidate_shout_related_cache', new=AsyncMock())
|
||||
async def test_unpublish_draft_removes_from_lists(test_data: dict[str, Any]) -> None:
|
||||
"""
|
||||
🧪 Тест снятия с публикации
|
||||
@@ -189,7 +238,10 @@ async def test_unpublish_draft_removes_from_lists(test_data: dict[str, Any]) ->
|
||||
|
||||
# Подготавливаем контекст
|
||||
info = GraphQLResolveInfoMock()
|
||||
info.context = {"author": {"id": test_data["author_id"]}}
|
||||
info.context = {
|
||||
"author": {"id": test_data["author_id"]},
|
||||
"roles": ["author", "reader"]
|
||||
}
|
||||
|
||||
# Сначала публикуем черновик
|
||||
publish_result = await publish_draft(None, info, test_data["draft_id"])
|
||||
|
||||
Reference in New Issue
Block a user