Skip to content

Commit e9a69a2

Browse files
authored
Simplified multipart upload tests (#63)
1 parent 767d756 commit e9a69a2

File tree

3 files changed

+49
-82
lines changed

3 files changed

+49
-82
lines changed

tests/client_test.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
from unittest.mock import patch, mock_open
2-
from collections import defaultdict
32

43
import pytest
54
from trafaret import DataError
65
from httmock import urlmatch, HTTMock, response
76

87
import filestack.models
98
from filestack import Client, Filelink, Transformation, Security
10-
from tests.helpers import DummyHttpResponse
119

1210

1311
APIKEY = 'APIKEY'
@@ -92,23 +90,3 @@ def api_zip(url, request):
9290

9391
assert zip_size == 9
9492
m().write.assert_called_once_with(b'zip-bytes')
95-
96-
97-
@patch('requests.put')
98-
@patch('requests.post')
99-
def test_upload_multipart_workflows(post_mock, put_mock, client):
100-
101-
workflow_ids = ['workflow-id-1', 'workflow-id-2']
102-
store_params = {'workflows': workflow_ids}
103-
put_mock.return_value = DummyHttpResponse(headers={'ETag': 'some_tag'})
104-
post_mock.side_effect = [
105-
DummyHttpResponse(json_dict=defaultdict(str)),
106-
DummyHttpResponse(json_dict=defaultdict(str)),
107-
DummyHttpResponse(json_dict={'handle': 'new_handle'})
108-
]
109-
110-
new_filelink = client.upload(filepath='tests/data/bird.jpg', store_params=store_params)
111-
112-
post_args, post_kwargs = post_mock.call_args
113-
assert post_kwargs['json']['store']['workflows'] == workflow_ids
114-
assert new_filelink.handle == 'new_handle'

tests/intelligent_ingestion_test.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33

44
import pytest
55

6-
from filestack import Security
7-
from filestack.uploads.intelligent_ingestion import upload_part, upload
6+
from filestack.uploads.intelligent_ingestion import upload_part
87
from tests.helpers import DummyHttpResponse
98

109

tests/multipart_test.py

Lines changed: 48 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,76 @@
11
import io
22
import json
33
from collections import defaultdict
4-
from unittest.mock import patch
54

65
import responses
7-
from httmock import HTTMock, response, urlmatch
6+
import pytest
87

9-
from tests.helpers import DummyHttpResponse
108
from filestack import Client
119
from filestack import config
1210
from filestack.uploads.multipart import upload_chunk, Chunk
1311

1412
APIKEY = 'APIKEY'
1513
HANDLE = 'SOMEHANDLE'
16-
URL = 'https://cdn.filestackcontent.com/{}'.format(HANDLE)
1714

1815

19-
def chunk_put_callback(request):
20-
body = {'url': URL}
21-
return 200, {'ETag': 'someetags'}, json.dumps(body)
16+
@pytest.fixture
17+
def multipart_mock():
18+
with responses.RequestsMock() as rsps:
19+
rsps.add(
20+
responses.POST, config.MULTIPART_START_URL, status=200,
21+
json={
22+
'region': 'us-east-1', 'upload_id': 'someuuid', 'uri': 'someuri',
23+
'location_url': 'fs-uploads.com'
24+
}
25+
)
26+
rsps.add(
27+
responses.POST, 'https://fs-uploads.com/multipart/upload',
28+
status=200, content_type='application/json',
29+
json={'url': 'http://somewhere.on.s3', 'headers': {'filestack': 'header'}}
30+
)
31+
rsps.add(responses.PUT, 'http://somewhere.on.s3', json={}, headers={'ETag': 'abc'})
32+
rsps.add(
33+
responses.POST, 'https://fs-uploads.com/multipart/complete', status=200,
34+
json={'url': 'https://cdn.filestackcontent.com/{}'.format(HANDLE), 'handle': HANDLE}
35+
)
36+
yield rsps
2237

2338

24-
@responses.activate
25-
def test_upload_filepath():
39+
def test_upload_filepath(multipart_mock):
2640
client = Client(APIKEY)
27-
28-
# add the different HTTP responses that are called during the multipart upload
29-
responses.add(
30-
responses.POST, config.MULTIPART_START_URL, status=200, content_type='application/json',
31-
json={'region': 'us-east-1', 'upload_id': 'someuuid', 'uri': 'someuri', 'location_url': 'fs-uploads.com'}
32-
)
33-
responses.add(
34-
responses.POST, 'https://fs-uploads.com/multipart/upload',
35-
status=200, content_type='application/json', json={'url': URL, 'headers': {}}
36-
)
37-
responses.add_callback(responses.PUT, URL, callback=chunk_put_callback)
38-
responses.add(
39-
responses.POST, 'https://fs-uploads.com/multipart/complete', status=200,
40-
content_type='application/json', json={'url': URL, 'handle': HANDLE}
41-
)
42-
43-
new_filelink = client.upload(filepath='tests/data/doom.mp4')
44-
assert new_filelink.handle == HANDLE
41+
filelink = client.upload(filepath='tests/data/doom.mp4')
42+
assert filelink.handle == HANDLE
43+
assert filelink.upload_response == {'url': 'https://cdn.filestackcontent.com/{}'.format(HANDLE), 'handle': HANDLE}
4544

4645

47-
@patch('filestack.uploads.multipart.requests.put')
48-
@patch('filestack.uploads.multipart.requests.post')
49-
def test_upload_file_obj(post_mock, put_mock):
50-
start_response = defaultdict(str)
51-
start_response['location_url'] = 'fs.api'
52-
post_mock.side_effect = [
53-
DummyHttpResponse(json_dict=start_response),
54-
DummyHttpResponse(json_dict=defaultdict(str)),
55-
DummyHttpResponse(json_dict={'handle': 'bytesHandle'})
56-
]
57-
put_mock.return_value = DummyHttpResponse(
58-
json_dict=defaultdict(str), headers={'ETag': 'etag-1'}
59-
)
46+
def test_upload_file_obj(multipart_mock):
6047
file_content = b'file bytes'
6148
filelink = Client(APIKEY).upload(file_obj=io.BytesIO(file_content))
62-
assert filelink.handle == 'bytesHandle'
63-
put_args, put_kwargs = put_mock.call_args
64-
assert put_kwargs['data'] == file_content
49+
assert filelink.handle == HANDLE
50+
assert multipart_mock.calls[2].request.headers['filestack'] == 'header'
51+
assert multipart_mock.calls[2].request.body == file_content
6552

6653

67-
def test_upload_chunk():
68-
@urlmatch(netloc=r'fsuploads\.com', path='/multipart/upload', method='post', scheme='https')
69-
def fs_backend_mock(url, request):
70-
return {
71-
'status_code': 200,
72-
'content': json.dumps({
73-
'url': 'https://amazon.com/upload', 'headers': {'one': 'two'}
74-
})
75-
}
54+
def test_upload_with_workflows(multipart_mock):
55+
workflow_ids = ['workflow-id-1', 'workflow-id-2']
56+
store_params = {'workflows': workflow_ids}
57+
client = Client(APIKEY)
58+
filelink = client.upload(filepath='tests/data/bird.jpg', store_params=store_params)
59+
assert filelink.handle == HANDLE
60+
multipart_complete_payload = json.loads(multipart_mock.calls[3].request.body.decode())
61+
assert multipart_complete_payload['store']['workflows'] == workflow_ids
62+
7663

77-
@urlmatch(netloc=r'amazon\.com', path='/upload', method='put', scheme='https')
78-
def amazon_mock(url, request):
79-
return response(200, b'', {'ETag': 'etagX'}, reason=None, elapsed=0, request=request)
64+
@responses.activate
65+
def test_upload_chunk():
66+
responses.add(
67+
responses.POST, 'https://fsuploads.com/multipart/upload',
68+
status=200, json={'url': 'http://s3-upload.url', 'headers': {}}
69+
)
70+
responses.add(responses.PUT, 'http://s3-upload.url', headers={'ETag': 'etagX'})
8071

8172
chunk = Chunk(num=123, seek_point=0, filepath='tests/data/doom.mp4')
8273
start_response = defaultdict(str)
8374
start_response['location_url'] = 'fsuploads.com'
84-
with HTTMock(fs_backend_mock), HTTMock(amazon_mock):
85-
upload_result = upload_chunk('apikey', 'filename', 's3', start_response, chunk)
86-
assert upload_result == {'part_number': 123, 'etag': 'etagX'}
75+
upload_result = upload_chunk('apikey', 'filename', 's3', start_response, chunk)
76+
assert upload_result == {'part_number': 123, 'etag': 'etagX'}

0 commit comments

Comments
 (0)