| Server IP : 85.214.239.14 / Your IP : 216.73.216.27 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 : /srv/modoboa/env/lib/python3.5/site-packages/modoboa_webmail/tests/ |
Upload File : |
# coding: utf-8
"""Webmail tests."""
from __future__ import unicode_literals
import os
import shutil
import tempfile
try:
import mock
except ImportError:
from unittest import mock
from six import BytesIO
from django.core import mail
from django.urls import reverse
from modoboa.admin import factories as admin_factories
from modoboa.core import models as core_models
from modoboa.lib.tests import ModoTestCase
from . import data as tests_data
BODYSTRUCTURE_SAMPLE_WITH_FLAGS = [
(b'19 (UID 19 FLAGS (\\Seen) RFC822.SIZE 100000 BODYSTRUCTURE (("text" "plain" ("charset" "ISO-8859-1" "format" "flowed") NIL NIL "7bit" 2 1 NIL NIL NIL NIL)("message" "rfc822" ("name*" "ISO-8859-1\'\'%5B%49%4E%53%43%52%49%50%54%49%4F%4E%5D%20%52%E9%63%E9%70%74%69%6F%6E%20%64%65%20%76%6F%74%72%65%20%64%6F%73%73%69%65%72%20%64%27%69%6E%73%63%72%69%70%74%69%6F%6E%20%46%72%65%65%20%48%61%75%74%20%44%E9%62%69%74") NIL NIL "8bit" 3632 ("Wed, 13 Dec 2006 20:30:02 +0100" {70}', # noqa
b"[INSCRIPTION] R\xe9c\xe9ption de votre dossier d'inscription Free Haut D\xe9bit"), # noqa
(b' (("Free Haut Debit" NIL "inscription" "freetelecom.fr")) (("Free Haut Debit" NIL "inscription" "freetelecom.fr")) ((NIL NIL "hautdebit" "freetelecom.fr")) ((NIL NIL "nguyen.antoine" "wanadoo.fr")) NIL NIL NIL "<20061213193125.9DA0919AC@dgroup2-2.proxad.net>") ("text" "plain" ("charset" "iso-8859-1") NIL NIL "8bit" 1428 38 NIL ("inline" NIL) NIL NIL) 76 NIL ("inline" ("filename*" "ISO-8859-1\'\'%5B%49%4E%53%43%52%49%50%54%49%4F%4E%5D%20%52%E9%63%E9%70%74%69%6F%6E%20%64%65%20%76%6F%74%72%65%20%64%6F%73%73%69%65%72%20%64%27%69%6E%73%63%72%69%70%74%69%6F%6E%20%46%72%65%65%20%48%61%75%74%20%44%E9%62%69%74")) NIL NIL) "mixed" ("boundary" "------------040706080908000209030901") NIL NIL NIL) BODY[HEADER.FIELDS (DATE FROM TO CC SUBJECT)] {266}', # noqa
b'Date: Tue, 19 Dec 2006 19:50:13 +0100\r\nFrom: Antoine Nguyen <nguyen.antoine@wanadoo.fr>\r\nTo: Antoine Nguyen <tonio@koalabs.org>\r\nSubject: [Fwd: [INSCRIPTION] =?ISO-8859-1?Q?R=E9c=E9ption_de_votre_?=\r\n =?ISO-8859-1?Q?dossier_d=27inscription_Free_Haut_D=E9bit=5D?=\r\n\r\n'
),
b')'
]
def get_gif():
"""Return gif."""
gif = BytesIO(
b"GIF87a\x01\x00\x01\x00\x80\x01\x00\x00\x00\x00ccc,\x00"
b"\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;")
gif.name = "image.gif"
return gif
class IMAP4Mock(object):
"""Fake IMAP4 client."""
def __init__(self, *args, **kwargs):
self.untagged_responses = {}
def _quote(self, data):
return data
def _simple_command(self, name, *args, **kwargs):
if name == "CAPABILITY":
self.untagged_responses["CAPABILITY"] = [b""]
elif name == "LIST":
self.untagged_responses["LIST"] = [b"() \".\" \"INBOX\""]
elif name == "NAMESPACE":
self.untagged_responses["NAMESPACE"] = [b'(("" "/")) NIL NIL']
return "OK", None
def append(self, *args, **kwargs):
pass
def create(self, name):
return "OK", None
def delete(self, name):
return "OK", None
def list(self):
return "OK", [b"() \".\" \"INBOX\""]
def rename(self, oldname, newname):
return "OK", None
def uid(self, command, *args):
if command == "SORT":
return "OK", [b"19"]
elif command == "FETCH":
uid = int(args[0])
data = BODYSTRUCTURE_SAMPLE_WITH_FLAGS
if uid == 46931:
if args[1] == "(BODYSTRUCTURE)":
data = tests_data.BODYSTRUCTURE_ONLY_4
elif "HEADER.FIELDS" in args[1]:
data = tests_data.BODYSTRUCTURE_SAMPLE_4
else:
data = tests_data.BODY_PLAIN_4
elif uid == 46932:
if args[1] == "(BODYSTRUCTURE)":
data = tests_data.BODYSTRUCTURE_ONLY_5
elif "HEADER.FIELDS" in args[1]:
data = tests_data.BODYSTRUCTURE_SAMPLE_9
else:
data = tests_data.BODYSTRUCTURE_SAMPLE_10
elif uid == 33:
if args[1] == "(BODYSTRUCTURE)":
data = tests_data.BODYSTRUCTURE_EMPTY_MAIL
else:
data = tests_data.EMPTY_BODY
elif uid == 133872:
data = tests_data.COMPLETE_MAIL
return "OK", data
elif command == "STORE":
return "OK", []
class WebmailTestCase(ModoTestCase):
"""Check webmail backend."""
@classmethod
def setUpTestData(cls): # noqa
"""Create some users."""
super(WebmailTestCase, cls).setUpTestData()
admin_factories.populate_database()
cls.user = core_models.User.objects.get(username="user@test.com")
def setUp(self):
"""Connect with a simpler user."""
patcher = mock.patch("imaplib.IMAP4")
self.mock_imap4 = patcher.start()
self.mock_imap4.return_value = IMAP4Mock()
self.addCleanup(patcher.stop)
self.set_global_parameter("imap_port", 1435)
self.workdir = tempfile.mkdtemp()
os.mkdir("{}/webmail".format(self.workdir))
self.set_global_parameter("update_scheme", False, app="core")
url = reverse("core:login")
data = {
"username": self.user.username, "password": "toto"
}
self.client.post(url, data)
def tearDown(self):
"""Cleanup."""
shutil.rmtree(self.workdir)
def test_listmailbox(self):
"""Check listmailbox action."""
url = reverse("modoboa_webmail:index")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.get(
"{}?action=listmailbox".format(url),
HTTP_X_REQUESTED_WITH="XMLHttpRequest"
)
self.assertEqual(response.status_code, 200)
self.assertIn(
"nguyen.antoine@wanadoo.fr", response.json()["listing"])
response = self.client.get(
"{}?action=listmailbox&pattern=Réception&criteria=Subject"
.format(url),
HTTP_X_REQUESTED_WITH="XMLHttpRequest"
)
self.assertEqual(response.status_code, 200)
self.assertIn(
"nguyen.antoine@wanadoo.fr", response.json()["listing"])
def test_attachments(self):
"""Check attachments."""
url = reverse("modoboa_webmail:index")
response = self.client.get("{}?action=compose".format(url))
self.assertEqual(response.status_code, 200)
self.assertIn("compose_mail", self.client.session)
url = reverse("modoboa_webmail:attachment_list")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.set_global_parameters({"max_attachment_size": "10"})
with self.settings(MEDIA_ROOT=self.workdir):
response = self.client.post(url, {"attachment": get_gif()})
self.assertContains(response, "Attachment is too big")
self.set_global_parameters({"max_attachment_size": "10K"})
with self.settings(MEDIA_ROOT=self.workdir):
response = self.client.post(url, {"attachment": get_gif()})
self.assertContains(response, "upload_success")
self.assertEqual(
len(self.client.session["compose_mail"]["attachments"]), 1)
name = self.client.session["compose_mail"]["attachments"][0]["tmpname"]
path = "{}/webmail/{}".format(self.workdir, name)
self.assertTrue(os.path.exists(path))
url = reverse("modoboa_webmail:attachment_delete")
with self.settings(MEDIA_ROOT=self.workdir):
self.ajax_get("{}?name={}".format(url, name))
self.assertFalse(os.path.exists(path))
def test_delattachment_errors(self):
"""Check error cases."""
url = reverse("modoboa_webmail:index")
response = self.client.get("{}?action=compose".format(url))
self.assertEqual(response.status_code, 200)
self.assertIn("compose_mail", self.client.session)
url = reverse("modoboa_webmail:attachment_delete")
with self.settings(MEDIA_ROOT=self.workdir):
response = self.ajax_get("{}?name=".format(url))
self.assertEqual(response["status"], "ko")
self.assertEqual(response["respmsg"], "Bad query")
with self.settings(MEDIA_ROOT=self.workdir):
response = self.ajax_get("{}?name=test".format(url))
self.assertEqual(response["status"], "ko")
self.assertEqual(response["respmsg"], "Unknown attachment")
def test_send_mail(self):
"""Check compose form."""
url = "{}?action=compose".format(reverse("modoboa_webmail:index"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.post(
url, {
"from_": self.user.email, "to": "test@example.test",
"subject": "test", "body": "Test"
}
)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(
mail.outbox[0].from_email, "user@test.com")
# Try to send an email using HTML format
self.user.first_name = "Antoine"
self.user.last_name = "Nguyen"
self.user.parameters.set_value("editor", "html")
self.user.save()
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
mail.outbox = []
response = self.client.post(
url, {
"from_": self.user.email,
"to": "test@example.test", "subject": "test",
"body": "<p>Test</p>"
}
)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(
mail.outbox[0].from_email, '"Antoine Nguyen" <user@test.com>')
def test_signature(self):
"""Check signature in different formats."""
signature = "Antoine Nguyen"
self.user.parameters.set_value("signature", signature)
self.user.save()
response = self.client.get(reverse("modoboa_webmail:index"))
self.assertEqual(response.status_code, 200)
url = "{}?action=compose".format(reverse("modoboa_webmail:index"))
response = self.ajax_get(url)
self.assertIn(signature, response["listing"])
def test_custom_js_in_preferences(self):
"""Check that custom js is included."""
url = reverse("core:user_index")
response = self.client.get(url)
self.assertContains(response, "function toggleSignatureEditor()")
def test_send_mail_errors(self):
"""Check error cases."""
url = "{}?action=compose".format(reverse("modoboa_webmail:index"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.ajax_post(
url, {"to": "", "subject": "test", "body": "Test"}, 400
)
self.assertEqual(len(mail.outbox), 0)
def test_new_folder(self):
"""Test folder creation."""
url = reverse("modoboa_webmail:folder_add")
response = self.client.get(url)
self.assertContains(response, "Create a new folder")
response = self.ajax_post(url, {"name": "Test"})
self.assertIn("newmb", response)
def test_edit_folder(self):
"""Test folder edition."""
url = reverse("modoboa_webmail:folder_change")
response = self.client.get(url)
self.assertContains(response, "Invalid request")
url = "{}?name=Test".format(url)
response = self.client.get(url)
self.assertContains(response, "Edit folder")
session = self.client.session
session["webmail_navparams"] = {"inbox": "Test"}
session.save()
response = self.ajax_post(url, {"oldname": "Test", "name": "Toto"})
self.assertEqual(response["respmsg"], "Folder updated")
def test_delete_folder(self):
"""Test folder removal."""
url = reverse("modoboa_webmail:folder_delete")
self.ajax_get(url, status=400)
url = "{}?name=Test".format(url)
session = self.client.session
session["webmail_navparams"] = {"inbox": "Test"}
session.save()
self.ajax_get(url)
def test_reply_to_email(self):
"""Test reply form."""
url = "{}?action=reply&mbox=INBOX&mailid=46931".format(
reverse("modoboa_webmail:index"))
session = self.client.session
session["lastaction"] = "compose"
session.save()
response = self.ajax_get(url)
self.assertIn('id="id_origmsgid"', response["listing"])
response = self.client.post(
url, {
"from_": self.user.email, "to": "test@example.test",
"subject": "test", "body": "Test",
"origmsgid": "<id@localhost>"
}
)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(
mail.outbox[0].from_email, "user@test.com")
self.assertIn("References", mail.outbox[0].extra_headers)
def test_forward_email(self):
"""Test forward form."""
url = "{}?action=forward&mbox=INBOX&mailid=46932".format(
reverse("modoboa_webmail:index"))
session = self.client.session
session["lastaction"] = "compose"
session.save()
response = self.ajax_get(url)
self.assertIn('id="id_origmsgid"', response["listing"])
self.assertEqual(
len(self.client.session["compose_mail"]["attachments"]), 1)
response = self.client.post(
url, {
"from_": self.user.email, "to": "test@example.test",
"subject": "test", "body": "Test",
"origmsgid": "<id@localhost>"
}
)
self.assertEqual(len(mail.outbox), 1)
def test_getmailcontent_empty_mail(self):
"""Try to display an empty email."""
url = "{}?action=reply&mbox=INBOX&mailid=33".format(
reverse("modoboa_webmail:mailcontent_get"))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
def test_getmailsource(self):
"""Try to display a message's source."""
url = "{}?mbox=INBOX&mailid=133872".format(
reverse("modoboa_webmail:mailsource_get"))
response = self.client.get(url)
self.assertContains(response, "Message-ID")