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

91 statements  

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

1from typing import List 

2 

3import pytest 

4 

5from prisma import Prisma 

6from lib.testing import async_fixture 

7from prisma.models import Post 

8 

9 

10@async_fixture(scope='module', name='user_id') 

11async def user_id_fixture(client: Prisma) -> str: 

12 user = await client.user.create({'name': 'Robert'}) 

13 posts = await create_or_get_posts(client, user.id) 

14 await client.custom_category.create( 

15 { 

16 'name': 'My Category', 

17 'posts': {'connect': [{'id': posts[0].id}, {'id': posts[1].id}]}, 

18 } 

19 ) 

20 return user.id 

21 

22 

23@async_fixture(scope='module', name='posts') 

24async def posts_fixture(client: Prisma, user_id: str) -> List[Post]: 

25 return await create_or_get_posts(client, user_id) 

26 

27 

28async def create_or_get_posts(client: Prisma, user_id: str) -> List[Post]: 

29 user = await client.user.find_unique( 

30 where={'id': user_id}, 

31 include={ 

32 'posts': { 

33 'order_by': { 

34 'title': 'asc', 

35 }, 

36 }, 

37 }, 

38 ) 

39 assert user is not None 

40 

41 if user.posts: 

42 return user.posts 

43 

44 return [ 

45 await client.post.create( 

46 { 

47 'title': 'Post 1', 

48 'published': False, 

49 'author': {'connect': {'id': user_id}}, 

50 } 

51 ), 

52 await client.post.create( 

53 { 

54 'title': 'Post 2', 

55 'published': True, 

56 'author': {'connect': {'id': user_id}}, 

57 } 

58 ), 

59 await client.post.create( 

60 { 

61 'title': 'Post 3', 

62 'published': True, 

63 'author': {'connect': {'id': user_id}}, 

64 } 

65 ), 

66 await client.post.create( 

67 { 

68 'title': 'Post 4', 

69 'published': False, 

70 'author': {'connect': {'id': user_id}}, 

71 } 

72 ), 

73 ] 

74 

75 

76@pytest.mark.asyncio 

77@pytest.mark.persist_data 

78async def test_find_unique_include(client: Prisma, user_id: str) -> None: 

79 """Including a one-to-many relationship returns all records as a list of models""" 

80 user = await client.user.find_unique( 

81 where={'id': user_id}, 

82 include={ 

83 'posts': { 

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

85 } 

86 }, 

87 ) 

88 assert user is not None 

89 assert user.name == 'Robert' 

90 assert user.posts is not None 

91 assert len(user.posts) == 4 

92 

93 for i, post in enumerate( 

94 user.posts, 

95 start=1, 

96 ): 

97 assert post.author is None 

98 assert post.author_id == user.id 

99 assert post.title == f'Post {i}' 

100 

101 

102@pytest.mark.asyncio 

103@pytest.mark.persist_data 

104async def test_find_unique_include_take(client: Prisma, user_id: str) -> None: 

105 """Including a one-to-many relationship with take limits amount of returned models""" 

106 user = await client.user.find_unique( 

107 where={ 

108 'id': user_id, 

109 }, 

110 include={ 

111 'posts': { 

112 'take': 1, 

113 }, 

114 }, 

115 ) 

116 assert user is not None 

117 assert user.posts is not None 

118 assert len(user.posts) == 1 

119 

120 

121@pytest.mark.asyncio 

122@pytest.mark.persist_data 

123async def test_find_unique_include_where(client: Prisma, user_id: str, posts: List[Post]) -> None: 

124 """Including a one-to-many relationship with a where argument filters results""" 

125 user = await client.user.find_unique( 

126 where={'id': user_id}, 

127 include={'posts': {'where': {'created_at': posts[0].created_at}}}, 

128 ) 

129 assert user is not None 

130 assert user.posts is not None 

131 assert len(user.posts) == 1 

132 assert user.posts[0].id == posts[0].id 

133 

134 

135@pytest.mark.asyncio 

136@pytest.mark.persist_data 

137async def test_find_unique_include_pagination(client: Prisma, user_id: str, posts: List[Post]) -> None: 

138 """Pagination by cursor id works forwards and backwards""" 

139 user = await client.user.find_unique( 

140 where={'id': user_id}, 

141 include={ 

142 'posts': { 

143 'cursor': {'id': posts[0].id}, 

144 'take': 1, 

145 'skip': 1, 

146 'order_by': { 

147 'title': 'asc', 

148 }, 

149 } 

150 }, 

151 ) 

152 assert user is not None 

153 assert user.posts is not None 

154 assert len(user.posts) == 1 

155 assert user.posts[0].id == posts[1].id 

156 

157 user = await client.user.find_unique( 

158 where={'id': user_id}, 

159 include={ 

160 'posts': { 

161 'cursor': {'id': posts[1].id}, 

162 'take': -1, 

163 'skip': 1, 

164 'order_by': { 

165 'title': 'asc', 

166 }, 

167 }, 

168 }, 

169 ) 

170 assert user is not None 

171 assert user.posts is not None 

172 assert len(user.posts) == 1 

173 assert user.posts[0].id == posts[0].id 

174 

175 

176@pytest.mark.asyncio 

177@pytest.mark.persist_data 

178async def test_find_unique_include_nested_where_or(client: Prisma, user_id: str, posts: List[Post]) -> None: 

179 """Include with nested or argument""" 

180 user = await client.user.find_unique( 

181 where={'id': user_id}, 

182 include={ 

183 'posts': { 

184 'where': { 

185 'OR': [ 

186 {'id': posts[0].id}, 

187 {'published': True}, 

188 ], 

189 }, 

190 'order_by': { 

191 'title': 'asc', 

192 }, 

193 } 

194 }, 

195 ) 

196 assert user is not None 

197 

198 assert posts[0].published is False 

199 assert user.posts is not None 

200 assert len(user.posts) == 3 

201 

202 assert user.posts[0].id == posts[0].id 

203 assert user.posts[1].id == posts[1].id 

204 assert user.posts[2].id == posts[2].id 

205 

206 assert user.posts[0].published is False 

207 assert user.posts[1].published is True 

208 assert user.posts[2].published is True 

209 

210 

211@pytest.mark.asyncio 

212@pytest.mark.persist_data 

213async def test_find_unique_include_nested_include(client: Prisma, user_id: str) -> None: 

214 """Multiple nested include arguments returns all models""" 

215 user = await client.user.find_unique( 

216 where={'id': user_id}, 

217 include={ 

218 'profile': True, 

219 'posts': {'include': {'categories': {'include': {'posts': True}}}}, 

220 }, 

221 ) 

222 assert user is not None 

223 assert user.profile is None 

224 assert user.posts is not None 

225 for post in user.posts: 

226 assert post.categories is not None 

227 for category in post.categories: 

228 assert category.posts is not None 

229 

230 

231@pytest.mark.asyncio 

232@pytest.mark.persist_data 

233async def test_create_include(client: Prisma) -> None: 

234 """Creating a record and including it at the same time""" 

235 post = await client.post.create( 

236 { 

237 'title': 'Post 4', 

238 'published': False, 

239 'author': {'create': {'name': 'Bob'}}, 

240 }, 

241 include={'author': True}, 

242 ) 

243 assert post.author is not None 

244 assert post.author.name == 'Bob'