deb-python-gabbi/gabbi/tests/test_utils.py
Chris Dent 4b82d0ddc7 Clean up content-type parsing
Some of the places in which not_binary was being called were
not guarded in a way that made sure that the content-type being
sent to not_binary was just a media-type (without charset etc).

A parse_content_type method was extracted from the
extract_content_type method so that both a headers dict or a simple
header value could be parsed.

This seemed more generic and contractual than making not_binary
extract if required.

Fixes #158
2016-07-03 14:11:12 -04:00

285 lines
10 KiB
Python

#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Test functions from the utils module.
"""
import unittest
from gabbi import utils
class BinaryTypesTest(unittest.TestCase):
BINARY_TYPES = [
'image/png',
'application/binary',
]
NON_BINARY_TYPES = [
'text/plain',
'application/atom+xml',
'application/vnd.custom+json',
'application/javascript',
'application/json',
'application/json-home',
]
def test_not_binary(self):
for media_type in self.NON_BINARY_TYPES:
self.assertTrue(utils.not_binary(media_type),
'%s should not be binary' % media_type)
def test_binary(self):
for media_type in self.BINARY_TYPES:
self.assertFalse(utils.not_binary(media_type),
'%s should be binary' % media_type)
class ParseContentTypeTest(unittest.TestCase):
def test_parse_simple(self):
self.assertEqual(
('text/plain', 'latin-1'),
utils.parse_content_type('text/plain; charset=latin-1'))
def test_parse_extra(self):
self.assertEqual(
('text/plain', 'latin-1'),
utils.parse_content_type(
'text/plain; charset=latin-1; version=1.2'))
def test_parse_default(self):
self.assertEqual(
('text/plain', 'utf-8'),
utils.parse_content_type('text/plain'))
def test_parse_error_default(self):
self.assertEqual(
('text/plain', 'utf-8'),
utils.parse_content_type(
'text/plain; face=ouch; charset=latin-1;'))
def test_parse_nocharset_default(self):
self.assertEqual(
('text/plain', 'utf-8'),
utils.parse_content_type(
'text/plain; face=ouch'))
def test_parse_override_default(self):
self.assertEqual(
('text/plain', 'latin-1'),
utils.parse_content_type(
'text/plain; face=ouch', default_charset='latin-1'))
class ExtractContentTypeTest(unittest.TestCase):
def test_extract_content_type_default_both(self):
"""Empty dicts returns default type and chartset."""
content_type, charset = utils.extract_content_type({})
self.assertEqual('application/binary', content_type)
self.assertEqual('utf-8', charset)
def test_extract_content_type_default_charset(self):
"""Empty dicts returns default type and chartset."""
content_type, charset = utils.extract_content_type({
'content-type': 'text/colorful'})
self.assertEqual('text/colorful', content_type)
self.assertEqual('utf-8', charset)
def test_extract_content_type_with_charset(self):
content_type, charset = utils.extract_content_type(
{'content-type': 'text/colorful; charset=latin-10'})
self.assertEqual('text/colorful', content_type)
self.assertEqual('latin-10', charset)
def test_extract_content_type_multiple_params(self):
content_type, charset = utils.extract_content_type(
{'content-type': 'text/colorful; version=1.24; charset=latin-10'})
self.assertEqual('text/colorful', content_type)
self.assertEqual('latin-10', charset)
def test_extract_content_type_bad_params(self):
content_type, charset = utils.extract_content_type(
{'content-type': 'text/colorful; version=1.24; charset=latin-10;'})
self.assertEqual('text/colorful', content_type)
self.assertEqual('utf-8', charset)
class ColorizeTest(unittest.TestCase):
def test_colorize_missing_color(self):
"""Make sure that choosing a non-existent color is safe."""
message = utils._colorize('CERULEAN', 'hello')
self.assertEqual('hello', message)
message = utils._colorize('BLUE', 'hello')
self.assertNotEqual('hello', message)
class CreateURLTest(unittest.TestCase):
def test_create_url_simple(self):
url = utils.create_url('/foo/bar', 'test.host.com')
self.assertEqual('http://test.host.com/foo/bar', url)
def test_create_url_ssl(self):
url = utils.create_url('/foo/bar', 'test.host.com', ssl=True)
self.assertEqual('https://test.host.com/foo/bar', url)
def test_create_url_prefix(self):
url = utils.create_url('/foo/bar', 'test.host.com', prefix='/zoom')
self.assertEqual('http://test.host.com/zoom/foo/bar', url)
def test_create_url_port(self):
url = utils.create_url('/foo/bar', 'test.host.com', port=8000)
self.assertEqual('http://test.host.com:8000/foo/bar', url)
def test_create_url_port_and_ssl(self):
url = utils.create_url('/foo/bar', 'test.host.com', ssl=True,
port=8000)
self.assertEqual('https://test.host.com:8000/foo/bar', url)
def test_create_url_not_ssl_on_443(self):
url = utils.create_url('/foo/bar', 'test.host.com', ssl=False,
port=443)
self.assertEqual('http://test.host.com:443/foo/bar', url)
def test_create_url_ssl_on_80(self):
url = utils.create_url('/foo/bar', 'test.host.com', ssl=True,
port=80)
self.assertEqual('https://test.host.com:80/foo/bar', url)
def test_create_url_preserve_query(self):
url = utils.create_url('/foo/bar?x=1&y=2', 'test.host.com', ssl=True,
port=80)
self.assertEqual('https://test.host.com:80/foo/bar?x=1&y=2', url)
def test_create_url_ipv6_ssl(self):
url = utils.create_url('/foo/bar?x=1&y=2', '::1', ssl=True)
self.assertEqual('https://[::1]/foo/bar?x=1&y=2', url)
def test_create_url_ipv6_ssl_weird_port(self):
url = utils.create_url('/foo/bar?x=1&y=2', '::1', ssl=True, port=80)
self.assertEqual('https://[::1]:80/foo/bar?x=1&y=2', url)
def test_create_url_ipv6_full(self):
url = utils.create_url('/foo/bar?x=1&y=2',
'2607:f8b0:4000:801::200e', port=8080)
self.assertEqual(
'http://[2607:f8b0:4000:801::200e]:8080/foo/bar?x=1&y=2', url)
def test_create_url_ipv6_already_bracket(self):
url = utils.create_url(
'/foo/bar?x=1&y=2', '[2607:f8b0:4000:801::200e]', port=999)
self.assertEqual(
'http://[2607:f8b0:4000:801::200e]:999/foo/bar?x=1&y=2', url)
def test_create_url_no_double_colon(self):
url = utils.create_url(
'/foo', 'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210', port=999)
self.assertEqual(
'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:999/foo', url)
class UtilsHostInfoFromTarget(unittest.TestCase):
def _test_hostport(self, url_or_host, expected_host,
provided_prefix=None, expected_port=None,
expected_prefix=None, expected_ssl=False):
host, port, prefix, ssl = utils.host_info_from_target(
url_or_host, provided_prefix)
# normalize hosts, they are case insensitive
self.assertEqual(expected_host.lower(), host.lower())
# port can be a string or int depending on the inputs
self.assertEqual(expected_port, port)
self.assertEqual(expected_prefix, prefix)
self.assertEqual(expected_ssl, ssl)
def test_plain_url_no_port(self):
self._test_hostport('http://foobar.com/news',
'foobar.com',
expected_port=None,
expected_prefix='/news')
def test_plain_url_with_port(self):
self._test_hostport('http://foobar.com:80/news',
'foobar.com',
expected_port=80,
expected_prefix='/news')
def test_ssl_url(self):
self._test_hostport('https://foobar.com/news',
'foobar.com',
expected_prefix='/news',
expected_ssl=True)
def test_ssl_port80_url(self):
self._test_hostport('https://foobar.com:80/news',
'foobar.com',
expected_prefix='/news',
expected_port=80,
expected_ssl=True)
def test_ssl_port_url(self):
self._test_hostport('https://foobar.com:999/news',
'foobar.com',
expected_prefix='/news',
expected_port=999,
expected_ssl=True)
def test_simple_hostport(self):
self._test_hostport('foobar.com:999',
'foobar.com',
expected_port='999')
def test_simple_hostport_with_prefix(self):
self._test_hostport('foobar.com:999',
'foobar.com',
provided_prefix='/news',
expected_port='999',
expected_prefix='/news')
def test_ipv6_url_long(self):
self._test_hostport(
'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:999/news',
'FEDC:BA98:7654:3210:FEDC:BA98:7654:3210',
expected_port=999,
expected_prefix='/news')
def test_ipv6_url_localhost(self):
self._test_hostport(
'http://[::1]:999/news',
'::1',
expected_port=999,
expected_prefix='/news')
def test_ipv6_host_localhost(self):
# If a user wants to use the hostport form, then they need
# to hack it with the brackets.
self._test_hostport(
'[::1]',
'::1')
def test_ipv6_hostport_localhost(self):
self._test_hostport(
'[::1]:999',
'::1',
expected_port='999')