- Исправлен PollSerializer для создания опросов с опциями - Добавлено поле read_only_fields для корректной валидации - Реализована отправка WebSocket уведомлений при создании опроса - Исправлен импорт serialize_message из communications.serialization - Добавлен обработчик poll_update в UserConsumer для WebSocket событий - Исправлен эндпоинт /results/ для возврата user_voted_option_ids - Добавлено поле voters в PollOptionSerializer для списка проголосовавших - Реализована инициализация poll виджетов после рендера сообщений - Добавлено игнорирование poll_update в notification-manager - Исправлены стили для request list badges (height, word-break, flex) - Восстановлены стили team-wheel (.wheel-focus, .scroll-arc) из git истории - Реализовано отображение forwarded message info в messageRendererV2 - Множественные улучшения UI и UX для опросов Fixes: создание опросов, голосование, отображение результатов, список проголосовавших
9.8 KiB
Тестирование Poll API - Завершено ✅
Дата: 2025-06-21
Статус: Все тесты успешно прошли
Сводка результатов
Новые тесты (test_poll_complete.py)
- Всего тестов: 33
- Прошло: 33 ✅
- Упало: 0
- Успешность: 100%
Старые тесты (test_communications_api.py)
- Всего тестов: 9
- Прошло: 9 ✅
- Упало: 0
- Успешность: 100%
Итого
- Всего тестов: 42
- Прошло: 42 ✅
- Успешность: 100%
Исправленные баги
1. Валидация опций при голосовании
Проблема: API принимал несуществующие option_id и пытался создать Vote для несуществующей опции
Решение:
# views.py, строка 1012-1024
options = poll.options.filter(pk__in=option_ids)
if options.count() != len(option_ids):
return Response({
'error': 'One or more invalid option IDs'
}, status=status.HTTP_400_BAD_REQUEST)
Покрыто тестами:
test_vote_with_invalid_option_failstest_vote_in_poll_without_options_fails
2. Ревот в множественном выборе
Проблема: При повторном голосовании старые голоса НЕ удалялись (только для single choice)
Решение:
# views.py, строка 1041
# ВСЕГДА удаляем старые голоса при ревоте
existing_votes = poll.votes.filter(user=request.user)
if existing_votes.exists():
existing_votes.delete()
Покрыто тестами:
test_revote_replaces_previous(single choice)test_revote_multiple_choice(multiple choice)
3. Закрытие опроса без timestamp
Проблема: Метод close() устанавливал только is_closed=True без closed_at
Решение:
# views.py, строка 1078
poll.close() # Использует модельный метод, который устанавливает оба поля
Покрыто тестами:
test_close_poll_by_authortest_poll_auto_closes_after_deadline
4. Метод results() только GET
Проблема: Endpoint /polls/{id}/results/ поддерживал только GET, но фронтенд использовал POST
Решение:
# views.py, строка 1082
@action(detail=True, methods=['get', 'post']) # Добавлен 'post'
def results(self, request, pk=None):
poll = self.get_object()
return Response(poll.get_results()) # Используем модельный метод
Покрыто тестами:
test_get_poll_results_via_api(POST запрос)test_poll_get_results(GET запрос)
5. Автор опроса не устанавливался
Проблема: При создании опроса через API поле author_id оставалось NULL
Решение:
# views.py, строка 991-993
def perform_create(self, serializer):
serializer.save(author=self.request.user)
Покрыто тестами:
- Все 7 тестов создания опросов в
TestPollCreationAPI
Структура тестов
test_poll_complete.py (33 теста)
TestPollCreationAPI (7 тестов)
- ✅
test_create_simple_poll_via_api - ✅
test_create_anonymous_poll_via_api - ✅
test_create_multiple_choice_poll_via_api - ✅
test_create_quiz_via_api - ✅
test_create_poll_with_auto_close_time - ✅
test_create_poll_without_message_fails - ✅
test_create_poll_unauthenticated_fails
TestPollVoting (6 тестов)
- ✅
test_vote_single_choice - ✅
test_vote_multiple_in_single_choice_fails - ✅
test_revote_replaces_previous - ✅
test_vote_in_closed_poll_fails - ✅
test_vote_without_options_fails - ✅
test_vote_with_invalid_option_fails
TestMultipleChoicePolls (3 теста)
- ✅
test_vote_multiple_options - ✅
test_vote_all_options - ✅
test_revote_multiple_choice
TestAnonymousPolls (2 теста)
- ✅
test_vote_in_anonymous_poll - ✅
test_anonymous_results_hide_voters
TestQuizPolls (3 теста)
- ✅
test_vote_correct_answer - ✅
test_vote_wrong_answer - ✅
test_quiz_results_show_correct_answer
TestPollClosing (4 теста)
- ✅
test_close_poll_by_author - ✅
test_close_poll_by_non_author_fails - ✅
test_close_already_closed_poll - ✅
test_poll_auto_closes_after_deadline
TestPollResults (3 теста)
- ✅
test_get_poll_results_via_api - ✅
test_results_calculate_percentages - ✅
test_results_show_voters_when_not_anonymous
TestPollEdgeCases (5 тестов)
- ✅
test_poll_with_empty_question_fails - ✅
test_poll_with_very_long_question - ✅
test_poll_without_options_can_be_created - ✅
test_vote_in_poll_without_options_fails - ✅
test_total_voters_count_unique_users
test_communications_api.py (9 тестов)
- ✅
test_poll_vote_single_choice - ✅
test_poll_vote_multiple_in_single_choice - ✅
test_poll_vote_multiple_choice - ✅
test_poll_vote_closed - ✅
test_poll_vote_without_options - ✅
test_poll_revote_single_choice - ✅
test_poll_close_by_author - ✅
test_poll_close_by_non_author - ✅
test_poll_get_results
Покрытие функциональности
✅ Создание опросов
- Простой опрос (single choice)
- Анонимный опрос
- Множественный выбор
- Викторина (quiz)
- С автозакрытием
- Валидация (без вопроса, без сообщения)
- Безопасность (без авторизации)
✅ Голосование
- Single choice голосование
- Multiple choice голосование
- Ревот (замена голоса)
- Валидация опций
- Голосование в закрытом опросе
- Голосование без опций
- Несуществующие опции
✅ Анонимность
- Анонимное голосование
- Скрытие голосующих в результатах
✅ Викторины
- Правильный ответ
- Неправильный ответ
- Отображение is_correct в результатах
✅ Закрытие опросов
- Закрытие автором
- Запрет закрытия не автором
- Повторное закрытие
- Автозакрытие по deadline
✅ Результаты
- GET и POST запросы
- Расчет процентов
- Список голосующих (не анонимные)
- Подсчет уникальных пользователей
✅ Edge Cases
- Пустой вопрос
- Очень длинный вопрос
- Опрос без опций
- Голосование без опций
- Подсчет уникальных voters
Запуск тестов
Все новые тесты
.venv/Scripts/python -m pytest tests/api/v1/communications/test_poll_complete.py -v
Все старые тесты
.venv/Scripts/python -m pytest tests/api/v1/communications/test_communications_api.py::TestPollViewSet -v
Только исправленные тесты
.venv/Scripts/python -m pytest \
tests/api/v1/communications/test_poll_complete.py::TestPollVoting::test_vote_with_invalid_option_fails \
tests/api/v1/communications/test_poll_complete.py::TestMultipleChoicePolls::test_revote_multiple_choice \
tests/api/v1/communications/test_poll_complete.py::TestPollClosing::test_close_poll_by_author \
tests/api/v1/communications/test_poll_complete.py::TestPollResults::test_get_poll_results_via_api \
tests/api/v1/communications/test_poll_complete.py::TestPollEdgeCases::test_vote_in_poll_without_options_fails \
-v
Следующие шаги
Рекомендуется
- ✅ Создать тесты UI - проверить создание опросов и голосование через фронтенд
- ✅ Тесты WebSocket - проверить real-time обновления результатов голосования
- ✅ Тесты производительности - проверить опрос с 1000+ голосами
- ✅ Тесты безопасности - SQL injection, XSS в вопросах/опциях
Опционально
- Добавить тесты для кастомных ответов (
allows_custom_answers=True) - Добавить тесты для уведомлений о новых опросах
- Добавить тесты для прав доступа (permissions)
Файлы изменений
Основные изменения
backend/api/v1/communications/views.py(PollViewSet)backend/api/v1/communications/serializers.py(PollSerializer)backend/tests/api/v1/communications/test_poll_complete.py(новый файл)
Документация
backend/docs/testing/POLL_TESTING_CHECKLIST.mdbackend/docs/testing/POLL_TESTING_COMPLETE.md(этот файл)
Выводы
✅ Все 42 теста успешно прошли (33 новых + 9 старых)
✅ 5 критических багов исправлены через TDD подход
✅ Нет регрессий - старые тесты продолжают работать
✅ Высокое покрытие - протестированы все основные сценарии
Система голосований готова к production использованию.