Repository: python-telegram-bot/python-telegram-bot
Pull request: Add missing shortcuts
Turns out, there where a lot more than I expected. 

`Chat` already has a method `send_action`. I added `send_chat_action` for completeness and both to `User`. 
**TL;DR:** Both. Both is good.
I guess the logic was to skip the `chat` similarly to `Message.edit_text` as shortcut for `Bot.edit_message_text`, but the `chat` in `send_chat_action` acutally comes from the class name `ChatAction` … But having both doesn't hurt.

Also, one *could* think of adding shortcuts to `ChosenInlineResult`, which has an `inline_message_id` attribute, but IMHO that doesn't really make sense. It would only be needed, if one would edit the message right after it's posted (why, though?). In all other cases one usually has only the `inline_message_id` and not the `CIR`.

Closes #2034

Problem statement:
[FEATURE] Add missing shortcuts
There are some shortcuts missing in `Message`, `CallbackQuery`, `User` and `Chat`. I noticed:

* `send/stop_message_live_location`
* `send_game`
* `set_game_score`
* `get_game_high_scores`

We should check that

* both `User` and `Chat` have shortcuts for all `send_*` methods
* both `Message` and `CallbackQuery` have shortcuts for all methods that can accept `inline_message_id`

Hints from issue discussion:

Commit message: A few more minor changes

Patch to review:
diff --git a/telegram/callbackquery.py b/telegram/callbackquery.py
index 5a3cf63603f..46c5f65a677 100644
--- a/telegram/callbackquery.py
+++ b/telegram/callbackquery.py
@@ -200,3 +200,142 @@ def edit_message_reply_markup(self, reply_markup, *args, **kwargs):
                                                       chat_id=self.message.chat_id,
                                                       message_id=self.message.message_id,
                                                       *args, **kwargs)
+
+    def edit_message_media(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.edit_message_replyMarkup(chat_id=update.callback_query.message.chat_id,
+                                         message_id=update.callback_query.message.message_id,
+                                         media=media,
+                                         *args, **kwargs)
+
+        or::
+
+            bot.edit_message_media(inline_message_id=update.callback_query.inline_message_id,
+                                   media=media,
+                                   *args, **kwargs)
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+
+        """
+        if self.inline_message_id:
+            return self.bot.edit_message_media(inline_message_id=self.inline_message_id,
+                                               *args, **kwargs)
+        else:
+            return self.bot.edit_message_media(chat_id=self.message.chat_id,
+                                               message_id=self.message.message_id,
+                                               *args, **kwargs)
+
+    def edit_message_live_location(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.edit_message_live_location(chat_id=update.callback_query.message.chat_id,
+                                           message_id=update.callback_query.message.message_id,
+                                           reply_markup=reply_markup,
+                                           *args, **kwargs)
+
+        or::
+
+            bot.edit_message_live_location(
+                inline_message_id=update.callback_query.inline_message_id,
+                reply_markup=reply_markup,
+                *args, **kwargs
+            )
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+
+        """
+        if self.inline_message_id:
+            return self.bot.edit_message_live_location(inline_message_id=self.inline_message_id,
+                                                       *args, **kwargs)
+        else:
+            return self.bot.edit_message_live_location(chat_id=self.message.chat_id,
+                                                       message_id=self.message.message_id,
+                                                       *args, **kwargs)
+
+    def stop_message_live_location(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.stop_message_live_location(chat_id=update.callback_query.message.chat_id,
+                                           message_id=update.callback_query.message.message_id,
+                                           reply_markup=reply_markup,
+                                           *args, **kwargs)
+
+        or::
+
+            bot.stop_message_live_location(
+                inline_message_id=update.callback_query.inline_message_id,
+                reply_markup=reply_markup,
+                *args, **kwargs
+            )
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+
+        """
+        if self.inline_message_id:
+            return self.bot.stop_message_live_location(inline_message_id=self.inline_message_id,
+                                                       *args, **kwargs)
+        else:
+            return self.bot.stop_message_live_location(chat_id=self.message.chat_id,
+                                                       message_id=self.message.message_id,
+                                                       *args, **kwargs)
+
+    def set_game_score(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.set_game_score(chat_id=update.callback_query.message.chat_id,
+                               message_id=update.callback_query.message.message_id,
+                               reply_markup=reply_markup,
+                               *args, **kwargs)
+
+        or::
+
+            bot.set_game_score(inline_message_id=update.callback_query.inline_message_id,
+                               reply_markup=reply_markup,
+                               *args, **kwargs)
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+
+        """
+        if self.inline_message_id:
+            return self.bot.set_game_score(inline_message_id=self.inline_message_id,
+                                           *args, **kwargs)
+        else:
+            return self.bot.set_game_score(chat_id=self.message.chat_id,
+                                           message_id=self.message.message_id,
+                                           *args, **kwargs)
+
+    def get_game_high_scores(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.get_game_high_scores(chat_id=update.callback_query.message.chat_id,
+                                     message_id=update.callback_query.message.message_id,
+                                     reply_markup=reply_markup,
+                                     *args, **kwargs)
+
+        or::
+
+            bot.get_game_high_scores(inline_message_id=update.callback_query.inline_message_id,
+                                     reply_markup=reply_markup,
+                                     *args, **kwargs)
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+
+        """
+        if self.inline_message_id:
+            return self.bot.get_game_high_scores(inline_message_id=self.inline_message_id,
+                                                 *args, **kwargs)
+        else:
+            return self.bot.get_game_high_scores(chat_id=self.message.chat_id,
+                                                 message_id=self.message.message_id,
+                                                 *args, **kwargs)
diff --git a/telegram/chat.py b/telegram/chat.py
index 09392896fa3..f3690f5b93c 100644
--- a/telegram/chat.py
+++ b/telegram/chat.py
@@ -149,18 +149,6 @@ def de_json(cls, data, bot):
 
         return cls(bot=bot, **data)
 
-    def send_action(self, *args, **kwargs):
-        """Shortcut for::
-
-            bot.send_chat_action(update.message.chat.id, *args, **kwargs)
-
-        Returns:
-            :obj:`bool`: If the action was sent successfully.
-
-        """
-
-        return self.bot.send_chat_action(self.id, *args, **kwargs)
-
     def leave(self, *args, **kwargs):
         """Shortcut for::
 
@@ -270,6 +258,35 @@ def send_message(self, *args, **kwargs):
         """
         return self.bot.send_message(self.id, *args, **kwargs)
 
+    def send_media_group(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_media_group(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            List[:class:`telegram.Message`:] On success, instance representing the message posted.
+
+        """
+        return self.bot.send_media_group(self.id, *args, **kwargs)
+
+    def send_chat_action(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_chat_action(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :obj:`True`: On success.
+
+        """
+        return self.bot.send_chat_action(self.id, *args, **kwargs)
+
+    send_action = send_chat_action
+    """Alias for :attr:`send_chat_action`"""
+
     def send_photo(self, *args, **kwargs):
         """Shortcut for::
 
@@ -283,6 +300,19 @@ def send_photo(self, *args, **kwargs):
         """
         return self.bot.send_photo(self.id, *args, **kwargs)
 
+    def send_contact(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_contact(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_contact(self.id, *args, **kwargs)
+
     def send_audio(self, *args, **kwargs):
         """Shortcut for::
 
@@ -309,6 +339,58 @@ def send_document(self, *args, **kwargs):
         """
         return self.bot.send_document(self.id, *args, **kwargs)
 
+    def send_dice(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_dice(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_dice(self.id, *args, **kwargs)
+
+    def send_game(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_game(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_game(self.id, *args, **kwargs)
+
+    def send_invoice(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_invoice(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_invoice(self.id, *args, **kwargs)
+
+    def send_location(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_location(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_location(self.id, *args, **kwargs)
+
     def send_animation(self, *args, **kwargs):
         """Shortcut for::
 
@@ -335,6 +417,19 @@ def send_sticker(self, *args, **kwargs):
         """
         return self.bot.send_sticker(self.id, *args, **kwargs)
 
+    def send_venue(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_venue(Chat.id, *args, **kwargs)
+
+        Where Chat is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_venue(self.id, *args, **kwargs)
+
     def send_video(self, *args, **kwargs):
         """Shortcut for::
 
diff --git a/telegram/message.py b/telegram/message.py
index 8f521a46ae5..b714070136d 100644
--- a/telegram/message.py
+++ b/telegram/message.py
@@ -935,6 +935,86 @@ def edit_reply_markup(self, *args, **kwargs):
         return self.bot.edit_message_reply_markup(
             chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
 
+    def edit_live_location(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.edit_message_live_location(chat_id=message.chat_id,
+                                           message_id=message.message_id,
+                                           *args,
+                                           **kwargs)
+
+        Note:
+            You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
+            of methods) or channel posts, if the bot is an admin in that channel. However, this
+            behaviour is undocumented and might be changed by Telegram.
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+        """
+        return self.bot.edit_message_live_location(
+            chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
+
+    def stop_live_location(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.stop_message_live_location(chat_id=message.chat_id,
+                                           message_id=message.message_id,
+                                           *args,
+                                           **kwargs)
+
+        Note:
+            You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
+            of methods) or channel posts, if the bot is an admin in that channel. However, this
+            behaviour is undocumented and might be changed by Telegram.
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+        """
+        return self.bot.stop_message_live_location(
+            chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
+
+    def set_game_score(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.set_game_score(chat_id=message.chat_id,
+                               message_id=message.message_id,
+                               *args,
+                               **kwargs)
+
+        Note:
+            You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
+            of methods) or channel posts, if the bot is an admin in that channel. However, this
+            behaviour is undocumented and might be changed by Telegram.
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+        """
+        return self.bot.set_game_score(
+            chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
+
+    def get_game_high_scores(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.get_game_high_scores(chat_id=message.chat_id,
+                                     message_id=message.message_id,
+                                     *args,
+                                     **kwargs)
+
+        Note:
+            You can only edit messages that the bot sent itself (i.e. of the ``bot.send_*`` family
+            of methods) or channel posts, if the bot is an admin in that channel. However, this
+            behaviour is undocumented and might be changed by Telegram.
+
+        Returns:
+            :class:`telegram.Message`: On success, if edited message is sent by the bot, the
+            edited Message is returned, otherwise ``True`` is returned.
+        """
+        return self.bot.get_game_high_scores(
+            chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
+
     def delete(self, *args, **kwargs):
         """Shortcut for::
 
@@ -966,6 +1046,21 @@ def stop_poll(self, *args, **kwargs):
         return self.bot.stop_poll(
             chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
 
+    def pin(self, *args, **kwargs):
+        """Shortcut for::
+
+             bot.pin_chat_message(chat_id=message.chat_id,
+                                  message_id=message.message_id,
+                                  *args,
+                                  **kwargs)
+
+        Returns:
+            :obj:`True`: On success.
+
+        """
+        return self.bot.pin_chat_message(
+            chat_id=self.chat_id, message_id=self.message_id, *args, **kwargs)
+
     def parse_entity(self, entity):
         """Returns the text from a given :class:`telegram.MessageEntity`.
 
diff --git a/telegram/user.py b/telegram/user.py
index 095596cded2..18236ab5d3e 100644
--- a/telegram/user.py
+++ b/telegram/user.py
@@ -206,6 +206,19 @@ def send_photo(self, *args, **kwargs):
         """
         return self.bot.send_photo(self.id, *args, **kwargs)
 
+    def send_media_group(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_media_group(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            List[:class:`telegram.Message`:] On success, instance representing the message posted.
+
+        """
+        return self.bot.send_media_group(self.id, *args, **kwargs)
+
     def send_audio(self, *args, **kwargs):
         """Shortcut for::
 
@@ -219,6 +232,48 @@ def send_audio(self, *args, **kwargs):
         """
         return self.bot.send_audio(self.id, *args, **kwargs)
 
+    def send_chat_action(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_chat_action(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :obj:`True`: On success.
+
+        """
+        return self.bot.send_chat_action(self.id, *args, **kwargs)
+
+    send_action = send_chat_action
+    """Alias for :attr:`send_chat_action`"""
+
+    def send_contact(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_contact(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_contact(self.id, *args, **kwargs)
+
+    def send_dice(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_dice(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_dice(self.id, *args, **kwargs)
+
     def send_document(self, *args, **kwargs):
         """Shortcut for::
 
@@ -232,6 +287,45 @@ def send_document(self, *args, **kwargs):
         """
         return self.bot.send_document(self.id, *args, **kwargs)
 
+    def send_game(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_game(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_game(self.id, *args, **kwargs)
+
+    def send_invoice(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_invoice(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_invoice(self.id, *args, **kwargs)
+
+    def send_location(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_location(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_location(self.id, *args, **kwargs)
+
     def send_animation(self, *args, **kwargs):
         """Shortcut for::
 
@@ -271,6 +365,19 @@ def send_video(self, *args, **kwargs):
         """
         return self.bot.send_video(self.id, *args, **kwargs)
 
+    def send_venue(self, *args, **kwargs):
+        """Shortcut for::
+
+            bot.send_venue(User.id, *args, **kwargs)
+
+        Where User is the current instance.
+
+        Returns:
+            :class:`telegram.Message`: On success, instance representing the message posted.
+
+        """
+        return self.bot.send_venue(self.id, *args, **kwargs)
+
     def send_video_note(self, *args, **kwargs):
         """Shortcut for::
 
diff --git a/tests/test_callbackquery.py b/tests/test_callbackquery.py
index be39e7aa2cb..f2648f1ee45 100644
--- a/tests/test_callbackquery.py
+++ b/tests/test_callbackquery.py
@@ -133,6 +133,81 @@ def test(*args, **kwargs):
         assert callback_query.edit_message_reply_markup(reply_markup=[['1', '2']])
         assert callback_query.edit_message_reply_markup([['1', '2']])
 
+    def test_edit_message_media(self, monkeypatch, callback_query):
+        def test(*args, **kwargs):
+            message_media = kwargs.get('media') == [['1', '2']] or args[0] == [['1', '2']]
+            try:
+                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
+                return id_ and message_media
+            except KeyError:
+                id_ = kwargs['chat_id'] == callback_query.message.chat_id
+                message = kwargs['message_id'] == callback_query.message.message_id
+                return id_ and message and message_media
+
+        monkeypatch.setattr(callback_query.bot, 'edit_message_media', test)
+        assert callback_query.edit_message_media(media=[['1', '2']])
+        assert callback_query.edit_message_media([['1', '2']])
+
+    def test_edit_message_live_location(self, monkeypatch, callback_query):
+        def test(*args, **kwargs):
+            latitude = kwargs.get('latitude') == 1 or args[0] == 1
+            longitude = kwargs.get('longitude') == 2 or args[1] == 2
+            try:
+                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
+                return id_ and latitude and longitude
+            except KeyError:
+                id_ = kwargs['chat_id'] == callback_query.message.chat_id
+                message = kwargs['message_id'] == callback_query.message.message_id
+                return id_ and message and latitude and longitude
+
+        monkeypatch.setattr(callback_query.bot, 'edit_message_live_location', test)
+        assert callback_query.edit_message_live_location(latitude=1, longitude=2)
+        assert callback_query.edit_message_live_location(1, 2)
+
+    def test_stop_message_live_location(self, monkeypatch, callback_query):
+        def test(*args, **kwargs):
+            try:
+                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
+                return id_
+            except KeyError:
+                id_ = kwargs['chat_id'] == callback_query.message.chat_id
+                message = kwargs['message_id'] == callback_query.message.message_id
+                return id_ and message
+
+        monkeypatch.setattr(callback_query.bot, 'stop_message_live_location', test)
+        assert callback_query.stop_message_live_location()
+
+    def test_set_game_score(self, monkeypatch, callback_query):
+        def test(*args, **kwargs):
+            user_id = kwargs.get('user_id') == 1 or args[0] == 1
+            score = kwargs.get('score') == 2 or args[1] == 2
+            try:
+                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
+                return id_ and user_id and score
+            except KeyError:
+                id_ = kwargs['chat_id'] == callback_query.message.chat_id
+                message = kwargs['message_id'] == callback_query.message.message_id
+                return id_ and message and user_id and score
+
+        monkeypatch.setattr(callback_query.bot, 'set_game_score', test)
+        assert callback_query.set_game_score(user_id=1, score=2)
+        assert callback_query.set_game_score(1, 2)
+
+    def test_get_game_high_scores(self, monkeypatch, callback_query):
+        def test(*args, **kwargs):
+            user_id = kwargs.get('user_id') == 1 or args[0] == 1
+            try:
+                id_ = kwargs['inline_message_id'] == callback_query.inline_message_id
+                return id_ and user_id
+            except KeyError:
+                id_ = kwargs['chat_id'] == callback_query.message.chat_id
+                message = kwargs['message_id'] == callback_query.message.message_id
+                return id_ and message and user_id
+
+        monkeypatch.setattr(callback_query.bot, 'get_game_high_scores', test)
+        assert callback_query.get_game_high_scores(user_id=1)
+        assert callback_query.get_game_high_scores(1)
+
     def test_equality(self):
         a = CallbackQuery(self.id_, self.from_user, 'chat')
         b = CallbackQuery(self.id_, self.from_user, 'chat')
diff --git a/tests/test_chat.py b/tests/test_chat.py
index 8c63de4d8f6..bbf203d7fc3 100644
--- a/tests/test_chat.py
+++ b/tests/test_chat.py
@@ -113,6 +113,7 @@ def test(*args, **kwargs):
 
         monkeypatch.setattr(chat.bot, 'send_chat_action', test)
         assert chat.send_action(action=ChatAction.TYPING)
+        assert chat.send_chat_action(action=ChatAction.TYPING)
 
     def test_leave(self, monkeypatch, chat):
         def test(*args, **kwargs):
@@ -189,6 +190,13 @@ def test(*args, **kwargs):
         monkeypatch.setattr(chat.bot, 'send_message', test)
         assert chat.send_message('test')
 
+    def test_instance_method_send_media_group(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_media_group'
+
+        monkeypatch.setattr(chat.bot, 'send_media_group', test)
+        assert chat.send_media_group('test_media_group')
+
     def test_instance_method_send_photo(self, monkeypatch, chat):
         def test(*args, **kwargs):
             return args[0] == chat.id and args[1] == 'test_photo'
@@ -196,6 +204,13 @@ def test(*args, **kwargs):
         monkeypatch.setattr(chat.bot, 'send_photo', test)
         assert chat.send_photo('test_photo')
 
+    def test_instance_method_send_contact(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_contact'
+
+        monkeypatch.setattr(chat.bot, 'send_contact', test)
+        assert chat.send_contact('test_contact')
+
     def test_instance_method_send_audio(self, monkeypatch, chat):
         def test(*args, **kwargs):
             return args[0] == chat.id and args[1] == 'test_audio'
@@ -210,6 +225,34 @@ def test(*args, **kwargs):
         monkeypatch.setattr(chat.bot, 'send_document', test)
         assert chat.send_document('test_document')
 
+    def test_instance_method_send_dice(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_dice'
+
+        monkeypatch.setattr(chat.bot, 'send_dice', test)
+        assert chat.send_dice('test_dice')
+
+    def test_instance_method_send_game(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_game'
+
+        monkeypatch.setattr(chat.bot, 'send_game', test)
+        assert chat.send_game('test_game')
+
+    def test_instance_method_send_invoice(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_invoice'
+
+        monkeypatch.setattr(chat.bot, 'send_invoice', test)
+        assert chat.send_invoice('test_invoice')
+
+    def test_instance_method_send_location(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_location'
+
+        monkeypatch.setattr(chat.bot, 'send_location', test)
+        assert chat.send_location('test_location')
+
     def test_instance_method_send_sticker(self, monkeypatch, chat):
         def test(*args, **kwargs):
             return args[0] == chat.id and args[1] == 'test_sticker'
@@ -217,6 +260,13 @@ def test(*args, **kwargs):
         monkeypatch.setattr(chat.bot, 'send_sticker', test)
         assert chat.send_sticker('test_sticker')
 
+    def test_instance_method_send_venue(self, monkeypatch, chat):
+        def test(*args, **kwargs):
+            return args[0] == chat.id and args[1] == 'test_venue'
+
+        monkeypatch.setattr(chat.bot, 'send_venue', test)
+        assert chat.send_venue('test_venue')
+
     def test_instance_method_send_video(self, monkeypatch, chat):
         def test(*args, **kwargs):
             return args[0] == chat.id and args[1] == 'test_video'
diff --git a/tests/test_message.py b/tests/test_message.py
index 9b3d592f2d6..2b53619dea6 100644
--- a/tests/test_message.py
+++ b/tests/test_message.py
@@ -795,6 +795,47 @@ def test(*args, **kwargs):
         monkeypatch.setattr(message.bot, 'edit_message_reply_markup', test)
         assert message.edit_reply_markup(reply_markup=[['1', '2']])
 
+    def test_edit_live_location(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            latitude = kwargs['latitude'] == 1
+            longitude = kwargs['longitude'] == 2
+            return chat_id and message_id and longitude and latitude
+
+        monkeypatch.setattr(message.bot, 'edit_message_live_location', test)
+        assert message.edit_live_location(latitude=1, longitude=2)
+
+    def test_stop_live_location(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            return chat_id and message_id
+
+        monkeypatch.setattr(message.bot, 'stop_message_live_location', test)
+        assert message.stop_live_location()
+
+    def test_set_game_score(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            user_id = kwargs['user_id'] == 1
+            score = kwargs['score'] == 2
+            return chat_id and message_id and user_id and score
+
+        monkeypatch.setattr(message.bot, 'set_game_score', test)
+        assert message.set_game_score(user_id=1, score=2)
+
+    def test_get_game_high_scores(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            user_id = kwargs['user_id'] == 1
+            return chat_id and message_id and user_id
+
+        monkeypatch.setattr(message.bot, 'get_game_high_scores', test)
+        assert message.get_game_high_scores(user_id=1, score=2)
+
     def test_delete(self, monkeypatch, message):
         def test(*args, **kwargs):
             chat_id = kwargs['chat_id'] == message.chat_id
@@ -804,6 +845,24 @@ def test(*args, **kwargs):
         monkeypatch.setattr(message.bot, 'delete_message', test)
         assert message.delete()
 
+    def test_stop_poll(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            return chat_id and message_id
+
+        monkeypatch.setattr(message.bot, 'stop_poll', test)
+        assert message.stop_poll()
+
+    def test_pin(self, monkeypatch, message):
+        def test(*args, **kwargs):
+            chat_id = kwargs['chat_id'] == message.chat_id
+            message_id = kwargs['message_id'] == message.message_id
+            return chat_id and message_id
+
+        monkeypatch.setattr(message.bot, 'pin_chat_message', test)
+        assert message.pin()
+
     def test_default_quote(self, message):
         kwargs = {}
 
diff --git a/tests/test_user.py b/tests/test_user.py
index 702d802cad5..b9df8c3f28e 100644
--- a/tests/test_user.py
+++ b/tests/test_user.py
@@ -141,6 +141,13 @@ def test(*args, **kwargs):
         monkeypatch.setattr(user.bot, 'send_photo', test)
         assert user.send_photo('test_photo')
 
+    def test_instance_method_send_media_group(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_media_group'
+
+        monkeypatch.setattr(user.bot, 'send_media_group', test)
+        assert user.send_media_group('test_media_group')
+
     def test_instance_method_send_audio(self, monkeypatch, user):
         def test(*args, **kwargs):
             return args[0] == user.id and args[1] == 'test_audio'
@@ -148,6 +155,27 @@ def test(*args, **kwargs):
         monkeypatch.setattr(user.bot, 'send_audio', test)
         assert user.send_audio('test_audio')
 
+    def test_instance_method_send_chat_action(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_chat_action'
+
+        monkeypatch.setattr(user.bot, 'send_chat_action', test)
+        assert user.send_chat_action('test_chat_action')
+
+    def test_instance_method_send_contact(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_contact'
+
+        monkeypatch.setattr(user.bot, 'send_contact', test)
+        assert user.send_contact('test_contact')
+
+    def test_instance_method_send_dice(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_dice'
+
+        monkeypatch.setattr(user.bot, 'send_dice', test)
+        assert user.send_dice('test_dice')
+
     def test_instance_method_send_document(self, monkeypatch, user):
         def test(*args, **kwargs):
             return args[0] == user.id and args[1] == 'test_document'
@@ -155,6 +183,27 @@ def test(*args, **kwargs):
         monkeypatch.setattr(user.bot, 'send_document', test)
         assert user.send_document('test_document')
 
+    def test_instance_method_send_game(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_game'
+
+        monkeypatch.setattr(user.bot, 'send_game', test)
+        assert user.send_game('test_game')
+
+    def test_instance_method_send_invoice(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_invoice'
+
+        monkeypatch.setattr(user.bot, 'send_invoice', test)
+        assert user.send_invoice('test_invoice')
+
+    def test_instance_method_send_location(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_location'
+
+        monkeypatch.setattr(user.bot, 'send_location', test)
+        assert user.send_location('test_location')
+
     def test_instance_method_send_sticker(self, monkeypatch, user):
         def test(*args, **kwargs):
             return args[0] == user.id and args[1] == 'test_sticker'
@@ -169,6 +218,13 @@ def test(*args, **kwargs):
         monkeypatch.setattr(user.bot, 'send_video', test)
         assert user.send_video('test_video')
 
+    def test_instance_method_send_venue(self, monkeypatch, user):
+        def test(*args, **kwargs):
+            return args[0] == user.id and args[1] == 'test_venue'
+
+        monkeypatch.setattr(user.bot, 'send_venue', test)
+        assert user.send_venue('test_venue')
+
     def test_instance_method_send_video_note(self, monkeypatch, user):
         def test(*args, **kwargs):
             return args[0] == user.id and args[1] == 'test_video_note'


Code review comments:
diff_hunk: @@ -200,3 +200,142 @@ def edit_message_reply_markup(self, reply_markup, *args, **kwargs):
                                                       chat_id=self.message.chat_id,
                                                       message_id=self.message.message_id,
                                                       *args, **kwargs)
+
+    def edit_message_media(self, *args, **kwargs):
+        """Shortcut for either::
+
+            bot.edit_message_replyMarkup(chat_id=update.callback_query.message.chat_id,
path: telegram/callbackquery.py
text: @user1:
```suggestion
            bot.edit_message_media(chat_id=update.callback_query.message.chat_id,
```

:)