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

Delta Between Two Patch Sets: tests/test_xtm_translations_utils.py

Issue 29886648: Issue #6942 - Add XTM integration in CMS (Closed)
Left Patch Set: Addressed initial comments Created Sept. 25, 2018, 12: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 import pytest 15
Vasily Kuznetsov 2018/09/26 15:45:27 Nit: pytest should be after stdlib.
Tudor Avram 2018/10/04 06:48:15 Done.
16 import json 16 import json
17 import os 17 import os
18 18
19 from cms.bin.xtm_translations import utils 19 import pytest
20 import cms.bin.xtm_translations.constants as const 20
21 from cms.translations.xtm import utils
22 import cms.translations.xtm.constants as const
21 from cms.sources import FileSource 23 from cms.sources import FileSource
22 from cms.bin.xtm_translations.xtm_api import XTMCloudAPI 24 from cms.translations.xtm.xtm_api import XTMCloudAPI
23
24 from tests.utils import exception_test 25 from tests.utils import exception_test
25 26
26 _API_TOKEN = 'TheXTM-APIToken-VALID' 27 _API_TOKEN = 'TheXTM-APIToken-VALID'
27 _PROJECT_ID = 1234 28 _PROJECT_ID = 1234
28 29
29 30
30 @pytest.fixture 31 @pytest.fixture
31 def toydir(tmpdir): 32 def toydir(tmpdir):
32 """""" 33 """Toy directory fixture with two locales - 'de' and 'en'."""
Vasily Kuznetsov 2018/09/26 15:45:27 Nit: probably no sense in having an empty docstrin
Tudor Avram 2018/10/04 06:48:15 Done.
33 toydir = tmpdir.mkdir('toydir') 34 toydir = tmpdir.mkdir('toydir')
34 35
35 en_dir = toydir.mkdir('en') 36 en_dir = toydir.mkdir('en')
36 en_dir.join('file.json').write(json.dumps({'a': 'b'})) 37 en_dir.join('file.json').write(json.dumps({'a': 'b'}))
37 38
38 de_dir = toydir.mkdir('de') 39 de_dir = toydir.mkdir('de')
39 de_dir.join('file.json').write(json.dumps({'a': 'b'})) 40 de_dir.join('file.json').write(json.dumps({'a': 'b'}))
40 de_dir.join('file.txt').write('test') 41 de_dir.join('file.txt').write('test')
41 42
42 return toydir 43 return toydir
43 44
44 45
45 def test_get_files_to_upload(): 46 def test_get_files_to_upload(temp_site):
46 """Generation of correct datatype for the XTMCloudAPI class.""" 47 """Generation of correct datatype for the XTMCloudAPI class."""
47 files = [('local.json', 'remote.json')] 48 files = utils.get_files_to_upload(FileSource(temp_site))
48 data = {'a': 'b', 'c': 12} 49
49 file_strings = {'local': data} 50 assert 'translate.json' in files
50 expected_output = [('remote.json', json.dumps(data))] 51 assert 'translate-not-enough.json' in files
51
52 assert expected_output == utils.get_files_to_upload(files, file_strings)
53 52
54 53
55 def test_read_token_invalid(): 54 def test_read_token_invalid():
56 """Test if appropriate exception is raised when no token is found.""" 55 """Test if appropriate exception is raised when no token is found."""
57 exp_msg = const.ErrorMessages.NO_TOKEN_PROVIDED.format( 56 exp_msg = const.ErrorMessages.NO_TOKEN_PROVIDED.format(
58 const.Token.CREATION_CMD, 57 const.Token.CREATION_CMD,
59 ) 58 )
60 with pytest.raises(Exception) as err: 59 with pytest.raises(Exception) as err:
61 utils.read_token() 60 utils.read_token()
62 assert exp_msg in str(err.value) 61 assert exp_msg in str(err.value)
63 62
64 63
65 def test_read_token_valid(): 64 def test_read_token_valid():
66 """Test if the token is read correctly when the env is setup.""" 65 """Test if the token is read correctly when the env is setup."""
67 env_var = const.Token.ENV_VAR 66 env_var = const.Token.ENV_VAR
68 token = 'test_token' 67 token = 'test_token'
69 os.environ[env_var] = token 68 os.environ[env_var] = token
70 69
71 try: 70 try:
72 assert token == utils.read_token() 71 assert token == utils.read_token()
73 finally: 72 finally:
74 del os.environ[env_var] 73 del os.environ[env_var]
75 74
76 75
77 def test_resolve_naming_conflicts_characters(): 76 def test_sanitize_project_name_characters():
78 """Test if invalid name characters are replaced as expected.""" 77 """Test if invalid name characters are replaced as expected."""
79 test_in = '{0}{1}{0}'.format( 78 test_in = '{0}{1}{0}'.format(
80 'test', ''.join(const.ProjectName.INVALID_CHARS), 79 'test', ''.join(const.ProjectName.INVALID_CHARS),
81 ) 80 )
82 exp_out = '{0}{1}{0}'.format( 81 exp_out = '{0}{1}{0}'.format(
83 'test', 82 'test',
84 const.ProjectName.NAME_WILDCARD * 83 const.ProjectName.NAME_WILDCARD *
85 len(const.ProjectName.INVALID_CHARS), 84 len(const.ProjectName.INVALID_CHARS),
86 ) 85 )
87 86
88 assert exp_out == utils.resolve_naming_conflicts(test_in) 87 assert exp_out == utils.sanitize_project_name(test_in)
89 88
90 89
91 def test_resolve_naming_conflicts_length(): 90 def test_sanitize_project_name_length():
92 """Test if names that are too long are truncated as expected.""" 91 """Test if names that are too long are truncated as expected."""
93 test_in = 'a' * (const.ProjectName.MAX_LENGTH + 10) 92 test_in = 'a' * (const.ProjectName.MAX_LENGTH + 10)
94 exp_out = 'a' * const.ProjectName.MAX_LENGTH 93 exp_out = 'a' * const.ProjectName.MAX_LENGTH
95 94
96 assert exp_out == utils.resolve_naming_conflicts(test_in) 95 assert exp_out == utils.sanitize_project_name(test_in)
97 96
98 97
99 def test_map_locales(temp_site): 98 def test_map_locales(temp_site):
100 """Test if a local website's languages are mapped to XTM's format.""" 99 """Test if a local website's languages are mapped to XTM's format."""
101 test_source = FileSource(str(temp_site)) 100 test_source = FileSource(str(temp_site))
102 exp_out = {'de_DE'} 101 exp_out = {'de_DE'}
103 102
104 assert exp_out == utils.map_locales(test_source) 103 assert exp_out == utils.map_locales(test_source)
105 104
106 105
107 def test_resolve_remote_filename_good(temp_site): 106 def test_remote_to_local_good(temp_site):
108 """Test if a remote filename is resolved to a valid OS path.""" 107 """Test if a remote filename is resolved to a valid OS path."""
109 test_in = '___foo___bar___faz___test.json' 108 test_in = '___foo___bar___faz___test.json'
110 exp_out = os.path.join(str(temp_site), *['foo', 'bar', 'faz', 'test.json']) 109 exp_out = os.path.join(str(temp_site), 'foo', 'bar', 'faz', 'test.json')
Vasily Kuznetsov 2018/09/26 15:45:26 Isn't this kind of the same as just removing the s
Tudor Avram 2018/10/04 06:48:14 Done.
111 110
112 assert exp_out == utils.resolve_remote_filename(test_in, str(temp_site), 111 assert exp_out == utils.remote_to_local(test_in, str(temp_site),
113 locales=['foo']) 112 locales=['foo'])
114 113
115 114
116 def test_resolve_remote_filename_exception(temp_site): 115 def test_remote_to_local_exception(temp_site):
117 test_in = '___foo___bar___faz___test.json' 116 test_in = '___foo___bar___faz___test.json'
118 exp_msg = const.ErrorMessages.CANT_RESOLVE_REMOTE_LANG.format('foo') 117 exp_msg = const.ErrorMessages.CANT_RESOLVE_REMOTE_LANG.format('foo')
119 118
120 exception_test(utils.resolve_remote_filename, Exception, exp_msg, 119 exception_test(utils.remote_to_local, Exception, exp_msg, test_in,
121 test_in, str(temp_site), locales=['bar']) 120 str(temp_site), locales=['bar'])
122 121
123 122
124 def test_run_and_wait_no_err(): 123 def test_run_and_wait_no_err():
125 exp_out = 'test' 124 exp_out = 'test'
126 125
127 def func(): 126 def func():
128 return exp_out 127 return exp_out
129 128
130 assert exp_out == utils.run_and_wait(func, Exception, '') 129 assert exp_out == utils.run_and_wait(func, Exception, '')
131 130
132 131
133 def test_run_and_wait_with_params(): 132 def test_run_and_wait_with_params():
134 test_in = 'test' 133 test_in = 'test'
135 134
136 def func(a): 135 def func(a):
137 return a 136 return a
138 137
139 assert test_in == utils.run_and_wait(func, Exception, '', a=test_in) 138 assert test_in == utils.run_and_wait(func, Exception, '', a=test_in)
140 139
141 140
142 @pytest.mark.slow_test 141 @pytest.mark.slow_test
143 def test_run_and_wait_infinite(): 142 def test_run_and_wait_infinite():
144 exp_msg = 'ERROR' 143 exp_msg = 'ERROR'
145 144
146 def func(): 145 def func():
147 raise Exception(exp_msg) 146 raise Exception(exp_msg)
148 147
149 with pytest.raises(Exception) as err: 148 with pytest.raises(Exception) as err:
150 utils.run_and_wait(func, Exception, exp_msg, max_tries=1) 149 utils.run_and_wait(func, Exception, exp_msg, retries=1)
151 150
152 assert exp_msg == str(err.value) 151 assert exp_msg == str(err.value)
153 152
154 153
155 def test_resolve_locales(intercept_populated, temp_site): 154 def test_resolve_locales(intercept_populated, temp_site):
156 """Test if locales are resolved correctly. 155 """Test if locales are resolved correctly.
157 156
158 In this environment, no languages have to be added. 157 In this environment, no languages have to be added.
159 """ 158 """
160 api = XTMCloudAPI(_API_TOKEN) 159 api = XTMCloudAPI(_API_TOKEN)
(...skipping 18 matching lines...) Expand all
179 assert exp_targets == api.get_target_languages(_PROJECT_ID) 178 assert exp_targets == api.get_target_languages(_PROJECT_ID)
180 179
181 180
182 def test_resolve_locales_raise_exception(intercept_populated, temp_site): 181 def test_resolve_locales_raise_exception(intercept_populated, temp_site):
183 """Test if locales are resolved correctly. 182 """Test if locales are resolved correctly.
184 183
185 In this environment, the API has more target languages configured than are 184 In this environment, the API has more target languages configured than are
186 available online. We except an exception to be raised. 185 available online. We except an exception to be raised.
187 """ 186 """
188 api = XTMCloudAPI(_API_TOKEN) 187 api = XTMCloudAPI(_API_TOKEN)
189 api.add_target_languages(_PROJECT_ID, ['ro_RO']) 188 api.add_target_languages(_PROJECT_ID, ['ro_RO'])
Vasily Kuznetsov 2018/09/26 15:45:27 ;)
Tudor Avram 2018/10/04 06:48:14 haha :D
190 source = FileSource(str(temp_site)) 189 source = FileSource(str(temp_site))
191 source.write_to_config('XTM', 'project_id', str(_PROJECT_ID)) 190 source.write_to_config('XTM', 'project_id', str(_PROJECT_ID))
192 exp_msg = ('The following languages are enabled in the API, but not ' 191 exp_msg = ('The following languages are enabled in the API, but not '
193 "listed in locales: set(['ro_RO'])! Please remove them manually" 192 "listed in locales: set(['ro_RO'])! Please remove them manually"
194 ' from project number 1234 and then re-run the script!') 193 ' from project number 1234 and then re-run the script!')
195 194
196 exception_test(utils.resolve_locales, Exception, exp_msg, api, source) 195 exception_test(utils.resolve_locales, Exception, exp_msg, api, source)
197 196
198 197
199 def test_list_locales(toydir): 198 def test_list_locales(toydir):
(...skipping 13 matching lines...) Expand all
213 212
214 213
215 @pytest.mark.parametrize('path', ['de/test.json', 'de/dir1/dir2/test.json']) 214 @pytest.mark.parametrize('path', ['de/test.json', 'de/dir1/dir2/test.json'])
216 def test_write_data(toydir, path): 215 def test_write_data(toydir, path):
217 """Test if writing data to files works as expected.""" 216 """Test if writing data to files works as expected."""
218 data = bytes(json.dumps({'a': 'b'})) 217 data = bytes(json.dumps({'a': 'b'}))
219 218
220 utils.write_to_file(data, str(toydir.join(path))) 219 utils.write_to_file(data, str(toydir.join(path)))
221 220
222 assert toydir.join(path).read('rb') == data 221 assert toydir.join(path).read('rb') == data
LEFTRIGHT

Powered by Google App Engine
This is Rietveld