Coverage for src/paperap/tests/pytest.py: 85%
122 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-15 03:55 -0400
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-15 03:55 -0400
1"""
6 ----------------------------------------------------------------------------
8 METADATA:
10 File: pytest.py
11 Project: paperap
12 Created: 2025-03-12
13 Version: 0.0.5
14 Author: Jess Mann
15 Email: jess@jmann.me
16 Copyright (c) 2025 Jess Mann
18 ----------------------------------------------------------------------------
20 LAST MODIFIED:
22 2025-03-12 By Jess Mann
24"""
25from __future__ import annotations
27import json
28import logging
29import os
30from pathlib import Path
31from typing import TYPE_CHECKING, Any, Callable, Generic, Iterator, override
32import pytest
34from pydantic import ValidationError
35from typing_extensions import TypeAlias, TypeVar
37from paperap.client import PaperlessClient
38from paperap.models import (BaseQuerySet, Correspondent, CorrespondentQuerySet,
39 CustomField, CustomFieldQuerySet,
40 Document, DocumentQuerySet, DocumentType,
41 DocumentTypeQuerySet, Group, GroupQuerySet,
42 Profile, ProfileQuerySet, SavedView,
43 SavedViewQuerySet, ShareLinks, ShareLinksQuerySet,
44 StandardModel, StandardQuerySet, StoragePath,
45 StoragePathQuerySet, Tag, TagQuerySet, Task,
46 TaskQuerySet, UISettings, UISettingsQuerySet, User,
47 UserQuerySet, Workflow, WorkflowAction,
48 WorkflowActionQuerySet, WorkflowQuerySet,
49 WorkflowTrigger, WorkflowTriggerQuerySet)
50from paperap.resources import (BaseResource, CorrespondentResource,
51 CustomFieldResource,
52 DocumentResource, DocumentTypeResource,
53 GroupResource, ProfileResource,
54 SavedViewResource, ShareLinksResource,
55 StandardResource, StoragePathResource,
56 TagResource, TaskResource, UISettingsResource,
57 UserResource, WorkflowActionResource,
58 WorkflowResource, WorkflowTriggerResource)
59from paperap.tests.factories import (CorrespondentFactory, DocumentFactory,
60 DocumentTypeFactory, GroupFactory,
61 ProfileFactory, PydanticFactory,
62 SavedViewFactory, ShareLinksFactory,
63 StoragePathFactory, TagFactory,
64 TaskFactory, UISettingsFactory,
65 UserFactory, WorkflowActionFactory,
66 WorkflowFactory, WorkflowTriggerFactory)
68from paperap.tests.testcase import TestMixin
70logger = logging.getLogger(__name__)
72_StandardModel = TypeVar("_StandardModel", bound="StandardModel", default="StandardModel")
73_StandardResource = TypeVar("_StandardResource", bound="StandardResource", default="StandardResource")
74_StandardQuerySet = TypeVar("_StandardQuerySet", bound="StandardQuerySet", default="StandardQuerySet")
76class PyTestCase(
77 TestMixin[_StandardModel, _StandardResource, _StandardQuerySet],
78 Generic[_StandardModel, _StandardResource, _StandardQuerySet]
79):
80 @pytest.fixture(autouse=True)
81 def setUp(self, mocker) -> None:
82 """
83 Set up the test case by initializing the client, resource, and model data.
84 """
85 self.setup_references()
86 self.setup_client(mocker)
87 self.setup_resource()
88 self.setup_model_data()
89 self.setup_model()
91 @override
92 def setup_client(self, mocker : Any = None, **kwargs):
93 """Set up the PaperlessClient instance, optionally mocking environment variables."""
94 if not hasattr(self, "client") or not self.client:
95 if self.mock_env:
96 # Patch os.environ with pytest
97 mocker.patch.dict(os.environ, self.env_data, clear=True)
98 self.client = PaperlessClient()
99 else:
100 self.client = PaperlessClient()
102 @override
103 def validate_field(self, field_name: str, test_cases: list[tuple[Any, Any]]):
104 """Validate that a model field processes data correctly."""
105 for input_value, expected in test_cases:
106 if isinstance(expected, type) and issubclass(expected, Exception):
107 with pytest.raises(expected, match=f"Setting {self.model.__class__.__name__}.{field_name} failed"):
108 setattr(self.model, field_name, input_value)
109 else:
110 setattr(self.model, field_name, input_value)
111 real_value = getattr(self.model, field_name)
112 assert isinstance(real_value, type(expected)), f"Expected type {type(expected)}, got {type(real_value)}"
113 assert real_value == expected, f"Expected {expected}, got {real_value}"
115class CustomFieldPyTest(PyTestCase["CustomField", "CustomFieldResource", "CustomFieldQuerySet"]):
116 """
117 A test case for the CustomField model and resource.
118 """
119 resource_class = CustomFieldResource
120 model_type = CustomField
121 queryset_type = CustomFieldQuerySet
122 #factory = PydanticFactory
124class DocumentPyTest(PyTestCase["Document", "DocumentResource", "DocumentQuerySet"]):
125 """
126 A test case for the Document model and resource.
127 """
128 resource_class = DocumentResource
129 model_type = Document
130 queryset_type = DocumentQuerySet
131 factory = DocumentFactory
133class DocumentTypePyTest(PyTestCase["DocumentType", "DocumentTypeResource", "DocumentTypeQuerySet"]):
134 """
135 A test case for the DocumentType model and resource.
136 """
137 resource_class = DocumentTypeResource
138 model_type = DocumentType
139 queryset_type = DocumentTypeQuerySet
140 factory = DocumentTypeFactory
142class CorrespondentPyTest(PyTestCase["Correspondent", "CorrespondentResource", "CorrespondentQuerySet"]):
143 """
144 A test case for the Correspondent model and resource.
145 """
146 resource_class = CorrespondentResource
147 model_type = Correspondent
148 queryset_type = CorrespondentQuerySet
149 factory = CorrespondentFactory
151class TagPyTest(PyTestCase["Tag", "TagResource", "TagQuerySet"]):
152 """
153 A test case for the Tag model and resource.
154 """
155 resource_class = TagResource
156 model_type = Tag
157 queryset_type = TagQuerySet
158 factory = TagFactory
160class UserPyTest(PyTestCase["User", "UserResource", "UserQuerySet"]):
161 """
162 A test case for the User model and resource.
163 """
164 resource_class = UserResource
165 model_type = User
166 queryset_type = UserQuerySet
167 factory = UserFactory
169class GroupPyTest(PyTestCase["Group", "GroupResource", "GroupQuerySet"]):
170 """
171 A test case for the Group model and resource.
172 """
173 resource_class = GroupResource
174 model_type = Group
175 queryset_type = GroupQuerySet
176 factory = GroupFactory
178class ProfilePyTest(PyTestCase["Profile", "ProfileResource", "ProfileQuerySet"]):
179 """
180 A test case for the Profile model and resource.
181 """
182 resource_class = ProfileResource
183 model_type = Profile
184 queryset_type = ProfileQuerySet
185 factory = ProfileFactory
187class TaskPyTest(PyTestCase["Task", "TaskResource", "TaskQuerySet"]):
188 """
189 A test case for the Task model and resource.
190 """
191 resource_class = TaskResource
192 model_type = Task
193 queryset_type = TaskQuerySet
194 factory = TaskFactory
196class WorkflowPyTest(PyTestCase["Workflow", "WorkflowResource", "WorkflowQuerySet"]):
197 """
198 A test case for the Workflow model and resource.
199 """
200 resource_class = WorkflowResource
201 model_type = Workflow
202 queryset_type = WorkflowQuerySet
203 factory = WorkflowFactory
205class SavedViewPyTest(PyTestCase["SavedView", "SavedViewResource", "SavedViewQuerySet"]):
206 """
207 A test case for the SavedView model and resource.
208 """
209 resource_class = SavedViewResource
210 model_type = SavedView
211 queryset_type = SavedViewQuerySet
212 factory = SavedViewFactory
214class ShareLinksPyTest(PyTestCase["ShareLinks", "ShareLinksResource", "ShareLinksQuerySet"]):
215 """
216 A test case for ShareLinks
217 """
218 resource_class = ShareLinksResource
219 model_type = ShareLinks
220 queryset_type = ShareLinksQuerySet
221 factory = ShareLinksFactory
223class UISettingsPyTest(PyTestCase["UISettings", "UISettingsResource", "UISettingsQuerySet"]):
224 """
225 A test case for the UISettings model and resource.
226 """
227 resource_class = UISettingsResource
228 model_type = UISettings
229 queryset_type = UISettingsQuerySet
230 factory = UISettingsFactory
232class StoragePathPyTest(PyTestCase["StoragePath", "StoragePathResource", "StoragePathQuerySet"]):
233 """
234 A test case for the StoragePath model and resource.
235 """
236 resource_class = StoragePathResource
237 model_type = StoragePath
238 queryset_type = StoragePathQuerySet
239 factory = StoragePathFactory
241class WorkflowActionPyTest(PyTestCase["WorkflowAction", "WorkflowActionResource", "WorkflowActionQuerySet"]):
242 """
243 A test case for the WorkflowAction model and resource.
244 """
245 resource_class = WorkflowActionResource
246 model_type = WorkflowAction
247 queryset_type = WorkflowActionQuerySet
248 factory = WorkflowActionFactory
250class WorkflowTriggerPyTest(PyTestCase["WorkflowTrigger", "WorkflowTriggerResource", "WorkflowTriggerQuerySet"]):
251 """
252 A test case for the WorkflowTrigger model and resource.
253 """
254 resource_class = WorkflowTriggerResource
255 model_type = WorkflowTrigger
256 queryset_type = WorkflowTriggerQuerySet
257 factory = WorkflowTriggerFactory