Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / server2 / jsc_view_test.py
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.
5
6 import json
7 import os
8 import unittest
9
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
31
32
33 class _FakeTemplateCache(object):
34
35   def GetFromFile(self, key):
36     return Future(value='motemplate %s' % key)
37
38
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}
48     })
49
50
51 class _FakeAvailabilityFinder(object):
52   def __init__(self, fake_availability):
53     self._fake_availability = fake_availability
54
55   def GetAPIAvailability(self, api_name):
56     return self._fake_availability
57
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
66
67
68 class JSCViewTest(unittest.TestCase):
69   def setUp(self):
70     self._base_path = Server2Path('test_data', 'test_json')
71
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))
83
84   def _ReadLocalFile(self, filename):
85     with open(os.path.join(self._base_path, filename), 'r') as f:
86       return f.read()
87
88   def _LoadJSON(self, filename):
89     return json.loads(self._ReadLocalFile(filename))
90
91   def _FakeLoadAddRulesSchema(self):
92     events = self._LoadJSON('add_rules_def_test.json')
93     return Future(value=GetEventByNameFromEvents(events))
94
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))
99
100   def testGetEventByNameFromEvents(self):
101     events = {}
102     # Missing 'types' completely.
103     self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
104
105     events['types'] = []
106     # No type 'Event' defined.
107     self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
108
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'])
115
116     events['types'][0]['functions'].append(add_rules)
117     # Duplicates are an error.
118     self.assertRaises(AssertionError, GetEventByNameFromEvents, events)
119
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',
131         [],
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'])
138
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',
152         [],
153         Request.ForTest(''))
154     self.assertEquals(expected_json, dict_)
155
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',
167         [],
168         Request.ForTest(''))
169
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'])
176
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'])
184
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',
196         [])
197     expected_list = [
198       { 'title': 'Description',
199         'content': [
200           { 'text': 'a test api' }
201         ]
202       },
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
209           }
210         ]
211       },
212       { 'title': 'Permissions',
213         'content': [
214           { 'class': 'override',
215             'text': '"tester"'
216           },
217           { 'text': 'is an API for testing things.' }
218         ]
219       },
220       { 'title': 'Manifest',
221         'content': [
222           { 'class': 'code',
223             'text': '"tester": {...}'
224           }
225         ]
226       },
227       { 'title': 'Content Scripts',
228         'content': [
229           {
230             'partial': 'motemplate chrome/common/extensions/docs' +
231                        '/templates/private/intro_tables/content_scripts.html',
232             'contentScriptSupport': {
233               'name': 'tester',
234               'restrictedTo': None
235             }
236           }
237         ]
238       },
239       { 'title': 'Learn More',
240         'content': [
241           { 'link': 'https://tester.test.com/welcome.html',
242             'text': 'Welcome!'
243           }
244         ]
245       }
246     ]
247     self.assertEquals(model._GetIntroTableList(), expected_list)
248
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',
261         [])
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
269         }
270       ]
271     }
272     self.assertEquals(model._GetIntroTableList(), expected_list)
273
274
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')
286
287
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
296     }
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',
307           [],
308           Request.ForTest(''))
309       self.assertEquals(availability,
310                         model_dict['introList'][1]['content'][0]['version'])
311
312
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())
333
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())
341
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})
345
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
354
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)
361
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
373       }
374       self.assertEquals(node_availabilities[node], actual)
375
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',
385         [],
386         Request.ForTest(''))
387
388     # Test nodes that have the same availability as their parent.
389
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'])
399
400     # Test nodes with varying availabilities.
401
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'])
414
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'])
422
423 if __name__ == '__main__':
424   unittest.main()