blob: edb05cd6940f3dbc854f98bde1521c4d96909bae [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001# Copyright 2016 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
Copybara854996b2021-09-07 19:36:02 +00004
5"""Unit tests for framework_views classes."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
10import time
11import unittest
12
13from framework import framework_constants
14from framework import framework_views
15from framework import monorailrequest
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010016from mrproto import project_pb2
17from mrproto import tracker_pb2
18from mrproto import user_pb2
Copybara854996b2021-09-07 19:36:02 +000019import settings
20from services import service_manager
21from testing import fake
22
23
24LONG_STR = 'VeryLongStringThatCertainlyWillNotFit'
25LONG_PART_STR = 'OnePartThatWillNotFit-OneShort'
26
27
28class LabelViewTest(unittest.TestCase):
29
30 def testLabelView(self):
31 view = framework_views.LabelView('', None)
32 self.assertEqual('', view.name)
33
34 view = framework_views.LabelView('Priority-High', None)
35 self.assertEqual('Priority-High', view.name)
36 self.assertIsNone(view.is_restrict)
37 self.assertEqual('', view.docstring)
38 self.assertEqual('Priority', view.prefix)
39 self.assertEqual('High', view.value)
40
41 view = framework_views.LabelView('%s-%s' % (LONG_STR, LONG_STR), None)
42 self.assertEqual('%s-%s' % (LONG_STR, LONG_STR), view.name)
43 self.assertEqual('', view.docstring)
44 self.assertEqual(LONG_STR, view.prefix)
45 self.assertEqual(LONG_STR, view.value)
46
47 view = framework_views.LabelView(LONG_PART_STR, None)
48 self.assertEqual(LONG_PART_STR, view.name)
49 self.assertEqual('', view.docstring)
50 self.assertEqual('OnePartThatWillNotFit', view.prefix)
51 self.assertEqual('OneShort', view.value)
52
53 config = tracker_pb2.ProjectIssueConfig()
54 config.well_known_labels.append(tracker_pb2.LabelDef(
55 label='Priority-High', label_docstring='Must ship in this milestone'))
56
57 view = framework_views.LabelView('Priority-High', config)
58 self.assertEqual('Must ship in this milestone', view.docstring)
59
60 view = framework_views.LabelView('Priority-Foo', config)
61 self.assertEqual('', view.docstring)
62
63 view = framework_views.LabelView('Restrict-View-Commit', None)
64 self.assertTrue(view.is_restrict)
65
66
67class StatusViewTest(unittest.TestCase):
68
69 def testStatusView(self):
70 view = framework_views.StatusView('', None)
71 self.assertEqual('', view.name)
72
73 view = framework_views.StatusView('Accepted', None)
74 self.assertEqual('Accepted', view.name)
75 self.assertEqual('', view.docstring)
76 self.assertEqual('yes', view.means_open)
77
78 view = framework_views.StatusView(LONG_STR, None)
79 self.assertEqual(LONG_STR, view.name)
80 self.assertEqual('', view.docstring)
81 self.assertEqual('yes', view.means_open)
82
83 config = tracker_pb2.ProjectIssueConfig()
84 config.well_known_statuses.append(tracker_pb2.StatusDef(
85 status='SlamDunk', status_docstring='Code fixed and taught a lesson',
86 means_open=False))
87
88 view = framework_views.StatusView('SlamDunk', config)
89 self.assertEqual('Code fixed and taught a lesson', view.docstring)
90 self.assertFalse(view.means_open)
91
92 view = framework_views.StatusView('SlammedBack', config)
93 self.assertEqual('', view.docstring)
94
95
96class UserViewTest(unittest.TestCase):
97
98 def setUp(self):
99 self.user = user_pb2.User(user_id=111)
100
101 def testGetAvailablity_Anon(self):
102 self.user.user_id = 0
103 user_view = framework_views.UserView(self.user)
104 self.assertEqual(None, user_view.avail_message)
105 self.assertEqual(None, user_view.avail_state)
106
107 def testGetAvailablity_Banned(self):
108 self.user.banned = 'spamming'
109 user_view = framework_views.UserView(self.user)
110 self.assertEqual('Banned', user_view.avail_message)
111 self.assertEqual('banned', user_view.avail_state)
112
113 def testGetAvailablity_Vacation(self):
114 self.user.vacation_message = 'gone fishing'
115 user_view = framework_views.UserView(self.user)
116 self.assertEqual('gone fishing', user_view.avail_message)
117 self.assertEqual('none', user_view.avail_state)
118
119 self.user.vacation_message = (
120 'Gone fishing as really long time with lots of friends and reading '
121 'a long novel by a famous author. I wont have internet access but '
122 'If you urgently need anything you can call Alice or Bob for most '
123 'things otherwise call Charlie. Wish me luck! ')
124 user_view = framework_views.UserView(self.user)
125 self.assertTrue(len(user_view.avail_message) >= 50)
126 self.assertTrue(len(user_view.avail_message_short) < 50)
127 self.assertEqual('none', user_view.avail_state)
128
129 def testGetAvailablity_Bouncing(self):
130 self.user.email_bounce_timestamp = 1234567890
131 user_view = framework_views.UserView(self.user)
132 self.assertEqual('Email to this user bounced', user_view.avail_message)
133 self.assertEqual(user_view.avail_message_short, user_view.avail_message)
134 self.assertEqual('none', user_view.avail_state)
135
136 def testGetAvailablity_Groups(self):
137 user_view = framework_views.UserView(self.user, is_group=True)
138 self.assertEqual(None, user_view.avail_message)
139 self.assertEqual(None, user_view.avail_state)
140
141 self.user.email = 'likely-user-group@example.com'
142 user_view = framework_views.UserView(self.user)
143 self.assertEqual(None, user_view.avail_message)
144 self.assertEqual(None, user_view.avail_state)
145
146 def testGetAvailablity_NeverVisitied(self):
147 self.user.last_visit_timestamp = 0
148 user_view = framework_views.UserView(self.user)
149 self.assertEqual('User never visited', user_view.avail_message)
150 self.assertEqual('never', user_view.avail_state)
151
152 def testGetAvailablity_NotRecent(self):
153 now = int(time.time())
154 self.user.last_visit_timestamp = now - 20 * framework_constants.SECS_PER_DAY
155 user_view = framework_views.UserView(self.user)
156 self.assertEqual('Last visit 20 days ago', user_view.avail_message)
157 self.assertEqual('unsure', user_view.avail_state)
158
159 def testGetAvailablity_ReallyLongTime(self):
160 now = int(time.time())
161 self.user.last_visit_timestamp = now - 99 * framework_constants.SECS_PER_DAY
162 user_view = framework_views.UserView(self.user)
163 self.assertEqual('Last visit > 30 days ago', user_view.avail_message)
164 self.assertEqual('none', user_view.avail_state)
165
166 def testDeletedUser(self):
167 deleted_user = user_pb2.User(user_id=1)
168 user_view = framework_views.UserView(deleted_user)
169 self.assertEqual(
170 user_view.display_name, framework_constants.DELETED_USER_NAME)
171 self.assertEqual(user_view.email, '')
172 self.assertEqual(user_view.obscure_email, '')
173 self.assertEqual(user_view.profile_url, '')
174
175class RevealEmailsToMembersTest(unittest.TestCase):
176
177 def setUp(self):
178 self.cnxn = fake.MonorailConnection()
179 self.services = service_manager.Services(
180 project=fake.ProjectService(),
181 user=fake.UserService(),
182 usergroup=fake.UserGroupService())
183 self.mr = monorailrequest.MonorailRequest(None)
184 self.mr.project = self.services.project.TestAddProject(
185 'proj',
186 project_id=789,
187 owner_ids=[111],
188 committer_ids=[222],
189 contrib_ids=[333, 888])
190 user = self.services.user.TestAddUser('test@example.com', 1000)
191 self.mr.auth.user_pb = user
192
193 def CheckRevealAllToMember(
194 self, logged_in_user_id, expected, viewed_user_id=333, group_id=None):
195 user_view = framework_views.StuffUserView(
196 viewed_user_id, 'user@example.com', True)
197
198 if group_id:
199 pass # xxx re-implement groups
200
201 users_by_id = {333: user_view}
202 self.mr.auth.user_id = logged_in_user_id
203 self.mr.auth.effective_ids = {logged_in_user_id}
204 # Assert display name is obscured before the reveal.
205 self.assertEqual('u...@example.com', user_view.display_name)
206 # Assert profile url contains user ID before the reveal.
207 self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
208 framework_views.RevealAllEmailsToMembers(
209 self.cnxn, self.services, self.mr.auth, users_by_id)
210 self.assertEqual(expected, not user_view.obscure_email)
211 if expected:
212 # Assert display name is now revealed.
213 self.assertEqual('user@example.com', user_view.display_name)
214 # Assert profile url contains the email.
215 self.assertEqual('/u/user@example.com/', user_view.profile_url)
216 else:
217 # Assert display name is still hidden.
218 self.assertEqual('u...@example.com', user_view.display_name)
219 # Assert profile url still contains user ID.
220 self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
221
222 # TODO(https://crbug.com/monorail/8192): Remove this method and related test.
223 def DeprecatedCheckRevealAllToMember(
224 self, logged_in_user_id, expected, viewed_user_id=333, group_id=None):
225 user_view = framework_views.StuffUserView(
226 viewed_user_id, 'user@example.com', True)
227
228 if group_id:
229 pass # xxx re-implement groups
230
231 users_by_id = {333: user_view}
232 self.mr.auth.user_id = logged_in_user_id
233 self.mr.auth.effective_ids = {logged_in_user_id}
234 # Assert display name is obscured before the reveal.
235 self.assertEqual('u...@example.com', user_view.display_name)
236 # Assert profile url contains user ID before the reveal.
237 self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
238 framework_views.RevealAllEmailsToMembers(
239 self.cnxn, self.services, self.mr.auth, users_by_id, self.mr.project)
240 self.assertEqual(expected, not user_view.obscure_email)
241 if expected:
242 # Assert display name is now revealed.
243 self.assertEqual('user@example.com', user_view.display_name)
244 # Assert profile url contains the email.
245 self.assertEqual('/u/user@example.com/', user_view.profile_url)
246 else:
247 # Assert display name is still hidden.
248 self.assertEqual('u...@example.com', user_view.display_name)
249 # Assert profile url still contains user ID.
250 self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
251
252 def testDontRevealEmailsToPriviledgedDomain(self):
253 """We no longer give this advantage based on email address domain."""
254 for priviledged_user_domain in settings.priviledged_user_domains:
255 self.mr.auth.user_pb.email = 'test@' + priviledged_user_domain
256 self.CheckRevealAllToMember(100001, False)
257
258 def testRevealEmailToSelf(self):
259 logged_in_user = self.services.user.TestAddUser('user@example.com', 333)
260 self.mr.auth.user_pb = logged_in_user
261 self.CheckRevealAllToMember(333, True)
262
263 def testRevealAllEmailsToMembers_Collaborators(self):
264 self.CheckRevealAllToMember(0, False)
265 self.CheckRevealAllToMember(111, True)
266 self.CheckRevealAllToMember(222, True)
267 self.CheckRevealAllToMember(333, True)
268 self.CheckRevealAllToMember(444, False)
269
270 # Viewed user has indirect role in the project via a group.
271 self.CheckRevealAllToMember(0, False, group_id=888)
272 self.CheckRevealAllToMember(111, True, group_id=888)
273 # xxx re-implement
274 # self.CheckRevealAllToMember(
275 # 111, True, viewed_user_id=444, group_id=888)
276
277 # Logged in user has indirect role in the project via a group.
278 self.CheckRevealAllToMember(888, True)
279
280 def testDeprecatedRevealAllEmailsToMembers_Collaborators(self):
281 self.DeprecatedCheckRevealAllToMember(0, False)
282 self.DeprecatedCheckRevealAllToMember(111, True)
283 self.DeprecatedCheckRevealAllToMember(222, True)
284 self.DeprecatedCheckRevealAllToMember(333, True)
285 self.DeprecatedCheckRevealAllToMember(444, False)
286
287 # Viewed user has indirect role in the project via a group.
288 self.DeprecatedCheckRevealAllToMember(0, False, group_id=888)
289 self.DeprecatedCheckRevealAllToMember(111, True, group_id=888)
290
291 # Logged in user has indirect role in the project via a group.
292 self.DeprecatedCheckRevealAllToMember(888, True)
293
294 def testRevealAllEmailsToMembers_Admins(self):
295 self.CheckRevealAllToMember(555, False)
296 self.mr.auth.user_pb.is_site_admin = True
297 self.CheckRevealAllToMember(555, True)
298
299
300class RevealAllEmailsTest(unittest.TestCase):
301
302 def testRevealAllEmail(self):
303 users_by_id = {
304 111: framework_views.StuffUserView(111, 'a@a.com', True),
305 222: framework_views.StuffUserView(222, 'b@b.com', True),
306 333: framework_views.StuffUserView(333, 'c@c.com', True),
307 999: framework_views.StuffUserView(999, 'z@z.com', True),
308 }
309 # Assert display names are obscured before the reveal.
310 self.assertEqual('a...@a.com', users_by_id[111].display_name)
311 self.assertEqual('b...@b.com', users_by_id[222].display_name)
312 self.assertEqual('c...@c.com', users_by_id[333].display_name)
313 self.assertEqual('z...@z.com', users_by_id[999].display_name)
314
315 framework_views.RevealAllEmails(users_by_id)
316
317 self.assertFalse(users_by_id[111].obscure_email)
318 self.assertFalse(users_by_id[222].obscure_email)
319 self.assertFalse(users_by_id[333].obscure_email)
320 self.assertFalse(users_by_id[999].obscure_email)
321 # Assert display names are now revealed.
322 self.assertEqual('a@a.com', users_by_id[111].display_name)
323 self.assertEqual('b@b.com', users_by_id[222].display_name)
324 self.assertEqual('c@c.com', users_by_id[333].display_name)
325 self.assertEqual('z@z.com', users_by_id[999].display_name)