test_plugins.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import click,pytest
  2. import zipfile,urllib,os,shutil
  3. from click.testing import CliRunner
  4. from flaskbb.cli import main as cli_main
  5. from flaskbb import plugins
  6. from flaskbb.extensions import db
  7. from importlib import import_module
  8. def test_new_plugin(tmpdir,application,monkeypatch):
  9. runner=CliRunner()
  10. #download the cookiecutter file to use locally (bypasses prompt about re-cloning)
  11. zipfilename=str(tmpdir.join('cookiecutter.zip'))
  12. urllib.urlretrieve('https://github.com/sh4nks/cookiecutter-flaskbb-plugin/archive/master.zip', zipfilename)
  13. with zipfile.ZipFile(zipfilename) as zf:
  14. zf.extractall(str(tmpdir))
  15. cookiecutterpath = tmpdir.join('cookiecutter-flaskbb-plugin-master')
  16. tmp_plugin_folder=str(tmpdir.join('plugin_folder'))
  17. os.mkdir(tmp_plugin_folder)
  18. monkeypatch.setattr(cli_main,'create_app',lambda s: application)
  19. monkeypatch.setattr(application.extensions['plugin_manager'],'plugin_folder',tmp_plugin_folder)
  20. input='\n'.join([
  21. 'Test Name',
  22. 'someone@nowhere.com',
  23. 'Testing Plugin',
  24. '',
  25. 'TestingPlugin',
  26. 'Straightforward Test Plugin',
  27. 'www.example.com',
  28. '1.0.0'])
  29. result=runner.invoke(cli_main.flaskbb,['plugins','new','testplugin','--template',str(cookiecutterpath)],input=input)
  30. assert result.exit_code == 0
  31. plugin_dir = os.path.join(application.extensions['plugin_manager'].plugin_folder, 'testing_plugin')
  32. assert os.path.exists(plugin_dir)
  33. assert os.path.isdir(plugin_dir)
  34. #add the temporary folder to the plugins path so import flaskbb.plugins.test_plugin works as expected
  35. monkeypatch.setattr(plugins,'__path__',plugins.__path__+[tmp_plugin_folder])
  36. assert import_module('flaskbb.plugins.testing_plugin').__plugin__=='TestingPlugin'
  37. def test_migrate_plugin(tmpdir,monkeypatch,application):
  38. pluginmanager = application.extensions['plugin_manager']
  39. orig_plugin_folder=pluginmanager.plugin_folder
  40. tmp_plugin_folder = str(tmpdir.join('plugin_folder'))
  41. os.mkdir(tmp_plugin_folder)
  42. shutil.copytree(os.path.join(orig_plugin_folder,'_migration_environment'),os.path.join(tmp_plugin_folder,'_migration_environment'))
  43. os.mkdir(os.path.join(tmp_plugin_folder,'testplugin'))
  44. with open(os.path.join(tmp_plugin_folder,'testplugin','__init__.py'),'w') as pyfile:
  45. pyfile.write('\r\n'.join([
  46. "from flaskbb.plugins import FlaskBBPlugin",
  47. "from flaskbb.extensions import db",
  48. "class TestPlugin(FlaskBBPlugin):",
  49. " settings_key='testplugin'",
  50. " def somequery(self):",
  51. " TestModel.query.all()",
  52. "class TestModel(db.Model):",
  53. " __tablename__='testtable'",
  54. " testkey=db.Column(db.Integer,primary_key=True)",
  55. "",
  56. "__plugin__='TestPlugin'",
  57. ]))
  58. import json
  59. jsoninfo={
  60. "identifier": "testplugin",
  61. "name": "TestPlugin",
  62. "author": "sh4nks",
  63. "website": "http://flaskbb.org",
  64. "license": "BSD",
  65. "description": "A Test Plugin for FlaskBB",
  66. "version": "0.1"
  67. }
  68. with open(os.path.join(tmp_plugin_folder,'testplugin','info.json'),'w') as jsonfile:
  69. json.dump(jsoninfo,jsonfile)
  70. monkeypatch.setattr(cli_main, 'create_app', lambda s: application)
  71. monkeypatch.setattr(pluginmanager, 'plugin_folder', tmp_plugin_folder)
  72. # add the temporary folder to the plugins path so import flaskbb.plugins.test_plugin works as expected
  73. monkeypatch.setattr(plugins, '__path__', plugins.__path__ + [tmp_plugin_folder])
  74. pluginmanager._plugins=None
  75. pluginmanager._all_plugins = None
  76. pluginmanager._available_plugins = dict()
  77. pluginmanager._found_plugins = dict()
  78. pluginmanager.setup_plugins()
  79. assert 'testplugin' in pluginmanager.plugins
  80. versionsdir=os.path.join(tmp_plugin_folder,'testplugin','migration_versions')
  81. assert not os.path.exists(versionsdir)
  82. testplugin=pluginmanager.plugins['testplugin']
  83. with application.app_context():
  84. testplugin.migrate()
  85. assert os.path.exists(versionsdir)
  86. dirlist = os.listdir(versionsdir)
  87. assert dirlist
  88. dirlist=[os.path.join(versionsdir,d) for d in dirlist if d.endswith('.py')]
  89. for d in dirlist:
  90. with open(d,'r') as f:
  91. output='\n'.join([l for l in f])
  92. assert 'testtable' in output
  93. with pytest.raises(Exception,message='Should not be able to run migrations twice'):
  94. testplugin.migrate()
  95. with pytest.raises(Exception,message='Operations should fail as model not yet registered'):
  96. testplugin.somequery()
  97. testplugin.upgrade_database()