1#!/usr/bin/env python
2# Copyright (c) 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'''Unit tests for grit.format.policy_templates.writers.ios_plist_writer'''
7
8
9import base64
10import functools
11import os
12import plistlib
13import sys
14if __name__ == '__main__':
15  sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
16
17import unittest
18
19try:
20  import Cocoa
21except:
22  Cocoa = None
23
24from grit.format.policy_templates.writers import writer_unittest_common
25
26
27class IOSPListWriterUnittest(writer_unittest_common.WriterUnittestCommon):
28  '''Unit tests for IOSPListWriter.'''
29
30  def _ParseWithPython(self, decode, text):
31    '''Parses a serialized Plist, using Python's plistlib.
32
33    If |decode| is true then |text| is decoded as Base64 before being
34    deserialized as a Plist.'''
35    if decode:
36      text = base64.b64decode(text)
37    return plistlib.readPlistFromString(text)
38
39  def _ParseWithCocoa(self, decode, text):
40    '''Parses a serialized Plist, using Cocoa's python bindings.
41
42    If |decode| is true then |text| is decoded as Base64 before being
43    deserialized as a Plist.'''
44    if decode:
45      data = Cocoa.NSData.alloc().initWithBase64EncodedString_options_(text, 0)
46    else:
47      data = Cocoa.NSData.alloc().initWithBytes_length_(text, len(text))
48    result = Cocoa.NSPropertyListSerialization. \
49        propertyListFromData_mutabilityOption_format_errorDescription_(
50            data, Cocoa.NSPropertyListImmutable, None, None)
51    return result[0]
52
53  def _VerifyGeneratedOutputWithParsers(self,
54                                        templates,
55                                        expected_output,
56                                        parse,
57                                        decode_and_parse):
58    # Generate the grit output for |templates|.
59    output = self.GetOutput(
60        self.PrepareTest(templates),
61        'fr',
62        { '_chromium': '1', 'mac_bundle_id': 'com.example.Test' },
63        'ios_plist',
64        'en')
65
66    # Parse it as a Plist.
67    plist = parse(output)
68    self.assertEquals(len(plist), 2)
69    self.assertTrue('ChromePolicy' in plist)
70    self.assertTrue('EncodedChromePolicy' in plist)
71
72    # Get the 2 expected fields.
73    chrome_policy = plist['ChromePolicy']
74    encoded_chrome_policy = plist['EncodedChromePolicy']
75
76    # Verify the ChromePolicy.
77    self.assertEquals(chrome_policy, expected_output)
78
79    # Decode the EncodedChromePolicy and verify it.
80    decoded_chrome_policy = decode_and_parse(encoded_chrome_policy)
81    self.assertEquals(decoded_chrome_policy, expected_output)
82
83  def _VerifyGeneratedOutput(self, templates, expected):
84    # plistlib is available on all Python platforms.
85    parse = functools.partial(self._ParseWithPython, False)
86    decode_and_parse = functools.partial(self._ParseWithPython, True)
87    self._VerifyGeneratedOutputWithParsers(
88        templates, expected, parse, decode_and_parse)
89
90    # The Cocoa bindings are available on Mac OS X only.
91    if Cocoa:
92      parse = functools.partial(self._ParseWithCocoa, False)
93      decode_and_parse = functools.partial(self._ParseWithCocoa, True)
94      self._VerifyGeneratedOutputWithParsers(
95          templates, expected, parse, decode_and_parse)
96
97  def _MakeTemplate(self, name, type, example, extra=''):
98    return '''
99    {
100      'policy_definitions': [
101        {
102          'name': '%s',
103          'type': '%s',
104          'desc': '',
105          'caption': '',
106          'supported_on': ['ios:35-'],
107          'example_value': %s,
108          %s
109        },
110      ],
111      'placeholders': [],
112      'messages': {},
113    }
114    ''' % (name, type, example, extra)
115
116  def testEmpty(self):
117    templates = '''
118    {
119      'policy_definitions': [],
120      'placeholders': [],
121      'messages': {},
122    }
123    '''
124    expected = {}
125    self._VerifyGeneratedOutput(templates, expected)
126
127  def testBoolean(self):
128    templates = self._MakeTemplate('BooleanPolicy', 'main', 'True')
129    expected = {
130      'BooleanPolicy': True,
131    }
132    self._VerifyGeneratedOutput(templates, expected)
133
134  def testString(self):
135    templates = self._MakeTemplate('StringPolicy', 'string', '"Foo"')
136    expected = {
137      'StringPolicy': 'Foo',
138    }
139    self._VerifyGeneratedOutput(templates, expected)
140
141  def testStringEnum(self):
142    templates = self._MakeTemplate(
143        'StringEnumPolicy', 'string-enum', '"Foo"',
144        '''
145          'items': [
146            { 'name': 'Foo', 'value': 'Foo', 'caption': '' },
147            { 'name': 'Bar', 'value': 'Bar', 'caption': '' },
148          ],
149        ''')
150    expected = {
151      'StringEnumPolicy': 'Foo',
152    }
153    self._VerifyGeneratedOutput(templates, expected)
154
155  def testInt(self):
156    templates = self._MakeTemplate('IntPolicy', 'int', '42')
157    expected = {
158      'IntPolicy': 42,
159    }
160    self._VerifyGeneratedOutput(templates, expected)
161
162  def testIntEnum(self):
163    templates = self._MakeTemplate(
164        'IntEnumPolicy', 'int-enum', '42',
165        '''
166          'items': [
167            { 'name': 'Foo', 'value': 100, 'caption': '' },
168            { 'name': 'Bar', 'value': 42, 'caption': '' },
169          ],
170        ''')
171    expected = {
172      'IntEnumPolicy': 42,
173    }
174    self._VerifyGeneratedOutput(templates, expected)
175
176  def testStringList(self):
177    templates = self._MakeTemplate('StringListPolicy', 'list', '["a", "b"]')
178    expected = {
179      'StringListPolicy': [ "a", "b" ],
180    }
181    self._VerifyGeneratedOutput(templates, expected)
182
183  def testStringEnumList(self):
184    templates = self._MakeTemplate('StringEnumListPolicy',
185                                   'string-enum-list', '["a", "b"]',
186        '''
187          'items': [
188            { 'name': 'Foo', 'value': 'a', 'caption': '' },
189            { 'name': 'Bar', 'value': 'b', 'caption': '' },
190          ],
191        ''')
192
193    expected = {
194      'StringEnumListPolicy': [ "a", "b" ],
195    }
196    self._VerifyGeneratedOutput(templates, expected)
197
198  def testListOfDictionary(self):
199    templates = self._MakeTemplate(
200        'ManagedBookmarks', 'dict',
201        '''
202        [
203          {
204            "name": "Google Search",
205            "url": "www.google.com",
206          },
207          {
208            "name": "Youtube",
209            "url": "www.youtube.com",
210          }
211        ]
212        ''')
213    expected = {
214      'ManagedBookmarks': [
215        { "name": "Google Search", "url": "www.google.com" },
216        { "name": "Youtube", "url": "www.youtube.com" },
217      ],
218    }
219    self._VerifyGeneratedOutput(templates, expected)
220
221
222if __name__ == '__main__':
223  unittest.main()
224