Coverage for databases/tests/test_find_first.py: 100%

105 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-28 15:17 +0000

1import pytest 

2 

3from prisma import Prisma 

4from prisma.types import UserWhereInput 

5 

6 

7@pytest.mark.asyncio 

8async def test_find_first(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 ] 

50 

51 post = await client.post.find_first( 

52 where={ 

53 'published': True, 

54 }, 

55 order={ 

56 'title': 'asc', 

57 }, 

58 ) 

59 assert post is not None 

60 assert post.id == posts[3].id 

61 assert post.title == 'Test post 4' 

62 assert post.published is True 

63 

64 post = await client.post.find_first( 

65 where={ 

66 'title': { 

67 'contains': 'not found', 

68 } 

69 } 

70 ) 

71 assert post is None 

72 

73 post = await client.post.find_first( 

74 where={ 

75 'published': True, 

76 }, 

77 order={ 

78 'title': 'asc', 

79 }, 

80 skip=1, 

81 ) 

82 assert post is not None 

83 assert post.id == posts[5].id 

84 assert post.title == 'Test post 6' 

85 assert post.published is True 

86 

87 post = await client.post.find_first( 

88 where={ 

89 'NOT': [ 

90 { 

91 'published': True, 

92 }, 

93 ], 

94 }, 

95 order={ 

96 'created_at': 'asc', 

97 }, 

98 ) 

99 assert post is not None 

100 assert post.title == 'Test post 1' 

101 

102 post = await client.post.find_first( 

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 is not None 

122 assert post.title == 'Test post 3' 

123 

124 post = await client.post.find_first( 

125 where={ 

126 'title': { 

127 'contains': 'Test', 

128 }, 

129 'AND': [ 

130 { 

131 'published': True, 

132 }, 

133 ], 

134 }, 

135 order={ 

136 'created_at': 'asc', 

137 }, 

138 ) 

139 assert post is not None 

140 assert post.title == 'Test post 4' 

141 

142 post = await client.post.find_first( 

143 where={ 

144 'AND': [ 

145 { 

146 'published': True, 

147 }, 

148 { 

149 'title': { 

150 'contains': 'Test', 

151 } 

152 }, 

153 ], 

154 }, 

155 order={ 

156 'created_at': 'asc', 

157 }, 

158 ) 

159 assert post is not None 

160 assert post.title == 'Test post 4' 

161 

162 post = await client.post.find_first( 

163 where={ 

164 'views': { 

165 'gt': 100, 

166 }, 

167 'OR': [ 

168 { 

169 'published': False, 

170 }, 

171 ], 

172 } 

173 ) 

174 assert post is None 

175 

176 post = await client.post.find_first( 

177 where={ 

178 'OR': [ 

179 { 

180 'views': { 

181 'gt': 100, 

182 }, 

183 }, 

184 { 

185 'published': False, 

186 }, 

187 ] 

188 }, 

189 order={ 

190 'created_at': 'asc', 

191 }, 

192 ) 

193 assert post is not None 

194 assert post.title == 'Test post 1' 

195 

196 post = await client.post.find_first( 

197 where={ 

198 'OR': [ 

199 { 

200 'views': { 

201 'gt': 100, 

202 }, 

203 }, 

204 ] 

205 } 

206 ) 

207 assert post is not None 

208 assert post.title == 'Test post 4' 

209 

210 

211@pytest.mark.asyncio 

212async def test_filtering_one_to_one_relation(client: Prisma) -> None: 

213 """Filtering by a 1-1 relational field and negating the filter""" 

214 async with client.batch_() as batcher: 

215 batcher.user.create( 

216 { 

217 'name': 'Robert', 

218 'profile': { 

219 'create': { 

220 'description': 'My very cool bio.', 

221 'country': 'Scotland', 

222 }, 

223 }, 

224 }, 

225 ) 

226 batcher.user.create( 

227 { 

228 'name': 'Tegan', 

229 'profile': { 

230 'create': { 

231 'description': 'Hello world, this is my bio.', 

232 'country': 'Scotland', 

233 }, 

234 }, 

235 }, 

236 ) 

237 batcher.user.create({'name': 'Callum'}) 

238 

239 user = await client.user.find_first( 

240 where={ 

241 'profile': { 

242 'is': { 

243 'description': { 

244 'contains': 'cool', 

245 } 

246 } 

247 } 

248 } 

249 ) 

250 assert user is not None 

251 assert user.name == 'Robert' 

252 assert user.profile is None 

253 

254 user = await client.user.find_first( 

255 where={ 

256 'profile': { 

257 'is_not': { 

258 'description': { 

259 'contains': 'bio', 

260 } 

261 } 

262 } 

263 } 

264 ) 

265 assert user is not None 

266 assert user.name == 'Callum' 

267 assert user.profile is None 

268 

269 

270@pytest.mark.asyncio 

271async def test_filtering_and_ordering_one_to_many_relation( 

272 client: Prisma, 

273) -> None: 

274 """Filtering with every, some, none and ordering by a 1-M relational field""" 

275 async with client.batch_() as batcher: 

276 batcher.user.create( 

277 { 

278 'name': 'Robert', 

279 'posts': { 

280 'create': [ 

281 {'title': 'My first post', 'published': True}, 

282 {'title': 'My second post', 'published': False}, 

283 ] 

284 }, 

285 } 

286 ) 

287 batcher.user.create( 

288 { 

289 'name': 'Tegan', 

290 'posts': { 

291 'create': [ 

292 {'title': 'Hello, world!', 'published': True}, 

293 {'title': 'My test post', 'published': False}, 

294 ] 

295 }, 

296 } 

297 ) 

298 batcher.user.create({'name': 'Callum'}) 

299 

300 user = await client.user.find_first( 

301 where={ 

302 'posts': { 

303 'every': { 

304 'title': { 

305 'contains': 'post', 

306 } 

307 } 

308 } 

309 }, 

310 ) 

311 assert user is not None 

312 assert user.name == 'Robert' 

313 

314 user = await client.user.find_first( 

315 where={ 

316 'posts': { 

317 'none': { 

318 'title': { 

319 'contains': 'Post', 

320 } 

321 } 

322 } 

323 }, 

324 order={ 

325 'name': 'asc', 

326 }, 

327 ) 

328 assert user is not None 

329 assert user.name == 'Callum' 

330 

331 user = await client.user.find_first( 

332 where={ 

333 'posts': { 

334 'some': { 

335 'title': 'foo', 

336 } 

337 } 

338 } 

339 ) 

340 assert user is None 

341 

342 # ordering 

343 

344 user = await client.user.find_first( 

345 where={ 

346 'posts': { 

347 'some': { 

348 'title': { 

349 'contains': 'post', 

350 } 

351 } 

352 } 

353 }, 

354 order={'name': 'asc'}, 

355 ) 

356 assert user is not None 

357 assert user.name == 'Robert' 

358 

359 user = await client.user.find_first( 

360 where={ 

361 'posts': { 

362 'some': { 

363 'title': { 

364 'contains': 'post', 

365 } 

366 } 

367 } 

368 }, 

369 order={'name': 'desc'}, 

370 ) 

371 assert user is not None 

372 assert user.name == 'Tegan' 

373 

374 

375@pytest.mark.asyncio 

376async def test_list_wrapper_query_transformation(client: Prisma) -> None: 

377 """Queries wrapped within a list transform global aliases""" 

378 query: UserWhereInput = { 

379 'OR': [ 

380 {'name': {'startswith': '40'}}, 

381 {'name': {'contains': ', 40'}}, 

382 {'name': {'contains': 'house'}}, 

383 ] 

384 } 

385 

386 await client.user.create({'name': 'Robert house'}) 

387 found = await client.user.find_first(where=query, order={'created_at': 'asc'}) 

388 assert found is not None 

389 assert found.name == 'Robert house' 

390 

391 await client.user.create({'name': '40 robert'}) 

392 found = await client.user.find_first(skip=1, where=query, order={'created_at': 'asc'}) 

393 assert found is not None 

394 assert found.name == '40 robert' 

395 

396 

397@pytest.mark.asyncio 

398async def test_distinct(client: Prisma) -> None: 

399 """Filtering by distinct combinations of fields""" 

400 users = [ 

401 await client.user.create( 

402 data={ 

403 'name': 'Robert', 

404 }, 

405 ), 

406 await client.user.create( 

407 data={ 

408 'name': 'Tegan', 

409 }, 

410 ), 

411 await client.user.create( 

412 data={ 

413 'name': 'Patrick', 

414 }, 

415 ), 

416 ] 

417 async with client.batch_() as batcher: 

418 batcher.profile.create( 

419 { 

420 'city': 'Dundee', 

421 'country': 'Scotland', 

422 'description': 'Foo', 

423 'user_id': users[0].id, 

424 } 

425 ) 

426 batcher.profile.create( 

427 { 

428 'city': 'Edinburgh', 

429 'country': 'Scotland', 

430 'description': 'Foo', 

431 'user_id': users[1].id, 

432 } 

433 ) 

434 batcher.profile.create( 

435 { 

436 'city': 'London', 

437 'country': 'England', 

438 'description': 'Foo', 

439 'user_id': users[2].id, 

440 } 

441 ) 

442 

443 found = await client.profile.find_first( 

444 where={'country': 'Scotland'}, 

445 distinct=['city'], 

446 order={'city': 'asc'}, 

447 ) 

448 assert found is not None 

449 assert found.city == 'Dundee' 

450 

451 found = await client.profile.find_first( 

452 where={'country': 'Scotland'}, 

453 distinct=['city'], 

454 order={'city': 'desc'}, 

455 ) 

456 assert found is not None 

457 assert found.city == 'Edinburgh' 

458 

459 

460@pytest.mark.asyncio 

461async def test_distinct_relations(client: Prisma) -> None: 

462 """Using `distinct` across relations""" 

463 user = await client.user.create( 

464 { 

465 'name': 'Robert', 

466 'posts': { 

467 'create': [ 

468 { 

469 'title': 'Post 1', 

470 'published': True, 

471 }, 

472 { 

473 'title': 'Post 2', 

474 'published': False, 

475 }, 

476 { 

477 'title': 'Post 3', 

478 'published': True, 

479 }, 

480 ] 

481 }, 

482 } 

483 ) 

484 

485 found = await client.user.find_first( 

486 where={ 

487 'id': user.id, 

488 }, 

489 include={ 

490 'posts': { 

491 'order_by': {'title': 'asc'}, 

492 'distinct': ['published'], 

493 } 

494 }, 

495 ) 

496 assert found is not None 

497 assert found.posts is not None 

498 assert len(found.posts) == 2 

499 assert found.posts[0].published is True 

500 assert found.posts[1].published is False