| OLD | NEW | 
|    1 # This Source Code Form is subject to the terms of the Mozilla Public |    1 # This Source Code Form is subject to the terms of the Mozilla Public | 
|    2 # License, v. 2.0. If a copy of the MPL was not distributed with this |    2 # License, v. 2.0. If a copy of the MPL was not distributed with this | 
|    3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. |    3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
|    4  |    4  | 
|    5 import ConfigParser |  | 
|    6 import json |  | 
|    7 import os |    5 import os | 
|    8 import shutil |    6 import io | 
 |    7  | 
|    9 import xml.etree.ElementTree as ET |    8 import xml.etree.ElementTree as ET | 
|   10 import zipfile |    9 import zipfile | 
|   11  |   10  | 
|   12 import pytest |   11 import pytest | 
|   13  |   12  | 
|   14 from buildtools import packager, packagerEdge |   13 from buildtools import packager, packagerEdge | 
|   15  |   14 from buildtools.tests.tools import copy_metadata | 
|   16 TEST_DIR = os.path.dirname(__file__) |  | 
|   17 TEST_METADATA = os.path.join(TEST_DIR, 'metadata.edge') |  | 
|   18 CHARS = b''.join(chr(i % 200 + 30) for i in range(500)) |  | 
|   19 MESSAGES_EN_US = json.dumps({ |  | 
|   20     'name': {'message': 'Adblock Plus'}, |  | 
|   21     'name_devbuild': {'message': 'devbuild-marker'}, |  | 
|   22     'description': { |  | 
|   23         'message': 'Adblock Plus is the most popular ad blocker ever, ' |  | 
|   24                    'and also supports websites by not blocking ' |  | 
|   25                    'unobstrusive ads by default (configurable).' |  | 
|   26     }, |  | 
|   27 }) |  | 
|   28  |   15  | 
|   29  |   16  | 
|   30 @pytest.fixture |   17 @pytest.fixture | 
|   31 def metadata(): |   18 def edge_metadata(tmpdir): | 
|   32     """Loaded metadata config.""" |   19     filename = 'metadata.edge' | 
|   33     conf_parser = ConfigParser.ConfigParser() |   20     copy_metadata(filename, tmpdir) | 
|   34     conf_parser.read(TEST_METADATA) |  | 
|   35     return conf_parser |  | 
|   36  |   21  | 
|   37  |   22     return packager.readMetadata(str(tmpdir), 'edge') | 
|   38 @pytest.fixture |  | 
|   39 def files(): |  | 
|   40     """Minimal Files() for testing manifest and blockmap.""" |  | 
|   41     files = packager.Files(set(), set()) |  | 
|   42     for size in ['44', '50', '150']: |  | 
|   43         files['Assets/logo_{}.png'.format(size)] = CHARS |  | 
|   44     files['Extension/_locales/en_US/messages.json'] = MESSAGES_EN_US |  | 
|   45     files['Extension/foo.xml'] = CHARS |  | 
|   46     files['Extension/bar.png'] = CHARS * 200 |  | 
|   47     return files |  | 
|   48  |  | 
|   49  |  | 
|   50 @pytest.fixture |  | 
|   51 def srcdir(tmpdir): |  | 
|   52     """Source directory for building the package.""" |  | 
|   53     srcdir = tmpdir.mkdir('src') |  | 
|   54     shutil.copy(TEST_METADATA, str(srcdir.join('metadata.edge'))) |  | 
|   55     for size in ['44', '50', '150']: |  | 
|   56         path = srcdir.join('chrome', 'icons', 'abp-{}.png'.format(size)) |  | 
|   57         path.write(size, ensure=True) |  | 
|   58     localedir = srcdir.mkdir('_locales') |  | 
|   59     en_us_dir = localedir.mkdir('en_US') |  | 
|   60     en_us_dir.join('messages.json').write(MESSAGES_EN_US) |  | 
|   61     return srcdir |  | 
|   62  |   23  | 
|   63  |   24  | 
|   64 def blockmap2dict(xml_data): |   25 def blockmap2dict(xml_data): | 
|   65     """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" |   26     """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" | 
|   66     return { |   27     return { | 
|   67         file.get('Name'): { |   28         file.get('Name'): { | 
|   68             'size': file.get('Size'), |   29             'size': file.get('Size'), | 
|   69             'lfhsize': file.get('LfhSize'), |   30             'lfhsize': file.get('LfhSize'), | 
|   70             'blocks': [b.get('Hash') for b in file] |   31             'blocks': [b.get('Hash') for b in file] | 
|   71         } |   32         } | 
|   72         for file in ET.fromstring(xml_data) |   33         for file in ET.fromstring(xml_data) | 
|   73     } |   34     } | 
|   74  |   35  | 
|   75  |   36  | 
|   76 def test_create_appx_blockmap(files): |   37 def test_create_appx_blockmap(base_files): | 
|   77     blockmap = blockmap2dict(packagerEdge.create_appx_blockmap(files)) |   38     blockmap = blockmap2dict(packagerEdge.create_appx_blockmap(base_files)) | 
|   78     assert blockmap['Extension\\foo.xml'] == { |   39     assert blockmap['Extension\\foo.xml'] == { | 
|   79         'size': '500', |   40         'size': '500', | 
|   80         'lfhsize': '47', |   41         'lfhsize': '47', | 
|   81         'blocks': ['Vhwfmzss1Ney+j/ssR2QVISvFyMNBQeS2P+UjeE/di0='] |   42         'blocks': ['Vhwfmzss1Ney+j/ssR2QVISvFyMNBQeS2P+UjeE/di0='] | 
|   82     } |   43     } | 
|   83     assert blockmap['Extension\\bar.png'] == { |   44     assert blockmap['Extension\\bar.png'] == { | 
|   84         'size': '100000', |   45         'size': '100000', | 
|   85         'lfhsize': '47', |   46         'lfhsize': '47', | 
|   86         'blocks': [ |   47         'blocks': [ | 
|   87             'KPW2SxeEikUEGhoKmKxruUSexKun0bGXMppOqUFrX5E=', |   48             'KPW2SxeEikUEGhoKmKxruUSexKun0bGXMppOqUFrX5E=', | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  122         'otf': 'application/octet-stream', |   83         'otf': 'application/octet-stream', | 
|  123         'png': 'image/png', |   84         'png': 'image/png', | 
|  124         'xml': 'application/xml' |   85         'xml': 'application/xml' | 
|  125     } |   86     } | 
|  126     assert ctm_dict['overrides'] == { |   87     assert ctm_dict['overrides'] == { | 
|  127         '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', |   88         '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', | 
|  128         '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' |   89         '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' | 
|  129     } |   90     } | 
|  130  |   91  | 
|  131  |   92  | 
|  132 def test_create_appx_manifest(metadata, files): |   93 @pytest.mark.parametrize('release_build', [True, False]) | 
|  133     namespaces = { |   94 def test_create_appx_manifest(base_files, srcdir, release_build, | 
|  134         'ns': 'http://schemas.microsoft.com/' |   95                               edge_metadata): | 
|  135               'appx/manifest/foundation/windows10', |   96     manifest = ET.fromstring(packagerEdge.create_appx_manifest( | 
|  136         'uap': 'http://schemas.microsoft.com/appx/manifest/uap/windows10', |   97         {'metadata': edge_metadata}, | 
|  137         'uap3': 'http://schemas.microsoft.com/appx/manifest/uap/windows10/3', |   98         base_files, | 
|  138     } |   99         release_build=release_build)) | 
|  139  |  100  | 
|  140     def first(elem): |  101     xmlpath = os.path.join( | 
|  141         return elem[0] |  102         os.path.dirname(__file__), | 
 |  103         'expecteddata', | 
 |  104         'manifest_edge_{}.xml'.format(release_build) | 
 |  105     ) | 
|  142  |  106  | 
|  143     def text(elem): |  107     with io.open(xmlpath, 'r') as fp: | 
|  144         return elem.text |  108         expected = ET.fromstring(fp.read()) | 
|  145  |  109  | 
|  146     def attr(attr): |  110     from buildtools.tests.tools import get_leafs_string | 
|  147         def wrapper(elem): |  111     assert set(get_leafs_string(expected)) == set(get_leafs_string(manifest)) | 
|  148             return elem.attrib[attr] |  | 
|  149         return wrapper |  | 
|  150  |  | 
|  151     base = [ |  | 
|  152         ('.//*', [len], 21.0), |  | 
|  153         ('./ns:Identity', [first, attr('Publisher')], |  | 
|  154             'CN=4F066043-8AFE-41C9-B762-6C15E77E3F88'), |  | 
|  155         ('./ns:Identity', [first, attr('Version')], '1.2.3.0'), |  | 
|  156         ('./ns:Properties/ns:PublisherDisplayName', [first, text], |  | 
|  157             'Eyeo GmbH'), |  | 
|  158         ('./ns:Properties/ns:Logo', [first, text], 'Assets\\logo_50.png'), |  | 
|  159         ('./ns:Dependencies/ns:TargetDeviceFamily', |  | 
|  160             [first, attr('MinVersion')], |  | 
|  161             '10.0.14332.0'), |  | 
|  162         ('./ns:Dependencies/ns:TargetDeviceFamily', |  | 
|  163             [first, attr('MaxVersionTested')], |  | 
|  164             '12.0.0.0'), |  | 
|  165         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  166             [first, attr('Square150x150Logo')], |  | 
|  167             'Assets\\logo_150.png'), |  | 
|  168         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  169             [first, attr('Square44x44Logo')], |  | 
|  170             'Assets\\logo_44.png'), |  | 
|  171         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  172             [first, attr('Description')], |  | 
|  173             'Adblock Plus is the most popular ad blocker ever, and also ' |  | 
|  174             'supports websites by not blocking unobstrusive ads by ' |  | 
|  175             'default (configurable).'), |  | 
|  176         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  177             [first, attr('BackgroundColor')], |  | 
|  178             'red'), |  | 
|  179     ] |  | 
|  180  |  | 
|  181     devbuild = base + [ |  | 
|  182         ('./ns:Identity', [first, attr('Name')], |  | 
|  183             'EyeoGmbH.AdblockPlusdevelopmentbuild'), |  | 
|  184         ('./ns:Properties/ns:DisplayName', [first, text], 'devbuild-marker'), |  | 
|  185         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  186             [first, attr('DisplayName')], |  | 
|  187             'devbuild-marker'), |  | 
|  188         ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |  | 
|  189             'uap3:AppExtension', |  | 
|  190             [first, attr('Id')], |  | 
|  191             'EdgeExtension'), |  | 
|  192         ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |  | 
|  193             'uap3:AppExtension', |  | 
|  194             [first, attr('DisplayName')], |  | 
|  195             'devbuild-marker'), |  | 
|  196     ] |  | 
|  197  |  | 
|  198     release = base + [ |  | 
|  199         ('./ns:Identity', [first, attr('Name')], 'EyeoGmbH.AdblockPlus'), |  | 
|  200         ('./ns:Properties/ns:DisplayName', [first, text], 'Adblock Plus'), |  | 
|  201         ('./ns:Applications/ns:Application/uap:VisualElements', |  | 
|  202             [first, attr('DisplayName')], |  | 
|  203             'Adblock Plus'), |  | 
|  204         ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |  | 
|  205             'uap3:AppExtension', |  | 
|  206             [first, attr('Id')], |  | 
|  207             '1.0'), |  | 
|  208         ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |  | 
|  209             'uap3:AppExtension', |  | 
|  210             [first, attr('DisplayName')], |  | 
|  211             'Adblock Plus'), |  | 
|  212     ] |  | 
|  213  |  | 
|  214     for release_build, pairs in [(False, devbuild), (True, release)]: |  | 
|  215         manifest = ET.fromstring(packagerEdge.create_appx_manifest( |  | 
|  216             {'metadata': metadata}, |  | 
|  217             files, |  | 
|  218             release_build=release_build)) |  | 
|  219         for expression, modifiers, value in pairs: |  | 
|  220             res = reduce( |  | 
|  221                 lambda val, func: func(val), |  | 
|  222                 modifiers, |  | 
|  223                 manifest.findall(expression, namespaces=namespaces)) |  | 
|  224             assert res == value |  | 
|  225  |  112  | 
|  226  |  113  | 
|  227 def test_move_files_to_extension(): |  114 def test_move_files_to_extension(str500chars): | 
|  228     files = packager.Files(set(), set()) |  115     files = packager.Files(set(), set()) | 
|  229     files['foo.xml'] = CHARS |  116     files['foo.xml'] = str500chars | 
|  230     files['foo/bar.xml'] = CHARS |  117     files['foo/bar.xml'] = str500chars | 
|  231     files['Extension/foo.xml'] = CHARS |  118     files['Extension/foo.xml'] = str500chars | 
|  232     packagerEdge.move_files_to_extension(files) |  119     packagerEdge.move_files_to_extension(files) | 
|  233     assert set(files.keys()) == { |  120     assert set(files.keys()) == { | 
|  234         'Extension/foo.xml', |  121         'Extension/foo.xml', | 
|  235         'Extension/foo/bar.xml', |  122         'Extension/foo/bar.xml', | 
|  236         'Extension/Extension/foo.xml' |  123         'Extension/Extension/foo.xml' | 
|  237     } |  124     } | 
|  238  |  125  | 
|  239  |  126  | 
 |  127 @pytest.mark.usefixtures('edge_metadata') | 
|  240 def test_create_build(tmpdir, srcdir): |  128 def test_create_build(tmpdir, srcdir): | 
|  241     out_file = str(tmpdir.join('abp.appx')) |  129     out_file = str(tmpdir.join('abp.appx')) | 
|  242     packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=True) |  130     packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=True) | 
|  243     appx = zipfile.ZipFile(out_file) |  131     appx = zipfile.ZipFile(out_file) | 
|  244  |  132  | 
|  245     names = set(appx.namelist()) |  133     names = set(appx.namelist()) | 
|  246     assert 'AppxManifest.xml' in names |  134     assert 'AppxManifest.xml' in names | 
|  247     assert 'AppxBlockMap.xml' in names |  135     assert 'AppxBlockMap.xml' in names | 
|  248     assert '[Content_Types].xml' in names |  136     assert '[Content_Types].xml' in names | 
|  249  |  137  | 
|  250     assert 'devbuild-marker' not in appx.read('AppxManifest.xml') |  138     assert 'devbuild-marker' not in appx.read('AppxManifest.xml') | 
|  251     assert appx.read('Assets/logo_44.png') == '44' |  139     assert appx.read('Assets/logo_44.png') == '44' | 
|  252     assert appx.read('Extension/icons/abp-44.png') == '44' |  140     assert appx.read('Extension/icons/abp-44.png') == '44' | 
|  253  |  141  | 
|  254  |  142  | 
 |  143 @pytest.mark.usefixtures('edge_metadata') | 
|  255 def test_create_devbuild(tmpdir, srcdir): |  144 def test_create_devbuild(tmpdir, srcdir): | 
|  256     out_file = str(tmpdir.join('abp.appx')) |  145     out_file = str(tmpdir.join('abp.appx')) | 
|  257     packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=False) |  146     packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=False) | 
|  258     appx = zipfile.ZipFile(out_file) |  147     appx = zipfile.ZipFile(out_file) | 
|  259     assert 'devbuild-marker' in appx.read('AppxManifest.xml') |  148     assert 'devbuild-marker' in appx.read('AppxManifest.xml') | 
| OLD | NEW |