Coverage for databases/tests/test_find_first_or_raise.py: 100%
86 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
1import pytest
3from prisma import Prisma, errors
4from prisma.types import UserWhereInput
7@pytest.mark.asyncio
8async def test_find_first_or_raise(client: Prisma) -> None:
9 """Skips multiple non-matching records"""
10 posts = [
11 await client.post.create(
12 {
13 'title': 'Test post 1',
14 'published': False,
15 'views': 100,
16 }
17 ),
18 await client.post.create(
19 {
20 'title': 'Test post 2',
21 'published': False,
22 }
23 ),
24 await client.post.create(
25 {
26 'title': 'Test post 3',
27 'published': False,
28 }
29 ),
30 await client.post.create(
31 {
32 'title': 'Test post 4',
33 'published': True,
34 'views': 500,
35 }
36 ),
37 await client.post.create(
38 {
39 'title': 'Test post 5',
40 'published': False,
41 }
42 ),
43 await client.post.create(
44 {
45 'title': 'Test post 6',
46 'published': True,
47 }
48 ),
49 ]
51 post = await client.post.find_first_or_raise(
52 where={
53 'published': True,
54 },
55 order={
56 'title': 'asc',
57 },
58 )
59 assert post.id == posts[3].id
60 assert post.title == 'Test post 4'
61 assert post.published is True
63 with pytest.raises(
64 errors.RecordNotFoundError,
65 match=r'depends on one or more records that were required but not found',
66 ):
67 await client.post.find_first_or_raise(
68 where={
69 'title': {
70 'contains': 'not found',
71 }
72 }
73 )
75 post = await client.post.find_first_or_raise(
76 where={
77 'published': True,
78 },
79 order={
80 'title': 'asc',
81 },
82 skip=1,
83 )
84 assert post.id == posts[5].id
85 assert post.title == 'Test post 6'
86 assert post.published is True
88 post = await client.post.find_first_or_raise(
89 where={
90 'NOT': [
91 {
92 'published': True,
93 },
94 ],
95 },
96 order={
97 'created_at': 'asc',
98 },
99 )
100 assert post.title == 'Test post 1'
102 post = await client.post.find_first_or_raise(
103 where={
104 'NOT': [
105 {
106 'title': {
107 'contains': '1',
108 },
109 },
110 {
111 'title': {
112 'contains': '2',
113 },
114 },
115 ],
116 },
117 order={
118 'created_at': 'asc',
119 },
120 )
121 assert post.title == 'Test post 3'
123 post = await client.post.find_first_or_raise(
124 where={
125 'title': {
126 'contains': 'Test',
127 },
128 'AND': [
129 {
130 'published': True,
131 },
132 ],
133 },
134 order={
135 'created_at': 'asc',
136 },
137 )
138 assert post.title == 'Test post 4'
140 post = await client.post.find_first_or_raise(
141 where={
142 'AND': [
143 {
144 'published': True,
145 },
146 {
147 'title': {
148 'contains': 'Test',
149 }
150 },
151 ],
152 },
153 order={
154 'created_at': 'asc',
155 },
156 )
157 assert post.title == 'Test post 4'
159 with pytest.raises(errors.RecordNotFoundError):
160 await client.post.find_first_or_raise(
161 where={
162 'views': {
163 'gt': 100,
164 },
165 'OR': [
166 {
167 'published': False,
168 },
169 ],
170 }
171 )
173 post = await client.post.find_first_or_raise(
174 where={
175 'OR': [
176 {
177 'views': {
178 'gt': 100,
179 },
180 },
181 {
182 'published': False,
183 },
184 ]
185 },
186 order={
187 'created_at': 'asc',
188 },
189 )
190 assert post.title == 'Test post 1'
192 post = await client.post.find_first_or_raise(
193 where={
194 'OR': [
195 {
196 'views': {
197 'gt': 100,
198 },
199 },
200 ]
201 }
202 )
203 assert post.title == 'Test post 4'
206@pytest.mark.asyncio
207async def test_filtering_one_to_one_relation(client: Prisma) -> None:
208 """Filtering by a 1-1 relational field and negating the filter"""
209 async with client.batch_() as batcher:
210 batcher.user.create(
211 {
212 'name': 'Robert',
213 'profile': {
214 'create': {
215 'description': 'My very cool bio.',
216 'country': 'Scotland',
217 },
218 },
219 },
220 )
221 batcher.user.create(
222 {
223 'name': 'Tegan',
224 'profile': {
225 'create': {
226 'description': 'Hello world, this is my bio.',
227 'country': 'Scotland',
228 },
229 },
230 },
231 )
232 batcher.user.create({'name': 'Callum'})
234 user = await client.user.find_first_or_raise(
235 where={
236 'profile': {
237 'is': {
238 'description': {
239 'contains': 'cool',
240 }
241 }
242 }
243 }
244 )
245 assert user.name == 'Robert'
246 assert user.profile is None
248 user = await client.user.find_first_or_raise(
249 where={
250 'profile': {
251 'is_not': {
252 'description': {
253 'contains': 'bio',
254 }
255 }
256 }
257 }
258 )
259 assert user.name == 'Callum'
260 assert user.profile is None
263@pytest.mark.asyncio
264async def test_filtering_and_ordering_one_to_many_relation(
265 client: Prisma,
266) -> None:
267 """Filtering with every, some, none and ordering by a 1-M relational field"""
268 async with client.batch_() as batcher:
269 batcher.user.create(
270 {
271 'name': 'Robert',
272 'posts': {
273 'create': [
274 {'title': 'My first post', 'published': True},
275 {'title': 'My second post', 'published': False},
276 ]
277 },
278 }
279 )
280 batcher.user.create(
281 {
282 'name': 'Tegan',
283 'posts': {
284 'create': [
285 {'title': 'Hello, world!', 'published': True},
286 {'title': 'My test post', 'published': False},
287 ]
288 },
289 }
290 )
291 batcher.user.create({'name': 'Callum'})
293 user = await client.user.find_first_or_raise(
294 where={
295 'posts': {
296 'every': {
297 'title': {
298 'contains': 'post',
299 }
300 }
301 }
302 },
303 )
304 assert user.name == 'Robert'
306 user = await client.user.find_first_or_raise(
307 where={
308 'posts': {
309 'none': {
310 'title': {
311 'contains': 'Post',
312 }
313 }
314 }
315 },
316 order={
317 'name': 'asc',
318 },
319 )
320 assert user.name == 'Callum'
322 with pytest.raises(errors.RecordNotFoundError):
323 await client.user.find_first_or_raise(
324 where={
325 'posts': {
326 'some': {
327 'title': 'foo',
328 }
329 }
330 }
331 )
333 # ordering
335 user = await client.user.find_first_or_raise(
336 where={
337 'posts': {
338 'some': {
339 'title': {
340 'contains': 'post',
341 }
342 }
343 }
344 },
345 order={'name': 'asc'},
346 )
347 assert user.name == 'Robert'
349 user = await client.user.find_first_or_raise(
350 where={
351 'posts': {
352 'some': {
353 'title': {
354 'contains': 'post',
355 }
356 }
357 }
358 },
359 order={'name': 'desc'},
360 )
361 assert user.name == 'Tegan'
364@pytest.mark.asyncio
365async def test_list_wrapper_query_transformation(client: Prisma) -> None:
366 """Queries wrapped within a list transform global aliases"""
367 query: UserWhereInput = {
368 'OR': [
369 {'name': {'startswith': '40'}},
370 {'name': {'contains': ', 40'}},
371 {'name': {'contains': 'house'}},
372 ]
373 }
375 await client.user.create({'name': 'Robert house'})
376 found = await client.user.find_first_or_raise(where=query, order={'created_at': 'asc'})
377 assert found.name == 'Robert house'
379 await client.user.create({'name': '40 robert'})
380 found = await client.user.find_first_or_raise(skip=1, where=query, order={'created_at': 'asc'})
381 assert found.name == '40 robert'
384@pytest.mark.asyncio
385async def test_distinct(client: Prisma) -> None:
386 """Filtering by distinct combinations of fields"""
387 users = [
388 await client.user.create(
389 data={
390 'name': 'Robert',
391 },
392 ),
393 await client.user.create(
394 data={
395 'name': 'Tegan',
396 },
397 ),
398 await client.user.create(
399 data={
400 'name': 'Patrick',
401 },
402 ),
403 ]
404 async with client.batch_() as batcher:
405 batcher.profile.create(
406 {
407 'city': 'Dundee',
408 'country': 'Scotland',
409 'description': 'Foo',
410 'user_id': users[0].id,
411 }
412 )
413 batcher.profile.create(
414 {
415 'city': 'Edinburgh',
416 'country': 'Scotland',
417 'description': 'Foo',
418 'user_id': users[1].id,
419 }
420 )
421 batcher.profile.create(
422 {
423 'city': 'London',
424 'country': 'England',
425 'description': 'Foo',
426 'user_id': users[2].id,
427 }
428 )
430 found = await client.profile.find_first_or_raise(
431 where={'country': 'Scotland'},
432 distinct=['city'],
433 order={'city': 'asc'},
434 )
435 assert found.city == 'Dundee'
437 found = await client.profile.find_first_or_raise(
438 where={'country': 'Scotland'},
439 distinct=['city'],
440 order={'city': 'desc'},
441 )
442 assert found.city == 'Edinburgh'
445@pytest.mark.asyncio
446async def test_distinct_relations(client: Prisma) -> None:
447 """Using `distinct` across relations"""
448 user = await client.user.create(
449 {
450 'name': 'Robert',
451 'posts': {
452 'create': [
453 {
454 'title': 'Post 1',
455 'published': True,
456 },
457 {
458 'title': 'Post 2',
459 'published': False,
460 },
461 {
462 'title': 'Post 3',
463 'published': True,
464 },
465 ]
466 },
467 }
468 )
470 found = await client.user.find_first_or_raise(
471 where={
472 'id': user.id,
473 },
474 include={
475 'posts': {
476 'order_by': {'title': 'asc'},
477 'distinct': ['published'],
478 }
479 },
480 )
481 assert found.posts is not None
482 assert len(found.posts) == 2
483 assert found.posts[0].published is True
484 assert found.posts[1].published is False