from pathlib import Path import sys from nonebug import App import pytest from nonebot import get_plugin from nonebot.matcher import Matcher, matchers from nonebot.message import _check_matcher, check_and_run_matcher from nonebot.permission import Permission, User from nonebot.rule import Rule from utils import FakeMessage, make_fake_event def test_matcher_info(app: App): from plugins.matcher.matcher_info import matcher assert issubclass(matcher, Matcher) assert matcher.type == "message" assert matcher.priority == 1 assert matcher.temp is False assert matcher.expire_time is None assert matcher.block is True assert matcher._source assert matcher._source.module_name == "plugins.matcher.matcher_info" assert matcher.module is sys.modules["plugins.matcher.matcher_info"] assert matcher.module_name == "plugins.matcher.matcher_info" assert matcher._source.plugin_id == "matcher:matcher_info" assert matcher._source.plugin_name == "matcher_info" assert matcher.plugin is get_plugin("matcher:matcher_info") assert matcher.plugin_id == "matcher:matcher_info" assert matcher.plugin_name == "matcher_info" assert ( matcher._source.file == (Path(__file__).parent.parent / "plugins/matcher/matcher_info.py").absolute() ) assert matcher._source.lineno == 3 @pytest.mark.anyio async def test_matcher_check(app: App): async def falsy(): return False async def truthy(): return True async def error(): raise RuntimeError event = make_fake_event(_type="test")() with app.provider.context({}): test_perm_falsy = Matcher.new(permission=Permission(falsy)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_perm_falsy, bot, event, {}) is False test_perm_truthy = Matcher.new(permission=Permission(truthy)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_perm_truthy, bot, event, {}) is True test_perm_error = Matcher.new(permission=Permission(error)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_perm_error, bot, event, {}) is False test_rule_falsy = Matcher.new(rule=Rule(falsy)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_rule_falsy, bot, event, {}) is False test_rule_truthy = Matcher.new(rule=Rule(truthy)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_rule_truthy, bot, event, {}) is True test_rule_error = Matcher.new(rule=Rule(error)) async with app.test_api() as ctx: bot = ctx.create_bot() assert await _check_matcher(test_rule_error, bot, event, {}) is False @pytest.mark.anyio async def test_matcher_handle(app: App): from plugins.matcher.matcher_process import test_handle message = FakeMessage("text") event = make_fake_event(_message=message)() assert len(test_handle.handlers) == 1 async with app.test_matcher(test_handle) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.should_call_send(event, "send", "result", at_sender=True) ctx.should_finished() @pytest.mark.anyio async def test_matcher_got(app: App): from plugins.matcher.matcher_process import test_got message = FakeMessage("text") event = make_fake_event(_message=message)() message_next = FakeMessage("text_next") event_next = make_fake_event(_message=message_next)() assert len(test_got.handlers) == 1 async with app.test_matcher(test_got) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.should_call_send(event, "prompt key1", "result1") ctx.receive_event(bot, event) ctx.should_call_send(event, "prompt key2", "result2") ctx.receive_event(bot, event) ctx.should_call_send(event, "reject", "result3", at_sender=True) ctx.should_rejected() ctx.receive_event(bot, event_next) @pytest.mark.anyio async def test_matcher_receive(app: App): from plugins.matcher.matcher_process import test_receive message = FakeMessage("text") event = make_fake_event(_message=message)() assert len(test_receive.handlers) == 1 async with app.test_matcher(test_receive) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.receive_event(bot, event) ctx.receive_event(bot, event) ctx.should_call_send(event, "pause", "result", at_sender=True) ctx.should_paused() @pytest.mark.anyio async def test_matcher_combine(app: App): from plugins.matcher.matcher_process import test_combine message = FakeMessage("text") event = make_fake_event(_message=message)() message_next = FakeMessage("text_next") event_next = make_fake_event(_message=message_next)() assert len(test_combine.handlers) == 1 async with app.test_matcher(test_combine) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.receive_event(bot, event) ctx.receive_event(bot, event) ctx.should_rejected() ctx.receive_event(bot, event_next) ctx.should_rejected() ctx.receive_event(bot, event_next) ctx.should_rejected() ctx.receive_event(bot, event_next) @pytest.mark.anyio async def test_matcher_preset(app: App): from plugins.matcher.matcher_process import test_preset message = FakeMessage("text") event = make_fake_event(_message=message)() message_next = FakeMessage("text_next") event_next = make_fake_event(_message=message_next)() assert len(test_preset.handlers) == 2 async with app.test_matcher(test_preset) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.receive_event(bot, event) ctx.should_rejected() ctx.receive_event(bot, event_next) @pytest.mark.anyio async def test_matcher_overload(app: App): from plugins.matcher.matcher_process import test_overload message = FakeMessage("text") event = make_fake_event(_message=message)() assert len(test_overload.handlers) == 2 async with app.test_matcher(test_overload) as ctx: bot = ctx.create_bot() ctx.receive_event(bot, event) ctx.should_finished() @pytest.mark.anyio async def test_matcher_destroy(app: App): from plugins.matcher.matcher_process import test_destroy async with app.test_matcher(test_destroy): assert len(matchers) == 1 assert len(matchers[test_destroy.priority]) == 1 assert matchers[test_destroy.priority][0] is test_destroy test_destroy.destroy() assert len(matchers[test_destroy.priority]) == 0 @pytest.mark.anyio async def test_type_updater(app: App): from plugins.matcher.matcher_type import test_custom_updater, test_type_updater event = make_fake_event()() assert test_type_updater.type == "test" async with app.test_api() as ctx: bot = ctx.create_bot() matcher = test_type_updater() new_type = await matcher.update_type(bot, event) assert new_type == "message" assert test_custom_updater.type == "test" async with app.test_api() as ctx: bot = ctx.create_bot() matcher = test_custom_updater() new_type = await matcher.update_type(bot, event) assert new_type == "custom" @pytest.mark.anyio async def test_default_permission_updater(app: App): from plugins.matcher.matcher_permission import ( default_permission, test_permission_updater, ) event = make_fake_event(_session_id="test")() assert test_permission_updater.permission is default_permission async with app.test_api() as ctx: bot = ctx.create_bot() matcher = test_permission_updater() new_perm = await matcher.update_permission(bot, event) assert len(new_perm.checkers) == 1 checker = next(iter(new_perm.checkers)).call assert isinstance(checker, User) assert checker.users == ("test",) assert checker.perm is default_permission @pytest.mark.anyio async def test_user_permission_updater(app: App): from plugins.matcher.matcher_permission import ( default_permission, test_user_permission_updater, ) event = make_fake_event(_session_id="test")() user_permission = next(iter(test_user_permission_updater.permission.checkers)).call assert isinstance(user_permission, User) assert user_permission.perm is default_permission async with app.test_api() as ctx: bot = ctx.create_bot() matcher = test_user_permission_updater() new_perm = await matcher.update_permission(bot, event) assert len(new_perm.checkers) == 1 checker = next(iter(new_perm.checkers)).call assert isinstance(checker, User) assert checker.users == ("test",) assert checker.perm is default_permission @pytest.mark.anyio async def test_custom_permission_updater(app: App): from plugins.matcher.matcher_permission import ( default_permission, new_permission, test_custom_updater, ) event = make_fake_event(_session_id="test")() assert test_custom_updater.permission is default_permission async with app.test_api() as ctx: bot = ctx.create_bot() matcher = test_custom_updater() new_perm = await matcher.update_permission(bot, event) assert new_perm is new_permission @pytest.mark.anyio async def test_run(app: App): with app.provider.context({}): assert not matchers event = make_fake_event()() async def reject(): await Matcher.reject() test_reject = Matcher.new(handlers=[reject]) async with app.test_api() as ctx: bot = ctx.create_bot() await test_reject().run(bot, event, {}) assert len(matchers[0]) == 1 assert len(matchers[0][0].handlers) == 1 del matchers[0] async def pause(): await Matcher.pause() test_pause = Matcher.new(handlers=[pause]) async with app.test_api() as ctx: bot = ctx.create_bot() await test_pause().run(bot, event, {}) assert len(matchers[0]) == 1 assert len(matchers[0][0].handlers) == 0 @pytest.mark.anyio async def test_temp(app: App): from plugins.matcher.matcher_expire import test_temp_matcher event = make_fake_event(_type="test")() with app.provider.context({test_temp_matcher.priority: [test_temp_matcher]}): async with app.test_api() as ctx: bot = ctx.create_bot() assert test_temp_matcher in matchers[test_temp_matcher.priority] await check_and_run_matcher(test_temp_matcher, bot, event, {}) assert test_temp_matcher not in matchers[test_temp_matcher.priority] @pytest.mark.anyio async def test_datetime_expire(app: App): from plugins.matcher.matcher_expire import test_datetime_matcher event = make_fake_event()() with app.provider.context( {test_datetime_matcher.priority: [test_datetime_matcher]} ): async with app.test_matcher(test_datetime_matcher) as ctx: bot = ctx.create_bot() assert test_datetime_matcher in matchers[test_datetime_matcher.priority] await check_and_run_matcher(test_datetime_matcher, bot, event, {}) assert test_datetime_matcher not in matchers[test_datetime_matcher.priority] @pytest.mark.anyio async def test_timedelta_expire(app: App): from plugins.matcher.matcher_expire import test_timedelta_matcher event = make_fake_event()() with app.provider.context( {test_timedelta_matcher.priority: [test_timedelta_matcher]} ): async with app.test_api() as ctx: bot = ctx.create_bot() assert test_timedelta_matcher in matchers[test_timedelta_matcher.priority] await check_and_run_matcher(test_timedelta_matcher, bot, event, {}) assert ( test_timedelta_matcher not in matchers[test_timedelta_matcher.priority] )