Coverage for tests/test_tutorial/test_security/test_tutorial003_an.py: 100%

43 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-08 03:53 +0000

1from dirty_equals import IsDict 1abcde

2from fastapi.testclient import TestClient 1abcde

3 

4from docs_src.security.tutorial003_an import app 1abcde

5 

6client = TestClient(app) 1abcde

7 

8 

9def test_login(): 1abcde

10 response = client.post("/token", data={"username": "johndoe", "password": "secret"}) 1abcde

11 assert response.status_code == 200, response.text 1abcde

12 assert response.json() == {"access_token": "johndoe", "token_type": "bearer"} 1abcde

13 

14 

15def test_login_incorrect_password(): 1abcde

16 response = client.post( 1abcde

17 "/token", data={"username": "johndoe", "password": "incorrect"} 

18 ) 

19 assert response.status_code == 400, response.text 1abcde

20 assert response.json() == {"detail": "Incorrect username or password"} 1abcde

21 

22 

23def test_login_incorrect_username(): 1abcde

24 response = client.post("/token", data={"username": "foo", "password": "secret"}) 1abcde

25 assert response.status_code == 400, response.text 1abcde

26 assert response.json() == {"detail": "Incorrect username or password"} 1abcde

27 

28 

29def test_no_token(): 1abcde

30 response = client.get("/users/me") 1abcde

31 assert response.status_code == 401, response.text 1abcde

32 assert response.json() == {"detail": "Not authenticated"} 1abcde

33 assert response.headers["WWW-Authenticate"] == "Bearer" 1abcde

34 

35 

36def test_token(): 1abcde

37 response = client.get("/users/me", headers={"Authorization": "Bearer johndoe"}) 1abcde

38 assert response.status_code == 200, response.text 1abcde

39 assert response.json() == { 1abcde

40 "username": "johndoe", 

41 "full_name": "John Doe", 

42 "email": "johndoe@example.com", 

43 "hashed_password": "fakehashedsecret", 

44 "disabled": False, 

45 } 

46 

47 

48def test_incorrect_token(): 1abcde

49 response = client.get("/users/me", headers={"Authorization": "Bearer nonexistent"}) 1abcde

50 assert response.status_code == 401, response.text 1abcde

51 assert response.json() == {"detail": "Invalid authentication credentials"} 1abcde

52 assert response.headers["WWW-Authenticate"] == "Bearer" 1abcde

53 

54 

55def test_incorrect_token_type(): 1abcde

56 response = client.get( 1abcde

57 "/users/me", headers={"Authorization": "Notexistent testtoken"} 

58 ) 

59 assert response.status_code == 401, response.text 1abcde

60 assert response.json() == {"detail": "Not authenticated"} 1abcde

61 assert response.headers["WWW-Authenticate"] == "Bearer" 1abcde

62 

63 

64def test_inactive_user(): 1abcde

65 response = client.get("/users/me", headers={"Authorization": "Bearer alice"}) 1abcde

66 assert response.status_code == 400, response.text 1abcde

67 assert response.json() == {"detail": "Inactive user"} 1abcde

68 

69 

70def test_openapi_schema(): 1abcde

71 response = client.get("/openapi.json") 1abcde

72 assert response.status_code == 200, response.text 1abcde

73 assert response.json() == { 1abcde

74 "openapi": "3.1.0", 

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

76 "paths": { 

77 "/token": { 

78 "post": { 

79 "responses": { 

80 "200": { 

81 "description": "Successful Response", 

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

83 }, 

84 "422": { 

85 "description": "Validation Error", 

86 "content": { 

87 "application/json": { 

88 "schema": { 

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

90 } 

91 } 

92 }, 

93 }, 

94 }, 

95 "summary": "Login", 

96 "operationId": "login_token_post", 

97 "requestBody": { 

98 "content": { 

99 "application/x-www-form-urlencoded": { 

100 "schema": { 

101 "$ref": "#/components/schemas/Body_login_token_post" 

102 } 

103 } 

104 }, 

105 "required": True, 

106 }, 

107 } 

108 }, 

109 "/users/me": { 

110 "get": { 

111 "responses": { 

112 "200": { 

113 "description": "Successful Response", 

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

115 } 

116 }, 

117 "summary": "Read Users Me", 

118 "operationId": "read_users_me_users_me_get", 

119 "security": [{"OAuth2PasswordBearer": []}], 

120 } 

121 }, 

122 }, 

123 "components": { 

124 "schemas": { 

125 "Body_login_token_post": { 

126 "title": "Body_login_token_post", 

127 "required": ["username", "password"], 

128 "type": "object", 

129 "properties": { 

130 "grant_type": IsDict( 

131 { 

132 "title": "Grant Type", 

133 "anyOf": [ 

134 {"pattern": "password", "type": "string"}, 

135 {"type": "null"}, 

136 ], 

137 } 

138 ) 

139 | IsDict( 

140 # TODO: remove when deprecating Pydantic v1 

141 { 

142 "title": "Grant Type", 

143 "pattern": "password", 

144 "type": "string", 

145 } 

146 ), 

147 "username": {"title": "Username", "type": "string"}, 

148 "password": {"title": "Password", "type": "string"}, 

149 "scope": {"title": "Scope", "type": "string", "default": ""}, 

150 "client_id": IsDict( 

151 { 

152 "title": "Client Id", 

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

154 } 

155 ) 

156 | IsDict( 

157 # TODO: remove when deprecating Pydantic v1 

158 {"title": "Client Id", "type": "string"} 

159 ), 

160 "client_secret": IsDict( 

161 { 

162 "title": "Client Secret", 

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

164 } 

165 ) 

166 | IsDict( 

167 # TODO: remove when deprecating Pydantic v1 

168 {"title": "Client Secret", "type": "string"} 

169 ), 

170 }, 

171 }, 

172 "ValidationError": { 

173 "title": "ValidationError", 

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

175 "type": "object", 

176 "properties": { 

177 "loc": { 

178 "title": "Location", 

179 "type": "array", 

180 "items": { 

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

182 }, 

183 }, 

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

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

186 }, 

187 }, 

188 "HTTPValidationError": { 

189 "title": "HTTPValidationError", 

190 "type": "object", 

191 "properties": { 

192 "detail": { 

193 "title": "Detail", 

194 "type": "array", 

195 "items": {"$ref": "#/components/schemas/ValidationError"}, 

196 } 

197 }, 

198 }, 

199 }, 

200 "securitySchemes": { 

201 "OAuth2PasswordBearer": { 

202 "type": "oauth2", 

203 "flows": {"password": {"scopes": {}, "tokenUrl": "token"}}, 

204 } 

205 }, 

206 }, 

207 }