summaryrefslogtreecommitdiffstats
path: root/test/units/module_utils/urls/test_RedirectHandlerFactory.py
blob: 7bbe4b5b3343df627a15fc7a902e209795fd9a11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# -*- coding: utf-8 -*-
# (c) 2018 Matt Martz <matt@sivel.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


from ansible.module_utils.urls import HAS_SSLCONTEXT, RedirectHandlerFactory, urllib_request, urllib_error
from ansible.module_utils.six import StringIO

import pytest


@pytest.fixture
def urllib_req():
    req = urllib_request.Request(
        'https://ansible.com/'
    )
    return req


@pytest.fixture
def request_body():
    return StringIO('TESTS')


def test_no_redirs(urllib_req, request_body):
    handler = RedirectHandlerFactory('none', False)
    inst = handler()
    with pytest.raises(urllib_error.HTTPError):
        inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')


def test_urllib2_redir(urllib_req, request_body, mocker):
    redir_request_mock = mocker.patch('ansible.module_utils.urls.urllib_request.HTTPRedirectHandler.redirect_request')

    handler = RedirectHandlerFactory('urllib2', False)
    inst = handler()
    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')

    redir_request_mock.assert_called_once_with(inst, urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')


def test_all_redir(urllib_req, request_body, mocker):
    req_mock = mocker.patch('ansible.module_utils.urls.RequestWithMethod')
    handler = RedirectHandlerFactory('all', False)
    inst = handler()
    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')
    req_mock.assert_called_once_with('https://docs.ansible.com/', data=None, headers={}, method='GET', origin_req_host='ansible.com', unverifiable=True)


def test_all_redir_post(request_body, mocker):
    handler = RedirectHandlerFactory('all', False)
    inst = handler()

    req = urllib_request.Request(
        'https://ansible.com/',
        'POST'
    )

    req_mock = mocker.patch('ansible.module_utils.urls.RequestWithMethod')
    inst.redirect_request(req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')
    req_mock.assert_called_once_with('https://docs.ansible.com/', data=None, headers={}, method='GET', origin_req_host='ansible.com', unverifiable=True)


def test_redir_headers_removal(urllib_req, request_body, mocker):
    req_mock = mocker.patch('ansible.module_utils.urls.RequestWithMethod')
    handler = RedirectHandlerFactory('all', False)
    inst = handler()

    urllib_req.headers = {
        'Content-Type': 'application/json',
        'Content-Length': 100,
        'Foo': 'bar',
    }

    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')
    req_mock.assert_called_once_with('https://docs.ansible.com/', data=None, headers={'Foo': 'bar'}, method='GET', origin_req_host='ansible.com',
                                     unverifiable=True)


def test_redir_url_spaces(urllib_req, request_body, mocker):
    req_mock = mocker.patch('ansible.module_utils.urls.RequestWithMethod')
    handler = RedirectHandlerFactory('all', False)
    inst = handler()

    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/foo bar')

    req_mock.assert_called_once_with('https://docs.ansible.com/foo%20bar', data=None, headers={}, method='GET', origin_req_host='ansible.com',
                                     unverifiable=True)


def test_redir_safe(urllib_req, request_body, mocker):
    req_mock = mocker.patch('ansible.module_utils.urls.RequestWithMethod')
    handler = RedirectHandlerFactory('safe', False)
    inst = handler()
    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')

    req_mock.assert_called_once_with('https://docs.ansible.com/', data=None, headers={}, method='GET', origin_req_host='ansible.com', unverifiable=True)


def test_redir_safe_not_safe(request_body):
    handler = RedirectHandlerFactory('safe', False)
    inst = handler()

    req = urllib_request.Request(
        'https://ansible.com/',
        'POST'
    )

    with pytest.raises(urllib_error.HTTPError):
        inst.redirect_request(req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')


def test_redir_no_error_on_invalid(urllib_req, request_body):
    handler = RedirectHandlerFactory('invalid', False)
    inst = handler()

    with pytest.raises(urllib_error.HTTPError):
        inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')


def test_redir_validate_certs(urllib_req, request_body, mocker):
    opener_mock = mocker.patch('ansible.module_utils.urls.urllib_request._opener')
    handler = RedirectHandlerFactory('all', True)
    inst = handler()
    inst.redirect_request(urllib_req, request_body, 301, '301 Moved Permanently', {}, 'https://docs.ansible.com/')

    assert opener_mock.add_handler.call_count == int(not HAS_SSLCONTEXT)


def test_redir_http_error_308_urllib2(urllib_req, request_body, mocker):
    redir_mock = mocker.patch.object(urllib_request.HTTPRedirectHandler, 'redirect_request')
    handler = RedirectHandlerFactory('urllib2', False)
    inst = handler()

    inst.redirect_request(urllib_req, request_body, 308, '308 Permanent Redirect', {}, 'https://docs.ansible.com/')

    assert redir_mock.call_count == 1