Index: appengine/monorail/services/test/features_svc_test.py |
diff --git a/appengine/monorail/services/test/features_svc_test.py b/appengine/monorail/services/test/features_svc_test.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..03909694b1dcdb5129d13f12c5fdbfe8b1662140 |
--- /dev/null |
+++ b/appengine/monorail/services/test/features_svc_test.py |
@@ -0,0 +1,340 @@ |
+# 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 features_svc module.""" |
+ |
+import unittest |
+ |
+import mox |
+ |
+from features import filterrules_helpers |
+from framework import sql |
+from services import features_svc |
+from testing import fake |
+from tracker import tracker_bizobj |
+from tracker import tracker_constants |
+ |
+ |
+class FeaturesServiceTest(unittest.TestCase): |
+ |
+ def MakeMockTable(self): |
+ return self.mox.CreateMock(sql.SQLTableManager) |
+ |
+ def setUp(self): |
+ self.mox = mox.Mox() |
+ self.cnxn = self.mox.CreateMock(sql.MonorailConnection) |
+ self.cache_manager = fake.CacheManager() |
+ |
+ self.features_service = features_svc.FeaturesService(self.cache_manager) |
+ |
+ for table_var in [ |
+ 'user2savedquery_tbl', 'quickedithistory_tbl', |
+ 'quickeditmostrecent_tbl', 'savedquery_tbl', |
+ 'savedqueryexecutesinproject_tbl', 'project2savedquery_tbl', |
+ 'filterrule_tbl']: |
+ setattr(self.features_service, table_var, self.MakeMockTable()) |
+ |
+ def tearDown(self): |
+ self.mox.UnsetStubs() |
+ self.mox.ResetAll() |
+ |
+ ### quickedit command history |
+ |
+ def testGetRecentCommands(self): |
+ self.features_service.quickedithistory_tbl.Select( |
+ self.cnxn, cols=['slot_num', 'command', 'comment'], |
+ user_id=1, project_id=12345).AndReturn( |
+ [(1, 'status=New', 'Brand new issue')]) |
+ self.features_service.quickeditmostrecent_tbl.SelectValue( |
+ self.cnxn, 'slot_num', default=1, user_id=1, project_id=12345 |
+ ).AndReturn(1) |
+ self.mox.ReplayAll() |
+ slots, recent_slot_num = self.features_service.GetRecentCommands( |
+ self.cnxn, 1, 12345) |
+ self.mox.VerifyAll() |
+ |
+ self.assertEqual(1, recent_slot_num) |
+ self.assertEqual( |
+ len(tracker_constants.DEFAULT_RECENT_COMMANDS), len(slots)) |
+ self.assertEqual('status=New', slots[0][1]) |
+ |
+ def testStoreRecentCommand(self): |
+ self.features_service.quickedithistory_tbl.InsertRow( |
+ self.cnxn, replace=True, user_id=1, project_id=12345, |
+ slot_num=1, command='status=New', comment='Brand new issue') |
+ self.features_service.quickeditmostrecent_tbl.InsertRow( |
+ self.cnxn, replace=True, user_id=1, project_id=12345, |
+ slot_num=1) |
+ self.mox.ReplayAll() |
+ self.features_service.StoreRecentCommand( |
+ self.cnxn, 1, 12345, 1, 'status=New', 'Brand new issue') |
+ self.mox.VerifyAll() |
+ |
+ def testExpungeQuickEditHistory(self): |
+ self.features_service.quickeditmostrecent_tbl.Delete( |
+ self.cnxn, project_id=12345) |
+ self.features_service.quickedithistory_tbl.Delete( |
+ self.cnxn, project_id=12345) |
+ self.mox.ReplayAll() |
+ self.features_service.ExpungeQuickEditHistory( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ |
+ ### Saved User and Project Queries |
+ |
+ def testGetSavedQuery(self): |
+ self.features_service.savedquery_tbl.Select( |
+ self.cnxn, cols=features_svc.SAVEDQUERY_COLS, id=[1]).AndReturn( |
+ [(1, 'query1', 100, 'owner:me')]) |
+ self.features_service.savedqueryexecutesinproject_tbl.Select( |
+ self.cnxn, cols=features_svc.SAVEDQUERYEXECUTESINPROJECT_COLS, |
+ query_id=[1]).AndReturn([(1, 12345)]) |
+ self.mox.ReplayAll() |
+ saved_query = self.features_service.GetSavedQuery( |
+ self.cnxn, 1) |
+ self.mox.VerifyAll() |
+ self.assertEqual(1, saved_query.query_id) |
+ self.assertEqual('query1', saved_query.name) |
+ self.assertEqual(100, saved_query.base_query_id) |
+ self.assertEqual('owner:me', saved_query.query) |
+ self.assertEqual([12345], saved_query.executes_in_project_ids) |
+ |
+ def SetUpUsersSavedQueries(self): |
+ query = tracker_bizobj.MakeSavedQuery(1, 'query1', 100, 'owner:me') |
+ self.features_service.saved_query_cache.CacheItem(1, [query]) |
+ self.features_service.user2savedquery_tbl.Select( |
+ self.cnxn, |
+ cols=features_svc.SAVEDQUERY_COLS + ['user_id', 'subscription_mode'], |
+ left_joins=[('SavedQuery ON query_id = id', [])], |
+ order_by=[('rank', [])], user_id=[2]).AndReturn( |
+ [(2, 'query2', 100, 'status:New', 2, 'Sub_Mode')]) |
+ self.features_service.savedqueryexecutesinproject_tbl.Select( |
+ self.cnxn, cols=features_svc.SAVEDQUERYEXECUTESINPROJECT_COLS, |
+ query_id=set([2])).AndReturn([(2, 12345)]) |
+ |
+ def testGetUsersSavedQueriesDict(self): |
+ self.SetUpUsersSavedQueries() |
+ self.mox.ReplayAll() |
+ results_dict = self.features_service._GetUsersSavedQueriesDict( |
+ self.cnxn, [1, 2]) |
+ self.mox.VerifyAll() |
+ self.assertIn(1, results_dict) |
+ self.assertIn(2, results_dict) |
+ |
+ def testGetSavedQueriesByUserID(self): |
+ self.SetUpUsersSavedQueries() |
+ self.mox.ReplayAll() |
+ saved_queries = self.features_service.GetSavedQueriesByUserID( |
+ self.cnxn, 2) |
+ self.mox.VerifyAll() |
+ self.assertEqual(1, len(saved_queries)) |
+ self.assertEqual(2, saved_queries[0].query_id) |
+ |
+ def SetUpCannedQueriesForProjects(self): |
+ self.features_service.project2savedquery_tbl.Select( |
+ self.cnxn, cols=['project_id'] + features_svc.SAVEDQUERY_COLS, |
+ left_joins=[('SavedQuery ON query_id = id', [])], |
+ order_by=[('rank', [])], project_id=[12345]).AndReturn( |
+ [(12345, 1, 'query1', 100, 'owner:me')]) |
+ |
+ def testGetCannedQueriesForProjects(self): |
+ self.SetUpCannedQueriesForProjects() |
+ self.mox.ReplayAll() |
+ results_dict = self.features_service.GetCannedQueriesForProjects( |
+ self.cnxn, [12345]) |
+ self.mox.VerifyAll() |
+ self.assertIn(12345, results_dict) |
+ |
+ def testGetCannedQueriesByProjectID(self): |
+ self.SetUpCannedQueriesForProjects() |
+ self.mox.ReplayAll() |
+ result = self.features_service.GetCannedQueriesByProjectID( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ self.assertEqual(1, len(result)) |
+ self.assertEqual(1, result[0].query_id) |
+ |
+ def SetUpUpdateSavedQueries(self, commit=True): |
+ query1 = tracker_bizobj.MakeSavedQuery(1, 'query1', 100, 'owner:me') |
+ query2 = tracker_bizobj.MakeSavedQuery(None, 'query2', 100, 'status:New') |
+ saved_queries = [query1, query2] |
+ savedquery_rows = [ |
+ (sq.query_id or None, sq.name, sq.base_query_id, sq.query) |
+ for sq in saved_queries] |
+ self.features_service.savedquery_tbl.Delete( |
+ self.cnxn, id=[1], commit=commit) |
+ self.features_service.savedquery_tbl.InsertRows( |
+ self.cnxn, features_svc.SAVEDQUERY_COLS, savedquery_rows, commit=commit, |
+ return_generated_ids=True).AndReturn([11, 12]) |
+ return saved_queries |
+ |
+ def testUpdateSavedQueries(self): |
+ saved_queries = self.SetUpUpdateSavedQueries() |
+ self.mox.ReplayAll() |
+ self.features_service._UpdateSavedQueries( |
+ self.cnxn, saved_queries, True) |
+ self.mox.VerifyAll() |
+ |
+ def testUpdateCannedQueries(self): |
+ self.features_service.project2savedquery_tbl.Delete( |
+ self.cnxn, project_id=12345, commit=False) |
+ canned_queries = self.SetUpUpdateSavedQueries(False) |
+ project2savedquery_rows = [(12345, 0, 1), (12345, 1, 12)] |
+ self.features_service.project2savedquery_tbl.InsertRows( |
+ self.cnxn, features_svc.PROJECT2SAVEDQUERY_COLS, |
+ project2savedquery_rows, commit=False) |
+ self.cnxn.Commit() |
+ self.mox.ReplayAll() |
+ self.features_service.UpdateCannedQueries( |
+ self.cnxn, 12345, canned_queries) |
+ self.mox.VerifyAll() |
+ |
+ def testUpdateUserSavedQueries(self): |
+ saved_queries = self.SetUpUpdateSavedQueries(False) |
+ self.features_service.savedqueryexecutesinproject_tbl.Delete( |
+ self.cnxn, query_id=[1], commit=False) |
+ self.features_service.user2savedquery_tbl.Delete( |
+ self.cnxn, user_id=1, commit=False) |
+ user2savedquery_rows = [ |
+ (1, 0, 1, 'noemail'), (1, 1, 12, 'noemail')] |
+ self.features_service.user2savedquery_tbl.InsertRows( |
+ self.cnxn, features_svc.USER2SAVEDQUERY_COLS, |
+ user2savedquery_rows, commit=False) |
+ self.features_service.savedqueryexecutesinproject_tbl.InsertRows( |
+ self.cnxn, features_svc.SAVEDQUERYEXECUTESINPROJECT_COLS, [], |
+ commit=False) |
+ self.cnxn.Commit() |
+ self.mox.ReplayAll() |
+ self.features_service.UpdateUserSavedQueries( |
+ self.cnxn, 1, saved_queries) |
+ self.mox.VerifyAll() |
+ |
+ ### Subscriptions |
+ |
+ def testGetSubscriptionsInProjects(self): |
+ join_str = ( |
+ 'SavedQueryExecutesInProject ON ' |
+ 'SavedQueryExecutesInProject.query_id = User2SavedQuery.query_id') |
+ self.features_service.user2savedquery_tbl.Select( |
+ self.cnxn, cols=['user_id'], distinct=True, |
+ joins=[(join_str, [])], |
+ subscription_mode='immediate', project_id=12345).AndReturn( |
+ [(1, 'asd'), (2, 'efg')]) |
+ self.SetUpUsersSavedQueries() |
+ self.mox.ReplayAll() |
+ result = self.features_service.GetSubscriptionsInProjects( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ self.assertIn(1, result) |
+ self.assertIn(2, result) |
+ |
+ def testExpungeSavedQueriesExecuteInProject(self): |
+ self.features_service.savedqueryexecutesinproject_tbl.Delete( |
+ self.cnxn, project_id=12345) |
+ self.features_service.project2savedquery_tbl.Select( |
+ self.cnxn, cols=['query_id'], project_id=12345).AndReturn( |
+ [(1, 'asd'), (2, 'efg')]) |
+ self.features_service.project2savedquery_tbl.Delete( |
+ self.cnxn, project_id=12345) |
+ self.features_service.savedquery_tbl.Delete( |
+ self.cnxn, id=[1, 2]) |
+ self.mox.ReplayAll() |
+ self.features_service.ExpungeSavedQueriesExecuteInProject( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ |
+ ### Filter Rules |
+ |
+ def testDeserializeFilterRules(self): |
+ filterrule_rows = [ |
+ (12345, 0, 'predicate1', 'default_status:New'), |
+ (12345, 1, 'predicate2', 'default_owner_id:1 add_cc_id:2'), |
+ ] |
+ result_dict = self.features_service._DeserializeFilterRules( |
+ filterrule_rows) |
+ self.assertIn(12345, result_dict) |
+ self.assertEqual(2, len(result_dict[12345])) |
+ self.assertEqual('New', result_dict[12345][0].default_status) |
+ self.assertEqual(1, result_dict[12345][1].default_owner_id) |
+ self.assertEqual([2], result_dict[12345][1].add_cc_ids) |
+ |
+ def testDeserializeRuleConsequence(self): |
+ consequence = ('default_status:New default_owner_id:1 add_cc_id:2' |
+ ' add_label:label1 add_label:label2 add_notify:admin') |
+ (default_status, default_owner_id, add_cc_ids, add_labels, |
+ add_notify) = self.features_service._DeserializeRuleConsequence( |
+ consequence) |
+ self.assertEqual('New', default_status) |
+ self.assertEqual(1, default_owner_id) |
+ self.assertEqual([2], add_cc_ids) |
+ self.assertEqual(['label1', 'label2'], add_labels) |
+ self.assertEqual(['admin'], add_notify) |
+ |
+ def SetUpGetFilterRulesByProjectIDs(self): |
+ filterrule_rows = [ |
+ (12345, 0, 'predicate1', 'default_status:New'), |
+ (12345, 1, 'predicate2', 'default_owner_id:1 add_cc_id:2'), |
+ ] |
+ |
+ self.features_service.filterrule_tbl.Select( |
+ self.cnxn, cols=features_svc.FILTERRULE_COLS, |
+ project_id=[12345]).AndReturn(filterrule_rows) |
+ |
+ def testGetFilterRulesByProjectIDs(self): |
+ self.SetUpGetFilterRulesByProjectIDs() |
+ self.mox.ReplayAll() |
+ result = self.features_service._GetFilterRulesByProjectIDs( |
+ self.cnxn, [12345]) |
+ self.mox.VerifyAll() |
+ self.assertIn(12345, result) |
+ self.assertEqual(2, len(result[12345])) |
+ |
+ def testGetFilterRules(self): |
+ self.SetUpGetFilterRulesByProjectIDs() |
+ self.mox.ReplayAll() |
+ result = self.features_service.GetFilterRules( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ self.assertEqual(2, len(result)) |
+ |
+ def testSerializeRuleConsequence(self): |
+ rule = filterrules_helpers.MakeRule( |
+ 'predicate', 'New', 1, [1, 2], ['label1', 'label2'], ['admin']) |
+ result = self.features_service._SerializeRuleConsequence(rule) |
+ self.assertEqual('add_label:label1 add_label:label2 default_status:New' |
+ ' default_owner_id:1 add_cc_id:1 add_cc_id:2' |
+ ' add_notify:admin', result) |
+ |
+ def testUpdateFilterRules(self): |
+ self.features_service.filterrule_tbl.Delete(self.cnxn, project_id=12345) |
+ rows = [ |
+ (12345, 0, 'predicate1', 'add_label:label1 add_label:label2' |
+ ' default_status:New default_owner_id:1' |
+ ' add_cc_id:1 add_cc_id:2 add_notify:admin'), |
+ (12345, 1, 'predicate2', 'add_label:label2 add_label:label3' |
+ ' default_status:Fixed default_owner_id:2' |
+ ' add_cc_id:1 add_cc_id:2 add_notify:admin2') |
+ ] |
+ self.features_service.filterrule_tbl.InsertRows( |
+ self.cnxn, features_svc.FILTERRULE_COLS, rows) |
+ rule1 = filterrules_helpers.MakeRule( |
+ 'predicate1', 'New', 1, [1, 2], ['label1', 'label2'], ['admin']) |
+ rule2 = filterrules_helpers.MakeRule( |
+ 'predicate2', 'Fixed', 2, [1, 2], ['label2', 'label3'], ['admin2']) |
+ self.mox.ReplayAll() |
+ self.features_service.UpdateFilterRules( |
+ self.cnxn, 12345, [rule1, rule2]) |
+ self.mox.VerifyAll() |
+ |
+ def testExpungeFilterRules(self): |
+ self.features_service.filterrule_tbl.Delete(self.cnxn, project_id=12345) |
+ self.mox.ReplayAll() |
+ self.features_service.ExpungeFilterRules( |
+ self.cnxn, 12345) |
+ self.mox.VerifyAll() |
+ |
+ |
+if __name__ == '__main__': |
+ unittest.main() |