blob: 48de180e2e97802ff7c9af589579799360ebadb9 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""Tests for the project_svc module."""
7from __future__ import print_function
8from __future__ import division
9from __future__ import absolute_import
10
11import 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
24from proto import project_pb2
25from proto import user_pb2
26from 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
82 self.assertItemsEqual([123, 234], list(project_dict.keys()))
83 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)
86 self.assertItemsEqual([111, 444], project_dict[123].owner_ids)
87 self.assertItemsEqual([222], project_dict[123].committer_ids)
88 self.assertItemsEqual([333], project_dict[123].contributor_ids)
89 self.assertEqual(234, project_dict[234].project_id)
90 self.assertItemsEqual([111], project_dict[234].owner_ids)
91 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()
281 self.assertItemsEqual([123, 234], list(project_dict.keys()))
282 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()
291 self.assertItemsEqual([234], list(project_dict.keys()))
292 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
300 def testGetVisibleLiveProjects_AnyoneAccessWithUser(self):
301 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')
314 project_ids = self.project_service.GetVisibleLiveProjects(
315 self.cnxn, user_a, set([111]))
316
317 self.mox.VerifyAll()
318 self.assertItemsEqual([234], project_ids)
319
320 def testGetVisibleLiveProjects_AnyoneAccessWithAnon(self):
321 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()
333 project_ids = self.project_service.GetVisibleLiveProjects(
334 self.cnxn, None, None)
335
336 self.mox.VerifyAll()
337 self.assertItemsEqual([234], project_ids)
338
339 def testGetVisibleLiveProjects_RestrictedAccessWithMember(self):
340 project_rows = [
341 (
342 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
343 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
344 False, False, None, None, None, None, None, None, False)
345 ]
346 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
347 self.proj2.contributor_ids.append(111)
348 self.project_service.project_2lc.CacheItem(234, self.proj2)
349
350 self.project_service.project_tbl.Select(
351 self.cnxn, cols=['project_id'],
352 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
353 self.mox.ReplayAll()
354 user_a = user_pb2.User(email='a@example.com')
355 project_ids = self.project_service.GetVisibleLiveProjects(
356 self.cnxn, user_a, set([111]))
357
358 self.mox.VerifyAll()
359 self.assertItemsEqual([234], project_ids)
360
361 def testGetVisibleLiveProjects_RestrictedAccessWithNonMember(self):
362 project_rows = [
363 (
364 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
365 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
366 False, None, None, None, None, None, None, False)
367 ]
368 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
369 self.project_service.project_2lc.CacheItem(234, self.proj2)
370
371 self.project_service.project_tbl.Select(
372 self.cnxn, cols=['project_id'],
373 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
374 self.mox.ReplayAll()
375 user_a = user_pb2.User(email='a@example.com')
376 project_ids = self.project_service.GetVisibleLiveProjects(
377 self.cnxn, user_a, set([111]))
378
379 self.mox.VerifyAll()
380 self.assertItemsEqual([], project_ids)
381
382 def testGetVisibleLiveProjects_RestrictedAccessWithAnon(self):
383 project_rows = [
384 (
385 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
386 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
387 False, None, None, None, None, None, None, False)
388 ]
389 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
390 self.project_service.project_2lc.CacheItem(234, self.proj2)
391
392 self.project_service.project_tbl.Select(
393 self.cnxn, cols=['project_id'],
394 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
395 self.mox.ReplayAll()
396 project_ids = self.project_service.GetVisibleLiveProjects(
397 self.cnxn, None, None)
398
399 self.mox.VerifyAll()
400 self.assertItemsEqual([], project_ids)
401
402 def testGetVisibleLiveProjects_RestrictedAccessWithSiteAdmin(self):
403 project_rows = [
404 (
405 234, 'proj2', 'test proj 2', 'test project', 'live', 'members_only',
406 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
407 False, None, None, None, None, None, None, False)
408 ]
409 self.proj2.access = project_pb2.ProjectAccess.MEMBERS_ONLY
410 self.project_service.project_2lc.CacheItem(234, self.proj2)
411
412 self.project_service.project_tbl.Select(
413 self.cnxn, cols=['project_id'],
414 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
415 self.mox.ReplayAll()
416 user_a = user_pb2.User(email='a@example.com')
417 user_a.is_site_admin = True
418 project_ids = self.project_service.GetVisibleLiveProjects(
419 self.cnxn, user_a, set([111]))
420
421 self.mox.VerifyAll()
422 self.assertItemsEqual([234], project_ids)
423
424 def testGetVisibleLiveProjects_ArchivedProject(self):
425 project_rows = [
426 (
427 234, 'proj2', 'test proj 2', 'test project', 'archived', 'anyone',
428 '', '', None, '', 0, 50 * 1024 * 1024, NOW, NOW, None, True, False,
429 False, None, None, None, None, None, None, False)
430 ]
431 self.proj2.state = project_pb2.ProjectState.ARCHIVED
432 self.project_service.project_2lc.CacheItem(234, self.proj2)
433
434 self.project_service.project_tbl.Select(
435 self.cnxn, cols=['project_id'],
436 state=project_pb2.ProjectState.LIVE).AndReturn(project_rows)
437 self.mox.ReplayAll()
438 user_a = user_pb2.User(email='a@example.com')
439 project_ids = self.project_service.GetVisibleLiveProjects(
440 self.cnxn, user_a, set([111]))
441
442 self.mox.VerifyAll()
443 self.assertItemsEqual([], project_ids)
444
445 def testGetProjectsByName(self):
446 self.project_service.project_names_to_ids.CacheItem('proj1', 123)
447 self.project_service.project_2lc.CacheItem(123, self.proj1)
448 self.SetUpLookupProjectIDs()
449 self.SetUpGetProjects()
450 self.mox.ReplayAll()
451 project_dict = self.project_service.GetProjectsByName(
452 self.cnxn, ['proj1', 'proj2'])
453 self.mox.VerifyAll()
454 self.assertItemsEqual(['proj1', 'proj2'], list(project_dict.keys()))
455 self.assertEqual(123, project_dict['proj1'].project_id)
456 self.assertEqual(234, project_dict['proj2'].project_id)
457
458 def SetUpExpungeProject(self):
459 self.project_service.user2project_tbl.Delete(
460 self.cnxn, project_id=234)
461 self.project_service.usergroupprojects_tbl.Delete(
462 self.cnxn, project_id=234)
463 self.project_service.extraperm_tbl.Delete(
464 self.cnxn, project_id=234)
465 self.project_service.membernotes_tbl.Delete(
466 self.cnxn, project_id=234)
467 self.project_service.acexclusion_tbl.Delete(
468 self.cnxn, project_id=234)
469 self.project_service.project_tbl.Delete(
470 self.cnxn, project_id=234)
471
472 def testExpungeProject(self):
473 self.SetUpExpungeProject()
474 self.mox.ReplayAll()
475 self.project_service.ExpungeProject(self.cnxn, 234)
476 self.mox.VerifyAll()
477
478 def SetUpUpdateProject(self, project_id, delta):
479 self.project_service.project_tbl.SelectValue(
480 self.cnxn, 'project_name', project_id=project_id).AndReturn('projN')
481 self.project_service.project_tbl.Update(
482 self.cnxn, delta, project_id=project_id, commit=False)
483 self.cnxn.Commit()
484
485 def testUpdateProject(self):
486 delta = {'summary': 'An even better one-line summary'}
487 self.SetUpUpdateProject(234, delta)
488 self.mox.ReplayAll()
489 self.project_service.UpdateProject(
490 self.cnxn, 234, summary='An even better one-line summary')
491 self.mox.VerifyAll()
492
493 def testUpdateProject_NotifyAlwaysDetailed(self):
494 delta = {'issue_notify_always_detailed': True}
495 self.SetUpUpdateProject(234, delta)
496 self.mox.ReplayAll()
497 self.project_service.UpdateProject(
498 self.cnxn, 234, issue_notify_always_detailed=True)
499 self.mox.VerifyAll()
500
501 def SetUpUpdateProjectRoles(
502 self, project_id, owner_ids, committer_ids, contributor_ids):
503 self.project_service.project_tbl.SelectValue(
504 self.cnxn, 'project_name', project_id=project_id).AndReturn('projN')
505 self.project_service.project_tbl.Update(
506 self.cnxn, {'cached_content_timestamp': NOW}, project_id=project_id,
507 commit=False)
508
509 self.project_service.user2project_tbl.Delete(
510 self.cnxn, project_id=project_id, role_name='owner', commit=False)
511 self.project_service.user2project_tbl.Delete(
512 self.cnxn, project_id=project_id, role_name='committer', commit=False)
513 self.project_service.user2project_tbl.Delete(
514 self.cnxn, project_id=project_id, role_name='contributor',
515 commit=False)
516
517 self.project_service.user2project_tbl.InsertRows(
518 self.cnxn, ['project_id', 'user_id', 'role_name'],
519 [(project_id, user_id, 'owner') for user_id in owner_ids],
520 commit=False)
521 self.project_service.user2project_tbl.InsertRows(
522 self.cnxn, ['project_id', 'user_id', 'role_name'],
523 [(project_id, user_id, 'committer') for user_id in committer_ids],
524 commit=False)
525 self.project_service.user2project_tbl.InsertRows(
526 self.cnxn, ['project_id', 'user_id', 'role_name'],
527 [(project_id, user_id, 'contributor') for user_id in contributor_ids],
528 commit=False)
529
530 self.cnxn.Commit()
531
532 def testUpdateProjectRoles(self):
533 self.SetUpUpdateProjectRoles(234, [111, 222], [333], [])
534 self.mox.ReplayAll()
535 self.project_service.UpdateProjectRoles(
536 self.cnxn, 234, [111, 222], [333], [], now=NOW)
537 self.mox.VerifyAll()
538
539 def SetUpMarkProjectDeletable(self):
540 delta = {
541 'project_name': 'DELETABLE_123',
542 'state': 'deletable',
543 }
544 self.project_service.project_tbl.Update(self.cnxn, delta, project_id=123)
545 self.config_service.InvalidateMemcacheForEntireProject(123)
546
547 def testMarkProjectDeletable(self):
548 self.SetUpMarkProjectDeletable()
549 self.mox.ReplayAll()
550 self.project_service.MarkProjectDeletable(
551 self.cnxn, 123, self.config_service)
552 self.mox.VerifyAll()
553
554 def testUpdateRecentActivity_SignificantlyLaterActivity(self):
555 activity_time = NOW + framework_constants.SECS_PER_HOUR * 3
556 delta = {'recent_activity_timestamp': activity_time}
557 self.SetUpGetProjects()
558 self.SetUpUpdateProject(234, delta)
559 self.mox.ReplayAll()
560 self.project_service.UpdateRecentActivity(self.cnxn, 234, now=activity_time)
561 self.mox.VerifyAll()
562
563 def testUpdateRecentActivity_NotSignificant(self):
564 activity_time = NOW + 123
565 self.SetUpGetProjects()
566 # ProjectUpdate is not called.
567 self.mox.ReplayAll()
568 self.project_service.UpdateRecentActivity(self.cnxn, 234, now=activity_time)
569 self.mox.VerifyAll()
570
571 def SetUpGetUserRolesInAllProjects(self):
572 rows = [
573 (123, 'committer'),
574 (234, 'owner'),
575 ]
576 self.project_service.user2project_tbl.Select(
577 self.cnxn, cols=['project_id', 'role_name'],
578 user_id={111, 888}).AndReturn(rows)
579
580 def testGetUserRolesInAllProjects(self):
581 self.SetUpGetUserRolesInAllProjects()
582 self.mox.ReplayAll()
583 actual = self.project_service.GetUserRolesInAllProjects(
584 self.cnxn, {111, 888})
585 owned_project_ids, membered_project_ids, contrib_project_ids = actual
586 self.mox.VerifyAll()
587 self.assertItemsEqual([234], owned_project_ids)
588 self.assertItemsEqual([123], membered_project_ids)
589 self.assertItemsEqual([], contrib_project_ids)
590
591 def testGetUserRolesInAllProjectsWithoutEffectiveIds(self):
592 self.mox.ReplayAll()
593 actual = self.project_service.GetUserRolesInAllProjects(self.cnxn, {})
594 owned_project_ids, membered_project_ids, contrib_project_ids = actual
595 self.mox.VerifyAll()
596 self.assertItemsEqual([], owned_project_ids)
597 self.assertItemsEqual([], membered_project_ids)
598 self.assertItemsEqual([], contrib_project_ids)
599
600 def SetUpUpdateExtraPerms(self):
601 self.project_service.extraperm_tbl.Delete(
602 self.cnxn, project_id=234, user_id=111, commit=False)
603 self.project_service.extraperm_tbl.InsertRows(
604 self.cnxn, project_svc.EXTRAPERM_COLS,
605 [(234, 111, 'SecurityTeam')], commit=False)
606 self.project_service.project_tbl.Update(
607 self.cnxn, {'cached_content_timestamp': NOW},
608 project_id=234, commit=False)
609 self.cnxn.Commit()
610
611 def testUpdateExtraPerms(self):
612 self.SetUpGetProjects(roles=[(234, 111, 'owner')])
613 self.SetUpUpdateExtraPerms()
614 self.mox.ReplayAll()
615 self.project_service.UpdateExtraPerms(
616 self.cnxn, 234, 111, ['SecurityTeam'], now=NOW)
617 self.mox.VerifyAll()
618
619 def testExpungeUsersInProjects(self):
620 self.project_service.extraperm_tbl.Delete = mock.Mock()
621 self.project_service.acexclusion_tbl.Delete = mock.Mock()
622 self.project_service.membernotes_tbl.Delete = mock.Mock()
623 self.project_service.user2project_tbl.Delete = mock.Mock()
624
625 user_ids = [111, 222]
626 limit= 16
627 self.project_service.ExpungeUsersInProjects(
628 self.cnxn, user_ids, limit=limit)
629
630 call = [mock.call(self.cnxn, user_id=user_ids, limit=limit, commit=False)]
631 self.project_service.extraperm_tbl.Delete.assert_has_calls(call)
632 self.project_service.acexclusion_tbl.Delete.assert_has_calls(call)
633 self.project_service.membernotes_tbl.Delete.assert_has_calls(call)
634 self.project_service.user2project_tbl.Delete.assert_has_calls(call)