1 #!/usr/bin/env python 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 import json 7 import os 8 import sys 9 import unittest 10 11 from api_data_source import (_JSCModel, 12 _FormatValue, 13 _GetEventByNameFromEvents) 14 from availability_finder import AvailabilityInfo 15 from branch_utility import ChannelInfo 16 from extensions_paths import CHROME_EXTENSIONS 17 from fake_host_file_system_provider import FakeHostFileSystemProvider 18 from features_bundle import FeaturesBundle 19 from file_system import FileNotFoundError 20 from future import Future 21 from object_store_creator import ObjectStoreCreator 22 from server_instance import ServerInstance 23 from test_data.canned_data import (CANNED_API_FILE_SYSTEM_DATA, CANNED_BRANCHES) 24 from test_data.api_data_source.canned_trunk_fs import CANNED_TRUNK_FS_DATA 25 from test_file_system import TestFileSystem 26 from test_util import Server2Path 27 from third_party.json_schema_compiler.memoize import memoize 28 29 30 def _MakeLink(href, text): 31 return '<a href="%s">%s</a>' % (href, text) 32 33 34 def _GetType(dict_, name): 35 for type_ in dict_['types']: 36 if type_['name'] == name: 37 return type_ 38 39 40 class _FakeAvailabilityFinder(object): 41 42 def GetAPIAvailability(self, version): 43 return AvailabilityInfo(ChannelInfo('stable', '396', 5)) 44 45 46 class _FakeScheduledAvailabilityFinder(object): 47 48 def GetAPIAvailability(self, version): 49 return AvailabilityInfo(ChannelInfo('beta', '1453', 27), scheduled=28) 50 51 52 class _FakeTemplateCache(object): 53 54 def GetFromFile(self, key): 55 return Future(value='handlebar %s' % key) 56 57 58 class APIDataSourceTest(unittest.TestCase): 59 60 def setUp(self): 61 self._base_path = Server2Path('test_data', 'test_json') 62 63 server_instance = ServerInstance.ForTest( 64 TestFileSystem(CANNED_TRUNK_FS_DATA, relative_to=CHROME_EXTENSIONS)) 65 file_system = server_instance.host_file_system_provider.GetTrunk() 66 self._json_cache = server_instance.compiled_fs_factory.ForJson(file_system) 67 self._features_bundle = FeaturesBundle(file_system, 68 server_instance.compiled_fs_factory, 69 server_instance.object_store_creator) 70 self._api_models = server_instance.api_models 71 72 # Used for testGetAPIAvailability() so that valid-ish data is processed. 73 server_instance = ServerInstance.ForTest( 74 file_system_provider=FakeHostFileSystemProvider( 75 CANNED_API_FILE_SYSTEM_DATA)) 76 self._avail_api_models = server_instance.api_models 77 self._avail_json_cache = server_instance.compiled_fs_factory.ForJson( 78 server_instance.host_file_system_provider.GetTrunk()) 79 self._avail_finder = server_instance.availability_finder 80 81 def _ReadLocalFile(self, filename): 82 with open(os.path.join(self._base_path, filename), 'r') as f: 83 return f.read() 84 85 def _LoadJSON(self, filename): 86 return json.loads(self._ReadLocalFile(filename)) 87 88 def testCreateId(self): 89 dict_ = _JSCModel(self._api_models.GetModel('tester').Get(), 90 _FakeAvailabilityFinder(), 91 self._json_cache, 92 _FakeTemplateCache(), 93 self._features_bundle, 94 None).ToDict() 95 self.assertEquals('type-TypeA', dict_['types'][0]['id']) 96 self.assertEquals('property-TypeA-b', 97 dict_['types'][0]['properties'][0]['id']) 98 self.assertEquals('method-get', dict_['functions'][0]['id']) 99 self.assertEquals('event-EventA', dict_['events'][0]['id']) 100 101 # TODO(kalman): re-enable this when we have a rebase option. 102 def DISABLED_testToDict(self): 103 expected_json = self._LoadJSON('expected_tester.json') 104 dict_ = _JSCModel(self._api_models.GetModel('tester').Get(), 105 _FakeAvailabilityFinder(), 106 self._json_cache, 107 _FakeTemplateCache(), 108 self._features_bundle, 109 None).ToDict() 110 self.assertEquals(expected_json, dict_) 111 112 def testFormatValue(self): 113 self.assertEquals('1,234,567', _FormatValue(1234567)) 114 self.assertEquals('67', _FormatValue(67)) 115 self.assertEquals('234,567', _FormatValue(234567)) 116 117 def testGetAPIAvailability(self): 118 api_availabilities = { 119 'bluetooth': AvailabilityInfo( 120 ChannelInfo('dev', CANNED_BRANCHES[28], 28)), 121 'contextMenus': AvailabilityInfo( 122 ChannelInfo('trunk', CANNED_BRANCHES['trunk'], 'trunk')), 123 'jsonStableAPI': AvailabilityInfo( 124 ChannelInfo('stable', CANNED_BRANCHES[20], 20)), 125 'idle': AvailabilityInfo( 126 ChannelInfo('stable', CANNED_BRANCHES[5], 5)), 127 'input.ime': AvailabilityInfo( 128 ChannelInfo('stable', CANNED_BRANCHES[18], 18)), 129 'tabs': AvailabilityInfo( 130 ChannelInfo('stable', CANNED_BRANCHES[18], 18)) 131 } 132 for api_name, availability in api_availabilities.iteritems(): 133 model = _JSCModel(self._avail_api_models.GetModel(api_name).Get(), 134 self._avail_finder, 135 self._avail_json_cache, 136 _FakeTemplateCache(), 137 self._features_bundle, 138 None) 139 self.assertEquals(availability, model._GetAPIAvailability()) 140 141 def testGetIntroList(self): 142 model = _JSCModel(self._api_models.GetModel('tester').Get(), 143 _FakeAvailabilityFinder(), 144 self._json_cache, 145 _FakeTemplateCache(), 146 self._features_bundle, 147 None) 148 expected_list = [ 149 { 'title': 'Description', 150 'content': [ 151 { 'text': 'a test api' } 152 ] 153 }, 154 { 'title': 'Availability', 155 'content': [ 156 { 'partial': 'handlebar chrome/common/extensions/docs/' + 157 'templates/private/intro_tables/stable_message.html', 158 'version': 5, 159 'scheduled': None 160 } 161 ] 162 }, 163 { 'title': 'Permissions', 164 'content': [ 165 { 'class': 'override', 166 'text': '"tester"' 167 }, 168 { 'text': 'is an API for testing things.' } 169 ] 170 }, 171 { 'title': 'Manifest', 172 'content': [ 173 { 'class': 'code', 174 'text': '"tester": {...}' 175 } 176 ] 177 }, 178 { 'title': 'Learn More', 179 'content': [ 180 { 'link': 'https://tester.test.com/welcome.html', 181 'text': 'Welcome!' 182 } 183 ] 184 } 185 ] 186 self.assertEquals(model._GetIntroTableList(), expected_list) 187 188 # Tests the same data with a scheduled availability. 189 model = _JSCModel(self._api_models.GetModel('tester').Get(), 190 _FakeScheduledAvailabilityFinder(), 191 self._json_cache, 192 _FakeTemplateCache(), 193 self._features_bundle, 194 None) 195 expected_list[1] = { 196 'title': 'Availability', 197 'content': [ 198 { 'partial': 'handlebar chrome/common/extensions/docs/' + 199 'templates/private/intro_tables/beta_message.html', 200 'version': 27, 201 'scheduled': 28 202 } 203 ] 204 } 205 self.assertEquals(model._GetIntroTableList(), expected_list) 206 207 def testGetEventByNameFromEvents(self): 208 events = {} 209 # Missing 'types' completely. 210 self.assertRaises(AssertionError, _GetEventByNameFromEvents, events) 211 212 events['types'] = [] 213 # No type 'Event' defined. 214 self.assertRaises(AssertionError, _GetEventByNameFromEvents, events) 215 216 events['types'].append({ 'name': 'Event', 217 'functions': []}) 218 add_rules = { "name": "addRules" } 219 events['types'][0]['functions'].append(add_rules) 220 self.assertEqual(add_rules, 221 _GetEventByNameFromEvents(events)['addRules']) 222 223 events['types'][0]['functions'].append(add_rules) 224 # Duplicates are an error. 225 self.assertRaises(AssertionError, _GetEventByNameFromEvents, events) 226 227 def _FakeLoadAddRulesSchema(self): 228 events = self._LoadJSON('add_rules_def_test.json') 229 return _GetEventByNameFromEvents(events) 230 231 def testAddRules(self): 232 dict_ = _JSCModel(self._api_models.GetModel('add_rules_tester').Get(), 233 _FakeAvailabilityFinder(), 234 self._json_cache, 235 _FakeTemplateCache(), 236 self._features_bundle, 237 self._FakeLoadAddRulesSchema).ToDict() 238 239 # Check that the first event has the addRulesFunction defined. 240 self.assertEquals('add_rules_tester', dict_['name']) 241 self.assertEquals('rules', dict_['events'][0]['name']) 242 self.assertEquals('notable_name_to_check_for', 243 dict_['events'][0]['byName']['addRules'][ 244 'parameters'][0]['name']) 245 246 # Check that the second event has addListener defined. 247 self.assertEquals('noRules', dict_['events'][1]['name']) 248 self.assertEquals('add_rules_tester', dict_['name']) 249 self.assertEquals('noRules', dict_['events'][1]['name']) 250 self.assertEquals('callback', 251 dict_['events'][0]['byName']['addListener'][ 252 'parameters'][0]['name']) 253 254 if __name__ == '__main__': 255 unittest.main() 256