234 lines
9 KiB
Python
234 lines
9 KiB
Python
import json
|
|
from unittest import mock
|
|
from datetime import datetime
|
|
|
|
from django.test import SimpleTestCase, RequestFactory
|
|
from django.contrib.auth.models import AnonymousUser
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
|
|
from interventions.views.calendar import intervention_calendar_details_ajax
|
|
from interventions.models import InterventionNote
|
|
|
|
|
|
class DummyConfig:
|
|
regional_standard = 'FR'
|
|
linked_configs = mock.MagicMock(values_list=lambda *args, **kwargs: [])
|
|
|
|
|
|
class DummyUser:
|
|
def __init__(self, id=1, first_name="Jean", last_name="Dupont"):
|
|
self.id = id
|
|
self.pk = id
|
|
self.first_name = first_name
|
|
self.last_name = last_name
|
|
self.is_authenticated = True
|
|
self.config = DummyConfig()
|
|
|
|
def get_full_name(self):
|
|
return f"{self.first_name} {self.last_name}"
|
|
|
|
def __str__(self):
|
|
return self.get_full_name()
|
|
|
|
|
|
class DummyNote:
|
|
def __init__(self, id, note_type, type_display, badge_class, icon_class, content, note_time, note_author, updated_at=None, updated_by=None):
|
|
self.id = id
|
|
self.pk = id
|
|
self.note_type = note_type
|
|
self._type_display = type_display
|
|
self.type_badge_class = badge_class
|
|
self.type_icon_class = icon_class
|
|
self.content = content
|
|
self.note_time = note_time
|
|
self.note_author = note_author
|
|
self.updated_at = updated_at
|
|
self.updated_by = updated_by
|
|
|
|
def get_note_type_display(self):
|
|
return self._type_display
|
|
|
|
|
|
class DummyDoc:
|
|
def __init__(self, id, filename, thumbnail_path=None, upload_date=None, uploaded_by=None):
|
|
self.id = id
|
|
self.pk = id
|
|
self.filename = filename
|
|
self.upload_date = upload_date or timezone.now()
|
|
self.uploaded_by = uploaded_by
|
|
self.file = type('DummyFile', (), {'name': filename})()
|
|
if thumbnail_path:
|
|
self.thumbnail = type('DummyThumb', (), {'name': thumbnail_path})()
|
|
else:
|
|
self.thumbnail = None
|
|
self._meta = type('DummyMeta', (), {
|
|
'app_label': 'interventions',
|
|
'model_name': 'interventiondocument',
|
|
'object_name': 'InterventionDocument',
|
|
})()
|
|
|
|
|
|
class CalendarInterventionDetailsAjaxSimpleTests(SimpleTestCase):
|
|
databases = set()
|
|
|
|
def setUp(self):
|
|
self.factory = RequestFactory()
|
|
self.url = reverse('interventions:intervention_calendar_details_ajax', args=[123])
|
|
|
|
def _create_request(self, user=None):
|
|
request = self.factory.get(self.url)
|
|
request.user = user if user is not None else AnonymousUser()
|
|
request.session = {
|
|
'account_switch_allowed_user_ids': [getattr(request.user, 'pk', 1)],
|
|
'account_switch_origin_user_id': getattr(request.user, 'pk', 1),
|
|
}
|
|
return request
|
|
|
|
def test_url_resolves(self):
|
|
self.assertEqual(self.url, '/interventions/calendar/intervention/123/details/')
|
|
|
|
def test_anonymous_user_redirects_to_login(self):
|
|
request = self._create_request(AnonymousUser())
|
|
response = intervention_calendar_details_ajax(request, intervention_id=123)
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertIn('/accounts/login/', response.url)
|
|
|
|
@mock.patch('interventions.views.calendar.can_view_intervention_summary', return_value=False)
|
|
@mock.patch('interventions.views.calendar.can_view_intervention', return_value=False)
|
|
@mock.patch('interventions.views.calendar.get_object_or_404')
|
|
def test_permission_denied_returns_403(self, mock_get_obj, mock_can_view, mock_can_view_summary):
|
|
mock_itv = mock.MagicMock(id=123)
|
|
mock_get_obj.return_value = mock_itv
|
|
|
|
user = DummyUser(id=99)
|
|
request = self._create_request(user)
|
|
|
|
response = intervention_calendar_details_ajax(request, intervention_id=123)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
@mock.patch('interventions.views.calendar.can_view_intervention_summary', return_value=False)
|
|
@mock.patch('interventions.views.calendar.can_view_intervention', return_value=True)
|
|
@mock.patch('interventions.views.calendar.InterventionNote.objects')
|
|
@mock.patch('interventions.views.calendar.get_object_or_404')
|
|
def test_authorized_user_receives_notes_and_documents(
|
|
self, mock_get_obj, mock_notes_qs, mock_can_view, mock_can_view_summary
|
|
):
|
|
mock_itv = mock.MagicMock(id=123, title="Intervention Réparation Éclairage")
|
|
mock_get_obj.return_value = mock_itv
|
|
|
|
now = timezone.now()
|
|
author = DummyUser(id=1, first_name="Jean", last_name="Dupont")
|
|
|
|
# Notes
|
|
note1 = DummyNote(
|
|
id=1,
|
|
note_type=InterventionNote.NoteType.EQUIPMENT,
|
|
type_display="Matériel",
|
|
badge_class="text-bg-warning text-dark",
|
|
icon_class="bi-tools",
|
|
content="Nacelle 15m requise pour intervention sur mât",
|
|
note_time=now,
|
|
note_author=author,
|
|
)
|
|
note2 = DummyNote(
|
|
id=2,
|
|
note_type=InterventionNote.NoteType.IMPORTANT_INFO,
|
|
type_display="Information importante",
|
|
badge_class="text-bg-danger text-white",
|
|
icon_class="bi-exclamation-triangle-fill",
|
|
content="Attention présence de câbles haute tension à proximité",
|
|
note_time=now,
|
|
note_author=author,
|
|
updated_at=now,
|
|
updated_by=author,
|
|
)
|
|
|
|
mock_filtered_notes = mock.MagicMock()
|
|
mock_filtered_notes.select_related.return_value = mock_filtered_notes
|
|
mock_filtered_notes.annotate.return_value = mock_filtered_notes
|
|
mock_filtered_notes.order_by.return_value = [note1, note2]
|
|
mock_notes_qs.filter.return_value = mock_filtered_notes
|
|
|
|
# Documents
|
|
doc_img = DummyDoc(
|
|
id=10,
|
|
filename="photo_degats.jpg",
|
|
thumbnail_path="thumbnails/photo_degats.jpg",
|
|
upload_date=now,
|
|
uploaded_by=author,
|
|
)
|
|
doc_pdf = DummyDoc(
|
|
id=11,
|
|
filename="rapport_securite.pdf",
|
|
thumbnail_path=None,
|
|
upload_date=now,
|
|
uploaded_by=author,
|
|
)
|
|
|
|
mock_docs_qs = mock.MagicMock()
|
|
mock_docs_qs.select_related.return_value = mock_docs_qs
|
|
mock_docs_qs.order_by.return_value = [doc_img, doc_pdf]
|
|
mock_itv.documents = mock_docs_qs
|
|
|
|
user = DummyUser(id=99)
|
|
request = self._create_request(user)
|
|
|
|
response = intervention_calendar_details_ajax(request, intervention_id=123)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
data = json.loads(response.content.decode('utf-8'))
|
|
self.assertTrue(data['success'])
|
|
self.assertEqual(data['notes_count'], 2)
|
|
self.assertEqual(data['documents_count'], 2)
|
|
self.assertEqual(data['total_count'], 4)
|
|
|
|
# Content assertions
|
|
self.assertIn("Nacelle 15m requise", data['html'])
|
|
self.assertIn("Attention présence de câbles haute tension", data['html'])
|
|
self.assertIn("photo_degats.jpg", data['html'])
|
|
self.assertIn("rapport_securite.pdf", data['html'])
|
|
self.assertIn("Jean D.", data['html'])
|
|
|
|
# Document flags computed by view
|
|
self.assertTrue(doc_img.is_image)
|
|
self.assertFalse(doc_img.is_pdf)
|
|
self.assertEqual(doc_img.ext, '.jpg')
|
|
|
|
self.assertFalse(doc_pdf.is_image)
|
|
self.assertTrue(doc_pdf.is_pdf)
|
|
self.assertEqual(doc_pdf.ext, '.pdf')
|
|
|
|
@mock.patch('interventions.views.calendar.can_view_intervention_summary', return_value=False)
|
|
@mock.patch('interventions.views.calendar.can_view_intervention', return_value=True)
|
|
@mock.patch('interventions.views.calendar.InterventionNote.objects')
|
|
@mock.patch('interventions.views.calendar.get_object_or_404')
|
|
def test_empty_notes_and_documents(
|
|
self, mock_get_obj, mock_notes_qs, mock_can_view, mock_can_view_summary
|
|
):
|
|
mock_itv = mock.MagicMock(id=456, title="Intervention Sans Notes")
|
|
mock_get_obj.return_value = mock_itv
|
|
|
|
mock_filtered_notes = mock.MagicMock()
|
|
mock_filtered_notes.select_related.return_value = mock_filtered_notes
|
|
mock_filtered_notes.annotate.return_value = mock_filtered_notes
|
|
mock_filtered_notes.order_by.return_value = []
|
|
mock_notes_qs.filter.return_value = mock_filtered_notes
|
|
|
|
mock_docs_qs = mock.MagicMock()
|
|
mock_docs_qs.select_related.return_value = mock_docs_qs
|
|
mock_docs_qs.order_by.return_value = []
|
|
mock_itv.documents = mock_docs_qs
|
|
|
|
user = DummyUser(id=99)
|
|
request = self._create_request(user)
|
|
|
|
response = intervention_calendar_details_ajax(request, intervention_id=456)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
data = json.loads(response.content.decode('utf-8'))
|
|
self.assertTrue(data['success'])
|
|
self.assertEqual(data['notes_count'], 0)
|
|
self.assertEqual(data['documents_count'], 0)
|
|
self.assertEqual(data['total_count'], 0)
|
|
self.assertIn("Aucune note ni document", data['html'])
|