Server IP : 85.214.239.14 / Your IP : 3.21.244.34 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /srv/modoboa/env/lib64/python3.5/site-packages/modoboa_contacts/ |
Upload File : |
# coding: utf-8 """Contacts backend tests.""" import httmock from django import forms from django.urls import reverse from django.utils import timezone from modoboa.admin import factories as admin_factories from modoboa.core import models as core_models from modoboa.lib.tests import ModoAPITestCase, ModoTestCase from modoboa.parameters import forms as param_forms from modoboa.parameters import tools as param_tools from . import factories from . import mocks from . import models class RadicaleParametersForm(param_forms.AdminParametersForm): """Since contacts plugin depends on radicale, we need this.""" app = "modoboa_radicale" server_location = forms.URLField( label="Server URL", help_text=( "The URL of your Radicale server. " "It will be used to construct calendar URLs." ), widget=forms.TextInput(attrs={"class": "form-control"}) ) param_tools.registry.add("global", RadicaleParametersForm, "Radicale") class TestDataMixin(object): """Create some data.""" @classmethod def setUpTestData(cls): """Create test data.""" super(TestDataMixin, cls).setUpTestData() admin_factories.populate_database() cls.user = core_models.User.objects.get(username="user@test.com") cls.addressbook = cls.user.addressbook_set.first() cls.category = factories.CategoryFactory(user=cls.user, name="Family") cls.contact = factories.ContactFactory( addressbook=cls.addressbook, emails=["homer@simpson.com"], phone_numbers=["01234567889"], ) factories.ContactFactory( addressbook=cls.addressbook, first_name="Marge", emails=["marge@simpson.com"], categories=[cls.category] ) factories.ContactFactory( addressbook=cls.addressbook, first_name="Bart", emails=["bart@simpson.com"]) def setUp(self): """Initiate test context.""" self.client.force_login(self.user) self.set_global_parameter( "server_location", "http://example.test/radicale/", app="modoboa_radicale") def enable_cdav_sync(self): """Enable sync. for user.""" url = reverse("core:user_preferences") with httmock.HTTMock(mocks.options_mock, mocks.mkcol_mock): response = self.client.post( url, {"modoboa_contacts-enable_carddav_sync": True, "modoboa_contacts-sync_frequency": 300}, ) self.assertEqual(response.status_code, 200) class ViewsTestCase(TestDataMixin, ModoTestCase): """Check views.""" def test_user_settings(self): """Check that remote collection creation request is sent.""" # 1. Addressbook with contacts must be synced manually data = {"username": self.user.username, "password": "toto"} self.client.post(reverse("core:login"), data) self.enable_cdav_sync() self.addressbook.refresh_from_db() self.assertIs(self.addressbook.last_sync, None) # 2. Addressbook with no contacts can be considered synced user = core_models.User.objects.get(username="user@test2.com") abook = user.addressbook_set.first() data = {"username": user.username, "password": "toto"} self.client.post(reverse("core:login"), data) abook.refresh_from_db() self.assertIs(abook.last_sync, None) # Now enable sync. self.enable_cdav_sync() abook.refresh_from_db() self.assertIsNot(abook.last_sync, None) # def test_index(self): # """Test index view.""" # url = reverse("modoboa_contacts:index") # with self.assertRaises(IOError): # response = self.client.get(url) # self.assertContains(response, '<div id="app">') class AddressBookViewSetTestCase(TestDataMixin, ModoAPITestCase): """Address book ViewSet tests.""" def test_default(self): """Test default endpoint.""" response = self.client.get(reverse("api:addressbook-default")) self.assertEqual(response.status_code, 200) self.assertEqual(response.data["name"], "Contacts") def test_sync_to_cdav(self): """Test sync to CardDAV endpoint.""" data = {"username": self.user.username, "password": "toto"} response = self.client.post(reverse("core:login"), data) self.enable_cdav_sync() with httmock.HTTMock( mocks.options_mock, mocks.mkcol_mock, mocks.put_mock, mocks.propfind_mock): response = self.client.get(reverse("api:addressbook-sync-to-cdav")) self.assertEqual(response.status_code, 200) abook = self.user.addressbook_set.first() self.assertIsNot(abook.sync_token, None) contact = abook.contact_set.first() self.assertIsNot(contact.etag, None) def test_sync_from_cdav(self): """Test sync from CardDAV endpoint.""" data = {"username": self.user.username, "password": "toto"} response = self.client.post(reverse("core:login"), data) self.enable_cdav_sync() self.user.addressbook_set.update(last_sync=timezone.now()) with httmock.HTTMock( mocks.options_mock, mocks.report_mock, mocks.get_mock): response = self.client.get( reverse("api:addressbook-sync-from-cdav")) self.assertEqual(response.status_code, 200) class CategoryViewSetTestCase(TestDataMixin, ModoAPITestCase): """Category ViewSet tests.""" def test_get_categories(self): """Check category list endpoint.""" url = reverse("api:category-list") response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) def test_create_category(self): """Create a new category.""" url = reverse("api:category-list") data = {"name": u"AmitiƩs"} response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) def test_update_category(self): """Update a category.""" url = reverse("api:category-detail", args=[self.category.pk]) data = {"name": u"Test"} response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) self.category.refresh_from_db() self.assertEqual(self.category.name, "Test") def test_delete_category(self): """Try to delete a category.""" url = reverse("api:category-detail", args=[self.category.pk]) response = self.client.delete(url) self.assertEqual(response.status_code, 204) with self.assertRaises(models.Category.DoesNotExist): self.category.refresh_from_db() class ContactViewSetTestCase(TestDataMixin, ModoAPITestCase): """Contact ViewSet tests.""" def test_contact_list(self): """Check contact list endpoint.""" url = reverse("api:contact-list") response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 3) response = self.client.get("{}?search=homer".format(url)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) def test_filter_by_category(self): """Check filtering.""" url = reverse("api:contact-list") response = self.client.get( "{}?category={}".format(url, self.category.name)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) def test_create_contact(self): """Create a new contact.""" data = {"username": self.user.username, "password": "toto"} response = self.client.post(reverse("core:login"), data) self.enable_cdav_sync() self.user.addressbook_set.update(last_sync=timezone.now()) data = { "first_name": "Magie", "last_name": "Simpson", "emails": [ {"address": "magie@simpson.com", "type": "home"} ], "phone_numbers": [ {"number": "+33123456789", "type": "home"} ] } url = reverse("api:contact-list") with httmock.HTTMock(mocks.options_mock, mocks.put_mock): response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) contact = models.Contact.objects.get(pk=response.data["pk"]) self.assertEqual(contact.emails.first().address, "magie@simpson.com") self.assertEqual( contact.phone_numbers.first().number, response.data["phone_numbers"][0]["number"]) self.assertEqual(contact.display_name, "Magie Simpson") self.assertIsNot(contact.etag, None) def test_create_contact_quick(self): """Create a contact with minimal information.""" data = { "emails": [ {"address": "magie@simpson.com", "type": "home"} ] } url = reverse("api:contact-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 400) self.assertEqual(response.data["display_name"][0], "Name or display name required") data["display_name"] = "Magie Simpson" response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) def test_create_contact_with_category(self): """Create a new contact with a category.""" data = { "first_name": "Magie", "last_name": "Simpson", "emails": [ {"address": "magie@simpson.com", "type": "home"} ], "categories": [self.category.pk] } url = reverse("api:contact-list") response = self.client.post(url, data, format="json") self.assertEqual(response.status_code, 201) contact = models.Contact.objects.get(pk=response.data["pk"]) self.assertEqual(contact.categories.first(), self.category) def test_update_contact(self): """Update existing contact.""" data = {"username": self.user.username, "password": "toto"} self.client.post(reverse("core:login"), data) self.enable_cdav_sync() self.user.addressbook_set.update(last_sync=timezone.now()) url = reverse("api:contact-detail", args=[self.contact.pk]) email_pk = self.contact.emails.first().pk data = { "first_name": "Homer 1", "last_name": "Simpson", "emails": [ {"address": "duff@simpson.com", "type": "work"}, {"address": "homer@simpson.com", "type": "other"} ], "phone_numbers": [ {"number": "+33123456789", "type": "home"}, {"number": "01234567889", "type": "work"}, ], "categories": [self.category.pk] } with httmock.HTTMock( mocks.options_mock, mocks.put_mock, mocks.report_mock): response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) self.contact.refresh_from_db() self.assertEqual(self.contact.first_name, "Homer 1") self.assertEqual(self.contact.emails.count(), 2) self.assertEqual( models.EmailAddress.objects.get(pk=email_pk).type, "other") self.assertEqual(self.contact.phone_numbers.count(), 2) self.assertEqual(self.contact.categories.first(), self.category) self.assertIsNot(self.contact.etag, None) data["emails"].pop(1) data["phone_numbers"].pop(1) with httmock.HTTMock( mocks.options_mock, mocks.put_mock, mocks.report_mock): response = self.client.put(url, data, format="json") self.assertEqual(response.status_code, 200) self.assertEqual(self.contact.emails.count(), 1) self.assertEqual(self.contact.phone_numbers.count(), 1) def test_delete_contact(self): """Try to delete a contact.""" data = {"username": self.user.username, "password": "toto"} response = self.client.post(reverse("core:login"), data) self.enable_cdav_sync() url = reverse("api:contact-detail", args=[self.contact.pk]) with httmock.HTTMock(mocks.options_mock, mocks.delete_mock): response = self.client.delete(url) self.assertEqual(response.status_code, 204) with self.assertRaises(models.Contact.DoesNotExist): self.contact.refresh_from_db() class EmailAddressViewSetTestCase(TestDataMixin, ModoAPITestCase): """EmailAddressViewSet tests.""" def test_emails_list(self): """Check list endpoint.""" url = reverse("api:emailaddress-list") response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 3) response = self.client.get("{}?search=homer".format(url)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) response = self.client.get("{}?search=Marge".format(url)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) response = self.client.get("{}?search=Simpson".format(url)) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 3)