Coverage for src/paperap/tests/factories/models.py: 100%
201 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-11 21:37 -0400
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-11 21:37 -0400
1"""
5 ----------------------------------------------------------------------------
7 METADATA:
9 File: models.py
10 Project: paperap
11 Created: 2025-03-07
12 Version: 0.0.5
13 Author: Jess Mann
14 Email: jess@jmann.me
15 Copyright (c) 2025 Jess Mann
17 ----------------------------------------------------------------------------
19 LAST MODIFIED:
21 2025-03-07 By Jess Mann
23"""
24from __future__ import annotations
26from abc import ABC
27from datetime import datetime, timezone
28from typing import Any, Generic
30import factory
31from faker import Faker
32from typing_extensions import TypeVar
34from paperap.models import (Correspondent, CustomField, Document, DocumentNote,
35 DocumentType, Group, Profile, SavedView,
36 ShareLinks, StoragePath, Tag, Task, UISettings,
37 User, Workflow, WorkflowAction, WorkflowTrigger)
39fake = Faker()
41class PydanticFactory(factory.Factory):
42 """Base factory for Pydantic models."""
44class CorrespondentFactory(PydanticFactory):
45 class Meta: # type: ignore # pyright handles this wrong
46 model = Correspondent
48 slug = factory.LazyFunction(fake.slug)
49 name = factory.Faker("name")
50 match = factory.Faker("word")
51 matching_algorithm = factory.Faker("random_int", min=0, max=3)
52 is_insensitive = factory.Faker("boolean")
53 document_count = factory.Faker("random_int", min=0, max=100)
54 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
55 user_can_change = factory.Faker("boolean")
57class CustomFieldFactory(PydanticFactory):
58 class Meta: # type: ignore # pyright handles this wrong
59 model = CustomField
61 name = factory.Faker("word")
62 data_type = factory.Faker("word")
63 extra_data = factory.Dict({"key": fake.word(), "value": fake.word()})
64 document_count = factory.Faker("random_int", min=0, max=100)
66class DocumentNoteFactory(PydanticFactory):
67 class Meta: # type: ignore # pyright handles this wrong
68 model = DocumentNote
70 note = factory.Faker("sentence")
71 created = factory.LazyFunction(datetime.now)
72 deleted_at = None
73 restored_at = None
74 transaction_id = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
75 document = factory.Faker("random_int", min=1, max=1000)
76 user = factory.Faker("random_int", min=1, max=1000)
78class DocumentFactory(PydanticFactory):
79 class Meta: # type: ignore # pyright handles this wrong
80 model = Document
82 added = factory.LazyFunction(datetime.now)
83 archive_serial_number = factory.Faker("random_int", min=1, max=100000)
84 archived_file_name = factory.Faker("file_name")
85 content = factory.Faker("text")
86 correspondent = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
87 created = factory.LazyFunction(datetime.now)
88 created_date = factory.Maybe(factory.Faker("boolean"), factory.Faker("date"), None)
89 updated = factory.LazyFunction(datetime.now)
90 deleted_at = None
91 document_type = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
92 is_shared_by_requester = factory.Faker("boolean")
93 original_file_name = factory.Faker("file_name")
94 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
95 page_count = factory.Faker("random_int", min=1, max=500)
96 storage_path = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
97 tags = factory.List([factory.Faker("random_int", min=1, max=50) for _ in range(5)])
98 title = factory.Faker("sentence")
99 user_can_change = factory.Faker("boolean")
100 # notes is a list of DocumentNote instances
101 notes = factory.LazyFunction(lambda: [DocumentNoteFactory() for _ in range(3)])
103class DocumentTypeFactory(PydanticFactory):
104 class Meta: # type: ignore # pyright handles this wrong
105 model = DocumentType
107 name = factory.Faker("word")
108 slug = factory.LazyFunction(fake.slug)
109 match = factory.Faker("word")
110 matching_algorithm = factory.Faker("random_int", min=0, max=3)
111 is_insensitive = factory.Faker("boolean")
112 document_count = factory.Faker("random_int", min=0, max=1000)
113 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
114 user_can_change = factory.Faker("boolean")
116class TagFactory(PydanticFactory):
117 class Meta: # type: ignore # pyright handles this wrong
118 model = Tag
120 name = factory.Faker("word")
121 slug = factory.LazyFunction(fake.slug)
122 colour = factory.Faker("hex_color")
123 match = factory.Faker("word")
124 matching_algorithm = factory.Faker("random_int", min=0, max=3)
125 is_insensitive = factory.Faker("boolean")
126 is_inbox_tag = factory.Faker("boolean")
127 document_count = factory.Faker("random_int", min=0, max=500)
128 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
129 user_can_change = factory.Faker("boolean")
131class ProfileFactory(PydanticFactory):
132 class Meta: # type: ignore # pyright handles this wrong
133 model = Profile
135 email = factory.Faker("email")
136 password = factory.Faker("password")
137 first_name = factory.Faker("first_name")
138 last_name = factory.Faker("last_name")
139 auth_token = factory.Faker("uuid4")
140 social_accounts = factory.List([factory.Faker("url") for _ in range(3)])
141 has_usable_password = factory.Faker("boolean")
143class UserFactory(PydanticFactory):
144 class Meta: # type: ignore # pyright handles this wrong
145 model = User
147 username = factory.Faker("user_name")
148 email = factory.Faker("email")
149 password = factory.Faker("password")
150 first_name = factory.Faker("first_name")
151 last_name = factory.Faker("last_name")
152 date_joined = factory.Faker("iso8601")
153 is_staff = factory.Faker("boolean")
154 is_active = factory.Faker("boolean")
155 is_superuser = factory.Faker("boolean")
156 groups = factory.List([factory.Faker("random_int", min=1, max=10) for _ in range(3)])
157 user_permissions = factory.List([factory.Faker("word") for _ in range(5)])
158 inherited_permissions = factory.List([factory.Faker("word") for _ in range(5)])
160class StoragePathFactory(PydanticFactory):
161 class Meta: # type: ignore # pyright handles this wrong
162 model = StoragePath
164 name = factory.Faker("word")
165 slug = factory.LazyFunction(fake.slug)
166 path = factory.Faker("file_path")
167 match = factory.Faker("word")
168 matching_algorithm = factory.Faker("random_int", min=0, max=3)
169 is_insensitive = factory.Faker("boolean")
170 document_count = factory.Faker("random_int", min=0, max=500)
171 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
172 user_can_change = factory.Faker("boolean")
174class SavedViewFactory(PydanticFactory):
175 class Meta: # type: ignore # pyright handles this wrong
176 model = SavedView
178 name = factory.Faker("sentence", nb_words=3)
179 show_on_dashboard = factory.Faker("boolean")
180 show_in_sidebar = factory.Faker("boolean")
181 sort_field = factory.Faker("word")
182 sort_reverse = factory.Faker("boolean")
183 filter_rules = factory.List([{"key": fake.word(), "value": fake.word()} for _ in range(3)])
184 page_size = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=10, max=100), None)
185 display_mode = factory.Faker("word")
186 display_fields = factory.List([factory.Faker("word") for _ in range(5)])
187 owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
188 user_can_change = factory.Faker("boolean")
190class ShareLinksFactory(PydanticFactory):
191 class Meta: # type: ignore # pyright handles this wrong
192 model = ShareLinks
194 expiration = factory.Maybe(factory.Faker("boolean"), factory.Faker("future_datetime"), None)
195 slug = factory.Faker("slug")
196 document = factory.Faker("random_int", min=1, max=1000)
197 created = factory.LazyFunction(datetime.now)
198 file_version = factory.Faker("word")
200class TaskFactory(PydanticFactory):
201 class Meta: # type: ignore # pyright handles this wrong
202 model = Task
204 task_id = factory.Faker("uuid4")
205 task_file_name = factory.Faker("file_name")
206 date_done = factory.Maybe(factory.Faker("boolean"), factory.Faker("iso8601"), None)
207 type = factory.Maybe(factory.Faker("boolean"), factory.Faker("word"), None)
208 status = factory.Faker("random_element", elements=["pending", "completed", "failed"])
209 result = factory.Maybe(factory.Faker("boolean"), factory.Faker("sentence"), None)
210 acknowledged = factory.Faker("boolean")
211 related_document = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=1000), None)
213class UISettingsFactory(PydanticFactory):
214 class Meta: # type: ignore # pyright handles this wrong
215 model = UISettings
217 user = factory.Dict({"theme": "dark", "language": "en"})
218 settings = factory.Dict({"dashboard_layout": "grid", "notification_settings": {"email": True}})
219 permissions = factory.List([factory.Faker("word") for _ in range(5)])
221class GroupFactory(PydanticFactory):
222 class Meta: # type: ignore # pyright handles this wrong
223 model = Group
225 name = factory.Faker("word")
226 permissions = factory.List([factory.Faker("word") for _ in range(5)])
228class WorkflowTriggerFactory(PydanticFactory):
229 class Meta: # type: ignore # pyright handles this wrong
230 model = WorkflowTrigger
232 sources = factory.List([factory.Faker("word") for _ in range(3)])
233 type = factory.Faker("random_int", min=1, max=10)
234 filter_path = factory.Maybe(factory.Faker("boolean"), factory.Faker("file_path"), None)
235 filter_filename = factory.Maybe(factory.Faker("boolean"), factory.Faker("file_name"), None)
236 filter_mailrule = factory.Maybe(factory.Faker("boolean"), factory.Faker("word"), None)
237 matching_algorithm = factory.Faker("random_int", min=0, max=3)
238 match = factory.Faker("word")
239 is_insensitive = factory.Faker("boolean")
240 filter_has_tags = factory.List([factory.Faker("random_int", min=1, max=50) for _ in range(5)])
241 filter_has_correspondent = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
242 filter_has_document_type = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
244class WorkflowActionFactory(PydanticFactory):
245 class Meta: # type: ignore # pyright handles this wrong
246 model = WorkflowAction
248 type = factory.Faker("word")
249 assign_title = factory.Maybe(factory.Faker("boolean"), factory.Faker("sentence"), None)
250 assign_tags = factory.List([factory.Faker("random_int", min=1, max=50) for _ in range(3)])
251 assign_correspondent = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
252 assign_document_type = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
253 assign_storage_path = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
254 assign_owner = factory.Maybe(factory.Faker("boolean"), factory.Faker("random_int", min=1, max=100), None)
255 assign_view_users = factory.List([factory.Faker("random_int", min=1, max=50) for _ in range(3)])
256 assign_view_groups = factory.List([factory.Faker("random_int", min=1, max=10) for _ in range(3)])
257 remove_all_tags = factory.Faker("boolean")
258 remove_all_custom_fields = factory.Faker("boolean")
260class WorkflowFactory(PydanticFactory):
261 class Meta: # type: ignore # pyright handles this wrong
262 model = Workflow
264 name = factory.Faker("sentence", nb_words=3)
265 order = factory.Faker("random_int", min=1, max=100)
266 enabled = factory.Faker("boolean")
267 triggers = factory.List([factory.Dict({"type": fake.random_int(min=1, max=10), "match": fake.word()}) for _ in range(3)])
268 actions = factory.List([factory.Dict({"type": fake.word(), "assign_tags": [fake.random_int(min=1, max=50)]}) for _ in range(3)])