def test_run_message_handler_for_bot(self): with patch('zulip_bots.lib.Client', new=FakeClient) as fake_client: mock_lib_module = MagicMock() # __file__ is not mocked by MagicMock(), so we assign a mock value manually. mock_lib_module.__file__ = "foo" mock_bot_handler = create_autospec(FakeBotHandler) mock_lib_module.handler_class.return_value = mock_bot_handler def call_on_each_event_mock(self, callback, event_types=None, narrow=None): def test_message(message, flags): event = {'message': message, 'flags': flags, 'type': 'message'} callback(event) # In the following test, expected_message is the dict that we expect # to be passed to the bot's handle_message function. original_message = {'content': '@**Alice** bar', 'type': 'stream'} expected_message = {'type': 'stream', 'content': 'bar', 'full_content': '@**Alice** bar'} test_message(original_message, {'mentioned'}) mock_bot_handler.handle_message.assert_called_with( message=expected_message, bot_handler=ANY) fake_client.call_on_each_event = call_on_each_event_mock.__get__( fake_client, fake_client.__class__) run_message_handler_for_bot(lib_module=mock_lib_module, quiet=True, config_file=None, bot_config_file=None, bot_name='testbot')
def main(): # type: () -> None options = parse_args() bot_name = options.name if options.path_to_bot: if options.provision: bot_dir = os.path.dirname(os.path.abspath(options.path_to_bot)) provision_bot(bot_dir, options.force) lib_module = import_module_from_source(options.path_to_bot, name=bot_name) elif options.name: if options.provision: current_dir = os.path.dirname(os.path.abspath(__file__)) bots_parent_dir = os.path.join(current_dir, "bots") bot_dir = os.path.join(bots_parent_dir, options.name) provision_bot(bot_dir, options.force) lib_module = import_module( 'zulip_bots.bots.{bot}.{bot}'.format(bot=bot_name)) if not options.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) run_message_handler_for_bot(lib_module=lib_module, config_file=options.config_file, quiet=options.quiet, bot_name=bot_name)
def main() -> None: args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ( "ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main() -> None: args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath(os.path.join(current_dir, 'bots', args.bot, args.bot+'.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ("ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name ) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main(): # type: () -> None (options, args) = parse_args() bot_name = args[0] lib_module = import_module( 'zulip_bots.bots.{bot}.{bot}'.format(bot=bot_name)) if not options.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) run_message_handler_for_bot(lib_module=lib_module, config_file=options.config_file, quiet=options.quiet)
def main(): # type: () -> None args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) lib_module = import_module_from_source(bot_path, bot_name) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_file_does_not_exist(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)
def main(): # type: () -> None args = parse_args() if os.path.isfile(args.bot): bot_path = os.path.abspath(args.bot) bot_name = os.path.splitext(basename(bot_path))[0] else: bot_path = os.path.abspath( os.path.join(current_dir, 'bots', args.bot, args.bot + '.py')) bot_name = args.bot if args.provision: provision_bot(os.path.dirname(bot_path), args.force) lib_module = import_module_from_source(bot_path, bot_name) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) run_message_handler_for_bot(lib_module=lib_module, config_file=args.config_file, quiet=args.quiet, bot_name=bot_name)
def test_run_message_handler_for_bot(self): with patch("zulip_bots.lib.Client", new=FakeClient) as fake_client: mock_lib_module = MagicMock() # __file__ is not mocked by MagicMock(), so we assign a mock value manually. mock_lib_module.__file__ = "foo" mock_bot_handler = create_autospec(FakeBotHandler) mock_lib_module.handler_class.return_value = mock_bot_handler def call_on_each_event_mock(self, callback, event_types=None, narrow=None): def test_message(message, flags): event = {"message": message, "flags": flags, "type": "message"} callback(event) # In the following test, expected_message is the dict that we expect # to be passed to the bot's handle_message function. original_message = {"content": "@**Alice** bar", "type": "stream"} expected_message = { "type": "stream", "content": "bar", "full_content": "@**Alice** bar", } test_message(original_message, {"mentioned"}) mock_bot_handler.handle_message.assert_called_with( message=expected_message, bot_handler=ANY ) fake_client.call_on_each_event = call_on_each_event_mock.__get__( fake_client, fake_client.__class__ ) run_message_handler_for_bot( lib_module=mock_lib_module, quiet=True, config_file=None, bot_config_file=None, bot_name="testbot", bot_source="bot code location", )
def main() -> None: args = parse_args() if args.registry: try: bot_source, lib_module = finder.import_module_from_zulip_bot_registry( args.bot) except finder.DuplicateRegisteredBotName as error: print( f'ERROR: Found duplicate entries for "{error}" in zulip bots registry.\n' "Make sure that you don't install bots using the same entry point. Exiting now." ) sys.exit(1) if lib_module: bot_name = args.bot else: result = finder.resolve_bot_path(args.bot) if result: bot_path, bot_name = result sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = finder.import_module_from_source( bot_path.as_posix(), bot_name) except ImportError: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ( "ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print( dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) bot_source = "source" else: lib_module = finder.import_module_by_name(args.bot) if lib_module: bot_name = lib_module.__name__ bot_source = "named module" if args.provision: print( "ERROR: Could not load bot's module for '{}'. Exiting now." ) sys.exit(1) if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_is_missing(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name, bot_source=bot_source, ) except NoBotConfigException: print(""" ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. """) sys.exit(1)
def main() -> None: args = parse_args() result = finder.resolve_bot_path(args.bot) if result: bot_path, bot_name = result sys.path.insert(0, os.path.dirname(bot_path)) if args.provision: provision_bot(os.path.dirname(bot_path), args.force) try: lib_module = finder.import_module_from_source(bot_path, bot_name) except ImportError as e: req_path = os.path.join(os.path.dirname(bot_path), "requirements.txt") with open(req_path) as fp: deps_list = fp.read() dep_err_msg = ("ERROR: The following dependencies for the {bot_name} bot are not installed:\n\n" "{deps_list}\n" "If you'd like us to install these dependencies, run:\n" " zulip-run-bot {bot_name} --provision") print(dep_err_msg.format(bot_name=bot_name, deps_list=deps_list)) sys.exit(1) else: lib_module = finder.import_module_by_name(args.bot) if lib_module: bot_name = lib_module.__name__ # Removed: Not needed as lib_module would have # been imported during runtime if control # flow reaches here. Adding any other provision # check after this would be unnecessary as # provision_bots require bot_path which # could not be found, hence result is None # and control is here. if lib_module is None: print("ERROR: Could not load bot module. Exiting now.") sys.exit(1) if not args.quiet: logging.basicConfig(stream=sys.stdout, level=logging.INFO) # It's a bit unfortunate that we have two config files, but the # alternative would be way worse for people running multiple bots # or testing against multiple Zulip servers. exit_gracefully_if_zulip_config_is_missing(args.config_file) exit_gracefully_if_bot_config_file_does_not_exist(args.bot_config_file) try: run_message_handler_for_bot( lib_module=lib_module, config_file=args.config_file, bot_config_file=args.bot_config_file, quiet=args.quiet, bot_name=bot_name ) except NoBotConfigException: print(''' ERROR: Your bot requires you to specify a third party config file with the --bot-config-file option. Exiting now. ''') sys.exit(1)