diff --git a/.github/workflows/pre-commit-updater.yml b/.github/workflows/pre-commit-updater.yml index 941481e..4a49b33 100644 --- a/.github/workflows/pre-commit-updater.yml +++ b/.github/workflows/pre-commit-updater.yml @@ -28,4 +28,4 @@ jobs: body: | Update versions of tools in pre-commit configs to latest version - labels: dependencies + labels: chore diff --git a/pypaperless/__init__.py b/pypaperless/__init__.py index f94b0bc..07accd8 100644 --- a/pypaperless/__init__.py +++ b/pypaperless/__init__.py @@ -192,7 +192,8 @@ async def generate_request( url = endpoint if endpoint.startswith("http") else f"http://{self.host}/api/{endpoint}" url = url.rstrip("/") + "/" # check and add trailing slash - kwargs.update(self._request_opts) + if isinstance(self._request_opts, dict): + kwargs.update(self._request_opts) if "headers" not in kwargs: kwargs["headers"] = {} diff --git a/pypaperless/api/documents.py b/pypaperless/api/documents.py index 207c310..fb89c5d 100644 --- a/pypaperless/api/documents.py +++ b/pypaperless/api/documents.py @@ -118,8 +118,8 @@ async def create(self, obj: DocumentPost) -> str: "document_type", "archive_serial_number", ): - if obj[field]: - form.add_field(field, obj[field]) + if getattr(obj, field): + form.add_field(field, getattr(obj, field)) if obj.tags and isinstance(obj.tags, list): for tag in obj.tags: diff --git a/tests/pypaperless/test_consumption_templates.py b/tests/api/test_consumption_templates.py similarity index 78% rename from tests/pypaperless/test_consumption_templates.py rename to tests/api/test_consumption_templates.py index 039ae22..06f899e 100644 --- a/tests/pypaperless/test_consumption_templates.py +++ b/tests/api/test_consumption_templates.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import ConsumptionTemplatesEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import ConsumptionTemplateSource +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["consumption_templates"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.consumption_templates, ConsumptionTemplatesEndpoint) assert not isinstance(paperless.consumption_templates, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["consumption_templates"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.consumption_templates.list() assert isinstance(result, list) @@ -32,18 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), ConsumptionTemplate) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["consumption_templates"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.consumption_templates.iterate(): assert isinstance(item, ConsumptionTemplate) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object( - paperless, "request_json", return_value=data["consumption_templates"]["results"][0] - ): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.consumption_templates.one(72) assert isinstance(item, ConsumptionTemplate) diff --git a/tests/pypaperless/test_correspondents.py b/tests/api/test_correspondents.py similarity index 81% rename from tests/pypaperless/test_correspondents.py rename to tests/api/test_correspondents.py index 565f8cf..dd2936c 100644 --- a/tests/pypaperless/test_correspondents.py +++ b/tests/api/test_correspondents.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import CorrespondentsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import MatchingAlgorithm +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["correspondents"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.correspondents, CorrespondentsEndpoint) assert isinstance(paperless.correspondents, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["correspondents"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.correspondents.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), Correspondent) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["correspondents"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.correspondents.iterate(): assert isinstance(item, Correspondent) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["correspondents"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.correspondents.one(72) assert isinstance(item, Correspondent) diff --git a/tests/pypaperless/test_custom_fields.py b/tests/api/test_custom_fields.py similarity index 81% rename from tests/pypaperless/test_custom_fields.py rename to tests/api/test_custom_fields.py index eba29ff..5e14618 100644 --- a/tests/pypaperless/test_custom_fields.py +++ b/tests/api/test_custom_fields.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import CustomFieldEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import CustomFieldType +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["custom_fields"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.custom_fields, CustomFieldEndpoint) assert isinstance(paperless.custom_fields, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["custom_fields"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.custom_fields.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), CustomField) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["custom_fields"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.custom_fields.iterate(): assert isinstance(item, CustomField) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["custom_fields"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.custom_fields.one(72) assert isinstance(item, CustomField) diff --git a/tests/pypaperless/test_document_types.py b/tests/api/test_document_types.py similarity index 81% rename from tests/pypaperless/test_document_types.py rename to tests/api/test_document_types.py index 2493a4d..173d479 100644 --- a/tests/pypaperless/test_document_types.py +++ b/tests/api/test_document_types.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import DocumentTypesEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import MatchingAlgorithm +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["document_types"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.document_types, DocumentTypesEndpoint) assert isinstance(paperless.document_types, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["document_types"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.document_types.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), DocumentType) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["document_types"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.document_types.iterate(): assert isinstance(item, DocumentType) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["document_types"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.document_types.one(72) assert isinstance(item, DocumentType) diff --git a/tests/pypaperless/test_documents.py b/tests/api/test_documents.py similarity index 84% rename from tests/pypaperless/test_documents.py rename to tests/api/test_documents.py index bf0a7c9..ec5da2c 100644 --- a/tests/pypaperless/test_documents.py +++ b/tests/api/test_documents.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import DocumentsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.custom_fields import CustomFieldValue +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["documents"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.documents, DocumentsEndpoint) assert isinstance(paperless.documents, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["documents"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.documents.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), Document) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["documents"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.documents.iterate(): assert isinstance(item, Document) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["documents"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.documents.one(72) assert isinstance(item, Document) diff --git a/tests/pypaperless/test_groups.py b/tests/api/test_groups.py similarity index 79% rename from tests/pypaperless/test_groups.py rename to tests/api/test_groups.py index 9ecd5df..5df52d9 100644 --- a/tests/pypaperless/test_groups.py +++ b/tests/api/test_groups.py @@ -2,21 +2,29 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import GroupsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult from pypaperless.models import Group +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["groups"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.groups, GroupsEndpoint) assert not isinstance(paperless.groups, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["groups"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.groups.list() assert isinstance(result, list) @@ -31,16 +39,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), Group) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["groups"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.groups.iterate(): assert isinstance(item, Group) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["groups"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.groups.one(72) assert isinstance(item, Group) diff --git a/tests/pypaperless/test_mail_accounts.py b/tests/api/test_mail_accounts.py similarity index 79% rename from tests/pypaperless/test_mail_accounts.py rename to tests/api/test_mail_accounts.py index d2d047e..4acbd98 100644 --- a/tests/pypaperless/test_mail_accounts.py +++ b/tests/api/test_mail_accounts.py @@ -2,21 +2,29 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import MailAccountsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult from pypaperless.models import MailAccount +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["mail_accounts"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.mail_accounts, MailAccountsEndpoint) assert not isinstance(paperless.mail_accounts, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["mail_accounts"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.mail_accounts.list() assert isinstance(result, list) @@ -31,16 +39,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), MailAccount) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["mail_accounts"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.mail_accounts.iterate(): assert isinstance(item, MailAccount) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["mail_accounts"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.mail_accounts.one(72) assert isinstance(item, MailAccount) diff --git a/tests/pypaperless/test_mail_rules.py b/tests/api/test_mail_rules.py similarity index 79% rename from tests/pypaperless/test_mail_rules.py rename to tests/api/test_mail_rules.py index ea32f4c..55fae6e 100644 --- a/tests/pypaperless/test_mail_rules.py +++ b/tests/api/test_mail_rules.py @@ -2,21 +2,29 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import MailRulesEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult from pypaperless.models import MailRule +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["mail_rules"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.mail_rules, MailRulesEndpoint) assert not isinstance(paperless.mail_rules, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["mail_rules"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.mail_rules.list() assert isinstance(result, list) @@ -31,16 +39,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), MailRule) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["mail_rules"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.mail_rules.iterate(): assert isinstance(item, MailRule) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["mail_rules"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.mail_rules.one(72) assert isinstance(item, MailRule) diff --git a/tests/pypaperless/test_saved_views.py b/tests/api/test_saved_views.py similarity index 82% rename from tests/pypaperless/test_saved_views.py rename to tests/api/test_saved_views.py index 45f0ce4..bd58c3f 100644 --- a/tests/pypaperless/test_saved_views.py +++ b/tests/api/test_saved_views.py @@ -2,21 +2,29 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import SavedViewsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult from pypaperless.models import SavedView, SavedViewFilterRule +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["saved_views"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.saved_views, SavedViewsEndpoint) assert not isinstance(paperless.saved_views, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["saved_views"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.saved_views.list() assert isinstance(result, list) @@ -31,16 +39,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), SavedView) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["saved_views"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.saved_views.iterate(): assert isinstance(item, SavedView) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["saved_views"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.saved_views.one(72) assert isinstance(item, SavedView) diff --git a/tests/pypaperless/test_storage_paths.py b/tests/api/test_storage_paths.py similarity index 81% rename from tests/pypaperless/test_storage_paths.py rename to tests/api/test_storage_paths.py index ff8d9fd..9840c5d 100644 --- a/tests/pypaperless/test_storage_paths.py +++ b/tests/api/test_storage_paths.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import StoragePathsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import MatchingAlgorithm +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["storage_paths"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.storage_paths, StoragePathsEndpoint) assert isinstance(paperless.storage_paths, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["storage_paths"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.storage_paths.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), StoragePath) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["storage_paths"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.storage_paths.iterate(): assert isinstance(item, StoragePath) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["storage_paths"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.storage_paths.one(72) assert isinstance(item, StoragePath) diff --git a/tests/pypaperless/test_tags.py b/tests/api/test_tags.py similarity index 80% rename from tests/pypaperless/test_tags.py rename to tests/api/test_tags.py index 2960595..a877571 100644 --- a/tests/pypaperless/test_tags.py +++ b/tests/api/test_tags.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import TagsEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult @@ -9,15 +11,21 @@ from pypaperless.models.shared import MatchingAlgorithm +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["tags"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.tags, TagsEndpoint) assert isinstance(paperless.tags, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["tags"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.tags.list() assert isinstance(result, list) @@ -32,16 +40,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), Tag) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["tags"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.tags.iterate(): assert isinstance(item, Tag) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["tags"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.tags.one(72) assert isinstance(item, Tag) diff --git a/tests/pypaperless/test_tasks.py b/tests/api/test_tasks.py similarity index 79% rename from tests/pypaperless/test_tasks.py rename to tests/api/test_tasks.py index 904dcb5..2eed008 100644 --- a/tests/pypaperless/test_tasks.py +++ b/tests/api/test_tasks.py @@ -2,6 +2,8 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import TasksEndpoint from pypaperless.api.base import BaseEndpointCrudMixin @@ -9,19 +11,23 @@ from pypaperless.models.shared import TaskStatus +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["tasks"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.tasks, TasksEndpoint) assert not isinstance(paperless.tasks, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["tasks"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.tasks.list() - # tasks have no list-all attribute... - # TODO: we have to do something with it assert isinstance(result, list) assert len(result) == 0 @@ -30,16 +36,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(tasks[0], Task) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["tasks"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.tasks.iterate(): assert isinstance(item, Task) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["tasks"]): + with patch.object(paperless, "request_json", return_value=dataset): item = await paperless.tasks.one("bd2de639-5ecd-4bc1-ab3d-106908ef00e1") assert isinstance(item, Task) diff --git a/tests/pypaperless/test_users.py b/tests/api/test_users.py similarity index 79% rename from tests/pypaperless/test_users.py rename to tests/api/test_users.py index dec7786..235494b 100644 --- a/tests/pypaperless/test_users.py +++ b/tests/api/test_users.py @@ -2,21 +2,29 @@ from unittest.mock import patch +import pytest + from pypaperless import Paperless from pypaperless.api import UsersEndpoint from pypaperless.api.base import BaseEndpointCrudMixin, PaginatedResult from pypaperless.models import User +@pytest.fixture(scope="module") +def dataset(data): + """Represent current data.""" + return data["users"] + + async def test_endpoint(paperless: Paperless) -> None: """Test endpoint.""" assert isinstance(paperless.users, UsersEndpoint) assert not isinstance(paperless.users, BaseEndpointCrudMixin) -async def test_list_and_get(paperless: Paperless, data): +async def test_list_and_get(paperless: Paperless, dataset): """Test list.""" - with patch.object(paperless, "request_json", return_value=data["users"]): + with patch.object(paperless, "request_json", return_value=dataset): result = await paperless.users.list() assert isinstance(result, list) @@ -31,16 +39,16 @@ async def test_list_and_get(paperless: Paperless, data): assert isinstance(page.items.pop(), User) -async def test_iterate(paperless: Paperless, data): +async def test_iterate(paperless: Paperless, dataset): """Test iterate.""" - with patch.object(paperless, "request_json", return_value=data["users"]): + with patch.object(paperless, "request_json", return_value=dataset): async for item in paperless.users.iterate(): assert isinstance(item, User) -async def test_one(paperless: Paperless, data): +async def test_one(paperless: Paperless, dataset): """Test one.""" - with patch.object(paperless, "request_json", return_value=data["users"]["results"][0]): + with patch.object(paperless, "request_json", return_value=dataset["results"][0]): item = await paperless.users.one(72) assert isinstance(item, User) diff --git a/tests/common/test_crud_default.py b/tests/common/test_crud_default.py new file mode 100644 index 0000000..356a6b1 --- /dev/null +++ b/tests/common/test_crud_default.py @@ -0,0 +1,60 @@ +"""Test CRUD.""" + +from unittest.mock import patch + +import pytest + +from pypaperless import Paperless +from pypaperless.models import Correspondent, CorrespondentPost +from pypaperless.models.shared import MatchingAlgorithm +from pypaperless.util import dataclass_from_dict, dataclass_to_dict + + +@pytest.fixture(scope="module") +def correspondent_dataset(data): + """Represent current data.""" + return data["correspondents"] + + +async def test_default_create(paperless: Paperless): + """Test default create.""" + to_create = CorrespondentPost(name="salty correspondent") + + # test matching model defaults + assert to_create.is_insensitive is True + assert to_create.match == "" + assert to_create.matching_algorithm == MatchingAlgorithm.NONE + + to_create.matching_algorithm = MatchingAlgorithm.FUZZY + + with patch.object(paperless, "request_json", return_value=dataclass_to_dict(to_create)): + created = await paperless.correspondents.create(to_create) + + assert isinstance(created, Correspondent) + assert created.matching_algorithm == MatchingAlgorithm.FUZZY + + +async def test_default_update(paperless: Paperless, correspondent_dataset): + """Test default update.""" + new_name = "Sample Correspondent Updated" + + to_update = dataclass_from_dict(Correspondent, correspondent_dataset["results"][0]) + assert isinstance(to_update, Correspondent) + + to_update.name = new_name + + with patch.object(paperless, "request_json", return_value=dataclass_to_dict(to_update)): + updated = await paperless.correspondents.update(to_update) + + assert isinstance(updated, Correspondent) + assert updated.name == new_name + + +async def test_default_delete(paperless: Paperless, correspondent_dataset): + """Test default delete.""" + to_delete = dataclass_from_dict(Correspondent, correspondent_dataset["results"][3]) + assert isinstance(to_delete, Correspondent) + + # figuring out how to test that well. + with patch.object(paperless, "request_json", return_value=True): + assert await paperless.correspondents.delete(to_delete) diff --git a/tests/common/test_crud_documents.py b/tests/common/test_crud_documents.py new file mode 100644 index 0000000..65f53eb --- /dev/null +++ b/tests/common/test_crud_documents.py @@ -0,0 +1,72 @@ +"""Test CRUD for documents.""" + +from unittest.mock import patch + +import pytest +from aiohttp import FormData + +from pypaperless import Paperless +from pypaperless.models import DocumentPost + + +@pytest.fixture(scope="module") +def documents_dataset(data): + """Represent current data.""" + return data["documents"] + + +async def test_document_create(paperless: Paperless): + """Test document create.""" + a_sample_document = bytes("Example content.", "utf-8") + a_sample_title = "Test Title" + a_sample_correspondent = 1337 + a_sample_doctype = 42 + a_sample_asn = 23 + a_sample_taglist = [0, 1, 1, 2, 3, 5, 8, 13] + + # we check the form data created + # the test seems useless but it actually executes the create() method + # and helped me find a dirty bug, so we love each other. obviously. :D + + to_create = DocumentPost( + document=a_sample_document, + title=a_sample_title, + correspondent=a_sample_correspondent, + document_type=a_sample_doctype, + archive_serial_number=a_sample_asn, + tags=a_sample_taglist, + ) + + async def fake_request_json(*args, **kwargs): + data = kwargs["data"] # supplied form data + + assert args[0] == "post" + assert isinstance(data, FormData) + + form = FormData() + form.add_fields( + ("document", a_sample_document), + ("title", a_sample_title), + ("correspondent", a_sample_correspondent), + ("document_type", a_sample_doctype), + ("archive_serial_number", a_sample_asn), + *(("tags", f"{tag}") for tag in a_sample_taglist), + ) + + assert ( + form._gen_form_urlencoded()._value # pylint: disable=protected-access + == data._gen_form_urlencoded()._value # pylint: disable=protected-access + ) + + return "bd2de639-5ecd-4bc1-ab3d-106908ef00e1" + + # mock request_json() method + with patch.object( + paperless, + "request_json", + fake_request_json, + ): + task_id = await paperless.documents.create(to_create) + + assert isinstance(task_id, str) + assert len(task_id) == 36 diff --git a/tests/conftest.py b/tests/conftest.py index 318e7b8..c61f411 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -30,12 +30,13 @@ def data(): @pytest.fixture async def paperless() -> Paperless: """Create and yield client.""" - api = Paperless("localhost:8000", "secret-key") def endpoints_data(): d = load_fixture_data("data.json") return d["endpoints"] + api = Paperless("local.test:1337", "secret-key") + with patch.object(api, "request_json", return_value=endpoints_data()): await api.initialize() yield api diff --git a/tests/fixtures/data.json b/tests/fixtures/data.json index 2469ff7..6fca8fd 100644 --- a/tests/fixtures/data.json +++ b/tests/fixtures/data.json @@ -578,7 +578,8 @@ ] } ] - }, "groups": { + }, + "groups": { "count": 1, "next": null, "previous": null, @@ -628,7 +629,8 @@ ] } ] - },"users":{ + }, + "users": { "count": 4, "next": null, "previous": null, @@ -903,7 +905,8 @@ ] } ] - },"mail_accounts":{ + }, + "mail_accounts": { "count": 1, "next": null, "previous": null, @@ -925,7 +928,8 @@ "user_can_change": true } ] - },"mail_rules":{ + }, + "mail_rules": { "count": 1, "next": null, "previous": null, @@ -960,7 +964,8 @@ "user_can_change": true } ] - },"saved_views":{ + }, + "saved_views": { "count": 5, "next": null, "previous": null, @@ -1061,7 +1066,8 @@ "user_can_change": true } ] - },"storage_paths":{ + }, + "storage_paths": { "count": 3, "next": null, "previous": null, @@ -1108,7 +1114,8 @@ "user_can_change": true } ] - },"tags":{ + }, + "tags": { "count": 11, "next": null, "previous": null, @@ -1132,7 +1139,8 @@ "document_count": 20, "owner": null, "user_can_change": true - },{ + }, + { "id": 10, "slug": "inbox", "name": "Inbox", @@ -1147,7 +1155,8 @@ "user_can_change": true } ] - },"tasks":[ + }, + "tasks": [ { "id": 2134, "task_id": "bd2de639-5ecd-4bc1-ab3d-106908ef00e1",