Coverage for src/mesh/tests/roles/test_role_handler.py: 100%

212 statements  

« prev     ^ index     » next       coverage.py v7.9.0, created at 2026-02-04 09:42 +0000

1from unittest.mock import patch 

2 

3from mesh.model.exceptions import RoleException 

4from mesh.model.roles.author import Author 

5from mesh.model.roles.editor import Editor 

6from mesh.model.roles.journal_manager import JournalManager 

7from mesh.model.roles.reviewer import Reviewer 

8from mesh.model.roles.role_handler import RoleData, RoleHandler 

9from mesh.model.user.user_interfaces import ImpersonateData, UserInfo 

10 

11from ...models import EditorSubmissionRight, Review, Submission, SubmissionMainFile 

12from ...models.factories import ( 

13 ReviewFactory, 

14 SubmissionAuthorFactory, 

15 SubmissionFactory, 

16 SubmissionVersionFactory, 

17 UserFactory, 

18) 

19from ...models.user_models import User 

20from ...views.model_proxy import ReviewProxy, SubmissionProxy 

21from ..base_test_case import BaseTestCase 

22 

23 

24class RoleDataTestCase(BaseTestCase): 

25 used_models = [User] 

26 

27 def setUp(self): 

28 super().setUp() 

29 self.user_base = UserFactory.create() 

30 self.role_data = RoleData.from_user(self.user_base) 

31 

32 def test_default_role(self): 

33 role = self.role_data.default_role() 

34 self.assertEqual(role.code(), Author.code()) 

35 

36 with patch.object(Reviewer, "active", True): 

37 with patch.object(Editor, "active", True): 

38 with patch.object(JournalManager, "active", True): 

39 role = self.role_data.default_role() 

40 self.assertEqual(role.code(), JournalManager.code()) 

41 

42 role = self.role_data.default_role() 

43 self.assertEqual(role.code(), Editor.code()) 

44 

45 role = self.role_data.default_role() 

46 self.assertEqual(role.code(), Reviewer.code()) 

47 

48 

49class RoleHandlerTestCase(BaseTestCase): 

50 class_used_models = [Review, Submission, User] 

51 

52 @classmethod 

53 def setUpClass(cls) -> None: 

54 """ 

55 We create all the ref data only once here in `setUpClass` method instead of 

56 in `setUp` method to save quite some overhead time (it reduces tests plan 

57 up to 10s on my local machine). 

58 Note that the actual data status/content may vary from one test function to the 

59 other as it depends on the previously runned test functions ... 

60 It should be okay because we don't really play with the data content in 

61 this test case. 

62 """ 

63 super().setUpClass() 

64 cls.user_journal_manager = UserFactory.create(journal_manager=True) 

65 cls.user_author = UserFactory.create() 

66 cls.user_reviewer = UserFactory.create() 

67 

68 cls.submission = SubmissionFactory.create( 

69 created_by=cls.user_author, author_agreement=True 

70 ) 

71 submission_version = SubmissionVersionFactory.create(submission=cls.submission) 

72 SubmissionMainFile.objects.create(attached_to=submission_version, file=cls.dummy_file) 

73 SubmissionAuthorFactory.create(submission=cls.submission) 

74 request = cls.dummy_request() 

75 request.user = cls.user_author 

76 # Update the submission object to reset cached_property 

77 cls.submission = Submission.objects.get(pk=cls.submission.pk) 

78 cls.submission.submit(cls.user_author) 

79 cls.review = ReviewFactory.create(reviewer=cls.user_reviewer, version=submission_version) 

80 

81 def setUp(self): 

82 super().setUp() 

83 # Reset cached_properties 

84 self.submission = Submission.objects.get(pk=self.submission.pk) 

85 self.review = Review.objects.get(pk=self.review.pk) 

86 

87 def test_init_user_roles(self): 

88 """ 

89 Test corret init of role_handler.role_data + partial_init boolean. 

90 """ 

91 user = User.objects.get(pk=self.user_author.pk) 

92 self.assertIsNone(user.current_role) 

93 

94 role_handler = RoleHandler(self.user_author, partial_init=True) 

95 self.assertFalse(role_handler.init_complete) 

96 self.assertIsNotNone(role_handler.role_data) 

97 

98 user = User.objects.get(pk=self.user_author.pk) 

99 self.assertIsNone(user.current_role) 

100 

101 role_handler = RoleHandler(self.user_author) 

102 self.assertTrue(role_handler.init_complete) 

103 self.assertIsNotNone(role_handler.role_data) 

104 self.assertIsNotNone(role_handler.rights) 

105 self.assertIsNotNone(role_handler.current_role) 

106 self.assertEqual(role_handler.current_role.code(), Author.code()) 

107 

108 user = User.objects.get(pk=self.user_author.pk) 

109 self.assertEqual(user.current_role, Author.code()) 

110 

111 def test_set_current_role_base(self): 

112 role_handler = RoleHandler(self.user_author) 

113 user = User.objects.get(pk=self.user_author.pk) 

114 self.assertEqual(role_handler.current_role.code(), Author.code()) 

115 self.assertEqual(user.current_role, Author.code()) 

116 

117 role_handler.set_current_role(role_handler.role_data.reviewer) 

118 user = User.objects.get(pk=self.user_author.pk) 

119 self.assertEqual(role_handler.current_role.code(), Reviewer.code()) 

120 self.assertEqual(user.current_role, Reviewer.code()) 

121 

122 def test_set_current_role_impersonate(self): 

123 role_handler = RoleHandler(self.user_author) 

124 user = User.objects.get(pk=self.user_author.pk) 

125 self.assertEqual(role_handler.current_role.code(), Author.code()) 

126 self.assertEqual(user.current_role, Author.code()) 

127 

128 request = self.dummy_request() 

129 impersonate_data = ImpersonateData( 

130 target_id=user.pk, source=UserInfo.from_user(self.user_journal_manager) 

131 ) 

132 impersonate_data.serialize(request.session) 

133 role_handler.request = request 

134 role_handler.set_current_role(role_handler.role_data.reviewer) 

135 self.assertEqual(role_handler.current_role.code(), Reviewer.code()) 

136 self.assertEqual(user.current_role, Author.code()) 

137 

138 impersonate_data = ImpersonateData.from_session(request.session) 

139 self.assertEqual(impersonate_data.target_role, Reviewer.code()) # type:ignore 

140 

141 # Check session data 

142 self.assertDictEqual(request.session["user_role"], Reviewer.summary().serialize()) 

143 self.assertEqual(len(request.session["available_roles"]), 1) 

144 

145 def test_get_current_active_role_base(self): 

146 # Test current role with brand new user 

147 self.user_reviewer.current_role = None 

148 self.user_reviewer.save() 

149 role_handler = RoleHandler(self.user_reviewer, partial_init=True) 

150 self.assertEqual(len(role_handler.role_data.get_active_roles()), 2) 

151 self.assertEqual(role_handler.get_current_active_role().code(), Reviewer.code()) 

152 

153 # Test curent role when DB data is corrupted 

154 user = User.objects.get(pk=self.user_reviewer.pk) 

155 user.current_role = "__UNKNOWN_ROLE__" 

156 user.save() 

157 role_handler = RoleHandler(user, partial_init=True) 

158 self.assertEqual(role_handler.get_current_active_role().code(), Reviewer.code()) 

159 

160 # Test current role when the DB value is valid 

161 user.current_role = Author.code() 

162 user.save() 

163 role_handler = RoleHandler(user, partial_init=True) 

164 self.assertEqual(role_handler.get_current_active_role().code(), Author.code()) 

165 

166 # Test current role when the DB value is an inactive role 

167 user.current_role = Reviewer.code() 

168 user.save() 

169 Review.objects.get(pk=self.review.pk).delete() 

170 role_handler = RoleHandler(user, partial_init=True) 

171 self.assertEqual(role_handler.get_current_active_role().code(), Author.code()) 

172 

173 # Recreate deleted review for test consistency 

174 self.review.save() 

175 

176 def test_get_current_active_role_impersonate(self): 

177 user = self.user_reviewer 

178 user.current_role = Reviewer.code() 

179 user.save() 

180 request = self.dummy_request() 

181 impersonate_data = ImpersonateData( 

182 target_id=user.pk, 

183 source=UserInfo.from_user(self.user_journal_manager), 

184 target_role=Author.code(), 

185 ) 

186 impersonate_data.serialize(request.session) 

187 role_handler = RoleHandler(user, request=request, partial_init=True) 

188 

189 self.assertEqual(role_handler.get_current_active_role().code(), Author.code()) 

190 

191 role_handler.request = None 

192 self.assertEqual(role_handler.get_current_active_role().code(), Reviewer.code()) 

193 

194 # Test corrupted impersonate data 

195 impersonate_data.target_role = "__UNKNOWN_ROLE__" 

196 impersonate_data.serialize(request.session) 

197 role_handler = RoleHandler(user, request=request, partial_init=True) 

198 

199 self.assertEqual(role_handler.get_current_active_role().code(), Reviewer.code()) 

200 

201 # Test inactive role 

202 impersonate_data.target_role = Editor.code() 

203 impersonate_data.serialize(request.session) 

204 role_handler = RoleHandler(user, request=request, partial_init=True) 

205 

206 self.assertEqual(role_handler.get_current_active_role().code(), Reviewer.code()) 

207 

208 def test_switch_role(self): 

209 user = self.user_reviewer 

210 user.current_role = Reviewer.code() 

211 user.save() 

212 role_handler = RoleHandler(user) 

213 self.assertEqual(role_handler.current_role.code(), Reviewer.code()) 

214 

215 role = role_handler.switch_role(Author.code()) 

216 self.assertEqual(role.code(), Author.code()) 

217 self.assertEqual(role_handler.current_role.code(), Author.code()) 

218 user = User.objects.get(pk=user.pk) 

219 self.assertEqual(user.current_role, Author.code()) 

220 

221 self.assertRaises(RoleException, role_handler.switch_role, "__UNKNOWN_ROLE__") 

222 user = User.objects.get(pk=user.pk) 

223 self.assertEqual(user.current_role, Author.code()) 

224 

225 self.assertRaises(RoleException, role_handler.switch_role, JournalManager.code()) 

226 user = User.objects.get(pk=user.pk) 

227 self.assertEqual(user.current_role, Author.code()) 

228 

229 def test_execute_rights_function(self): 

230 role_handler = RoleHandler(self.user_author) 

231 

232 # Test author access to his own submission 

233 function_name = "can_access_submission" 

234 right_result = role_handler.execute_rights_function( 

235 role_handler.rights, function_name, self.submission 

236 ) 

237 self.assertTrue(right_result) 

238 

239 # Test wrong function 

240 function_name = "can_do_unkwnown_action" 

241 self.assertRaises( 

242 RoleException, 

243 role_handler.execute_rights_function, 

244 role_handler.rights, 

245 function_name, 

246 ) 

247 

248 # Test with attribute 

249 function_name = "submissions" 

250 self.assertRaises( 

251 RoleException, 

252 role_handler.execute_rights_function, 

253 role_handler.rights, 

254 function_name, 

255 ) 

256 

257 def test_check_rights(self): 

258 function_name = "can_access_submission" 

259 role_handler = RoleHandler(self.user_reviewer) 

260 

261 role_handler.switch_role(Reviewer.code()) 

262 right_result = role_handler.check_rights(function_name, self.submission) 

263 self.assertTrue(right_result) 

264 

265 role_handler.switch_role(Author.code()) 

266 right_result = role_handler.check_rights(function_name, self.submission) 

267 self.assertFalse(right_result) 

268 

269 def test_check_global_rights(self): 

270 function_name = "can_access_submission" 

271 role_handler = RoleHandler(self.user_reviewer) 

272 

273 role_handler.switch_role(Reviewer.code()) 

274 right_result = role_handler.check_global_rights(function_name, self.submission) 

275 self.assertTrue(right_result) 

276 

277 role_handler.switch_role(Author.code()) 

278 right_result = role_handler.check_global_rights(function_name, self.submission) 

279 self.assertTrue(right_result) 

280 

281 def test_get_from_rights(self): 

282 function_name = "get_submission_status" 

283 role_handler = RoleHandler(self.user_reviewer) 

284 

285 role_handler.switch_role(Reviewer.code()) 

286 result = role_handler.get_from_rights(function_name, self.submission) 

287 self.assertIsNotNone(result) 

288 

289 role_handler.switch_role(Author.code()) 

290 result = role_handler.get_from_rights(function_name, self.submission) 

291 self.assertIsNotNone(result) 

292 

293 def test_get_attribute(self): 

294 attribute_name = "submissions" 

295 role_handler = RoleHandler(self.user_reviewer) 

296 

297 role_handler.switch_role(Reviewer.code()) 

298 result = role_handler.get_attribute(attribute_name) 

299 self.assertIsNotNone(result) 

300 

301 role_handler.switch_role(Author.code()) 

302 result = role_handler.get_attribute(attribute_name) 

303 self.assertIsNotNone(result) 

304 

305 def test_get_proxy(self): 

306 role_handler = RoleHandler(self.user_reviewer) 

307 

308 submission_proxy = SubmissionProxy(self.submission, role_handler) 

309 self.assertIsInstance(submission_proxy, SubmissionProxy) 

310 

311 review_proxy = ReviewProxy(self.review, role_handler) 

312 self.assertIsInstance(review_proxy, ReviewProxy) 

313 

314 def test_token_authentication_allowed(self): 

315 role_handler = RoleHandler(self.user_author) 

316 self.assertTrue(role_handler.token_authentication_allowed()) 

317 

318 role_handler = RoleHandler(self.user_reviewer) 

319 self.assertTrue(role_handler.token_authentication_allowed()) 

320 

321 # Give editor right to user_reviewer 

322 EditorSubmissionRight.objects.create(user=self.user_reviewer, submission=self.submission) 

323 role_handler = RoleHandler(self.user_reviewer) 

324 self.assertFalse(role_handler.token_authentication_allowed()) 

325 EditorSubmissionRight.objects.all().delete() 

326 

327 role_handler = RoleHandler(self.user_journal_manager) 

328 self.assertFalse(role_handler.token_authentication_allowed())