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

1""" 

2 

3 

4 

5 

6 ---------------------------------------------------------------------------- 

7 

8 METADATA: 

9 

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 

17 

18 ---------------------------------------------------------------------------- 

19 

20 LAST MODIFIED: 

21 

22 2025-03-12 By Jess Mann 

23 

24""" 

25from __future__ import annotations 

26 

27import json 

28import logging 

29import os 

30from pathlib import Path 

31from typing import TYPE_CHECKING, Any, Callable, Generic, Iterator, override 

32import pytest 

33 

34from pydantic import ValidationError 

35from typing_extensions import TypeAlias, TypeVar 

36 

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) 

67 

68from paperap.tests.testcase import TestMixin 

69 

70logger = logging.getLogger(__name__) 

71 

72_StandardModel = TypeVar("_StandardModel", bound="StandardModel", default="StandardModel") 

73_StandardResource = TypeVar("_StandardResource", bound="StandardResource", default="StandardResource") 

74_StandardQuerySet = TypeVar("_StandardQuerySet", bound="StandardQuerySet", default="StandardQuerySet") 

75 

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() 

90 

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() 

101 

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}" 

114 

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 

123 

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 

132 

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 

141 

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 

150 

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 

159 

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 

168 

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 

177 

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 

186 

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 

195 

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 

204 

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 

213 

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 

222 

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 

231 

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 

240 

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 

249 

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