mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-16 14:48:00 +00:00
test(mail): convert test_api.py to pytest style
This commit is contained in:
@@ -1,44 +1,37 @@
|
||||
import json
|
||||
from unittest import mock
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
import pytest
|
||||
from django.contrib.auth.models import User
|
||||
from guardian.shortcuts import assign_perm
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from documents.tests.factories import CorrespondentFactory
|
||||
from documents.tests.factories import DocumentTypeFactory
|
||||
from documents.tests.factories import TagFactory
|
||||
from documents.tests.utils import DirectoriesMixin
|
||||
from paperless_mail.models import MailAccount
|
||||
from paperless_mail.models import MailRule
|
||||
from paperless_mail.models import ProcessedMail
|
||||
from paperless_mail.tests.factories import MailAccountFactory
|
||||
from paperless_mail.tests.factories import MailRuleFactory
|
||||
from paperless_mail.tests.factories import ProcessedMailFactory
|
||||
from paperless_mail.tests.test_mail import BogusMailBox
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from paperless_mail.tests.test_mail import BogusMailBox
|
||||
|
||||
|
||||
class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
ENDPOINT = "/api/mail_accounts/"
|
||||
MAIL_ACCOUNTS_ENDPOINT = "/api/mail_accounts/"
|
||||
MAIL_RULES_ENDPOINT = "/api/mail_rules/"
|
||||
PROCESSED_MAIL_ENDPOINT = "/api/processed_mail/"
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.bogus_mailbox = BogusMailBox()
|
||||
|
||||
patcher = mock.patch("paperless_mail.mail.MailBox")
|
||||
m = patcher.start()
|
||||
m.return_value = self.bogus_mailbox
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_mail_accounts(self) -> None:
|
||||
@pytest.mark.django_db
|
||||
class TestAPIMailAccounts:
|
||||
def test_get_mail_accounts(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured mail accounts
|
||||
@@ -47,7 +40,6 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Configured mail accounts are provided
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory(
|
||||
name="Email1",
|
||||
username="username1",
|
||||
@@ -56,31 +48,30 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
imap_port=443,
|
||||
)
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(MAIL_ACCOUNTS_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 1)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 1
|
||||
returned_account1 = response.data["results"][0]
|
||||
|
||||
self.assertEqual(returned_account1["name"], account1.name)
|
||||
self.assertEqual(returned_account1["username"], account1.username)
|
||||
self.assertEqual(
|
||||
returned_account1["password"],
|
||||
"**********",
|
||||
)
|
||||
self.assertEqual(returned_account1["imap_server"], account1.imap_server)
|
||||
self.assertEqual(returned_account1["imap_port"], account1.imap_port)
|
||||
self.assertEqual(returned_account1["imap_security"], account1.imap_security)
|
||||
self.assertEqual(returned_account1["character_set"], account1.character_set)
|
||||
assert returned_account1["name"] == account1.name
|
||||
assert returned_account1["username"] == account1.username
|
||||
assert returned_account1["password"] == "**********"
|
||||
assert returned_account1["imap_server"] == account1.imap_server
|
||||
assert returned_account1["imap_port"] == account1.imap_port
|
||||
assert returned_account1["imap_security"] == account1.imap_security
|
||||
assert returned_account1["character_set"] == account1.character_set
|
||||
|
||||
def test_create_mail_account(self) -> None:
|
||||
def test_create_mail_account(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
WHEN:
|
||||
- API request is made to add a mail account
|
||||
THEN:
|
||||
- A new mail account is created
|
||||
"""
|
||||
|
||||
account1 = {
|
||||
"name": "Email1",
|
||||
"username": "username1",
|
||||
@@ -91,24 +82,27 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
"character_set": "UTF-8",
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT,
|
||||
response = mail_api_client.post(
|
||||
MAIL_ACCOUNTS_ENDPOINT,
|
||||
data=account1,
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
returned_account1 = MailAccount.objects.get(name="Email1")
|
||||
|
||||
self.assertEqual(returned_account1.name, account1["name"])
|
||||
self.assertEqual(returned_account1.username, account1["username"])
|
||||
self.assertEqual(returned_account1.password, account1["password"])
|
||||
self.assertEqual(returned_account1.imap_server, account1["imap_server"])
|
||||
self.assertEqual(returned_account1.imap_port, account1["imap_port"])
|
||||
self.assertEqual(returned_account1.imap_security, account1["imap_security"])
|
||||
self.assertEqual(returned_account1.character_set, account1["character_set"])
|
||||
assert returned_account1.name == account1["name"]
|
||||
assert returned_account1.username == account1["username"]
|
||||
assert returned_account1.password == account1["password"]
|
||||
assert returned_account1.imap_server == account1["imap_server"]
|
||||
assert returned_account1.imap_port == account1["imap_port"]
|
||||
assert returned_account1.imap_security == account1["imap_security"]
|
||||
assert returned_account1.character_set == account1["character_set"]
|
||||
|
||||
def test_delete_mail_account(self) -> None:
|
||||
def test_delete_mail_account(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Existing mail account
|
||||
@@ -117,18 +111,20 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Account is deleted
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
|
||||
response = self.client.delete(
|
||||
f"{self.ENDPOINT}{account1.pk}/",
|
||||
response = mail_api_client.delete(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}{account1.pk}/",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
self.assertEqual(len(MailAccount.objects.all()), 0)
|
||||
assert len(MailAccount.objects.all()) == 0
|
||||
|
||||
def test_update_mail_account(self) -> None:
|
||||
def test_update_mail_account(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Existing mail accounts
|
||||
@@ -137,38 +133,41 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- The mail account is updated, password only updated if not '****'
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
|
||||
response = self.client.patch(
|
||||
f"{self.ENDPOINT}{account1.pk}/",
|
||||
response = mail_api_client.patch(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}{account1.pk}/",
|
||||
data={
|
||||
"name": "Updated Name 1",
|
||||
"password": "******",
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
returned_account1 = MailAccount.objects.get(pk=account1.pk)
|
||||
self.assertEqual(returned_account1.name, "Updated Name 1")
|
||||
self.assertEqual(returned_account1.password, account1.password)
|
||||
assert returned_account1.name == "Updated Name 1"
|
||||
assert returned_account1.password == account1.password
|
||||
|
||||
response = self.client.patch(
|
||||
f"{self.ENDPOINT}{account1.pk}/",
|
||||
response = mail_api_client.patch(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}{account1.pk}/",
|
||||
data={
|
||||
"name": "Updated Name 2",
|
||||
"password": "123xyz",
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
returned_account2 = MailAccount.objects.get(pk=account1.pk)
|
||||
self.assertEqual(returned_account2.name, "Updated Name 2")
|
||||
self.assertEqual(returned_account2.password, "123xyz")
|
||||
assert returned_account2.name == "Updated Name 2"
|
||||
assert returned_account2.password == "123xyz"
|
||||
|
||||
def test_mail_account_test_fail(self) -> None:
|
||||
def test_mail_account_test_fail(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
bogus_mailbox: "BogusMailBox",
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Errnoeous mail account details
|
||||
@@ -177,9 +176,8 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- API returns 400 bad request
|
||||
"""
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}test/",
|
||||
response = mail_api_client.post(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}test/",
|
||||
json.dumps(
|
||||
{
|
||||
"imap_server": "server.example.com",
|
||||
@@ -192,9 +190,13 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
|
||||
def test_mail_account_test_success(self) -> None:
|
||||
def test_mail_account_test_success(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
bogus_mailbox: "BogusMailBox",
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Working mail account details
|
||||
@@ -203,9 +205,8 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- API returns success
|
||||
"""
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}test/",
|
||||
response = mail_api_client.post(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}test/",
|
||||
json.dumps(
|
||||
{
|
||||
"imap_server": "server.example.com",
|
||||
@@ -217,10 +218,14 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
),
|
||||
content_type="application/json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["success"], True)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["success"] is True
|
||||
|
||||
def test_mail_account_test_existing(self) -> None:
|
||||
def test_mail_account_test_existing(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
bogus_mailbox: "BogusMailBox",
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Testing server details for an existing account with obfuscated password (***)
|
||||
@@ -236,8 +241,8 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
imap_port=443,
|
||||
)
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}test/",
|
||||
response = mail_api_client.post(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}test/",
|
||||
json.dumps(
|
||||
{
|
||||
"id": account.pk,
|
||||
@@ -250,12 +255,16 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
),
|
||||
content_type="application/json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["success"], True)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["success"] is True
|
||||
|
||||
def test_mail_account_test_existing_nonexistent_id_forbidden(self) -> None:
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}test/",
|
||||
def test_mail_account_test_existing_nonexistent_id_forbidden(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
bogus_mailbox: "BogusMailBox",
|
||||
) -> None:
|
||||
response = mail_api_client.post(
|
||||
f"{MAIL_ACCOUNTS_ENDPOINT}test/",
|
||||
json.dumps(
|
||||
{
|
||||
"id": 999999,
|
||||
@@ -268,10 +277,15 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
),
|
||||
content_type="application/json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertEqual(response.content.decode(), "Insufficient permissions")
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
assert response.content.decode() == "Insufficient permissions"
|
||||
|
||||
def test_get_mail_accounts_owner_aware(self) -> None:
|
||||
def test_get_mail_accounts_owner_aware(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured accounts with different users
|
||||
@@ -280,36 +294,29 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only unowned, owned by user or granted accounts are provided
|
||||
"""
|
||||
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = django_user_model.objects.create_user(username="temp_admin2")
|
||||
|
||||
account1 = MailAccountFactory(name="Email1")
|
||||
account2 = MailAccountFactory(name="Email2", owner=self.user)
|
||||
account2 = MailAccountFactory(name="Email2", owner=mail_api_user)
|
||||
_account3 = MailAccountFactory(name="Email3", owner=user2)
|
||||
account4 = MailAccountFactory(name="Email4", owner=user2)
|
||||
assign_perm("view_mailaccount", self.user, account4)
|
||||
assign_perm("view_mailaccount", mail_api_user, account4)
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(MAIL_ACCOUNTS_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 3)
|
||||
self.assertEqual(response.data["results"][0]["name"], account1.name)
|
||||
self.assertEqual(response.data["results"][1]["name"], account2.name)
|
||||
self.assertEqual(response.data["results"][2]["name"], account4.name)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 3
|
||||
assert response.data["results"][0]["name"] == account1.name
|
||||
assert response.data["results"][1]["name"] == account2.name
|
||||
assert response.data["results"][2]["name"] == account4.name
|
||||
|
||||
|
||||
class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
ENDPOINT = "/api/mail_rules/"
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_mail_rules(self) -> None:
|
||||
@pytest.mark.django_db
|
||||
class TestAPIMailRules:
|
||||
def test_get_mail_rules(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured mail accounts and rules
|
||||
@@ -318,7 +325,6 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Configured mail rules are provided
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(
|
||||
name="Rule1",
|
||||
@@ -330,34 +336,37 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
filter_attachment_filename_include="file.pdf",
|
||||
)
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(MAIL_RULES_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 1)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 1
|
||||
returned_rule1 = response.data["results"][0]
|
||||
|
||||
self.assertEqual(returned_rule1["name"], rule1.name)
|
||||
self.assertEqual(returned_rule1["account"], account1.pk)
|
||||
self.assertEqual(returned_rule1["folder"], rule1.folder)
|
||||
self.assertEqual(returned_rule1["filter_from"], rule1.filter_from)
|
||||
self.assertEqual(returned_rule1["filter_to"], rule1.filter_to)
|
||||
self.assertEqual(returned_rule1["filter_subject"], rule1.filter_subject)
|
||||
self.assertEqual(returned_rule1["filter_body"], rule1.filter_body)
|
||||
self.assertEqual(
|
||||
returned_rule1["filter_attachment_filename_include"],
|
||||
rule1.filter_attachment_filename_include,
|
||||
assert returned_rule1["name"] == rule1.name
|
||||
assert returned_rule1["account"] == account1.pk
|
||||
assert returned_rule1["folder"] == rule1.folder
|
||||
assert returned_rule1["filter_from"] == rule1.filter_from
|
||||
assert returned_rule1["filter_to"] == rule1.filter_to
|
||||
assert returned_rule1["filter_subject"] == rule1.filter_subject
|
||||
assert returned_rule1["filter_body"] == rule1.filter_body
|
||||
assert (
|
||||
returned_rule1["filter_attachment_filename_include"]
|
||||
== rule1.filter_attachment_filename_include
|
||||
)
|
||||
self.assertEqual(returned_rule1["maximum_age"], rule1.maximum_age)
|
||||
self.assertEqual(returned_rule1["action"], rule1.action)
|
||||
self.assertEqual(returned_rule1["assign_title_from"], rule1.assign_title_from)
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_correspondent_from"],
|
||||
rule1.assign_correspondent_from,
|
||||
assert returned_rule1["maximum_age"] == rule1.maximum_age
|
||||
assert returned_rule1["action"] == rule1.action
|
||||
assert returned_rule1["assign_title_from"] == rule1.assign_title_from
|
||||
assert (
|
||||
returned_rule1["assign_correspondent_from"]
|
||||
== rule1.assign_correspondent_from
|
||||
)
|
||||
self.assertEqual(returned_rule1["order"], rule1.order)
|
||||
self.assertEqual(returned_rule1["attachment_type"], rule1.attachment_type)
|
||||
assert returned_rule1["order"] == rule1.order
|
||||
assert returned_rule1["attachment_type"] == rule1.attachment_type
|
||||
|
||||
def test_create_mail_rule(self) -> None:
|
||||
def test_create_mail_rule(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured mail account exists
|
||||
@@ -366,7 +375,6 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- A new mail rule is created
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
tag = TagFactory(name="t")
|
||||
correspondent = CorrespondentFactory(name="c")
|
||||
@@ -394,58 +402,51 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
"assign_owner_from_rule": True,
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT,
|
||||
response = mail_api_client.post(
|
||||
MAIL_RULES_ENDPOINT,
|
||||
data=rule1,
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(MAIL_RULES_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 1)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 1
|
||||
returned_rule1 = response.data["results"][0]
|
||||
|
||||
self.assertEqual(returned_rule1["name"], rule1["name"])
|
||||
self.assertEqual(returned_rule1["account"], account1.pk)
|
||||
self.assertEqual(returned_rule1["folder"], rule1["folder"])
|
||||
self.assertEqual(returned_rule1["filter_from"], rule1["filter_from"])
|
||||
self.assertEqual(returned_rule1["filter_to"], rule1["filter_to"])
|
||||
self.assertEqual(returned_rule1["filter_subject"], rule1["filter_subject"])
|
||||
self.assertEqual(returned_rule1["filter_body"], rule1["filter_body"])
|
||||
self.assertEqual(
|
||||
returned_rule1["filter_attachment_filename_include"],
|
||||
rule1["filter_attachment_filename_include"],
|
||||
assert returned_rule1["name"] == rule1["name"]
|
||||
assert returned_rule1["account"] == account1.pk
|
||||
assert returned_rule1["folder"] == rule1["folder"]
|
||||
assert returned_rule1["filter_from"] == rule1["filter_from"]
|
||||
assert returned_rule1["filter_to"] == rule1["filter_to"]
|
||||
assert returned_rule1["filter_subject"] == rule1["filter_subject"]
|
||||
assert returned_rule1["filter_body"] == rule1["filter_body"]
|
||||
assert (
|
||||
returned_rule1["filter_attachment_filename_include"]
|
||||
== rule1["filter_attachment_filename_include"]
|
||||
)
|
||||
self.assertEqual(returned_rule1["maximum_age"], rule1["maximum_age"])
|
||||
self.assertEqual(returned_rule1["action"], rule1["action"])
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_title_from"],
|
||||
rule1["assign_title_from"],
|
||||
assert returned_rule1["maximum_age"] == rule1["maximum_age"]
|
||||
assert returned_rule1["action"] == rule1["action"]
|
||||
assert returned_rule1["assign_title_from"] == rule1["assign_title_from"]
|
||||
assert (
|
||||
returned_rule1["assign_correspondent_from"]
|
||||
== rule1["assign_correspondent_from"]
|
||||
)
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_correspondent_from"],
|
||||
rule1["assign_correspondent_from"],
|
||||
)
|
||||
self.assertEqual(returned_rule1["order"], rule1["order"])
|
||||
self.assertEqual(returned_rule1["attachment_type"], rule1["attachment_type"])
|
||||
self.assertEqual(returned_rule1["action_parameter"], rule1["action_parameter"])
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_correspondent"],
|
||||
rule1["assign_correspondent"],
|
||||
)
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_document_type"],
|
||||
rule1["assign_document_type"],
|
||||
)
|
||||
self.assertEqual(returned_rule1["assign_tags"], rule1["assign_tags"])
|
||||
self.assertEqual(
|
||||
returned_rule1["assign_owner_from_rule"],
|
||||
rule1["assign_owner_from_rule"],
|
||||
assert returned_rule1["order"] == rule1["order"]
|
||||
assert returned_rule1["attachment_type"] == rule1["attachment_type"]
|
||||
assert returned_rule1["action_parameter"] == rule1["action_parameter"]
|
||||
assert returned_rule1["assign_correspondent"] == rule1["assign_correspondent"]
|
||||
assert returned_rule1["assign_document_type"] == rule1["assign_document_type"]
|
||||
assert returned_rule1["assign_tags"] == rule1["assign_tags"]
|
||||
assert (
|
||||
returned_rule1["assign_owner_from_rule"] == rule1["assign_owner_from_rule"]
|
||||
)
|
||||
|
||||
def test_delete_mail_rule(self) -> None:
|
||||
def test_delete_mail_rule(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Existing mail rule
|
||||
@@ -454,19 +455,21 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Rule is deleted
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(account=account1)
|
||||
|
||||
response = self.client.delete(
|
||||
f"{self.ENDPOINT}{rule1.pk}/",
|
||||
response = mail_api_client.delete(
|
||||
f"{MAIL_RULES_ENDPOINT}{rule1.pk}/",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
self.assertEqual(len(MailRule.objects.all()), 0)
|
||||
assert len(MailRule.objects.all()) == 0
|
||||
|
||||
def test_update_mail_rule(self) -> None:
|
||||
def test_update_mail_rule(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Existing mail rule
|
||||
@@ -475,30 +478,33 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- The mail rule is updated
|
||||
"""
|
||||
|
||||
account1 = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(account=account1)
|
||||
|
||||
response = self.client.patch(
|
||||
f"{self.ENDPOINT}{rule1.pk}/",
|
||||
response = mail_api_client.patch(
|
||||
f"{MAIL_RULES_ENDPOINT}{rule1.pk}/",
|
||||
data={
|
||||
"name": "Updated Name 1",
|
||||
"action": MailRule.MailAction.DELETE,
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
returned_rule1 = MailRule.objects.get(pk=rule1.pk)
|
||||
self.assertEqual(returned_rule1.name, "Updated Name 1")
|
||||
self.assertEqual(returned_rule1.action, MailRule.MailAction.DELETE)
|
||||
assert returned_rule1.name == "Updated Name 1"
|
||||
assert returned_rule1.action == MailRule.MailAction.DELETE
|
||||
|
||||
def test_create_mail_rule_scopes_accounts(self) -> None:
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
def test_create_mail_rule_scopes_accounts(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
other_user = django_user_model.objects.create_user(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(name="ForeignEmail", owner=other_user)
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT,
|
||||
response = mail_api_client.post(
|
||||
MAIL_RULES_ENDPOINT,
|
||||
data={
|
||||
"name": "Rule1",
|
||||
"account": foreign_account.pk,
|
||||
@@ -512,8 +518,8 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
"attachment_type": MailRule.AttachmentProcessing.ATTACHMENTS_ONLY,
|
||||
},
|
||||
)
|
||||
missing_response = self.client.post(
|
||||
self.ENDPOINT,
|
||||
missing_response = mail_api_client.post(
|
||||
MAIL_RULES_ENDPOINT,
|
||||
data={
|
||||
"name": "Rule1",
|
||||
"account": foreign_account.pk + 1000,
|
||||
@@ -528,21 +534,24 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(missing_response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(response.data["account"][0].code, "does_not_exist")
|
||||
self.assertEqual(missing_response.data["account"][0].code, "does_not_exist")
|
||||
self.assertEqual(MailRule.objects.count(), 0)
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert missing_response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert response.data["account"][0].code == "does_not_exist"
|
||||
assert missing_response.data["account"][0].code == "does_not_exist"
|
||||
assert MailRule.objects.count() == 0
|
||||
|
||||
def test_create_mail_rule_allowed_for_granted_account_change_permission(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
other_user = django_user_model.objects.create_user(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(name="ForeignEmail", owner=other_user)
|
||||
assign_perm("change_mailaccount", self.user, foreign_account)
|
||||
assign_perm("change_mailaccount", mail_api_user, foreign_account)
|
||||
|
||||
response = self.client.post(
|
||||
self.ENDPOINT,
|
||||
response = mail_api_client.post(
|
||||
MAIL_RULES_ENDPOINT,
|
||||
data={
|
||||
"name": "Rule1",
|
||||
"account": foreign_account.pk,
|
||||
@@ -557,25 +566,34 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(MailRule.objects.get().account, foreign_account)
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
assert MailRule.objects.get().account == foreign_account
|
||||
|
||||
def test_update_mail_rule_forbidden_for_unpermitted_account(self) -> None:
|
||||
def test_update_mail_rule_forbidden_for_unpermitted_account(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
own_account = MailAccountFactory()
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
other_user = django_user_model.objects.create_user(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(owner=other_user)
|
||||
rule1 = MailRuleFactory(account=own_account)
|
||||
|
||||
response = self.client.patch(
|
||||
f"{self.ENDPOINT}{rule1.pk}/",
|
||||
response = mail_api_client.patch(
|
||||
f"{MAIL_RULES_ENDPOINT}{rule1.pk}/",
|
||||
data={"account": foreign_account.pk},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
rule1.refresh_from_db()
|
||||
self.assertEqual(rule1.account, own_account)
|
||||
assert rule1.account == own_account
|
||||
|
||||
def test_get_mail_rules_owner_aware(self) -> None:
|
||||
def test_get_mail_rules_owner_aware(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured rules with different users
|
||||
@@ -584,24 +602,26 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only unowned, owned by user or granted mail rules are provided
|
||||
"""
|
||||
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = django_user_model.objects.create_user(username="temp_admin2")
|
||||
account1 = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(account=account1, order=0)
|
||||
rule2 = MailRuleFactory(account=account1, order=1, owner=self.user)
|
||||
rule2 = MailRuleFactory(account=account1, order=1, owner=mail_api_user)
|
||||
MailRuleFactory(account=account1, order=2, owner=user2)
|
||||
rule4 = MailRuleFactory(account=account1, order=3, owner=user2)
|
||||
assign_perm("view_mailrule", self.user, rule4)
|
||||
assign_perm("view_mailrule", mail_api_user, rule4)
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(MAIL_RULES_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 3)
|
||||
self.assertEqual(response.data["results"][0]["name"], rule1.name)
|
||||
self.assertEqual(response.data["results"][1]["name"], rule2.name)
|
||||
self.assertEqual(response.data["results"][2]["name"], rule4.name)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 3
|
||||
assert response.data["results"][0]["name"] == rule1.name
|
||||
assert response.data["results"][1]["name"] == rule2.name
|
||||
assert response.data["results"][2]["name"] == rule4.name
|
||||
|
||||
def test_mailrule_maxage_validation(self) -> None:
|
||||
def test_mailrule_maxage_validation(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- An existing mail account
|
||||
@@ -629,24 +649,24 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
"attachment_type": MailRule.AttachmentProcessing.ATTACHMENTS_ONLY,
|
||||
}
|
||||
|
||||
response = self.client.post(self.ENDPOINT, data=rule_data, format="json")
|
||||
response = mail_api_client.post(
|
||||
MAIL_RULES_ENDPOINT,
|
||||
data=rule_data,
|
||||
format="json",
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertIn("maximum_age", response.data)
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert "maximum_age" in response.data
|
||||
|
||||
|
||||
class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
ENDPOINT = "/api/processed_mail/"
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_processed_mails_owner_aware(self) -> None:
|
||||
@pytest.mark.django_db
|
||||
class TestAPIProcessedMails:
|
||||
def test_get_processed_mails_owner_aware(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Configured processed mails with different users
|
||||
@@ -655,27 +675,31 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only unowned, owned by user or granted processed mails are provided
|
||||
"""
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = django_user_model.objects.create_user(username="temp_admin2")
|
||||
rule = MailRuleFactory()
|
||||
pm1 = ProcessedMailFactory(rule=rule)
|
||||
pm2 = ProcessedMailFactory(
|
||||
rule=rule,
|
||||
status="FAILED",
|
||||
error="err",
|
||||
owner=self.user,
|
||||
owner=mail_api_user,
|
||||
)
|
||||
ProcessedMailFactory(rule=rule, owner=user2)
|
||||
pm4 = ProcessedMailFactory(rule=rule, owner=user2)
|
||||
assign_perm("view_processedmail", self.user, pm4)
|
||||
assign_perm("view_processedmail", mail_api_user, pm4)
|
||||
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
response = mail_api_client.get(PROCESSED_MAIL_ENDPOINT)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["count"], 3)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 3
|
||||
returned_ids = {r["id"] for r in response.data["results"]}
|
||||
self.assertSetEqual(returned_ids, {pm1.id, pm2.id, pm4.id})
|
||||
assert returned_ids == {pm1.id, pm2.id, pm4.id}
|
||||
|
||||
def test_get_processed_mails_filter_by_rule(self) -> None:
|
||||
def test_get_processed_mails_filter_by_rule(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Processed mails belonging to two different rules
|
||||
@@ -687,17 +711,22 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
account = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(account=account)
|
||||
rule2 = MailRuleFactory(account=account)
|
||||
pm1 = ProcessedMailFactory(rule=rule1, owner=self.user)
|
||||
pm1 = ProcessedMailFactory(rule=rule1, owner=mail_api_user)
|
||||
pm2 = ProcessedMailFactory(rule=rule1, status="FAILED", error="e")
|
||||
ProcessedMailFactory(rule=rule2)
|
||||
|
||||
response = self.client.get(f"{self.ENDPOINT}?rule={rule1.pk}")
|
||||
response = mail_api_client.get(f"{PROCESSED_MAIL_ENDPOINT}?rule={rule1.pk}")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
returned_ids = {r["id"] for r in response.data["results"]}
|
||||
self.assertSetEqual(returned_ids, {pm1.id, pm2.id})
|
||||
assert returned_ids == {pm1.id, pm2.id}
|
||||
|
||||
def test_bulk_delete_processed_mails(self) -> None:
|
||||
def test_bulk_delete_processed_mails(
|
||||
self,
|
||||
mail_api_client: APIClient,
|
||||
mail_api_user: User,
|
||||
django_user_model: type[User],
|
||||
) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- Processed mails belonging to two different rules and different users
|
||||
@@ -706,7 +735,7 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only the specified processed mails are deleted, respecting ownership and permissions
|
||||
"""
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = django_user_model.objects.create_user(username="temp_admin2")
|
||||
rule = MailRuleFactory()
|
||||
# unowned, owned by self, and one with explicit object perm
|
||||
pm_unowned = ProcessedMailFactory(rule=rule)
|
||||
@@ -714,46 +743,47 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
rule=rule,
|
||||
status="FAILED",
|
||||
error="e",
|
||||
owner=self.user,
|
||||
owner=mail_api_user,
|
||||
)
|
||||
pm_granted = ProcessedMailFactory(rule=rule, owner=user2)
|
||||
assign_perm("delete_processedmail", self.user, pm_granted)
|
||||
assign_perm("delete_processedmail", mail_api_user, pm_granted)
|
||||
pm_forbidden = ProcessedMailFactory(rule=rule, owner=user2)
|
||||
|
||||
# Success for allowed items
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}bulk_delete/",
|
||||
response = mail_api_client.post(
|
||||
f"{PROCESSED_MAIL_ENDPOINT}bulk_delete/",
|
||||
data={
|
||||
"mail_ids": [pm_unowned.id, pm_owned.id, pm_granted.id],
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["result"], "OK")
|
||||
self.assertSetEqual(
|
||||
set(response.data["deleted_mail_ids"]),
|
||||
{pm_unowned.id, pm_owned.id, pm_granted.id},
|
||||
)
|
||||
self.assertFalse(ProcessedMail.objects.filter(id=pm_unowned.id).exists())
|
||||
self.assertFalse(ProcessedMail.objects.filter(id=pm_owned.id).exists())
|
||||
self.assertFalse(ProcessedMail.objects.filter(id=pm_granted.id).exists())
|
||||
self.assertTrue(ProcessedMail.objects.filter(id=pm_forbidden.id).exists())
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["result"] == "OK"
|
||||
assert set(response.data["deleted_mail_ids"]) == {
|
||||
pm_unowned.id,
|
||||
pm_owned.id,
|
||||
pm_granted.id,
|
||||
}
|
||||
assert not ProcessedMail.objects.filter(id=pm_unowned.id).exists()
|
||||
assert not ProcessedMail.objects.filter(id=pm_owned.id).exists()
|
||||
assert not ProcessedMail.objects.filter(id=pm_granted.id).exists()
|
||||
assert ProcessedMail.objects.filter(id=pm_forbidden.id).exists()
|
||||
|
||||
# 403 and not deleted
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}bulk_delete/",
|
||||
response = mail_api_client.post(
|
||||
f"{PROCESSED_MAIL_ENDPOINT}bulk_delete/",
|
||||
data={
|
||||
"mail_ids": [pm_forbidden.id],
|
||||
},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertTrue(ProcessedMail.objects.filter(id=pm_forbidden.id).exists())
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
assert ProcessedMail.objects.filter(id=pm_forbidden.id).exists()
|
||||
|
||||
# missing mail_ids
|
||||
response = self.client.post(
|
||||
f"{self.ENDPOINT}bulk_delete/",
|
||||
response = mail_api_client.post(
|
||||
f"{PROCESSED_MAIL_ENDPOINT}bulk_delete/",
|
||||
data={"mail_ids": "not-a-list"},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
|
||||
Reference in New Issue
Block a user