| Server IP : 85.214.239.14 / Your IP : 216.73.216.210 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/srv/modoboa/env/lib/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)