|
1 | 1 | import io
|
2 | 2 | import json
|
3 | 3 | from collections import defaultdict
|
4 |
| -from unittest.mock import patch |
5 | 4 |
|
6 | 5 | import responses
|
7 |
| -from httmock import HTTMock, response, urlmatch |
| 6 | +import pytest |
8 | 7 |
|
9 |
| -from tests.helpers import DummyHttpResponse |
10 | 8 | from filestack import Client
|
11 | 9 | from filestack import config
|
12 | 10 | from filestack.uploads.multipart import upload_chunk, Chunk
|
13 | 11 |
|
14 | 12 | APIKEY = 'APIKEY'
|
15 | 13 | HANDLE = 'SOMEHANDLE'
|
16 |
| -URL = 'https://cdn.filestackcontent.com/{}'.format(HANDLE) |
17 | 14 |
|
18 | 15 |
|
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 |
22 | 37 |
|
23 | 38 |
|
24 |
| -@responses.activate |
25 |
| -def test_upload_filepath(): |
| 39 | +def test_upload_filepath(multipart_mock): |
26 | 40 | 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} |
45 | 44 |
|
46 | 45 |
|
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): |
60 | 47 | file_content = b'file bytes'
|
61 | 48 | 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 |
65 | 52 |
|
66 | 53 |
|
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 | + |
76 | 63 |
|
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'}) |
80 | 71 |
|
81 | 72 | chunk = Chunk(num=123, seek_point=0, filepath='tests/data/doom.mp4')
|
82 | 73 | start_response = defaultdict(str)
|
83 | 74 | 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