| 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 | |
| 8 import shutil | |
| 9 import xml.etree.ElementTree as ET | 5 import xml.etree.ElementTree as ET |
| 10 import zipfile | 6 import zipfile |
| 11 | 7 |
| 12 import pytest | 8 import pytest |
| 13 | 9 |
| 14 from buildtools import packager, packagerEdge | 10 from buildtools import packager, packagerEdge |
| 15 | 11 |
| 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 | |
| 29 | |
| 30 @pytest.fixture | |
| 31 def metadata(): | |
| 32 """Loaded metadata config.""" | |
| 33 conf_parser = ConfigParser.ConfigParser() | |
| 34 conf_parser.read(TEST_METADATA) | |
| 35 return conf_parser | |
| 36 | |
| 37 | |
| 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 | |
| 63 | 12 |
| 64 def blockmap2dict(xml_data): | 13 def blockmap2dict(xml_data): |
| 65 """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" | 14 """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" |
| 66 return { | 15 return { |
| 67 file.get('Name'): { | 16 file.get('Name'): { |
| 68 'size': file.get('Size'), | 17 'size': file.get('Size'), |
| 69 'lfhsize': file.get('LfhSize'), | 18 'lfhsize': file.get('LfhSize'), |
| 70 'blocks': [b.get('Hash') for b in file] | 19 'blocks': [b.get('Hash') for b in file] |
| 71 } | 20 } |
| 72 for file in ET.fromstring(xml_data) | 21 for file in ET.fromstring(xml_data) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 'otf': 'application/octet-stream', | 71 'otf': 'application/octet-stream', |
| 123 'png': 'image/png', | 72 'png': 'image/png', |
| 124 'xml': 'application/xml' | 73 'xml': 'application/xml' |
| 125 } | 74 } |
| 126 assert ctm_dict['overrides'] == { | 75 assert ctm_dict['overrides'] == { |
| 127 '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', | 76 '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', |
| 128 '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' | 77 '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' |
| 129 } | 78 } |
| 130 | 79 |
| 131 | 80 |
| 132 def test_create_appx_manifest(metadata, files): | 81 @pytest.mark.parametrize('metadata_files', ['metadata.edge'], indirect=True) |
| 82 @pytest.mark.usefixtures('metadata_files') |
| 83 def test_create_appx_manifest(files, srcdir): |
| 133 namespaces = { | 84 namespaces = { |
| 134 'ns': 'http://schemas.microsoft.com/' | 85 'ns': 'http://schemas.microsoft.com/' |
| 135 'appx/manifest/foundation/windows10', | 86 'appx/manifest/foundation/windows10', |
| 136 'uap': 'http://schemas.microsoft.com/appx/manifest/uap/windows10', | 87 'uap': 'http://schemas.microsoft.com/appx/manifest/uap/windows10', |
| 137 'uap3': 'http://schemas.microsoft.com/appx/manifest/uap/windows10/3', | 88 'uap3': 'http://schemas.microsoft.com/appx/manifest/uap/windows10/3', |
| 138 } | 89 } |
| 139 | 90 |
| 140 def first(elem): | 91 def first(elem): |
| 141 return elem[0] | 92 return elem[0] |
| 142 | 93 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' | 155 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |
| 205 'uap3:AppExtension', | 156 'uap3:AppExtension', |
| 206 [first, attr('Id')], | 157 [first, attr('Id')], |
| 207 '1.0'), | 158 '1.0'), |
| 208 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' | 159 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' |
| 209 'uap3:AppExtension', | 160 'uap3:AppExtension', |
| 210 [first, attr('DisplayName')], | 161 [first, attr('DisplayName')], |
| 211 'Adblock Plus'), | 162 'Adblock Plus'), |
| 212 ] | 163 ] |
| 213 | 164 |
| 165 metadata = packager.readMetadata(str(srcdir), 'edge') |
| 166 |
| 214 for release_build, pairs in [(False, devbuild), (True, release)]: | 167 for release_build, pairs in [(False, devbuild), (True, release)]: |
| 215 manifest = ET.fromstring(packagerEdge.create_appx_manifest( | 168 manifest = ET.fromstring(packagerEdge.create_appx_manifest( |
| 216 {'metadata': metadata}, | 169 {'metadata': metadata}, |
| 217 files, | 170 files, |
| 218 release_build=release_build)) | 171 release_build=release_build)) |
| 219 for expression, modifiers, value in pairs: | 172 for expression, modifiers, value in pairs: |
| 220 res = reduce( | 173 res = reduce( |
| 221 lambda val, func: func(val), | 174 lambda val, func: func(val), |
| 222 modifiers, | 175 modifiers, |
| 223 manifest.findall(expression, namespaces=namespaces)) | 176 manifest.findall(expression, namespaces=namespaces)) |
| 224 assert res == value | 177 assert res == value |
| 225 | 178 |
| 226 | 179 |
| 227 def test_move_files_to_extension(): | 180 def test_move_files_to_extension(chars): |
| 228 files = packager.Files(set(), set()) | 181 files = packager.Files(set(), set()) |
| 229 files['foo.xml'] = CHARS | 182 files['foo.xml'] = chars |
| 230 files['foo/bar.xml'] = CHARS | 183 files['foo/bar.xml'] = chars |
| 231 files['Extension/foo.xml'] = CHARS | 184 files['Extension/foo.xml'] = chars |
| 232 packagerEdge.move_files_to_extension(files) | 185 packagerEdge.move_files_to_extension(files) |
| 233 assert set(files.keys()) == { | 186 assert set(files.keys()) == { |
| 234 'Extension/foo.xml', | 187 'Extension/foo.xml', |
| 235 'Extension/foo/bar.xml', | 188 'Extension/foo/bar.xml', |
| 236 'Extension/Extension/foo.xml' | 189 'Extension/Extension/foo.xml' |
| 237 } | 190 } |
| 238 | 191 |
| 239 | 192 |
| 193 @pytest.mark.parametrize('metadata_files', ['metadata.edge'], indirect=True) |
| 194 @pytest.mark.usefixtures('metadata_files') |
| 240 def test_create_build(tmpdir, srcdir): | 195 def test_create_build(tmpdir, srcdir): |
| 241 out_file = str(tmpdir.join('abp.appx')) | 196 out_file = str(tmpdir.join('abp.appx')) |
| 242 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=True) | 197 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=True) |
| 243 appx = zipfile.ZipFile(out_file) | 198 appx = zipfile.ZipFile(out_file) |
| 244 | 199 |
| 245 names = set(appx.namelist()) | 200 names = set(appx.namelist()) |
| 246 assert 'AppxManifest.xml' in names | 201 assert 'AppxManifest.xml' in names |
| 247 assert 'AppxBlockMap.xml' in names | 202 assert 'AppxBlockMap.xml' in names |
| 248 assert '[Content_Types].xml' in names | 203 assert '[Content_Types].xml' in names |
| 249 | 204 |
| 250 assert 'devbuild-marker' not in appx.read('AppxManifest.xml') | 205 assert 'devbuild-marker' not in appx.read('AppxManifest.xml') |
| 251 assert appx.read('Assets/logo_44.png') == '44' | 206 assert appx.read('Assets/logo_44.png') == '44' |
| 252 assert appx.read('Extension/icons/abp-44.png') == '44' | 207 assert appx.read('Extension/icons/abp-44.png') == '44' |
| 253 | 208 |
| 254 | 209 |
| 210 @pytest.mark.parametrize('metadata_files', ['metadata.edge'], indirect=True) |
| 211 @pytest.mark.usefixtures('metadata_files') |
| 255 def test_create_devbuild(tmpdir, srcdir): | 212 def test_create_devbuild(tmpdir, srcdir): |
| 256 out_file = str(tmpdir.join('abp.appx')) | 213 out_file = str(tmpdir.join('abp.appx')) |
| 257 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=False) | 214 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=False) |
| 258 appx = zipfile.ZipFile(out_file) | 215 appx = zipfile.ZipFile(out_file) |
| 259 assert 'devbuild-marker' in appx.read('AppxManifest.xml') | 216 assert 'devbuild-marker' in appx.read('AppxManifest.xml') |
| OLD | NEW |