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

1import sys 

2 

3import pytest 

4from inline_snapshot import snapshot 

5 

6from prisma import types, validate 

7from prisma._compat import PYDANTIC_V2 

8 

9 

10class Foo: 

11 pass 

12 

13 

14if PYDANTIC_V2: 

15 from pydantic.v1 import ValidationError 

16else: 

17 from pydantic import ValidationError # type: ignore[assignment] 

18 

19 

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} 

25 

26 validated = validate(types.IntFilter, {'equals': '1'}) 

27 assert validated == {'equals': 1} 

28 

29 

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) 

34 

35 assert str(exc.value) == snapshot( 

36 "Only TypedDict types are supported, got: <class 'tests.test_validator.Foo'> instead." 

37 ) 

38 

39 with pytest.raises(TypeError) as exc: 

40 validate(dict, None) 

41 

42 assert str(exc.value) == snapshot("Only TypedDict types are supported, got: <class 'dict'> instead.") 

43 

44 

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) 

49 

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 ) 

57 

58 

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'}}}) 

64 

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 ) 

78 

79 validated = validate(types.FloatFilter, {'not': {'not': {'not': '193.4'}}}) 

80 assert validated == {'not': {'not': {'not': 193.4}}} 

81 

82 

83def test_missing_values() -> None: 

84 """TypedDict with required keys is correctly validated""" 

85 with pytest.raises(ValidationError) as exc: 

86 validate(types.PostCreateInput, {}) 

87 

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 ) 

97 

98 

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} 

103 

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 } 

113 

114 

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'}) 

119 

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 )