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

Delta Between Two Patch Sets: tests/test_xtm_translate.py

Issue 29886648: Issue #6942 - Add XTM integration in CMS (Closed)
Left Patch Set: Created Sept. 20, 2018, 4:24 p.m.
Right Patch Set: Addressed comments from Patch Set #4 Created Oct. 5, 2018, 4:23 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 # This file is part of the Adblock Plus web scripts, 1 # This file is part of the Adblock Plus web scripts,
2 # Copyright (C) 2006-present eyeo GmbH 2 # Copyright (C) 2006-present eyeo GmbH
3 # 3 #
4 # Adblock Plus is free software: you can redistribute it and/or modify 4 # Adblock Plus is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 3 as 5 # it under the terms of the GNU General Public License version 3 as
6 # published by the Free Software Foundation. 6 # published by the Free Software Foundation.
7 # 7 #
8 # Adblock Plus is distributed in the hope that it will be useful, 8 # Adblock Plus is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details. 11 # GNU General Public License for more details.
12 # 12 #
13 # You should have received a copy of the GNU General Public License 13 # You should have received a copy of the GNU General Public License
14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
15
15 from __future__ import unicode_literals 16 from __future__ import unicode_literals
16
17 import pytest
18 17
19 import os 18 import os
20 from ConfigParser import SafeConfigParser 19 from ConfigParser import SafeConfigParser
21 import io 20 import io
22 import sys 21 import sys
23 import json 22 import json
24 23
25 from cms.bin.xtm_translations import constants as cnts 24 import pytest
26 from cms.bin.xtm_translations.projects_handler import ( 25
27 main as main_project_handler, 26 from cms.translations.xtm import constants as const
27 from cms.translations.xtm.projects_handler import (
28 create_project, upload_files, download_files, 28 create_project, upload_files, download_files,
29 ) 29 )
30 from cms.bin.xtm_translations.translate_xtm_cloud import generate_token 30 from cms.translations.xtm.cli import (
31 generate_token, handle_projects as main_project_handler,
32 )
31 33
32 _CMD_START = ['python', '-m', 'cms.bin.xtm_translations'] 34 _CMD_START = ['python', '-m', 'cms.bin.xtm_translations']
33 35
34 _ENV_NO_TOKEN = dict(os.environ) 36 _ENV_NO_TOKEN = dict(os.environ)
35 _ENV_NO_TOKEN.pop(cnts.TOKEN['env_var'], None) 37 _ENV_NO_TOKEN.pop(const.Token.ENV_VAR, None)
36 38
37 _ENV_TOKEN_VALID = dict(os.environ) 39 _ENV_TOKEN_VALID = dict(os.environ)
38 _ENV_TOKEN_VALID[cnts.TOKEN['env_var']] = 'TheXTM-APIToken-VALID' 40 _ENV_TOKEN_VALID[const.Token.ENV_VAR] = 'TheXTM-APIToken-VALID'
39 41
40 _ENV_TOKEN_INVALID = dict(os.environ) 42 _ENV_TOKEN_INVALID = dict(os.environ)
41 _ENV_TOKEN_INVALID[cnts.TOKEN['env_var']] = 'TheXTM-APIToken-INVALID' 43 _ENV_TOKEN_INVALID[const.Token.ENV_VAR] = 'TheXTM-APIToken-INVALID'
42 44
43 45
44 class _CreationArgsNamespace: 46 class _CreationArgsNamespace:
45 def __init__(self): 47 def __init__(self):
46 pass 48 pass
47 49
48 name = 'bar' 50 name = 'bar'
49 desc = 'foo' 51 desc = 'foo'
50 client_id = 10 52 client_id = 10
51 ref_id = 'faz' 53 ref_id = 'faz'
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 @pytest.fixture 88 @pytest.fixture
87 def env_valid_token(): 89 def env_valid_token():
88 old_env = os.environ 90 old_env = os.environ
89 os.environ = _ENV_TOKEN_VALID 91 os.environ = _ENV_TOKEN_VALID
90 yield True 92 yield True
91 os.environ = old_env 93 os.environ = old_env
92 94
93 95
94 @pytest.mark.script_launch_mode('subprocess') 96 @pytest.mark.script_launch_mode('subprocess')
95 @pytest.mark.parametrize('args,exp_msg', [ 97 @pytest.mark.parametrize('args,exp_msg', [
96 (['-h'], 'usage: __main__.py [-h] [-v] {login,create,upload,download} ' 98 (['-h'], 'usage: xtm_translations.py [-h] [-v] '
97 '...'), 99 '{login,create,upload,download} ...'),
98 (['create', '-h'], 'usage: __main__.py create [-h] --name NAME --desc ' 100 (['create', '-h'], 'usage: xtm_translations.py create [-h] --name NAME '
99 'DESC --client-id CLIENT_ID --ref-id REF_ID ' 101 '--desc DESC --client-id CLIENT_ID --ref-id REF_ID '
100 '--workflow-id WORKFLOW_ID [--source-lang SOURCE_LANG] ' 102 '--workflow-id WORKFLOW_ID [--source-lang SOURCE_LANG] '
101 '[--save-id] [source_dir]'), 103 '[--save-id] [source_dir]'),
102 (['upload', '-h'], 'usage: __main__.py upload [-h] [--no-overwrite] ' 104 (['upload', '-h'], 'usage: xtm_translations.py upload [-h] '
103 '[source_dir]'), 105 '[--no-overwrite] [source_dir]'),
104 (['download', '-h'], 'usage: __main__.py download [-h] [source_dir]'), 106 (['download', '-h'], 'usage: xtm_translations.py download [-h] '
107 '[source_dir]'),
105 ]) 108 ])
106 def test_usage_messages(args, exp_msg, script_runner): 109 def test_usage_messages(args, exp_msg, script_runner):
107 """Test if appropriate usage messages are displayed.""" 110 """Test if appropriate usage messages are displayed."""
108 cmd = list(_CMD_START) 111 cmd = list(_CMD_START)
109 cmd.extend(args) 112 cmd.extend(args)
110 ret = script_runner.run(*cmd) 113 ret = script_runner.run(*cmd)
111 114
112 usg_msg = ret.stdout.replace('\n', '').replace(' ', '') 115 usg_msg = ret.stdout.replace('\n', '').replace(' ', '')
113 116
114 assert exp_msg.replace(' ', '') in usg_msg 117 assert exp_msg.replace(' ', '') in usg_msg
115 118
116 119
117 @pytest.mark.script_launch_mode('subprocess') 120 @pytest.mark.script_launch_mode('subprocess')
118 @pytest.mark.parametrize('args', [ 121 @pytest.mark.parametrize('args', [
119 ['create', '--name', 'bar', '--desc', 'foo', '--client-id', '1', 122 ['create', '--name', 'bar', '--desc', 'foo', '--client-id', '1',
120 '--ref-id', 'faz', '--workflow-id', '3'], 123 '--ref-id', 'faz', '--workflow-id', '3'],
121 ['upload'], 124 ['upload'],
122 ['download'], 125 ['download'],
123 ]) 126 ])
124 def test_default_source_directory(args, script_runner): 127 def test_default_source_directory(args, script_runner):
125 """Test if the source directory if set to default if not provided.""" 128 """Test if the source directory if set to default if not provided."""
126 exp = cnts.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0] 129 exp = const.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]
127 cmd = list(_CMD_START) 130 cmd = list(_CMD_START)
128 cmd.extend(args) 131 cmd.extend(args)
129 132
130 ret = script_runner.run(*cmd) 133 ret = script_runner.run(*cmd)
131 134
132 assert not ret.success 135 assert not ret.success
133 assert exp in ret.stderr 136 assert exp in ret.stderr
134 137
135 138
136 @pytest.mark.script_launch_mode('subprocess') 139 @pytest.mark.script_launch_mode('subprocess')
137 @pytest.mark.parametrize('source_dir,args,env,exp_msg', [ 140 @pytest.mark.parametrize('source_dir,args,env,exp_msg', [
138 ('str(temp_site)', _CREATION_ARGS_INVALID_TYPE_1, _ENV_NO_TOKEN, 141 ('str(temp_site)', _CREATION_ARGS_INVALID_TYPE_1, _ENV_NO_TOKEN,
139 "--client-id: invalid int value: 'foo'"), 142 "--client-id: invalid int value: 'foo'"),
140 ('str(temp_site)', _CREATION_ARGS_INVALID_TYPE_2, _ENV_NO_TOKEN, 143 ('str(temp_site)', _CREATION_ARGS_INVALID_TYPE_2, _ENV_NO_TOKEN,
141 "--workflow-id: invalid int value: 'foo'"), 144 "--workflow-id: invalid int value: 'foo'"),
142 ('str(temp_site)', _CREATION_ARGS_DEFAULT, _ENV_NO_TOKEN, 145 ('str(temp_site)', _CREATION_ARGS_DEFAULT, _ENV_NO_TOKEN,
143 cnts.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]), 146 const.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]),
144 ('str(temp_site_valid_project)', _CREATION_ARGS_DEFAULT, _ENV_TOKEN_VALID, 147 ('str(temp_site_valid_project)', _CREATION_ARGS_DEFAULT, _ENV_TOKEN_VALID,
145 cnts.ErrorMessages.EXISTENT_PROJECT.format(1234)), 148 const.ErrorMessages.PROJECT_EXISTS.format(1234)),
146 ('str(temp_site)', _CREATION_ARGS_DEFAULT, _ENV_TOKEN_INVALID, 149 ('str(temp_site)', _CREATION_ARGS_DEFAULT, _ENV_TOKEN_INVALID,
147 'Authentication failed'), 150 'Authentication failed'),
148 ]) 151 ])
149 def test_creation_error_messages(temp_site, intercept, script_runner, args, 152 def test_creation_error_messages(temp_site, intercept, script_runner, args,
150 source_dir, temp_site_valid_project, env, 153 source_dir, temp_site_valid_project, env,
151 exp_msg): 154 exp_msg):
152 """Test if error cases are treated correctly when creating a project.""" 155 """Test if error cases are treated correctly when creating a project."""
153 cmd = list(_CMD_START) 156 cmd = list(_CMD_START)
154 cmd.extend(['create', eval(source_dir)]) 157 cmd.extend(['create', eval(source_dir)])
155 cmd.extend(args) 158 cmd.extend(args)
(...skipping 16 matching lines...) Expand all
172 namespace = _CreationArgsNamespace() 175 namespace = _CreationArgsNamespace()
173 namespace.source_dir = str(temp_site) 176 namespace.source_dir = str(temp_site)
174 namespace.save_id = True 177 namespace.save_id = True
175 main_project_handler(namespace) 178 main_project_handler(namespace)
176 cnf = SafeConfigParser() 179 cnf = SafeConfigParser()
177 try: 180 try:
178 with io.open(os.path.join(temp_site, 'settings.ini'), 181 with io.open(os.path.join(temp_site, 'settings.ini'),
179 encoding='utf-8') as f: 182 encoding='utf-8') as f:
180 cnf_data = f.read() 183 cnf_data = f.read()
181 cnf.readfp(io.StringIO(cnf_data)) 184 cnf.readfp(io.StringIO(cnf_data))
182 project_id = cnf.get(cnts.CONFIG['XTM_section'], 185 project_id = cnf.get(const.Config.XTM_SECTION,
183 cnts.CONFIG['project_option']) 186 const.Config.PROJECT_OPTION)
184 187
185 assert int(project_id) == 1234 188 assert int(project_id) == 1234
186 finally: 189 finally:
187 cnf.remove_option(cnts.CONFIG['XTM_section'], 190 cnf.remove_option(const.Config.XTM_SECTION,
188 cnts.CONFIG['project_option']) 191 const.Config.PROJECT_OPTION)
189 cnf.write(open(os.path.join(temp_site, 'settings.ini'), 'w')) 192 cnf.write(open(os.path.join(temp_site, 'settings.ini'), 'w'))
190 193
191 194
192 def test_login(intercept, monkeypatch, capsys): 195 def test_login(intercept, monkeypatch, capsys):
193 """Test if the login functionality works as expected.""" 196 """Test if the login functionality works as expected."""
194 exp_output = cnts.TOKEN['save_cmd'].format(cnts.TOKEN['env_var'], 197 exp_output = const.Token.SAVE_COMMAND.format(const.Token.ENV_VAR,
195 'TheXTM-APIToken-VALID') 198 'TheXTM-APIToken-VALID')
196 monkeypatch.setattr('cms.bin.xtm_translations.translate_xtm_cloud.input', 199 monkeypatch.setattr(
197 lambda inp: 'admin' if 'username' in inp.lower() 200 'cms.translations.xtm.cli.input_fn',
198 else '20') 201 lambda inp: 'admin' if 'username' in inp.lower() else '20',
202 )
199 monkeypatch.setattr('getpass.getpass', lambda prompt: 'pass') 203 monkeypatch.setattr('getpass.getpass', lambda prompt: 'pass')
200 204
201 generate_token(None) 205 generate_token(None)
202 out, err = capsys.readouterr() 206 out, err = capsys.readouterr()
203 207
204 assert err == '' 208 assert err == ''
205 assert exp_output in out 209 assert exp_output in out
206 210
207 211
208 def test_login_wrong_credentials(intercept, monkeypatch, capsys): 212 def test_login_wrong_credentials(intercept, monkeypatch, capsys):
209 """Test exception handling when generating the tokens.""" 213 """Test exception handling when generating the tokens."""
210 monkeypatch.setattr('cms.bin.xtm_translations.translate_xtm_cloud.input', 214 monkeypatch.setattr(
211 lambda inp: 'foo' if 'username' in inp.lower() else 215 'cms.translations.xtm.cli.input_fn',
212 '50') 216 lambda inp: 'foo' if 'username' in inp.lower() else '50',
217 )
213 monkeypatch.setattr('getpass.getpass', lambda prompt: 'pass') 218 monkeypatch.setattr('getpass.getpass', lambda prompt: 'pass')
214 monkeypatch.setattr('sys.exit', lambda x: sys.stderr.write(str(x))) 219 monkeypatch.setattr('sys.exit', lambda x: sys.stderr.write(str(x)))
215 220
216 generate_token(None) 221 generate_token(None)
217 out, err = capsys.readouterr() 222 out, err = capsys.readouterr()
218 223
219 assert 'Invalid credentials' in err 224 assert 'Invalid credentials' in err
220 assert out == '' 225 assert out == ''
221 226
222 227
223 @pytest.mark.script_launch_mode('subprocess') 228 @pytest.mark.script_launch_mode('subprocess')
224 @pytest.mark.parametrize('args,env,exp_msg', [ 229 @pytest.mark.parametrize('args,env,exp_msg', [
225 (['str(temp_site)'], _ENV_NO_TOKEN, 230 (['str(temp_site)'], _ENV_NO_TOKEN,
226 cnts.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]), 231 const.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]),
227 (['str(temp_site)'], _ENV_TOKEN_VALID, 'No project configured'), 232 (['str(temp_site)'], _ENV_TOKEN_VALID, 'No project configured'),
228 ]) 233 ])
229 def test_upload_error_messages_as_script(temp_site, script_runner, args, env, 234 def test_upload_error_messages_as_script(temp_site, script_runner, args, env,
230 exp_msg): 235 exp_msg):
231 cmd = list(_CMD_START) 236 cmd = list(_CMD_START)
232 cmd.append('upload') 237 cmd.append('upload')
233 238
234 cmd.extend(list(map(eval, args))) 239 cmd.extend(list(map(eval, args)))
235 240
236 ret = script_runner.run(*cmd, env=env) 241 ret = script_runner.run(*cmd, env=env)
(...skipping 16 matching lines...) Expand all
253 258
254 def test_upload_successful(intercept, env_valid_token, 259 def test_upload_successful(intercept, env_valid_token,
255 temp_site_valid_project, monkeypatch, capsys): 260 temp_site_valid_project, monkeypatch, capsys):
256 namespace = _UploadArgsNamespace() 261 namespace = _UploadArgsNamespace()
257 namespace.source_dir = str(temp_site_valid_project) 262 namespace.source_dir = str(temp_site_valid_project)
258 monkeypatch.setattr('logging.info', lambda x: sys.stderr.write(x)) 263 monkeypatch.setattr('logging.info', lambda x: sys.stderr.write(x))
259 264
260 main_project_handler(namespace) 265 main_project_handler(namespace)
261 _, err = capsys.readouterr() 266 _, err = capsys.readouterr()
262 267
263 assert cnts.InfoMessages.FILES_UPLOADED in err 268 assert const.InfoMessages.FILES_UPLOADED in err
264 assert 'Created job 1' in err 269 assert 'Created job 1' in err
265 270
266 271
267 @pytest.mark.script_launch_mode('subprocess') 272 @pytest.mark.script_launch_mode('subprocess')
268 @pytest.mark.parametrize('env,exp_msg', [ 273 @pytest.mark.parametrize('env,exp_msg', [
269 (_ENV_NO_TOKEN, cnts.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]), 274 (_ENV_NO_TOKEN, const.ErrorMessages.NO_TOKEN_PROVIDED.split('\n')[0]),
270 (_ENV_TOKEN_VALID, 'No project configured'), 275 (_ENV_TOKEN_VALID, 'No project configured'),
271 ]) 276 ])
272 def test_download_error_messages_as_script(temp_site, script_runner, env, 277 def test_download_error_messages_as_script(temp_site, script_runner, env,
273 exp_msg): 278 exp_msg):
274 cmd = list(_CMD_START) 279 cmd = list(_CMD_START)
275 cmd.extend(['download', str(temp_site)]) 280 cmd.extend(['download', str(temp_site)])
276 281
277 ret = script_runner.run(*cmd, env=env) 282 ret = script_runner.run(*cmd, env=env)
278 283
279 assert not ret.success 284 assert not ret.success
280 assert exp_msg in ret.stderr 285 assert exp_msg in ret.stderr
281 286
282 287
283 def test_download_no_target_files(temp_site_no_target_files, env_valid_token, 288 def test_download_no_target_files(temp_site_no_target_files, env_valid_token,
284 intercept, monkeypatch, capsys): 289 intercept, monkeypatch, capsys):
285 namespace = _DownloadArgsNamespace() 290 namespace = _DownloadArgsNamespace()
286 namespace.source_dir = str(temp_site_no_target_files) 291 namespace.source_dir = str(temp_site_no_target_files)
287 monkeypatch.setattr('sys.exit', lambda x: sys.stderr.write(x)) 292 monkeypatch.setattr('sys.exit', lambda x: sys.stderr.write(x))
288 293
289 main_project_handler(namespace) 294 main_project_handler(namespace)
290 out, err = capsys.readouterr() 295 out, err = capsys.readouterr()
291 296
292 assert cnts.ErrorMessages.NO_TARGET_FILES_FOUND in err 297 assert const.ErrorMessages.NO_TARGET_FILES_FOUND in err
293 298
294 299
295 def test_download_saves_to_disk(temp_site_valid_project, env_valid_token, 300 def test_download_saves_to_disk(temp_site_valid_project, env_valid_token,
296 intercept_populated): 301 intercept_populated):
297 namespace = _DownloadArgsNamespace() 302 namespace = _DownloadArgsNamespace()
298 namespace.source_dir = str(temp_site_valid_project) 303 namespace.source_dir = str(temp_site_valid_project)
299 304
300 main_project_handler(namespace) 305 main_project_handler(namespace)
301 306
302 with open(os.path.join(temp_site_valid_project, 'locales', 'de', 307 with open(os.path.join(temp_site_valid_project, 'locales', 'de',
303 'file.json')) as f: 308 'file.json')) as f:
304 assert json.dumps({'foo': 'bar', 'faz': 'baz'}) == f.read() 309 assert json.dumps({'foo': 'bar', 'faz': 'baz'}) == f.read()
305 310
306 with open(os.path.join(temp_site_valid_project, 'locales', 'de', 'foo', 311 with open(os.path.join(temp_site_valid_project, 'locales', 'de', 'foo',
307 'file-utf8.json'), 'rb') as f: 312 'file-utf8.json'), 'rb') as f:
308 assert json.loads(f.read()) == {'foo': '\u1234'} 313 assert json.loads(f.read()) == {'foo': '\u1234'}
LEFTRIGHT

Powered by Google App Engine
This is Rietveld