Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1""" 

2This file (test_admin.py) contains the functional tests for 

3the `admin` blueprint. 

4 

5These tests use GETs and POSTs to different endpoints to check 

6for the proper behavior of the `admin` blueprint. 

7""" 

8import json 

9import os 

10 

11import pytest 

12from flask import request 

13from flask import url_for 

14from modules.box__default.auth.models import Role 

15from modules.box__default.auth.models import role_user_bridge 

16from modules.box__default.auth.models import User 

17 

18 

19dirpath = os.path.dirname(os.path.abspath(__file__)) 

20module_path = os.path.dirname(dirpath) 

21 

22module_info = None 

23 

24 

25class TestAdminInvalidAccess: 

26 """ 

27 Test all admin routes for correct user authentication 

28 """ 

29 

30 routes_get = [ 

31 "/", 

32 "/add", 

33 "/delete/<id>", 

34 "/edit/<id>", 

35 "/roles", 

36 "/roles/<role_id>/delete", 

37 ] 

38 

39 routes_post = ["/update", "/roles/update", "/roles/add", "/add"] 

40 

41 @pytest.mark.parametrize("route", routes_get) 

42 def test_redirect_if_not_logged_in_get(self, test_client, route, auth): 

43 auth.logout() 

44 with open(os.path.join(module_path, "info.json")) as f: 

45 module_info = json.load(f) 

46 response = test_client.get( 

47 f"{module_info['url_prefix']}{route}", follow_redirects=True 

48 ) 

49 

50 assert response.status_code == 200 

51 assert request.path == url_for("auth.login") 

52 

53 @pytest.mark.parametrize("route", routes_post) 

54 def test_redirect_if_not_logged_in_post(self, test_client, route, auth): 

55 auth.logout() 

56 with open(os.path.join(module_path, "info.json")) as f: 

57 module_info = json.load(f) 

58 response = test_client.post( 

59 f"{module_info['url_prefix']}{route}", follow_redirects=True 

60 ) 

61 

62 assert response.status_code == 200 

63 assert request.path == url_for("auth.login") 

64 

65 @pytest.mark.usefixtures("login_non_admin_user") 

66 @pytest.mark.parametrize("route", routes_get) 

67 def test_no_admin_access_if_not_admin_get(self, test_client, route): 

68 with open(os.path.join(module_path, "info.json")) as f: 

69 module_info = json.load(f) 

70 response = test_client.get( 

71 f"{module_info['url_prefix']}{route}", follow_redirects=True 

72 ) 

73 

74 assert response.status_code == 200 

75 assert request.path == url_for("dashboard.index") 

76 assert b"You need to be an admin to view this page" in response.data 

77 

78 @pytest.mark.usefixtures("login_non_admin_user") 

79 @pytest.mark.parametrize("route", routes_post) 

80 def test_no_admin_access_if_not_admin_post(self, test_client, route): 

81 with open(os.path.join(module_path, "info.json")) as f: 

82 module_info = json.load(f) 

83 response = test_client.post( 

84 f"{module_info['url_prefix']}{route}", follow_redirects=True 

85 ) 

86 

87 assert response.status_code == 200 

88 assert request.path == url_for("dashboard.index") 

89 assert b"You need to be an admin to view this page" in response.data 

90 

91 

92@pytest.mark.usefixtures("login_admin_user") 

93class TestAdminEndpoints: 

94 """ 

95 Test all admin api post and get requests 

96 """ 

97 

98 def test_admin_user_list_get(self, test_client): 

99 with open(os.path.join(module_path, "info.json")) as f: 

100 module_info = json.load(f) 

101 response = test_client.get(f"{module_info['url_prefix']}/") 

102 

103 assert response.status_code == 200 

104 assert b"Admin" in response.data 

105 assert b"id" in response.data 

106 assert b"Email" in response.data 

107 assert b"Password" in response.data 

108 assert b"Roles" in response.data 

109 

110 def test_admin_add_get(self, test_client): 

111 with open(os.path.join(module_path, "info.json")) as f: 

112 module_info = json.load(f) 

113 response = test_client.get(f"{module_info['url_prefix']}/add") 

114 

115 assert response.status_code == 200 

116 assert b"Email" in response.data 

117 assert b"Password" in response.data 

118 assert b"First Name" in response.data 

119 assert b"Last Name" in response.data 

120 assert b"Admin User" in response.data 

121 

122 def test_admin_add_unique_user_post(self, test_client): 

123 with open(os.path.join(module_path, "info.json")) as f: 

124 module_info = json.load(f) 

125 role1 = Role.create(name="test1-role") 

126 role2 = Role.create(name="test2-role") 

127 data = { 

128 "email": "test@gmail.com", 

129 "password": "pass", 

130 "first_name": "Test", 

131 "last_name": "User", 

132 "is_admin": "", 

133 f"role_{role1.id}": "", 

134 f"role_{role2.id}": "", 

135 } 

136 

137 test_client.post( 

138 f"{module_info['url_prefix']}/add", 

139 data=data, 

140 follow_redirects=True, 

141 ) 

142 test_user = User.query.filter(User.email == "test@gmail.com").scalar() 

143 

144 assert test_user is not None 

145 assert test_user.first_name == "Test" 

146 assert test_user.last_name == "User" 

147 assert test_user.is_admin is False 

148 assert test_user.roles is not None 

149 assert len(test_user.roles) == 2 

150 assert role1.users[0].email == "test@gmail.com" 

151 assert role2.users[0].email == "test@gmail.com" 

152 

153 def test_admin_add_existing_user_post(self, test_client): 

154 with open(os.path.join(module_path, "info.json")) as f: 

155 module_info = json.load(f) 

156 User.create(email="test@gmail.com", password="pass") 

157 data = { 

158 "email": "test@gmail.com", 

159 "password": "pass", 

160 "first_name": "Test", 

161 "last_name": "User", 

162 "is_admin": "", 

163 } 

164 

165 response = test_client.post( 

166 f"{module_info['url_prefix']}/add", 

167 data=data, 

168 follow_redirects=True, 

169 ) 

170 test_users = User.query.filter(User.email == "test@gmail.com").count() 

171 

172 assert response.status_code == 200 

173 assert b"User with same email already exists" in response.data 

174 assert test_users == 1 

175 

176 def test_admin_delete_existing_user_get(self, test_client): 

177 with open(os.path.join(module_path, "info.json")) as f: 

178 module_info = json.load(f) 

179 user = User(email="test@gmail.com", password="pass") 

180 role1 = Role(name="test1-role") 

181 role2 = Role(name="test2-role") 

182 user.roles = [role1, role2] 

183 user.save() 

184 

185 response = test_client.get( 

186 f"{module_info['url_prefix']}/delete/{user.id}", 

187 follow_redirects=True, 

188 ) 

189 test_user = User.query.filter(User.email == user.email).scalar() 

190 test_roles = Role.query.count() 

191 user_role = ( 

192 User.query.join(role_user_bridge) 

193 .join(Role) 

194 .filter(User.id == user.id) 

195 .scalar() 

196 ) 

197 

198 assert response.status_code == 200 

199 assert test_user is None 

200 assert user_role is None 

201 assert test_roles == 2 

202 

203 def test_admin_delete_nonexisting_user_get(self, test_client): 

204 with open(os.path.join(module_path, "info.json")) as f: 

205 module_info = json.load(f) 

206 response = test_client.get( 

207 f"{module_info['url_prefix']}/delete/some_id", 

208 follow_redirects=True, 

209 ) 

210 

211 assert response.status_code == 200 

212 assert b"Unable to delete. Invalid user id" in response.data 

213 

214 def test_admin_edit_existing_user_get(self, test_client): 

215 with open(os.path.join(module_path, "info.json")) as f: 

216 module_info = json.load(f) 

217 user = User.create(email="test@gmail.com", password="pass") 

218 

219 response = test_client.get( 

220 f"{module_info['url_prefix']}/edit/{user.id}", 

221 ) 

222 

223 assert response.status_code == 200 

224 assert b"test@gmail.com" in response.data 

225 assert b"Edit User" in response.data 

226 

227 def test_admin_edit_nonexisting_user_get(self, test_client): 

228 with open(os.path.join(module_path, "info.json")) as f: 

229 module_info = json.load(f) 

230 response = test_client.get( 

231 f"{module_info['url_prefix']}/edit/some-id", follow_redirects=True 

232 ) 

233 

234 assert response.status_code == 200 

235 assert b"Invalid user id" in response.data 

236 assert request.path == f"{module_info['url_prefix']}/" 

237 

238 def test_admin_update_user_adding_new_roles_to_user(self, test_client): 

239 with open(os.path.join(module_path, "info.json")) as f: 

240 module_info = json.load(f) 

241 user = User.create(email="foo@gmail.com", password="pass") 

242 role1 = Role.create(name="test1-role") 

243 role2 = Role.create(name="test2-role") 

244 data = { 

245 "id": str(user.id), 

246 "email": "bar@gmail.com", 

247 "password": "newpass", 

248 "first_name": "Test", 

249 "last_name": "User", 

250 "is_admin": "", 

251 f"role_{role1.id}": "", 

252 f"role_{role2.id}": "", 

253 } 

254 

255 response = test_client.post( 

256 f"{module_info['url_prefix']}/update", 

257 data=data, 

258 follow_redirects=True, 

259 ) 

260 

261 assert response.status_code == 200 

262 assert user.email == "bar@gmail.com" 

263 assert user.check_password("newpass") 

264 assert user.first_name == "Test" 

265 assert user.last_name == "User" 

266 assert len(user.roles) == 2 

267 assert role1.users[0].email == "bar@gmail.com" 

268 assert role2.users[0].email == "bar@gmail.com" 

269 

270 def test_admin_update_user_remove_old_roles_from_user(self, test_client): 

271 with open(os.path.join(module_path, "info.json")) as f: 

272 module_info = json.load(f) 

273 user = User(email="foo@gmail.com", password="pass", is_admin=True) 

274 user.is_admin = True 

275 role1 = Role(name="test1-role") 

276 role2 = Role(name="test2-role") 

277 user.roles = [role1, role2] 

278 user.save() 

279 data = { 

280 "id": str(user.id), 

281 "email": "bar@gmail.com", 

282 "first_name": "Test", 

283 "last_name": "User", 

284 "password": " ", 

285 "is_admin": None, 

286 } 

287 

288 response = test_client.post( 

289 f"{module_info['url_prefix']}/update", 

290 data=data, 

291 follow_redirects=True, 

292 ) 

293 

294 assert response.status_code == 200 

295 assert user.email == "bar@gmail.com" 

296 assert user.check_password("pass") 

297 assert len(user.roles) == 0 

298 assert len(role1.users) == 0 

299 assert len(role2.users) == 0 

300 

301 def test_admin_roles_get(self, test_client): 

302 with open(os.path.join(module_path, "info.json")) as f: 

303 module_info = json.load(f) 

304 response = test_client.get(f"{module_info['url_prefix']}/roles") 

305 

306 assert response.status_code == 200 

307 assert b"Roles" in response.data 

308 

309 def test_admin_roles_add_nonexisting_role_post(self, test_client): 

310 with open(os.path.join(module_path, "info.json")) as f: 

311 module_info = json.load(f) 

312 response = test_client.post( 

313 f"{module_info['url_prefix']}/roles/add", 

314 data=dict(name="new-role"), 

315 follow_redirects=True, 

316 ) 

317 

318 role = Role.query.filter(Role.name == "new-role").scalar() 

319 role_count = Role.query.count() 

320 

321 assert response.status_code == 200 

322 assert role is not None 

323 assert role_count == 1 

324 

325 def test_admin_roles_add_existing_role_post(self, test_client): 

326 with open(os.path.join(module_path, "info.json")) as f: 

327 module_info = json.load(f) 

328 Role.create(name="new-role") 

329 

330 response = test_client.post( 

331 f"{module_info['url_prefix']}/roles/add", 

332 data=dict(name="new-role"), 

333 follow_redirects=True, 

334 ) 

335 role_count = Role.query.count() 

336 role = Role.query.filter(Role.name == "new-role").scalar() 

337 

338 assert response.status_code == 200 

339 assert b"Role already exists" in response.data 

340 assert role is not None 

341 assert role_count == 1 

342 

343 def test_admin_roles_delete_nonexisting_role_get(self, test_client): 

344 with open(os.path.join(module_path, "info.json")) as f: 

345 module_info = json.load(f) 

346 response = test_client.get( 

347 f"{module_info['url_prefix']}/roles/some-id/delete", 

348 follow_redirects=True, 

349 ) 

350 

351 assert response.status_code == 200 

352 assert request.path == f"{module_info['url_prefix']}/roles" 

353 assert b"Unable to delete. Invalid role id" in response.data 

354 

355 def test_admin_roles_delete_existing_role_get(self, test_client): 

356 with open(os.path.join(module_path, "info.json")) as f: 

357 module_info = json.load(f) 

358 role1 = Role.create(name="new-role1") 

359 role2 = Role.create(name="new-role2") 

360 

361 response = test_client.get( 

362 f"{module_info['url_prefix']}/roles/{role1.id}/delete", 

363 follow_redirects=True, 

364 ) 

365 roles = Role.query.all() 

366 

367 assert response.status_code == 200 

368 assert request.path == f"{module_info['url_prefix']}/roles" 

369 assert b"Role successfully deleted" in response.data 

370 assert roles is not None 

371 assert roles[0].name == role2.name 

372 assert len(roles) == 1 

373 

374 def test_admin_roles_update_nonexisting_role_post(self, test_client): 

375 with open(os.path.join(module_path, "info.json")) as f: 

376 module_info = json.load(f) 

377 response = test_client.post( 

378 f"{module_info['url_prefix']}/roles/update", 

379 data=dict(role_id="some-id"), 

380 follow_redirects=True, 

381 ) 

382 roles = Role.query.count() 

383 

384 assert response.status_code == 200 

385 assert request.path == f"{module_info['url_prefix']}/roles" 

386 assert b"Unable to update. Role does not exist" in response.data 

387 assert roles == 0 

388 

389 def test_admin_roles_update_existing_role_post(self, test_client): 

390 with open(os.path.join(module_path, "info.json")) as f: 

391 module_info = json.load(f) 

392 new_role = Role.create(name="new-role1") 

393 

394 response = test_client.post( 

395 f"{module_info['url_prefix']}/roles/update", 

396 data=dict(role_id=new_role.id, role_name="update-role"), 

397 follow_redirects=True, 

398 ) 

399 role = Role.query.scalar() 

400 

401 assert response.status_code == 200 

402 assert request.path == f"{module_info['url_prefix']}/roles" 

403 assert b"Role successfully updated" in response.data 

404 assert role is not None 

405 assert role.name == "update-role"