wip: Radicale extension #574

Unit tests.
This commit is contained in:
Antoine Nguyen
2014-06-27 14:58:16 +02:00
parent faaf1f628c
commit 314f60b87b
8 changed files with 325 additions and 21 deletions
+1
View File
@@ -21,6 +21,7 @@ class GroupFactory(factory.DjangoModelFactory):
class UserFactory(PermissionFactory):
FACTORY_FOR = models.User
FACTORY_DJANGO_GET_OR_CREATE = ("username", )
email = factory.LazyAttribute(lambda a: a.username)
password = '{PLAIN}toto'
+9
View File
@@ -1,9 +1,15 @@
"""
Fixtures factories.
"""
import factory
from modoboa.core.factories import PermissionFactory, UserFactory
from . import models
class DomainFactory(PermissionFactory):
FACTORY_FOR = models.Domain
FACTORY_DJANGO_GET_OR_CREATE = ("name", )
quota = 10
enabled = True
@@ -12,6 +18,8 @@ class DomainFactory(PermissionFactory):
class MailboxFactory(PermissionFactory):
FACTORY_FOR = models.Mailbox
domain = factory.SubFactory(DomainFactory)
user = factory.SubFactory(UserFactory)
quota = 10
enabled = True
@@ -21,6 +29,7 @@ class AliasFactory(PermissionFactory):
enabled = True
def populate_database():
"""Create test data.
+2 -2
View File
@@ -4,9 +4,9 @@ from modoboa.lib import parameters
from modoboa.core.models import User
from modoboa.core.factories import UserFactory
from modoboa.extensions.admin.factories import (
DomainFactory, MailboxFactory, populate_database
populate_database
)
from modoboa.extensions.admin.models import Alias, Domain, DomainAlias
from modoboa.extensions.admin.models import Alias, Domain
from modoboa.extensions.limits.models import LimitTemplates
+31
View File
@@ -0,0 +1,31 @@
"""
Fixtures factories.
"""
import factory
from modoboa.extensions.admin.factories import (
DomainFactory, MailboxFactory
)
from . import models
class UserCalendarFactory(factory.DjangoModelFactory):
FACTORY_FOR = models.UserCalendar
name = factory.Sequence(lambda n: 'User calendar %s' % n)
mailbox = factory.SubFactory(MailboxFactory)
class SharedCalendarFactory(factory.DjangoModelFactory):
FACTORY_FOR = models.SharedCalendar
name = factory.Sequence(lambda n: 'Shared calendar %s' % n)
domain = factory.SubFactory(DomainFactory)
class AccessRuleFactory(factory.DjangoModelFactory):
FACTORY_FOR = models.AccessRule
mailbox = factory.SubFactory(MailboxFactory)
calendar = factory.SubFactory(UserCalendarFactory)
@@ -4,7 +4,9 @@ from optparse import make_option
from django.core.management.base import BaseCommand
from modoboa.core.models import User
from modoboa.lib import parameters
from modoboa.extensions.admin import Domain
from modoboa.extensions.radicale import Radicale
from modoboa.extensions.radicale.models import (
AccessRule
@@ -24,14 +26,14 @@ class Command(BaseCommand):
def _generate_acr(self, name, user, collection, perm="rw", comment=None):
"""Write a new access control rule to the config file.
"""
if comment is not None:
self._cfgfile.write("\n# %s" % comment)
self._cfgfile.write("""
%s
[%s]
user = %s
collection = %s
permission = %s
""" % ("" if comment is None else ("# %s" % comment),
name, user, collection, perm)
""" % (name, user, collection, perm)
)
def _user_access_rules(self):
@@ -39,7 +41,7 @@ permission = %s
"""
for acr in AccessRule.objects.select_related().all():
section = "%s-to-%s-acr" % (
acr.calendar.mailbox, acr.mailbox
acr.mailbox, acr.calendar
)
permission = ""
if acr.read:
@@ -54,7 +56,7 @@ permission = %s
"""Generate access rules for super administrators.
"""
for sa in User.objects.filter(is_superuser=True):
section = "[sa-%s-acr]" % sa.username
section = "sa-%s-acr" % sa.username
self._generate_acr(
section, sa.username, ".*"
)
@@ -64,7 +66,7 @@ permission = %s
"""
for da in User.objects.filter(groups__name="DomainAdmins"):
for domain in Domain.objects.get_for_admin(da):
section = "[da-%s-to-%s-acr]" % (da.email, da.name)
section = "da-%s-to-%s-acr" % (da.email, domain.name)
self._generate_acr(
section, da.email, "%s/user/.*" % domain.name
)
+264 -11
View File
@@ -1,16 +1,269 @@
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
Replace this with more appropriate tests for your application.
Radicale extension unit tests.
"""
import os
import tempfile
from ConfigParser import SafeConfigParser
from django.test import TestCase
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.core import management
from modoboa.lib import parameters
from modoboa.lib.tests import ExtTestCase
from modoboa.extensions.admin.factories import (
MailboxFactory, populate_database
)
from modoboa.extensions.admin.models import (
Domain, Mailbox
)
from .factories import (
UserCalendarFactory, SharedCalendarFactory, AccessRuleFactory
)
from .models import UserCalendar, SharedCalendar, AccessRule
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
class UserCalendarTestCase(ExtTestCase):
fixtures = ["initial_users.json"]
def setUp(self):
super(UserCalendarTestCase, self).setUp()
self.activate_extensions('radicale')
populate_database()
def assertRuleEqual(self, calname, username, read=False, write=False):
acr = AccessRule.objects.get(
mailbox__user__username=username,
calendar__name=calname)
self.assertEqual(acr.read, read)
self.assertEqual(acr.write, write)
def test_add_calendar(self):
MailboxFactory(
address="polo", domain__name="test.com",
user__username="polo@test.com")
# As a super administrator
mbox = Mailbox.objects.get(address='user', domain__name='test.com')
values = {
"name": "Test calendar",
"mailbox": mbox.pk,
"username": "admin@test.com",
"read_access": 1,
"stepid": "step2"
}
self.ajax_post(
reverse("new_user_calendar"), values)
self.clt.logout()
self.assertRuleEqual("Test calendar", "admin@test.com", read=True)
# As a domain administrator
self.clt.login(username="admin@test.com", password="toto")
values = {
"name": "Test calendar 2",
"mailbox": mbox.pk,
"username": "admin@test.com",
"read_access": 1,
"write_access": 1,
"stepid": "step2"
}
self.ajax_post(
reverse("new_user_calendar"), values)
self.clt.logout()
self.assertRuleEqual(
"Test calendar 2", "admin@test.com", read=True, write=True
)
# As a user
self.clt.login(username="user@test.com", password="toto")
values = {
"name": "My calendar",
"username": "admin@test.com",
"read_access": 1,
"write_access": 1,
"username_1": "polo@test.com",
"write_access_1": 1,
"stepid": "step2"
}
self.ajax_post(
reverse("new_user_calendar"), values)
UserCalendar.objects.get(name="My calendar")
self.assertRuleEqual(
"My calendar", "admin@test.com", read=True, write=True)
self.assertRuleEqual("My calendar", "polo@test.com", write=True)
def test_edit_calendar(self):
cal = UserCalendarFactory(
mailbox__user__username='test@modoboa.org',
mailbox__address='test', mailbox__domain__name='modoboa.org')
values = {
"name": "Modified", "mailbox": cal.mailbox.pk
}
self.ajax_post(
reverse("user_calendar", args=[cal.pk]), values
)
def test_del_calendar(self):
cal = UserCalendarFactory(
mailbox__user__username='test@modoboa.org',
mailbox__address='test', mailbox__domain__name='modoboa.org')
self.ajax_delete(
reverse("user_calendar", args=[cal.pk])
)
with self.assertRaises(ObjectDoesNotExist):
UserCalendar.objects.get(pk=cal.pk)
def test_del_calendar_denied(self):
cal = UserCalendarFactory(
mailbox__user__username='test@modoboa.org',
mailbox__address='test', mailbox__domain__name='modoboa.org')
self.clt.logout()
self.clt.login(username="admin@test.com", password="toto")
self.ajax_delete(
reverse("user_calendar", args=[cal.pk]), status=403
)
def test_add_calendar_denied(self):
self.clt.logout()
self.clt.login(username="admin@test.com", password="toto")
values = {
"name": "Test calendar",
"mailbox": Mailbox.objects.get(
address="user", domain__name="test2.com").pk,
"stepid": "step2"
}
self.ajax_post(
reverse("new_user_calendar"), values, status=400)
class SharedCalendarTestCase(ExtTestCase):
fixtures = ["initial_users.json"]
def setUp(self):
super(SharedCalendarTestCase, self).setUp()
self.activate_extensions('radicale')
populate_database()
def test_add_calendar(self):
# As a super administrator
domain = Domain.objects.get(name="test.com")
values = {
"name": "Test calendar",
"domain": domain.pk,
}
self.ajax_post(
reverse("new_shared_calendar"), values)
self.clt.logout()
# As a domain administrator
self.clt.login(username="admin@test.com", password="toto")
values = {
"name": "Test calendar 2",
"domain": domain.pk
}
self.ajax_post(
reverse("new_shared_calendar"), values)
self.clt.logout()
def test_add_calendar_denied(self):
self.clt.logout()
self.clt.login(username="admin@test.com", password="toto")
values = {
"name": "Test calendar",
"domain": Domain.objects.get(name="test2.com")
}
self.ajax_post(
reverse("new_shared_calendar"), values, status=400)
def test_edit_calendar(self):
cal = SharedCalendarFactory(
domain__name='modoboa.org')
values = {
"name": "Modified", "domain": cal.domain.pk
}
self.ajax_post(
reverse("shared_calendar", args=[cal.pk]), values
)
cal = SharedCalendar.objects.get(pk=cal.pk)
self.assertEqual(cal.name, "Modified")
def test_del_calendar(self):
cal = SharedCalendarFactory(domain__name='modoboa.org')
self.ajax_delete(
reverse("shared_calendar", args=[cal.pk])
)
with self.assertRaises(ObjectDoesNotExist):
SharedCalendar.objects.get(pk=cal.pk)
def test_del_calendar_denied(self):
cal = SharedCalendarFactory(domain__name='modoboa.org')
self.clt.logout()
self.clt.login(username="admin@test.com", password="toto")
self.ajax_delete(
reverse("shared_calendar", args=[cal.pk]), status=403
)
class AccessRuleTestCase(ExtTestCase):
fixtures = ["initial_users.json"]
def setUp(self):
super(AccessRuleTestCase, self).setUp()
self.activate_extensions('radicale')
populate_database()
self.rights_file_path = tempfile.mktemp()
parameters.save_admin(
"RIGHTS_FILE_PATH", self.rights_file_path, app="radicale")
def tearDown(self):
os.unlink(self.rights_file_path)
def test_rights_file_generation(self):
mbox = Mailbox.objects.get(address="admin", domain__name="test.com")
cal = UserCalendarFactory(mailbox=mbox)
AccessRuleFactory(
mailbox=Mailbox.objects.get(
address="user", domain__name="test.com"),
calendar=cal, read=True)
management.call_command("generate_rights", verbosity=False)
cfg = SafeConfigParser()
with open(self.rights_file_path) as fpo:
cfg.readfp(fpo)
# Check mandatory rules
self.assertTrue(cfg.has_section("domain-shared-calendars"))
self.assertTrue(cfg.has_section("owners-access"))
# Check user-defined rules
section = "user@test.com-to-User calendar 1-acr"
self.assertTrue(cfg.has_section(section))
self.assertEqual(cfg.get(section, "user"), "user@test.com")
self.assertEqual(
cfg.get(section, "collection"),
"test.com/user/admin/User calendar 1"
)
self.assertEqual(cfg.get(section, "permission"), "r")
def test_rights_file_generation_with_admin(self):
parameters.save_admin(
"ALLOW_CALENDARS_ADMINISTRATION", "yes", app="radicale")
management.call_command("generate_rights", verbosity=False)
cfg = SafeConfigParser()
with open(self.rights_file_path) as fpo:
cfg.readfp(fpo)
# Check mandatory rules
self.assertTrue(cfg.has_section("domain-shared-calendars"))
self.assertTrue(cfg.has_section("owners-access"))
# Super admin rules
section = "sa-admin-acr"
self.assertTrue(cfg.has_section(section))
# Domain admin rules
for section in ["da-admin@test.com-to-test.com-acr",
"da-admin@test2.com-to-test2.com-acr"]:
self.assertTrue(cfg.has_section(section))
+9 -1
View File
@@ -13,7 +13,9 @@ class ModoTestCase(TestCase):
self.clt = Client()
self.assertEqual(self.clt.login(username=username, password=password), True)
def ajax_request(self, method, url, params, status=200):
def ajax_request(self, method, url, params=None, status=200):
if params is None:
params = {}
response = getattr(self.clt, method) \
(url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(response.status_code, status)
@@ -22,6 +24,12 @@ class ModoTestCase(TestCase):
def ajax_post(self, *args, **kwargs):
return self.ajax_request('post', *args, **kwargs)
def ajax_put(self, *args, **kwargs):
return self.ajax_request('put', *args, **kwargs)
def ajax_delete(self, *args, **kwargs):
return self.ajax_request('delete', *args, **kwargs)
def ajax_get(self, *args, **kwargs):
return self.ajax_request('get', *args, **kwargs)
+1 -1
View File
@@ -8,5 +8,5 @@ sievelib
chardet
argparse
rfc6266
factory-boy
factory-boy<2.4
passlib