Commit 346cc130 authored by Abhilash Raj's avatar Abhilash Raj
Browse files

Merge branch 'cleanup' into 'master'

Remove old vcr helpers

See merge request !169
parents d4659d1c 490a93d9
Loading
Loading
Loading
Loading
Loading
+0 −109
Original line number Diff line number Diff line
# Copyright (C) 2015-2022 by the Free Software Foundation, Inc.
#
# This file is part of mailmanclient.
#
# GNU Mailman is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# GNU Mailman.  If not, see <http://www.gnu.org/licenses/>.

"""Helpers for VCR"""

import vcr

from functools import update_wrapper
from six import binary_type, text_type
from six.moves.urllib.parse import urlparse, urlunparse, parse_qsl, urlencode


__all__ = [
    'get_vcr',
    ]

# XXX: This module exists to maintain compatibility with some parts of
# Postorius' test suite which use this internal API. This is duplicated in new
# versions of Postorius (for >1.1 releases).


def filter_response_headers(response):
    for header in ('Date', 'Server', 'date', 'server'):
        # The headers are lowercase on Python 2 and capitalized on Python 3
        if header in response['headers']:
            del response['headers'][header]
    return response


def reorder_request_params(request):
    def reorder_params(params):
        parsed = parse_qsl(params)
        if parsed:
            return urlencode(sorted(parsed, key=lambda kv: kv[0]))
        else:
            # Parsing failed, it may be a simple string.
            return params
    # sort the URL query-string by key names.
    uri_parts = urlparse(request.uri)
    if uri_parts.query:
        request.uri = urlunparse((
            uri_parts.scheme, uri_parts.netloc, uri_parts.path,
            uri_parts.params, reorder_params(uri_parts.query),
            uri_parts.fragment,
            ))
    # convert the request body to text and sort the parameters.
    if isinstance(request.body, binary_type):
        try:
            request._body = request._body.decode('utf-8')
        except UnicodeDecodeError:
            pass
    if isinstance(request.body, text_type):
        request._body = reorder_params(request._body.encode('utf-8'))
    return request


def get_vcr(**kwargs):
    return vcr.VCR(
        filter_headers=['authorization', 'user-agent', 'date'],
        before_record=reorder_request_params,
        before_record_response=filter_response_headers,
        **kwargs
        )


class vcr_testcase:
    """
    Decorator for TestCases that use VCR.
    It automatically sets up a different cassette for each test function.
    """

    def __init__(self, vcr_instance):
        self.vcr = vcr_instance

    def __call__(self, testcase):
        return self.decorate_class(testcase)

    def decorate_class(self, testcase):
        """Create a subclass that will add setUp instructions."""
        vcr_instance = self.vcr

        class VCRTestCase(testcase):
            vcr = vcr_instance

            def setUp(self):
                cm = self.vcr.use_cassette('.'.join([
                    # testcase.__module__.rpartition('.')[2],
                    testcase.__name__, self._testMethodName, 'yaml']))
                self.cassette = cm.__enter__()
                self.addCleanup(cm.__exit__, None, None, None)
                super(VCRTestCase, self).setUp()

        return update_wrapper(
            VCRTestCase, testcase,
            assigned=('__module__', '__name__'), updated=[])