 Issue 29501558:
  Issue 5383 - Add tests for the Chrome and Firefox packagers  (Closed)
    
  
    Issue 29501558:
  Issue 5383 - Add tests for the Chrome and Firefox packagers  (Closed) 
  | Left: | ||
| Right: | 
| 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 | |
| 9 import xml.etree.ElementTree as ET | |
| 10 import zipfile | |
| 11 | |
| 12 import pytest | 6 import pytest | 
| 13 | 7 | 
| 8 import xml.etree.ElementTree as ET | |
| 9 | |
| 10 from buildtools.tests.tools import (ZipContent, run_webext_build, locale_files, | |
| 11 copy_metadata, assert_manifest_content, | |
| 12 assert_all_locales_present) | |
| 13 from buildtools.tests.conftest import ALL_LANGUAGES | |
| 14 from buildtools import packager, packagerEdge | 14 from buildtools import packager, packagerEdge | 
| 15 | 15 | 
| 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 | 16 | 
| 30 @pytest.fixture | 17 @pytest.fixture | 
| 31 def metadata(): | 18 def locale_files_edge(tmpdir): | 
| 32 """Loaded metadata config.""" | 19 return locale_files(ALL_LANGUAGES, '_locales', tmpdir) | 
| 33 conf_parser = ConfigParser.ConfigParser() | 20 | 
| 34 conf_parser.read(TEST_METADATA) | 21 | 
| 35 return conf_parser | 22 @pytest.fixture | 
| 23 def edge_metadata(tmpdir): | |
| 24 filename = 'metadata.edge' | |
| 25 copy_metadata(filename, tmpdir) | |
| 26 | |
| 27 return packager.readMetadata(str(tmpdir), 'edge') | |
| 36 | 28 | 
| 37 | 29 | 
| 38 @pytest.fixture | 30 @pytest.fixture | 
| 39 def files(): | 31 def files(): | 
| 40 """Minimal Files() for testing manifest and blockmap.""" | 32 """Minimal Files() for testing blockmap.""" | 
| 33 str500 = b''.join(chr(i % 200 + 30) for i in range(500)) | |
| 41 files = packager.Files(set(), set()) | 34 files = packager.Files(set(), set()) | 
| 42 for size in ['44', '50', '150']: | 35 files['Extension/foo.xml'] = str500 | 
| 43 files['Assets/logo_{}.png'.format(size)] = CHARS | 36 files['Extension/bar.png'] = str500 * 200 | 
| 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 | 37 return files | 
| 48 | 38 | 
| 49 | 39 | 
| 50 @pytest.fixture | 40 @pytest.fixture | 
| 51 def srcdir(tmpdir): | 41 def js_extensions(srcdir): | 
| 52 """Source directory for building the package.""" | 42 srcdir.mkdir('ext').join('foo.js').write('var foo;') | 
| 53 srcdir = tmpdir.mkdir('src') | 43 srcdir.join('bar.js').write('var bar;') | 
| 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 | 44 | 
| 63 | 45 | 
| 64 def blockmap2dict(xml_data): | 46 def blockmap2dict(xml_data): | 
| 65 """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" | 47 """Convert AppxBlockMap.xml to a dict of dicts easier to inspect.""" | 
| 66 return { | 48 return { | 
| 67 file.get('Name'): { | 49 file.get('Name'): { | 
| 68 'size': file.get('Size'), | 50 'size': file.get('Size'), | 
| 69 'lfhsize': file.get('LfhSize'), | 51 'lfhsize': file.get('LfhSize'), | 
| 70 'blocks': [b.get('Hash') for b in file] | 52 'blocks': [b.get('Hash') for b in file] | 
| 71 } | 53 } | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 'otf': 'application/octet-stream', | 104 'otf': 'application/octet-stream', | 
| 123 'png': 'image/png', | 105 'png': 'image/png', | 
| 124 'xml': 'application/xml' | 106 'xml': 'application/xml' | 
| 125 } | 107 } | 
| 126 assert ctm_dict['overrides'] == { | 108 assert ctm_dict['overrides'] == { | 
| 127 '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', | 109 '/AppxBlockMap.xml': 'application/vnd.ms-appx.blockmap+xml', | 
| 128 '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' | 110 '/AppxManifest.xml': 'application/vnd.ms-appx.manifest+xml' | 
| 129 } | 111 } | 
| 130 | 112 | 
| 131 | 113 | 
| 132 def test_create_appx_manifest(metadata, files): | 114 @pytest.mark.usefixtures('locale_files_edge', 'js_extensions') | 
| 133 namespaces = { | 115 @pytest.mark.parametrize('dev_build_release,buildnum', [ | 
| 134 'ns': 'http://schemas.microsoft.com/' | 116 pytest.param('devenv', None, marks=pytest.mark.xfail), | 
| 135 'appx/manifest/foundation/windows10', | 117 ('release', None), | 
| 136 'uap': 'http://schemas.microsoft.com/appx/manifest/uap/windows10', | 118 ('build', '1337'), | 
| 137 'uap3': 'http://schemas.microsoft.com/appx/manifest/uap/windows10/3', | 119 ]) | 
| 138 } | 120 def test_build_edge(dev_build_release, tmpdir, srcdir, edge_metadata, | 
| 121 buildnum): | |
| 122 release = dev_build_release == 'release' | |
| 139 | 123 | 
| 140 def first(elem): | 124 run_webext_build('edge', dev_build_release, srcdir, buildnum=buildnum) | 
| 141 return elem[0] | |
| 142 | 125 | 
| 143 def text(elem): | 126 if release: | 
| 144 return elem.text | 127 out_file = 'adblockplusedge-1.2.3.appx' | 
| 128 else: | |
| 129 out_file = 'adblockplusedge-1.2.3.{}.appx'.format(buildnum) | |
| 145 | 130 | 
| 146 def attr(attr): | 131 with ZipContent(out_file) as package: | 
| 147 def wrapper(elem): | 132 filenames = set(package.namelist()) | 
| 148 return elem.attrib[attr] | |
| 149 return wrapper | |
| 150 | 133 | 
| 151 base = [ | 134 assert_all_locales_present(package, 'Extension/_locales') | 
| 152 ('.//*', [len], 21.0), | |
| 153 ('./ns:Identity', [first, attr('Publisher')], | |
| 154 'CN=4F066043-8AFE-41C9-B762-6C15E77E3F88'), | |
| 155 ('./ns:Properties/ns:PublisherDisplayName', [first, text], | |
| 156 'Eyeo GmbH'), | |
| 157 ('./ns:Properties/ns:Logo', [first, text], 'Assets\\logo_50.png'), | |
| 158 ('./ns:Dependencies/ns:TargetDeviceFamily', | |
| 159 [first, attr('MinVersion')], | |
| 160 '10.0.14332.0'), | |
| 161 ('./ns:Dependencies/ns:TargetDeviceFamily', | |
| 162 [first, attr('MaxVersionTested')], | |
| 163 '12.0.0.0'), | |
| 164 ('./ns:Applications/ns:Application/uap:VisualElements', | |
| 165 [first, attr('Square150x150Logo')], | |
| 166 'Assets\\logo_150.png'), | |
| 167 ('./ns:Applications/ns:Application/uap:VisualElements', | |
| 168 [first, attr('Square44x44Logo')], | |
| 169 'Assets\\logo_44.png'), | |
| 170 ('./ns:Applications/ns:Application/uap:VisualElements', | |
| 171 [first, attr('Description')], | |
| 172 'Adblock Plus is the most popular ad blocker ever, and also ' | |
| 173 'supports websites by not blocking unobstrusive ads by ' | |
| 174 'default (configurable).'), | |
| 175 ('./ns:Applications/ns:Application/uap:VisualElements', | |
| 176 [first, attr('BackgroundColor')], | |
| 177 'red'), | |
| 178 ] | |
| 179 | 135 | 
| 180 devbuild = base + [ | 136 assert 'AppxManifest.xml' in filenames | 
| 181 ('./ns:Identity', [first, attr('Name')], | 137 assert 'AppxBlockMap.xml' in filenames | 
| 182 'EyeoGmbH.AdblockPlusdevelopmentbuild'), | 138 assert '[Content_Types].xml' in filenames | 
| 183 ('./ns:Identity', [first, attr('Version')], '1.2.1000.0'), | |
| 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 | 139 | 
| 198 release = base + [ | 140 assert 'Extension/ext/foo.js' in filenames | 
| 199 ('./ns:Identity', [first, attr('Name')], 'EyeoGmbH.AdblockPlus'), | 141 assert 'Extension/bar.js' in filenames | 
| 200 ('./ns:Identity', [first, attr('Version')], '1.2.3.0'), | |
| 201 ('./ns:Properties/ns:DisplayName', [first, text], 'Adblock Plus'), | |
| 202 ('./ns:Applications/ns:Application/uap:VisualElements', | |
| 203 [first, attr('DisplayName')], | |
| 204 'Adblock Plus'), | |
| 205 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' | |
| 206 'uap3:AppExtension', | |
| 207 [first, attr('Id')], | |
| 208 '1.0'), | |
| 209 ('./ns:Applications/ns:Application/ns:Extensions/uap3:Extension/' | |
| 210 'uap3:AppExtension', | |
| 211 [first, attr('DisplayName')], | |
| 212 'Adblock Plus'), | |
| 213 ] | |
| 214 | 142 | 
| 215 for args, pairs in [(('1000', False), devbuild), ((None, True), release)]: | 143 assert package.read('Assets/logo_44.png') == '44' | 
| 216 manifest = ET.fromstring(packagerEdge.create_appx_manifest( | 144 assert package.read('Extension/icons/abp-44.png') == '44' | 
| 217 {'metadata': metadata}, files, *args | |
| 218 )) | |
| 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 | 145 | 
| 146 filename = '{{}}_edge_{}_{}.{{}}'.format(release, buildnum) | |
| 
Sebastian Noack
2017/09/21 19:09:04
The buildnum is redundant here. The filenames are
 
Sebastian Noack
2017/09/22 01:56:05
Also it is inconsistent with "edge" and "gecko-web
 
tlucas
2017/09/22 09:02:18
Done.
 | |
| 226 | 147 | 
| 227 def test_move_files_to_extension(): | 148 for folder, name, ext in [('', 'AppxManifest', 'xml'), | 
| 228 files = packager.Files(set(), set()) | 149 ('Extension', 'manifest', 'json')]: | 
| 229 files['foo.xml'] = CHARS | 150 expected = os.path.join( | 
| 230 files['foo/bar.xml'] = CHARS | 151 os.path.dirname(__file__), | 
| 231 files['Extension/foo.xml'] = CHARS | 152 'expecteddata', | 
| 232 packagerEdge.move_files_to_extension(files) | 153 filename.format(name, ext), | 
| 233 assert set(files.keys()) == { | 154 ) | 
| 234 'Extension/foo.xml', | |
| 235 'Extension/foo/bar.xml', | |
| 236 'Extension/Extension/foo.xml' | |
| 237 } | |
| 238 | 155 | 
| 239 | 156 assert_manifest_content( | 
| 240 def test_create_build(tmpdir, srcdir): | 157 package.read(os.path.join(folder, '{}.{}'.format(name, ext))), | 
| 241 out_file = str(tmpdir.join('abp.appx')) | 158 expected, | 
| 242 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=True) | 159 ) | 
| 243 appx = zipfile.ZipFile(out_file) | |
| 244 | |
| 245 names = set(appx.namelist()) | |
| 246 assert 'AppxManifest.xml' in names | |
| 247 assert 'AppxBlockMap.xml' in names | |
| 248 assert '[Content_Types].xml' in names | |
| 249 | |
| 250 assert 'devbuild-marker' not in appx.read('AppxManifest.xml') | |
| 251 assert appx.read('Assets/logo_44.png') == '44' | |
| 252 assert appx.read('Extension/icons/abp-44.png') == '44' | |
| 253 | |
| 254 | |
| 255 def test_create_devbuild(tmpdir, srcdir): | |
| 256 out_file = str(tmpdir.join('abp.appx')) | |
| 257 packagerEdge.createBuild(str(srcdir), outFile=out_file, releaseBuild=False) | |
| 258 appx = zipfile.ZipFile(out_file) | |
| 259 assert 'devbuild-marker' in appx.read('AppxManifest.xml') | |
| OLD | NEW |