 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: | 
| LEFT | RIGHT | 
|---|---|
| 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 re | 5 import re | 
| 6 import json | 6 import json | 
| 7 import zipfile | 7 import zipfile | 
| 8 | 8 | 
| 9 from xml.etree import ElementTree | 9 from xml.etree import ElementTree | 
| 10 from itertools import product | |
| 11 | 10 | 
| 12 import pytest | 11 import pytest | 
| 13 | 12 | 
| 14 from buildtools import packager, packagerChrome | 13 from buildtools import packager, packagerChrome | 
| 14 from buildtools.tests.tools import copy_metadata | |
| 15 | 15 | 
| 16 ICON_SIZES = [32, 48, 64, 256, 53] | 16 ICON_SIZES = [32, 48, 64, 256, 53] | 
| 17 | 17 | 
| 18 TR_FA = [True, False] | 18 MINIMUM_MANIFEST = [ | 
| 
Vasily Kuznetsov
2017/08/03 16:52:29
Not sure having this constant is worth it. TR_FA i
 
tlucas
2017/08/03 21:26:01
This will be gotten rid of by proper parametrizati
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 19 | 19 ('manifest_version', 2), | 
| 20 MINIMUM_MANIFEST_JSON = [ | 20 ('author', 'Eyeo GmbH'), | 
| 
Vasily Kuznetsov
2017/08/03 16:52:29
Isn't this name a bit confusing given that the con
 
tlucas
2017/08/03 21:26:01
Acknowledged.
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 21 ('manifest_version', 2), | 21 ('permissions', [ | 
| 
Vasily Kuznetsov
2017/08/03 16:52:28
For consistency with other code, it would be bette
 
tlucas
2017/08/03 21:26:00
Acknowledged.
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 22 ('author', 'Eyeo GmbH'), | 22 'tabs', | 
| 23 ('permissions', ['tabs', '<all_urls>', 'contextMenus', 'webRequest', | 23 '<all_urls>', | 
| 24 'webRequestBlocking', 'webNavigation', 'storage', | 24 'contextMenus', | 
| 25 'unlimitedStorage', 'notifications']), | 25 'webRequest', | 
| 26 ('minimum_chrome_version', '49.0'), | 26 'webRequestBlocking', | 
| 27 ('minimum_opera_version', '36.0'), | 27 'webNavigation', | 
| 28 ('devtools_page', 'devtools.html'), | 28 'storage', | 
| 29 ('description', '__MSG_description__'), | 29 'unlimitedStorage', | 
| 30 ('default_locale', 'en_US'), | 30 'notifications', | 
| 31 ('short_name', '__MSG_name__'), | 31 ]), | 
| 32 ('storage', {'managed_schema': 'managed-storage-schema.json'}), | 32 ('minimum_chrome_version', '49.0'), | 
| 33 ('options_ui', {'open_in_tab': True, 'page': 'options.html'}), | 33 ('minimum_opera_version', '36.0'), | 
| 34 ] | 34 ('devtools_page', 'devtools.html'), | 
| 35 ('description', '__MSG_description__'), | |
| 36 ('default_locale', 'en_US'), | |
| 37 ('short_name', '__MSG_name__'), | |
| 38 ('storage', {'managed_schema': 'managed-storage-schema.json'}), | |
| 39 ('options_ui', {'open_in_tab': True, 'page': 'options.html'}), | |
| 40 ] | |
| 41 | |
| 42 | |
| 43 @pytest.fixture | |
| 44 def chrome_metadata(tmpdir): | |
| 45 filename = 'metadata.chrome' | |
| 46 copy_metadata(filename, tmpdir) | |
| 47 | |
| 48 return packager.readMetadata(str(tmpdir), 'chrome') | |
| 49 | |
| 50 | |
| 51 @pytest.fixture | |
| 52 def gecko_webext_metadata(tmpdir, chrome_metadata): | |
| 53 filename = 'metadata.gecko-webext' | |
| 54 copy_metadata(filename, tmpdir) | |
| 55 | |
| 56 # gecko-webext metadata inherits from chrome metadata, assure existence | |
| 57 assert chrome_metadata is not None | |
| 58 | |
| 59 return packager.readMetadata(str(tmpdir), 'gecko-webext') | |
| 35 | 60 | 
| 36 | 61 | 
| 37 @pytest.fixture | 62 @pytest.fixture | 
| 38 def icons(tmpdir): | 63 def icons(tmpdir): | 
| 39 """Valid .png files for testing make_icons""" | 64 """Valid .png files for testing make_icons""" | 
| 40 try: | 65 from PIL import Image | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
Since this runs in tests, we probably know which b
 
tlucas
2017/08/03 21:26:01
We actually do, i just added this try/except befor
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 41 from PIL import Image | |
| 42 except: | |
| 43 import Image | |
| 44 | 66 | 
| 45 paths = [] | 67 paths = [] | 
| 46 icon_dir = tmpdir.mkdir('tmp_icons') | 68 icon_dir = tmpdir.mkdir('tmp_icons') | 
| 47 | 69 | 
| 48 for size in ICON_SIZES: | 70 for size in ICON_SIZES: | 
| 71 img_path = str(icon_dir.join('abp-{}.png'.format(size))) | |
| 49 img = Image.new('1', (size, size if size != 53 else size + 1), 0) | 72 img = Image.new('1', (size, size if size != 53 else size + 1), 0) | 
| 50 paths += [str(icon_dir.join('abp-{}.png'.format(size)))] | 73 img.save(img_path) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
What do you think about rewriting this as follows?
 
tlucas
2017/08/03 21:26:00
I agree, this would be a lot more readable.
Regar
 
tlucas
2017/08/04 14:51:57
Done / as discussed, not changing the str()-thing
 | |
| 51 img.save(paths[-1]) | 74 paths.append(img_path) | 
| 52 | 75 | 
| 53 return paths | 76 return paths | 
| 54 | 77 | 
| 55 | 78 | 
| 56 @pytest.fixture | 79 @pytest.fixture | 
| 57 def keyfile(tmpdir): | 80 def keyfile(tmpdir): | 
| 58 """Test-privatekey for signing files""" | 81 """Test-privatekey for signing files""" | 
| 59 | 82 | 
| 60 content = """-----BEGIN RSA PRIVATE KEY----- | 83 content = """-----BEGIN RSA PRIVATE KEY----- | 
| 61 MIIEowIBAAKCAQEA0P06DVxOWZ97cvBZWz7DV0DYTFF7Cdrxnu/sCxnHp8IEq+sM | 84 MIIEowIBAAKCAQEA0P06DVxOWZ97cvBZWz7DV0DYTFF7Cdrxnu/sCxnHp8IEq+sM | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 86 -----END RSA PRIVATE KEY-----""" | 109 -----END RSA PRIVATE KEY-----""" | 
| 87 | 110 | 
| 88 keyfile_path = str(tmpdir.mkdir('rsakey').join('keyfile')) | 111 keyfile_path = str(tmpdir.mkdir('rsakey').join('keyfile')) | 
| 89 | 112 | 
| 90 with open(keyfile_path, 'wb') as key_fp: | 113 with open(keyfile_path, 'wb') as key_fp: | 
| 91 key_fp.write(content) | 114 key_fp.write(content) | 
| 92 | 115 | 
| 93 return keyfile_path | 116 return keyfile_path | 
| 94 | 117 | 
| 95 | 118 | 
| 96 @pytest.mark.parametrize( | 119 @pytest.mark.parametrize('release', [True, False]) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:28
What do you think about creating 3 fixtures instea
 
tlucas
2017/08/03 21:26:00
This would also reduce the amount of readMetadata-
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 97 'metadata_files', | 120 @pytest.mark.parametrize('devenv', [True, False]) | 
| 98 [['metadata.chrome', 'metadata.gecko-webext']], | 121 @pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext']) | 
| 99 indirect=True) | 122 def test_create_manifest(srcdir, files, release, devenv, ext_type, | 
| 100 @pytest.mark.usefixtures('metadata_files') | 123 chrome_metadata, gecko_webext_metadata): | 
| 101 def test_create_manifest(srcdir, files): | 124 | 
| 102 for release, devenv, ext_type in product( | 125 if ext_type == 'chrome': | 
| 
Vasily Kuznetsov
2017/08/10 19:48:28
Instead of this you could do:
@pytest.mark.parame
 
tlucas
2017/08/11 12:17:09
I thought about that too and i definitely agree wi
 
Vasily Kuznetsov
2017/08/11 16:46:00
Yes, you're right.
 | |
| 103 TR_FA, TR_FA, ['chrome', 'gecko-webext']): | 126 metadata = chrome_metadata | 
| 104 | 127 else: | 
| 105 metadata = packagerChrome.readMetadata(str(srcdir), ext_type) | 128 metadata = gecko_webext_metadata | 
| 106 | 129 | 
| 107 version = packager.getBuildVersion(str(srcdir), metadata, release) | 130 version = packager.getBuildVersion(str(srcdir), metadata, release) | 
| 108 params = { | 131 params = { | 
| 109 'type': ext_type, | 132 'type': ext_type, | 
| 110 'baseDir': str(srcdir), | 133 'baseDir': str(srcdir), | 
| 111 'releaseBuild': release, | 134 'releaseBuild': release, | 
| 112 'version': version, | 135 'version': version, | 
| 113 'devenv': devenv, | 136 'devenv': devenv, | 
| 114 'metadata': metadata, | 137 'metadata': metadata, | 
| 115 } | 138 } | 
| 116 manifest = json.loads(packagerChrome.createManifest(params, files)) | 139 manifest = json.loads(packagerChrome.createManifest(params, files)) | 
| 117 | 140 | 
| 118 expected_values = MINIMUM_MANIFEST_JSON + [ | 141 expected_values = MINIMUM_MANIFEST + [ | 
| 119 ('name', '__MSG_name_' + ('devbuild__' if not release else '_')), | 142 ('name', '__MSG_name_' + ('devbuild__' if not release else '_')), | 
| 120 ('version', '1.2.3' + ('.0' if not release else '')), | 143 ('version', '1.2.3' + ('.0' if not release else '')), | 
| 144 ] | |
| 145 | |
| 146 if ext_type == 'gecko-webext': | |
| 147 expected_values += [ | |
| 148 ('applications', { | |
| 149 'gecko': { | |
| 150 'id': '{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}', | |
| 151 'strict_min_version': '50.0', | |
| 152 } | |
| 153 }) | |
| 121 ] | 154 ] | 
| 122 | 155 if not release: | 
| 123 if ext_type == 'gecko-webext': | 156 expected_values[-1][1]['gecko'].update({ | 
| 124 expected_values += [ | 157 'update_url': ''.join(( | 
| 125 ('applications', { | 158 'https://downloads.adblockplus.org/devbuilds/', | 
| 126 'gecko': { | 159 'adblockplusfirefox/updates.json')) | 
| 127 'id': '{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}', | 160 }) | 
| 128 'strict_min_version': '50.0', | 161 | 
| 129 } | 162 for key, value in expected_values: | 
| 130 }) | 163 assert manifest.get(key, None) == value | 
| 131 ] | |
| 132 if not release: | |
| 133 expected_values[-1][1]['gecko'].update({ | |
| 134 'update_url': ''.join(( | |
| 135 'https://downloads.adblockplus.org/devbuilds/', | |
| 136 'adblockplusfirefox/updates.json')) | |
| 137 }) | |
| 138 | |
| 139 for key, value in expected_values: | |
| 140 assert manifest.get(key, None) == value | |
| 141 | 164 | 
| 142 | 165 | 
| 143 def test_sign_binary(files, keyfile): | 166 def test_sign_binary(files, keyfile): | 
| 144 from Crypto.Hash import SHA | 167 from Crypto.Hash import SHA | 
| 145 from Crypto.PublicKey import RSA | 168 from Crypto.PublicKey import RSA | 
| 146 from Crypto.Signature import PKCS1_v1_5 | 169 from Crypto.Signature import PKCS1_v1_5 | 
| 147 | 170 | 
| 148 digest = SHA.new() | 171 digest = SHA.new() | 
| 149 | 172 | 
| 150 signature = packagerChrome.signBinary(files.zipToString(), keyfile) | 173 signature = packagerChrome.signBinary(files.zipToString(), keyfile) | 
| 151 | 174 | 
| 152 with open(keyfile, 'r') as fp: | 175 with open(keyfile, 'r') as fp: | 
| 153 rsa_key = RSA.importKey(fp.read()) | 176 rsa_key = RSA.importKey(fp.read()) | 
| 154 | 177 | 
| 155 signer = PKCS1_v1_5.new(rsa_key) | 178 signer = PKCS1_v1_5.new(rsa_key) | 
| 156 | 179 | 
| 157 digest.update(files.zipToString()) | 180 digest.update(files.zipToString()) | 
| 158 assert signer.verify(digest, signature) | 181 assert signer.verify(digest, signature) | 
| 159 | 182 | 
| 160 | 183 | 
| 161 def test_get_public_key(keyfile): | 184 def test_get_public_key(keyfile): | 
| 162 expected = ''.join(( | 185 expected = ( | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
You can actually write this as follows:
    expec
 
tlucas
2017/08/03 21:26:02
Acknowledged.
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 163 '30820122300d06092a864886f70d01010105000382010f003082010a0282010100d0', | 186 '30820122300d06092a864886f70d01010105000382010f003082010a0282010100d0' | 
| 164 'fd3a0d5c4e599f7b72f0595b3ec35740d84c517b09daf19eefec0b19c7a7c204abeb', | 187 'fd3a0d5c4e599f7b72f0595b3ec35740d84c517b09daf19eefec0b19c7a7c204abeb' | 
| 165 '0caeaa1da768bc793b1d767b614e703ddf08858855f3ebff658902ab481b68804186', | 188 '0caeaa1da768bc793b1d767b614e703ddf08858855f3ebff658902ab481b68804186' | 
| 166 'dad9ab4fbde3cb999d39e866ee1ea6523cbac0bb99422b98fd1589eb8e77ff41f76c', | 189 'dad9ab4fbde3cb999d39e866ee1ea6523cbac0bb99422b98fd1589eb8e77ff41f76c' | 
| 167 'a080f08948754f0f9249f90c9587f988a24940f4d54e5930b9fc9bff8e0ffafd08bb', | 190 'a080f08948754f0f9249f90c9587f988a24940f4d54e5930b9fc9bff8e0ffafd08bb' | 
| 168 '205a8255e15097cb3308b5c73c86545b8927bfdc342664e3db17405dd49bfa94d038', | 191 '205a8255e15097cb3308b5c73c86545b8927bfdc342664e3db17405dd49bfa94d038' | 
| 169 '446d14f2803aab9b35e70de7fff16334eade568732c6059658693f6b09642667b5c6', | 192 '446d14f2803aab9b35e70de7fff16334eade568732c6059658693f6b09642667b5c6' | 
| 170 '7df2077ca1ef86f9d451ecafdbe18938dcb3e40d3b5052f5f03fa1abf30ceb354387', | 193 '7df2077ca1ef86f9d451ecafdbe18938dcb3e40d3b5052f5f03fa1abf30ceb354387' | 
| 171 'cb9d36ca9fa2658393808d6b62ab8be3490203010001')) | 194 'cb9d36ca9fa2658393808d6b62ab8be3490203010001') | 
| 172 | 195 | 
| 173 publickey = packagerChrome.getPublicKey(keyfile) | 196 publickey = packagerChrome.getPublicKey(keyfile) | 
| 174 assert publickey.encode('hex') == expected | 197 assert publickey.encode('hex') == expected | 
| 175 | 198 | 
| 176 | 199 | 
| 177 @pytest.mark.parametrize('metadata_files', ['metadata.chrome'], indirect=True) | 200 @pytest.mark.usefixtures('chrome_metadata') | 
| 178 @pytest.mark.usefixtures('metadata_files') | 201 @pytest.mark.parametrize('devenv', [True, False]) | 
| 179 def test_get_package_files(srcdir): | 202 def test_get_package_files(srcdir, devenv): | 
| 180 extensions = ['html', 'js', 'json', 'xml'] | 203 filenames = [ | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
What do you think about replacing this with:
 
tlucas
2017/08/03 21:26:00
Acknowledged.
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 181 for extension in extensions: | 204 'foo.html', | 
| 182 srcdir.join(''.join(('foo.', extension))).write('', ensure=True) | 205 'foo.js', | 
| 183 | 206 'foo.json', | 
| 184 for devenv in [True, False]: | 207 'foo.xml', | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
What do you think about making devenv a parameter
 
tlucas
2017/08/03 21:26:00
Acknowledged.
 
tlucas
2017/08/04 14:51:59
Done.
 | |
| 185 params = { | 208 ] | 
| 186 'baseDir': str(srcdir), | 209 | 
| 187 'devenv': devenv, | 210 for filename in filenames: | 
| 188 } | 211 srcdir.join(filename).write('', ensure=True) | 
| 189 | 212 | 
| 190 files = packagerChrome.getPackageFiles(params) | 213 params = { | 
| 191 | 214 'baseDir': str(srcdir), | 
| 192 assert devenv == ('qunit' in files) | 215 'devenv': devenv, | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
This is clever and compact, but I'm wondering if i
 
tlucas
2017/08/03 21:26:01
In this case i'll choose your reordered approach -
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 193 | 216 } | 
| 194 for expected in ['icons', 'ui', 'skin', 'ext', '_locales', 'lib', | 217 | 
| 195 'jquery-ui'] + ['foo.' + ext for ext in extensions]: | 218 files = packagerChrome.getPackageFiles(params) | 
| 196 assert expected in files | 219 | 
| 220 assert ('qunit' in files) == devenv | |
| 221 | |
| 222 for expected in ['icons', 'ui', 'skin', 'ext', '_locales', 'lib', | |
| 223 'jquery-ui'] + [name for name in filenames]: | |
| 224 assert expected in files | |
| 197 | 225 | 
| 198 | 226 | 
| 199 def test_make_icons(icons, capsys): | 227 def test_make_icons(icons, capsys): | 
| 200 files = packager.Files(set(), set()) | 228 files = packager.Files(set(), set()) | 
| 201 for path in icons: | 229 for path in icons: | 
| 202 files[path] = open(path, 'r').read() | 230 files[path] = open(path, 'r').read() | 
| 203 result = packagerChrome.makeIcons(files, icons) | 231 result = packagerChrome.makeIcons(files, icons) | 
| 204 | 232 | 
| 205 out, err = capsys.readouterr() | 233 out, err = capsys.readouterr() | 
| 206 | 234 | 
| 207 assert 'should be square' in err | 235 assert 'should be square' in err | 
| 208 assert not any(size not in result for size in ICON_SIZES) | 236 assert set(result) == set(ICON_SIZES) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:28
Is this the same as `assert all(size in result for
 
tlucas
2017/08/03 21:26:02
The result would be the same - but all(..) is more
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 209 | 237 | 
| 210 | 238 | 
| 211 @pytest.mark.parametrize('metadata_files', ['metadata.chrome'], indirect=True) | 239 def test_create_script_page(srcdir, chrome_metadata): | 
| 212 @pytest.mark.usefixtures('metadata_files') | 240 params = {'metadata': chrome_metadata} | 
| 213 def test_create_script_page(srcdir): | |
| 214 metadata = packagerChrome.readMetadata(str(srcdir), 'chrome') | |
| 215 params = {'metadata': metadata} | |
| 216 | 241 | 
| 217 template = packagerChrome.createScriptPage( | 242 template = packagerChrome.createScriptPage( | 
| 
Vasily Kuznetsov
2017/08/03 16:52:29
Could you please reformat this as follows:
    te
 
tlucas
2017/08/03 21:26:01
Acknowledged.
 
tlucas
2017/08/04 14:51:59
Done.
 | |
| 218 params, 'testIndex.html.tmpl', ('general', 'testScripts')) | 243 params, 'testIndex.html.tmpl', ('general', 'testScripts') | 
| 219 | 244 ) | 
| 220 template_scripts = [elem.attrib['src'] for elem in | 245 | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
Not that it matters for performance, but to improv
 
tlucas
2017/08/03 21:26:01
Acknowledged.
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 221 ElementTree.fromstring(template).iter('script')] | 246 template_scripts = {elem.attrib['src'] for elem in | 
| 222 | 247 ElementTree.fromstring(template).iter('script')} | 
| 223 for src in metadata.get('general', 'testScripts').split(): | 248 | 
| 249 for src in chrome_metadata.get('general', 'testScripts').split(): | |
| 224 assert src in template_scripts | 250 assert src in template_scripts | 
| 225 | 251 | 
| 226 | 252 | 
| 227 @pytest.mark.parametrize('metadata_files', ['metadata.chrome'], indirect=True) | 253 def test_convert_js(srcdir, files, chrome_metadata): | 
| 228 @pytest.mark.usefixtures('metadata_files') | |
| 229 def test_convert_js(srcdir, files): | |
| 230 metadata = packagerChrome.readMetadata(str(srcdir), 'chrome') | |
| 231 params = { | 254 params = { | 
| 232 'type': 'chrome', | 255 'type': 'chrome', | 
| 233 'metadata': metadata, | 256 'metadata': chrome_metadata, | 
| 234 } | 257 } | 
| 235 | 258 | 
| 236 packagerChrome.convertJS(params, files) | 259 packagerChrome.convertJS(params, files) | 
| 237 source = files['lib/foo.js'] | 260 source = files['lib/foo.js'] | 
| 238 | 261 | 
| 239 assert 'var foo;' in source | 262 assert 'var foo;' in source | 
| 240 assert 'var bar;' in source | 263 assert 'var bar;' in source | 
| 241 | 264 | 
| 242 | 265 | 
| 243 def test_to_json(): | 266 def test_to_json(): | 
| 244 data = {'bar': ['foo', 'foobar', 1, True]} | 267 data = {'bar': ['foo', 'foobar', 1, True]} | 
| 245 data_json = packagerChrome.toJson(data) | 268 data_json = packagerChrome.toJson(data) | 
| 246 | 269 | 
| 247 assert data_json[-1] == '\n' | 270 assert data_json.endswith('\n') | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
Maybe `data_json.endswith('\n')`?
 
tlucas
2017/08/03 21:26:01
Acknowledged.
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 248 json.loads(data_json) | 271 json.loads(data_json) | 
| 249 | 272 | 
| 250 | 273 | 
| 251 @pytest.mark.parametrize('metadata_files', ['metadata.chrome'], indirect=True) | 274 def test_import_gecko_locales(tmpdir, srcdir, files, chrome_metadata): | 
| 252 @pytest.mark.usefixtures('metadata_files') | 275 version = packager.getBuildVersion(str(srcdir), chrome_metadata, False) | 
| 253 def test_import_gecko_locales(tmp_dir, srcdir, files): | |
| 254 metadata = packagerChrome.readMetadata(str(srcdir), 'chrome') | |
| 255 version = packager.getBuildVersion(str(srcdir), metadata, False) | |
| 
Vasily Kuznetsov
2017/08/03 16:52:28
Here and in other places: it's better to do it thi
 
tlucas
2017/08/03 21:26:01
Please see comment above
 
tlucas
2017/08/04 14:51:58
As discussed
 | |
| 256 params = { | 276 params = { | 
| 257 'type': 'chrome', | 277 'type': 'chrome', | 
| 258 'baseDir': str(srcdir), | 278 'baseDir': str(srcdir), | 
| 259 'releaseBuild': False, | 279 'releaseBuild': False, | 
| 260 'version': version, | 280 'version': version, | 
| 261 'devenv': False, | 281 'devenv': False, | 
| 262 'metadata': metadata, | 282 'metadata': chrome_metadata, | 
| 263 } | 283 } | 
| 264 | 284 | 
| 265 data = {'name': 'foo', 'name_devbuild': 'bar'} | 285 data = {'name': 'foo', 'name_devbuild': 'bar'} | 
| 266 | 286 | 
| 267 t_dir = tmp_dir.mkdir('_trans').mkdir('en-US') | 287 t_dir = tmpdir.mkdir('_trans').mkdir('en-US') | 
| 268 t_dir.join('test.properties').write( | 288 t_dir.join('test.properties').write( | 
| 269 '\n'.join( | 289 '\n'.join( | 
| 
Vasily Kuznetsov
2017/08/10 19:48:28
The following line would fit on this line too. Not
 
tlucas
2017/08/11 12:17:09
Done.
 | |
| 270 '='.join((k, v)) for k, v in data.iteritems())) | 290 '{}={}'.format(k, v) for k, v in data.items())) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
What do you think about
    '{}={}'.format(k, v)
 
tlucas
2017/08/03 21:26:00
Acknowledged.
 
tlucas
2017/08/04 14:51:59
Done.
 | |
| 271 | 291 | 
| 272 packagerChrome.importGeckoLocales(params, files) | 292 packagerChrome.importGeckoLocales(params, files) | 
| 273 trans_data = json.loads(files['_locales/en_US/messages.json']) | 293 trans_data = json.loads(files['_locales/en_US/messages.json']) | 
| 274 | 294 | 
| 275 for key, value in data.iteritems(): | 295 for key, value in data.items(): | 
| 276 assert trans_data.get('test_{}'.format(key), {})\ | 296 assert trans_data.get('test_' + key, {}).get('message', '') == value | 
| 
Vasily Kuznetsov
2017/08/03 16:52:28
Flake8 should have told you that `'test_' + key` i
 
tlucas
2017/08/03 21:26:00
Acknowledged, although flake8 / tox did not inform
 
tlucas
2017/08/04 14:51:59
Done. No idea why flake8 didn't bother though
 | |
| 277 .get('message', '') == value | |
| 278 | 297 | 
| 279 | 298 | 
| 280 def test_fix_translations_for_cws(files): | 299 def test_fix_translations_for_cws(files): | 
| 281 files['_locales/de/messages.json'] = packagerChrome.toJson({}) | 300 files['_locales/de/messages.json'] = packagerChrome.toJson({}) | 
| 282 files['manifest.json'] = packagerChrome.toJson( | 301 files['manifest.json'] = packagerChrome.toJson( | 
| 
Vasily Kuznetsov
2017/08/10 19:48:28
Here the following line would also fit into this l
 
tlucas
2017/08/11 12:17:08
Done.
 | |
| 283 {k: v for k, v in MINIMUM_MANIFEST_JSON}) | 302 dict(MINIMUM_MANIFEST)) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:30
You can just use `dict(MINIMUM_MANIFEST_JUST)` her
 
tlucas
2017/08/03 21:26:00
Acknowledged.
 
tlucas
2017/08/04 14:51:59
Done.
 | |
| 284 packagerChrome.fixTranslationsForCWS(files) | 303 packagerChrome.fixTranslationsForCWS(files) | 
| 285 | 304 | 
| 286 ger_messages = json.loads(files['_locales/de/messages.json']) | 305 ger_messages = json.loads(files['_locales/de/messages.json']) | 
| 287 eng_messages = json.loads(files['_locales/en_US/messages.json']) | 306 eng_messages = json.loads(files['_locales/en_US/messages.json']) | 
| 307 | |
| 308 # Check for inserted translations, none were present in 'de' beforehand | |
| 288 for match in re.finditer(r'__MSG_(\S+)__', files['manifest.json']): | 309 for match in re.finditer(r'__MSG_(\S+)__', files['manifest.json']): | 
| 289 name = match.group(1) | 310 name = match.group(1) | 
| 290 assert ger_messages[name]['message'] == eng_messages[name]['message'] | 311 assert ger_messages[name]['message'] == eng_messages[name]['message'] | 
| 291 | 312 | 
| 313 # CWS enforces max-lengths on string | |
| 292 assert len(ger_messages['description']['message']) <= 132 | 314 assert len(ger_messages['description']['message']) <= 132 | 
| 
Vasily Kuznetsov
2017/08/03 16:52:28
This is a curious assertion. What exactly are we c
 
tlucas
2017/08/03 21:26:02
ChromeWebStore enforces a max-length to be applied
 
tlucas
2017/08/04 14:51:58
Done.
 | |
| 293 assert len(ger_messages['name']['message']) <= 12 | 315 assert len(ger_messages['name']['message']) <= 12 | 
| 294 | 316 | 
| 295 | 317 | 
| 296 @pytest.mark.parametrize( | 318 @pytest.mark.usefixtures('files', 'gecko_webext_metadata', 'chrome_metadata') | 
| 297 'metadata_files', | 319 @pytest.mark.parametrize('release', [True, False]) | 
| 298 [['metadata.chrome', 'metadata.gecko-webext']], | 320 @pytest.mark.parametrize('devenv', [True, False]) | 
| 299 indirect=True) | 321 @pytest.mark.parametrize('ext_type', ['chrome', 'gecko-webext']) | 
| 300 @pytest.mark.usefixtures('metadata_files', 'files') | 322 @pytest.mark.parametrize('key', [True, False]) | 
| 301 def test_create_build(srcdir, keyfile, tmp_dir): | 323 def test_create_build(srcdir, tmpdir, release, devenv, ext_type, | 
| 324 key, keyfile): | |
| 302 | 325 | 
| 303 basefiles = [ | 326 basefiles = [ | 
| 304 'manifest.json', | 327 'manifest.json', | 
| 305 'lib/foo.js', | 328 'lib/foo.js', | 
| 306 'foo/logo_50.png', | 329 'foo/logo_50.png', | 
| 307 '_locales/en_US/messages.json', | 330 '_locales/en_US/messages.json', | 
| 308 '_locales/en-US/test.properties', | 331 '_locales/en-US/test.properties', | 
| 309 'logo_44.png', | 332 'logo_44.png', | 
| 310 'qunit/index.html', | |
| 311 'icons/logo_150.png', | 333 'icons/logo_150.png', | 
| 312 ] | 334 ] | 
| 313 | 335 | 
| 314 for release, devenv, ext_type, key in product( | 336 out_file = str(tmpdir.join('out')) | 
| 
Vasily Kuznetsov
2017/08/03 16:52:31
Perhaps it would be better to make this a parametr
 
tlucas
2017/08/03 21:26:01
Totally agreed!
 
tlucas
2017/08/04 14:51:57
Done.
 | |
| 315 TR_FA, TR_FA, ['chrome', 'gecko-webext'], [None, keyfile]): | 337 | 
| 316 | 338 packagerChrome.createBuild( | 
| 317 out_file = str(tmp_dir.join('out')) | 339 outFile=out_file, | 
| 318 | 340 baseDir=str(srcdir), | 
| 319 packagerChrome.createBuild( | 341 type=ext_type, | 
| 320 outFile=out_file, | 342 releaseBuild=release, | 
| 321 baseDir=str(srcdir), | 343 keyFile=keyfile if key else None, | 
| 322 type=ext_type, | 344 devenv=devenv) | 
| 323 releaseBuild=release, | 345 | 
| 324 keyFile=key, | 346 with zipfile.ZipFile(out_file, 'r') as zipfp: | 
| 325 devenv=devenv) | 347 zipfp.testzip() | 
| 326 | 348 | 
| 327 with zipfile.ZipFile(out_file, 'r') as zipfp: | 349 filenames = [zipinfo.filename for zipinfo in zipfp.infolist()] | 
| 328 zipfp.testzip() | 350 for filename in basefiles if not devenv else basefiles + [ | 
| 329 | 351 'devenvPoller__.js', | 
| 330 filenames = [zipinfo.filename for zipinfo in zipfp.infolist()] | 352 'devenvVersion__', | 
| 331 for filename in basefiles if not devenv else basefiles + [ | 353 'qunit/index.html', | 
| 332 'devenvPoller__.js', | 354 ]: | 
| 333 'devenvVersion__', | 355 assert filename in filenames | 
| 334 ]: | |
| 335 assert filename in filenames | |
| LEFT | RIGHT |