loko/streetup/home/tests.py

254 lines
10 KiB
Python

from django.contrib.auth import get_user_model
from django.test import TestCase
from datetime import date
from common.models import Role, Thematic, UserConfig, UserThematics
from contracts.models import Company, CompanyTeam, Contract
from home.models import HomeWidget, HomeWidgetConditionGroup, HomeWidgetCondition
class HomeWidgetConditionTests(TestCase):
def setUp(self):
User = get_user_model()
self.user = User.objects.create_user('testuser', password='pass')
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
self.widget = HomeWidget.objects.create(widget_code='intervention_stats')
self.group = HomeWidgetConditionGroup.objects.create(
widget=self.widget,
label='Test Group',
order=1,
priority=10
)
# Role
self.role_admin, _ = Role.objects.get_or_create(name='admin')
self.role_tech, _ = Role.objects.get_or_create(name='technician')
# Team
self.company = Company.objects.create(name='Test Company')
self.team_a = CompanyTeam.objects.create(name='Team A', company=self.company)
self.team_b = CompanyTeam.objects.create(name='Team B', company=self.company)
# Contract
self.contract_a = Contract.objects.create(
company=self.company,
contract_number='C-001',
start_date=date(2026, 1, 1),
end_date=date(2026, 12, 31)
)
self.contract_b = Contract.objects.create(
company=self.company,
contract_number='C-002',
start_date=date(2026, 1, 1),
end_date=date(2026, 12, 31)
)
# Thematic
self.thematic_a = Thematic.objects.create(code='THEME-A', name_fr='Thema A', name_nl='Thema A')
self.thematic_b = Thematic.objects.create(code='THEME-B', name_fr='Thema B', name_nl='Thema B')
def test_role_condition_evaluation(self):
# 1. Non-negated: User has role -> True
self.user_config.roles.add(self.role_admin)
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='role',
role=self.role_admin,
is_negated=False
)
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
# User does not have role -> False
cond.role = self.role_tech
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# 2. Negated: User has role -> False
cond.role = self.role_admin
cond.is_negated = True
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# User does not have role -> True
cond.role = self.role_tech
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
def test_team_condition_evaluation(self):
# 1. Non-negated: User team matches -> True
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='team',
team=self.team_a,
is_negated=False
)
self.assertTrue(cond.evaluate(self.user_config, self.team_a, Contract.objects.none()))
# User team does not match -> False
self.assertFalse(cond.evaluate(self.user_config, self.team_b, Contract.objects.none()))
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# 2. Negated: User team matches -> False
cond.is_negated = True
cond.save()
self.assertFalse(cond.evaluate(self.user_config, self.team_a, Contract.objects.none()))
# User team does not match -> True
self.assertTrue(cond.evaluate(self.user_config, self.team_b, Contract.objects.none()))
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
def test_contract_condition_evaluation(self):
# 1. Non-negated: User has contract -> True
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='contract',
contract=self.contract_a,
is_negated=False
)
user_contracts = Contract.objects.filter(id=self.contract_a.id)
self.assertTrue(cond.evaluate(self.user_config, None, user_contracts))
# User does not have contract -> False
other_contracts = Contract.objects.filter(id=self.contract_b.id)
self.assertFalse(cond.evaluate(self.user_config, None, other_contracts))
# 2. Negated: User has contract -> False
cond.is_negated = True
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, user_contracts))
# User does not have contract -> True
self.assertTrue(cond.evaluate(self.user_config, None, other_contracts))
def test_thematic_condition_evaluation(self):
# 1. Non-negated: User has thematic -> True
UserThematics.objects.create(user_config=self.user_config, thematic=self.thematic_a)
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='thematic',
thematic=self.thematic_a,
is_negated=False
)
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
# User does not have thematic -> False
cond.thematic = self.thematic_b
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# 2. Negated: User has thematic -> False
cond.thematic = self.thematic_a
cond.is_negated = True
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# User does not have thematic -> True
cond.thematic = self.thematic_b
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
def test_is_intern_condition_evaluation(self):
# 1. Non-negated: matches -> True
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='is_intern',
is_intern=True,
is_negated=False
)
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
# Does not match -> False
cond.is_intern = False
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# 2. Negated: matches -> False
cond.is_intern = True
cond.is_negated = True
cond.save()
self.assertFalse(cond.evaluate(self.user_config, None, Contract.objects.none()))
# Does not match -> True
cond.is_intern = False
self.assertTrue(cond.evaluate(self.user_config, None, Contract.objects.none()))
def test_condition_summary_and_string_representation(self):
cond = HomeWidgetCondition.objects.create(
group=self.group,
condition_type='role',
role=self.role_admin,
is_negated=False
)
self.assertEqual(str(cond), "Role: admin")
self.assertEqual(self.group.get_summary(), "role=admin")
cond.is_negated = True
cond.save()
self.assertEqual(str(cond), "NOT Role: admin")
self.assertEqual(self.group.get_summary(), "not(role=admin)")
class HomeIndexViewTests(TestCase):
def test_home_index_inspector_link(self):
from django.urls import reverse
from django.contrib.auth import get_user_model
from common.models import Role, UserConfig
User = get_user_model()
user = User.objects.create_user('inspector_user', password='pass')
user_config = UserConfig.objects.create(user=user)
inspector_role, _ = Role.objects.get_or_create(name='inspector')
user_config.roles.add(inspector_role)
self.client.force_login(user)
response = self.client.get(reverse('home:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, reverse('inspections:quick_inspection_map'))
self.assertNotContains(response, 'data-bs-target="#newInspectionModal"')
def test_home_index_unread_notifications_banner(self):
from django.urls import reverse
from django.contrib.auth import get_user_model
from common.models import UserConfig
from notifications.models import Notification, NotificationRecipient
User = get_user_model()
user = User.objects.create_user('notif_user', password='pass')
UserConfig.objects.create(user=user)
self.client.force_login(user)
# 1. No unread notifications -> banner not shown
response = self.client.get(reverse('home:index'))
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, 'id="home-unread-notifications-alert"')
# 2. Add unread notification -> banner shown with count
notif = Notification.objects.create(title="Test notification")
NotificationRecipient.objects.create(notification=notif, user=user)
response = self.client.get(reverse('home:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'id="home-unread-notifications-alert"')
self.assertContains(response, 'Vous avez <strong class="home-unread-notifications-count">1</strong> notification non lue.')
def test_home_index_intervention_on_pause_widget(self):
from django.urls import reverse
from django.contrib.auth import get_user_model
from common.models import UserConfig
from home.models import HomeWidget
User = get_user_model()
user = User.objects.create_user('pause_widget_user', password='pass')
UserConfig.objects.create(user=user)
self.client.force_login(user)
# Create the widget
HomeWidget.objects.create(widget_code='intervention_on_pause')
response = self.client.get(reverse('home:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Interventions en pause')
self.assertContains(response, 'status=on_pause')