Merge pull request #502 from carpedm20/remove-enums

Remove extraneous enums
This commit is contained in:
Mads Marquart
2020-01-09 21:12:53 +01:00
committed by GitHub
19 changed files with 143 additions and 182 deletions

View File

@@ -28,8 +28,6 @@ Messages
.. autoclass:: Mention .. autoclass:: Mention
.. autoclass:: EmojiSize(Enum) .. autoclass:: EmojiSize(Enum)
:undoc-members: :undoc-members:
.. autoclass:: MessageReaction(Enum)
:undoc-members:
Exceptions Exceptions
---------- ----------
@@ -56,11 +54,7 @@ Miscellaneous
.. autoclass:: ThreadLocation(Enum) .. autoclass:: ThreadLocation(Enum)
:undoc-members: :undoc-members:
.. autoclass:: ThreadColor(Enum)
:undoc-members:
.. autoclass:: ActiveStatus() .. autoclass:: ActiveStatus()
.. autoclass:: TypingStatus(Enum)
:undoc-members:
.. autoclass:: QuickReply .. autoclass:: QuickReply
.. autoclass:: QuickReplyText .. autoclass:: QuickReplyText

View File

@@ -70,8 +70,8 @@ corresponds to the ID of a single user, and the ID of a group respectively::
Some functions don't require a thread type, so in these cases you just provide the thread ID:: Some functions don't require a thread type, so in these cases you just provide the thread ID::
thread = fbchat.Thread(session=session, id="<user-or-group-id>") thread = fbchat.Thread(session=session, id="<user-or-group-id>")
thread.set_color(ThreadColor.BILOBA_FLOWER) thread.set_color("#a695c7")
thread.set_color(ThreadColor.MESSENGER_BLUE) thread.set_color("#67b868")
.. _intro_message_ids: .. _intro_message_ids:
@@ -82,12 +82,10 @@ Message IDs
Every message you send on Facebook has a unique ID, and every action you do in a thread, Every message you send on Facebook has a unique ID, and every action you do in a thread,
like changing a nickname or adding a person, has a unique ID too. like changing a nickname or adding a person, has a unique ID too.
Some of ``fbchat``'s functions require these ID's, like `Client.react_to_message`,
and some of then provide this ID, like `Client.send`.
This snippet shows how to send a message, and then use the returned ID to react to that message with a 😍 emoji:: This snippet shows how to send a message, and then use the returned ID to react to that message with a 😍 emoji::
message_id = thread.send(Message(text='message')) message = thread.send_text("A message!")
client.react_to_message(message_id, MessageReaction.LOVE) message.react("😍")
.. _intro_interacting: .. _intro_interacting:

View File

@@ -54,8 +54,8 @@ thread.set_nickname(fbchat.User(session=session, id="<user id>"), "<new nickname
# Will set the typing status of the thread # Will set the typing status of the thread
thread.start_typing() thread.start_typing()
# Will change the thread color to `MESSENGER_BLUE` # Will change the thread color to #0084ff
thread.set_color(fbchat.ThreadColor.MESSENGER_BLUE) thread.set_color("#0084ff")
# Will change the thread emoji to `👍` # Will change the thread emoji to `👍`
thread.set_emoji("👍") thread.set_emoji("👍")
@@ -63,4 +63,4 @@ thread.set_emoji("👍")
message = fbchat.Message(session=session, id="<message id>") message = fbchat.Message(session=session, id="<message id>")
# Will react to a message with a 😍 emoji # Will react to a message with a 😍 emoji
message.react(fbchat.MessageReaction.LOVE) message.react("😍")

View File

@@ -4,7 +4,7 @@ import fbchat
old_thread_id = "1234567890" old_thread_id = "1234567890"
# Change these to match your liking # Change these to match your liking
old_color = fbchat.ThreadColor.MESSENGER_BLUE old_color = "#0084ff"
old_emoji = "👍" old_emoji = "👍"
old_title = "Old group chat name" old_title = "Old group chat name"
old_nicknames = { old_nicknames = {

View File

@@ -14,11 +14,11 @@ from . import _core, _util
from ._core import Image from ._core import Image
from ._exception import FBchatException, FBchatFacebookError from ._exception import FBchatException, FBchatFacebookError
from ._session import Session from ._session import Session
from ._thread import ThreadLocation, ThreadColor, ThreadABC, Thread from ._thread import ThreadLocation, ThreadABC, Thread
from ._user import TypingStatus, User, UserData, ActiveStatus from ._user import User, UserData, ActiveStatus
from ._group import Group, GroupData from ._group import Group, GroupData
from ._page import Page, PageData from ._page import Page, PageData
from ._message import EmojiSize, MessageReaction, Mention, Message from ._message import EmojiSize, Mention, Message
from ._attachment import Attachment, UnsentMessage, ShareAttachment from ._attachment import Attachment, UnsentMessage, ShareAttachment
from ._sticker import Sticker from ._sticker import Sticker
from ._location import LocationAttachment, LiveLocationAttachment from ._location import LocationAttachment, LiveLocationAttachment

View File

@@ -6,11 +6,11 @@ from ._core import log
from . import _util, _graphql, _session from . import _util, _graphql, _session
from ._exception import FBchatException, FBchatFacebookError from ._exception import FBchatException, FBchatFacebookError
from ._thread import ThreadLocation, ThreadColor from ._thread import ThreadLocation
from ._user import TypingStatus, User, UserData, ActiveStatus from ._user import User, UserData, ActiveStatus
from ._group import Group, GroupData from ._group import Group, GroupData
from ._page import Page, PageData from ._page import Page, PageData
from ._message import EmojiSize, MessageReaction, Mention, Message from ._message import EmojiSize, Mention, Message
from ._attachment import Attachment from ._attachment import Attachment
from ._sticker import Sticker from ._sticker import Sticker
from ._location import LocationAttachment, LiveLocationAttachment from ._location import LocationAttachment, LiveLocationAttachment
@@ -947,12 +947,11 @@ class Client:
# Color change # Color change
elif delta_type == "change_thread_theme": elif delta_type == "change_thread_theme":
new_color = ThreadColor._from_graphql(delta["untypedData"]["theme_color"])
thread = get_thread(metadata) thread = get_thread(metadata)
self.on_color_change( self.on_color_change(
mid=mid, mid=mid,
author_id=author_id, author_id=author_id,
new_color=new_color, new_color=ThreadABC._parse_color(delta["untypedData"]["theme_color"]),
thread=get_thread(metadata), thread=get_thread(metadata),
at=at, at=at,
metadata=metadata, metadata=metadata,
@@ -1259,14 +1258,11 @@ class Client:
i = d["deltaMessageReaction"] i = d["deltaMessageReaction"]
mid = i["messageId"] mid = i["messageId"]
author_id = str(i["userId"]) author_id = str(i["userId"])
reaction = (
MessageReaction(i["reaction"]) if i.get("reaction") else None
)
add_reaction = not bool(i["action"]) add_reaction = not bool(i["action"])
if add_reaction: if add_reaction:
self.on_reaction_added( self.on_reaction_added(
mid=mid, mid=mid,
reaction=reaction, reaction=i.get("reaction"),
author_id=author_id, author_id=author_id,
thread=get_thread(metadata), thread=get_thread(metadata),
at=at, at=at,
@@ -1405,9 +1401,8 @@ class Client:
else: else:
thread_id = author_id thread_id = author_id
thread = User(session=self.session, id=thread_id) thread = User(session=self.session, id=thread_id)
typing_status = TypingStatus(m.get("st"))
self.on_typing( self.on_typing(
author_id=author_id, status=typing_status, thread=thread, author_id=author_id, status=m["st"] == 1, thread=thread
) )
# Delivered # Delivered
@@ -1569,7 +1564,7 @@ class Client:
Args: Args:
mid: The action ID mid: The action ID
author_id: The ID of the person who changed the color author_id: The ID of the person who changed the color
new_color (ThreadColor): The new color new_color: The new color. Not limited to the ones in `ThreadABC.set_color`
thread: Thread that the action was sent to. See :ref:`intro_threads` thread: Thread that the action was sent to. See :ref:`intro_threads`
at (datetime.datetime): When the action was executed at (datetime.datetime): When the action was executed
metadata: Extra metadata about the action metadata: Extra metadata about the action
@@ -1816,7 +1811,7 @@ class Client:
Args: Args:
author_id: The ID of the person who sent the action author_id: The ID of the person who sent the action
status (TypingStatus): The typing status is_typing: ``True`` if the user started typing, ``False`` if they stopped.
thread: Thread that the action was sent to. See :ref:`intro_threads` thread: Thread that the action was sent to. See :ref:`intro_threads`
""" """
pass pass
@@ -1855,7 +1850,7 @@ class Client:
Args: Args:
mid: Message ID, that user reacted to mid: Message ID, that user reacted to
reaction (MessageReaction): Reaction reaction: The added reaction. Not limited to the ones in `Message.react`
add_reaction: Whether user added or removed reaction add_reaction: Whether user added or removed reaction
author_id: The ID of the person who reacted to the message author_id: The ID of the person who reacted to the message
thread: Thread that the action was sent to. See :ref:`intro_threads` thread: Thread that the action was sent to. See :ref:`intro_threads`
@@ -1863,7 +1858,7 @@ class Client:
""" """
log.info( log.info(
"{} reacted to message {} with {} in {}".format( "{} reacted to message {} with {} in {}".format(
author_id, mid, reaction.name, thread author_id, mid, reaction, thread
) )
) )

View File

@@ -1,7 +1,6 @@
import sys import sys
import attr import attr
import logging import logging
import aenum
log = logging.getLogger("fbchat") log = logging.getLogger("fbchat")
@@ -12,25 +11,6 @@ kw_only = sys.version_info[:2] > (3, 5)
attrs_default = attr.s(slots=True, kw_only=kw_only) attrs_default = attr.s(slots=True, kw_only=kw_only)
class Enum(aenum.Enum):
"""Used internally to support enumerations"""
def __repr__(self):
# For documentation:
return "{}.{}".format(type(self).__name__, self.name)
@classmethod
def _extend_if_invalid(cls, value):
try:
return cls(value)
except ValueError:
log.warning(
"Failed parsing {.__name__}({!r}). Extending enum.".format(cls, value)
)
aenum.extend_enum(cls, "UNKNOWN_{}".format(value).upper(), value)
return cls(value)
# Frozen, so that it can be used in sets # Frozen, so that it can be used in sets
@attr.s(frozen=True, slots=True, kw_only=kw_only) @attr.s(frozen=True, slots=True, kw_only=kw_only)
class Image: class Image:

View File

@@ -150,7 +150,7 @@ class GroupData(Group):
participants = attr.ib(factory=set) participants = attr.ib(factory=set)
#: A dictionary, containing user nicknames mapped to their IDs #: A dictionary, containing user nicknames mapped to their IDs
nicknames = attr.ib(factory=dict) nicknames = attr.ib(factory=dict)
#: A `ThreadColor`. The groups's message color #: The groups's message color
color = attr.ib(None) color = attr.ib(None)
#: The groups's default emoji #: The groups's default emoji
emoji = attr.ib(None) emoji = attr.ib(None)
@@ -189,8 +189,8 @@ class GroupData(Group):
] ]
), ),
nicknames=c_info.get("nicknames"), nicknames=c_info.get("nicknames"),
color=c_info.get("color"), color=c_info["color"],
emoji=c_info.get("emoji"), emoji=c_info["emoji"],
admins=set([node.get("id") for node in data.get("thread_admins")]), admins=set([node.get("id") for node in data.get("thread_admins")]),
approval_mode=bool(data.get("approval_mode")) approval_mode=bool(data.get("approval_mode"))
if data.get("approval_mode") is not None if data.get("approval_mode") is not None

View File

@@ -1,11 +1,12 @@
import attr import attr
import enum
from string import Formatter from string import Formatter
from ._core import log, attrs_default, Enum from ._core import log, attrs_default
from . import _util, _session, _attachment, _location, _file, _quick_reply, _sticker from . import _util, _session, _attachment, _location, _file, _quick_reply, _sticker
from typing import Optional from typing import Optional
class EmojiSize(Enum): class EmojiSize(enum.Enum):
"""Used to specify the size of a sent emoji.""" """Used to specify the size of a sent emoji."""
LARGE = "369239383222810" LARGE = "369239383222810"
@@ -29,19 +30,6 @@ class EmojiSize(Enum):
return None return None
class MessageReaction(Enum):
"""Used to specify a message reaction."""
HEART = ""
LOVE = "😍"
SMILE = "😆"
WOW = "😮"
SAD = "😢"
ANGRY = "😠"
YES = "👍"
NO = "👎"
@attrs_default @attrs_default
class Mention: class Mention:
"""Represents a ``@mention``.""" """Represents a ``@mention``."""
@@ -74,6 +62,9 @@ class Mention:
} }
SENDABLE_REACTIONS = ("", "😍", "😆", "😮", "😢", "😠", "👍", "👎")
@attrs_default @attrs_default
class Message: class Message:
"""Represents a Facebook message.""" """Represents a Facebook message."""
@@ -93,18 +84,26 @@ class Message:
data = {"message_id": self.id} data = {"message_id": self.id}
j = self.session._payload_post("/messaging/unsend_message/?dpr=1", data) j = self.session._payload_post("/messaging/unsend_message/?dpr=1", data)
def react(self, reaction: Optional[MessageReaction]): def react(self, reaction: Optional[str]):
"""React to the message, or removes reaction. """React to the message, or removes reaction.
Currently, you can use "", "😍", "😆", "😮", "😢", "😠", "👍" or "👎". It
should be possible to add support for more, but we haven't figured that out yet.
Args: Args:
reaction: Reaction emoji to use, if ``None`` removes reaction reaction: Reaction emoji to use, or if ``None``, removes reaction.
""" """
if reaction and reaction not in SENDABLE_REACTIONS:
raise ValueError(
"Invalid reaction! Please use one of: {}".format(SENDABLE_REACTIONS)
)
data = { data = {
"action": "ADD_REACTION" if reaction else "REMOVE_REACTION", "action": "ADD_REACTION" if reaction else "REMOVE_REACTION",
"client_mutation_id": "1", "client_mutation_id": "1",
"actor_id": self.session.user_id, "actor_id": self.session.user_id,
"message_id": self.id, "message_id": self.id,
"reaction": reaction.value if reaction else None, "reaction": reaction,
} }
data = { data = {
"doc_id": 1491398900900362, "doc_id": 1491398900900362,
@@ -190,7 +189,7 @@ class MessageData(Message):
is_read = attr.ib(None) is_read = attr.ib(None)
#: A list of people IDs who read the message, works only with `Client.fetch_thread_messages` #: A list of people IDs who read the message, works only with `Client.fetch_thread_messages`
read_by = attr.ib(factory=list) read_by = attr.ib(factory=list)
#: A dictionary with user's IDs as keys, and their `MessageReaction` as values #: A dictionary with user's IDs as keys, and their reaction as values
reactions = attr.ib(factory=dict) reactions = attr.ib(factory=dict)
#: A `Sticker` #: A `Sticker`
sticker = attr.ib(None) sticker = attr.ib(None)
@@ -266,8 +265,7 @@ class MessageData(Message):
if _util.millis_to_datetime(int(receipt["watermark"])) >= created_at if _util.millis_to_datetime(int(receipt["watermark"])) >= created_at
], ],
reactions={ reactions={
str(r["user"]["id"]): MessageReaction._extend_if_invalid(r["reaction"]) str(r["user"]["id"]): r["reaction"] for r in data["message_reactions"]
for r in data["message_reactions"]
}, },
sticker=_sticker.Sticker._from_graphql(data.get("sticker")), sticker=_sticker.Sticker._from_graphql(data.get("sticker")),
attachments=attachments, attachments=attachments,

View File

@@ -1,10 +1,11 @@
import attr import attr
import datetime import datetime
from ._core import attrs_default, Enum import enum
from ._core import attrs_default
from . import _exception, _util, _session from . import _exception, _util, _session
class GuestStatus(Enum): class GuestStatus(enum.Enum):
INVITED = 1 INVITED = 1
GOING = 2 GOING = 2
DECLINED = 3 DECLINED = 3

View File

@@ -2,12 +2,13 @@ import abc
import attr import attr
import collections import collections
import datetime import datetime
from ._core import attrs_default, Enum, Image import enum
from ._core import attrs_default, Image
from . import _util, _exception, _session, _graphql, _attachment, _file, _plan from . import _util, _exception, _session, _graphql, _attachment, _file, _plan
from typing import MutableMapping, Any, Iterable, Tuple from typing import MutableMapping, Any, Iterable, Tuple, Optional
class ThreadLocation(Enum): class ThreadLocation(enum.Enum):
"""Used to specify where a thread is located (inbox, pending, archived, other).""" """Used to specify where a thread is located (inbox, pending, archived, other)."""
INBOX = "INBOX" INBOX = "INBOX"
@@ -16,39 +17,29 @@ class ThreadLocation(Enum):
OTHER = "OTHER" OTHER = "OTHER"
class ThreadColor(Enum): DEFAULT_COLOR = "#0084ff"
"""Used to specify a thread colors.""" SETABLE_COLORS = (
DEFAULT_COLOR,
MESSENGER_BLUE = "#0084ff" "#44bec7",
VIKING = "#44bec7" "#ffc300",
GOLDEN_POPPY = "#ffc300" "#fa3c4c",
RADICAL_RED = "#fa3c4c" "#d696bb",
SHOCKING = "#d696bb" "#6699cc",
PICTON_BLUE = "#6699cc" "#13cf13",
FREE_SPEECH_GREEN = "#13cf13" "#ff7e29",
PUMPKIN = "#ff7e29" "#e68585",
LIGHT_CORAL = "#e68585" "#7646ff",
MEDIUM_SLATE_BLUE = "#7646ff" "#20cef5",
DEEP_SKY_BLUE = "#20cef5" "#67b868",
FERN = "#67b868" "#d4a88c",
CAMEO = "#d4a88c" "#ff5ca1",
BRILLIANT_ROSE = "#ff5ca1" "#a695c7",
BILOBA_FLOWER = "#a695c7" "#ff7ca8",
TICKLE_ME_PINK = "#ff7ca8" "#1adb5b",
MALACHITE = "#1adb5b" "#f01d6a",
RUBY = "#f01d6a" "#ff9c19",
DARK_TANGERINE = "#ff9c19" "#0edcde",
BRIGHT_TURQUOISE = "#0edcde" )
@classmethod
def _from_graphql(cls, color):
if color is None:
return None
if not color:
return cls.MESSENGER_BLUE
color = color[2:] # Strip the alpha value
value = "#{}".format(color.lower())
return cls._extend_if_invalid(value)
class ThreadABC(metaclass=abc.ABCMeta): class ThreadABC(metaclass=abc.ABCMeta):
@@ -375,22 +366,50 @@ class ThreadABC(metaclass=abc.ABCMeta):
"/messaging/save_thread_nickname/?source=thread_settings&dpr=1", data "/messaging/save_thread_nickname/?source=thread_settings&dpr=1", data
) )
def set_color(self, color: ThreadColor): def set_color(self, color: str):
"""Change thread color. """Change thread color.
The new color must be one of the following:
"#0084ff", "#44bec7", "#ffc300", "#fa3c4c", "#d696bb", "#6699cc", "#13cf13",
"#ff7e29", "#e68585", "#7646ff", "#20cef5", "#67b868", "#d4a88c", "#ff5ca1",
"#a695c7", "#ff7ca8", "#1adb5b", "#f01d6a", "#ff9c19" or "#0edcde".
The default is "#0084ff".
This list is subject to change in the future!
Args: Args:
color: New thread color color: New thread color
""" """
data = { if color not in SETABLE_COLORS:
"color_choice": color.value if color != ThreadColor.MESSENGER_BLUE else "", raise ValueError(
"thread_or_other_fbid": self.id, "Invalid color! Please use one of: {}".format(SETABLE_COLORS)
} )
# Set color to "" if DEFAULT_COLOR. Just how the endpoint works...
if color == DEFAULT_COLOR:
color = ""
data = {"color_choice": color, "thread_or_other_fbid": self.id}
j = self.session._payload_post( j = self.session._payload_post(
"/messaging/save_thread_color/?source=thread_settings&dpr=1", data "/messaging/save_thread_color/?source=thread_settings&dpr=1", data
) )
# def set_theme(self, theme_id: str):
# data = {
# "client_mutation_id": "0",
# "actor_id": self.session.user_id,
# "thread_id": self.id,
# "theme_id": theme_id,
# "source": "SETTINGS",
# }
# j = self.session._graphql_requests(
# _graphql.from_doc_id("1768656253222505", {"data": data})
# )
def set_emoji(self, emoji: str): def set_emoji(self, emoji: str):
"""Change thread color. """Change thread emoji.
Args: Args:
emoji: New thread emoji emoji: New thread emoji
@@ -541,15 +560,22 @@ class ThreadABC(metaclass=abc.ABCMeta):
) )
return j return j
@staticmethod
def _parse_color(inp: Optional[str]) -> str:
if not inp:
return DEFAULT_COLOR
# Strip the alpha value, and lower the string
return "#{}".format(inp[2:].lower())
@staticmethod @staticmethod
def _parse_customization_info(data: Any) -> MutableMapping[str, Any]: def _parse_customization_info(data: Any) -> MutableMapping[str, Any]:
if data is None or data.get("customization_info") is None: if not data or not data.get("customization_info"):
return {} return {"emoji": None, "color": DEFAULT_COLOR}
info = data["customization_info"] info = data["customization_info"]
rtn = { rtn = {
"emoji": info.get("emoji"), "emoji": info.get("emoji"),
"color": ThreadColor._from_graphql(info.get("outgoing_bubble_color")), "color": ThreadABC._parse_color(info.get("outgoing_bubble_color")),
} }
if ( if (
data.get("thread_type") == "GROUP" data.get("thread_type") == "GROUP"

View File

@@ -1,5 +1,5 @@
import attr import attr
from ._core import log, attrs_default, Enum, Image from ._core import log, attrs_default, Image
from . import _util, _session, _plan, _thread from . import _util, _session, _plan, _thread
@@ -33,13 +33,6 @@ GENDERS = {
} }
class TypingStatus(Enum):
"""Used to specify whether the user is typing or has stopped typing."""
STOPPED = 0
TYPING = 1
@attrs_default @attrs_default
class User(_thread.ThreadABC): class User(_thread.ThreadABC):
"""Represents a Facebook user. Implements `ThreadABC`.""" """Represents a Facebook user. Implements `ThreadABC`."""
@@ -110,7 +103,7 @@ class UserData(User):
nickname = attr.ib(None) nickname = attr.ib(None)
#: The clients nickname, as seen by the user #: The clients nickname, as seen by the user
own_nickname = attr.ib(None) own_nickname = attr.ib(None)
#: A `ThreadColor`. The message color #: The message color
color = attr.ib(None) color = attr.ib(None)
#: The default emoji #: The default emoji
emoji = attr.ib(None) emoji = attr.ib(None)
@@ -136,8 +129,8 @@ class UserData(User):
gender=GENDERS.get(data["gender"]), gender=GENDERS.get(data["gender"]),
affinity=data.get("viewer_affinity"), affinity=data.get("viewer_affinity"),
nickname=c_info.get("nickname"), nickname=c_info.get("nickname"),
color=c_info.get("color"), color=c_info["color"],
emoji=c_info.get("emoji"), emoji=c_info["emoji"],
own_nickname=c_info.get("own_nickname"), own_nickname=c_info.get("own_nickname"),
photo=Image._from_uri(data["profile_picture"]), photo=Image._from_uri(data["profile_picture"]),
name=data["name"], name=data["name"],
@@ -186,8 +179,8 @@ class UserData(User):
is_friend=user["is_viewer_friend"], is_friend=user["is_viewer_friend"],
gender=GENDERS.get(user["gender"]), gender=GENDERS.get(user["gender"]),
nickname=c_info.get("nickname"), nickname=c_info.get("nickname"),
color=c_info.get("color"), color=c_info["color"],
emoji=c_info.get("emoji"), emoji=c_info["emoji"],
own_nickname=c_info.get("own_nickname"), own_nickname=c_info.get("own_nickname"),
photo=Image._from_uri(user["big_image_src"]), photo=Image._from_uri(user["big_image_src"]),
message_count=data["messages_count"], message_count=data["messages_count"],

View File

@@ -14,7 +14,6 @@ maintainer = "Mads Marquart"
maintainer-email = "madsmtm@gmail.com" maintainer-email = "madsmtm@gmail.com"
home-page = "https://github.com/carpedm20/fbchat/" home-page = "https://github.com/carpedm20/fbchat/"
requires = [ requires = [
"aenum~=2.0",
"attrs>=19.1", "attrs>=19.1",
"requests~=2.19", "requests~=2.19",
"beautifulsoup4~=4.0", "beautifulsoup4~=4.0",

View File

@@ -1,14 +0,0 @@
import pytest
from fbchat._core import Enum
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_enum_extend_if_invalid():
class TestEnum(Enum):
A = 1
B = 2
assert TestEnum._extend_if_invalid(1) == TestEnum.A
assert TestEnum._extend_if_invalid(3) == TestEnum.UNKNOWN_3
assert TestEnum._extend_if_invalid(3) == TestEnum.UNKNOWN_3
assert TestEnum(3) == TestEnum.UNKNOWN_3

View File

@@ -35,7 +35,7 @@ def test_group_from_graphql(session):
plan=None, plan=None,
participants={"1234", "2345", "3456"}, participants={"1234", "2345", "3456"},
nicknames={}, nicknames={},
color=None, color="#0084ff",
emoji="😀", emoji="😀",
admins={"1234"}, admins={"1234"},
approval_mode=False, approval_mode=False,

View File

@@ -1,16 +1,11 @@
import pytest import pytest
from fbchat import Message, MessageReaction from fbchat import Message
from utils import subset from utils import subset
pytestmark = pytest.mark.online pytestmark = pytest.mark.online
def test_set_reaction(client):
mid = client.send(Message(text="This message will be reacted to"))
client.react_to_message(mid, MessageReaction.LOVE)
def test_delete_messages(client): def test_delete_messages(client):
text1 = "This message will stay" text1 = "This message will stay"
text2 = "This message will be removed" text2 = "This message will be removed"

View File

@@ -1,20 +1,19 @@
import pytest import pytest
import fbchat import fbchat
from fbchat import ThreadColor, ThreadABC, Thread from fbchat import ThreadABC, Thread
def test_thread_color_from_graphql(): def test_parse_color():
assert None is ThreadColor._from_graphql(None) assert "#0084ff" == ThreadABC._parse_color(None)
assert ThreadColor.MESSENGER_BLUE is ThreadColor._from_graphql("") assert "#0084ff" == ThreadABC._parse_color("")
assert ThreadColor.VIKING is ThreadColor._from_graphql("FF44BEC7") assert "#44bec7" == ThreadABC._parse_color("FF44BEC7")
assert ThreadColor._from_graphql("DEADBEEF") is getattr( assert "#adbeef" == ThreadABC._parse_color("DEADBEEF")
ThreadColor, "UNKNOWN_#ADBEEF"
)
def test_thread_parse_customization_info_empty(): def test_thread_parse_customization_info_empty():
assert {} == ThreadABC._parse_customization_info(None) default = {"color": "#0084ff", "emoji": None}
assert {} == ThreadABC._parse_customization_info({"customization_info": None}) assert default == ThreadABC._parse_customization_info(None)
assert default == ThreadABC._parse_customization_info({"customization_info": None})
def test_thread_parse_customization_info_group(): def test_thread_parse_customization_info_group():
@@ -34,7 +33,7 @@ def test_thread_parse_customization_info_group():
} }
expected = { expected = {
"emoji": "🎉", "emoji": "🎉",
"color": ThreadColor.BRILLIANT_ROSE, "color": "#ff5ca1",
"nicknames": {"123456789": "A", "987654321": "B"}, "nicknames": {"123456789": "A", "987654321": "B"},
} }
assert expected == ThreadABC._parse_customization_info(data) assert expected == ThreadABC._parse_customization_info(data)
@@ -55,7 +54,7 @@ def test_thread_parse_customization_info_user():
"thread_type": "ONE_TO_ONE", "thread_type": "ONE_TO_ONE",
# ... Other irrelevant fields # ... Other irrelevant fields
} }
expected = {"emoji": None, "color": None, "own_nickname": "A", "nickname": "B"} expected = {"emoji": None, "color": "#0084ff", "own_nickname": "A", "nickname": "B"}
assert expected == ThreadABC._parse_customization_info(data) assert expected == ThreadABC._parse_customization_info(data)

View File

@@ -1,6 +1,6 @@
import pytest import pytest
from fbchat import Message, FBchatFacebookError, TypingStatus, ThreadColor from fbchat import Message, FBchatFacebookError
from utils import random_hex, subset from utils import random_hex, subset
from os import path from os import path
@@ -91,14 +91,10 @@ def test_change_image_remote(client1, group, catch_event):
) )
@pytest.mark.parametrize( def test_change_color(client, catch_event, compare):
"color",
[x for x in ThreadColor if x in [ThreadColor.MESSENGER_BLUE, ThreadColor.PUMPKIN]],
)
def test_change_color(client, catch_event, compare, color):
with catch_event("on_color_change") as x: with catch_event("on_color_change") as x:
client.change_thread_color(color) client.change_thread_color("#44bec7")
assert compare(x, new_color=color) assert compare(x, new_color="#44bec7")
@pytest.mark.xfail(raises=FBchatFacebookError, reason="Should fail, but doesn't") @pytest.mark.xfail(raises=FBchatFacebookError, reason="Should fail, but doesn't")
@@ -109,7 +105,7 @@ def test_change_color_invalid(client):
client.change_thread_color(InvalidColor()) client.change_thread_color(InvalidColor())
@pytest.mark.parametrize("status", TypingStatus) @pytest.mark.parametrize("status", [True, False])
def test_typing_status(client, catch_event, compare, status): def test_typing_status(client, catch_event, compare, status):
with catch_event("on_typing") as x: with catch_event("on_typing") as x:
client.set_typing_status(status) client.set_typing_status(status)

View File

@@ -27,6 +27,7 @@ def test_user_from_graphql(session):
is_friend=True, is_friend=True,
gender="female_singular", gender="female_singular",
affinity=0.4560002, affinity=0.4560002,
color="#0084ff",
) == UserData._from_graphql(session, data) ) == UserData._from_graphql(session, data)
@@ -152,7 +153,7 @@ def test_user_from_thread_fetch(session):
gender="female_singular", gender="female_singular",
nickname="A", nickname="A",
own_nickname="B", own_nickname="B",
color=None, color="#0084ff",
emoji=None, emoji=None,
) == UserData._from_thread_fetch(session, data) ) == UserData._from_thread_fetch(session, data)