Coverage for tests/test_forms_single_model.py: 100%

33 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-01-13 13:38 +0000

1from typing import List, Optional 1abcde

2 

3from dirty_equals import IsDict 1abcde

4from fastapi import FastAPI, Form 1abcde

5from fastapi.testclient import TestClient 1abcde

6from pydantic import BaseModel, Field 1abcde

7from typing_extensions import Annotated 1abcde

8 

9app = FastAPI() 1abcde

10 

11 

12class FormModel(BaseModel): 1abcde

13 username: str 1abcde

14 lastname: str 1abcde

15 age: Optional[int] = None 1abcde

16 tags: List[str] = ["foo", "bar"] 1abcde

17 alias_with: str = Field(alias="with", default="nothing") 1abcde

18 

19 

20@app.post("/form/") 1abcde

21def post_form(user: Annotated[FormModel, Form()]): 1abcde

22 return user 1fghijklmno

23 

24 

25client = TestClient(app) 1abcde

26 

27 

28def test_send_all_data(): 1abcde

29 response = client.post( 1gikmo

30 "/form/", 

31 data={ 

32 "username": "Rick", 

33 "lastname": "Sanchez", 

34 "age": "70", 

35 "tags": ["plumbus", "citadel"], 

36 "with": "something", 

37 }, 

38 ) 

39 assert response.status_code == 200, response.text 1gikmo

40 assert response.json() == { 1gikmo

41 "username": "Rick", 

42 "lastname": "Sanchez", 

43 "age": 70, 

44 "tags": ["plumbus", "citadel"], 

45 "with": "something", 

46 } 

47 

48 

49def test_defaults(): 1abcde

50 response = client.post("/form/", data={"username": "Rick", "lastname": "Sanchez"}) 1fhjln

51 assert response.status_code == 200, response.text 1fhjln

52 assert response.json() == { 1fhjln

53 "username": "Rick", 

54 "lastname": "Sanchez", 

55 "age": None, 

56 "tags": ["foo", "bar"], 

57 "with": "nothing", 

58 } 

59 

60 

61def test_invalid_data(): 1abcde

62 response = client.post( 1pqrst

63 "/form/", 

64 data={ 

65 "username": "Rick", 

66 "lastname": "Sanchez", 

67 "age": "seventy", 

68 "tags": ["plumbus", "citadel"], 

69 }, 

70 ) 

71 assert response.status_code == 422, response.text 1pqrst

72 assert response.json() == IsDict( 1pqrst

73 { 

74 "detail": [ 

75 { 

76 "type": "int_parsing", 

77 "loc": ["body", "age"], 

78 "msg": "Input should be a valid integer, unable to parse string as an integer", 

79 "input": "seventy", 

80 } 

81 ] 

82 } 

83 ) | IsDict( 

84 # TODO: remove when deprecating Pydantic v1 

85 { 

86 "detail": [ 

87 { 

88 "loc": ["body", "age"], 

89 "msg": "value is not a valid integer", 

90 "type": "type_error.integer", 

91 } 

92 ] 

93 } 

94 ) 

95 

96 

97def test_no_data(): 1abcde

98 response = client.post("/form/") 1uvwxy

99 assert response.status_code == 422, response.text 1uvwxy

100 assert response.json() == IsDict( 1uvwxy

101 { 

102 "detail": [ 

103 { 

104 "type": "missing", 

105 "loc": ["body", "username"], 

106 "msg": "Field required", 

107 "input": {"tags": ["foo", "bar"], "with": "nothing"}, 

108 }, 

109 { 

110 "type": "missing", 

111 "loc": ["body", "lastname"], 

112 "msg": "Field required", 

113 "input": {"tags": ["foo", "bar"], "with": "nothing"}, 

114 }, 

115 ] 

116 } 

117 ) | IsDict( 

118 # TODO: remove when deprecating Pydantic v1 

119 { 

120 "detail": [ 

121 { 

122 "loc": ["body", "username"], 

123 "msg": "field required", 

124 "type": "value_error.missing", 

125 }, 

126 { 

127 "loc": ["body", "lastname"], 

128 "msg": "field required", 

129 "type": "value_error.missing", 

130 }, 

131 ] 

132 } 

133 )