Coverage for databases/tests/types/test_bytes.py: 100%
77 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
1from typing import List
3import pytest
4from pydantic import BaseModel
5from dirty_equals import IsPartialDict
7from prisma import Prisma
8from prisma.fields import Base64
9from prisma.models import Types
10from prisma._compat import (
11 PYDANTIC_V2,
12 model_dict,
13 model_json,
14 model_parse,
15 model_parse_json,
16 model_json_schema,
17)
20@pytest.mark.asyncio
21async def test_filtering(client: Prisma) -> None:
22 """Finding records by a Bytes value"""
23 async with client.batch_() as batcher:
24 batcher.types.create({'bytes': Base64.encode(b'a')})
25 batcher.types.create({'bytes': Base64.encode(b'b')})
26 batcher.types.create({'bytes': Base64.encode(b'foo bar')})
28 total = await client.types.count(
29 where={
30 'bytes': {
31 'equals': Base64.encode(b'a'),
32 },
33 },
34 )
35 assert total == 1
37 found = await client.types.find_first(
38 where={
39 'bytes': {
40 'equals': Base64.encode(b'foo bar'),
41 },
42 },
43 )
44 assert found is not None
45 assert found.bytes.decode() == b'foo bar'
46 assert found.bytes.decode_str() == 'foo bar'
48 found = await client.types.find_first(
49 where={
50 'bytes': {
51 'not': Base64.encode(b'a'),
52 },
53 },
54 )
55 assert found is not None
56 assert found.bytes.decode() == b'b'
58 found = await client.types.find_first(
59 where={
60 'bytes': Base64.encode(b'a'),
61 },
62 )
63 assert found is not None
64 assert found.bytes.decode() == b'a'
66 found = await client.types.find_first(
67 where={
68 'bytes': {
69 'in': [Base64.encode(b'a'), Base64.encode(b'c')],
70 }
71 },
72 )
73 assert found is not None
74 assert found.bytes.decode() == b'a'
76 found = await client.types.find_first(
77 where={
78 'bytes': {
79 'in': [Base64.encode(b'c')],
80 },
81 },
82 )
83 assert found is None
85 found_list = await client.types.find_many(
86 where={
87 'bytes': {
88 'not_in': [Base64.encode(b'a'), Base64.encode(b'c')],
89 }
90 },
91 )
92 found_values = {record.bytes.decode() for record in found_list}
93 assert found_values == {b'b', b'foo bar'}
96@pytest.mark.asyncio
97async def test_json(client: Prisma) -> None:
98 """Base64 fields can be serialised to and from JSON"""
99 record = await client.types.create(
100 data={
101 'bytes': Base64.encode(b'foo'),
102 },
103 )
104 model = model_parse_json(Types, model_json(record, exclude={'json_obj'}))
105 assert isinstance(model.bytes, Base64)
106 assert model.bytes.decode() == b'foo'
109@pytest.mark.asyncio
110async def test_constructing(client: Prisma) -> None:
111 """Base64 fields can be passed to the model constructor"""
112 record = await client.types.create({})
113 model = model_parse(
114 Types,
115 {
116 **model_dict(record, exclude={'json_obj'}),
117 'bytes': Base64.encode(b'foo'),
118 },
119 )
120 assert model.bytes == Base64.encode(b'foo')
123@pytest.mark.asyncio
124async def test_filtering_nulls(client: Prisma) -> None:
125 """None is a valid filter for nullable Bytes fields"""
126 await client.types.create(
127 {
128 'string': 'a',
129 'optional_bytes': None,
130 },
131 )
132 await client.types.create(
133 {
134 'string': 'b',
135 'optional_bytes': Base64.encode(b'foo'),
136 },
137 )
138 await client.types.create(
139 {
140 'string': 'c',
141 'optional_bytes': Base64.encode(b'bar'),
142 },
143 )
145 found = await client.types.find_first(
146 where={
147 'NOT': [
148 {
149 'optional_bytes': None,
150 },
151 ],
152 },
153 order={
154 'string': 'asc',
155 },
156 )
157 assert found is not None
158 assert found.string == 'b'
159 assert found.optional_bytes == Base64.encode(b'foo')
161 count = await client.types.count(
162 where={
163 'optional_bytes': None,
164 },
165 )
166 assert count == 1
168 count = await client.types.count(
169 where={
170 'NOT': [
171 {
172 'optional_bytes': None,
173 },
174 ],
175 },
176 )
177 assert count == 2
180class Base64Model(BaseModel):
181 value: Base64
182 array: List[Base64]
185def test_pydantic_conversion() -> None:
186 """Raw inputs are converted to Base64 objects at the Pydantic level"""
187 record = model_parse(Base64Model, {'value': 'foo', 'array': []})
188 assert isinstance(record.value, Base64)
189 assert record.value._raw == b'foo'
190 assert record.array == []
192 record = model_parse(
193 Base64Model,
194 {
195 'value': Base64.encode(b'foo'),
196 'array': ['foo', b'bar', Base64.encode(b'baz')],
197 },
198 )
199 assert isinstance(record.value, Base64)
200 assert record.value.decode() == b'foo'
201 assert len(record.array) == 3
202 assert record.array[0]._raw == b'foo'
203 assert record.array[1]._raw == b'bar'
204 assert record.array[2].decode_str() == 'baz'
207def test_json_schema() -> None:
208 """Ensure a JSON Schema definition can be created"""
209 if PYDANTIC_V2:
210 assert model_json_schema(Types) == IsPartialDict(
211 properties=IsPartialDict(
212 {
213 'bytes': {
214 'format': 'byte',
215 'title': 'Bytes',
216 'type': 'string',
217 },
218 'optional_bytes': {
219 'anyOf': [
220 {'format': 'byte', 'type': 'string'},
221 {'type': 'null'},
222 ],
223 'default': None,
224 'title': 'Optional Bytes',
225 },
226 }
227 )
228 )
229 else:
230 assert model_json_schema(Types) == IsPartialDict(
231 properties=IsPartialDict(
232 {
233 'bytes': {
234 'title': 'Bytes',
235 'type': 'string',
236 'format': 'byte',
237 },
238 'optional_bytes': {
239 'title': 'Optional Bytes',
240 'type': 'string',
241 'format': 'byte',
242 },
243 }
244 )
245 )