Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: appengine/monorail/features/test/filterrules_helpers_test.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is govered 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 """Unit tests for filterrules_helpers feature."""
7
8 import unittest
9
10 import mox
11
12 from google.appengine.api import taskqueue
13
14 import settings
15 from features import filterrules_helpers
16 from framework import template_helpers
17 from framework import urls
18 from proto import ast_pb2
19 from proto import tracker_pb2
20 from search import query2ast
21 from services import service_manager
22 from testing import fake
23 from tracker import tracker_bizobj
24
25
26 ORIG_SUMMARY = 'this is the orginal summary'
27 ORIG_LABELS = ['one', 'two']
28
29 # Fake user id mapping
30 TEST_ID_MAP = {
31 'mike.j.parent': 1,
32 'jrobbins': 2,
33 'ningerso': 3,
34 }
35
36
37 class MockTaskQueue(object):
38 def __init__(self):
39 self.work_items = []
40
41 def add(self, **kwargs):
42 self.work_items.append(kwargs)
43
44
45 class RecomputeAllDerivedFieldsTest(unittest.TestCase):
46
47 BLOCK = filterrules_helpers.BLOCK
48
49 def setUp(self):
50 self.features = fake.FeaturesService()
51 self.user = fake.UserService()
52 self.services = service_manager.Services(
53 features=self.features,
54 user=self.user,
55 issue=fake.IssueService())
56 self.project = fake.Project(project_name='proj')
57 self.config = 'fake config'
58 self.cnxn = 'fake cnxn'
59 self.mox = mox.Mox()
60 self.mock_task_queue = MockTaskQueue()
61 self.mox.StubOutWithMock(taskqueue, 'add')
62
63 def tearDown(self):
64 self.mox.UnsetStubs()
65 self.mox.ResetAll()
66
67 def testRecomputeDerivedFields_Disabled(self):
68 """Servlet should just call RecomputeAllDerivedFieldsNow with no bounds."""
69 saved_flag = settings.recompute_derived_fields_in_worker
70 settings.recompute_derived_fields_in_worker = False
71 self.mox.ReplayAll()
72
73 filterrules_helpers.RecomputeAllDerivedFields(
74 self.cnxn, self.services, self.project, self.config)
75 self.assertTrue(self.services.issue.get_all_issues_in_project_called)
76 self.assertTrue(self.services.issue.update_issues_called)
77 self.assertTrue(self.services.issue.enqueue_issues_called)
78
79 self.mox.VerifyAll()
80 settings.recompute_derived_fields_in_worker = saved_flag
81
82 def testRecomputeDerivedFields_DisabledNextIDSet(self):
83 """Servlet should just call RecomputeAllDerivedFields with no bounds."""
84 saved_flag = settings.recompute_derived_fields_in_worker
85 settings.recompute_derived_fields_in_worker = False
86 self.services.issue.next_id = 1234
87 self.mox.ReplayAll()
88
89 filterrules_helpers.RecomputeAllDerivedFields(
90 self.cnxn, self.services, self.project, self.config)
91 self.services.issue.UpdateIssues('no', ['1'])
92 self.assertTrue(self.services.issue.get_all_issues_in_project_called)
93 self.assertTrue(self.services.issue.update_issues_called)
94 self.assertTrue(self.services.issue.enqueue_issues_called)
95
96 self.mox.VerifyAll()
97 settings.recompute_derived_fields_in_worker = saved_flag
98
99 def testRecomputeDerivedFields_NoIssues(self):
100 """Servlet should not call because there is no work to do."""
101 saved_flag = settings.recompute_derived_fields_in_worker
102 settings.recompute_derived_fields_in_worker = True
103 self.mox.ReplayAll()
104
105 filterrules_helpers.RecomputeAllDerivedFields(
106 self.cnxn, self.services, self.project, self.config)
107 self.assertFalse(self.services.issue.get_all_issues_in_project_called)
108 self.assertFalse(self.services.issue.update_issues_called)
109 self.assertFalse(self.services.issue.enqueue_issues_called)
110
111 self.mox.VerifyAll()
112 settings.recompute_derived_fields_in_worker = saved_flag
113
114 def testRecomputeDerivedFields_SomeIssues(self):
115 """Servlet should enqueue one work item rather than call directly."""
116 saved_flag = settings.recompute_derived_fields_in_worker
117 settings.recompute_derived_fields_in_worker = True
118 self.services.issue.next_id = 1234
119 num_calls = (self.services.issue.next_id // self.BLOCK + 1)
120 for _ in range(num_calls):
121 taskqueue.add(
122 params=mox.IsA(dict),
123 url='/_task/recomputeDerivedFields.do').WithSideEffects(
124 self.mock_task_queue.add)
125 self.mox.ReplayAll()
126
127 filterrules_helpers.RecomputeAllDerivedFields(
128 self.cnxn, self.services, self.project, self.config)
129 self.assertFalse(self.services.issue.get_all_issues_in_project_called)
130 self.assertFalse(self.services.issue.update_issues_called)
131 self.assertFalse(self.services.issue.enqueue_issues_called)
132 work_items = self.mock_task_queue.work_items
133 self.assertEqual(num_calls, len(work_items))
134
135 self.mox.VerifyAll()
136 settings.recompute_derived_fields_in_worker = saved_flag
137
138 def testRecomputeDerivedFields_LotsOfIssues(self):
139 """Servlet should enqueue multiple work items."""
140 saved_flag = settings.recompute_derived_fields_in_worker
141 settings.recompute_derived_fields_in_worker = True
142 self.services.issue.next_id = 12345
143 num_calls = (self.services.issue.next_id // self.BLOCK + 1)
144 for _ in range(num_calls):
145 taskqueue.add(
146 params=mox.IsA(dict),
147 url='/_task/recomputeDerivedFields.do').WithSideEffects(
148 self.mock_task_queue.add)
149 self.mox.ReplayAll()
150
151 filterrules_helpers.RecomputeAllDerivedFields(
152 self.cnxn, self.services, self.project, self.config)
153 self.assertFalse(self.services.issue.get_all_issues_in_project_called)
154 self.assertFalse(self.services.issue.update_issues_called)
155 self.assertFalse(self.services.issue.enqueue_issues_called)
156
157 work_items = self.mock_task_queue.work_items
158 self.assertEqual(num_calls, len(work_items))
159 url, params = work_items[0]['url'], work_items[0]['params']
160 self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
161 self.assertEqual(self.project.project_id, params['project_id'])
162 self.assertEqual(12345 // self.BLOCK * self.BLOCK + 1,
163 params['lower_bound'])
164 self.assertEqual(12345, params['upper_bound'])
165
166 url, params = work_items[-1]['url'], work_items[-1]['params']
167 self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
168 self.assertEqual(self.project.project_id, params['project_id'])
169 self.assertEqual(1, params['lower_bound'])
170 self.assertEqual(self.BLOCK + 1, params['upper_bound'])
171
172 self.mox.VerifyAll()
173 settings.recompute_derived_fields_in_worker = saved_flag
174
175 def testRecomputeAllDerivedFieldsNow(self):
176 """Servlet should reapply all filter rules to project's issues."""
177 self.services.issue.next_id = 12345
178 test_issue_1 = fake.MakeTestIssue(
179 project_id=self.project.project_id, local_id=1, issue_id=1001,
180 summary='sum1', owner_id=100, status='New')
181 test_issue_2 = fake.MakeTestIssue(
182 project_id=self.project.project_id, local_id=2, issue_id=1002,
183 summary='sum2', owner_id=100, status='New')
184 test_issues = [test_issue_1, test_issue_2]
185 self.services.issue.TestAddIssue(test_issue_1)
186 self.services.issue.TestAddIssue(test_issue_2)
187
188 self.mox.StubOutWithMock(filterrules_helpers, 'ApplyGivenRules')
189 for test_issue in test_issues:
190 filterrules_helpers.ApplyGivenRules(
191 self.cnxn, self.services, test_issue, self.config,
192 [], []).AndReturn(True)
193 self.mox.ReplayAll()
194
195 filterrules_helpers.RecomputeAllDerivedFieldsNow(
196 self.cnxn, self.services, self.project, self.config)
197
198 self.assertTrue(self.services.issue.get_all_issues_in_project_called)
199 self.assertTrue(self.services.issue.update_issues_called)
200 self.assertTrue(self.services.issue.enqueue_issues_called)
201 self.assertEqual(test_issues, self.services.issue.updated_issues)
202 self.assertEqual([issue.issue_id for issue in test_issues],
203 self.services.issue.enqueued_issues)
204 self.mox.VerifyAll()
205
206
207 class FilterRulesHelpersTest(unittest.TestCase):
208
209 def setUp(self):
210 self.cnxn = 'fake cnxn'
211 self.services = service_manager.Services()
212 self.services.user = fake.UserService()
213 self.services.project = fake.ProjectService()
214 self.services.issue = fake.IssueService()
215 self.project = self.services.project.TestAddProject('proj', project_id=789)
216 self.other_project = self.services.project.TestAddProject(
217 'otherproj', project_id=890)
218 for email, user_id in TEST_ID_MAP.iteritems():
219 self.services.user.TestAddUser(email, user_id)
220
221 def testApplyRule(self):
222 cnxn = 'fake sql connection'
223 issue = fake.MakeTestIssue(
224 789, 1, ORIG_SUMMARY, 'New', 111L, labels=ORIG_LABELS)
225 config = tracker_pb2.ProjectIssueConfig()
226 # Empty label set cannot satisfy rule looking for labels.
227 pred = 'label:a label:b'
228 rule = filterrules_helpers.MakeRule(
229 pred, default_owner_id=1, default_status='S')
230 predicate_ast = query2ast.ParseUserQuery(
231 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
232 self.assertEquals(
233 (None, None, [], [], []),
234 filterrules_helpers._ApplyRule(
235 cnxn, self.services, rule, predicate_ast, issue, set(), config))
236
237 pred = 'label:a -label:b'
238 rule = filterrules_helpers.MakeRule(
239 pred, default_owner_id=1, default_status='S')
240 predicate_ast = query2ast.ParseUserQuery(
241 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
242 self.assertEquals(
243 (None, None, [], [], []),
244 filterrules_helpers._ApplyRule(
245 cnxn, self.services, rule, predicate_ast, issue, set(), config))
246
247 # Empty label set will satisfy rule looking for missing labels.
248 pred = '-label:a -label:b'
249 rule = filterrules_helpers.MakeRule(
250 pred, default_owner_id=1, default_status='S')
251 predicate_ast = query2ast.ParseUserQuery(
252 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
253 self.assertEquals(
254 (1, 'S', [], [], []),
255 filterrules_helpers._ApplyRule(
256 cnxn, self.services, rule, predicate_ast, issue, set(), config))
257
258 # Label set has the needed labels.
259 pred = 'label:a label:b'
260 rule = filterrules_helpers.MakeRule(
261 pred, default_owner_id=1, default_status='S')
262 predicate_ast = query2ast.ParseUserQuery(
263 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
264 self.assertEquals(
265 (1, 'S', [], [], []),
266 filterrules_helpers._ApplyRule(
267 cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
268 config))
269
270 # Label set has the needed labels with test for unicode.
271 pred = 'label:a label:b'
272 rule = filterrules_helpers.MakeRule(
273 pred, default_owner_id=1, default_status='S')
274 predicate_ast = query2ast.ParseUserQuery(
275 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
276 self.assertEquals(
277 (1, 'S', [], [], []),
278 filterrules_helpers._ApplyRule(
279 cnxn, self.services, rule, predicate_ast, issue, {u'a', u'b'},
280 config))
281
282 # Label set has the needed labels, capitalization irrelevant.
283 pred = 'label:A label:B'
284 rule = filterrules_helpers.MakeRule(
285 pred, default_owner_id=1, default_status='S')
286 predicate_ast = query2ast.ParseUserQuery(
287 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
288 self.assertEquals(
289 (1, 'S', [], [], []),
290 filterrules_helpers._ApplyRule(
291 cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
292 config))
293
294 # Label set has a label, the rule negates.
295 pred = 'label:a -label:b'
296 rule = filterrules_helpers.MakeRule(
297 pred, default_owner_id=1, default_status='S')
298 predicate_ast = query2ast.ParseUserQuery(
299 pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
300 self.assertEquals(
301 (None, None, [], [], []),
302 filterrules_helpers._ApplyRule(
303 cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
304 config))
305
306 def testComputeDerivedFields(self):
307 cnxn = 'fake sql connection'
308 rules = [
309 filterrules_helpers.MakeRule(
310 'label:HasWorkaround', add_labels=['Priority-Low']),
311 filterrules_helpers.MakeRule(
312 'label:Security', add_labels=['Private']),
313 filterrules_helpers.MakeRule(
314 'label:Security', add_labels=['Priority-High'],
315 add_notify=['jrobbins@chromium.org']),
316 filterrules_helpers.MakeRule(
317 'Priority=High label:Regression', add_labels=['Urgent']),
318 filterrules_helpers.MakeRule(
319 'Size=L', default_owner_id=444L),
320 ]
321 excl_prefixes = ['priority', 'type', 'milestone']
322 config = tracker_pb2.ProjectIssueConfig(
323 exclusive_label_prefixes=excl_prefixes)
324 predicate_asts = filterrules_helpers.ParsePredicateASTs(rules, config, None)
325
326 # No rules fire.
327 issue = fake.MakeTestIssue(
328 789, 1, ORIG_SUMMARY, 'New', 0L, labels=ORIG_LABELS)
329 self.assertEquals(
330 (0, '', [], [], []),
331 filterrules_helpers._ComputeDerivedFields(
332 cnxn, self.services, issue, config, rules, predicate_asts))
333
334 issue = fake.MakeTestIssue(
335 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['foo', 'bar'])
336 self.assertEquals(
337 (0, '', [], [], []),
338 filterrules_helpers._ComputeDerivedFields(
339 cnxn, self.services, issue, config, rules, predicate_asts))
340
341 # One rule fires.
342 issue = fake.MakeTestIssue(
343 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['Size-L'])
344 self.assertEquals(
345 (444L, '', [], [], []),
346 filterrules_helpers._ComputeDerivedFields(
347 cnxn, self.services, issue, config, rules, predicate_asts))
348
349 # One rule fires, but no effect because of explicit fields.
350 issue = fake.MakeTestIssue(
351 789, 1, ORIG_SUMMARY, 'New', 0L,
352 labels=['HasWorkaround', 'Priority-Critical'])
353 self.assertEquals(
354 (0, '', [], [], []),
355 filterrules_helpers._ComputeDerivedFields(
356 cnxn, self.services, issue, config, rules, predicate_asts))
357
358 # One rule fires, but limited effect because of explicit exclusive label.
359 issue = fake.MakeTestIssue(
360 789, 1, ORIG_SUMMARY, 'New', 0L,
361 labels=['Security', 'Priority-Critical'])
362 self.assertEquals(
363 (0, '', [], ['Private'], ['jrobbins@chromium.org']),
364 filterrules_helpers._ComputeDerivedFields(
365 cnxn, self.services, issue, config, rules, predicate_asts))
366
367 # Multiple rules have cumulative effect.
368 issue = fake.MakeTestIssue(
369 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['HasWorkaround', 'Size-L'])
370 self.assertEquals(
371 (444L, '', [], ['Priority-Low'], []),
372 filterrules_helpers._ComputeDerivedFields(
373 cnxn, self.services, issue, config, rules, predicate_asts))
374
375 # Two rules fire, second overwrites the first.
376 issue = fake.MakeTestIssue(
377 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['HasWorkaround', 'Security'])
378 self.assertEquals(
379 (0, '', [], ['Private', 'Priority-High'], ['jrobbins@chromium.org']),
380 filterrules_helpers._ComputeDerivedFields(
381 cnxn, self.services, issue, config, rules, predicate_asts))
382
383 # Two rules fire, second triggered by the first.
384 issue = fake.MakeTestIssue(
385 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['Security', 'Regression'])
386 self.assertEquals(
387 (0, '', [], ['Private', 'Priority-High', 'Urgent'],
388 ['jrobbins@chromium.org']),
389 filterrules_helpers._ComputeDerivedFields(
390 cnxn, self.services, issue, config, rules, predicate_asts))
391
392 # Two rules fire, each one wants to add the same CC: only add once.
393 rules.append(filterrules_helpers.MakeRule('Watch', add_cc_ids=[111L]))
394 rules.append(filterrules_helpers.MakeRule('Monitor', add_cc_ids=[111L]))
395 config = tracker_pb2.ProjectIssueConfig(
396 exclusive_label_prefixes=excl_prefixes)
397 predicate_asts = filterrules_helpers.ParsePredicateASTs(rules, config, None)
398 issue = fake.MakeTestIssue(
399 789, 1, ORIG_SUMMARY, 'New', 111L, labels=['Watch', 'Monitor'])
400 self.assertEquals(
401 (0, '', [111L], [], []),
402 filterrules_helpers._ComputeDerivedFields(
403 cnxn, self.services, issue, config, rules, predicate_asts))
404
405 def testCompareComponents_Trivial(self):
406 config = tracker_pb2.ProjectIssueConfig()
407 self.assertTrue(filterrules_helpers._CompareComponents(
408 config, ast_pb2.QueryOp.IS_DEFINED, [], [123]))
409 self.assertFalse(filterrules_helpers._CompareComponents(
410 config, ast_pb2.QueryOp.IS_NOT_DEFINED, [], [123]))
411 self.assertFalse(filterrules_helpers._CompareComponents(
412 config, ast_pb2.QueryOp.IS_DEFINED, [], []))
413 self.assertTrue(filterrules_helpers._CompareComponents(
414 config, ast_pb2.QueryOp.IS_NOT_DEFINED, [], []))
415 self.assertFalse(filterrules_helpers._CompareComponents(
416 config, ast_pb2.QueryOp.EQ, [123], []))
417
418 def testCompareComponents_Normal(self):
419 config = tracker_pb2.ProjectIssueConfig()
420 config.component_defs.append(tracker_bizobj.MakeComponentDef(
421 100, 789, 'UI', 'doc', False, [], [], 0, 0))
422 config.component_defs.append(tracker_bizobj.MakeComponentDef(
423 110, 789, 'UI>Help', 'doc', False, [], [], 0, 0))
424 config.component_defs.append(tracker_bizobj.MakeComponentDef(
425 200, 789, 'Networking', 'doc', False, [], [], 0, 0))
426
427 # Check if the issue is in a specified component or subcomponent.
428 self.assertTrue(filterrules_helpers._CompareComponents(
429 config, ast_pb2.QueryOp.EQ, ['UI'], [100]))
430 self.assertTrue(filterrules_helpers._CompareComponents(
431 config, ast_pb2.QueryOp.EQ, ['UI>Help'], [110]))
432 self.assertTrue(filterrules_helpers._CompareComponents(
433 config, ast_pb2.QueryOp.EQ, ['UI'], [100, 110]))
434 self.assertFalse(filterrules_helpers._CompareComponents(
435 config, ast_pb2.QueryOp.EQ, ['UI'], []))
436 self.assertFalse(filterrules_helpers._CompareComponents(
437 config, ast_pb2.QueryOp.EQ, ['UI'], [110]))
438 self.assertFalse(filterrules_helpers._CompareComponents(
439 config, ast_pb2.QueryOp.EQ, ['UI'], [200]))
440 self.assertFalse(filterrules_helpers._CompareComponents(
441 config, ast_pb2.QueryOp.EQ, ['UI>Help'], [100]))
442 self.assertFalse(filterrules_helpers._CompareComponents(
443 config, ast_pb2.QueryOp.EQ, ['Networking'], [100]))
444
445 self.assertTrue(filterrules_helpers._CompareComponents(
446 config, ast_pb2.QueryOp.NE, ['UI'], []))
447 self.assertFalse(filterrules_helpers._CompareComponents(
448 config, ast_pb2.QueryOp.NE, ['UI'], [100]))
449 self.assertTrue(filterrules_helpers._CompareComponents(
450 config, ast_pb2.QueryOp.NE, ['Networking'], [100]))
451
452 # Exact vs non-exact.
453 self.assertFalse(filterrules_helpers._CompareComponents(
454 config, ast_pb2.QueryOp.EQ, ['Help'], [110]))
455 self.assertTrue(filterrules_helpers._CompareComponents(
456 config, ast_pb2.QueryOp.TEXT_HAS, ['UI'], [110]))
457 self.assertFalse(filterrules_helpers._CompareComponents(
458 config, ast_pb2.QueryOp.TEXT_HAS, ['Help'], [110]))
459 self.assertFalse(filterrules_helpers._CompareComponents(
460 config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['UI'], [110]))
461 self.assertTrue(filterrules_helpers._CompareComponents(
462 config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['Help'], [110]))
463
464 # Multivalued issues and Quick-OR notation
465 self.assertTrue(filterrules_helpers._CompareComponents(
466 config, ast_pb2.QueryOp.EQ, ['Networking'], [200]))
467 self.assertFalse(filterrules_helpers._CompareComponents(
468 config, ast_pb2.QueryOp.EQ, ['Networking'], [100, 110]))
469 self.assertTrue(filterrules_helpers._CompareComponents(
470 config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [100]))
471 self.assertFalse(filterrules_helpers._CompareComponents(
472 config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [110]))
473 self.assertTrue(filterrules_helpers._CompareComponents(
474 config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [200]))
475 self.assertTrue(filterrules_helpers._CompareComponents(
476 config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [110, 200]))
477 self.assertTrue(filterrules_helpers._CompareComponents(
478 config, ast_pb2.QueryOp.TEXT_HAS, ['UI', 'Networking'], [110, 200]))
479 self.assertTrue(filterrules_helpers._CompareComponents(
480 config, ast_pb2.QueryOp.EQ, ['UI>Help', 'Networking'], [110, 200]))
481
482 def testCompareIssueRefs_Trivial(self):
483 self.assertTrue(filterrules_helpers._CompareIssueRefs(
484 self.cnxn, self.services, self.project,
485 ast_pb2.QueryOp.IS_DEFINED, [], [123]))
486 self.assertFalse(filterrules_helpers._CompareIssueRefs(
487 self.cnxn, self.services, self.project,
488 ast_pb2.QueryOp.IS_NOT_DEFINED, [], [123]))
489 self.assertFalse(filterrules_helpers._CompareIssueRefs(
490 self.cnxn, self.services, self.project,
491 ast_pb2.QueryOp.IS_DEFINED, [], []))
492 self.assertTrue(filterrules_helpers._CompareIssueRefs(
493 self.cnxn, self.services, self.project,
494 ast_pb2.QueryOp.IS_NOT_DEFINED, [], []))
495 self.assertFalse(filterrules_helpers._CompareIssueRefs(
496 self.cnxn, self.services, self.project,
497 ast_pb2.QueryOp.EQ, ['1'], []))
498
499 def testCompareIssueRefs_Normal(self):
500 self.services.issue.TestAddIssue(fake.MakeTestIssue(
501 789, 1, 'summary', 'New', 0L, issue_id=123))
502 self.services.issue.TestAddIssue(fake.MakeTestIssue(
503 789, 2, 'summary', 'New', 0L, issue_id=124))
504 self.services.issue.TestAddIssue(fake.MakeTestIssue(
505 890, 1, 'other summary', 'New', 0L, issue_id=125))
506
507 # EQ and NE, implict references to the current project.
508 self.assertTrue(filterrules_helpers._CompareIssueRefs(
509 self.cnxn, self.services, self.project,
510 ast_pb2.QueryOp.EQ, ['1'], [123]))
511 self.assertFalse(filterrules_helpers._CompareIssueRefs(
512 self.cnxn, self.services, self.project,
513 ast_pb2.QueryOp.NE, ['1'], [123]))
514
515 # EQ and NE, explicit project references.
516 self.assertTrue(filterrules_helpers._CompareIssueRefs(
517 self.cnxn, self.services, self.project,
518 ast_pb2.QueryOp.EQ, ['proj:1'], [123]))
519 self.assertTrue(filterrules_helpers._CompareIssueRefs(
520 self.cnxn, self.services, self.project,
521 ast_pb2.QueryOp.EQ, ['otherproj:1'], [125]))
522
523 # Inequalities
524 self.assertTrue(filterrules_helpers._CompareIssueRefs(
525 self.cnxn, self.services, self.project,
526 ast_pb2.QueryOp.GE, ['1'], [123]))
527 self.assertTrue(filterrules_helpers._CompareIssueRefs(
528 self.cnxn, self.services, self.project,
529 ast_pb2.QueryOp.GE, ['1'], [124]))
530 self.assertTrue(filterrules_helpers._CompareIssueRefs(
531 self.cnxn, self.services, self.project,
532 ast_pb2.QueryOp.GE, ['2'], [124]))
533 self.assertFalse(filterrules_helpers._CompareIssueRefs(
534 self.cnxn, self.services, self.project,
535 ast_pb2.QueryOp.GT, ['2'], [124]))
536
537 def testCompareUsers(self):
538 pass # TODO(jrobbins): Add this test.
539
540 def testCompareUserIDs(self):
541 pass # TODO(jrobbins): Add this test.
542
543 def testCompareEmails(self):
544 pass # TODO(jrobbins): Add this test.
545
546 def testCompare(self):
547 pass # TODO(jrobbins): Add this test.
548
549 def testParseOneRuleAddLabels(self):
550 cnxn = 'fake SQL connection'
551 error_list = []
552 rule_pb = filterrules_helpers._ParseOneRule(
553 cnxn, 'label:lab1 label:lab2', 'add_labels', 'hot cOld, ', None, 1,
554 error_list)
555 self.assertEquals('label:lab1 label:lab2', rule_pb.predicate)
556 self.assertEquals(error_list, [])
557 self.assertEquals(len(rule_pb.add_labels), 2)
558 self.assertEquals(rule_pb.add_labels[0], 'hot')
559 self.assertEquals(rule_pb.add_labels[1], 'cOld')
560
561 rule_pb = filterrules_helpers._ParseOneRule(
562 cnxn, '', 'default_status', 'hot cold', None, 1, error_list)
563 self.assertEquals(len(rule_pb.predicate), 0)
564 self.assertEquals(error_list, [])
565
566 def testParseOneRuleDefaultOwner(self):
567 cnxn = 'fake SQL connection'
568 error_list = []
569 rule_pb = filterrules_helpers._ParseOneRule(
570 cnxn, 'label:lab1, label:lab2 ', 'default_owner', 'jrobbins',
571 self.services.user, 1, error_list)
572 self.assertEquals(error_list, [])
573 self.assertEquals(rule_pb.default_owner_id, TEST_ID_MAP['jrobbins'])
574
575 def testParseOneRuleDefaultStatus(self):
576 cnxn = 'fake SQL connection'
577 error_list = []
578 rule_pb = filterrules_helpers._ParseOneRule(
579 cnxn, 'label:lab1', 'default_status', 'InReview',
580 None, 1, error_list)
581 self.assertEquals(error_list, [])
582 self.assertEquals(rule_pb.default_status, 'InReview')
583
584 def testParseOneRuleAddCcs(self):
585 cnxn = 'fake SQL connection'
586 error_list = []
587 rule_pb = filterrules_helpers._ParseOneRule(
588 cnxn, 'label:lab1', 'add_ccs', 'jrobbins, mike.j.parent',
589 self.services.user, 1, error_list)
590 self.assertEquals(error_list, [])
591 self.assertEquals(rule_pb.add_cc_ids[0], TEST_ID_MAP['jrobbins'])
592 self.assertEquals(rule_pb.add_cc_ids[1], TEST_ID_MAP['mike.j.parent'])
593 self.assertEquals(len(rule_pb.add_cc_ids), 2)
594
595 def testParseRulesNone(self):
596 cnxn = 'fake SQL connection'
597 post_data = {}
598 rules = filterrules_helpers.ParseRules(
599 cnxn, post_data, None, template_helpers.EZTError())
600 self.assertEquals(rules, [])
601
602 def testParseRules(self):
603 cnxn = 'fake SQL connection'
604 post_data = {
605 'predicate1': 'a, b c',
606 'action_type1': 'default_status',
607 'action_value1': 'Reviewed',
608 'predicate2': 'a, b c',
609 'action_type2': 'default_owner',
610 'action_value2': 'jrobbins',
611 'predicate3': 'a, b c',
612 'action_type3': 'add_ccs',
613 'action_value3': 'jrobbins, mike.j.parent',
614 'predicate4': 'a, b c',
615 'action_type4': 'add_labels',
616 'action_value4': 'hot, cold',
617 }
618 errors = template_helpers.EZTError()
619 rules = filterrules_helpers.ParseRules(
620 cnxn, post_data, self.services.user, errors)
621 self.assertEquals(rules[0].predicate, 'a, b c')
622 self.assertEquals(rules[0].default_status, 'Reviewed')
623 self.assertEquals(rules[1].default_owner_id, TEST_ID_MAP['jrobbins'])
624 self.assertEquals(rules[2].add_cc_ids[0], TEST_ID_MAP['jrobbins'])
625 self.assertEquals(rules[2].add_cc_ids[1], TEST_ID_MAP['mike.j.parent'])
626 self.assertEquals(rules[3].add_labels[0], 'hot')
627 self.assertEquals(rules[3].add_labels[1], 'cold')
628 self.assertEquals(len(rules), 4)
629 self.assertFalse(errors.AnyErrors())
630
631
632 if __name__ == '__main__':
633 unittest.main()
OLDNEW
« no previous file with comments | « appengine/monorail/features/test/cues_test.py ('k') | appengine/monorail/features/test/filterrules_views_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698