213 lines
9.5 KiB
Python
213 lines
9.5 KiB
Python
from django.test import TestCase
|
|
from django.urls import reverse
|
|
from django.contrib.auth import get_user_model
|
|
from notifications.models import Discussion, Message
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class DiscussionListTests(TestCase):
|
|
def setUp(self):
|
|
self.user1 = User.objects.create_user(username='user1', password='pass')
|
|
self.user2 = User.objects.create_user(username='user2', password='pass')
|
|
self.user3 = User.objects.create_user(username='user3', password='pass')
|
|
|
|
def test_discussion_list_filtering_on_inbox(self):
|
|
# Discussion 1: created by user1
|
|
d1 = Discussion.objects.create(title="Discussion 1", created_by=self.user1)
|
|
d1.participants.add(self.user1, self.user2, self.user3)
|
|
|
|
# Discussion 2: created by user2, user1 wrote a message
|
|
d2 = Discussion.objects.create(title="Discussion 2", created_by=self.user2)
|
|
d2.participants.add(self.user1, self.user2, self.user3)
|
|
Message.objects.create(discussion=d2, author=self.user1, content="Hello from user1")
|
|
|
|
# Discussion 3: created by user2, user1 is tagged
|
|
d3 = Discussion.objects.create(title="Discussion 3", created_by=self.user2)
|
|
d3.participants.add(self.user1, self.user2, self.user3)
|
|
Message.objects.create(discussion=d3, author=self.user2, content=f"Hello @[User 1](u:{self.user1.pk})")
|
|
|
|
# Discussion 4: created by user2, user3 participant but user1 is NOT author and NOT tagged
|
|
d4 = Discussion.objects.create(title="Discussion 4", created_by=self.user2)
|
|
d4.participants.add(self.user1, self.user2, self.user3)
|
|
|
|
# Discussion 5: auto-created intervention discussion with created_by=user1, but user1 never posted a message and was never tagged
|
|
from django.contrib.contenttypes.models import ContentType
|
|
ct = ContentType.objects.get_for_model(User)
|
|
d5 = Discussion.objects.create(title="Discussion 5", created_by=self.user1, content_type=ct, object_id=1)
|
|
Message.objects.create(discussion=d5, author=self.user2, content="Hello user3")
|
|
|
|
self.client.force_login(self.user1)
|
|
response = self.client.get(reverse('notifications:inbox') + '?tab=discussions')
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.context['active_tab'], 'discussions')
|
|
|
|
discussions_in_context = [item['discussion'] for item in response.context['discussion_items']]
|
|
self.assertIn(d1, discussions_in_context)
|
|
self.assertIn(d2, discussions_in_context)
|
|
self.assertIn(d3, discussions_in_context)
|
|
self.assertNotIn(d4, discussions_in_context)
|
|
self.assertNotIn(d5, discussions_in_context)
|
|
|
|
def test_discussion_list_url_redirect(self):
|
|
self.client.force_login(self.user1)
|
|
response = self.client.get(reverse('notifications:discussion_list'))
|
|
self.assertEqual(response.status_code, 302)
|
|
self.assertIn('tab=discussions', response.url)
|
|
|
|
def test_discussion_create(self):
|
|
self.client.force_login(self.user1)
|
|
response = self.client.post(reverse('notifications:discussion_create'), {
|
|
'title': 'Sujet test',
|
|
'content': f'Bonjour @[User 2](u:{self.user2.pk})',
|
|
})
|
|
self.assertEqual(response.status_code, 302)
|
|
discussion = Discussion.objects.get(title='Sujet test')
|
|
self.assertEqual(discussion.created_by, self.user1)
|
|
self.assertIn(self.user1, discussion.participants.all())
|
|
self.assertIn(self.user2, discussion.participants.all())
|
|
self.assertEqual(discussion.messages.count(), 1)
|
|
|
|
|
|
class InboxTests(TestCase):
|
|
def setUp(self):
|
|
self.user = User.objects.create_user(username='test_inbox_user', password='pass')
|
|
from notifications.models import Notification, NotificationRecipient, Discussion
|
|
# Create a notification for user
|
|
notif = Notification.objects.create(
|
|
title="Test notification",
|
|
content="Notification content",
|
|
notification_type=Notification.TYPE_INFO,
|
|
)
|
|
NotificationRecipient.objects.create(
|
|
notification=notif,
|
|
user=self.user,
|
|
)
|
|
# Create a discussion for user
|
|
d = Discussion.objects.create(title="Test discussion", created_by=self.user)
|
|
d.participants.add(self.user)
|
|
|
|
def test_inbox_renders_both_notifications_and_discussions(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse('notifications:inbox'))
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.context['active_tab'], 'notifications')
|
|
self.assertEqual(response.context['unread_count'], 1)
|
|
self.assertEqual(len(response.context['notifications']), 1)
|
|
self.assertEqual(len(response.context['discussion_items']), 1)
|
|
self.assertContains(response, 'Test notification')
|
|
self.assertContains(response, 'Test discussion')
|
|
self.assertContains(response, 'id="pane-notifications"')
|
|
self.assertContains(response, 'id="pane-discussions"')
|
|
self.assertContains(response, 'id="tab-notifications-btn"')
|
|
self.assertContains(response, 'id="tab-discussions-btn"')
|
|
|
|
def test_inbox_tab_discussions_parameter(self):
|
|
self.client.force_login(self.user)
|
|
response = self.client.get(reverse('notifications:inbox') + '?tab=discussions')
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.context['active_tab'], 'discussions')
|
|
|
|
|
|
class NotificationReminderTests(TestCase):
|
|
def setUp(self):
|
|
from common.models import UserConfig
|
|
self.user = User.objects.create_user(username='testuser', email='test@example.com', password='pass')
|
|
self.config, _ = UserConfig.objects.get_or_create(user=self.user)
|
|
|
|
def test_notification_settings_view(self):
|
|
self.client.force_login(self.user)
|
|
# GET settings page
|
|
response = self.client.get(reverse('notifications:settings'))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# POST updated settings
|
|
response = self.client.post(reverse('notifications:settings'), {
|
|
'preferred_language': 'nl',
|
|
'notification_reminder_enabled': 'on',
|
|
'notification_reminder_emails': 'custom@example.com, other@example.com',
|
|
'notification_reminder_delay_hours': 12,
|
|
})
|
|
self.assertEqual(response.status_code, 302)
|
|
|
|
self.config.refresh_from_db()
|
|
self.assertEqual(self.config.preferred_language, 'nl')
|
|
self.assertTrue(self.config.notification_reminder_enabled)
|
|
self.assertEqual(self.config.notification_reminder_emails, 'custom@example.com, other@example.com')
|
|
self.assertEqual(self.config.notification_reminder_delay_hours, 12)
|
|
|
|
from django.test import override_settings
|
|
|
|
@override_settings(EMAIL_OVERRIDE=None)
|
|
def test_send_unread_notification_reminders_command(self):
|
|
from datetime import timedelta
|
|
from django.utils import timezone
|
|
from django.core import mail
|
|
from django.core.management import call_command
|
|
from notifications.models import Notification, NotificationRecipient
|
|
|
|
# Configure user for reminders
|
|
self.config.notification_reminder_enabled = True
|
|
self.config.notification_reminder_delay_hours = 2
|
|
self.config.save()
|
|
|
|
# Create unread notification created 3 hours ago (> 2h delay)
|
|
past_time = timezone.now() - timedelta(hours=3)
|
|
notif = Notification.objects.create(
|
|
title="Notification urgente non lue",
|
|
content="Détail de la notification",
|
|
notification_type=Notification.TYPE_ALERT,
|
|
)
|
|
recipient = NotificationRecipient.objects.create(
|
|
notification=notif,
|
|
user=self.user,
|
|
)
|
|
# Backdate notification creation
|
|
Notification.objects.filter(pk=notif.pk).update(created_at=past_time)
|
|
|
|
# Run management command
|
|
call_command('send_unread_notification_reminders')
|
|
|
|
# Check that 1 email was sent
|
|
self.assertEqual(len(mail.outbox), 1)
|
|
sent_email = mail.outbox[0]
|
|
self.assertIn("Notification urgente non lue", sent_email.body)
|
|
self.assertIn('test@example.com', sent_email.to)
|
|
|
|
# Verify reminder_sent_at is set
|
|
recipient.refresh_from_db()
|
|
self.assertIsNotNone(recipient.reminder_sent_at)
|
|
|
|
@override_settings(EMAIL_OVERRIDE=None)
|
|
def test_send_unread_notification_reminders_multilingual(self):
|
|
from datetime import timedelta
|
|
from django.utils import timezone
|
|
from django.core import mail
|
|
from django.core.management import call_command
|
|
from notifications.models import Notification, NotificationRecipient
|
|
|
|
self.config.notification_reminder_enabled = True
|
|
self.config.notification_reminder_delay_hours = 1
|
|
self.config.preferred_language = 'nl'
|
|
self.config.save()
|
|
|
|
past_time = timezone.now() - timedelta(hours=2)
|
|
notif = Notification.objects.create(
|
|
title="Dringende melding",
|
|
content="Details",
|
|
notification_type=Notification.TYPE_ALERT,
|
|
)
|
|
recipient = NotificationRecipient.objects.create(
|
|
notification=notif,
|
|
user=self.user,
|
|
)
|
|
Notification.objects.filter(pk=notif.pk).update(created_at=past_time)
|
|
|
|
mail.outbox.clear()
|
|
call_command('send_unread_notification_reminders')
|
|
|
|
self.assertEqual(len(mail.outbox), 1)
|
|
sent_email = mail.outbox[0]
|
|
# In Dutch, subject contains 'Herinnering'
|
|
self.assertIn("Herinnering", sent_email.subject)
|
|
|