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

Side by Side Diff: tests/test_packagerWebExt.py

Issue 29501558: Issue 5383 - Add tests for the Chrome and Firefox packagers (Closed)
Patch Set: Simplifying parameters Created Sept. 21, 2017, 11:27 a.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 os
6 import shutil
7 import json
8 import re
9 from struct import unpack
10
11 import pytest
12 from Crypto.Hash import SHA
13 from Crypto.PublicKey import RSA
14 from Crypto.Signature import PKCS1_v1_5
15
16
17 from buildtools import packager
18 from buildtools.tests.tools import (DirContent, ZipContent, copy_metadata,
19 run_webext_build, assert_manifest_content,
20 assert_all_locales_present, locale_files)
21 from buildtools.tests.conftest import ALL_LANGUAGES
22
23
24 LOCALES_MODULE = {
25 'test.Foobar': {
26 'message': 'Ensuring dict-copy from modules for $domain$',
27 'description': 'test description',
28 'placeholders': {'content': '$1', 'example': 'www.adblockplus.org'}
29 }
30 }
31
32 DTD_TEST = ('<!ENTITY access.key "access key(&amp;a)">'
33 '<!ENTITY ampersand "foo &amp;-bar">')
34
35 PROPERTIES_TEST = 'description=very descriptive!'
36
37
38 @pytest.fixture
39 def gecko_import(tmpdir):
40 tmpdir.mkdir('_imp').mkdir('en-US').join('gecko.dtd').write(DTD_TEST)
41
42
43 @pytest.fixture
44 def locale_modules(tmpdir):
45 mod_dir = tmpdir.mkdir('_modules')
46 lang_dir = mod_dir.mkdir('en-US')
47 lang_dir.join('module.json').write(json.dumps(LOCALES_MODULE))
48 lang_dir.join('unit.properties').write(json.dumps(PROPERTIES_TEST))
49
50
51 @pytest.fixture
52 def icons(srcdir):
53 icons_dir = srcdir.mkdir('icons')
54 for filename in ['abp-16.png', 'abp-19.png', 'abp-53.png']:
55 shutil.copy(
56 os.path.join(os.path.dirname(__file__), filename),
57 os.path.join(str(icons_dir), filename),
58 )
59
60
61 @pytest.fixture
62 def all_lang_locales(tmpdir):
63 return locale_files(ALL_LANGUAGES, '_locales', tmpdir)
64
65
66 @pytest.fixture
67 def chrome_metadata(tmpdir):
68 filename = 'metadata.chrome'
69 copy_metadata(filename, tmpdir)
70
71
72 @pytest.fixture
73 def gecko_webext_metadata(tmpdir, chrome_metadata):
74 filename = 'metadata.gecko-webext'
75 copy_metadata(filename, tmpdir)
76
77
78 @pytest.fixture
79 def keyfile(tmpdir):
80 """Test-privatekey for signing chrome release-package"""
81 return os.path.join(os.path.dirname(__file__), 'chrome_rsa.pem')
82
83
84 @pytest.fixture
85 def lib_files(tmpdir):
86 files = packager.Files(['lib'], set())
87 files['ext/a.js'] = 'var bar;'
88 files['lib/b.js'] = 'var foo;'
89
90 tmpdir.mkdir('lib').join('b.js').write(files['lib/b.js'])
91 tmpdir.mkdir('ext').join('a.js').write(files['ext/a.js'])
92
93 return files
94
95
96 def assert_gecko_locale_conversion(package):
97 locale = json.loads(package.read('_locales/en_US/messages.json'))
98
99 assert locale.get('test_Foobar', {}) == LOCALES_MODULE['test.Foobar']
100 assert locale.get('access_key', {}) == {'message': 'access key'}
101 assert locale.get('ampersand', {}) == {'message': 'foo -bar'}
102 assert locale.get('_description', {}) == {'message': 'very descriptive!"'}
103
104
105 def assert_convert_js(package, excluded=False):
106 libfoo = package.read('lib/foo.js')
107
108 assert 'var bar;' in libfoo
109 assert 'require.modules["ext_a"]' in libfoo
110
111 assert ('var foo;' in libfoo) != excluded
112 assert ('require.modules["b"]' in libfoo) != excluded
113
114
115 def assert_devenv_scripts(package, devenv):
116 manifest = json.loads(package.read('manifest.json'))
117 filenames = package.namelist()
118 scripts = [
119 'ext/common.js',
120 'ext/background.js',
121 ]
122
123 if devenv:
124 assert 'qunit/index.html' in filenames
125 assert 'devenvPoller__.js' in filenames
126 assert 'devenvVersion__' in filenames
127
128 assert '../ext/common.js' in package.read('qunit/index.html')
129 assert '../ext/background.js' in package.read('qunit/index.html')
130
131 assert set(manifest['background']['scripts']) == set(
132 scripts + ['devenvPoller__.js']
133 )
134 else:
135 assert 'qunit/index.html' not in filenames
Sebastian Noack 2017/09/21 19:09:05 Neither should 'devenvPoller__.js' and devenvVersi
tlucas 2017/09/22 09:02:19 I agree, although i will switch places, see the di
136
137 assert set(manifest['background']['scripts']) == set(scripts)
138
139
140 def assert_base_files(package):
141 filenames = set(package.namelist())
142
143 assert 'bar.json' in filenames
144 assert 'manifest.json' in filenames
145 assert 'lib/foo.js' in filenames
146 assert 'foo/logo_50.png' in filenames
147 assert 'icons/logo_150.png' in filenames
148
149
150 def assert_chrome_signature(filename, keyfile):
151 with open(filename, 'r') as fp:
152 content = fp.read()
153
154 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16])
155 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature]
156
157 digest = SHA.new()
158 with open(keyfile, 'r') as fp:
159 rsa_key = RSA.importKey(fp.read())
160
161 signer = PKCS1_v1_5.new(rsa_key)
162
163 digest.update(content[16 + l_pubkey + l_signature:])
164 assert signer.verify(digest, signature)
165
166
167 def assert_locale_upfix(package):
168 translations = [
169 json.loads(package.read('_locales/{}/messages.json'.format(lang)))
170 for lang in ALL_LANGUAGES
171 ]
172
173 manifest = package.read('manifest.json')
174
175 # Chrome Web Store requires descriptive translations to be present in
176 # every language.
177 for match in re.finditer(r'__MSG_(\S+)__', manifest):
178 name = match.group(1)
179
180 for other in translations[1:]:
181 assert translations[0][name]['message'] == other[name]['message']
182
183
184 @pytest.mark.usefixtures(
185 'all_lang_locales',
186 'locale_modules',
187 'gecko_import',
188 'icons',
189 'lib_files',
190 'chrome_metadata',
191 'gecko_webext_metadata',
192 )
193 @pytest.mark.parametrize('platform', ['chrome', 'gecko-webext'])
194 @pytest.mark.parametrize('dev_build_release,buildnum', [
195 ('build', '1337'),
196 ('devenv', None),
197 ('release', None),
198 ])
199 def test_build_webext(platform, dev_build_release, keyfile, tmpdir, srcdir,
200 buildnum, capsys):
201 release = dev_build_release == 'release'
202 devenv = dev_build_release == 'devenv'
203
204 if platform == 'chrome' and release:
205 key = keyfile
206 else:
207 key = None
208
209 filenames = {
210 'gecko-webext': 'adblockplusfirefox-1.2.3{}.xpi',
211 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format(
212 {True: 'crx', False: 'zip'}[release]
213 ),
214 }
215
216 expected_manifest = os.path.join(
217 os.path.dirname(__file__),
218 'expecteddata',
219 'manifest_{}_{}_{}.json'.format(platform, dev_build_release, buildnum),
Sebastian Noack 2017/09/21 19:09:04 The buildnum is redundant here. The filenames are
tlucas 2017/09/22 09:02:20 Done.
220 )
221
222 run_webext_build(platform, dev_build_release, srcdir, buildnum=buildnum,
223 keyfile=key)
224
225 # The makeIcons() in packagerChrome.py should warn about non-square
226 # icons via stderr.
227 out, err = capsys.readouterr()
228 assert 'icon should be square' in err
229
230 if devenv:
231 content_class = DirContent
232 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform)
233 else:
234 content_class = ZipContent
235
236 if release:
237 add_version = ''
238 else:
239 add_version = '.' + buildnum
240
241 out_file = filenames[platform].format(add_version)
242
243 out_file_path = os.path.abspath(os.path.join(
244 os.path.dirname(__file__), os.pardir, out_file))
245 assert os.path.exists(out_file_path)
246
247 if release and platform == 'chrome':
248 assert_chrome_signature(out_file_path, keyfile)
249
250 with content_class(out_file_path) as package:
251 assert_manifest_content(
252 package.read('manifest.json'), expected_manifest
253 )
254 assert_base_files(package)
Sebastian Noack 2017/09/21 19:09:06 The features tested here are relevant for "edge" b
tlucas 2017/09/22 09:02:18 This test happens in edge as well, see the 7 singl
Sebastian Noack 2017/09/22 18:31:04 The logic there seems inconsistent. It seems that
Sebastian Noack 2017/09/25 20:21:19 Yes, I agree that there is no reason to split out
255 assert_devenv_scripts(package, devenv)
256 assert_all_locales_present(package, '_locales')
257 assert_gecko_locale_conversion(package)
258 assert_convert_js(package, platform == 'gecko-webext')
259
260 if platform == 'chrome':
261 assert_locale_upfix(package)
OLDNEW

Powered by Google App Engine
This is Rietveld