import pytest import json from utils import * from contextlib import contextmanager from fbchat import Message, Mention @pytest.fixture(scope="session") def session(): return object() # TODO: Add a mocked session @pytest.fixture(scope="session") def user(client2): return {"id": client2.id, "type": None} @pytest.fixture(scope="session") def group(pytestconfig): return { "id": load_variable("group_id", pytestconfig.cache), "type": None, } @pytest.fixture( scope="session", params=["user", "group", pytest.param("none", marks=[pytest.mark.xfail()])], ) def thread(request, user, group): return {"user": user, "group": group, "none": {"id": "0", "type": None},}[ request.param ] @pytest.fixture(scope="session") def client1(pytestconfig): with load_client(1, pytestconfig.cache) as c: yield c @pytest.fixture(scope="session") def client2(pytestconfig): with load_client(2, pytestconfig.cache) as c: yield c @pytest.fixture(scope="module") def client(client1, thread): # TODO: These are commented out since `setDefaultThread` is removed - But now any # test that use this fixture is likely broken! # client1.setDefaultThread(thread["id"], thread["type"]) yield client1 # client1.resetDefaultThread() @pytest.fixture(scope="session", params=["client1", "client2"]) def client_all(request, client1, client2): return client1 if request.param == "client1" else client2 @pytest.fixture(scope="session") def catch_event(client2): t = ClientThread(client2) t.start() @contextmanager def inner(method_name): caught = CaughtValue() old_method = getattr(client2, method_name) # Will be called by the other thread def catch_value(*args, **kwargs): old_method(*args, **kwargs) # Make sure the `set` is only called once if not caught.is_set(): caught.set(kwargs) setattr(client2, method_name, catch_value) yield caught caught.wait() if not caught.is_set(): raise ValueError("The value could not be caught") setattr(client2, method_name, old_method) yield inner t.should_stop.set() try: # Make the client send a messages to itself, so the blocking pull request will return # This is probably not safe, since the client is making two requests simultaneously client2.send(Message(text=random_hex()), client2.id) finally: t.join() @pytest.fixture(scope="module") def compare(client, thread): def inner(caught_event, **kwargs): d = { "author_id": client.id, "thread_id": client.id if thread["type"] == None else thread["id"], "thread_type": thread["type"], } d.update(kwargs) return subset(caught_event.res, **d) return inner @pytest.fixture(params=["me", "other", "me other"]) def message_with_mentions(request, client, client2, group): text = "Hi there [" mentions = [] if "me" in request.param: mentions.append(Mention(thread_id=client.id, offset=len(text), length=2)) text += "me, " if "other" in request.param: mentions.append(Mention(thread_id=client2.id, offset=len(text), length=5)) text += "other, " # Unused, because Facebook don't properly support sending mentions with groups as targets if "group" in request.param: mentions.append(Mention(thread_id=group["id"], offset=len(text), length=5)) text += "group, " text += "nothing]" return Message(text, mentions=mentions)