python-telegram-bot/tests/test_requestdata.py

232 lines
8.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2022
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 Lesser Public License for more details.
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
from urllib.parse import quote
try:
import ujson as json
except ImportError:
import json
from typing import Any, Dict
import pytest
from telegram import InputFile, MessageEntity, InputMediaPhoto, InputMediaVideo
from telegram.request import RequestData
from telegram.request._requestparameter import RequestParameter
from tests.conftest import data_file
@pytest.fixture(scope='module')
def inputfiles() -> Dict[bool, InputFile]:
return {True: InputFile(obj='data', attach=True), False: InputFile(obj='data', attach=False)}
@pytest.fixture(scope='module')
def input_media_video() -> InputMediaVideo:
return InputMediaVideo(
media=data_file('telegram.mp4').read_bytes(),
thumb=data_file('telegram.jpg').read_bytes(),
parse_mode=None,
)
@pytest.fixture(scope='module')
def input_media_photo() -> InputMediaPhoto:
return InputMediaPhoto(
media=data_file('telegram.jpg').read_bytes(),
parse_mode=None,
)
@pytest.fixture(scope='module')
def simple_params() -> Dict[str, Any]:
return {
'string': 'string',
'integer': 1,
'tg_object': MessageEntity('type', 1, 1),
'list': [1, 'string', MessageEntity('type', 1, 1)],
}
@pytest.fixture(scope='module')
def simple_jsons() -> Dict[str, Any]:
return {
'string': 'string',
'integer': json.dumps(1),
'tg_object': MessageEntity('type', 1, 1).to_json(),
'list': json.dumps([1, 'string', MessageEntity('type', 1, 1).to_dict()]),
}
@pytest.fixture(scope='module')
def simple_rqs(simple_params) -> RequestData:
return RequestData(
[RequestParameter.from_input(key, value) for key, value in simple_params.items()]
)
@pytest.fixture(scope='module')
def file_params(inputfiles, input_media_video, input_media_photo) -> Dict[str, Any]:
return {
'inputfile_attach': inputfiles[True],
'inputfile_no_attach': inputfiles[False],
'inputmedia': input_media_video,
'inputmedia_list': [input_media_video, input_media_photo],
}
@pytest.fixture(scope='module')
def file_jsons(inputfiles, input_media_video, input_media_photo) -> Dict[str, Any]:
input_media_video_dict = input_media_video.to_dict()
input_media_video_dict['media'] = input_media_video.media.attach_uri
input_media_video_dict['thumb'] = input_media_video.thumb.attach_uri
input_media_photo_dict = input_media_photo.to_dict()
input_media_photo_dict['media'] = input_media_photo.media.attach_uri
return {
'inputfile_attach': inputfiles[True].attach_uri,
'inputmedia': json.dumps(input_media_video_dict),
'inputmedia_list': json.dumps([input_media_video_dict, input_media_photo_dict]),
}
@pytest.fixture(scope='module')
def file_rqs(file_params) -> RequestData:
return RequestData(
[RequestParameter.from_input(key, value) for key, value in file_params.items()]
)
@pytest.fixture()
def mixed_params(file_params, simple_params) -> Dict[str, Any]:
both = file_params.copy()
both.update(simple_params)
return both
@pytest.fixture()
def mixed_jsons(file_jsons, simple_jsons) -> Dict[str, Any]:
both = file_jsons.copy()
both.update(simple_jsons)
return both
@pytest.fixture()
def mixed_rqs(mixed_params) -> RequestData:
return RequestData(
[RequestParameter.from_input(key, value) for key, value in mixed_params.items()]
)
class TestRequestData:
def test_slot_behaviour(self, simple_rqs, mro_slots):
for attr in simple_rqs.__slots__:
assert getattr(simple_rqs, attr, 'err') != 'err', f"got extra slot '{attr}'"
assert len(mro_slots(simple_rqs)) == len(set(mro_slots(simple_rqs))), "duplicate slot"
def test_contains_files(self, simple_rqs, file_rqs, mixed_rqs):
assert not simple_rqs.contains_files
assert file_rqs.contains_files
assert mixed_rqs.contains_files
def test_parameters(
self, simple_rqs, file_rqs, mixed_rqs, inputfiles, input_media_video, input_media_photo
):
simple_params_expected = {
'string': 'string',
'integer': 1,
'tg_object': MessageEntity('type', 1, 1).to_dict(),
'list': [1, 'string', MessageEntity('type', 1, 1).to_dict()],
}
video_value = {
'media': input_media_video.media.attach_uri,
'thumb': input_media_video.thumb.attach_uri,
'type': input_media_video.type,
}
photo_value = {'media': input_media_photo.media.attach_uri, 'type': input_media_photo.type}
file_params_expected = {
'inputfile_attach': inputfiles[True].attach_uri,
'inputmedia': video_value,
'inputmedia_list': [video_value, photo_value],
}
mixed_params_expected = simple_params_expected.copy()
mixed_params_expected.update(file_params_expected)
assert simple_rqs.parameters == simple_params_expected
assert file_rqs.parameters == file_params_expected
assert mixed_rqs.parameters == mixed_params_expected
def test_json_parameters(
self, simple_rqs, file_rqs, mixed_rqs, simple_jsons, file_jsons, mixed_jsons
):
assert simple_rqs.json_parameters == simple_jsons
assert file_rqs.json_parameters == file_jsons
assert mixed_rqs.json_parameters == mixed_jsons
def test_json_payload(
self, simple_rqs, file_rqs, mixed_rqs, simple_jsons, file_jsons, mixed_jsons
):
assert simple_rqs.json_payload == json.dumps(simple_jsons).encode()
assert file_rqs.json_payload == json.dumps(file_jsons).encode()
assert mixed_rqs.json_payload == json.dumps(mixed_jsons).encode()
def test_multipart_data(
self,
simple_rqs,
file_rqs,
mixed_rqs,
inputfiles,
input_media_video,
input_media_photo,
):
expected = {
inputfiles[True].attach_name: inputfiles[True].field_tuple,
'inputfile_no_attach': inputfiles[False].field_tuple,
input_media_photo.media.attach_name: input_media_photo.media.field_tuple,
input_media_video.media.attach_name: input_media_video.media.field_tuple,
input_media_video.thumb.attach_name: input_media_video.thumb.field_tuple,
}
assert simple_rqs.multipart_data == {}
assert file_rqs.multipart_data == expected
assert mixed_rqs.multipart_data == expected
def test_url_encoding(self, monkeypatch):
data = RequestData(
[
RequestParameter.from_input('chat_id', 123),
RequestParameter.from_input('text', 'Hello there/!'),
]
)
expected_params = 'chat_id=123&text=Hello+there%2F%21'
expected_url = 'https://te.st/method?' + expected_params
assert data.url_encoded_parameters() == expected_params
assert data.parametrized_url('https://te.st/method') == expected_url
expected_params = 'chat_id=123&text=Hello%20there/!'
expected_url = 'https://te.st/method?' + expected_params
assert (
data.url_encoded_parameters(encode_kwargs={'quote_via': quote, 'safe': '/!'})
== expected_params
)
assert (
data.parametrized_url(
'https://te.st/method', encode_kwargs={'quote_via': quote, 'safe': '/!'}
)
== expected_url
)