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: Adressing comments Created Sept. 22, 2017, 8:59 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
« no previous file with comments | « tests/test_packagerEdge.py ('k') | tests/tools.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 assert ('qunit/index.html' in filenames) == devenv
124 assert ('devenvPoller__.js' in filenames) == devenv
125 assert ('devenvVersion__' in filenames) == devenv
126
127 if devenv:
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 set(manifest['background']['scripts']) == set(scripts)
136
137
138 def assert_base_files(package):
139 filenames = set(package.namelist())
140
141 assert 'bar.json' in filenames
142 assert 'manifest.json' in filenames
143 assert 'lib/foo.js' in filenames
144 assert 'foo/logo_50.png' in filenames
145 assert 'icons/logo_150.png' in filenames
146
147
148 def assert_chrome_signature(filename, keyfile):
149 with open(filename, 'r') as fp:
150 content = fp.read()
151
152 _, _, l_pubkey, l_signature = unpack('<4sIII', content[:16])
153 signature = content[16 + l_pubkey: 16 + l_pubkey + l_signature]
154
155 digest = SHA.new()
156 with open(keyfile, 'r') as fp:
157 rsa_key = RSA.importKey(fp.read())
158
159 signer = PKCS1_v1_5.new(rsa_key)
160
161 digest.update(content[16 + l_pubkey + l_signature:])
162 assert signer.verify(digest, signature)
163
164
165 def assert_locale_upfix(package):
166 translations = [
167 json.loads(package.read('_locales/{}/messages.json'.format(lang)))
168 for lang in ALL_LANGUAGES
169 ]
170
171 manifest = package.read('manifest.json')
172
173 # Chrome Web Store requires descriptive translations to be present in
174 # every language.
175 for match in re.finditer(r'__MSG_(\S+)__', manifest):
176 name = match.group(1)
177
178 for other in translations[1:]:
179 assert translations[0][name]['message'] == other[name]['message']
180
181
182 @pytest.mark.usefixtures(
183 'all_lang_locales',
184 'locale_modules',
185 'gecko_import',
186 'icons',
187 'lib_files',
188 'chrome_metadata',
189 'gecko_webext_metadata',
190 )
191 @pytest.mark.parametrize('platform', ['chrome', 'gecko-webext'])
192 @pytest.mark.parametrize('dev_build_release,buildnum', [
193 ('build', '1337'),
194 ('devenv', None),
195 ('release', None),
196 ])
197 def test_build_webext(platform, dev_build_release, keyfile, tmpdir, srcdir,
198 buildnum, capsys):
199 release = dev_build_release == 'release'
200 devenv = dev_build_release == 'devenv'
201
202 if platform == 'chrome' and release:
203 key = keyfile
204 else:
205 key = None
206
207 filenames = {
208 'gecko-webext': 'adblockplusfirefox-1.2.3{}.xpi',
209 'chrome': 'adblockpluschrome-1.2.3{{}}.{}'.format(
210 {True: 'crx', False: 'zip'}[release]
211 ),
212 }
213
214 expected_manifest = os.path.join(
215 os.path.dirname(__file__),
216 'expecteddata',
217 'manifest_{}_{}.json'.format(platform, dev_build_release),
218 )
219
220 run_webext_build(platform, dev_build_release, srcdir, buildnum=buildnum,
221 keyfile=key)
222
223 # The makeIcons() in packagerChrome.py should warn about non-square
224 # icons via stderr.
225 out, err = capsys.readouterr()
226 assert 'icon should be square' in err
227
228 if devenv:
229 content_class = DirContent
230 out_file_path = os.path.join(str(srcdir), 'devenv.' + platform)
231 else:
232 content_class = ZipContent
233
234 if release:
235 add_version = ''
236 else:
237 add_version = '.' + buildnum
238
239 out_file = filenames[platform].format(add_version)
240
241 out_file_path = os.path.abspath(os.path.join(
242 os.path.dirname(__file__), os.pardir, out_file))
243 assert os.path.exists(out_file_path)
244
245 if release and platform == 'chrome':
246 assert_chrome_signature(out_file_path, keyfile)
247
248 with content_class(out_file_path) as package:
249 assert_manifest_content(
250 package.read('manifest.json'), expected_manifest
251 )
252 assert_base_files(package)
253 assert_devenv_scripts(package, devenv)
254 assert_all_locales_present(package, '_locales')
255 assert_gecko_locale_conversion(package)
256 assert_convert_js(package, platform == 'gecko-webext')
257
258 if platform == 'chrome':
259 assert_locale_upfix(package)
OLDNEW
« no previous file with comments | « tests/test_packagerEdge.py ('k') | tests/tools.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld