httpie-cli/tests/test_downloads.py

140 lines
4.6 KiB
Python
Raw Normal View History

2014-04-24 14:07:31 +02:00
import os
import time
from unittest import TestCase
2014-04-24 14:07:31 +02:00
2014-04-24 17:08:40 +02:00
import pytest
2014-04-24 15:48:01 +02:00
from requests.structures import CaseInsensitiveDict
2014-04-24 14:07:31 +02:00
from httpie.compat import urlopen
from httpie.downloads import (
2014-04-24 18:20:23 +02:00
parse_content_range, filename_from_content_disposition, filename_from_url,
get_unique_filename, ContentRangeError, Download,
2014-04-24 14:07:31 +02:00
)
2014-04-24 15:48:01 +02:00
from tests import httpbin, http, TestEnvironment
2014-04-24 14:07:31 +02:00
2014-04-24 15:48:01 +02:00
class Response(object):
# noinspection PyDefaultArgument
def __init__(self, url, headers={}, status_code=200):
self.url = url
self.headers = CaseInsensitiveDict(headers)
self.status_code = status_code
2014-04-24 14:07:31 +02:00
2014-04-24 15:48:01 +02:00
class DownloadUtilsTest(TestCase):
def test_Content_Range_parsing(self):
2014-04-24 14:07:31 +02:00
parse = parse_content_range
assert parse('bytes 100-199/200', 100) == 200
assert parse('bytes 100-199/*', 100) == 200
2014-04-24 14:07:31 +02:00
# missing
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, None, 100)
2014-04-24 14:07:31 +02:00
# syntax error
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, 'beers 100-199/*', 100)
2014-04-24 14:07:31 +02:00
# unexpected range
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, 'bytes 100-199/*', 99)
2014-04-24 14:07:31 +02:00
# invalid instance-length
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, 'bytes 100-199/199', 100)
2014-04-24 14:07:31 +02:00
# invalid byte-range-resp-spec
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, 'bytes 100-99/199', 100)
2014-04-24 14:07:31 +02:00
# invalid byte-range-resp-spec
2014-04-24 17:08:40 +02:00
pytest.raises(ContentRangeError, parse, 'bytes 100-100/*', 100)
2014-04-24 14:07:31 +02:00
def test_Content_Disposition_parsing(self):
parse = filename_from_content_disposition
assert 'hello-WORLD_123.txt' == parse(
'attachment; filename=hello-WORLD_123.txt')
assert 'hello-WORLD_123.txt' == parse(
'attachment; filename=".hello-WORLD_123.txt"')
assert 'white space.txt' == parse(
'attachment; filename="white space.txt"')
assert '"quotes".txt' == parse(
r'attachment; filename="\"quotes\".txt"')
assert parse('attachment; filename=/etc/hosts') == 'hosts'
assert parse('attachment; filename=') is None
2014-04-24 14:07:31 +02:00
def test_filename_from_url(self):
assert 'foo.txt' == filename_from_url(
2014-04-24 14:07:31 +02:00
url='http://example.org/foo',
content_type='text/plain'
)
assert 'foo.html' == filename_from_url(
2014-04-24 14:07:31 +02:00
url='http://example.org/foo',
content_type='text/html; charset=utf8'
)
assert 'foo' == filename_from_url(
2014-04-24 14:07:31 +02:00
url='http://example.org/foo',
content_type=None
)
assert 'foo' == filename_from_url(
2014-04-24 14:07:31 +02:00
url='http://example.org/foo',
content_type='x-foo/bar'
)
2014-04-24 14:07:31 +02:00
def test_unique_filename(self):
2014-04-24 15:48:01 +02:00
def attempts(unique_on_attempt=0):
2014-04-24 14:07:31 +02:00
# noinspection PyUnresolvedReferences,PyUnusedLocal
def exists(filename):
if exists.attempt == unique_on_attempt:
return False
exists.attempt += 1
return True
2014-04-24 15:48:01 +02:00
2014-04-24 14:07:31 +02:00
exists.attempt = 0
return exists
2014-04-24 15:48:01 +02:00
assert 'foo.bar' == get_unique_filename('foo.bar', attempts(0))
assert 'foo.bar-1' == get_unique_filename('foo.bar', attempts(1))
assert 'foo.bar-10' == get_unique_filename('foo.bar', attempts(10))
2014-04-24 14:07:31 +02:00
class DownloadsTest(TestCase):
2014-04-24 14:07:31 +02:00
# TODO: more tests
def test_actual_download(self):
url = httpbin('/robots.txt')
body = urlopen(url).read().decode()
2014-04-24 15:48:01 +02:00
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
r = http('--download', url, env=env)
assert 'Downloading' in r.stderr
assert '[K' in r.stderr
assert 'Done' in r.stderr
assert body == r
2014-04-24 14:07:31 +02:00
def test_download_with_Content_Length(self):
download = Download(output_file=open(os.devnull, 'w'))
download.start(Response(
url=httpbin('/'),
2014-04-24 15:48:01 +02:00
headers={'Content-Length': 10}
2014-04-24 14:07:31 +02:00
))
time.sleep(1.1)
download.chunk_downloaded(b'12345')
time.sleep(1.1)
download.chunk_downloaded(b'12345')
download.finish()
assert not download.interrupted
2014-04-24 14:07:31 +02:00
def test_download_no_Content_Length(self):
download = Download(output_file=open(os.devnull, 'w'))
download.start(Response(url=httpbin('/')))
time.sleep(1.1)
download.chunk_downloaded(b'12345')
download.finish()
assert not download.interrupted
2014-04-24 14:07:31 +02:00
def test_download_interrupted(self):
download = Download(output_file=open(os.devnull, 'w'))
download.start(Response(
url=httpbin('/'),
headers={'Content-Length': 5}
))
download.chunk_downloaded(b'1234')
download.finish()
assert download.interrupted