python-telegram-bot/tests/test_gifts.py

267 lines
8.8 KiB
Python

#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2024
# 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 collections.abc import Sequence
import pytest
from telegram import BotCommand, Gift, Gifts, MessageEntity, Sticker
from telegram._utils.defaultvalue import DEFAULT_NONE
from telegram.request import RequestData
from tests.auxil.slots import mro_slots
@pytest.fixture
def gift(request):
return Gift(
id=GiftTestBase.id,
sticker=GiftTestBase.sticker,
star_count=GiftTestBase.star_count,
total_count=GiftTestBase.total_count,
remaining_count=GiftTestBase.remaining_count,
)
class GiftTestBase:
id = "some_id"
sticker = Sticker(
file_id="file_id",
file_unique_id="file_unique_id",
width=512,
height=512,
is_animated=False,
is_video=False,
type="regular",
)
star_count = 5
total_count = 10
remaining_count = 5
class TestGiftWithoutRequest(GiftTestBase):
def test_slot_behaviour(self, gift):
for attr in gift.__slots__:
assert getattr(gift, attr, "err") != "err", f"got extra slot '{attr}'"
assert len(mro_slots(gift)) == len(set(mro_slots(gift))), "duplicate slot"
def test_de_json(self, offline_bot, gift):
json_dict = {
"id": self.id,
"sticker": self.sticker.to_dict(),
"star_count": self.star_count,
"total_count": self.total_count,
"remaining_count": self.remaining_count,
}
gift = Gift.de_json(json_dict, offline_bot)
assert gift.api_kwargs == {}
assert gift.id == self.id
assert gift.sticker == self.sticker
assert gift.star_count == self.star_count
assert gift.total_count == self.total_count
assert gift.remaining_count == self.remaining_count
assert Gift.de_json(None, offline_bot) is None
def test_to_dict(self, gift):
gift_dict = gift.to_dict()
assert isinstance(gift_dict, dict)
assert gift_dict["id"] == self.id
assert gift_dict["sticker"] == self.sticker.to_dict()
assert gift_dict["star_count"] == self.star_count
assert gift_dict["total_count"] == self.total_count
assert gift_dict["remaining_count"] == self.remaining_count
def test_equality(self, gift):
a = gift
b = Gift(self.id, self.sticker, self.star_count, self.total_count, self.remaining_count)
c = Gift(
"other_uid", self.sticker, self.star_count, self.total_count, self.remaining_count
)
d = BotCommand("start", "description")
assert a == b
assert hash(a) == hash(b)
assert a != c
assert hash(a) != hash(c)
assert a != d
assert hash(a) != hash(d)
@pytest.mark.parametrize(
"gift",
[
"gift_id",
Gift(
"gift_id",
Sticker("file_id", "file_unique_id", 512, 512, False, False, "regular"),
5,
10,
5,
),
],
ids=["string", "Gift"],
)
async def test_send_gift(self, offline_bot, gift, monkeypatch):
# We can't send actual gifts, so we just check that the correct parameters are passed
text_entities = [
MessageEntity(MessageEntity.TEXT_LINK, 0, 4, "url"),
MessageEntity(MessageEntity.BOLD, 5, 9),
]
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
user_id = request_data.parameters["user_id"] == "user_id"
gift_id = request_data.parameters["gift_id"] == "gift_id"
text = request_data.parameters["text"] == "text"
text_parse_mode = request_data.parameters["text_parse_mode"] == "text_parse_mode"
tes = request_data.parameters["text_entities"] == [
me.to_dict() for me in text_entities
]
return user_id and gift_id and text and text_parse_mode and tes
monkeypatch.setattr(offline_bot.request, "post", make_assertion)
assert await offline_bot.send_gift(
"user_id", gift, "text", text_parse_mode="text_parse_mode", text_entities=text_entities
)
@pytest.mark.parametrize("default_bot", [{"parse_mode": "Markdown"}], indirect=True)
@pytest.mark.parametrize(
("passed_value", "expected_value"),
[(DEFAULT_NONE, "Markdown"), ("HTML", "HTML"), (None, None)],
)
async def test_send_gift_default_parse_mode(
self, default_bot, monkeypatch, passed_value, expected_value
):
async def make_assertion(url, request_data: RequestData, *args, **kwargs):
return request_data.parameters.get("text_parse_mode") == expected_value
monkeypatch.setattr(default_bot.request, "post", make_assertion)
kwargs = {
"user_id": "user_id",
"gift_id": "gift_id",
}
if passed_value is not DEFAULT_NONE:
kwargs["text_parse_mode"] = passed_value
assert await default_bot.send_gift(**kwargs)
@pytest.fixture
def gifts(request):
return Gifts(gifts=GiftsTestBase.gifts)
class GiftsTestBase:
gifts: Sequence[Gift] = [
Gift(
id="id1",
sticker=Sticker(
file_id="file_id",
file_unique_id="file_unique_id",
width=512,
height=512,
is_animated=False,
is_video=False,
type="regular",
),
star_count=5,
total_count=5,
remaining_count=5,
),
Gift(
id="id2",
sticker=Sticker(
file_id="file_id",
file_unique_id="file_unique_id",
width=512,
height=512,
is_animated=False,
is_video=False,
type="regular",
),
star_count=6,
total_count=6,
remaining_count=6,
),
Gift(
id="id3",
sticker=Sticker(
file_id="file_id",
file_unique_id="file_unique_id",
width=512,
height=512,
is_animated=False,
is_video=False,
type="regular",
),
star_count=7,
total_count=7,
remaining_count=7,
),
]
class TestGiftsWithoutRequest(GiftsTestBase):
def test_slot_behaviour(self, gifts):
for attr in gifts.__slots__:
assert getattr(gifts, attr, "err") != "err", f"got extra slot '{attr}'"
assert len(mro_slots(gifts)) == len(set(mro_slots(gifts))), "duplicate slot"
def test_de_json(self, offline_bot, gifts):
json_dict = {"gifts": [gift.to_dict() for gift in self.gifts]}
gifts = Gifts.de_json(json_dict, offline_bot)
assert gifts.api_kwargs == {}
assert gifts.gifts == tuple(self.gifts)
for de_json_gift, original_gift in zip(gifts.gifts, self.gifts):
assert de_json_gift.id == original_gift.id
assert de_json_gift.sticker == original_gift.sticker
assert de_json_gift.star_count == original_gift.star_count
assert de_json_gift.total_count == original_gift.total_count
assert de_json_gift.remaining_count == original_gift.remaining_count
assert Gifts.de_json(None, offline_bot) is None
def test_to_dict(self, gifts):
gifts_dict = gifts.to_dict()
assert isinstance(gifts_dict, dict)
assert gifts_dict["gifts"] == [gift.to_dict() for gift in self.gifts]
def test_equality(self, gifts):
a = gifts
b = Gifts(self.gifts)
c = Gifts(self.gifts[:2])
d = BotCommand("start", "description")
assert a == b
assert hash(a) == hash(b)
assert a != c
assert hash(a) != hash(c)
assert a != d
assert hash(a) != hash(d)
class TestGiftsWithRequest(GiftTestBase):
async def test_get_available_gifts(self, bot, chat_id):
# We don't control the available gifts, so we can not make any better assertions
assert isinstance(await bot.get_available_gifts(), Gifts)