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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: appengine/monorail/features/test/filterrules_helpers_test.py
diff --git a/appengine/monorail/features/test/filterrules_helpers_test.py b/appengine/monorail/features/test/filterrules_helpers_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..8c481072d0dc49021bdb373366c1de11964a2a7b
--- /dev/null
+++ b/appengine/monorail/features/test/filterrules_helpers_test.py
@@ -0,0 +1,633 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Unit tests for filterrules_helpers feature."""
+
+import unittest
+
+import mox
+
+from google.appengine.api import taskqueue
+
+import settings
+from features import filterrules_helpers
+from framework import template_helpers
+from framework import urls
+from proto import ast_pb2
+from proto import tracker_pb2
+from search import query2ast
+from services import service_manager
+from testing import fake
+from tracker import tracker_bizobj
+
+
+ORIG_SUMMARY = 'this is the orginal summary'
+ORIG_LABELS = ['one', 'two']
+
+# Fake user id mapping
+TEST_ID_MAP = {
+ 'mike.j.parent': 1,
+ 'jrobbins': 2,
+ 'ningerso': 3,
+ }
+
+
+class MockTaskQueue(object):
+ def __init__(self):
+ self.work_items = []
+
+ def add(self, **kwargs):
+ self.work_items.append(kwargs)
+
+
+class RecomputeAllDerivedFieldsTest(unittest.TestCase):
+
+ BLOCK = filterrules_helpers.BLOCK
+
+ def setUp(self):
+ self.features = fake.FeaturesService()
+ self.user = fake.UserService()
+ self.services = service_manager.Services(
+ features=self.features,
+ user=self.user,
+ issue=fake.IssueService())
+ self.project = fake.Project(project_name='proj')
+ self.config = 'fake config'
+ self.cnxn = 'fake cnxn'
+ self.mox = mox.Mox()
+ self.mock_task_queue = MockTaskQueue()
+ self.mox.StubOutWithMock(taskqueue, 'add')
+
+ def tearDown(self):
+ self.mox.UnsetStubs()
+ self.mox.ResetAll()
+
+ def testRecomputeDerivedFields_Disabled(self):
+ """Servlet should just call RecomputeAllDerivedFieldsNow with no bounds."""
+ saved_flag = settings.recompute_derived_fields_in_worker
+ settings.recompute_derived_fields_in_worker = False
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFields(
+ self.cnxn, self.services, self.project, self.config)
+ self.assertTrue(self.services.issue.get_all_issues_in_project_called)
+ self.assertTrue(self.services.issue.update_issues_called)
+ self.assertTrue(self.services.issue.enqueue_issues_called)
+
+ self.mox.VerifyAll()
+ settings.recompute_derived_fields_in_worker = saved_flag
+
+ def testRecomputeDerivedFields_DisabledNextIDSet(self):
+ """Servlet should just call RecomputeAllDerivedFields with no bounds."""
+ saved_flag = settings.recompute_derived_fields_in_worker
+ settings.recompute_derived_fields_in_worker = False
+ self.services.issue.next_id = 1234
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFields(
+ self.cnxn, self.services, self.project, self.config)
+ self.services.issue.UpdateIssues('no', ['1'])
+ self.assertTrue(self.services.issue.get_all_issues_in_project_called)
+ self.assertTrue(self.services.issue.update_issues_called)
+ self.assertTrue(self.services.issue.enqueue_issues_called)
+
+ self.mox.VerifyAll()
+ settings.recompute_derived_fields_in_worker = saved_flag
+
+ def testRecomputeDerivedFields_NoIssues(self):
+ """Servlet should not call because there is no work to do."""
+ saved_flag = settings.recompute_derived_fields_in_worker
+ settings.recompute_derived_fields_in_worker = True
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFields(
+ self.cnxn, self.services, self.project, self.config)
+ self.assertFalse(self.services.issue.get_all_issues_in_project_called)
+ self.assertFalse(self.services.issue.update_issues_called)
+ self.assertFalse(self.services.issue.enqueue_issues_called)
+
+ self.mox.VerifyAll()
+ settings.recompute_derived_fields_in_worker = saved_flag
+
+ def testRecomputeDerivedFields_SomeIssues(self):
+ """Servlet should enqueue one work item rather than call directly."""
+ saved_flag = settings.recompute_derived_fields_in_worker
+ settings.recompute_derived_fields_in_worker = True
+ self.services.issue.next_id = 1234
+ num_calls = (self.services.issue.next_id // self.BLOCK + 1)
+ for _ in range(num_calls):
+ taskqueue.add(
+ params=mox.IsA(dict),
+ url='/_task/recomputeDerivedFields.do').WithSideEffects(
+ self.mock_task_queue.add)
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFields(
+ self.cnxn, self.services, self.project, self.config)
+ self.assertFalse(self.services.issue.get_all_issues_in_project_called)
+ self.assertFalse(self.services.issue.update_issues_called)
+ self.assertFalse(self.services.issue.enqueue_issues_called)
+ work_items = self.mock_task_queue.work_items
+ self.assertEqual(num_calls, len(work_items))
+
+ self.mox.VerifyAll()
+ settings.recompute_derived_fields_in_worker = saved_flag
+
+ def testRecomputeDerivedFields_LotsOfIssues(self):
+ """Servlet should enqueue multiple work items."""
+ saved_flag = settings.recompute_derived_fields_in_worker
+ settings.recompute_derived_fields_in_worker = True
+ self.services.issue.next_id = 12345
+ num_calls = (self.services.issue.next_id // self.BLOCK + 1)
+ for _ in range(num_calls):
+ taskqueue.add(
+ params=mox.IsA(dict),
+ url='/_task/recomputeDerivedFields.do').WithSideEffects(
+ self.mock_task_queue.add)
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFields(
+ self.cnxn, self.services, self.project, self.config)
+ self.assertFalse(self.services.issue.get_all_issues_in_project_called)
+ self.assertFalse(self.services.issue.update_issues_called)
+ self.assertFalse(self.services.issue.enqueue_issues_called)
+
+ work_items = self.mock_task_queue.work_items
+ self.assertEqual(num_calls, len(work_items))
+ url, params = work_items[0]['url'], work_items[0]['params']
+ self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
+ self.assertEqual(self.project.project_id, params['project_id'])
+ self.assertEqual(12345 // self.BLOCK * self.BLOCK + 1,
+ params['lower_bound'])
+ self.assertEqual(12345, params['upper_bound'])
+
+ url, params = work_items[-1]['url'], work_items[-1]['params']
+ self.assertEqual(urls.RECOMPUTE_DERIVED_FIELDS_TASK + '.do', url)
+ self.assertEqual(self.project.project_id, params['project_id'])
+ self.assertEqual(1, params['lower_bound'])
+ self.assertEqual(self.BLOCK + 1, params['upper_bound'])
+
+ self.mox.VerifyAll()
+ settings.recompute_derived_fields_in_worker = saved_flag
+
+ def testRecomputeAllDerivedFieldsNow(self):
+ """Servlet should reapply all filter rules to project's issues."""
+ self.services.issue.next_id = 12345
+ test_issue_1 = fake.MakeTestIssue(
+ project_id=self.project.project_id, local_id=1, issue_id=1001,
+ summary='sum1', owner_id=100, status='New')
+ test_issue_2 = fake.MakeTestIssue(
+ project_id=self.project.project_id, local_id=2, issue_id=1002,
+ summary='sum2', owner_id=100, status='New')
+ test_issues = [test_issue_1, test_issue_2]
+ self.services.issue.TestAddIssue(test_issue_1)
+ self.services.issue.TestAddIssue(test_issue_2)
+
+ self.mox.StubOutWithMock(filterrules_helpers, 'ApplyGivenRules')
+ for test_issue in test_issues:
+ filterrules_helpers.ApplyGivenRules(
+ self.cnxn, self.services, test_issue, self.config,
+ [], []).AndReturn(True)
+ self.mox.ReplayAll()
+
+ filterrules_helpers.RecomputeAllDerivedFieldsNow(
+ self.cnxn, self.services, self.project, self.config)
+
+ self.assertTrue(self.services.issue.get_all_issues_in_project_called)
+ self.assertTrue(self.services.issue.update_issues_called)
+ self.assertTrue(self.services.issue.enqueue_issues_called)
+ self.assertEqual(test_issues, self.services.issue.updated_issues)
+ self.assertEqual([issue.issue_id for issue in test_issues],
+ self.services.issue.enqueued_issues)
+ self.mox.VerifyAll()
+
+
+class FilterRulesHelpersTest(unittest.TestCase):
+
+ def setUp(self):
+ self.cnxn = 'fake cnxn'
+ self.services = service_manager.Services()
+ self.services.user = fake.UserService()
+ self.services.project = fake.ProjectService()
+ self.services.issue = fake.IssueService()
+ self.project = self.services.project.TestAddProject('proj', project_id=789)
+ self.other_project = self.services.project.TestAddProject(
+ 'otherproj', project_id=890)
+ for email, user_id in TEST_ID_MAP.iteritems():
+ self.services.user.TestAddUser(email, user_id)
+
+ def testApplyRule(self):
+ cnxn = 'fake sql connection'
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 111L, labels=ORIG_LABELS)
+ config = tracker_pb2.ProjectIssueConfig()
+ # Empty label set cannot satisfy rule looking for labels.
+ pred = 'label:a label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (None, None, [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, set(), config))
+
+ pred = 'label:a -label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (None, None, [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, set(), config))
+
+ # Empty label set will satisfy rule looking for missing labels.
+ pred = '-label:a -label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (1, 'S', [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, set(), config))
+
+ # Label set has the needed labels.
+ pred = 'label:a label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (1, 'S', [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
+ config))
+
+ # Label set has the needed labels with test for unicode.
+ pred = 'label:a label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (1, 'S', [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, {u'a', u'b'},
+ config))
+
+ # Label set has the needed labels, capitalization irrelevant.
+ pred = 'label:A label:B'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (1, 'S', [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
+ config))
+
+ # Label set has a label, the rule negates.
+ pred = 'label:a -label:b'
+ rule = filterrules_helpers.MakeRule(
+ pred, default_owner_id=1, default_status='S')
+ predicate_ast = query2ast.ParseUserQuery(
+ pred, '', query2ast.BUILTIN_ISSUE_FIELDS, config)
+ self.assertEquals(
+ (None, None, [], [], []),
+ filterrules_helpers._ApplyRule(
+ cnxn, self.services, rule, predicate_ast, issue, {'a', 'b'},
+ config))
+
+ def testComputeDerivedFields(self):
+ cnxn = 'fake sql connection'
+ rules = [
+ filterrules_helpers.MakeRule(
+ 'label:HasWorkaround', add_labels=['Priority-Low']),
+ filterrules_helpers.MakeRule(
+ 'label:Security', add_labels=['Private']),
+ filterrules_helpers.MakeRule(
+ 'label:Security', add_labels=['Priority-High'],
+ add_notify=['jrobbins@chromium.org']),
+ filterrules_helpers.MakeRule(
+ 'Priority=High label:Regression', add_labels=['Urgent']),
+ filterrules_helpers.MakeRule(
+ 'Size=L', default_owner_id=444L),
+ ]
+ excl_prefixes = ['priority', 'type', 'milestone']
+ config = tracker_pb2.ProjectIssueConfig(
+ exclusive_label_prefixes=excl_prefixes)
+ predicate_asts = filterrules_helpers.ParsePredicateASTs(rules, config, None)
+
+ # No rules fire.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=ORIG_LABELS)
+ self.assertEquals(
+ (0, '', [], [], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['foo', 'bar'])
+ self.assertEquals(
+ (0, '', [], [], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # One rule fires.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['Size-L'])
+ self.assertEquals(
+ (444L, '', [], [], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # One rule fires, but no effect because of explicit fields.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L,
+ labels=['HasWorkaround', 'Priority-Critical'])
+ self.assertEquals(
+ (0, '', [], [], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # One rule fires, but limited effect because of explicit exclusive label.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L,
+ labels=['Security', 'Priority-Critical'])
+ self.assertEquals(
+ (0, '', [], ['Private'], ['jrobbins@chromium.org']),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # Multiple rules have cumulative effect.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['HasWorkaround', 'Size-L'])
+ self.assertEquals(
+ (444L, '', [], ['Priority-Low'], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # Two rules fire, second overwrites the first.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['HasWorkaround', 'Security'])
+ self.assertEquals(
+ (0, '', [], ['Private', 'Priority-High'], ['jrobbins@chromium.org']),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # Two rules fire, second triggered by the first.
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 0L, labels=['Security', 'Regression'])
+ self.assertEquals(
+ (0, '', [], ['Private', 'Priority-High', 'Urgent'],
+ ['jrobbins@chromium.org']),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ # Two rules fire, each one wants to add the same CC: only add once.
+ rules.append(filterrules_helpers.MakeRule('Watch', add_cc_ids=[111L]))
+ rules.append(filterrules_helpers.MakeRule('Monitor', add_cc_ids=[111L]))
+ config = tracker_pb2.ProjectIssueConfig(
+ exclusive_label_prefixes=excl_prefixes)
+ predicate_asts = filterrules_helpers.ParsePredicateASTs(rules, config, None)
+ issue = fake.MakeTestIssue(
+ 789, 1, ORIG_SUMMARY, 'New', 111L, labels=['Watch', 'Monitor'])
+ self.assertEquals(
+ (0, '', [111L], [], []),
+ filterrules_helpers._ComputeDerivedFields(
+ cnxn, self.services, issue, config, rules, predicate_asts))
+
+ def testCompareComponents_Trivial(self):
+ config = tracker_pb2.ProjectIssueConfig()
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.IS_DEFINED, [], [123]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.IS_NOT_DEFINED, [], [123]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.IS_DEFINED, [], []))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.IS_NOT_DEFINED, [], []))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, [123], []))
+
+ def testCompareComponents_Normal(self):
+ config = tracker_pb2.ProjectIssueConfig()
+ config.component_defs.append(tracker_bizobj.MakeComponentDef(
+ 100, 789, 'UI', 'doc', False, [], [], 0, 0))
+ config.component_defs.append(tracker_bizobj.MakeComponentDef(
+ 110, 789, 'UI>Help', 'doc', False, [], [], 0, 0))
+ config.component_defs.append(tracker_bizobj.MakeComponentDef(
+ 200, 789, 'Networking', 'doc', False, [], [], 0, 0))
+
+ # Check if the issue is in a specified component or subcomponent.
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI'], [100]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI>Help'], [110]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI'], [100, 110]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI'], []))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI'], [110]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI'], [200]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI>Help'], [100]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['Networking'], [100]))
+
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.NE, ['UI'], []))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.NE, ['UI'], [100]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.NE, ['Networking'], [100]))
+
+ # Exact vs non-exact.
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['Help'], [110]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.TEXT_HAS, ['UI'], [110]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.TEXT_HAS, ['Help'], [110]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['UI'], [110]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.NOT_TEXT_HAS, ['Help'], [110]))
+
+ # Multivalued issues and Quick-OR notation
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['Networking'], [200]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['Networking'], [100, 110]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [100]))
+ self.assertFalse(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [110]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [200]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI', 'Networking'], [110, 200]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.TEXT_HAS, ['UI', 'Networking'], [110, 200]))
+ self.assertTrue(filterrules_helpers._CompareComponents(
+ config, ast_pb2.QueryOp.EQ, ['UI>Help', 'Networking'], [110, 200]))
+
+ def testCompareIssueRefs_Trivial(self):
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.IS_DEFINED, [], [123]))
+ self.assertFalse(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.IS_NOT_DEFINED, [], [123]))
+ self.assertFalse(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.IS_DEFINED, [], []))
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.IS_NOT_DEFINED, [], []))
+ self.assertFalse(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.EQ, ['1'], []))
+
+ def testCompareIssueRefs_Normal(self):
+ self.services.issue.TestAddIssue(fake.MakeTestIssue(
+ 789, 1, 'summary', 'New', 0L, issue_id=123))
+ self.services.issue.TestAddIssue(fake.MakeTestIssue(
+ 789, 2, 'summary', 'New', 0L, issue_id=124))
+ self.services.issue.TestAddIssue(fake.MakeTestIssue(
+ 890, 1, 'other summary', 'New', 0L, issue_id=125))
+
+ # EQ and NE, implict references to the current project.
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.EQ, ['1'], [123]))
+ self.assertFalse(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.NE, ['1'], [123]))
+
+ # EQ and NE, explicit project references.
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.EQ, ['proj:1'], [123]))
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.EQ, ['otherproj:1'], [125]))
+
+ # Inequalities
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.GE, ['1'], [123]))
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.GE, ['1'], [124]))
+ self.assertTrue(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.GE, ['2'], [124]))
+ self.assertFalse(filterrules_helpers._CompareIssueRefs(
+ self.cnxn, self.services, self.project,
+ ast_pb2.QueryOp.GT, ['2'], [124]))
+
+ def testCompareUsers(self):
+ pass # TODO(jrobbins): Add this test.
+
+ def testCompareUserIDs(self):
+ pass # TODO(jrobbins): Add this test.
+
+ def testCompareEmails(self):
+ pass # TODO(jrobbins): Add this test.
+
+ def testCompare(self):
+ pass # TODO(jrobbins): Add this test.
+
+ def testParseOneRuleAddLabels(self):
+ cnxn = 'fake SQL connection'
+ error_list = []
+ rule_pb = filterrules_helpers._ParseOneRule(
+ cnxn, 'label:lab1 label:lab2', 'add_labels', 'hot cOld, ', None, 1,
+ error_list)
+ self.assertEquals('label:lab1 label:lab2', rule_pb.predicate)
+ self.assertEquals(error_list, [])
+ self.assertEquals(len(rule_pb.add_labels), 2)
+ self.assertEquals(rule_pb.add_labels[0], 'hot')
+ self.assertEquals(rule_pb.add_labels[1], 'cOld')
+
+ rule_pb = filterrules_helpers._ParseOneRule(
+ cnxn, '', 'default_status', 'hot cold', None, 1, error_list)
+ self.assertEquals(len(rule_pb.predicate), 0)
+ self.assertEquals(error_list, [])
+
+ def testParseOneRuleDefaultOwner(self):
+ cnxn = 'fake SQL connection'
+ error_list = []
+ rule_pb = filterrules_helpers._ParseOneRule(
+ cnxn, 'label:lab1, label:lab2 ', 'default_owner', 'jrobbins',
+ self.services.user, 1, error_list)
+ self.assertEquals(error_list, [])
+ self.assertEquals(rule_pb.default_owner_id, TEST_ID_MAP['jrobbins'])
+
+ def testParseOneRuleDefaultStatus(self):
+ cnxn = 'fake SQL connection'
+ error_list = []
+ rule_pb = filterrules_helpers._ParseOneRule(
+ cnxn, 'label:lab1', 'default_status', 'InReview',
+ None, 1, error_list)
+ self.assertEquals(error_list, [])
+ self.assertEquals(rule_pb.default_status, 'InReview')
+
+ def testParseOneRuleAddCcs(self):
+ cnxn = 'fake SQL connection'
+ error_list = []
+ rule_pb = filterrules_helpers._ParseOneRule(
+ cnxn, 'label:lab1', 'add_ccs', 'jrobbins, mike.j.parent',
+ self.services.user, 1, error_list)
+ self.assertEquals(error_list, [])
+ self.assertEquals(rule_pb.add_cc_ids[0], TEST_ID_MAP['jrobbins'])
+ self.assertEquals(rule_pb.add_cc_ids[1], TEST_ID_MAP['mike.j.parent'])
+ self.assertEquals(len(rule_pb.add_cc_ids), 2)
+
+ def testParseRulesNone(self):
+ cnxn = 'fake SQL connection'
+ post_data = {}
+ rules = filterrules_helpers.ParseRules(
+ cnxn, post_data, None, template_helpers.EZTError())
+ self.assertEquals(rules, [])
+
+ def testParseRules(self):
+ cnxn = 'fake SQL connection'
+ post_data = {
+ 'predicate1': 'a, b c',
+ 'action_type1': 'default_status',
+ 'action_value1': 'Reviewed',
+ 'predicate2': 'a, b c',
+ 'action_type2': 'default_owner',
+ 'action_value2': 'jrobbins',
+ 'predicate3': 'a, b c',
+ 'action_type3': 'add_ccs',
+ 'action_value3': 'jrobbins, mike.j.parent',
+ 'predicate4': 'a, b c',
+ 'action_type4': 'add_labels',
+ 'action_value4': 'hot, cold',
+ }
+ errors = template_helpers.EZTError()
+ rules = filterrules_helpers.ParseRules(
+ cnxn, post_data, self.services.user, errors)
+ self.assertEquals(rules[0].predicate, 'a, b c')
+ self.assertEquals(rules[0].default_status, 'Reviewed')
+ self.assertEquals(rules[1].default_owner_id, TEST_ID_MAP['jrobbins'])
+ self.assertEquals(rules[2].add_cc_ids[0], TEST_ID_MAP['jrobbins'])
+ self.assertEquals(rules[2].add_cc_ids[1], TEST_ID_MAP['mike.j.parent'])
+ self.assertEquals(rules[3].add_labels[0], 'hot')
+ self.assertEquals(rules[3].add_labels[1], 'cold')
+ self.assertEquals(len(rules), 4)
+ self.assertFalse(errors.AnyErrors())
+
+
+if __name__ == '__main__':
+ unittest.main()
« 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