dave-shawley/ietfparse

View on GitHub
tests/test_headers_parse_accept.py

Summary

Maintainability
A
0 mins
Test Coverage
import unittest

from ietfparse import datastructures, headers


class ParseAcceptHeaderTests(unittest.TestCase):

    # First example from https://tools.ietf.org/html/rfc7231#section-5.3.2

    def test_that_all_items_are_returned(self):
        parsed = headers.parse_accept('audio/*;q=0.2,audio/basic,'
                                      'audio/aiff;q=0')
        self.assertEqual(len(parsed), 3)

    def test_that_highest_priority_is_first(self):
        parsed = headers.parse_accept('audio/*;q=0.2,audio/basic,'
                                      'audio/aiff;q=0')
        self.assertEqual(parsed[0],
                         datastructures.ContentType('audio', 'basic'))

    def test_that_quality_parameter_is_removed(self):
        parsed = headers.parse_accept('audio/*;q=0.2,audio/basic,'
                                      'audio/aiff;q=0')
        for value in parsed:
            self.assertNotIn('q', value.parameters)

    # Final example in https://tools.ietf.org/html/rfc7231#section-5.3.2

    def test_that_most_specific_value_is_first(self):
        parsed = headers.parse_accept('text/*, text/plain,'
                                      'text/plain;format=flowed, */*')
        self.assertEqual(
            parsed[0],
            datastructures.ContentType('text', 'plain', {'format': 'flowed'}))

    def test_that_specific_value_without_parameters_is_second(self):
        parsed = headers.parse_accept('text/*, text/plain,'
                                      'text/plain;format=flowed, */*')
        self.assertEqual(parsed[1],
                         datastructures.ContentType('text', 'plain'))

    def test_that_subtype_wildcard_is_next_to_last(self):
        parsed = headers.parse_accept('text/*, text/plain,'
                                      'text/plain;format=flowed, */*')
        self.assertEqual(parsed[2], datastructures.ContentType('text', '*'))

    def test_that_least_specific_wildcard_is_least_preferred(self):
        parsed = headers.parse_accept('text/*, text/plain,'
                                      'text/plain;format=flowed, */*')
        self.assertEqual(parsed[3], datastructures.ContentType('*', '*'))

    def test_that_extension_tokens_are_parsed(self):
        self.assertEqual(
            headers.parse_accept('application/json;charset="utf-8"'), [
                datastructures.ContentType('application', 'json',
                                           {'charset': 'utf-8'})
            ])

    def test_that_extension_tokens_with_spaces_are_parsed(self):
        self.assertEqual(
            headers.parse_accept('application/json;x-foo=" something else"'), [
                datastructures.ContentType('application', 'json',
                                           {'x-foo': ' something else'})
            ])

    def test_that_invalid_parts_are_skipped(self):
        parsed = headers.parse_accept('text/html, image/gif, image/jpeg, '
                                      '*; q=.2, */*; q=.2')
        self.assertEqual(len(parsed), 4)
        self.assertEqual(parsed[0], datastructures.ContentType('text', 'html'))
        self.assertEqual(parsed[1],
                         datastructures.ContentType('image', 'jpeg'))
        self.assertEqual(parsed[2], datastructures.ContentType('image', 'gif'))
        self.assertEqual(parsed[3], datastructures.ContentType('*', '*'))

    def test_that_invalid_parts_raise_error_when_strict_is_enabled(self):
        with self.assertRaises(ValueError):
            headers.parse_accept(
                'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2',
                strict=True)

    def test_the_invalid_header_returns_empty_list(self):
        parsed = headers.parse_accept('*')
        self.assertEqual(len(parsed), 0)


class ParseAcceptCharsetHeaderTests(unittest.TestCase):

    # Final example in https://tools.ietf.org/html/rfc7231#section-5.3.3

    def test_that_simple_wildcard_parses(self):
        self.assertEqual(headers.parse_accept_charset('*'), ['*'])

    def test_that_response_sorted_by_quality(self):
        self.assertEqual(
            headers.parse_accept_charset('us-ascii;q=0.1, latin1;q=0.5,'
                                         'utf-8; q=1.0'),
            ['utf-8', 'latin1', 'us-ascii'],
        )

    def test_that_unspecified_quality_is_treated_as_highest(self):
        self.assertEqual(
            headers.parse_accept_charset('us-ascii;q=0.1,utf-8,latin1;q=0.8'),
            ['utf-8', 'latin1', 'us-ascii'],
        )

    def test_that_wildcard_sorts_before_rejected_character_sets(self):
        self.assertEqual(
            headers.parse_accept_charset('latin1;q=0.5, utf-8;q=1.0,'
                                         'us-ascii;q=0.1, ebcdic;q=0, *'),
            ['utf-8', 'latin1', 'us-ascii', '*', 'ebcdic'],
        )

    def test_that_quality_below_0_001_is_rejected(self):
        self.assertEqual(
            headers.parse_accept_charset('acceptable, rejected;q=0.0009, *'),
            ['acceptable', '*', 'rejected'],
        )


class ParseAcceptEncodingTests(unittest.TestCase):

    # Final example in https://tools.ietf.org/html/rfc7231#section-5.3.4

    def test_that_simple_wildcard_parses(self):
        self.assertEqual(headers.parse_accept_encoding('*'), ['*'])

    def test_that_response_sorted_by_quality(self):
        self.assertEqual(
            headers.parse_accept_encoding('compress, gzip;q=0.8, bzip;q=0.7'),
            ['compress', 'gzip', 'bzip'])

    def test_that_unspecified_quality_is_treated_as_highest(self):
        self.assertEqual(
            headers.parse_accept_encoding('snappy;q=0.1,gzip,bzip;q=0.8'),
            ['gzip', 'bzip', 'snappy'])

    def test_that_wildcard_sorts_before_rejected_character_sets(self):
        self.assertEqual(
            headers.parse_accept_encoding('gzip;q=0.5, compress;q=1.0,'
                                          'bzip;q=0.1, snappy;q=0, *'),
            ['compress', 'gzip', 'bzip', '*', 'snappy'])

    def test_that_quality_below_0_001_is_rejected(self):
        self.assertEqual(
            headers.parse_accept_encoding('bzip, gzip;q=0.0009, *'),
            ['bzip', '*', 'gzip'])


class ParseAcceptLanguageTests(unittest.TestCase):

    # Final example in https://tools.ietf.org/html/rfc7231#section-5.3.5

    def test_that_simple_wildcard_parses(self):
        self.assertEqual(headers.parse_accept_language('*'), ['*'])

    def test_that_response_sorted_by_quality(self):
        self.assertEqual(
            headers.parse_accept_language('de, en-gb;q=0.8, en;q=0.7'),
            ['de', 'en-gb', 'en'])

    def test_that_unspecified_quality_is_treated_as_highest(self):
        self.assertEqual(
            headers.parse_accept_language('en-gb;q=0.1,de,en;q=0.8'),
            ['de', 'en', 'en-gb'])

    def test_that_wildcard_sorts_before_rejected_character_sets(self):
        self.assertEqual(
            headers.parse_accept_language('es;q=0.5, es-mx;q=1.0,'
                                          'es-es;q=0.1, es-pr;q=0, *'),
            ['es-mx', 'es', 'es-es', '*', 'es-pr'])

    def test_that_quality_below_0_001_is_rejected(self):
        self.assertEqual(headers.parse_accept_language('aa, bb;q=0.0009, *'),
                         ['aa', '*', 'bb'])

    def test_that_order_is_retained_without_quality(self):
        self.assertEqual(
            headers.parse_accept_language('de-Latn-DE,de-Latf-DE,'
                                          'de-Latn-DE-1996'),
            ['de-Latn-DE', 'de-Latf-DE', 'de-Latn-DE-1996'],
        )

    def test_that_explicit_highest_quality_is_first(self):
        self.assertEqual(
            headers.parse_accept_language('de-Latn-DE,de-Latf-DE,'
                                          'de-Latn-DE-1996;q=1.0'),
            ['de-Latn-DE-1996', 'de-Latn-DE', 'de-Latf-DE'],
        )

    def test_that_order_is_retained_for_explicit_highest_quality(self):
        self.assertEqual(
            headers.parse_accept_language('de-Latn-DE,de-Latf-DE;q=1.0,'
                                          'de-Latn-DE-1996;q=1.0'),
            ['de-Latf-DE', 'de-Latn-DE-1996', 'de-Latn-DE'],
        )