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

Unified 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.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/test_packagerChrome.py
diff --git a/tests/test_packagerChrome.py b/tests/test_packagerChrome.py
new file mode 100644
index 0000000000000000000000000000000000000000..34fbe7a5ea4600c9cd9e96ac61c2f79e6b65b238
--- /dev/null
+++ b/tests/test_packagerChrome.py
@@ -0,0 +1,320 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import re
+import os
+import json
+import zipfile
+
+from xml.etree import ElementTree
+from Crypto.Hash import SHA
+import pytest
+
+from buildtools import packager, packagerChrome
+from buildtools.tests.tools import copy_metadata
+
+ICON_SIZES = [32, 48, 64, 256, 53]
+
+GECKO_DEV_UPDATE_URL = (
+ 'https://downloads.adblockplus.org/devbuilds/'
+ 'adblockplusfirefox/updates.json'
+)
+
+MINIMUM_MANIFEST = {
+ 'manifest_version': 2,
+ 'author': 'Eyeo GmbH',
+ 'permissions': [
+ 'tabs',
+ '<all_urls>',
+ 'contextMenus',
+ 'webRequest',
+ 'webRequestBlocking',
+ 'webNavigation',
+ 'storage',
+ 'unlimitedStorage',
+ 'notifications',
+ ],
+ 'minimum_chrome_version': '49.0',
+ 'minimum_opera_version': '36.0',
+ 'devtools_page': 'devtools.html',
+ 'description': '__MSG_description__',
+ 'default_locale': 'en_US',
+ 'short_name': '__MSG_name__',
+ 'storage': {'managed_schema': 'managed-storage-schema.json'},
+ 'options_ui': {'open_in_tab': True, 'page': 'options.html'},
+}
+
+
+@pytest.fixture
+def lib_files(tmpdir):
+ files = packager.Files(['lib'], set())
+ files['lib/a.js'] = 'var bar;'
+ files['lib/b.js'] = 'var foo;'
+
+ lib_dir = tmpdir.mkdir('lib')
+
+ lib_dir.join('a.js').write(files['lib/a.js'])
+ lib_dir.join('b.js').write(files['lib/b.js'])
+ return files
+
+
+@pytest.fixture
+def chrome_metadata(tmpdir):
+ filename = 'metadata.chrome'
+ copy_metadata(filename, tmpdir)
+
+ return packager.readMetadata(str(tmpdir), 'chrome')
+
+
+@pytest.fixture
+def gecko_webext_metadata(tmpdir, chrome_metadata):
+ filename = 'metadata.gecko-webext'
+ copy_metadata(filename, tmpdir)
+
+ return packager.readMetadata(str(tmpdir), 'gecko-webext')
+
+
+@pytest.fixture
+def icons(tmpdir):
+ """Valid .png files for testing make_icons"""
+ from PIL import Image
+
+ paths = []
+ icon_dir = tmpdir.mkdir('tmp_icons')
+
+ for size in ICON_SIZES:
+ img_path = str(icon_dir.join('abp-{}.png'.format(size)))
+ img = Image.new('1', (size, size if size != 53 else size + 1), 0)
+ img.save(img_path)
+ paths.append(img_path)
+
+ return paths
+
+
+@pytest.fixture
+def keyfile(tmpdir):
+ """Test-privatekey for signing files"""
+ return os.path.join(os.path.dirname(__file__), 'chrome_rsa.pem')
+
+
+@pytest.mark.parametrize('release', [True, False])
+@pytest.mark.parametrize('devenv', [True, False])
+@pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext'])
+def test_create_manifest(srcdir, base_files, release, devenv, ext_type,
+ chrome_metadata, gecko_webext_metadata):
+
+ if ext_type == 'chrome':
+ metadata = chrome_metadata
+ else:
+ metadata = gecko_webext_metadata
+
+ version = packager.getBuildVersion(str(srcdir), metadata, release)
+ params = {
+ 'type': ext_type,
+ 'baseDir': str(srcdir),
+ 'releaseBuild': release,
+ 'version': version,
+ 'devenv': devenv,
+ 'metadata': metadata,
+ }
+ manifest = json.loads(packagerChrome.createManifest(params, base_files))
+
+ if ext_type == 'gecko-webext':
+ gecko_app = manifest['applications']['gecko']
+
+ assert gecko_app['id'] == '{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}'
+ assert gecko_app['strict_min_version'] == '50.0'
+ if not release:
+ assert gecko_app['update_url'] == GECKO_DEV_UPDATE_URL
+
+ if release:
+ assert manifest['name'] == '__MSG_name__'
+ assert manifest['version'] == '1.2.3'
+ else:
+ assert manifest['name'] == '__MSG_name_devbuild__'
+ assert manifest['version'] == '1.2.3.0'
+
+ for key, value in MINIMUM_MANIFEST.items():
+ assert manifest.get(key, None) == value
+
+
+def test_sign_binary(base_files, keyfile):
+ from Crypto.PublicKey import RSA
+ from Crypto.Signature import PKCS1_v1_5
+
+ digest = SHA.new()
+
+ signature = packagerChrome.signBinary(base_files.zipToString(), keyfile)
+
+ with open(keyfile, 'r') as fp:
+ rsa_key = RSA.importKey(fp.read())
+
+ signer = PKCS1_v1_5.new(rsa_key)
+
+ digest.update(base_files.zipToString())
+ assert signer.verify(digest, signature)
+
+
+def test_get_public_key(keyfile):
+ expected_hash = '8dfe9486446eb4da8ce15dd18f5dfd6a776c2674'
+
+ publickey = packagerChrome.getPublicKey(keyfile)
+ assert SHA.new(publickey).hexdigest() == expected_hash
+
+
+@pytest.mark.usefixtures('chrome_metadata')
+@pytest.mark.parametrize('devenv', [True, False])
+def test_get_package_files(srcdir, devenv):
+ filenames = [
+ 'foo.html',
+ 'foo.js',
+ 'foo.json',
+ 'foo.xml',
+ ]
+
+ for filename in filenames:
+ srcdir.join(filename).write('', ensure=True)
+
+ params = {
+ 'baseDir': str(srcdir),
+ 'devenv': devenv,
+ }
+
+ files = packagerChrome.getPackageFiles(params)
+
+ assert ('qunit' in files) == devenv
+
+ for expected in ['icons', 'ui', 'skin', 'ext', '_locales', 'lib',
+ 'jquery-ui'] + [name for name in filenames]:
+ assert expected in files
+
+
+def test_make_icons(icons, capsys):
+ files = packager.Files(set(), set())
+ for path in icons:
+ files[path] = open(path, 'r').read()
+ result = packagerChrome.makeIcons(files, icons)
+
+ out, err = capsys.readouterr()
+
+ assert 'should be square' in err
+ assert set(result) == set(ICON_SIZES)
+
+
+def test_create_script_page(srcdir, chrome_metadata):
+ params = {'metadata': chrome_metadata}
+
+ template = packagerChrome.createScriptPage(
+ params, 'testIndex.html.tmpl', ('general', 'testScripts')
+ )
+
+ template_scripts = {elem.attrib['src'] for elem in
+ ElementTree.fromstring(template).iter('script')}
+
+ for src in chrome_metadata.get('general', 'testScripts').split():
+ assert src in template_scripts
+
+
+def test_convert_js(srcdir, chrome_metadata, lib_files):
+ params = {
+ 'type': 'chrome',
+ 'metadata': chrome_metadata,
+ }
+
+ packagerChrome.convertJS(params, lib_files)
+ source = lib_files['lib/foo.js']
+
+ assert 'var foo;' in source
+ assert 'var bar;' in source
+
+
+def test_to_json():
+ data = {'bar': ['foo', 'foobar', 1, True]}
+ data_json = packagerChrome.toJson(data)
+
+ assert data_json.endswith('\n')
+ assert json.loads(data_json) == data
+
+
+def test_import_gecko_locales(tmpdir, srcdir, base_files, chrome_metadata):
+ version = packager.getBuildVersion(str(srcdir), chrome_metadata, False)
+ params = {
+ 'type': 'chrome',
+ 'baseDir': str(srcdir),
+ 'releaseBuild': False,
+ 'version': version,
+ 'devenv': False,
+ 'metadata': chrome_metadata,
+ }
+
+ data = {'name': 'foo', 'name_devbuild': 'bar'}
+
+ t_dir = tmpdir.mkdir('_trans').mkdir('en-US')
+ t_dir.join('test.properties').write(
+ '\n'.join('{}={}'.format(k, v) for k, v in data.items()))
+
+ packagerChrome.importGeckoLocales(params, base_files)
+ trans_data = json.loads(base_files['_locales/en_US/messages.json'])
+
+ for key, value in data.items():
+ assert trans_data.get('test_' + key, {}).get('message', '') == value
+
+
+def test_fix_translations_for_cws(base_files):
+ base_files['_locales/de/messages.json'] = packagerChrome.toJson({})
+ base_files['manifest.json'] = packagerChrome.toJson(MINIMUM_MANIFEST)
+ packagerChrome.fixTranslationsForCWS(base_files)
+
+ ger_messages = json.loads(base_files['_locales/de/messages.json'])
+ eng_messages = json.loads(base_files['_locales/en_US/messages.json'])
+
+ # Check for inserted translations, none were present in 'de' beforehand
+ for match in re.finditer(r'__MSG_(\S+)__', base_files['manifest.json']):
+ name = match.group(1)
+ assert ger_messages[name]['message'] == eng_messages[name]['message']
+
+ # CWS enforces max-lengths on string
+ assert len(ger_messages['description']['message']) <= 132
+ assert len(ger_messages['name']['message']) <= 12
+
+
+@pytest.mark.usefixtures('base_files', 'lib_files',
+ 'gecko_webext_metadata', 'chrome_metadata')
+@pytest.mark.parametrize('release', [True, False])
+@pytest.mark.parametrize('devenv', [True, False])
+@pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext'])
+@pytest.mark.parametrize('key', [True, False])
+def test_create_build(srcdir, tmpdir, release, devenv, ext_type,
+ key, keyfile):
+
+ basefiles = [
+ 'manifest.json',
+ 'lib/foo.js',
+ 'foo/logo_50.png',
+ '_locales/en_US/messages.json',
+ '_locales/en-US/test.properties',
+ 'logo_44.png',
+ 'icons/logo_150.png',
+ ]
+
+ out_file = str(tmpdir.join('out'))
+
+ packagerChrome.createBuild(
+ outFile=out_file,
+ baseDir=str(srcdir),
+ type=ext_type,
+ releaseBuild=release,
+ keyFile=keyfile if key else None,
+ devenv=devenv)
+
+ with zipfile.ZipFile(out_file, 'r') as zipfp:
+ zipfp.testzip()
+
+ filenames = [zipinfo.filename for zipinfo in zipfp.infolist()]
+ for filename in basefiles if not devenv else basefiles + [
+ 'devenvPoller__.js',
+ 'devenvVersion__',
+ 'qunit/index.html',
+ ]:
+ assert filename in filenames

Powered by Google App Engine
This is Rietveld