Coverage for modules/box__default/appadmin/tests/test_admin.py: 89%

# Coverage for modules/box__default/appadmin/tests/test_admin.py : 89%

## 232 statements

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"""

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

3 the `admin` blueprint.

4

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

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

7"""

8 import json

9 import os

10

11 import pytest

12 from flask import request

13 from flask import url_for

14 from modules.box__default.auth.models import Role

15 from modules.box__default.auth.models import role_user_bridge

16 from modules.box__default.auth.models import User

17

18

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

20 module_path = os.path.dirname(dirpath)

21

22 module_info = None

23

24

25 class 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")

93 class 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"