@@ -650,6 +650,188 @@ async def fake_inject(dependent: object) -> Bot: # noqa: ARG001
650650 assert msg .extract_plain_text () == "fallback help"
651651
652652
653+ async def test_func_detail_inherits_plugin_template (
654+ picmenu_plugin : object , # noqa: ARG001
655+ monkeypatch : "pytest.MonkeyPatch" ,
656+ ) -> None :
657+ from nonebot_plugin_alconna .uniseg import UniMessage
658+ from nonebot_plugin_picmenu_next import __main__
659+ from nonebot_plugin_picmenu_next .data_source .models import (
660+ PMDataItem ,
661+ PMNData ,
662+ PMNPluginInfo ,
663+ )
664+
665+ async def render_func_detail (
666+ pmn : PMNData ,
667+ func_template : str | None = None ,
668+ ) -> UniMessage | None :
669+ monkeypatch .setattr (__main__ , "resolve_main_mixin" , fake_resolve_main )
670+ monkeypatch .setattr (__main__ , "resolve_detail_mixin" , fake_resolve_detail )
671+ monkeypatch .setattr (
672+ __main__ ,
673+ "get_infos" ,
674+ lambda : [
675+ PMNPluginInfo (
676+ name = "继承模板插件" ,
677+ pmn = pmn ,
678+ pm_data = [
679+ PMDataItem (
680+ func = "继承模板功能" ,
681+ trigger_method = "继承模板功能" ,
682+ trigger_condition = "指令" ,
683+ brief_des = "测试继承插件模板" ,
684+ detail_des = "测试继承插件模板详情" ,
685+ pmn_template = func_template ,
686+ ),
687+ ],
688+ ),
689+ ],
690+ )
691+ monkeypatch .setitem (
692+ __main__ .func_detail_templates .data ,
693+ "default" ,
694+ default_func_detail ,
695+ )
696+ monkeypatch .setitem (
697+ __main__ .func_detail_templates .data ,
698+ "inherited" ,
699+ inherited_func_detail ,
700+ )
701+
702+ bot = cast ("Bot" , SimpleNamespace (adapter = SimpleNamespace ()))
703+ ev = cast ("Event" , SimpleNamespace ())
704+
705+ msg , _ , _ = await __main__ .render_menu (
706+ bot ,
707+ ev ,
708+ q_plugin = "1" ,
709+ q_function = "1" ,
710+ )
711+ return msg
712+
713+ async def fake_resolve_main (infos : list [PMNPluginInfo ]) -> list [PMNPluginInfo ]:
714+ return infos
715+
716+ async def fake_resolve_detail (info : PMNPluginInfo ) -> PMNPluginInfo :
717+ return info
718+
719+ async def default_func_detail (
720+ info : PMNPluginInfo , # noqa: ARG001
721+ info_index : int , # noqa: ARG001
722+ func : PMDataItem , # noqa: ARG001
723+ func_index : int | None , # noqa: ARG001
724+ showing_hidden : bool , # noqa: ARG001
725+ user_can_see_hidden : bool | None , # noqa: ARG001
726+ ) -> UniMessage :
727+ return UniMessage ("default template" )
728+
729+ async def inherited_func_detail (
730+ info : PMNPluginInfo ,
731+ info_index : int ,
732+ func : PMDataItem ,
733+ func_index : int | None ,
734+ showing_hidden : bool ,
735+ user_can_see_hidden : bool | None ,
736+ ) -> UniMessage :
737+ assert info .name == "继承模板插件"
738+ assert info_index == 0
739+ assert func .func == "继承模板功能"
740+ assert func_index == 0
741+ assert showing_hidden is False
742+ assert user_can_see_hidden is None
743+ return UniMessage ("inherited template" )
744+
745+ msg = await render_func_detail (PMNData (template = "inherited" ))
746+
747+ assert msg is not None
748+ assert msg .extract_plain_text () == "inherited template"
749+
750+
751+ async def test_func_detail_can_disable_plugin_template_inheritance (
752+ picmenu_plugin : object , # noqa: ARG001
753+ monkeypatch : "pytest.MonkeyPatch" ,
754+ ) -> None :
755+ from nonebot_plugin_alconna .uniseg import UniMessage
756+ from nonebot_plugin_picmenu_next import __main__
757+ from nonebot_plugin_picmenu_next .data_source .models import (
758+ PMDataItem ,
759+ PMNData ,
760+ PMNPluginInfo ,
761+ )
762+
763+ async def fake_resolve_main (infos : list [PMNPluginInfo ]) -> list [PMNPluginInfo ]:
764+ return infos
765+
766+ async def fake_resolve_detail (info : PMNPluginInfo ) -> PMNPluginInfo :
767+ return info
768+
769+ async def default_func_detail (
770+ info : PMNPluginInfo , # noqa: ARG001
771+ info_index : int , # noqa: ARG001
772+ func : PMDataItem , # noqa: ARG001
773+ func_index : int | None , # noqa: ARG001
774+ showing_hidden : bool , # noqa: ARG001
775+ user_can_see_hidden : bool | None , # noqa: ARG001
776+ ) -> UniMessage :
777+ return UniMessage ("default template" )
778+
779+ async def inherited_func_detail (
780+ info : PMNPluginInfo , # noqa: ARG001
781+ info_index : int , # noqa: ARG001
782+ func : PMDataItem , # noqa: ARG001
783+ func_index : int | None , # noqa: ARG001
784+ showing_hidden : bool , # noqa: ARG001
785+ user_can_see_hidden : bool | None , # noqa: ARG001
786+ ) -> UniMessage :
787+ return UniMessage ("inherited template" )
788+
789+ monkeypatch .setattr (__main__ , "resolve_main_mixin" , fake_resolve_main )
790+ monkeypatch .setattr (__main__ , "resolve_detail_mixin" , fake_resolve_detail )
791+ monkeypatch .setattr (
792+ __main__ ,
793+ "get_infos" ,
794+ lambda : [
795+ PMNPluginInfo (
796+ name = "禁用继承插件" ,
797+ pmn = PMNData (template = "inherited" , inherit_func_template = False ),
798+ pm_data = [
799+ PMDataItem (
800+ func = "禁用继承功能" ,
801+ trigger_method = "禁用继承功能" ,
802+ trigger_condition = "指令" ,
803+ brief_des = "测试关闭继承插件模板" ,
804+ detail_des = "测试关闭继承插件模板详情" ,
805+ ),
806+ ],
807+ ),
808+ ],
809+ )
810+ monkeypatch .setitem (
811+ __main__ .func_detail_templates .data ,
812+ "default" ,
813+ default_func_detail ,
814+ )
815+ monkeypatch .setitem (
816+ __main__ .func_detail_templates .data ,
817+ "inherited" ,
818+ inherited_func_detail ,
819+ )
820+
821+ bot = cast ("Bot" , SimpleNamespace (adapter = SimpleNamespace ()))
822+ ev = cast ("Event" , SimpleNamespace ())
823+
824+ msg , _ , _ = await __main__ .render_menu (
825+ bot ,
826+ ev ,
827+ q_plugin = "1" ,
828+ q_function = "1" ,
829+ )
830+
831+ assert msg is not None
832+ assert msg .extract_plain_text () == "default template"
833+
834+
653835async def test_help_extension_generates_current_command_when_visible_func_missing (
654836 picmenu_plugin : object , # noqa: ARG001
655837 monkeypatch : "pytest.MonkeyPatch" ,
0 commit comments