1 | # -*- coding: utf-8 -*- |
||
2 | import tempfile |
||
3 | |||
4 | import pytest |
||
5 | |||
6 | from cookiecutter import zipfile |
||
7 | from cookiecutter.exceptions import InvalidZipRepository |
||
8 | |||
9 | |||
10 | def mock_download(): |
||
11 | with open('tests/files/fake-repo-tmpl.zip', 'rb') as zf: |
||
12 | chunk = zf.read(1024) |
||
13 | while chunk: |
||
14 | yield chunk |
||
15 | chunk = zf.read(1024) |
||
16 | |||
17 | |||
18 | def test_unzip_local_file(mocker, tmpdir): |
||
19 | """In `unzip()`, a local file reference can be unzipped. |
||
20 | """ |
||
21 | mock_prompt_and_delete = mocker.patch( |
||
22 | 'cookiecutter.zipfile.prompt_and_delete', |
||
23 | return_value=True, |
||
24 | autospec=True |
||
25 | ) |
||
26 | |||
27 | clone_to_dir = tmpdir.mkdir('clone') |
||
28 | |||
29 | output_dir = zipfile.unzip( |
||
30 | 'tests/files/fake-repo-tmpl.zip', |
||
31 | is_url=False, |
||
32 | clone_to_dir=str(clone_to_dir) |
||
33 | ) |
||
34 | |||
35 | assert output_dir.startswith(tempfile.gettempdir()) |
||
36 | assert not mock_prompt_and_delete.called |
||
37 | |||
38 | |||
39 | def test_unzip_protected_local_file_environment_password(mocker, tmpdir): |
||
40 | """In `unzip()`, the environment can be used to provide a repo password |
||
41 | """ |
||
42 | mock_prompt_and_delete = mocker.patch( |
||
43 | 'cookiecutter.zipfile.prompt_and_delete', |
||
44 | return_value=True, |
||
45 | autospec=True |
||
46 | ) |
||
47 | |||
48 | clone_to_dir = tmpdir.mkdir('clone') |
||
49 | |||
50 | output_dir = zipfile.unzip( |
||
51 | 'tests/files/protected-fake-repo-tmpl.zip', |
||
52 | is_url=False, |
||
53 | clone_to_dir=str(clone_to_dir), |
||
54 | password='sekrit' |
||
55 | ) |
||
56 | |||
57 | assert output_dir.startswith(tempfile.gettempdir()) |
||
58 | assert not mock_prompt_and_delete.called |
||
59 | |||
60 | |||
61 | def test_unzip_protected_local_file_bad_environment_password(mocker, tmpdir): |
||
62 | """In `unzip()`, an error occurs if the environment has a bad password. |
||
63 | """ |
||
64 | mocker.patch( |
||
65 | 'cookiecutter.zipfile.prompt_and_delete', |
||
66 | return_value=True, |
||
67 | autospec=True |
||
68 | ) |
||
69 | |||
70 | clone_to_dir = tmpdir.mkdir('clone') |
||
71 | |||
72 | with pytest.raises(InvalidZipRepository): |
||
73 | zipfile.unzip( |
||
74 | 'tests/files/protected-fake-repo-tmpl.zip', |
||
75 | is_url=False, |
||
76 | clone_to_dir=str(clone_to_dir), |
||
77 | password='not-the-right-password' |
||
78 | ) |
||
79 | |||
80 | |||
81 | def test_unzip_protected_local_file_user_password_with_noinput(mocker, tmpdir): |
||
82 | """In `unzip()`, you can't unpack a password-protected repo in no_input mode |
||
83 | """ |
||
84 | mocker.patch( |
||
85 | 'cookiecutter.zipfile.prompt_and_delete', |
||
86 | return_value=True, |
||
87 | autospec=True |
||
88 | ) |
||
89 | |||
90 | clone_to_dir = tmpdir.mkdir('clone') |
||
91 | |||
92 | with pytest.raises(InvalidZipRepository): |
||
93 | zipfile.unzip( |
||
94 | 'tests/files/protected-fake-repo-tmpl.zip', |
||
95 | is_url=False, |
||
96 | clone_to_dir=str(clone_to_dir), |
||
97 | no_input=True |
||
98 | ) |
||
99 | |||
100 | |||
101 | def test_unzip_protected_local_file_user_password(mocker, tmpdir): |
||
102 | """In `unzip()`, a password-protected local file reference can be unzipped. |
||
103 | """ |
||
104 | mock_prompt_and_delete = mocker.patch( |
||
105 | 'cookiecutter.zipfile.prompt_and_delete', |
||
106 | return_value=True, |
||
107 | autospec=True |
||
108 | ) |
||
109 | mocker.patch( |
||
110 | 'cookiecutter.zipfile.read_repo_password', |
||
111 | return_value='sekrit' |
||
112 | ) |
||
113 | |||
114 | clone_to_dir = tmpdir.mkdir('clone') |
||
115 | |||
116 | output_dir = zipfile.unzip( |
||
117 | 'tests/files/protected-fake-repo-tmpl.zip', |
||
118 | is_url=False, |
||
119 | clone_to_dir=str(clone_to_dir) |
||
120 | ) |
||
121 | |||
122 | assert output_dir.startswith(tempfile.gettempdir()) |
||
123 | assert not mock_prompt_and_delete.called |
||
124 | |||
125 | |||
126 | def test_unzip_protected_local_file_user_bad_password(mocker, tmpdir): |
||
127 | """In `unzip()`, If you can't provide a valid password, you get an error |
||
128 | """ |
||
129 | mocker.patch( |
||
130 | 'cookiecutter.zipfile.prompt_and_delete', |
||
131 | return_value=True, |
||
132 | autospec=True |
||
133 | ) |
||
134 | mocker.patch( |
||
135 | 'cookiecutter.zipfile.read_repo_password', |
||
136 | return_value='not-the-right-password' |
||
137 | ) |
||
138 | |||
139 | clone_to_dir = tmpdir.mkdir('clone') |
||
140 | |||
141 | with pytest.raises(InvalidZipRepository): |
||
142 | zipfile.unzip( |
||
143 | 'tests/files/protected-fake-repo-tmpl.zip', |
||
144 | is_url=False, |
||
145 | clone_to_dir=str(clone_to_dir) |
||
146 | ) |
||
147 | |||
148 | |||
149 | def test_empty_zip_file(mocker, tmpdir): |
||
150 | """In `unzip()`, an empty file raises an error. |
||
151 | """ |
||
152 | mocker.patch( |
||
153 | 'cookiecutter.zipfile.prompt_and_delete', |
||
154 | return_value=True, |
||
155 | autospec=True |
||
156 | ) |
||
157 | |||
158 | clone_to_dir = tmpdir.mkdir('clone') |
||
159 | |||
160 | with pytest.raises(InvalidZipRepository): |
||
161 | zipfile.unzip( |
||
162 | 'tests/files/empty.zip', |
||
163 | is_url=False, |
||
164 | clone_to_dir=str(clone_to_dir) |
||
165 | ) |
||
166 | |||
167 | |||
168 | def test_non_repo_zip_file(mocker, tmpdir): |
||
169 | """In `unzip()`, a repository must have a top level directory |
||
170 | """ |
||
171 | mocker.patch( |
||
172 | 'cookiecutter.zipfile.prompt_and_delete', |
||
173 | return_value=True, |
||
174 | autospec=True |
||
175 | ) |
||
176 | |||
177 | clone_to_dir = tmpdir.mkdir('clone') |
||
178 | |||
179 | with pytest.raises(InvalidZipRepository): |
||
180 | zipfile.unzip( |
||
181 | 'tests/files/not-a-repo.zip', |
||
182 | is_url=False, |
||
183 | clone_to_dir=str(clone_to_dir) |
||
184 | ) |
||
185 | |||
186 | |||
187 | def test_bad_zip_file(mocker, tmpdir): |
||
188 | """In `unzip()`, a corrupted zip file raises an error. |
||
189 | """ |
||
190 | mocker.patch( |
||
191 | 'cookiecutter.zipfile.prompt_and_delete', |
||
192 | return_value=True, |
||
193 | autospec=True |
||
194 | ) |
||
195 | |||
196 | clone_to_dir = tmpdir.mkdir('clone') |
||
197 | |||
198 | with pytest.raises(InvalidZipRepository): |
||
199 | zipfile.unzip( |
||
200 | 'tests/files/bad-zip-file.zip', |
||
201 | is_url=False, |
||
202 | clone_to_dir=str(clone_to_dir) |
||
203 | ) |
||
204 | |||
205 | |||
206 | View Code Duplication | def test_unzip_url(mocker, tmpdir): |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
207 | """In `unzip()`, a url will be downloaded and unzipped |
||
208 | """ |
||
209 | mock_prompt_and_delete = mocker.patch( |
||
210 | 'cookiecutter.zipfile.prompt_and_delete', |
||
211 | return_value=True, |
||
212 | autospec=True |
||
213 | ) |
||
214 | |||
215 | request = mocker.MagicMock() |
||
216 | request.iter_content.return_value = mock_download() |
||
217 | |||
218 | mocker.patch( |
||
219 | 'cookiecutter.zipfile.requests.get', |
||
220 | return_value=request, |
||
221 | autospec=True, |
||
222 | ) |
||
223 | |||
224 | clone_to_dir = tmpdir.mkdir('clone') |
||
225 | |||
226 | output_dir = zipfile.unzip( |
||
227 | 'https://example.com/path/to/fake-repo-tmpl.zip', |
||
228 | is_url=True, |
||
229 | clone_to_dir=str(clone_to_dir) |
||
230 | ) |
||
231 | |||
232 | assert output_dir.startswith(tempfile.gettempdir()) |
||
233 | assert not mock_prompt_and_delete.called |
||
234 | |||
235 | |||
236 | View Code Duplication | def test_unzip_url_existing_cache(mocker, tmpdir): |
|
0 ignored issues
–
show
|
|||
237 | """In `unzip()`, a url will be downloaded and unzipped; an existing zip file |
||
238 | will be removed. |
||
239 | """ |
||
240 | mock_prompt_and_delete = mocker.patch( |
||
241 | 'cookiecutter.zipfile.prompt_and_delete', |
||
242 | return_value=True, |
||
243 | autospec=True |
||
244 | ) |
||
245 | |||
246 | request = mocker.MagicMock() |
||
247 | request.iter_content.return_value = mock_download() |
||
248 | |||
249 | mocker.patch( |
||
250 | 'cookiecutter.zipfile.requests.get', |
||
251 | return_value=request, |
||
252 | autospec=True, |
||
253 | ) |
||
254 | |||
255 | clone_to_dir = tmpdir.mkdir('clone') |
||
256 | |||
257 | # Create an existing cache of the zipfile |
||
258 | existing_zip = clone_to_dir.join('fake-repo-tmpl.zip') |
||
259 | existing_zip.write('This is an existing zipfile') |
||
260 | |||
261 | output_dir = zipfile.unzip( |
||
262 | 'https://example.com/path/to/fake-repo-tmpl.zip', |
||
263 | is_url=True, |
||
264 | clone_to_dir=str(clone_to_dir) |
||
265 | ) |
||
266 | |||
267 | assert output_dir.startswith(tempfile.gettempdir()) |
||
268 | assert mock_prompt_and_delete.call_count == 1 |
||
269 | |||
270 | |||
271 | def test_unzip_url_existing_cache_no_input(mocker, tmpdir): |
||
272 | """In `unzip()`, if no_input is provided, the existing file will be removed. |
||
273 | """ |
||
274 | request = mocker.MagicMock() |
||
275 | request.iter_content.return_value = mock_download() |
||
276 | |||
277 | mocker.patch( |
||
278 | 'cookiecutter.zipfile.requests.get', |
||
279 | return_value=request, |
||
280 | autospec=True, |
||
281 | ) |
||
282 | |||
283 | clone_to_dir = tmpdir.mkdir('clone') |
||
284 | |||
285 | # Create an existing cache of the zipfile |
||
286 | existing_zip = clone_to_dir.join('fake-repo-tmpl.zip') |
||
287 | existing_zip.write('This is an existing zipfile') |
||
288 | |||
289 | output_dir = zipfile.unzip( |
||
290 | 'https://example.com/path/to/fake-repo-tmpl.zip', |
||
291 | is_url=True, |
||
292 | clone_to_dir=str(clone_to_dir), |
||
293 | no_input=True |
||
294 | ) |
||
295 | |||
296 | assert output_dir.startswith(tempfile.gettempdir()) |
||
297 | |||
298 | |||
299 | View Code Duplication | def test_unzip_should_abort_if_no_redownload(mocker, tmpdir): |
|
0 ignored issues
–
show
|
|||
300 | """In `unzip()`, if user doesn't want to download, Cookiecutter should exit |
||
301 | without cloning anything. |
||
302 | """ |
||
303 | mocker.patch( |
||
304 | 'cookiecutter.zipfile.prompt_and_delete', |
||
305 | side_effect=SystemExit, |
||
306 | autospec=True |
||
307 | ) |
||
308 | |||
309 | mock_requests_get = mocker.patch( |
||
310 | 'cookiecutter.zipfile.requests.get', |
||
311 | autospec=True, |
||
312 | ) |
||
313 | |||
314 | clone_to_dir = tmpdir.mkdir('clone') |
||
315 | |||
316 | # Create an existing cache of the zipfile |
||
317 | existing_zip = clone_to_dir.join('fake-repo-tmpl.zip') |
||
318 | existing_zip.write('This is an existing zipfile') |
||
319 | |||
320 | zipfile_url = 'https://example.com/path/to/fake-repo-tmpl.zip' |
||
321 | |||
322 | with pytest.raises(SystemExit): |
||
323 | zipfile.unzip(zipfile_url, is_url=True, clone_to_dir=str(clone_to_dir)) |
||
324 | |||
325 | assert not mock_requests_get.called |
||
326 |