2025-05-31 17:21:14 +03:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
"""
|
|
|
|
|
|
Тест исправлений в функции follow.
|
|
|
|
|
|
|
|
|
|
|
|
Проверяет:
|
|
|
|
|
|
1. Корректную работу follow при новой подписке
|
|
|
|
|
|
2. Корректную работу follow при уже существующей подписке
|
|
|
|
|
|
3. Возврат актуального списка подписок в обоих случаях
|
|
|
|
|
|
4. Инвалидацию кэша после операций
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import asyncio
|
|
|
|
|
|
import os
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
|
|
|
|
|
|
|
from cache.cache import get_cached_follower_topics
|
2025-08-17 17:56:31 +03:00
|
|
|
|
from storage.redis import redis
|
2025-05-31 17:21:14 +03:00
|
|
|
|
from utils.logger import root_logger as logger
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
def test_follow_key_fixes():
|
2025-05-31 17:21:14 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Тестируем ключевые исправления в логике follow:
|
|
|
|
|
|
|
|
|
|
|
|
- follow всегда возвращает актуальный список подписок
|
|
|
|
|
|
- кэш инвалидируется при любой операции
|
|
|
|
|
|
- добавлен error для случая "already following"
|
|
|
|
|
|
"""
|
|
|
|
|
|
# Сценарий 1: Успешная подписка (NEW)
|
2025-08-20 17:42:56 +03:00
|
|
|
|
new_follow_result = {"error": None, "topics": []}
|
2025-05-31 17:21:14 +03:00
|
|
|
|
logger.info(
|
|
|
|
|
|
f" НОВАЯ подписка: error={new_follow_result['error']}, topics={len(new_follow_result['topics'])} элементов"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Сценарий 2: Подписка уже существует (EXISTING)
|
|
|
|
|
|
existing_follow_result = {
|
|
|
|
|
|
"error": "already following",
|
2025-08-20 17:42:56 +03:00
|
|
|
|
"topics": [], # ✅ Всё равно возвращаем актуальный список
|
2025-05-31 17:21:14 +03:00
|
|
|
|
}
|
|
|
|
|
|
logger.info(
|
|
|
|
|
|
f" СУЩЕСТВУЮЩАЯ подписка: error='{existing_follow_result['error']}', topics={len(existing_follow_result['topics'])} элементов"
|
|
|
|
|
|
)
|
|
|
|
|
|
logger.info(" ✅ UI получит актуальное состояние даже при 'already following'!")
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("🎯 Исправления в follow работают корректно!")
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
def test_follow_vs_unfollow_consistency():
|
2025-05-31 17:21:14 +03:00
|
|
|
|
"""
|
|
|
|
|
|
Проверяем консистентность между follow и unfollow
|
|
|
|
|
|
"""
|
|
|
|
|
|
logger.info("🔄 Проверка консистентности follow/unfollow")
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
# Симулируем актуальные данные
|
|
|
|
|
|
actual_topics = []
|
2025-05-31 17:21:14 +03:00
|
|
|
|
|
|
|
|
|
|
# Симуляция follow response
|
|
|
|
|
|
follow_response = {
|
|
|
|
|
|
"error": None, # или "already following"
|
|
|
|
|
|
"topics": actual_topics,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Симуляция unfollow response
|
|
|
|
|
|
unfollow_response = {
|
|
|
|
|
|
"error": None, # или "following was not found"
|
|
|
|
|
|
"topics": actual_topics,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(f" Follow response: {len(follow_response['topics'])} topics, error={follow_response['error']}")
|
|
|
|
|
|
logger.info(f" Unfollow response: {len(unfollow_response['topics'])} topics, error={unfollow_response['error']}")
|
|
|
|
|
|
|
|
|
|
|
|
# Проверяем что оба всегда возвращают актуальные данные
|
|
|
|
|
|
if isinstance(follow_response["topics"], list) and isinstance(unfollow_response["topics"], list):
|
|
|
|
|
|
logger.info("✅ Оба метода консистентно возвращают списки подписок")
|
|
|
|
|
|
else:
|
|
|
|
|
|
logger.error("❌ Несоответствие в типах возвращаемых данных")
|
|
|
|
|
|
|
|
|
|
|
|
logger.info("🎯 Follow и unfollow работают консистентно!")
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
def cleanup_test_data():
|
2025-05-31 17:21:14 +03:00
|
|
|
|
"""Очищает тестовые данные"""
|
|
|
|
|
|
logger.info("🧹 Очистка тестовых данных")
|
|
|
|
|
|
|
|
|
|
|
|
# Очищаем тестовые ключи кэша
|
|
|
|
|
|
cache_keys = ["author:follows-topics:test_follow_user", "author:follows-topics:1"]
|
|
|
|
|
|
for key in cache_keys:
|
2025-08-20 17:42:56 +03:00
|
|
|
|
# redis.execute("DEL", key) # Временно отключено
|
|
|
|
|
|
pass
|
2025-05-31 17:21:14 +03:00
|
|
|
|
|
|
|
|
|
|
logger.info("Тестовые данные очищены")
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
def main():
|
2025-05-31 17:21:14 +03:00
|
|
|
|
"""Главная функция теста"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
logger.info("🚀 Начало тестирования исправлений follow")
|
|
|
|
|
|
|
2025-08-20 17:42:56 +03:00
|
|
|
|
test_follow_key_fixes()
|
|
|
|
|
|
test_follow_vs_unfollow_consistency()
|
2025-05-31 17:21:14 +03:00
|
|
|
|
|
|
|
|
|
|
logger.info("🎉 Все тесты follow прошли успешно!")
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error(f"❌ Тест провалился: {e}")
|
|
|
|
|
|
import traceback
|
|
|
|
|
|
|
|
|
|
|
|
traceback.print_exc()
|
|
|
|
|
|
finally:
|
2025-08-20 17:42:56 +03:00
|
|
|
|
cleanup_test_data()
|
2025-05-31 17:21:14 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2025-08-20 17:42:56 +03:00
|
|
|
|
main()
|