From 4035fea8c9660c76c723622aaae9c0d835d98a56 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Wed, 10 Apr 2024 15:44:02 +0200 Subject: [PATCH] Added unit tests --- modoboa/sievefilters/api/v2/serializers.py | 1 - modoboa/sievefilters/api/v2/tests.py | 113 +++++++++++++++++++++ modoboa/sievefilters/api/v2/viewsets.py | 7 +- modoboa/sievefilters/lib.py | 2 +- modoboa/sievefilters/mocks.py | 11 +- modoboa/sievefilters/tests.py | 2 - 6 files changed, 125 insertions(+), 11 deletions(-) create mode 100644 modoboa/sievefilters/api/v2/tests.py diff --git a/modoboa/sievefilters/api/v2/serializers.py b/modoboa/sievefilters/api/v2/serializers.py index 8091da1d6..92784eb86 100644 --- a/modoboa/sievefilters/api/v2/serializers.py +++ b/modoboa/sievefilters/api/v2/serializers.py @@ -156,7 +156,6 @@ class ActionArgumentSerializer(serializers.Serializer): choices = serializers.SerializerMethodField(required=False) def get_choices(self, obj): - print(obj) if "vloader" not in obj: return None loader = getattr(vloaders, obj["vloader"]) diff --git a/modoboa/sievefilters/api/v2/tests.py b/modoboa/sievefilters/api/v2/tests.py new file mode 100644 index 000000000..17907468c --- /dev/null +++ b/modoboa/sievefilters/api/v2/tests.py @@ -0,0 +1,113 @@ +"""API v2 tests.""" + +from unittest import mock + +from django.urls import reverse + +from rest_framework.authtoken.models import Token + +from modoboa.admin import factories as admin_factories +from modoboa.core import models as core_models +from modoboa.lib.tests import ModoAPITestCase +from modoboa.sievefilters import mocks + + +class FilterSetViewSetTestCase(ModoAPITestCase): + + @classmethod + def setUpTestData(cls): + """Create some users.""" + super().setUpTestData() + admin_factories.populate_database() + cls.user = core_models.User.objects.get(username="user@test.com") + + def setUp(self): + """Connect with a simpler user.""" + super().setUp() + patcher = mock.patch("sievelib.managesieve.Client") + self.mock_client = patcher.start() + self.mock_client.return_value = mocks.ManagesieveClientMock() + self.addCleanup(patcher.stop) + + patcher = mock.patch("imaplib.IMAP4") + self.mock_imap4 = patcher.start() + self.mock_imap4.return_value = mocks.IMAP4Mock() + self.addCleanup(patcher.stop) + + def authenticate(self, username: str = "user@test.com"): + # FIXME: replace ASAP with an oauth2 token + token = Token.objects.create( + user=core_models.User.objects.get(username=username) + ) + self.client.credentials(HTTP_AUTHORIZATION="Token " + token.key) + + def test_list(self): + self.authenticate() + url = reverse("v2:filterset-list") + resp = self.client.get(url) + self.assertEqual(resp.status_code, 200) + self.assertEqual(len(resp.json()), 2) + + def test_create(self): + self.authenticate() + url = reverse("v2:filterset-list") + data = {"name": "Test script", "active": True} + resp = self.client.post(url, data, format="json") + self.assertEqual(resp.status_code, 201) + + def test_update(self): + self.authenticate() + url = reverse("v2:filterset-detail", args=["unknown"]) + data = {"content": "# Empty script"} + resp = self.client.put(url, data, format="json") + self.assertEqual(resp.status_code, 404) + + url = reverse("v2:filterset-detail", args=["main_script"]) + resp = self.client.put(url, data, format="json") + self.assertEqual(resp.status_code, 200) + + def test_activate(self): + self.authenticate() + url = reverse("v2:filterset-activate", args=["unknown"]) + resp = self.client.post(url) + self.assertEqual(resp.status_code, 404) + + url = reverse("v2:filterset-activate", args=["main_script"]) + resp = self.client.post(url) + self.assertEqual(resp.status_code, 200) + + def test_download(self): + self.authenticate() + url = reverse("v2:filterset-download", args=["unknown"]) + resp = self.client.get(url) + self.assertEqual(resp.status_code, 404) + + url = reverse("v2:filterset-download", args=["main_script"]) + resp = self.client.get(url) + self.assertEqual(resp.status_code, 200) + + def test_delete(self): + self.authenticate() + url = reverse("v2:filterset-detail", args=["unknown"]) + resp = self.client.delete(url) + self.assertEqual(resp.status_code, 404) + + url = reverse("v2:filterset-detail", args=["main_script"]) + resp = self.client.delete(url) + self.assertEqual(resp.status_code, 204) + + def test_retrieve_condition_templates(self): + self.authenticate() + url = reverse("v2:filterset-condition-templates") + resp = self.client.get(url) + self.assertEqual(resp.status_code, 200) + self.assertEqual(len(resp.json()), 5) + + def test_retrieve_action_templates(self): + self.authenticate() + url = reverse("v2:filterset-action-templates") + resp = self.client.get(url) + self.assertEqual(resp.status_code, 200) + actions = resp.json() + self.assertEqual(len(actions), 4) + self.assertIn("choices", actions[0]["args"][0]) diff --git a/modoboa/sievefilters/api/v2/viewsets.py b/modoboa/sievefilters/api/v2/viewsets.py index db084ab6d..e53bf9f97 100644 --- a/modoboa/sievefilters/api/v2/viewsets.py +++ b/modoboa/sievefilters/api/v2/viewsets.py @@ -1,7 +1,6 @@ """Sievefilters viewsets.""" import copy -from typing import Optional from sievelib.commands import BadArgument, BadValue from sievelib.factory import FilterAlreadyExists @@ -70,7 +69,7 @@ class FilterSetViewSet(viewsets.ViewSet): """Update filter set content.""" sclient = self.get_sieve_client(request) try: - fset = sclient.getscript(pk) + sclient.getscript(pk) except SieveClientError: return response.Response(status=404) serializer = serializers.FilterSetContentSerializer( @@ -89,7 +88,7 @@ class FilterSetViewSet(viewsets.ViewSet): """Activate an existing filter set.""" sclient = self.get_sieve_client(request) try: - fset = sclient.getscript(pk, format="fset") + sclient.getscript(pk, format="fset") except SieveClientError: return response.Response(status=404) try: @@ -116,7 +115,7 @@ class FilterSetViewSet(viewsets.ViewSet): """Delete an existing filter set.""" sclient = self.get_sieve_client(request) try: - fset = sclient.getscript(pk, format="fset") + sclient.getscript(pk, format="fset") except SieveClientError: return response.Response(status=404) sclient.deletescript(pk) diff --git a/modoboa/sievefilters/lib.py b/modoboa/sievefilters/lib.py index 61a6bfcf7..68194871f 100644 --- a/modoboa/sievefilters/lib.py +++ b/modoboa/sievefilters/lib.py @@ -63,7 +63,7 @@ class SieveClient: if self.msc is not None: try: self.msc.capability() - except managesieve.Error as e: + except managesieve.Error: pass else: return diff --git a/modoboa/sievefilters/mocks.py b/modoboa/sievefilters/mocks.py index b2370a355..940a89ada 100644 --- a/modoboa/sievefilters/mocks.py +++ b/modoboa/sievefilters/mocks.py @@ -26,9 +26,11 @@ if anyof (header :contains "Subject" "toto", not header :contains "To" "peƩ") { """ -class ManagesieveClientMock(object): +class ManagesieveClientMock: """Fake managesieve client.""" + errmsg: bytes = b"" + def __init__(self, *args, **kwargs): self.scripts = { "main_script": SAMPLE_SIEVE_SCRIPT, @@ -37,7 +39,7 @@ class ManagesieveClientMock(object): } def connect(self, username, password, **kwargs): - return username == "user@test.com" and password == "toto" + return username == "user@test.com" def logout(self): return True @@ -70,8 +72,11 @@ class ManagesieveClientMock(object): def deletescript(self, name): return True + def checkscript(self, content): + return True -class IMAP4Mock(object): + +class IMAP4Mock: """Fake IMAP4 client.""" def __init__(self, *args, **kwargs): diff --git a/modoboa/sievefilters/tests.py b/modoboa/sievefilters/tests.py index 998142514..61d777323 100644 --- a/modoboa/sievefilters/tests.py +++ b/modoboa/sievefilters/tests.py @@ -1,5 +1,3 @@ -# coding: utf-8 - """Sievefilters tests.""" from unittest import mock