2 # Copyright 2014 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.
10 from jsc_view import GetEventByNameFromEvents
11 from api_schema_graph import APISchemaGraph
12 from availability_finder import AvailabilityFinder, AvailabilityInfo
13 from branch_utility import BranchUtility, ChannelInfo
14 from compiled_file_system import CompiledFileSystem
15 from extensions_paths import CHROME_EXTENSIONS
16 from fake_host_file_system_provider import FakeHostFileSystemProvider
17 from fake_url_fetcher import FakeUrlFetcher
18 from features_bundle import FeaturesBundle
19 from future import Future
20 from host_file_system_iterator import HostFileSystemIterator
21 from jsc_view import CreateJSCView, _JSCViewBuilder, _FormatValue
22 from object_store_creator import ObjectStoreCreator
23 from schema_processor import SchemaProcessorFactoryForTest
24 from servlet import Request
25 from server_instance import ServerInstance
26 from test_data.api_data_source.canned_master_fs import CANNED_MASTER_FS_DATA
27 from test_data.canned_data import CANNED_API_FILE_SYSTEM_DATA
28 from test_data.object_level_availability.tabs import TABS_SCHEMA_BRANCHES
29 from test_file_system import TestFileSystem
30 from test_util import Server2Path
33 class _FakeTemplateCache(object):
35 def GetFromFile(self, key):
36 return Future(value='motemplate %s' % key)
39 class _FakeFeaturesBundle(object):
40 def GetAPIFeatures(self):
42 'bluetooth': {'value': True},
43 'contextMenus': {'value': True},
44 'jsonStableAPI': {'value': True},
45 'idle': {'value': True},
46 'input.ime': {'value': True},
47 'tabs': {'value': True}
51 class _FakeAvailabilityFinder(object):
52 def __init__(self, fake_availability):
53 self._fake_availability = fake_availability
55 def GetAPIAvailability(self, api_name):
56 return self._fake_availability
58 def GetAPINodeAvailability(self, api_name):
59 schema_graph = APISchemaGraph()
60 api_graph = APISchemaGraph(json.loads(
61 CANNED_MASTER_FS_DATA['api'][api_name + '.json']))
62 # Give the graph fake ChannelInfo; it's not used in tests.
63 channel_info = ChannelInfo('stable', '28', 28)
64 schema_graph.Update(api_graph, lambda _: channel_info)
68 class JSCViewTest(unittest.TestCase):
70 self._base_path = Server2Path('test_data', 'test_json')
72 server_instance = ServerInstance.ForTest(
73 TestFileSystem(CANNED_MASTER_FS_DATA, relative_to=CHROME_EXTENSIONS))
74 file_system = server_instance.host_file_system_provider.GetMaster()
75 self._json_cache = server_instance.compiled_fs_factory.ForJson(file_system)
76 self._features_bundle = FeaturesBundle(file_system,
77 server_instance.compiled_fs_factory,
78 server_instance.object_store_creator,
80 self._api_models = server_instance.platform_bundle.GetAPIModels(
82 self._fake_availability = AvailabilityInfo(ChannelInfo('stable', '396', 5))
84 def _ReadLocalFile(self, filename):
85 with open(os.path.join(self._base_path, filename), 'r') as f:
88 def _LoadJSON(self, filename):
89 return json.loads(self._ReadLocalFile(filename))
91 def _FakeLoadAddRulesSchema(self):
92 events = self._LoadJSON('add_rules_def_test.json')
93 return Future(value=GetEventByNameFromEvents(events))
95 def testFormatValue(self):
96 self.assertEquals('1,234,567', _FormatValue(1234567))
97 self.assertEquals('67', _FormatValue(67))
98 self.assertEquals('234,567', _FormatValue(234567))
100 def testGetEventByNameFromEvents(self):
102 # Missing 'types' completely.
103 self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
106 # No type 'Event' defined.
107 self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
109 events['types'].append({ 'name': 'Event',
111 add_rules = { "name": "addRules" }
112 events['types'][0]['functions'].append(add_rules)
113 self.assertEqual(add_rules,
114 GetEventByNameFromEvents(events)['addRules'])
116 events['types'][0]['functions'].append(add_rules)
117 # Duplicates are an error.
118 self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
120 def testCreateId(self):
121 fake_avail_finder = _FakeAvailabilityFinder(self._fake_availability)
122 dict_ = CreateJSCView(
123 self._api_models.GetContentScriptAPIs().Get(),
124 self._api_models.GetModel('tester').Get(),
127 _FakeTemplateCache(),
128 self._features_bundle,
133 self.assertEquals('type-TypeA', dict_['types'][0]['id'])
134 self.assertEquals('property-TypeA-b',
135 dict_['types'][0]['properties'][0]['id'])
136 self.assertEquals('method-get', dict_['functions'][0]['id'])
137 self.assertEquals('event-EventA', dict_['events'][0]['id'])
139 # TODO(kalman): re-enable this when we have a rebase option.
140 def DISABLED_testToDict(self):
141 fake_avail_finder = _FakeAvailabilityFinder(self._fake_availability)
142 expected_json = self._LoadJSON('expected_tester.json')
143 dict_ = CreateJSCView(
144 self._api_models.GetContentScriptAPIs().Get(),
145 self._api_models.GetModel('tester').Get(),
148 _FakeTemplateCache(),
149 self._features_bundle,
154 self.assertEquals(expected_json, dict_)
156 def testAddRules(self):
157 fake_avail_finder = _FakeAvailabilityFinder(self._fake_availability)
158 dict_ = CreateJSCView(
159 self._api_models.GetContentScriptAPIs().Get(),
160 self._api_models.GetModel('add_rules_tester').Get(),
163 _FakeTemplateCache(),
164 self._features_bundle,
165 self._FakeLoadAddRulesSchema(),
170 # Check that the first event has the addRulesFunction defined.
171 self.assertEquals('add_rules_tester', dict_['name'])
172 self.assertEquals('rules', dict_['events'][0]['name'])
173 self.assertEquals('notable_name_to_check_for',
174 dict_['events'][0]['byName']['addRules'][
175 'parameters'][0]['name'])
177 # Check that the second event has addListener defined.
178 self.assertEquals('noRules', dict_['events'][1]['name'])
179 self.assertEquals('add_rules_tester', dict_['name'])
180 self.assertEquals('noRules', dict_['events'][1]['name'])
181 self.assertEquals('callback',
182 dict_['events'][0]['byName']['addListener'][
183 'parameters'][0]['name'])
185 def testGetIntroList(self):
186 fake_avail_finder = _FakeAvailabilityFinder(self._fake_availability)
187 model = _JSCViewBuilder(
188 self._api_models.GetContentScriptAPIs().Get(),
189 self._api_models.GetModel('tester').Get(),
192 _FakeTemplateCache(),
193 self._features_bundle,
198 { 'title': 'Description',
200 { 'text': 'a test api' }
203 { 'title': 'Availability',
205 { 'partial': 'motemplate chrome/common/extensions/docs/' +
206 'templates/private/intro_tables/stable_message.html',
212 { 'title': 'Permissions',
214 { 'class': 'override',
217 { 'text': 'is an API for testing things.' }
220 { 'title': 'Manifest',
223 'text': '"tester": {...}'
227 { 'title': 'Content Scripts',
230 'partial': 'motemplate chrome/common/extensions/docs' +
231 '/templates/private/intro_tables/content_scripts.html',
232 'contentScriptSupport': {
239 { 'title': 'Learn More',
241 { 'link': 'https://tester.test.com/welcome.html',
247 self.assertEquals(model._GetIntroTableList(), expected_list)
249 # Tests the same data with a scheduled availability.
250 fake_avail_finder = _FakeAvailabilityFinder(
251 AvailabilityInfo(ChannelInfo('beta', '1453', 27), scheduled=28))
252 model = _JSCViewBuilder(
253 self._api_models.GetContentScriptAPIs().Get(),
254 self._api_models.GetModel('tester').Get(),
257 _FakeTemplateCache(),
258 self._features_bundle,
263 'title': 'Availability',
265 { 'partial': 'motemplate chrome/common/extensions/docs/' +
266 'templates/private/intro_tables/beta_message.html',
272 self.assertEquals(model._GetIntroTableList(), expected_list)
275 class JSCViewWithoutNodeAvailabilityTest(unittest.TestCase):
277 server_instance = ServerInstance.ForTest(
278 file_system_provider=FakeHostFileSystemProvider(
279 CANNED_API_FILE_SYSTEM_DATA))
280 self._api_models = server_instance.platform_bundle.GetAPIModels(
282 self._json_cache = server_instance.compiled_fs_factory.ForJson(
283 server_instance.host_file_system_provider.GetMaster())
284 self._avail_finder = server_instance.platform_bundle.GetAvailabilityFinder(
288 def testGetAPIAvailability(self):
289 api_availabilities = {
291 'contextMenus': 'master',
297 for api_name, availability in api_availabilities.iteritems():
298 model_dict = CreateJSCView(
299 self._api_models.GetContentScriptAPIs().Get(),
300 self._api_models.GetModel(api_name).Get(),
303 _FakeTemplateCache(),
304 _FakeFeaturesBundle(),
309 self.assertEquals(availability,
310 model_dict['introList'][1]['content'][0]['version'])
313 class JSCViewWithNodeAvailabilityTest(unittest.TestCase):
315 tabs_unmodified_versions = (16, 20, 23, 24)
316 self._branch_utility = BranchUtility(
317 os.path.join('branch_utility', 'first.json'),
318 os.path.join('branch_utility', 'second.json'),
319 FakeUrlFetcher(Server2Path('test_data')),
320 ObjectStoreCreator.ForTest())
321 self._node_fs_creator = FakeHostFileSystemProvider(TABS_SCHEMA_BRANCHES)
322 self._node_fs_iterator = HostFileSystemIterator(self._node_fs_creator,
323 self._branch_utility)
324 test_object_store = ObjectStoreCreator.ForTest()
325 self._avail_finder = AvailabilityFinder(
326 self._branch_utility,
327 CompiledFileSystem.Factory(test_object_store),
328 self._node_fs_iterator,
329 self._node_fs_creator.GetMaster(),
332 SchemaProcessorFactoryForTest())
334 server_instance = ServerInstance.ForTest(
335 file_system_provider=FakeHostFileSystemProvider(
336 TABS_SCHEMA_BRANCHES))
337 self._api_models = server_instance.platform_bundle.GetAPIModels(
339 self._json_cache = server_instance.compiled_fs_factory.ForJson(
340 server_instance.host_file_system_provider.GetMaster())
342 # Imitate the actual SVN file system by incrementing the stats for paths
343 # where an API schema has changed.
344 last_stat = type('last_stat', (object,), {'val': 0})
346 def stat_paths(file_system, channel_info):
347 if channel_info.version not in tabs_unmodified_versions:
349 # HACK: |file_system| is a MockFileSystem backed by a TestFileSystem.
350 # Increment the TestFileSystem stat count.
351 file_system._file_system.IncrementStat(by=last_stat.val)
352 # Continue looping. The iterator will stop after 'master' automatically.
355 # Use the HostFileSystemIterator created above to change global stat values
356 # for the TestFileSystems that it creates.
357 self._node_fs_iterator.Ascending(
358 # The earliest version represented with the tabs' test data is 13.
359 self._branch_utility.GetStableChannelInfo(13),
362 def testGetAPINodeAvailability(self):
363 def assertEquals(node, actual):
364 node_availabilities = {
366 'tabs.fakeTabsProperty1': None,
368 'tabs.onUpdated': None,
369 'tabs.InjectDetails': 25,
370 'tabs.fakeTabsProperty2': 15,
371 'tabs.getCurrent': 19,
372 'tabs.onActivated': 30
374 self.assertEquals(node_availabilities[node], actual)
376 model_dict = CreateJSCView(
377 self._api_models.GetContentScriptAPIs().Get(),
378 self._api_models.GetModel('tabs').Get(),
381 _FakeTemplateCache(),
382 _FakeFeaturesBundle(),
388 # Test nodes that have the same availability as their parent.
391 assertEquals('tabs.Tab', model_dict['types'][0]['availability'])
393 assertEquals('tabs.fakeTabsProperty1',
394 model_dict['properties'][0]['availability'])
396 assertEquals('tabs.get', model_dict['functions'][1]['availability'])
398 assertEquals('tabs.onUpdated', model_dict['events'][1]['availability'])
400 # Test nodes with varying availabilities.
403 assertEquals('tabs.InjectDetails',
404 model_dict['types'][1]['availability']['version'])
406 assertEquals('tabs.fakeTabsProperty2',
407 model_dict['properties'][2]['availability']['version'])
409 assertEquals('tabs.getCurrent',
410 model_dict['functions'][0]['availability']['version'])
412 assertEquals('tabs.onActivated',
413 model_dict['events'][0]['availability']['version'])
415 # Test a node that became deprecated.
419 'partial': 'motemplate chrome/common/extensions/docs/templates/' +
420 'private/intro_tables/deprecated_message.html'
421 }, model_dict['types'][2]['availability'])
423 if __name__ == '__main__':