blob: 3ada8eae776c6516142216d67c16650519c953cc [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"""Tests for the project_svc module."""
6from __future__ import print_function
7from __future__ import division
8from __future__ import absolute_import
9
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010010import six
Copybara854996b2021-09-07 19:36:02 +000011import time
12import unittest
13
Adrià Vilanova Martínez9f9ade52022-10-10 23:20:11 +020014try:
15 from mox3 import mox
16except ImportError:
17 import mox
Copybara854996b2021-09-07 19:36:02 +000018import mock
19
20from google.appengine.ext import testbed
21
22from framework import framework_constants
23from framework import sql
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010024from mrproto import project_pb2
25from mrproto import user_pb2
Copybara854996b2021-09-07 19:36:02 +000026from services import config_svc
27from services import project_svc
28from testing import fake
29
30NOW = 12345678
31
32
33def MakeProjectService(cache_manager, my_mox):
34 project_service = project_svc.ProjectService(cache_manager)
35 project_service.project_tbl = my_mox.CreateMock(sql.SQLTableManager)
36 project_service.user2project_tbl = my_mox.CreateMock(sql.SQLTableManager)
37 project_service.extraperm_tbl = my_mox.CreateMock(sql.SQLTableManager)
38 project_service.membernotes_tbl = my_mox.CreateMock(sql.SQLTableManager)
39 project_service.usergroupprojects_tbl = my_mox.CreateMock(
40 sql.SQLTableManager)
41 project_service.acexclusion_tbl = my_mox.CreateMock(
42 sql.SQLTableManager)
43 return project_service
44
45
46class ProjectTwoLevelCacheTest(unittest.TestCase):
47
48 def setUp(self):
49 self.testbed = testbed.Testbed()
50 self.testbed.activate()
51 self.testbed.init_memcache_stub()
52
53 self.mox = mox.Mox()
54 self.cnxn = self.mox.CreateMock(sql.MonorailConnection)
55 self.cache_manager = fake.CacheManager()
56 self.project_service = MakeProjectService(self.cache_manager, self.mox)
57
58 def tearDown(self):
59 self.testbed.deactivate()
60
61 def testDeserializeProjects(self):
62 project_rows = [
63 (
64 123, 'proj1', 'test proj 1', 'test project', 'live', 'anyone', '',
65 '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
66 False, None, None, None, None, None, None, False),
67 (
68 234, 'proj2', 'test proj 2', 'test project', 'live', 'anyone', '',
69 '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
70 False, None, None, None, None, None, None, True)
71 ]
72 role_rows = [
73 (123, 111, 'owner'), (123, 444, 'owner'),
74 (123, 222, 'committer'),
75 (123, 333, 'contributor'),
76 (234, 111, 'owner')]
77 extraperm_rows = []
78
79 project_dict = self.project_service.project_2lc._DeserializeProjects(
80 project_rows, role_rows, extraperm_rows)
81
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010082 six.assertCountEqual(self, [123, 234], list(project_dict.keys()))
Copybara854996b2021-09-07 19:36:02 +000083 self.assertEqual(123, project_dict[123].project_id)
84 self.assertEqual('proj1', project_dict[123].project_name)
85 self.assertEqual(NOW, project_dict[123].recent_activity)
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010086 six.assertCountEqual(self, [111, 444], project_dict[123].owner_ids)
87 six.assertCountEqual(self, [222], project_dict[123].committer_ids)
88 six.assertCountEqual(self, [333], project_dict[123].contributor_ids)
Copybara854996b2021-09-07 19:36:02 +000089 self.assertEqual(234, project_dict[234].project_id)
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +010090 six.assertCountEqual(self, [111], project_dict[234].owner_ids)
Copybara854996b2021-09-07 19:36:02 +000091 self.assertEqual(False, project_dict[123].issue_notify_always_detailed)
92 self.assertEqual(True, project_dict[234].issue_notify_always_detailed)
93
94
95class UserToProjectIdTwoLevelCacheTest(unittest.TestCase):
96
97 def setUp(self):
98 self.testbed = testbed.Testbed()
99 self.testbed.activate()
100 self.testbed.init_memcache_stub()
101
102 self.cnxn = fake.MonorailConnection()
103 self.cache_manager = fake.CacheManager()
104 self.mox = mox.Mox()
105 self.project_service = MakeProjectService(self.cache_manager, self.mox)
106 self.user_to_project_2lc = self.project_service.user_to_project_2lc
107
108 # Set up DB query mocks.
109 self.cached_user_ids = [100, 101]
110 self.from_db_user_ids = [102, 103]
111 test_table = [
112 (900, self.cached_user_ids[0]), # Project 900, User 100
113 (900, self.cached_user_ids[1]), # Project 900, User 101
114 (901, self.cached_user_ids[0]), # Project 901, User 101
115 (902, self.from_db_user_ids[0]), # Project 902, User 102
116 (902, self.from_db_user_ids[1]), # Project 902, User 103
117 (903, self.from_db_user_ids[0]), # Project 903, User 102
118 ]
119 self.project_service.user2project_tbl.Select = mock.Mock(
120 return_value=test_table)
121
122 def tearDown(self):
123 # memcache.flush_all()
124 self.testbed.deactivate()
125 self.mox.UnsetStubs()
126 self.mox.ResetAll()
127
128 def testGetAll(self):
129 # Cache user 100 and 101.
130 self.user_to_project_2lc.CacheItem(self.cached_user_ids[0], set([900, 901]))
131 self.user_to_project_2lc.CacheItem(self.cached_user_ids[1], set([900]))
132 # Test that other project_ids and user_ids get returned by DB queries.
133 first_hit, first_misses = self.user_to_project_2lc.GetAll(
134 self.cnxn, self.cached_user_ids + self.from_db_user_ids)
135
136 self.project_service.user2project_tbl.Select.assert_called_once_with(
137 self.cnxn, cols=['project_id', 'user_id'])
138
139 self.assertEqual(
140 first_hit, {
141 100: set([900, 901]),
142 101: set([900]),
143 102: set([902, 903]),
144 103: set([902]),
145 })
146 self.assertEqual([], first_misses)
147
148 def testGetAllRateLimit(self):
149 test_now = time.time()
150 # Initial request that queries table.
151 self.user_to_project_2lc._GetCurrentTime = mock.Mock(
152 return_value=test_now + 60)
153 self.user_to_project_2lc.GetAll(
154 self.cnxn, self.cached_user_ids + self.from_db_user_ids)
155
156 # Request a user with no projects right after the last request.
157 self.user_to_project_2lc._GetCurrentTime = mock.Mock(
158 return_value=test_now + 61)
159 second_hit, second_misses = self.user_to_project_2lc.GetAll(
160 self.cnxn, [104])
161
162 # Request one more user without project that should make a DB request
163 # because the required rate limit time has passed.
164 self.user_to_project_2lc._GetCurrentTime = mock.Mock(
165 return_value=test_now + 121)
166 third_hit, third_misses = self.user_to_project_2lc.GetAll(self.cnxn, [105])
167
168 # Queried only twice because the second request was rate limited.
169 self.assertEqual(self.project_service.user2project_tbl.Select.call_count, 2)
170
171 # Rate limited response will not return the full table.
172 self.assertEqual(second_hit, {
173 104: set([]),
174 })
175 self.assertEqual([], second_misses)
176 self.assertEqual(
177 third_hit, {
178 100: set([900, 901]),
179 101: set([900]),
180 102: set([902, 903]),
181 103: set([902]),
182 105: set([]),
183 })
184 self.assertEqual([], third_misses)
185
186
187class ProjectServiceTest(unittest.TestCase):
188
189 def setUp(self):
190 self.testbed = testbed.Testbed()
191 self.testbed.activate()
192 self.testbed.init_memcache_stub()
193
194 self.mox = mox.Mox()
195 self.cnxn = self.mox.CreateMock(sql.MonorailConnection)
196 self.cache_manager = fake.CacheManager()
197 self.config_service = self.mox.CreateMock(config_svc.ConfigService)
198 self.project_service = MakeProjectService(self.cache_manager, self.mox)
199
200 self.proj1 = fake.Project(project_name='proj1', project_id=123)
201 self.proj2 = fake.Project(project_name='proj2', project_id=234)
202
203 def tearDown(self):
204 self.testbed.deactivate()
205 self.mox.UnsetStubs()
206 self.mox.ResetAll()
207
208 def SetUpCreateProject(self):
209 # Check for existing project: there should be none.
210 self.project_service.project_tbl.Select(
211 self.cnxn, cols=['project_name', 'project_id'],
212 project_name=['proj1']).AndReturn([])
213
214 # Inserting the project gives the project ID.
215 self.project_service.project_tbl.InsertRow(
216 self.cnxn, project_name='proj1',
217 summary='Test project summary', description='Test project description',
218 home_page=None, docs_url=None, source_url=None,
219 logo_file_name=None, logo_gcs_id=None,
220 state='LIVE', access='ANYONE').AndReturn(123)
221
222 # Insert the users. There are none.
223 self.project_service.user2project_tbl.InsertRows(
224 self.cnxn, ['project_id', 'user_id', 'role_name'], [])
225
226 def testCreateProject(self):
227 self.SetUpCreateProject()
228 self.mox.ReplayAll()
229 self.project_service.CreateProject(
230 self.cnxn, 'proj1', owner_ids=[], committer_ids=[], contributor_ids=[],
231 summary='Test project summary', description='Test project description')
232 self.mox.VerifyAll()
233
234 def SetUpLookupProjectIDs(self):
235 self.project_service.project_tbl.Select(
236 self.cnxn, cols=['project_name', 'project_id'],
237 project_name=['proj2']).AndReturn([('proj2', 234)])
238
239 def testLookupProjectIDs(self):
240 self.SetUpLookupProjectIDs()
241 self.project_service.project_names_to_ids.CacheItem('proj1', 123)
242 self.mox.ReplayAll()
243 id_dict = self.project_service.LookupProjectIDs(
244 self.cnxn, ['proj1', 'proj2'])
245 self.mox.VerifyAll()
246 self.assertEqual({'proj1': 123, 'proj2': 234}, id_dict)
247
248 def testLookupProjectNames(self):
249 self.SetUpGetProjects() # Same as testGetProjects()
250 self.project_service.project_2lc.CacheItem(123, self.proj1)
251 self.mox.ReplayAll()
252 name_dict = self.project_service.LookupProjectNames(
253 self.cnxn, [123, 234])
254 self.mox.VerifyAll()
255 self.assertEqual({123: 'proj1', 234: 'proj2'}, name_dict)
256
257 def SetUpGetProjects(self, roles=None, extra_perms=None):
258 project_rows = [
259 (
260 234, 'proj2', 'test proj 2', 'test project', 'live', 'anyone', '',
261 '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
262 False, None, None, None, None, None, None, False)
263 ]
264 self.project_service.project_tbl.Select(
265 self.cnxn, cols=project_svc.PROJECT_COLS,
266 project_id=[234]).AndReturn(project_rows)
267 self.project_service.user2project_tbl.Select(
268 self.cnxn, cols=['project_id', 'user_id', 'role_name'],
269 project_id=[234]).AndReturn(roles or [])
270 self.project_service.extraperm_tbl.Select(
271 self.cnxn, cols=project_svc.EXTRAPERM_COLS,
272 project_id=[234]).AndReturn(extra_perms or [])
273
274 def testGetProjects(self):
275 self.project_service.project_2lc.CacheItem(123, self.proj1)
276 self.SetUpGetProjects()
277 self.mox.ReplayAll()
278 project_dict = self.project_service.GetProjects(
279 self.cnxn, [123, 234])
280 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100281 six.assertCountEqual(self, [123, 234], list(project_dict.keys()))
Copybara854996b2021-09-07 19:36:02 +0000282 self.assertEqual('proj1', project_dict[123].project_name)
283 self.assertEqual('proj2', project_dict[234].project_name)
284
285 def testGetProjects_ExtraPerms(self):
286 self.SetUpGetProjects(extra_perms=[(234, 222, 'BarPerm'),
287 (234, 111, 'FooPerm')])
288 self.mox.ReplayAll()
289 project_dict = self.project_service.GetProjects(self.cnxn, [234])
290 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100291 six.assertCountEqual(self, [234], list(project_dict.keys()))
Copybara854996b2021-09-07 19:36:02 +0000292 self.assertEqual(
293 [project_pb2.Project.ExtraPerms(
294 member_id=111, perms=['FooPerm']),
295 project_pb2.Project.ExtraPerms(
296 member_id=222, perms=['BarPerm'])],
297 project_dict[234].extra_perms)
298
299
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100300 def testGetVisibleProjects_AnyoneAccessWithUser(self):
Copybara854996b2021-09-07 19:36:02 +0000301 project_rows = [
302 (
303 234, 'proj2', 'test proj 2', 'test project', 'live', 'anyone', '',
304 '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
305 False, None, None, None, False)
306 ]
307
308 self.project_service.project_tbl.Select(
309 self.cnxn, cols=['project_id'],
310 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
311 self.SetUpGetProjects()
312 self.mox.ReplayAll()
313 user_a = user_pb2.User(email='a@example.com')
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100314 project_ids = self.project_service.GetVisibleProjects(
Copybara854996b2021-09-07 19:36:02 +0000315 self.cnxn, user_a, set([111]))
316
317 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100318 six.assertCountEqual(self, [234], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000319
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100320 def testGetVisibleProjects_AnyoneAccessWithAnon(self):
Copybara854996b2021-09-07 19:36:02 +0000321 project_rows = [
322 (
323 234, 'proj2', 'test proj 2', 'test project', 'live', 'anyone', '',
324 '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
325 False, None, None, None, None, None, None, False)
326 ]
327
328 self.project_service.project_tbl.Select(
329 self.cnxn, cols=['project_id'],
330 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
331 self.SetUpGetProjects()
332 self.mox.ReplayAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100333 project_ids = self.project_service.GetVisibleProjects(self.cnxn, None, None)
Copybara854996b2021-09-07 19:36:02 +0000334
335 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100336 six.assertCountEqual(self, [234], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000337
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100338 def testGetVisibleProjects_RestrictedAccessWithMember(self):
Copybara854996b2021-09-07 19:36:02 +0000339 project_rows = [
340 (
341 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
342 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
343 False, False, None, None, None, None, None, None, False)
344 ]
345 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
346 self.proj2.contributor_ids.append(111)
347 self.project_service.project_2lc.CacheItem(234, self.proj2)
348
349 self.project_service.project_tbl.Select(
350 self.cnxn, cols=['project_id'],
351 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
352 self.mox.ReplayAll()
353 user_a = user_pb2.User(email='a@example.com')
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100354 project_ids = self.project_service.GetVisibleProjects(
Copybara854996b2021-09-07 19:36:02 +0000355 self.cnxn, user_a, set([111]))
356
357 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100358 six.assertCountEqual(self, [234], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000359
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100360 def testGetVisibleProjects_RestrictedAccessWithNonMember(self):
Copybara854996b2021-09-07 19:36:02 +0000361 project_rows = [
362 (
363 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
364 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
365 False, None, None, None, None, None, None, False)
366 ]
367 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
368 self.project_service.project_2lc.CacheItem(234, self.proj2)
369
370 self.project_service.project_tbl.Select(
371 self.cnxn, cols=['project_id'],
372 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
373 self.mox.ReplayAll()
374 user_a = user_pb2.User(email='a@example.com')
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100375 project_ids = self.project_service.GetVisibleProjects(
Copybara854996b2021-09-07 19:36:02 +0000376 self.cnxn, user_a, set([111]))
377
378 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100379 six.assertCountEqual(self, [], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000380
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100381 def testGetVisibleProjects_RestrictedAccessWithAnon(self):
Copybara854996b2021-09-07 19:36:02 +0000382 project_rows = [
383 (
384 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
385 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
386 False, None, None, None, None, None, None, False)
387 ]
388 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
389 self.project_service.project_2lc.CacheItem(234, self.proj2)
390
391 self.project_service.project_tbl.Select(
392 self.cnxn, cols=['project_id'],
393 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
394 self.mox.ReplayAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100395 project_ids = self.project_service.GetVisibleProjects(self.cnxn, None, None)
Copybara854996b2021-09-07 19:36:02 +0000396
397 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100398 six.assertCountEqual(self, [], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000399
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100400 def testGetVisibleProjects_RestrictedAccessWithSiteAdmin(self):
Copybara854996b2021-09-07 19:36:02 +0000401 project_rows = [
402 (
403 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
404 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
405 False, None, None, None, None, None, None, False)
406 ]
407 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
408 self.project_service.project_2lc.CacheItem(234, self.proj2)
409
410 self.project_service.project_tbl.Select(
411 self.cnxn, cols=['project_id'],
412 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
413 self.mox.ReplayAll()
414 user_a = user_pb2.User(email='a@example.com')
415 user_a.is_site_admin = True
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100416 project_ids = self.project_service.GetVisibleProjects(
Copybara854996b2021-09-07 19:36:02 +0000417 self.cnxn, user_a, set([111]))
418
419 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100420 six.assertCountEqual(self, [234], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000421
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100422 def testGetVisibleProjects_ArchivedProject(self):
Copybara854996b2021-09-07 19:36:02 +0000423 project_rows = [
424 (
425 234, 'proj2', 'test proj 2', 'test project', 'archived', 'anyone',
426 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
427 False, None, None, None, None, None, None, False)
428 ]
429 self.proj2.state = project_pb2.ProjectState.ARCHIVED
430 self.project_service.project_2lc.CacheItem(234, self.proj2)
431
432 self.project_service.project_tbl.Select(
433 self.cnxn, cols=['project_id'],
434 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
435 self.mox.ReplayAll()
436 user_a = user_pb2.User(email='a@example.com')
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100437 project_ids = self.project_service.GetVisibleProjects(
Copybara854996b2021-09-07 19:36:02 +0000438 self.cnxn, user_a, set([111]))
439
440 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100441 six.assertCountEqual(self, [234], project_ids)
Copybara854996b2021-09-07 19:36:02 +0000442
443 def testGetProjectsByName(self):
444 self.project_service.project_names_to_ids.CacheItem('proj1', 123)
445 self.project_service.project_2lc.CacheItem(123, self.proj1)
446 self.SetUpLookupProjectIDs()
447 self.SetUpGetProjects()
448 self.mox.ReplayAll()
449 project_dict = self.project_service.GetProjectsByName(
450 self.cnxn, ['proj1', 'proj2'])
451 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100452 six.assertCountEqual(self, ['proj1', 'proj2'], list(project_dict.keys()))
Copybara854996b2021-09-07 19:36:02 +0000453 self.assertEqual(123, project_dict['proj1'].project_id)
454 self.assertEqual(234, project_dict['proj2'].project_id)
455
456 def SetUpExpungeProject(self):
457 self.project_service.user2project_tbl.Delete(
458 self.cnxn, project_id=234)
459 self.project_service.usergroupprojects_tbl.Delete(
460 self.cnxn, project_id=234)
461 self.project_service.extraperm_tbl.Delete(
462 self.cnxn, project_id=234)
463 self.project_service.membernotes_tbl.Delete(
464 self.cnxn, project_id=234)
465 self.project_service.acexclusion_tbl.Delete(
466 self.cnxn, project_id=234)
467 self.project_service.project_tbl.Delete(
468 self.cnxn, project_id=234)
469
470 def testExpungeProject(self):
471 self.SetUpExpungeProject()
472 self.mox.ReplayAll()
473 self.project_service.ExpungeProject(self.cnxn, 234)
474 self.mox.VerifyAll()
475
476 def SetUpUpdateProject(self, project_id, delta):
477 self.project_service.project_tbl.SelectValue(
478 self.cnxn, 'project_name', project_id=project_id).AndReturn('projN')
479 self.project_service.project_tbl.Update(
480 self.cnxn, delta, project_id=project_id, commit=False)
481 self.cnxn.Commit()
482
483 def testUpdateProject(self):
484 delta = {'summary': 'An even better one-line summary'}
485 self.SetUpUpdateProject(234, delta)
486 self.mox.ReplayAll()
487 self.project_service.UpdateProject(
488 self.cnxn, 234, summary='An even better one-line summary')
489 self.mox.VerifyAll()
490
491 def testUpdateProject_NotifyAlwaysDetailed(self):
492 delta = {'issue_notify_always_detailed': True}
493 self.SetUpUpdateProject(234, delta)
494 self.mox.ReplayAll()
495 self.project_service.UpdateProject(
496 self.cnxn, 234, issue_notify_always_detailed=True)
497 self.mox.VerifyAll()
498
499 def SetUpUpdateProjectRoles(
500 self, project_id, owner_ids, committer_ids, contributor_ids):
501 self.project_service.project_tbl.SelectValue(
502 self.cnxn, 'project_name', project_id=project_id).AndReturn('projN')
503 self.project_service.project_tbl.Update(
504 self.cnxn, {'cached_content_timestamp': NOW}, project_id=project_id,
505 commit=False)
506
507 self.project_service.user2project_tbl.Delete(
508 self.cnxn, project_id=project_id, role_name='owner', commit=False)
509 self.project_service.user2project_tbl.Delete(
510 self.cnxn, project_id=project_id, role_name='committer', commit=False)
511 self.project_service.user2project_tbl.Delete(
512 self.cnxn, project_id=project_id, role_name='contributor',
513 commit=False)
514
515 self.project_service.user2project_tbl.InsertRows(
516 self.cnxn, ['project_id', 'user_id', 'role_name'],
517 [(project_id, user_id, 'owner') for user_id in owner_ids],
518 commit=False)
519 self.project_service.user2project_tbl.InsertRows(
520 self.cnxn, ['project_id', 'user_id', 'role_name'],
521 [(project_id, user_id, 'committer') for user_id in committer_ids],
522 commit=False)
523 self.project_service.user2project_tbl.InsertRows(
524 self.cnxn, ['project_id', 'user_id', 'role_name'],
525 [(project_id, user_id, 'contributor') for user_id in contributor_ids],
526 commit=False)
527
528 self.cnxn.Commit()
529
530 def testUpdateProjectRoles(self):
531 self.SetUpUpdateProjectRoles(234, [111, 222], [333], [])
532 self.mox.ReplayAll()
533 self.project_service.UpdateProjectRoles(
534 self.cnxn, 234, [111, 222], [333], [], now=NOW)
535 self.mox.VerifyAll()
536
537 def SetUpMarkProjectDeletable(self):
538 delta = {
539 'project_name': 'DELETABLE_123',
540 'state': 'deletable',
541 }
542 self.project_service.project_tbl.Update(self.cnxn, delta, project_id=123)
543 self.config_service.InvalidateMemcacheForEntireProject(123)
544
545 def testMarkProjectDeletable(self):
546 self.SetUpMarkProjectDeletable()
547 self.mox.ReplayAll()
548 self.project_service.MarkProjectDeletable(
549 self.cnxn, 123, self.config_service)
550 self.mox.VerifyAll()
551
552 def testUpdateRecentActivity_SignificantlyLaterActivity(self):
553 activity_time = NOW + framework_constants.SECS_PER_HOUR * 3
554 delta = {'recent_activity_timestamp': activity_time}
555 self.SetUpGetProjects()
556 self.SetUpUpdateProject(234, delta)
557 self.mox.ReplayAll()
558 self.project_service.UpdateRecentActivity(self.cnxn, 234, now=activity_time)
559 self.mox.VerifyAll()
560
561 def testUpdateRecentActivity_NotSignificant(self):
562 activity_time = NOW + 123
563 self.SetUpGetProjects()
564 # ProjectUpdate is not called.
565 self.mox.ReplayAll()
566 self.project_service.UpdateRecentActivity(self.cnxn, 234, now=activity_time)
567 self.mox.VerifyAll()
568
569 def SetUpGetUserRolesInAllProjects(self):
570 rows = [
571 (123, 'committer'),
572 (234, 'owner'),
573 ]
574 self.project_service.user2project_tbl.Select(
575 self.cnxn, cols=['project_id', 'role_name'],
576 user_id={111, 888}).AndReturn(rows)
577
578 def testGetUserRolesInAllProjects(self):
579 self.SetUpGetUserRolesInAllProjects()
580 self.mox.ReplayAll()
581 actual = self.project_service.GetUserRolesInAllProjects(
582 self.cnxn, {111, 888})
583 owned_project_ids, membered_project_ids, contrib_project_ids = actual
584 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100585 six.assertCountEqual(self, [234], owned_project_ids)
586 six.assertCountEqual(self, [123], membered_project_ids)
587 six.assertCountEqual(self, [], contrib_project_ids)
Copybara854996b2021-09-07 19:36:02 +0000588
589 def testGetUserRolesInAllProjectsWithoutEffectiveIds(self):
590 self.mox.ReplayAll()
591 actual = self.project_service.GetUserRolesInAllProjects(self.cnxn, {})
592 owned_project_ids, membered_project_ids, contrib_project_ids = actual
593 self.mox.VerifyAll()
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +0100594 six.assertCountEqual(self, [], owned_project_ids)
595 six.assertCountEqual(self, [], membered_project_ids)
596 six.assertCountEqual(self, [], contrib_project_ids)
Copybara854996b2021-09-07 19:36:02 +0000597
598 def SetUpUpdateExtraPerms(self):
599 self.project_service.extraperm_tbl.Delete(
600 self.cnxn, project_id=234, user_id=111, commit=False)
601 self.project_service.extraperm_tbl.InsertRows(
602 self.cnxn, project_svc.EXTRAPERM_COLS,
603 [(234, 111, 'SecurityTeam')], commit=False)
604 self.project_service.project_tbl.Update(
605 self.cnxn, {'cached_content_timestamp': NOW},
606 project_id=234, commit=False)
607 self.cnxn.Commit()
608
609 def testUpdateExtraPerms(self):
610 self.SetUpGetProjects(roles=[(234, 111, 'owner')])
611 self.SetUpUpdateExtraPerms()
612 self.mox.ReplayAll()
613 self.project_service.UpdateExtraPerms(
614 self.cnxn, 234, 111, ['SecurityTeam'], now=NOW)
615 self.mox.VerifyAll()
616
617 def testExpungeUsersInProjects(self):
618 self.project_service.extraperm_tbl.Delete = mock.Mock()
619 self.project_service.acexclusion_tbl.Delete = mock.Mock()
620 self.project_service.membernotes_tbl.Delete = mock.Mock()
621 self.project_service.user2project_tbl.Delete = mock.Mock()
622
623 user_ids = [111, 222]
624 limit= 16
625 self.project_service.ExpungeUsersInProjects(
626 self.cnxn, user_ids, limit=limit)
627
628 call = [mock.call(self.cnxn, user_id=user_ids, limit=limit, commit=False)]
629 self.project_service.extraperm_tbl.Delete.assert_has_calls(call)
630 self.project_service.acexclusion_tbl.Delete.assert_has_calls(call)
631 self.project_service.membernotes_tbl.Delete.assert_has_calls(call)
632 self.project_service.user2project_tbl.Delete.assert_has_calls(call)