diff options
author | Android Chromium Automerger <chromium-automerger@android> | 2014-04-07 20:31:55 +0000 |
---|---|---|
committer | Android Chromium Automerger <chromium-automerger@android> | 2014-04-07 20:31:55 +0000 |
commit | fc300288d9f8b8f795aa8131cd0ab5f4cec154a4 (patch) | |
tree | 2346d58f8a1c83d83320e5fe103037d04b0a5658 | |
parent | 529c71f7f29a05c176f72df33223359540d28488 (diff) | |
parent | 3cc30808743b43aba1bc37a2c0e4b6fb55746508 (diff) | |
download | grit-fc300288d9f8b8f795aa8131cd0ab5f4cec154a4.tar.gz |
Merge tools/grit from https://chromium.googlesource.com/external/grit-i18n.git at 3cc30808743b43aba1bc37a2c0e4b6fb55746508
This commit was generated by merge_from_chromium.py.
Change-Id: Idbf846876a213d12d032a7cfb02651d898320c23
-rw-r--r-- | grit/format/policy_templates/writers/ios_plist_writer.py | 122 | ||||
-rw-r--r-- | grit/format/policy_templates/writers/ios_plist_writer_unittest.py | 208 |
2 files changed, 330 insertions, 0 deletions
diff --git a/grit/format/policy_templates/writers/ios_plist_writer.py b/grit/format/policy_templates/writers/ios_plist_writer.py new file mode 100644 index 0000000..1da64aa --- /dev/null +++ b/grit/format/policy_templates/writers/ios_plist_writer.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# Copyright (c) 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +import base64 + +from xml.dom import minidom +from grit.format.policy_templates.writers import plist_writer + + +# This writer outputs a Property List with an example for each of the policies +# supported on iOS. This plist can be pushed to Chrome on iOS via the MDM API +# introduced in iOS 7. + +CHROME_POLICY_COMMENT = '''\ + ChromePolicy is the preferred key to configure Chrome. + Each of the keys in this <dict> configures a Chrome policy. + All of the Chrome policies are configured with an example + value below. + Note that it's not necessary to configure all of them. ''' + +ENCODED_CHROME_POLICY_COMMENT = '''\ + EncodedChromePolicy contains a Property List file, encoded in Base64, + which contains the same policies that can go in ChromePolicy. + This key can be used by vendors that restrict the app configuration + types to strings. + The value of this string can be validated by running these + commands in Mac OS X: + + # (first, copy-paste the string into a file named "policy.plist") + # base64 -D < policy.plist > decoded_policy.plist + # plutil -lint decoded_policy.plist + + plutil should indicate that decoded_policy.plist is valid, + otherwise Chrome will reject the encoded string too. + + This command can be used to pretty-print the plist file: + + # plutil -convert xml1 decoded_policy.plist + + Note that <ChromePolicy> is the preferred key to configure Chrome. + If <ChromePolicy> is present then <EncodedChromePolicy> is ignored. ''' + +def GetWriter(config): + '''Factory method for creating IOSPlistWriter objects. + See the constructor of TemplateWriter for description of + arguments. + ''' + return IOSPlistWriter(['ios'], config) + + +class IOSPlistWriter(plist_writer.PListWriter): + '''Class for generating policy templates in the iOS plist format. + It is used by PolicyTemplateGenerator to write plist files. + ''' + + # Overridden. + def IsPolicySupported(self, policy): + # Output examples only for policies that are supported on iOS. + for support_on in policy['supported_on']: + if ('ios' in support_on['platforms'] and + support_on['until_version'] == '' and + super(IOSPlistWriter, self).IsPolicySupported(policy)): + return True + return False + + def _WriteValue(self, parent, value): + if type(value) == bool: + self.AddElement(parent, 'true' if value else 'false') + elif type(value) == int: + self.AddElement(parent, 'integer', {}, str(value)) + elif type(value) == str: + self.AddElement(parent, 'string', {}, value) + elif type(value) == list: + array = self.AddElement(parent, 'array') + for element in value: + self._WriteValue(array, element) + elif type(value) == dict: + dic = self.AddElement(parent, 'dict') + for k, v in sorted(value.iteritems()): + self.AddElement(dic, 'key', {}, k) + self._WriteValue(dic, v) + else: + raise ValueError('Unsupported type in example value: ' + type(value)) + + # Overridden. + def WritePolicy(self, policy): + for dict in [self._dict, self._encoded_dict]: + self.AddElement(dict, 'key', {}, policy['name']) + self._WriteValue(dict, policy['example_value']) + + # Overridden. + # |self._plist| is created in super.Init(). + def BeginTemplate(self): + self._plist.attributes['version'] = '1.0' + self._root_dict = self.AddElement(self._plist, 'dict') + self.AddComment(self._root_dict, CHROME_POLICY_COMMENT) + self._dict = self._AddKeyValuePair(self._root_dict, 'ChromePolicy', 'dict') + + self._encoded_plist.attributes['version'] = '1.0' + self._encoded_dict = self.AddElement(self._encoded_plist, 'dict') + + # Overridden. + def EndTemplate(self): + # Add the "EncodedChromePolicy" entry. + encoded = base64.b64encode(self._encoded_doc.toxml()) + self.AddComment(self._root_dict, ENCODED_CHROME_POLICY_COMMENT) + self._AddStringKeyValuePair(self._root_dict, 'EncodedChromePolicy', encoded) + + # Overridden. + def Init(self): + super(IOSPlistWriter, self).Init() + # Create a secondary DOM for the EncodedChromePolicy Plist, which will be + # serialized and encoded in EndTemplate. + self._encoded_doc = self.CreatePlistDocument() + self._encoded_plist = self._encoded_doc.documentElement + + # Overridden. + def GetTemplateText(self): + return self.ToPrettyXml(self._doc, encoding='UTF-8') diff --git a/grit/format/policy_templates/writers/ios_plist_writer_unittest.py b/grit/format/policy_templates/writers/ios_plist_writer_unittest.py new file mode 100644 index 0000000..14a0cab --- /dev/null +++ b/grit/format/policy_templates/writers/ios_plist_writer_unittest.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python +# Copyright (c) 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +'''Unit tests for grit.format.policy_templates.writers.ios_plist_writer''' + + +import base64 +import functools +import os +import plistlib +import sys +if __name__ == '__main__': + sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..')) + +import unittest + +try: + import Cocoa +except: + Cocoa = None + +from grit.format.policy_templates.writers import writer_unittest_common + + +class IOSPListWriterUnittest(writer_unittest_common.WriterUnittestCommon): + '''Unit tests for IOSPListWriter.''' + + def _ParseWithPython(self, decode, text): + '''Parses a serialized Plist, using Python's plistlib. + + If |decode| is true then |text| is decoded as Base64 before being + deserialized as a Plist.''' + if decode: + text = base64.b64decode(text) + return plistlib.readPlistFromString(text) + + def _ParseWithCocoa(self, decode, text): + '''Parses a serialized Plist, using Cocoa's python bindings. + + If |decode| is true then |text| is decoded as Base64 before being + deserialized as a Plist.''' + if decode: + data = Cocoa.NSData.alloc().initWithBase64EncodedString_options_(text, 0) + else: + data = Cocoa.NSData.alloc().initWithBytes_length_(text, len(text)) + result = Cocoa.NSPropertyListSerialization. \ + propertyListFromData_mutabilityOption_format_errorDescription_( + data, Cocoa.NSPropertyListImmutable, None, None) + return result[0] + + def _VerifyGeneratedOutputWithParsers(self, + templates, + expected_output, + parse, + decode_and_parse): + # Generate the grit output for |templates|. + output = self.GetOutput( + self.PrepareTest(templates), + 'fr', + { '_chromium': '1', 'mac_bundle_id': 'com.example.Test' }, + 'ios_plist', + 'en') + + # Parse it as a Plist. + plist = parse(output) + self.assertEquals(len(plist), 2) + self.assertTrue('ChromePolicy' in plist) + self.assertTrue('EncodedChromePolicy' in plist) + + # Get the 2 expected fields. + chrome_policy = plist['ChromePolicy'] + encoded_chrome_policy = plist['EncodedChromePolicy'] + + # Verify the ChromePolicy. + self.assertEquals(chrome_policy, expected_output) + + # Decode the EncodedChromePolicy and verify it. + decoded_chrome_policy = decode_and_parse(encoded_chrome_policy) + self.assertEquals(decoded_chrome_policy, expected_output) + + def _VerifyGeneratedOutput(self, templates, expected): + # plistlib is available on all Python platforms. + parse = functools.partial(self._ParseWithPython, False) + decode_and_parse = functools.partial(self._ParseWithPython, True) + self._VerifyGeneratedOutputWithParsers( + templates, expected, parse, decode_and_parse) + + # The Cocoa bindings are available on Mac OS X only. + if Cocoa: + parse = functools.partial(self._ParseWithCocoa, False) + decode_and_parse = functools.partial(self._ParseWithCocoa, True) + self._VerifyGeneratedOutputWithParsers( + templates, expected, parse, decode_and_parse) + + def _MakeTemplate(self, name, type, example, extra=''): + return ''' + { + 'policy_definitions': [ + { + 'name': '%s', + 'type': '%s', + 'desc': '', + 'caption': '', + 'supported_on': ['ios:35-'], + 'example_value': %s, + %s + }, + ], + 'placeholders': [], + 'messages': {}, + } + ''' % (name, type, example, extra) + + def testEmpty(self): + templates = ''' + { + 'policy_definitions': [], + 'placeholders': [], + 'messages': {}, + } + ''' + expected = {} + self._VerifyGeneratedOutput(templates, expected) + + def testBoolean(self): + templates = self._MakeTemplate('BooleanPolicy', 'main', 'True') + expected = { + 'BooleanPolicy': True, + } + self._VerifyGeneratedOutput(templates, expected) + + def testString(self): + templates = self._MakeTemplate('StringPolicy', 'string', '"Foo"') + expected = { + 'StringPolicy': 'Foo', + } + self._VerifyGeneratedOutput(templates, expected) + + def testStringEnum(self): + templates = self._MakeTemplate( + 'StringEnumPolicy', 'string-enum', '"Foo"', + ''' + 'items': [ + { 'name': 'Foo', 'value': 'Foo', 'caption': '' }, + { 'name': 'Bar', 'value': 'Bar', 'caption': '' }, + ], + ''') + expected = { + 'StringEnumPolicy': 'Foo', + } + self._VerifyGeneratedOutput(templates, expected) + + def testInt(self): + templates = self._MakeTemplate('IntPolicy', 'int', '42') + expected = { + 'IntPolicy': 42, + } + self._VerifyGeneratedOutput(templates, expected) + + def testIntEnum(self): + templates = self._MakeTemplate( + 'IntEnumPolicy', 'int-enum', '42', + ''' + 'items': [ + { 'name': 'Foo', 'value': 100, 'caption': '' }, + { 'name': 'Bar', 'value': 42, 'caption': '' }, + ], + ''') + expected = { + 'IntEnumPolicy': 42, + } + self._VerifyGeneratedOutput(templates, expected) + + def testStringList(self): + templates = self._MakeTemplate('StringListPolicy', 'list', '["a", "b"]') + expected = { + 'StringListPolicy': [ "a", "b" ], + } + self._VerifyGeneratedOutput(templates, expected) + + def testListOfDictionary(self): + templates = self._MakeTemplate( + 'ManagedBookmarks', 'dict', + ''' + [ + { + "name": "Google Search", + "url": "www.google.com", + }, + { + "name": "Youtube", + "url": "www.youtube.com", + } + ] + ''') + expected = { + 'ManagedBookmarks': [ + { "name": "Google Search", "url": "www.google.com" }, + { "name": "Youtube", "url": "www.youtube.com" }, + ], + } + self._VerifyGeneratedOutput(templates, expected) + + +if __name__ == '__main__': + unittest.main() |