import click,pytest import zipfile,urllib,os,shutil from click.testing import CliRunner from flaskbb.cli import main as cli_main from flaskbb import plugins from flaskbb.extensions import db from importlib import import_module def test_new_plugin(tmpdir,application,monkeypatch): runner=CliRunner() #download the cookiecutter file to use locally (bypasses prompt about re-cloning) zipfilename=str(tmpdir.join('cookiecutter.zip')) urllib.urlretrieve('https://github.com/sh4nks/cookiecutter-flaskbb-plugin/archive/master.zip', zipfilename) with zipfile.ZipFile(zipfilename) as zf: zf.extractall(str(tmpdir)) cookiecutterpath = tmpdir.join('cookiecutter-flaskbb-plugin-master') tmp_plugin_folder=str(tmpdir.join('plugin_folder')) os.mkdir(tmp_plugin_folder) monkeypatch.setattr(cli_main,'create_app',lambda s: application) monkeypatch.setattr(application.extensions['plugin_manager'],'plugin_folder',tmp_plugin_folder) input='\n'.join([ 'Test Name', 'someone@nowhere.com', 'Testing Plugin', '', 'TestingPlugin', 'Straightforward Test Plugin', 'www.example.com', '1.0.0']) result=runner.invoke(cli_main.flaskbb,['plugins','new','testplugin','--template',str(cookiecutterpath)],input=input) assert result.exit_code == 0 plugin_dir = os.path.join(application.extensions['plugin_manager'].plugin_folder, 'testing_plugin') assert os.path.exists(plugin_dir) assert os.path.isdir(plugin_dir) #add the temporary folder to the plugins path so import flaskbb.plugins.test_plugin works as expected monkeypatch.setattr(plugins,'__path__',plugins.__path__+[tmp_plugin_folder]) assert import_module('flaskbb.plugins.testing_plugin').__plugin__=='TestingPlugin' def test_migrate_plugin(tmpdir,monkeypatch,application): pluginmanager = application.extensions['plugin_manager'] orig_plugin_folder=pluginmanager.plugin_folder tmp_plugin_folder = str(tmpdir.join('plugin_folder')) os.mkdir(tmp_plugin_folder) shutil.copytree(os.path.join(orig_plugin_folder,'_migration_environment'),os.path.join(tmp_plugin_folder,'_migration_environment')) os.mkdir(os.path.join(tmp_plugin_folder,'testplugin')) with open(os.path.join(tmp_plugin_folder,'testplugin','__init__.py'),'w') as pyfile: pyfile.write('\r\n'.join([ "from flaskbb.plugins import FlaskBBPlugin", "from flaskbb.extensions import db", "class TestPlugin(FlaskBBPlugin):", " settings_key='testplugin'", " def somequery(self):", " TestModel.query.all()", "class TestModel(db.Model):", " __tablename__='testtable'", " testkey=db.Column(db.Integer,primary_key=True)", "", "__plugin__='TestPlugin'", ])) import json jsoninfo={ "identifier": "testplugin", "name": "TestPlugin", "author": "sh4nks", "website": "http://flaskbb.org", "license": "BSD", "description": "A Test Plugin for FlaskBB", "version": "0.1" } with open(os.path.join(tmp_plugin_folder,'testplugin','info.json'),'w') as jsonfile: json.dump(jsoninfo,jsonfile) monkeypatch.setattr(cli_main, 'create_app', lambda s: application) monkeypatch.setattr(pluginmanager, 'plugin_folder', tmp_plugin_folder) # add the temporary folder to the plugins path so import flaskbb.plugins.test_plugin works as expected monkeypatch.setattr(plugins, '__path__', plugins.__path__ + [tmp_plugin_folder]) pluginmanager._plugins=None pluginmanager._all_plugins = None pluginmanager._available_plugins = dict() pluginmanager._found_plugins = dict() pluginmanager.setup_plugins() assert 'testplugin' in pluginmanager.plugins versionsdir=os.path.join(tmp_plugin_folder,'testplugin','migration_versions') assert not os.path.exists(versionsdir) testplugin=pluginmanager.plugins['testplugin'] with application.app_context(): testplugin.migrate() assert os.path.exists(versionsdir) dirlist = os.listdir(versionsdir) assert dirlist dirlist=[os.path.join(versionsdir,d) for d in dirlist if d.endswith('.py')] for d in dirlist: with open(d,'r') as f: output='\n'.join([l for l in f]) assert 'testtable' in output with pytest.raises(Exception,message='Should not be able to run migrations twice'): testplugin.migrate() with pytest.raises(Exception,message='Operations should fail as model not yet registered'): testplugin.somequery() testplugin.upgrade_database()