Completed
Pull Request — master (#961)
by
unknown
41s
created

test_unzip_url()   B

Complexity

Conditions 3

Size

Total Lines 28

Duplication

Lines 28
Ratio 100 %

Importance

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