summaryrefslogtreecommitdiffstats
path: root/test/units/module_utils/urls/test_prepare_multipart.py
blob: 226d9edd024445e0f3d558cedb1eabd690ee3b71 (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
# -*- coding: utf-8 -*-
# (c) 2020 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

import os

from io import StringIO

from email.message import Message

import pytest

from ansible.module_utils.urls import prepare_multipart


def test_prepare_multipart():
    fixture_boundary = b'===============3996062709511591449=='

    here = os.path.dirname(__file__)
    multipart = os.path.join(here, 'fixtures/multipart.txt')

    client_cert = os.path.join(here, 'fixtures/client.pem')
    client_key = os.path.join(here, 'fixtures/client.key')
    client_txt = os.path.join(here, 'fixtures/client.txt')
    fields = {
        'form_field_1': 'form_value_1',
        'form_field_2': {
            'content': 'form_value_2',
        },
        'form_field_3': {
            'content': '<html></html>',
            'mime_type': 'text/html',
        },
        'form_field_4': {
            'content': '{"foo": "bar"}',
            'mime_type': 'application/json',
        },
        'file1': {
            'content': 'file_content_1',
            'filename': 'fake_file1.txt',
        },
        'file2': {
            'content': '<html></html>',
            'mime_type': 'text/html',
            'filename': 'fake_file2.html',
        },
        'file3': {
            'content': '{"foo": "bar"}',
            'mime_type': 'application/json',
            'filename': 'fake_file3.json',
        },
        'file4': {
            'filename': client_cert,
            'mime_type': 'text/plain',
        },
        'file5': {
            'filename': client_key,
            'mime_type': 'application/octet-stream'
        },
        'file6': {
            'filename': client_txt,
        },
    }

    content_type, b_data = prepare_multipart(fields)

    headers = Message()
    headers['Content-Type'] = content_type
    assert headers.get_content_type() == 'multipart/form-data'
    boundary = headers.get_boundary()
    assert boundary is not None

    with open(multipart, 'rb') as f:
        b_expected = f.read().replace(fixture_boundary, boundary.encode())

    # Depending on Python version, there may or may not be a trailing newline
    assert b_data.rstrip(b'\r\n') == b_expected.rstrip(b'\r\n')


def test_wrong_type():
    pytest.raises(TypeError, prepare_multipart, 'foo')
    pytest.raises(TypeError, prepare_multipart, {'foo': None})


def test_empty():
    pytest.raises(ValueError, prepare_multipart, {'foo': {}})


def test_unknown_mime(mocker):
    fields = {'foo': {'filename': 'foo.boom', 'content': 'foo'}}
    mocker.patch('mimetypes.guess_type', return_value=(None, None))
    content_type, b_data = prepare_multipart(fields)
    assert b'Content-Type: application/octet-stream' in b_data


def test_bad_mime(mocker):
    fields = {'foo': {'filename': 'foo.boom', 'content': 'foo'}}
    mocker.patch('mimetypes.guess_type', side_effect=TypeError)
    content_type, b_data = prepare_multipart(fields)
    assert b'Content-Type: application/octet-stream' in b_data