import json from django.test import TestCase, Client, RequestFactory, override_settings from django.urls import reverse from .models import ContactRequest from .context_processors import site_context # ───────────────────────────────────────────── # Helpers # ───────────────────────────────────────────── VALID_CONTACT = { 'last_name': 'Coulibaly', 'first_name': 'Israel', 'email': 'test@jool-int.com', 'phone': '+225 07 00 00 00', 'message': 'Demande de démonstration.', } # ───────────────────────────────────────────── # Pages publiques — codes HTTP # ───────────────────────────────────────────── class PublicPagesTest(TestCase): def setUp(self): self.client = Client() def _get(self, name): return self.client.get(reverse(f'core:{name}')) def test_home_200(self): self.assertEqual(self._get('home').status_code, 200) def test_about_200(self): self.assertEqual(self._get('about').status_code, 200) def test_kiriq_200(self): self.assertEqual(self._get('kiriq').status_code, 200) def test_monitor_200(self): self.assertEqual(self._get('monitor').status_code, 200) def test_joolid_200(self): self.assertEqual(self._get('joolid').status_code, 200) def test_monagro_200(self): self.assertEqual(self._get('monagro').status_code, 200) def test_privacy_200(self): self.assertEqual(self._get('privacy').status_code, 200) def test_robots_txt_200(self): r = self._get('robots_txt') self.assertEqual(r.status_code, 200) self.assertIn('text/plain', r['Content-Type']) def test_sitemap_xml_200(self): r = self._get('sitemap_xml') self.assertEqual(r.status_code, 200) self.assertIn('xml', r['Content-Type']) # ───────────────────────────────────────────── # Templates — contenu minimal # ───────────────────────────────────────────── class TemplateContentTest(TestCase): def test_home_contains_products(self): r = self.client.get(reverse('core:home')) self.assertContains(r, 'KIRIQ') self.assertContains(r, 'Jool Monitor') self.assertContains(r, 'Jool ID') self.assertContains(r, 'Mon Agro') def test_kiriq_page_title(self): r = self.client.get(reverse('core:kiriq')) self.assertContains(r, 'KIRIQ') def test_monitor_page_title(self): r = self.client.get(reverse('core:monitor')) self.assertContains(r, 'Monitor') def test_joolid_page_title(self): r = self.client.get(reverse('core:joolid')) self.assertContains(r, 'Jool ID') def test_monagro_page_title(self): r = self.client.get(reverse('core:monagro')) self.assertContains(r, 'Mon Agro') def test_about_has_solutions_section(self): r = self.client.get(reverse('core:about')) self.assertContains(r, 'Nos solutions') self.assertContains(r, 'Mon Agro') def test_privacy_noindex(self): r = self.client.get(reverse('core:privacy')) self.assertContains(r, 'noindex') def test_robots_txt_content(self): r = self.client.get(reverse('core:robots_txt')) content = r.content.decode() self.assertIn('User-agent', content) self.assertIn('sitemap', content.lower()) def test_sitemap_xml_has_urls(self): r = self.client.get(reverse('core:sitemap_xml')) content = r.content.decode() self.assertIn('', content) self.assertIn('jool-international.com', content) # ───────────────────────────────────────────── # Formulaire de contact # ───────────────────────────────────────────── class ContactFormTest(TestCase): def setUp(self): self.url = reverse('core:contact_ajax') def _post(self, data): return self.client.post( self.url, data, HTTP_X_REQUESTED_WITH='XMLHttpRequest', ) @override_settings( EMAIL_BACKEND='django.core.mail.backends.dummy.EmailBackend' ) def test_valid_form_creates_contact(self): r = self._post(VALID_CONTACT) self.assertEqual(r.status_code, 200) body = json.loads(r.content) self.assertTrue(body['ok']) self.assertEqual(ContactRequest.objects.count(), 1) obj = ContactRequest.objects.first() self.assertEqual(obj.email, 'test@jool-int.com') def test_missing_required_fields_returns_400(self): r = self._post({'last_name': 'Coulibaly'}) self.assertEqual(r.status_code, 400) body = json.loads(r.content) self.assertFalse(body['ok']) self.assertIn('errors', body) def test_invalid_email_returns_400(self): data = {**VALID_CONTACT, 'email': 'pas-un-email'} r = self._post(data) self.assertEqual(r.status_code, 400) body = json.loads(r.content) self.assertFalse(body['ok']) def test_invalid_phone_returns_400(self): data = {**VALID_CONTACT, 'phone': 'abc!!!'} r = self._post(data) self.assertEqual(r.status_code, 400) body = json.loads(r.content) self.assertFalse(body['ok']) def test_get_method_not_allowed(self): r = self.client.get(self.url) self.assertEqual(r.status_code, 405) @override_settings( EMAIL_BACKEND='django.core.mail.backends.dummy.EmailBackend' ) def test_phone_optional(self): data = {k: v for k, v in VALID_CONTACT.items() if k != 'phone'} r = self._post(data) self.assertEqual(r.status_code, 200) self.assertTrue(json.loads(r.content)['ok']) # ───────────────────────────────────────────── # Modèle ContactRequest # ───────────────────────────────────────────── class ContactRequestModelTest(TestCase): def test_str_representation(self): obj = ContactRequest( first_name='Israel', last_name='Coulibaly', email='test@jool-int.com', ) self.assertIn('Israel', str(obj)) self.assertIn('Coulibaly', str(obj)) def test_is_read_default_false(self): obj = ContactRequest.objects.create(**VALID_CONTACT) self.assertFalse(obj.is_read) def test_ordering_newest_first(self): ContactRequest.objects.create(**VALID_CONTACT) data2 = {**VALID_CONTACT, 'email': 'second@jool-int.com'} ContactRequest.objects.create(**data2) first = ContactRequest.objects.first() self.assertEqual(first.email, 'second@jool-int.com') # ───────────────────────────────────────────── # Context processor — careers_enabled # ───────────────────────────────────────────── class ContextProcessorTest(TestCase): def setUp(self): self.factory = RequestFactory() @override_settings(CAREERS_ENABLED=False) def test_careers_disabled_in_context(self): r = self.client.get(reverse('core:home')) self.assertFalse(r.context['careers_enabled']) self.assertNotContains(r, 'Carrières') @override_settings(CAREERS_ENABLED=False) def test_careers_disabled_returns_false(self): request = self.factory.get('/') ctx = site_context(request) self.assertFalse(ctx['careers_enabled']) self.assertEqual(ctx['open_jobs_count'], 0) @override_settings(CAREERS_ENABLED=True) def test_careers_enabled_returns_true(self): request = self.factory.get('/') ctx = site_context(request) self.assertTrue(ctx['careers_enabled']) self.assertIn('open_jobs_count', ctx)