Coverage for tests/test_tutorial/test_fastapi/test_multiple_models/test_tutorial001.py: 100%

46 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-09 00:02 +0000

1from dirty_equals import IsDict 1ghijkl

2from fastapi.testclient import TestClient 1ghijkl

3from sqlalchemy import inspect 1ghijkl

4from sqlalchemy.engine.reflection import Inspector 1ghijkl

5from sqlmodel import create_engine 1ghijkl

6from sqlmodel.pool import StaticPool 1ghijkl

7 

8 

9def test_tutorial(clear_sqlmodel): 1ghijkl

10 from docs_src.tutorial.fastapi.multiple_models import tutorial001 as mod 1fabcde

11 

12 mod.sqlite_url = "sqlite://" 1fabcde

13 mod.engine = create_engine( 1fabcde

14 mod.sqlite_url, connect_args=mod.connect_args, poolclass=StaticPool 

15 ) 

16 

17 with TestClient(mod.app) as client: 1fabcde

18 hero1_data = {"name": "Deadpond", "secret_name": "Dive Wilson"} 1fabcde

19 hero2_data = { 1abcde

20 "name": "Spider-Boy", 

21 "secret_name": "Pedro Parqueador", 

22 "id": 9000, 

23 } 

24 response = client.post("/heroes/", json=hero1_data) 1fabcde

25 data = response.json() 1fabcde

26 

27 assert response.status_code == 200, response.text 1fabcde

28 assert data["name"] == hero1_data["name"] 1fabcde

29 assert data["secret_name"] == hero1_data["secret_name"] 1fabcde

30 assert data["id"] is not None 1fabcde

31 assert data["age"] is None 1fabcde

32 

33 response = client.post("/heroes/", json=hero2_data) 1fabcde

34 data = response.json() 1fabcde

35 

36 assert response.status_code == 200, response.text 1fabcde

37 assert data["name"] == hero2_data["name"] 1fabcde

38 assert data["secret_name"] == hero2_data["secret_name"] 1fabcde

39 assert data["id"] != hero2_data["id"], ( 1fabcde

40 "Now it's not possible to predefine the ID from the request, " 

41 "it's now set by the database" 

42 ) 

43 assert data["age"] is None 1fabcde

44 

45 response = client.get("/heroes/") 1fabcde

46 data = response.json() 1fabcde

47 

48 assert response.status_code == 200, response.text 1fabcde

49 assert len(data) == 2 1fabcde

50 assert data[0]["name"] == hero1_data["name"] 1fabcde

51 assert data[0]["secret_name"] == hero1_data["secret_name"] 1fabcde

52 assert data[1]["name"] == hero2_data["name"] 1fabcde

53 assert data[1]["secret_name"] == hero2_data["secret_name"] 1fabcde

54 assert data[1]["id"] != hero2_data["id"] 1fabcde

55 

56 response = client.get("/openapi.json") 1fabcde

57 

58 assert response.status_code == 200, response.text 1fabcde

59 

60 assert response.json() == { 1fabcde

61 "openapi": "3.1.0", 

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

63 "paths": { 

64 "/heroes/": { 

65 "get": { 

66 "summary": "Read Heroes", 

67 "operationId": "read_heroes_heroes__get", 

68 "responses": { 

69 "200": { 

70 "description": "Successful Response", 

71 "content": { 

72 "application/json": { 

73 "schema": { 

74 "title": "Response Read Heroes Heroes Get", 

75 "type": "array", 

76 "items": { 

77 "$ref": "#/components/schemas/HeroPublic" 

78 }, 

79 } 

80 } 

81 }, 

82 } 

83 }, 

84 }, 

85 "post": { 

86 "summary": "Create Hero", 

87 "operationId": "create_hero_heroes__post", 

88 "requestBody": { 

89 "content": { 

90 "application/json": { 

91 "schema": { 

92 "$ref": "#/components/schemas/HeroCreate" 

93 } 

94 } 

95 }, 

96 "required": True, 

97 }, 

98 "responses": { 

99 "200": { 

100 "description": "Successful Response", 

101 "content": { 

102 "application/json": { 

103 "schema": { 

104 "$ref": "#/components/schemas/HeroPublic" 

105 } 

106 } 

107 }, 

108 }, 

109 "422": { 

110 "description": "Validation Error", 

111 "content": { 

112 "application/json": { 

113 "schema": { 

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

115 } 

116 } 

117 }, 

118 }, 

119 }, 

120 }, 

121 } 

122 }, 

123 "components": { 

124 "schemas": { 

125 "HTTPValidationError": { 

126 "title": "HTTPValidationError", 

127 "type": "object", 

128 "properties": { 

129 "detail": { 

130 "title": "Detail", 

131 "type": "array", 

132 "items": { 

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

134 }, 

135 } 

136 }, 

137 }, 

138 "HeroCreate": { 

139 "title": "HeroCreate", 

140 "required": ["name", "secret_name"], 

141 "type": "object", 

142 "properties": { 

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

144 "secret_name": {"title": "Secret Name", "type": "string"}, 

145 "age": IsDict( 

146 { 

147 "title": "Age", 

148 "anyOf": [{"type": "integer"}, {"type": "null"}], 

149 } 

150 ) 

151 | IsDict( 

152 # TODO: remove when deprecating Pydantic v1 

153 {"title": "Age", "type": "integer"} 

154 ), 

155 }, 

156 }, 

157 "HeroPublic": { 

158 "title": "HeroPublic", 

159 "required": ["id", "name", "secret_name"], 

160 "type": "object", 

161 "properties": { 

162 "id": {"title": "Id", "type": "integer"}, 

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

164 "secret_name": {"title": "Secret Name", "type": "string"}, 

165 "age": IsDict( 

166 { 

167 "title": "Age", 

168 "anyOf": [{"type": "integer"}, {"type": "null"}], 

169 } 

170 ) 

171 | IsDict( 

172 # TODO: remove when deprecating Pydantic v1 

173 {"title": "Age", "type": "integer"} 

174 ), 

175 }, 

176 }, 

177 "ValidationError": { 

178 "title": "ValidationError", 

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

180 "type": "object", 

181 "properties": { 

182 "loc": { 

183 "title": "Location", 

184 "type": "array", 

185 "items": { 

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

187 }, 

188 }, 

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

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

191 }, 

192 }, 

193 } 

194 }, 

195 } 

196 

197 # Test inherited indexes 

198 insp: Inspector = inspect(mod.engine) 1fabcde

199 indexes = insp.get_indexes(str(mod.Hero.__tablename__)) 1fabcde

200 expected_indexes = [ 1abcde

201 { 

202 "name": "ix_hero_name", 

203 "dialect_options": {}, 

204 "column_names": ["name"], 

205 "unique": 0, 

206 }, 

207 { 

208 "name": "ix_hero_age", 

209 "dialect_options": {}, 

210 "column_names": ["age"], 

211 "unique": 0, 

212 }, 

213 ] 

214 for index in expected_indexes: 1fabcde

215 assert index in indexes, "This expected index should be in the indexes in DB" 1fabcde

216 # Now that this index was checked, remove it from the list of indexes 

217 indexes.pop(indexes.index(index)) 1fabcde

218 assert len(indexes) == 0, "The database should only have the expected indexes" 1fabcde