Coverage for tests/test_validator.py: 100%
34 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 sys
3import pytest
4from inline_snapshot import snapshot
6from prisma import types, validate
7from prisma._compat import PYDANTIC_V2
10class Foo:
11 pass
14if PYDANTIC_V2:
15 from pydantic.v1 import ValidationError
16else:
17 from pydantic import ValidationError # type: ignore[assignment]
20@pytest.mark.skipif(sys.version_info >= (3, 12), reason='transitive dep is broken :(')
21def test_valid() -> None:
22 """Basic usage with correct data"""
23 validated = validate(types.IntFilter, {'equals': 1})
24 assert validated == {'equals': 1}
26 validated = validate(types.IntFilter, {'equals': '1'})
27 assert validated == {'equals': 1}
30def test_disallows_non_typeddict_type() -> None:
31 """Validating against non TypedDict types throws an error"""
32 with pytest.raises(TypeError) as exc:
33 validate(Foo, None)
35 assert str(exc.value) == snapshot(
36 "Only TypedDict types are supported, got: <class 'tests.test_validator.Foo'> instead."
37 )
39 with pytest.raises(TypeError) as exc:
40 validate(dict, None)
42 assert str(exc.value) == snapshot("Only TypedDict types are supported, got: <class 'dict'> instead.")
45def test_non_dictionary_values() -> None:
46 """Validating a non-dictionary value throws an error"""
47 with pytest.raises(ValidationError) as exc:
48 validate(types.UserCreateInput, None)
50 assert str(exc.value) == snapshot(
51 """\
521 validation error for UserCreateInput
53__root__
54 UserCreateInput expected dict not NoneType (type=type_error)\
55"""
56 )
59@pytest.mark.skipif(sys.version_info >= (3, 12), reason='transitive dep is broken :(')
60def test_recursive() -> None:
61 """Validating recursive types works as expected"""
62 with pytest.raises(ValidationError) as exc:
63 validate(types.FloatFilter, {'not': {'not': {'not': 'a'}}})
65 assert str(exc.value) == snapshot(
66 """\
674 validation errors for FloatFilter
68not
69 value is not a valid float (type=type_error.float)
70not -> not
71 value is not a valid float (type=type_error.float)
72not -> not -> not
73 value is not a valid float (type=type_error.float)
74not -> not -> not -> __root__
75 FloatFilterRecursive3 expected dict not str (type=type_error)\
76"""
77 )
79 validated = validate(types.FloatFilter, {'not': {'not': {'not': '193.4'}}})
80 assert validated == {'not': {'not': {'not': 193.4}}}
83def test_missing_values() -> None:
84 """TypedDict with required keys is correctly validated"""
85 with pytest.raises(ValidationError) as exc:
86 validate(types.PostCreateInput, {})
88 assert str(exc.value) == snapshot(
89 """\
902 validation errors for PostCreateInput
91title
92 field required (type=value_error.missing)
93published
94 field required (type=value_error.missing)\
95"""
96 )
99def test_optional_values() -> None:
100 """Fields that can be None are still included in the validated data"""
101 validated = validate(types.PostCreateInput, dict(title='My Title', published=True))
102 assert validated == {'title': 'My Title', 'published': True}
104 validated = validate(
105 type=types.PostCreateInput,
106 data=dict(title='My Title', published=True, desc=None),
107 )
108 assert validated == {
109 'title': 'My Title',
110 'published': True,
111 'desc': None,
112 }
115def test_disallows_extra_values() -> None:
116 """Fields that are not present in the TypedDict are not allowed"""
117 with pytest.raises(ValidationError) as exc:
118 validate(types.PostCreateInput, {'foo': 'bar'})
120 assert str(exc.value) == snapshot(
121 """\
1223 validation errors for PostCreateInput
123title
124 field required (type=value_error.missing)
125published
126 field required (type=value_error.missing)
127foo
128 extra fields not permitted (type=value_error.extra)\
129"""
130 )