1515
1616if typing .TYPE_CHECKING :
1717 from sopel .config import Config
18- from sopel .tests .factories import BotFactory , IRCFactory , UserFactory
18+ from sopel .tests .factories import (
19+ BotFactory , ConfigFactory , IRCFactory , TriggerFactory , UserFactory ,
20+ )
1921 from sopel .tests .mocks import MockIRCServer
2022
2123
@@ -81,17 +83,17 @@ def ignored():
8183
8284
8385@pytest .fixture
84- def tmpconfig (configfactory ) :
86+ def tmpconfig (configfactory : ConfigFactory ) -> Config :
8587 return configfactory ('test.cfg' , TMP_CONFIG )
8688
8789
8890@pytest .fixture
89- def mockbot (tmpconfig , botfactory ) :
91+ def mockbot (tmpconfig : Config , botfactory : BotFactory ) -> bot . Sopel :
9092 return botfactory (tmpconfig )
9193
9294
9395@pytest .fixture
94- def mockplugin (tmpdir ):
96+ def mockplugin (tmpdir ) -> plugins . handlers . PyFilePlugin :
9597 root = tmpdir .mkdir ('loader_mods' )
9698 mod_file = root .join ('mockplugin.py' )
9799 mod_file .write (MOCK_MODULE_CONTENT )
@@ -676,7 +678,7 @@ def url_callback_http(bot, trigger, match):
676678# call_rule
677679
678680@pytest .fixture
679- def match_hello_rule (mockbot , triggerfactory ):
681+ def match_hello_rule (mockbot : bot . Sopel , triggerfactory : TriggerFactory ):
680682 """Helper for generating matches to each `Rule` in the following tests"""
681683 def _factory (rule_hello ):
682684 # trigger
@@ -694,7 +696,25 @@ def _factory(rule_hello):
694696 return _factory
695697
696698
697- def test_call_rule (mockbot , match_hello_rule ):
699+ @pytest .fixture
700+ def multimatch_hello_rule (mockbot : bot .Sopel , triggerfactory : TriggerFactory ):
701+ def _factory (rule_hello ):
702+ # trigger
703+ line = ':[email protected] PRIVMSG #channel :hello hello hello' 704+
705+ trigger = triggerfactory (mockbot , line )
706+ pretrigger = trigger ._pretrigger
707+
708+ for match in rule_hello .match (mockbot , pretrigger ):
709+ wrapper = bot .SopelWrapper (mockbot , trigger )
710+ yield match , trigger , wrapper
711+ return _factory
712+
713+
714+ def test_call_rule (
715+ mockbot : bot .Sopel ,
716+ match_hello_rule : typing .Callable ,
717+ ) -> None :
698718 # setup
699719 items = []
700720
@@ -721,9 +741,10 @@ def testrule(bot, trigger):
721741 assert items == [1 ]
722742
723743 # assert the rule is not rate limited
724- assert not rule_hello .is_user_rate_limited (Identifier ('Test' ))
725- assert not rule_hello .is_channel_rate_limited ('#channel' )
726- assert not rule_hello .is_global_rate_limited ()
744+ at_time = datetime .now (timezone .utc )
745+ assert not rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
746+ assert not rule_hello .is_channel_rate_limited ('#channel' , at_time )
747+ assert not rule_hello .is_global_rate_limited (at_time )
727748
728749 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
729750
@@ -738,6 +759,36 @@ def testrule(bot, trigger):
738759 assert items == [1 , 1 ]
739760
740761
762+ def test_call_rule_multiple_matches (
763+ mockbot : bot .Sopel ,
764+ multimatch_hello_rule : typing .Callable ,
765+ ) -> None :
766+ # setup
767+ items = []
768+
769+ def testrule (bot , trigger ):
770+ bot .say ('hi' )
771+ items .append (1 )
772+ return "Return Value"
773+
774+ find_hello = rules .FindRule (
775+ [re .compile (r'(hi|hello|hey|sup)' )],
776+ plugin = 'testplugin' ,
777+ label = 'testrule' ,
778+ handler = testrule )
779+
780+ for match , rule_trigger , wrapper in multimatch_hello_rule (find_hello ):
781+ mockbot .call_rule (find_hello , wrapper , rule_trigger )
782+
783+ # assert the rule has been executed three times now
784+ assert mockbot .backend .message_sent == rawlist (
785+ 'PRIVMSG #channel :hi' ,
786+ 'PRIVMSG #channel :hi' ,
787+ 'PRIVMSG #channel :hi' ,
788+ )
789+ assert items == [1 , 1 , 1 ]
790+
791+
741792def test_call_rule_rate_limited_user (mockbot , match_hello_rule ):
742793 items = []
743794
@@ -767,9 +818,10 @@ def testrule(bot, trigger):
767818 assert items == [1 ]
768819
769820 # assert the rule is now rate limited
770- assert rule_hello .is_user_rate_limited (Identifier ('Test' ))
771- assert not rule_hello .is_channel_rate_limited ('#channel' )
772- assert not rule_hello .is_global_rate_limited ()
821+ at_time = datetime .now (timezone .utc )
822+ assert rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
823+ assert not rule_hello .is_channel_rate_limited ('#channel' , at_time )
824+ assert not rule_hello .is_global_rate_limited (at_time )
773825
774826 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
775827
@@ -852,9 +904,10 @@ def testrule(bot, trigger):
852904 assert items == [1 ]
853905
854906 # assert the rule is now rate limited
855- assert not rule_hello .is_user_rate_limited (Identifier ('Test' ))
856- assert rule_hello .is_channel_rate_limited ('#channel' )
857- assert not rule_hello .is_global_rate_limited ()
907+ at_time = datetime .now (timezone .utc )
908+ assert not rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
909+ assert rule_hello .is_channel_rate_limited ('#channel' , at_time )
910+ assert not rule_hello .is_global_rate_limited (at_time )
858911
859912 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
860913
@@ -897,9 +950,10 @@ def testrule(bot, trigger):
897950 assert items == [1 ]
898951
899952 # assert the rule is now rate limited
900- assert not rule_hello .is_user_rate_limited (Identifier ('Test' ))
901- assert rule_hello .is_channel_rate_limited ('#channel' )
902- assert not rule_hello .is_global_rate_limited ()
953+ at_time = datetime .now (timezone .utc )
954+ assert not rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
955+ assert rule_hello .is_channel_rate_limited ('#channel' , at_time )
956+ assert not rule_hello .is_global_rate_limited (at_time )
903957
904958 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
905959
@@ -942,9 +996,10 @@ def testrule(bot, trigger):
942996 assert items == [1 ]
943997
944998 # assert the rule is now rate limited
945- assert not rule_hello .is_user_rate_limited (Identifier ('Test' ))
946- assert not rule_hello .is_channel_rate_limited ('#channel' )
947- assert rule_hello .is_global_rate_limited ()
999+ at_time = datetime .now (timezone .utc )
1000+ assert not rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
1001+ assert not rule_hello .is_channel_rate_limited ('#channel' , at_time )
1002+ assert rule_hello .is_global_rate_limited (at_time )
9481003
9491004 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
9501005
@@ -987,9 +1042,10 @@ def testrule(bot, trigger):
9871042 assert items == [1 ]
9881043
9891044 # assert the rule is now rate limited
990- assert not rule_hello .is_user_rate_limited (Identifier ('Test' ))
991- assert not rule_hello .is_channel_rate_limited ('#channel' )
992- assert rule_hello .is_global_rate_limited ()
1045+ at_time = datetime .now (timezone .utc )
1046+ assert not rule_hello .is_user_rate_limited (Identifier ('Test' ), at_time )
1047+ assert not rule_hello .is_channel_rate_limited ('#channel' , at_time )
1048+ assert rule_hello .is_global_rate_limited (at_time )
9931049
9941050 match , rule_trigger , wrapper = match_hello_rule (rule_hello )
9951051
0 commit comments