Coverage for src/mesh/tests/test_mixins.py: 100%

138 statements  

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

1from unittest.mock import patch 

2 

3from django.contrib.auth.models import AnonymousUser 

4from django.http import Http404, HttpResponse 

5from django.urls import reverse 

6 

7from mesh.model.roles.author import Author 

8from mesh.model.roles.editor import Editor 

9from mesh.model.roles.reviewer import Reviewer 

10from mesh.model.roles.role_handler import ROLE_HANDLER_CACHE, RoleHandler 

11from mesh.views.mixins import ROLE_SWITCH_QUERY_PARAM, BaseRoleMixin, RoleMixin 

12 

13from ..models.factories import ( 

14 ReviewFactory, 

15 SubmissionFactory, 

16 SubmissionVersionFactory, 

17 UserFactory, 

18) 

19from ..models.submission_models import Submission 

20from ..models.user_models import User 

21from .base_test_case import BaseTestCase 

22 

23TEST_RESPONSE = HttpResponse("NAIVE RESPONSE") 

24 

25 

26class NaiveDispatcher: 

27 """ 

28 Naive dispatcher to be used for test purposes. 

29 """ 

30 

31 def dispatch(self, *args, **kwargs): 

32 return TEST_RESPONSE 

33 

34 

35class TestMixin(RoleMixin, NaiveDispatcher): 

36 pass 

37 

38 

39class TestRoleMixin(BaseTestCase): 

40 class_used_models = [Submission, User] 

41 

42 @classmethod 

43 def setUpClass(cls) -> None: 

44 super().setUpClass() 

45 cls.user_author = UserFactory.create() 

46 submission = SubmissionFactory.create(created_by=cls.user_author) 

47 version = SubmissionVersionFactory.create(submission=submission) 

48 cls.user_reviewer = UserFactory.create() 

49 ReviewFactory.create(version=version, reviewer=cls.user_reviewer) # noqa 

50 

51 def test_dispatch_no_authenticated_user(self): 

52 mixin = TestMixin() 

53 request = self.dummy_request("/") 

54 request.user = AnonymousUser() 

55 mixin.request = request 

56 response = mixin.dispatch(request) 

57 

58 self.assertRedirects(response, "/accounts/login/?next=/", fetch_redirect_response=False) 

59 

60 mixin = BaseRoleMixin() 

61 self.assertRaises(AssertionError, mixin.dispatch, request) 

62 

63 def test_base_dispatch(self): 

64 """ 

65 Test the instantiation of the role_handler and the request attributes. 

66 """ 

67 mixin = TestMixin() 

68 request = self.dummy_request() 

69 request.user = self.user_author 

70 self.assertFalse(hasattr(mixin, "role_handler")) 

71 self.assertFalse(hasattr(mixin, "request")) 

72 

73 response = mixin.dispatch(request) 

74 self.assertIs(response, TEST_RESPONSE) 

75 self.assertIsInstance(mixin.role_handler, RoleHandler) 

76 self.assertIs(mixin.role_handler.user, self.user_author) 

77 self.assertTrue(mixin.role_handler.init_complete) 

78 self.assertIs(mixin.request, request) 

79 

80 def test_cached_role_handler(self): 

81 # Test when the role_handler is cahced for the correct user 

82 mixin = TestMixin() 

83 request = self.dummy_request() 

84 request.user = self.user_author 

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

86 setattr(request, ROLE_HANDLER_CACHE, role_handler) 

87 

88 self.assertIsNone(role_handler.request) 

89 self.assertFalse(role_handler.init_complete) 

90 

91 response = mixin.dispatch(request) 

92 self.assertIs(response, TEST_RESPONSE) 

93 self.assertIs(mixin.role_handler, role_handler) 

94 self.assertIs(role_handler.request, request) 

95 self.assertIs(role_handler.user, self.user_author) 

96 self.assertTrue(role_handler.init_complete) 

97 

98 # Test role_handler for another user 

99 mixin = TestMixin() 

100 request = self.dummy_request() 

101 request.user = self.user_author 

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

103 setattr(request, ROLE_HANDLER_CACHE, role_handler) 

104 

105 self.assertIsNone(role_handler.request) 

106 self.assertFalse(role_handler.init_complete) 

107 

108 response = mixin.dispatch(request) 

109 self.assertIs(response, TEST_RESPONSE) 

110 self.assertIsNot(mixin.role_handler, role_handler) 

111 self.assertIsNone(role_handler.request) 

112 self.assertIs(mixin.role_handler.user, self.user_author) 

113 self.assertIs(role_handler.user, self.user_reviewer) 

114 self.assertTrue(mixin.role_handler.init_complete) 

115 

116 def test_restrict_dispatch(self): 

117 mixin = TestMixin() 

118 request = self.dummy_request() 

119 request.user = self.user_author 

120 with patch.object(RoleMixin, "restrict_dispatch", return_value=False): 

121 response = mixin.dispatch(request) 

122 

123 self.assertIs(response, TEST_RESPONSE) 

124 

125 mixin = TestMixin() 

126 request = self.dummy_request() 

127 request.user = self.user_author 

128 with patch.object(RoleMixin, "restrict_dispatch", return_value=True): 

129 response = mixin.dispatch(request) 

130 

131 self.assertRedirects(response, reverse("mesh:home"), fetch_redirect_response=False) 

132 

133 redirect_uri = "/you_failed/dummy/" 

134 mixin.fail_redirect_uri = redirect_uri 

135 with patch.object(RoleMixin, "restrict_dispatch", return_value=True): 

136 response = mixin.dispatch(request) 

137 

138 self.assertRedirects(response, redirect_uri, fetch_redirect_response=False) 

139 

140 def test_force_role(self): 

141 role_handler = RoleHandler(self.user_reviewer) 

142 role_handler.switch_role(Author.code()) 

143 

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

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

146 

147 # Test forcing active reviewer role 

148 mixin = TestMixin() 

149 mixin.restricted_roles = [Reviewer] 

150 request = self.dummy_request() 

151 request.user = self.user_reviewer 

152 

153 response = mixin.dispatch(request) 

154 self.assertIs(response, TEST_RESPONSE) 

155 self.assertEqual(mixin.role_handler.current_role.code(), Reviewer.code()) 

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

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

158 

159 # Test forcing current role again 

160 mixin = TestMixin() 

161 mixin.restricted_roles = [Reviewer] 

162 request = self.dummy_request() 

163 request.user = self.user_reviewer 

164 

165 response = mixin.dispatch(request) 

166 self.assertIs(response, TEST_RESPONSE) 

167 self.assertEqual(mixin.role_handler.current_role.code(), Reviewer.code()) 

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

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

170 

171 # Test forcing inactive role 

172 mixin = TestMixin() 

173 mixin.restricted_roles = [Editor] 

174 

175 self.assertRaises(Http404, mixin.dispatch, request) 

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

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

178 

179 def test_force_role_when_switching(self): 

180 role_handler = RoleHandler(self.user_reviewer) 

181 role_handler.switch_role(Author.code()) 

182 

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

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

185 

186 query_params = {ROLE_SWITCH_QUERY_PARAM: "true"} 

187 request = self.dummy_request("/restricted_route", data=query_params) 

188 request.user = self.user_reviewer 

189 

190 mixin = TestMixin() 

191 mixin.restricted_roles = [Reviewer] 

192 response = mixin.dispatch(request) 

193 self.assertIs(response, TEST_RESPONSE) 

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

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