Coverage for tests / test_tutorial / test_body / test_tutorial002.py: 100%

28 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-04-06 01:24 +0000

1import importlib 1abcd

2 

3import pytest 1abcd

4from fastapi.testclient import TestClient 1abcd

5from inline_snapshot import snapshot 1abcd

6 

7from ...utils import needs_py310 1abcd

8 

9 

10@pytest.fixture( 1abcd

11 name="client", 

12 params=[ 

13 pytest.param("tutorial002_py310", marks=needs_py310), 

14 ], 

15) 

16def get_client(request: pytest.FixtureRequest): 1abcd

17 mod = importlib.import_module(f"docs_src.body.{request.param}") 1efghijklmnopqrstuvwx

18 

19 client = TestClient(mod.app) 1efghijklmnopqrstuvwx

20 return client 1efghijklmnopqrstuvwx

21 

22 

23@pytest.mark.parametrize("price", ["50.5", 50.5]) 1abcd

24def test_post_with_tax(client: TestClient, price: str | float): 1abcd

25 response = client.post( 1yzABCDEF

26 "/items/", 

27 json={"name": "Foo", "price": price, "description": "Some Foo", "tax": 0.3}, 

28 ) 

29 assert response.status_code == 200 1yzABCDEF

30 assert response.json() == { 1yzABCDEF

31 "name": "Foo", 

32 "price": 50.5, 

33 "description": "Some Foo", 

34 "tax": 0.3, 

35 "price_with_tax": 50.8, 

36 } 

37 

38 

39@pytest.mark.parametrize("price", ["50.5", 50.5]) 1abcd

40def test_post_without_tax(client: TestClient, price: str | float): 1abcd

41 response = client.post( 1GHIJKLMN

42 "/items/", json={"name": "Foo", "price": price, "description": "Some Foo"} 

43 ) 

44 assert response.status_code == 200 1GHIJKLMN

45 assert response.json() == { 1GHIJKLMN

46 "name": "Foo", 

47 "price": 50.5, 

48 "description": "Some Foo", 

49 "tax": None, 

50 } 

51 

52 

53def test_post_with_no_data(client: TestClient): 1abcd

54 response = client.post("/items/", json={}) 1OPQR

55 assert response.status_code == 422 1OPQR

56 assert response.json() == { 1OPQR

57 "detail": [ 

58 { 

59 "type": "missing", 

60 "loc": ["body", "name"], 

61 "msg": "Field required", 

62 "input": {}, 

63 }, 

64 { 

65 "type": "missing", 

66 "loc": ["body", "price"], 

67 "msg": "Field required", 

68 "input": {}, 

69 }, 

70 ] 

71 } 

72 

73 

74def test_openapi_schema(client: TestClient): 1abcd

75 response = client.get("/openapi.json") 1STUV

76 assert response.status_code == 200, response.text 1STUV

77 assert response.json() == snapshot( 1STUV

78 { 

79 "openapi": "3.1.0", 

80 "info": {"title": "FastAPI", "version": "0.1.0"}, 

81 "paths": { 

82 "/items/": { 

83 "post": { 

84 "responses": { 

85 "200": { 

86 "description": "Successful Response", 

87 "content": {"application/json": {"schema": {}}}, 

88 }, 

89 "422": { 

90 "description": "Validation Error", 

91 "content": { 

92 "application/json": { 

93 "schema": { 

94 "$ref": "#/components/schemas/HTTPValidationError" 

95 } 

96 } 

97 }, 

98 }, 

99 }, 

100 "summary": "Create Item", 

101 "operationId": "create_item_items__post", 

102 "requestBody": { 

103 "content": { 

104 "application/json": { 

105 "schema": {"$ref": "#/components/schemas/Item"} 

106 } 

107 }, 

108 "required": True, 

109 }, 

110 } 

111 } 

112 }, 

113 "components": { 

114 "schemas": { 

115 "Item": { 

116 "title": "Item", 

117 "required": ["name", "price"], 

118 "type": "object", 

119 "properties": { 

120 "name": {"title": "Name", "type": "string"}, 

121 "price": {"title": "Price", "type": "number"}, 

122 "description": { 

123 "title": "Description", 

124 "anyOf": [{"type": "string"}, {"type": "null"}], 

125 }, 

126 "tax": { 

127 "title": "Tax", 

128 "anyOf": [{"type": "number"}, {"type": "null"}], 

129 }, 

130 }, 

131 }, 

132 "ValidationError": { 

133 "title": "ValidationError", 

134 "required": ["loc", "msg", "type"], 

135 "type": "object", 

136 "properties": { 

137 "loc": { 

138 "title": "Location", 

139 "type": "array", 

140 "items": { 

141 "anyOf": [{"type": "string"}, {"type": "integer"}] 

142 }, 

143 }, 

144 "msg": {"title": "Message", "type": "string"}, 

145 "type": {"title": "Error Type", "type": "string"}, 

146 "input": {"title": "Input"}, 

147 "ctx": {"title": "Context", "type": "object"}, 

148 }, 

149 }, 

150 "HTTPValidationError": { 

151 "title": "HTTPValidationError", 

152 "type": "object", 

153 "properties": { 

154 "detail": { 

155 "title": "Detail", 

156 "type": "array", 

157 "items": { 

158 "$ref": "#/components/schemas/ValidationError" 

159 }, 

160 } 

161 }, 

162 }, 

163 } 

164 }, 

165 } 

166 )