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

127 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-08-11 09:47 +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.models.orm.factories import ( 

8 ReviewFactory, 

9 SubmissionFactory, 

10 SubmissionVersionFactory, 

11 UserFactory, 

12) 

13from mesh.models.orm.submission_models import Submission 

14from mesh.models.orm.user_models import User 

15from mesh.models.roles.author import Author 

16from mesh.models.roles.editor import Editor 

17from mesh.models.roles.reviewer import Reviewer 

18from mesh.models.roles.role_handler import ROLE_HANDLER_CACHE, RoleHandler 

19from mesh.tests.base_test_case import BaseTestCase 

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

21 

22TEST_RESPONSE = HttpResponse("NAIVE RESPONSE") 

23 

24 

25class NaiveDispatcher: 

26 """ 

27 Naive dispatcher to be used for test purposes. 

28 """ 

29 

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

31 return TEST_RESPONSE 

32 

33 

34class TestMixin(RoleMixin, NaiveDispatcher): 

35 pass 

36 

37 

38class TestRoleMixin(BaseTestCase): 

39 class_used_models = [Submission, User] 

40 

41 @classmethod 

42 def setUpClass(cls) -> None: 

43 super().setUpClass() 

44 cls.user_author = UserFactory.create() 

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

46 version = SubmissionVersionFactory.create(submission=submission) 

47 cls.user_reviewer = UserFactory.create() 

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

49 

50 def test_dispatch_no_authenticated_user(self): 

51 mixin = TestMixin() 

52 request = self.dummy_request("/") 

53 request.user = AnonymousUser() 

54 mixin.request = request 

55 response = mixin.dispatch(request) 

56 

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

58 

59 mixin = BaseRoleMixin() 

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

61 

62 def test_base_dispatch(self): 

63 """ 

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

65 """ 

66 mixin = TestMixin() 

67 request = self.dummy_request() 

68 request.user = self.user_author 

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

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

71 

72 response = mixin.dispatch(request) 

73 self.assertIs(response, TEST_RESPONSE) 

74 self.assertIs(mixin.request, request) 

75 

76 def test_cached_role_handler(self): 

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

78 mixin = TestMixin() 

79 request = self.dummy_request() 

80 request.user = self.user_author 

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

82 setattr(request, ROLE_HANDLER_CACHE, role_handler) 

83 

84 response = mixin.dispatch(request) 

85 self.assertIs(response, TEST_RESPONSE) 

86 

87 # Test role_handler for another user 

88 mixin = TestMixin() 

89 request = self.dummy_request() 

90 request.user = self.user_author 

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

92 setattr(request, ROLE_HANDLER_CACHE, role_handler) 

93 

94 self.assertIsNone(role_handler.request) 

95 self.assertFalse(role_handler.init_complete) 

96 

97 response = mixin.dispatch(request) 

98 self.assertIs(response, TEST_RESPONSE) 

99 self.assertIsNone(role_handler.request) 

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

101 

102 def test_restrict_dispatch(self): 

103 mixin = TestMixin() 

104 request = self.dummy_request() 

105 request.user = self.user_author 

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

107 response = mixin.dispatch(request) 

108 

109 self.assertIs(response, TEST_RESPONSE) 

110 

111 mixin = TestMixin() 

112 request = self.dummy_request() 

113 request.user = self.user_author 

114 request.current_role = Author(request.user) 

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

116 response = mixin.dispatch(request) 

117 

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

119 

120 redirect_uri = "/you_failed/dummy/" 

121 mixin.fail_redirect_uri = redirect_uri 

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

123 response = mixin.dispatch(request) 

124 

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

126 

127 def test_force_role(self): 

128 role_handler = RoleHandler(self.user_reviewer) 

129 role_handler.switch_role(Author.code()) 

130 

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

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

133 

134 # Test forcing active reviewer role 

135 mixin = TestMixin() 

136 mixin.restricted_roles = [Reviewer] 

137 request = self.dummy_request() 

138 request.user = self.user_reviewer 

139 request.current_role = self.user_reviewer.current_role 

140 

141 response = mixin.dispatch(request) 

142 self.assertIs(response, TEST_RESPONSE) 

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

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

145 

146 # Test forcing current role again 

147 mixin = TestMixin() 

148 mixin.restricted_roles = [Reviewer] 

149 request = self.dummy_request() 

150 request.user = self.user_reviewer 

151 request.current_role = self.user_reviewer.current_role 

152 

153 response = mixin.dispatch(request) 

154 self.assertIs(response, TEST_RESPONSE) 

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

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

157 

158 # Test forcing inactive role 

159 mixin = TestMixin() 

160 mixin.restricted_roles = [Editor] 

161 

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

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

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

165 

166 def test_force_role_when_switching(self): 

167 role_handler = RoleHandler(self.user_reviewer) 

168 role_handler.switch_role(Author.code()) 

169 

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

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

172 

173 query_params = {ROLE_SWITCH_QUERY_PARAM: "true"} 

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

175 request.user = self.user_reviewer 

176 

177 mixin = TestMixin() 

178 mixin.restricted_roles = [Reviewer] 

179 response = mixin.dispatch(request) 

180 self.assertIs(response, TEST_RESPONSE) 

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

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