from unittest.mock import patch import pytest from django.urls import reverse from rest_framework import status from rest_framework.test import APIRequestFactory, force_authenticate from company.models.company import Company from company.models.location import LocationCode from incident.models import Incident from ncircc.enums.notifications import NotificationCategoryEnum, EventTypeEnum, NotificationStatusEnum from ncircc.models.notification import Notification from ncircc.serializers.notification import NotificationSerializer from ncircc.tests.utils import mocked_notification_requests_post_status_201, \ mocked_notification_requests_post_status_200 from ncircc.views.notification_api import NotificationApiViewSet @pytest.mark.django_db class TestNotificationApi: """ Test Notification Api View """ @pytest.fixture(autouse=True) def setup_test(self, add_user_with_permissions): """Setup data for test""" self.incident = Incident.objects.create(title='test_inc', importance=10, event_count=10, events='') self.user = add_user_with_permissions(username='test_user', password='TesTPasWord1', is_superuser=True) self.notification = Notification.objects.create( incident=self.incident, category=NotificationCategoryEnum.INCIDENT.value, type=EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value, notification_status=NotificationStatusEnum.ADDITION_REQUIRED.value) location, _ = LocationCode.objects.get_or_create(code='RU-MOS') self.company = Company.objects.create(name='Test_name_1', city='Moscow', location=location) @pytest.mark.unit @patch('requests.post', side_effect=mocked_notification_requests_post_status_201) def test_create_api_valid(self, *args): """Test creating notification""" incident = Incident.objects.create(title='test_inc', importance=10, event_count=10, events='') count_before = Notification.objects.count() data = { 'incident': incident.pk, "category": NotificationCategoryEnum.INCIDENT.value, "type": EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value, 'event_description': 'description', 'affected_system_name': 'name' } url = reverse('ncircc_notification-list') request = APIRequestFactory().post(url, data=data) view = NotificationApiViewSet.as_view({'post': 'create'}) force_authenticate(request, self.user) response = view(request) count_after = Notification.objects.count() assert response.status_code == 201 assert count_after == count_before + 1 assert 'incident' in response.data assert response.data['incident'] == incident.pk fields = NotificationSerializer.Meta.fields for field in fields: assert field in response.data @pytest.mark.unit def test_get_list_api_valid(self): """Test valid getting notification list""" count = Notification.objects.count() url = reverse('ncircc_notification-list') request = APIRequestFactory().get(url) view = NotificationApiViewSet.as_view({'get': 'list'}) force_authenticate(request, self.user) response = view(request) assert response.status_code == 200 assert count == response.data.get('count') @pytest.mark.unit @patch('requests.post', side_effect=mocked_notification_requests_post_status_200) def test_update_api(self, *args): """Test valid updated notification""" data = { 'type': EventTypeEnum.INVOLVING_INTO_MALWARE_INFRASTRUCTURE.value, 'assistance': True, 'incident': self.incident.pk, 'category': NotificationCategoryEnum.INCIDENT.value, 'event_description': 'description', 'affected_system_name': 'name' } url = reverse('ncircc_notification-detail', args=[self.notification.pk]) request = APIRequestFactory().patch(url, data) view = NotificationApiViewSet.as_view({'patch': 'update'}) force_authenticate(request, self.user) response = view(request, pk=self.notification.pk) assert response.status_code == 200 fields = NotificationSerializer.Meta.fields for field in fields: assert field in response.data notification = Notification.objects.get(pk=self.notification.pk) assert notification.assistance assert notification.type == 'Вовлечение контролируемого ресурса в инфраструктуру ВПО' @pytest.mark.unit @patch('requests.post', side_effect=mocked_notification_requests_post_status_200) def test_create_notification_with_same_incident(self, _, api_client): api_client.force_authenticate(self.user) url = reverse('ncircc_notification-list') data = { 'incident': self.incident.pk, "category": NotificationCategoryEnum.INCIDENT.value, "type": EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value, 'event_description': 'description', 'affected_system_name': 'name' } response = api_client.post(url, data=data) assert response.status_code == status.HTTP_400_BAD_REQUEST assert response.json() == {'incident': ["This field must be unique."]} # already exists in setup_test @pytest.mark.unit def test_create_notification_without_required_field(self, api_client): api_client.force_authenticate(self.user) incident = Incident.objects.create(title='test_inc', importance=10, event_count=10, events='') url = reverse('ncircc_notification-list') data = { 'incident': incident.pk, "category": NotificationCategoryEnum.INCIDENT.value, "type": EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value, } response = api_client.post(url, data=data) assert response.status_code == status.HTTP_400_BAD_REQUEST assert 'affected_system_name' in response.json() assert 'event_description' in response.json()