Adding the orphaned options pages to the navigation
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / jsc_view_test.py
blobad6092628279ec54c2be3c7ce159c232fc5cc6ec
1 #!/usr/bin/env python
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.
6 import json
7 import os
8 import unittest
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):
41 return Future(value={
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)
65 return schema_graph
68 class JSCViewTest(unittest.TestCase):
69 def setUp(self):
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,
79 'extensions')
80 self._api_models = server_instance.platform_bundle.GetAPIModels(
81 'extensions')
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:
86 return f.read()
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):
101 events = {}
102 # Missing 'types' completely.
103 self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
105 events['types'] = []
106 # No type 'Event' defined.
107 self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
109 events['types'].append({ 'name': 'Event',
110 'functions': []})
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(),
125 fake_avail_finder,
126 self._json_cache,
127 _FakeTemplateCache(),
128 self._features_bundle,
129 None,
130 'extensions',
132 Request.ForTest(''))
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(),
146 fake_avail_finder,
147 self._json_cache,
148 _FakeTemplateCache(),
149 self._features_bundle,
150 None,
151 'extensions',
153 Request.ForTest(''))
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(),
161 fake_avail_finder,
162 self._json_cache,
163 _FakeTemplateCache(),
164 self._features_bundle,
165 self._FakeLoadAddRulesSchema(),
166 'extensions',
168 Request.ForTest(''))
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(),
190 fake_avail_finder,
191 self._json_cache,
192 _FakeTemplateCache(),
193 self._features_bundle,
194 None,
195 'extensions',
197 expected_list = [
198 { 'title': 'Description',
199 'content': [
200 { 'text': 'a test api' }
203 { 'title': 'Availability',
204 'content': [
205 { 'partial': 'motemplate chrome/common/extensions/docs/' +
206 'templates/private/intro_tables/stable_message.html',
207 'version': 5,
208 'scheduled': None
212 { 'title': 'Permissions',
213 'content': [
214 { 'class': 'override',
215 'text': '"tester"'
217 { 'text': 'is an API for testing things.' }
220 { 'title': 'Manifest',
221 'content': [
222 { 'class': 'code',
223 'text': '"tester": {...}'
227 { 'title': 'Content Scripts',
228 'content': [
230 'partial': 'motemplate chrome/common/extensions/docs' +
231 '/templates/private/intro_tables/content_scripts.html',
232 'contentScriptSupport': {
233 'name': 'tester',
234 'restrictedTo': None
239 { 'title': 'Learn More',
240 'content': [
241 { 'link': 'https://tester.test.com/welcome.html',
242 'text': 'Welcome!'
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(),
255 fake_avail_finder,
256 self._json_cache,
257 _FakeTemplateCache(),
258 self._features_bundle,
259 None,
260 'extensions',
262 expected_list[1] = {
263 'title': 'Availability',
264 'content': [
265 { 'partial': 'motemplate chrome/common/extensions/docs/' +
266 'templates/private/intro_tables/beta_message.html',
267 'version': 27,
268 'scheduled': 28
272 self.assertEquals(model._GetIntroTableList(), expected_list)
275 class JSCViewWithoutNodeAvailabilityTest(unittest.TestCase):
276 def setUp(self):
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(
281 'extensions')
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(
285 'extensions')
288 def testGetAPIAvailability(self):
289 api_availabilities = {
290 'bluetooth': 31,
291 'contextMenus': 'master',
292 'jsonStableAPI': 20,
293 'idle': 5,
294 'input.ime': 18,
295 'tabs': 18
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(),
301 self._avail_finder,
302 self._json_cache,
303 _FakeTemplateCache(),
304 _FakeFeaturesBundle(),
305 None,
306 'extensions',
308 Request.ForTest(''))
309 self.assertEquals(availability,
310 model_dict['introList'][1]['content'][0]['version'])
313 class JSCViewWithNodeAvailabilityTest(unittest.TestCase):
314 def setUp(self):
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(),
330 test_object_store,
331 'extensions',
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(
338 'extensions')
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:
348 last_stat.val += 1
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.
353 return True
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),
360 stat_paths)
362 def testGetAPINodeAvailability(self):
363 def assertEquals(node, actual):
364 node_availabilities = {
365 'tabs.Tab': None,
366 'tabs.fakeTabsProperty1': None,
367 'tabs.get': 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(),
379 self._avail_finder,
380 self._json_cache,
381 _FakeTemplateCache(),
382 _FakeFeaturesBundle(),
383 None,
384 'extensions',
386 Request.ForTest(''))
388 # Test nodes that have the same availability as their parent.
390 # Test type.
391 assertEquals('tabs.Tab', model_dict['types'][0]['availability'])
392 # Test property.
393 assertEquals('tabs.fakeTabsProperty1',
394 model_dict['properties'][0]['availability'])
395 # Test function.
396 assertEquals('tabs.get', model_dict['functions'][1]['availability'])
397 # Test event.
398 assertEquals('tabs.onUpdated', model_dict['events'][1]['availability'])
400 # Test nodes with varying availabilities.
402 # Test type.
403 assertEquals('tabs.InjectDetails',
404 model_dict['types'][1]['availability']['version'])
405 # Test property.
406 assertEquals('tabs.fakeTabsProperty2',
407 model_dict['properties'][2]['availability']['version'])
408 # Test function.
409 assertEquals('tabs.getCurrent',
410 model_dict['functions'][0]['availability']['version'])
411 # Test event.
412 assertEquals('tabs.onActivated',
413 model_dict['events'][0]['availability']['version'])
415 # Test a node that became deprecated.
416 self.assertEquals({
417 'scheduled': None,
418 'version': 26,
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__':
424 unittest.main()