Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: tests/test_packagerChrome.py

Issue 29501558: Issue 5383 - Add tests for the Chrome and Firefox packagers (Closed)
Patch Set: Adding pytest-cov, adhering to comments Created Aug. 14, 2017, 2:19 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5 import re
6 import os
7 import json
8 import zipfile
9
10 from xml.etree import ElementTree
11 from Crypto.Hash import SHA
12 import pytest
13
14 from buildtools import packager, packagerChrome
15 from buildtools.tests.tools import copy_metadata
16
17 ICON_SIZES = [32, 48, 64, 256, 53]
18
19 GECKO_DEV_UPDATE_URL = (
20 'https://downloads.adblockplus.org/devbuilds/'
21 'adblockplusfirefox/updates.json'
22 )
23
24 MINIMUM_MANIFEST = {
25 'manifest_version': 2,
26 'author': 'Eyeo GmbH',
27 'permissions': [
28 'tabs',
29 '<all_urls>',
30 'contextMenus',
31 'webRequest',
32 'webRequestBlocking',
33 'webNavigation',
34 'storage',
35 'unlimitedStorage',
36 'notifications',
37 ],
38 'minimum_chrome_version': '49.0',
39 'minimum_opera_version': '36.0',
40 'devtools_page': 'devtools.html',
41 'description': '__MSG_description__',
42 'default_locale': 'en_US',
43 'short_name': '__MSG_name__',
44 'storage': {'managed_schema': 'managed-storage-schema.json'},
45 'options_ui': {'open_in_tab': True, 'page': 'options.html'},
46 }
47
48
49 @pytest.fixture
50 def lib_files(tmpdir):
51 files = packager.Files(['lib'], set())
52 files['lib/a.js'] = 'var bar;'
53 files['lib/b.js'] = 'var foo;'
54
55 lib_dir = tmpdir.mkdir('lib')
56
57 lib_dir.join('a.js').write(files['lib/a.js'])
58 lib_dir.join('b.js').write(files['lib/b.js'])
59 return files
60
61
62 @pytest.fixture
63 def chrome_metadata(tmpdir):
64 filename = 'metadata.chrome'
65 copy_metadata(filename, tmpdir)
66
67 return packager.readMetadata(str(tmpdir), 'chrome')
68
69
70 @pytest.fixture
71 def gecko_webext_metadata(tmpdir, chrome_metadata):
72 filename = 'metadata.gecko-webext'
73 copy_metadata(filename, tmpdir)
74
75 return packager.readMetadata(str(tmpdir), 'gecko-webext')
76
77
78 @pytest.fixture
79 def icons(tmpdir):
80 """Valid .png files for testing make_icons"""
81 from PIL import Image
82
83 paths = []
84 icon_dir = tmpdir.mkdir('tmp_icons')
85
86 for size in ICON_SIZES:
87 img_path = str(icon_dir.join('abp-{}.png'.format(size)))
88 img = Image.new('1', (size, size if size != 53 else size + 1), 0)
89 img.save(img_path)
90 paths.append(img_path)
91
92 return paths
93
94
95 @pytest.fixture
96 def keyfile(tmpdir):
97 """Test-privatekey for signing files"""
98 return os.path.join(os.path.dirname(__file__), 'chrome_rsa.pem')
99
100
101 @pytest.mark.parametrize('release', [True, False])
102 @pytest.mark.parametrize('devenv', [True, False])
103 @pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext'])
104 def test_create_manifest(srcdir, base_files, release, devenv, ext_type,
105 chrome_metadata, gecko_webext_metadata):
106
107 if ext_type == 'chrome':
108 metadata = chrome_metadata
109 else:
110 metadata = gecko_webext_metadata
111
112 version = packager.getBuildVersion(str(srcdir), metadata, release)
113 params = {
114 'type': ext_type,
115 'baseDir': str(srcdir),
116 'releaseBuild': release,
117 'version': version,
118 'devenv': devenv,
119 'metadata': metadata,
120 }
121 manifest = json.loads(packagerChrome.createManifest(params, base_files))
122
123 if ext_type == 'gecko-webext':
124 gecko_app = manifest['applications']['gecko']
125
126 assert gecko_app['id'] == '{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
127 assert gecko_app['strict_min_version'] == '50.0'
128 if not release:
129 assert gecko_app['update_url'] == GECKO_DEV_UPDATE_URL
130
131 if release:
132 assert manifest['name'] == '__MSG_name__'
133 assert manifest['version'] == '1.2.3'
134 else:
135 assert manifest['name'] == '__MSG_name_devbuild__'
136 assert manifest['version'] == '1.2.3.0'
137
138 for key, value in MINIMUM_MANIFEST.items():
139 assert manifest.get(key, None) == value
140
141
142 def test_sign_binary(base_files, keyfile):
143 from Crypto.PublicKey import RSA
144 from Crypto.Signature import PKCS1_v1_5
145
146 digest = SHA.new()
147
148 signature = packagerChrome.signBinary(base_files.zipToString(), keyfile)
149
150 with open(keyfile, 'r') as fp:
151 rsa_key = RSA.importKey(fp.read())
152
153 signer = PKCS1_v1_5.new(rsa_key)
154
155 digest.update(base_files.zipToString())
156 assert signer.verify(digest, signature)
157
158
159 def test_get_public_key(keyfile):
160 expected_hash = '8dfe9486446eb4da8ce15dd18f5dfd6a776c2674'
161
162 publickey = packagerChrome.getPublicKey(keyfile)
163 assert SHA.new(publickey).hexdigest() == expected_hash
164
165
166 @pytest.mark.usefixtures('chrome_metadata')
167 @pytest.mark.parametrize('devenv', [True, False])
168 def test_get_package_files(srcdir, devenv):
169 filenames = [
170 'foo.html',
171 'foo.js',
172 'foo.json',
173 'foo.xml',
174 ]
175
176 for filename in filenames:
177 srcdir.join(filename).write('', ensure=True)
178
179 params = {
180 'baseDir': str(srcdir),
181 'devenv': devenv,
182 }
183
184 files = packagerChrome.getPackageFiles(params)
185
186 assert ('qunit' in files) == devenv
187
188 for expected in ['icons', 'ui', 'skin', 'ext', '_locales', 'lib',
189 'jquery-ui'] + [name for name in filenames]:
190 assert expected in files
191
192
193 def test_make_icons(icons, capsys):
194 files = packager.Files(set(), set())
195 for path in icons:
196 files[path] = open(path, 'r').read()
197 result = packagerChrome.makeIcons(files, icons)
198
199 out, err = capsys.readouterr()
200
201 assert 'should be square' in err
202 assert set(result) == set(ICON_SIZES)
203
204
205 def test_create_script_page(srcdir, chrome_metadata):
206 params = {'metadata': chrome_metadata}
207
208 template = packagerChrome.createScriptPage(
209 params, 'testIndex.html.tmpl', ('general', 'testScripts')
210 )
211
212 template_scripts = {elem.attrib['src'] for elem in
213 ElementTree.fromstring(template).iter('script')}
214
215 for src in chrome_metadata.get('general', 'testScripts').split():
216 assert src in template_scripts
217
218
219 def test_convert_js(srcdir, chrome_metadata, lib_files):
220 params = {
221 'type': 'chrome',
222 'metadata': chrome_metadata,
223 }
224
225 packagerChrome.convertJS(params, lib_files)
226 source = lib_files['lib/foo.js']
227
228 assert 'var foo;' in source
229 assert 'var bar;' in source
230
231
232 def test_to_json():
233 data = {'bar': ['foo', 'foobar', 1, True]}
234 data_json = packagerChrome.toJson(data)
235
236 assert data_json.endswith('\n')
237 assert json.loads(data_json) == data
238
239
240 def test_import_gecko_locales(tmpdir, srcdir, base_files, chrome_metadata):
241 version = packager.getBuildVersion(str(srcdir), chrome_metadata, False)
242 params = {
243 'type': 'chrome',
244 'baseDir': str(srcdir),
245 'releaseBuild': False,
246 'version': version,
247 'devenv': False,
248 'metadata': chrome_metadata,
249 }
250
251 data = {'name': 'foo', 'name_devbuild': 'bar'}
252
253 t_dir = tmpdir.mkdir('_trans').mkdir('en-US')
254 t_dir.join('test.properties').write(
255 '\n'.join('{}={}'.format(k, v) for k, v in data.items()))
256
257 packagerChrome.importGeckoLocales(params, base_files)
258 trans_data = json.loads(base_files['_locales/en_US/messages.json'])
259
260 for key, value in data.items():
261 assert trans_data.get('test_' + key, {}).get('message', '') == value
262
263
264 def test_fix_translations_for_cws(base_files):
265 base_files['_locales/de/messages.json'] = packagerChrome.toJson({})
266 base_files['manifest.json'] = packagerChrome.toJson(MINIMUM_MANIFEST)
267 packagerChrome.fixTranslationsForCWS(base_files)
268
269 ger_messages = json.loads(base_files['_locales/de/messages.json'])
270 eng_messages = json.loads(base_files['_locales/en_US/messages.json'])
271
272 # Check for inserted translations, none were present in 'de' beforehand
273 for match in re.finditer(r'__MSG_(\S+)__', base_files['manifest.json']):
274 name = match.group(1)
275 assert ger_messages[name]['message'] == eng_messages[name]['message']
276
277 # CWS enforces max-lengths on string
278 assert len(ger_messages['description']['message']) <= 132
279 assert len(ger_messages['name']['message']) <= 12
280
281
282 @pytest.mark.usefixtures('base_files', 'lib_files',
283 'gecko_webext_metadata', 'chrome_metadata')
284 @pytest.mark.parametrize('release', [True, False])
285 @pytest.mark.parametrize('devenv', [True, False])
286 @pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext'])
287 @pytest.mark.parametrize('key', [True, False])
288 def test_create_build(srcdir, tmpdir, release, devenv, ext_type,
289 key, keyfile):
290
291 basefiles = [
292 'manifest.json',
293 'lib/foo.js',
294 'foo/logo_50.png',
295 '_locales/en_US/messages.json',
296 '_locales/en-US/test.properties',
297 'logo_44.png',
298 'icons/logo_150.png',
299 ]
300
301 out_file = str(tmpdir.join('out'))
302
303 packagerChrome.createBuild(
304 outFile=out_file,
305 baseDir=str(srcdir),
306 type=ext_type,
307 releaseBuild=release,
308 keyFile=keyfile if key else None,
309 devenv=devenv)
310
311 with zipfile.ZipFile(out_file, 'r') as zipfp:
312 zipfp.testzip()
313
314 filenames = [zipinfo.filename for zipinfo in zipfp.infolist()]
315 for filename in basefiles if not devenv else basefiles + [
316 'devenvPoller__.js',
317 'devenvVersion__',
318 'qunit/index.html',
319 ]:
320 assert filename in filenames
OLDNEW

Powered by Google App Engine
This is Rietveld