This commit is contained in:
@@ -21,187 +21,13 @@ try:
|
||||
# Patch Redis at module level
|
||||
import storage.redis
|
||||
|
||||
# Add execute method to FakeRedis
|
||||
async def fake_redis_execute(command: str, *args):
|
||||
print(f"🔍 FakeRedis.execute called with: {command}, {args}")
|
||||
|
||||
# Handle Redis commands that might not exist in FakeRedis
|
||||
if command.upper() == "HSET":
|
||||
if len(args) >= 3:
|
||||
key, field, value = args[0], args[1], args[2]
|
||||
result = fake_redis.hset(key, field, value)
|
||||
print(f"✅ FakeRedis.execute HSET result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HGET":
|
||||
if len(args) >= 2:
|
||||
key, field = args[0], args[1]
|
||||
result = fake_redis.hget(key, field)
|
||||
print(f"✅ FakeRedis.execute HGET result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HDEL":
|
||||
if len(args) >= 2:
|
||||
key, field = args[0], args[1]
|
||||
result = fake_redis.hdel(key, field)
|
||||
print(f"✅ FakeRedis.execute HDEL result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HGETALL":
|
||||
if len(args) >= 1:
|
||||
key = args[0]
|
||||
result = fake_redis.hgetall(key)
|
||||
print(f"✅ FakeRedis.execute HGETALL result: {result}")
|
||||
return result
|
||||
|
||||
# Try to use the original FakeRedis method if it exists
|
||||
cmd_method = getattr(fake_redis, command.lower(), None)
|
||||
if cmd_method is not None:
|
||||
if hasattr(cmd_method, '__call__'):
|
||||
result = await cmd_method(*args)
|
||||
print(f"✅ FakeRedis.execute result: {result}")
|
||||
return result
|
||||
else:
|
||||
print(f"✅ FakeRedis.execute result: {cmd_method}")
|
||||
return cmd_method
|
||||
|
||||
print(f"❌ FakeRedis.execute: command {command} not found")
|
||||
return None
|
||||
|
||||
# Ensure fake_redis is the actual FakeRedis instance, not a fixture
|
||||
if hasattr(fake_redis, 'hset'):
|
||||
fake_redis.execute = fake_redis_execute
|
||||
else:
|
||||
print("❌ fake_redis is not a proper FakeRedis instance")
|
||||
# Create a new instance if needed
|
||||
fake_redis = fakeredis.aioredis.FakeRedis()
|
||||
fake_redis.execute = fake_redis_execute
|
||||
|
||||
# Mock the global redis instance
|
||||
storage.redis.redis = fake_redis
|
||||
|
||||
# Mock RedisService class
|
||||
class MockRedisService:
|
||||
def __init__(self):
|
||||
self._client = fake_redis
|
||||
self.is_connected = True
|
||||
|
||||
async def connect(self):
|
||||
return True
|
||||
|
||||
async def disconnect(self):
|
||||
pass
|
||||
|
||||
async def execute(self, command: str, *args):
|
||||
cmd_method = getattr(fake_redis, command.lower(), None)
|
||||
if cmd_method is not None:
|
||||
if hasattr(cmd_method, '__call__'):
|
||||
return await cmd_method(*args)
|
||||
else:
|
||||
return cmd_method
|
||||
return None
|
||||
|
||||
def get(self, key):
|
||||
return fake_redis.get(key)
|
||||
|
||||
def set(self, key, value):
|
||||
return fake_redis.set(key, value)
|
||||
|
||||
def delete(self, key):
|
||||
return fake_redis.delete(key)
|
||||
|
||||
def exists(self, key):
|
||||
return fake_redis.exists(key)
|
||||
|
||||
def ping(self):
|
||||
return True
|
||||
|
||||
def hset(self, key, field, value):
|
||||
return fake_redis.hset(key, field, value)
|
||||
|
||||
def hget(self, key, field):
|
||||
return fake_redis.hget(key, field)
|
||||
|
||||
def hgetall(self, key):
|
||||
return fake_redis.hgetall(key)
|
||||
|
||||
def hdel(self, key, field):
|
||||
return fake_redis.hdel(key, field)
|
||||
|
||||
def expire(self, key, time):
|
||||
return fake_redis.expire(key, time)
|
||||
|
||||
def ttl(self, key):
|
||||
return fake_redis.ttl(key)
|
||||
|
||||
def keys(self, pattern):
|
||||
return fake_redis.keys(pattern)
|
||||
|
||||
def scan(self, cursor=0, match=None, count=None):
|
||||
return fake_redis.scan(cursor, match, count)
|
||||
|
||||
storage.redis.RedisService = MockRedisService
|
||||
|
||||
print("✅ Redis patched with fakeredis at module level")
|
||||
|
||||
except ImportError:
|
||||
# If fakeredis is not available, use basic mocks
|
||||
import storage.redis
|
||||
|
||||
class MockRedisService:
|
||||
def __init__(self):
|
||||
self.is_connected = True
|
||||
|
||||
async def connect(self):
|
||||
return True
|
||||
|
||||
async def disconnect(self):
|
||||
pass
|
||||
|
||||
async def execute(self, command: str, *args):
|
||||
return None
|
||||
|
||||
def get(self, key):
|
||||
return None
|
||||
|
||||
def set(self, key, value):
|
||||
return True
|
||||
|
||||
def delete(self, key):
|
||||
return True
|
||||
|
||||
def exists(self, key):
|
||||
return False
|
||||
|
||||
def ping(self):
|
||||
return True
|
||||
|
||||
def hset(self, key, field, value):
|
||||
return True
|
||||
|
||||
def hget(self, key, field):
|
||||
return None
|
||||
|
||||
def hgetall(self, key):
|
||||
return {}
|
||||
|
||||
def hdel(self, key, field):
|
||||
return True
|
||||
|
||||
def expire(self, key, time):
|
||||
return True
|
||||
|
||||
def ttl(self, key):
|
||||
return -1
|
||||
|
||||
def keys(self, pattern):
|
||||
return []
|
||||
|
||||
def scan(self, cursor=0, match=None, count=None):
|
||||
return ([], 0)
|
||||
|
||||
# Mock the global redis instance
|
||||
storage.redis.redis = MockRedisService()
|
||||
storage.redis.RedisService = MockRedisService
|
||||
|
||||
print("✅ Redis patched with basic mocks at module level")
|
||||
print("❌ fakeredis not available, tests may fail")
|
||||
|
||||
from orm.base import BaseModel as Base
|
||||
|
||||
@@ -265,174 +91,13 @@ def pytest_configure(config):
|
||||
# Patch Redis at module level
|
||||
import storage.redis
|
||||
|
||||
# Add execute method to FakeRedis
|
||||
async def fake_redis_execute(command: str, *args):
|
||||
print(f"🔍 FakeRedis.execute called with: {command}, {args}")
|
||||
|
||||
# Handle Redis commands that might not exist in FakeRedis
|
||||
if command.upper() == "HSET":
|
||||
if len(args) >= 3:
|
||||
key, field, value = args[0], args[1], args[2]
|
||||
result = fake_redis.hset(key, field, value)
|
||||
print(f"✅ FakeRedis.execute HSET result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HGET":
|
||||
if len(args) >= 2:
|
||||
key, field = args[0], args[1]
|
||||
result = fake_redis.hget(key, field)
|
||||
print(f"✅ FakeRedis.execute HGET result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HDEL":
|
||||
if len(args) >= 2:
|
||||
key, field = args[0], args[1]
|
||||
result = fake_redis.hdel(key, field)
|
||||
print(f"✅ FakeRedis.execute HDEL result: {result}")
|
||||
return result
|
||||
elif command.upper() == "HGETALL":
|
||||
if len(args) >= 1:
|
||||
key = args[0]
|
||||
result = fake_redis.hgetall(key)
|
||||
print(f"✅ FakeRedis.execute HGETALL result: {result}")
|
||||
return result
|
||||
|
||||
# Try to use the original FakeRedis method if it exists
|
||||
cmd_method = getattr(fake_redis, command.lower(), None)
|
||||
if cmd_method is not None:
|
||||
if hasattr(cmd_method, '__call__'):
|
||||
result = await cmd_method(*args)
|
||||
print(f"✅ FakeRedis.execute result: {result}")
|
||||
return result
|
||||
else:
|
||||
print(f"✅ FakeRedis.execute result: {cmd_method}")
|
||||
return cmd_method
|
||||
|
||||
print(f"❌ FakeRedis.execute: command {command} not found")
|
||||
return None
|
||||
|
||||
fake_redis.execute = fake_redis_execute
|
||||
|
||||
# Mock the global redis instance
|
||||
storage.redis.redis = fake_redis
|
||||
|
||||
# Mock RedisService class
|
||||
class MockRedisService:
|
||||
def __init__(self):
|
||||
self._client = fake_redis
|
||||
self.is_connected = True
|
||||
|
||||
async def connect(self):
|
||||
return True
|
||||
|
||||
async def disconnect(self):
|
||||
pass
|
||||
|
||||
async def execute(self, command: str, *args):
|
||||
return await fake_redis_execute(command, *args)
|
||||
|
||||
def get(self, key):
|
||||
return fake_redis.get(key)
|
||||
|
||||
def set(self, key, value):
|
||||
return fake_redis.set(key, value)
|
||||
|
||||
def delete(self, key):
|
||||
return fake_redis.delete(key)
|
||||
|
||||
def exists(self, key):
|
||||
return fake_redis.exists(key)
|
||||
|
||||
def ping(self):
|
||||
return True
|
||||
|
||||
def hset(self, key, field, value):
|
||||
return fake_redis.hset(key, field, value)
|
||||
|
||||
def hget(self, key, field):
|
||||
return fake_redis.hget(key, field)
|
||||
|
||||
def hgetall(self, key):
|
||||
return fake_redis.hgetall(key)
|
||||
|
||||
def hdel(self, key, field):
|
||||
return fake_redis.hdel(key, field)
|
||||
|
||||
def expire(self, key, time):
|
||||
return fake_redis.expire(key, time)
|
||||
|
||||
def ttl(self, key):
|
||||
return fake_redis.ttl(key)
|
||||
|
||||
def keys(self, key):
|
||||
return fake_redis.keys(key)
|
||||
|
||||
def scan(self, cursor=0, match=None, count=None):
|
||||
return fake_redis.scan(cursor, match, count)
|
||||
|
||||
storage.redis.RedisService = MockRedisService
|
||||
|
||||
print("✅ Redis patched with fakeredis in pytest_configure")
|
||||
|
||||
except ImportError:
|
||||
# If fakeredis is not available, use basic mocks
|
||||
import storage.redis
|
||||
|
||||
class MockRedisService:
|
||||
def __init__(self):
|
||||
self.is_connected = True
|
||||
|
||||
async def connect(self):
|
||||
return True
|
||||
|
||||
async def disconnect(self):
|
||||
pass
|
||||
|
||||
async def execute(self, command: str, *args):
|
||||
return None
|
||||
|
||||
def get(self, key):
|
||||
return None
|
||||
|
||||
def set(self, key, value):
|
||||
return True
|
||||
|
||||
def delete(self, key):
|
||||
return True
|
||||
|
||||
def exists(self, key):
|
||||
return False
|
||||
|
||||
def ping(self):
|
||||
return True
|
||||
|
||||
def hset(self, key, field, value):
|
||||
return True
|
||||
|
||||
def hget(self, key, field):
|
||||
return None
|
||||
|
||||
def hgetall(self, key):
|
||||
return {}
|
||||
|
||||
def hdel(self, key, field):
|
||||
return True
|
||||
|
||||
def expire(self, key, time):
|
||||
return True
|
||||
|
||||
def ttl(self, key):
|
||||
return -1
|
||||
|
||||
def keys(self, key):
|
||||
return []
|
||||
|
||||
def scan(self, cursor=0, match=None, count=None):
|
||||
return ([], 0)
|
||||
|
||||
# Mock the global redis instance
|
||||
storage.redis.redis = MockRedisService()
|
||||
storage.redis.RedisService = MockRedisService
|
||||
|
||||
print("✅ Redis patched with basic mocks in pytest_configure")
|
||||
print("❌ fakeredis not available in pytest_configure")
|
||||
|
||||
|
||||
def force_create_all_tables(engine):
|
||||
@@ -512,7 +177,6 @@ def test_engine():
|
||||
Использует in-memory SQLite для быстрых тестов.
|
||||
"""
|
||||
# Принудительно импортируем ВСЕ модели чтобы они были зарегистрированы в Base.metadata
|
||||
# Это критично для CI среды где импорты могут работать по-разному
|
||||
import orm.base
|
||||
import orm.community
|
||||
import orm.author
|
||||
@@ -558,8 +222,8 @@ def test_engine():
|
||||
required_tables = [
|
||||
'author', 'community', 'community_author', 'community_follower',
|
||||
'draft', 'draft_author', 'draft_topic',
|
||||
'shout', 'shout_author', 'shout_topic', 'shout_reactions_followers', 'shout_collection',
|
||||
'topic', 'topic_followers', 'reaction', 'invite', 'notification', 'notification_seen',
|
||||
'shout', 'shout_author', 'shout_topic', 'shout_reactions_followers',
|
||||
'topic', 'topic_followers', 'reaction', 'invite', 'notification',
|
||||
'collection', 'author_follower', 'author_rating', 'author_bookmark'
|
||||
]
|
||||
|
||||
@@ -610,9 +274,6 @@ def test_engine():
|
||||
Collection.__table__.create(engine, checkfirst=True)
|
||||
elif table_name == 'topic_followers':
|
||||
TopicFollower.__table__.create(engine, checkfirst=True)
|
||||
elif table_name == 'notification_seen':
|
||||
# notification_seen может быть частью notification модели
|
||||
pass
|
||||
print(f"✅ Created table {table_name}")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to create table {table_name}: {e}")
|
||||
@@ -1236,101 +897,6 @@ def fake_redis():
|
||||
pytest.skip("fakeredis не установлен - установите: pip install fakeredis[aioredis]")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def redis_service_mock(fake_redis):
|
||||
"""Создает мок RedisService с fakeredis"""
|
||||
try:
|
||||
import fakeredis.aioredis
|
||||
|
||||
with patch('storage.redis.RedisService') as mock_service:
|
||||
# Создаем экземпляр с fakeredis
|
||||
mock_service.return_value._client = fake_redis
|
||||
|
||||
# Эмулируем execute метод
|
||||
async def mock_execute(command: str, *args):
|
||||
cmd_method = getattr(fake_redis, command.lower(), None)
|
||||
if cmd_method is not None:
|
||||
if hasattr(cmd_method, '__call__'):
|
||||
return await cmd_method(*args)
|
||||
else:
|
||||
return cmd_method
|
||||
return None
|
||||
|
||||
mock_service.return_value.execute = mock_execute
|
||||
mock_service.return_value.get = fake_redis.get
|
||||
mock_service.return_value.set = fake_redis.set
|
||||
mock_service.return_value.delete = fake_redis.delete
|
||||
mock_service.return_value.exists = fake_redis.exists
|
||||
mock_service.return_value.hset = fake_redis.hset
|
||||
mock_service.return_value.hget = fake_redis.hget
|
||||
mock_service.return_value.hgetall = fake_redis.hgetall
|
||||
mock_service.return_value.hdel = fake_redis.hdel
|
||||
mock_service.return_value.expire = fake_redis.expire
|
||||
mock_service.return_value.ttl = fake_redis.ttl
|
||||
mock_service.return_value.keys = fake_redis.keys
|
||||
mock_service.return_value.scan = fake_redis.scan
|
||||
|
||||
yield mock_service.return_value
|
||||
|
||||
except ImportError:
|
||||
pytest.skip("fakeredis не установлен - установите: pip install fakeredis[aioredis]")
|
||||
|
||||
|
||||
# Используем fakeredis для тестов Redis
|
||||
@pytest.fixture
|
||||
def mock_redis_if_unavailable():
|
||||
"""Заменяет Redis на fakeredis для тестов - более реалистичная имитация Redis"""
|
||||
try:
|
||||
import fakeredis.aioredis
|
||||
|
||||
# Создаем fakeredis сервер
|
||||
fake_redis = fakeredis.aioredis.FakeRedis()
|
||||
|
||||
# Патчим глобальный redis экземпляр
|
||||
with patch('storage.redis.redis') as mock_redis:
|
||||
# Эмулируем RedisService.execute метод
|
||||
async def mock_execute(command: str, *args):
|
||||
cmd_method = getattr(fake_redis, command.lower(), None)
|
||||
if cmd_method is not None:
|
||||
if hasattr(cmd_method, '__call__'):
|
||||
return await cmd_method(*args)
|
||||
else:
|
||||
return cmd_method
|
||||
return None
|
||||
|
||||
# Патчим все основные методы Redis
|
||||
mock_redis.execute = mock_execute
|
||||
mock_redis.get = fake_redis.get
|
||||
mock_redis.set = fake_redis.set
|
||||
mock_redis.delete = fake_redis.delete
|
||||
mock_redis.exists = fake_redis.exists
|
||||
mock_redis.ping = fake_redis.ping
|
||||
mock_redis.hset = fake_redis.hset
|
||||
mock_redis.hget = fake_redis.hget
|
||||
mock_redis.hgetall = fake_redis.hgetall
|
||||
mock_redis.hdel = fake_redis.hdel
|
||||
mock_redis.expire = fake_redis.expire
|
||||
mock_redis.ttl = fake_redis.ttl
|
||||
mock_redis.keys = fake_redis.keys
|
||||
mock_redis.scan = fake_redis.scan
|
||||
mock_redis.is_connected = True
|
||||
|
||||
# Async методы для connect/disconnect
|
||||
async def mock_connect():
|
||||
return True
|
||||
|
||||
async def mock_disconnect():
|
||||
pass
|
||||
|
||||
mock_redis.connect = mock_connect
|
||||
mock_redis.disconnect = mock_disconnect
|
||||
|
||||
yield
|
||||
|
||||
except ImportError:
|
||||
pytest.skip("fakeredis не установлен - установите: pip install fakeredis[aioredis]")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def ensure_rbac_initialized():
|
||||
"""Обеспечивает инициализацию RBAC системы для каждого теста"""
|
||||
|
||||
Reference in New Issue
Block a user