diff --git a/plugins/python/plugin_importer/plugin_importer.py b/plugins/python/plugin_importer/plugin_importer.py
--- a/plugins/python/plugin_importer/plugin_importer.py
+++ b/plugins/python/plugin_importer/plugin_importer.py
@@ -132,7 +132,8 @@
def get_source_module(self, name):
namelist = self.archive.namelist()
for filename in namelist:
- if filename.endswith('/%s/' % name):
+ if (filename.endswith('/%s/' % name)
+ or filename == '%s/' % name):
# Sanity check: There should be an __init__.py inside
if ('%s__init__.py' % filename) in namelist:
return filename
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo.desktop
@@ -0,0 +1,5 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_missing_keys_desktop_file/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_desktop_file/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_init_file/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=wrong_name
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_no_matching_plugindir/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.action
@@ -0,0 +1 @@
+this is wrong
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_action_file/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo.desktop
@@ -0,0 +1 @@
+this is wrong
\ No newline at end of file
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/fail_unparsable_desktop_file/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_nested/plugin/somedir/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_no_action/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.action b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_simple/plugin/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.action b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.action
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.action
@@ -0,0 +1,19 @@
+
+
+
+ Foo
+
+
+
+ Foo...
+
+
+
+ 0
+ 0
+
+ false
+
+
+
+
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.desktop b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.desktop
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo.desktop
@@ -0,0 +1,6 @@
+[Desktop Entry]
+Type=Service
+ServiceTypes=Krita/PythonPlugin
+X-KDE-Library=foo
+X-Python-2-Compatible=false
+Name=Foo
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/__init__.py b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/__init__.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/__init__.py
@@ -0,0 +1 @@
+print('hello')
diff --git a/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/foo.py b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/foo.py
new file mode 100644
--- /dev/null
+++ b/plugins/python/plugin_importer/tests/fixtures/success_toplevel/foo/foo.py
@@ -0,0 +1 @@
+print('foo')
diff --git a/plugins/python/plugin_importer/tests/test_plugin_importer.py b/plugins/python/plugin_importer/tests/test_plugin_importer.py
--- a/plugins/python/plugin_importer/tests/test_plugin_importer.py
+++ b/plugins/python/plugin_importer/tests/test_plugin_importer.py
@@ -1,37 +1,300 @@
+"""Unit tests for the plugin_importer module.
+
+Unit tests can either be toplevel functions whose names start with
+`test_`, or they can be class methods on classes derived from
+`unittest.TestCase`; again the method names need to start with `test_`.
+"""
+
+
import os
import pytest
from tempfile import TemporaryDirectory
-from unittest import TestCase
-
+from unittest import mock, TestCase
+from zipfile import ZipFile
-from .. plugin_importer import PluginImporter, PluginReadError
+from .. plugin_importer import (
+ NoPluginsFoundException,
+ PluginImporter,
+ PluginReadError,
+)
class PluginImporterTestCase(TestCase):
+ """Collection of unit tests for the plugin_importer module.
+
+ Since the tests need a bit of setup for file system operations, we gather
+ them together in a TestCase class.
+ """
def setUp(self):
+ """This method will be run before each test in this class.
+
+ We create temporary directories for creating and extracting
+ zip files: `resources_dir` will be the destination (a stand-in
+ for Krita's resources dir), `plugin_dir` the source where our
+ plugin zip is located.
+ """
+
self.resources_dir = TemporaryDirectory()
self.plugin_dir = TemporaryDirectory()
def tearDown(self):
+ """This method will be run after each test in this class.
+
+ We remove the temporary directories created in `setUp`.
+ """
+
self.resources_dir.cleanup()
self.plugin_dir.cleanup()
@property
def zip_filename(self):
- return os.path.join(
- self.resources_dir.name, 'plugin.zip')
+ """Helper method for easy access to the full path of the zipped
+ plugin.
+ """
+ return os.path.join(self.plugin_dir.name, 'plugin.zip')
+
+ def zip_plugin(self, dirname):
+ """Helper method to zip a plugin from the subdirectory `dirname` in
+ the `fixtures` folder and store it in the temporary directory
+ `self.plugin_dir`.
+
+ The `fixtures` directory contains the non-zipped plugins for easier
+ maintenance.
+ """
+
+ # Get the full name of the folder this file resides in:
+ testroot = os.path.dirname(os.path.realpath(__file__))
+
+ # From that, we can get the full name of the plugin fixture folder:
+ src = os.path.join(testroot, 'fixtures', dirname)
+
+ # Zip it:
+ with ZipFile(self.zip_filename, 'w') as plugin_zip:
+ for root, dirs, files in os.walk(src):
+ dirname = root.replace(src, '')
+ for filename in files + dirs:
+ plugin_zip.write(
+ filename=os.path.join(root, filename),
+ arcname=os.path.join(dirname, filename))
+
+ def assert_in_resources_dir(self, *path):
+ """Helper method to check whether a directory or file exists inside
+ `self.resources_dir`.
+ """
+
+ assert os.path.exists(os.path.join(self.resources_dir.name, *path))
+
+ def assert_not_in_resources_dir(self, *path):
+ """Helper method to check whether a directory or file doesn't exist
+ inside `self.resources_dir`.
+ """
+
+ assert not os.path.exists(os.path.join(self.resources_dir.name, *path))
+
+ ############################################################
+ # The actual tests start below
def test_zipfile_doesnt_exist(self):
+ """Test: Import a filename that doesn't exist."""
+
+ # Create nothing here...
+
with pytest.raises(PluginReadError):
+ # We expect an exception
PluginImporter(self.zip_filename,
self.resources_dir.name,
lambda x: True)
def test_zipfile_not_a_zip(self):
+ """Test: Import a file that isn't a zip file."""
+
+ # Create a text file:
with open(self.zip_filename, 'w') as f:
f.write('foo')
+
with pytest.raises(PluginReadError):
+ # We expect an exception
PluginImporter(self.zip_filename,
self.resources_dir.name,
lambda x: True)
+
+ def test_simple_plugin_success(self):
+ """Test: Import a basic plugin."""
+
+ self.zip_plugin('success_simple')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ imported = importer.import_all()
+ assert len(imported) == 1
+ self.assert_in_resources_dir('pykrita', 'foo')
+ self.assert_in_resources_dir('pykrita', 'foo', '__init__.py')
+ self.assert_in_resources_dir('pykrita', 'foo', 'foo.py')
+ self.assert_in_resources_dir('pykrita', 'foo.desktop')
+ self.assert_in_resources_dir('actions', 'foo.action')
+
+ def test_toplevel_plugin_success(self):
+ """Test: Import a plugin with everything at toplevel."""
+
+ self.zip_plugin('success_toplevel')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ imported = importer.import_all()
+ assert len(imported) == 1
+ self.assert_in_resources_dir('pykrita', 'foo')
+ self.assert_in_resources_dir('pykrita', 'foo', '__init__.py')
+ self.assert_in_resources_dir('pykrita', 'foo', 'foo.py')
+ self.assert_in_resources_dir('pykrita', 'foo.desktop')
+ self.assert_in_resources_dir('actions', 'foo.action')
+
+ def test_nested_plugin_success(self):
+ """Test: Import a plugin with nested directories."""
+
+ self.zip_plugin('success_nested')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ imported = importer.import_all()
+ assert len(imported) == 1
+ self.assert_in_resources_dir('pykrita', 'foo')
+ self.assert_in_resources_dir('pykrita', 'foo', '__init__.py')
+ self.assert_in_resources_dir('pykrita', 'foo', 'foo.py')
+ self.assert_in_resources_dir('pykrita', 'foo.desktop')
+ self.assert_in_resources_dir('actions', 'foo.action')
+
+ def test_no_action_success(self):
+ """Test: Import a plugin without action file.
+
+ Should import fine without creating an action file."""
+
+ self.zip_plugin('success_no_action')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ imported = importer.import_all()
+ assert len(imported) == 1
+ self.assert_in_resources_dir('pykrita', 'foo')
+ self.assert_in_resources_dir('pykrita', 'foo', '__init__.py')
+ self.assert_in_resources_dir('pykrita', 'foo', 'foo.py')
+ self.assert_in_resources_dir('pykrita', 'foo.desktop')
+ self.assert_not_in_resources_dir('actions', 'foo.action')
+
+ def test_overwrite_existing(self):
+ """Test: Overwrite an existing plugin when overwrite confirmed."""
+
+ self.zip_plugin('success_simple')
+
+ # Create an existing python module in the the resources directory:
+ plugin_dir = os.path.join(self.resources_dir.name, 'pykrita', 'foo')
+ os.makedirs(plugin_dir)
+ init_file = os.path.join(plugin_dir, '__init__.py')
+ with open(init_file, 'w') as f:
+ f.write('# existing module')
+
+ # Create a mock callback on which we can test that it has been called:
+ confirm_callback = mock.MagicMock(return_value=True)
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ confirm_callback)
+ imported = importer.import_all()
+ assert len(imported) == 1
+ assert confirm_callback.called
+
+ # Existing plugin should be overwritten:
+ with open(init_file, 'r') as f:
+ assert f.read().strip() == "print('hello')"
+
+ def test_dont_overwrite_existing(self):
+ """Test: Don't overwrite an existing plugin when overwrite not
+ confirmed."""
+
+ self.zip_plugin('success_simple')
+
+ # Create an existing python module in the the resources directory:
+ plugin_dir = os.path.join(self.resources_dir.name, 'pykrita', 'foo')
+ os.makedirs(plugin_dir)
+ init_file = os.path.join(plugin_dir, '__init__.py')
+ with open(init_file, 'w') as f:
+ f.write('# existing module')
+
+ # Create a mock callback on which we can test that it has been called:
+ confirm_callback = mock.MagicMock(return_value=False)
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ confirm_callback)
+ imported = importer.import_all()
+ assert len(imported) == 0
+ assert confirm_callback.called
+
+ # Existing plugin should not be overwritten:
+ with open(init_file, 'r') as f:
+ assert f.read().strip() == '# existing module'
+
+ def test_missing_desktop_file(self):
+ """Test: Import plugin without a desktop file."""
+
+ self.zip_plugin('fail_no_desktop_file')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(NoPluginsFoundException):
+ # We expect an exception
+ importer.import_all()
+
+ def test_unparsable_desktop_file(self):
+ """Test: Import plugin whose desktop file is not parsable."""
+
+ self.zip_plugin('fail_unparsable_desktop_file')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(PluginReadError):
+ # We expect an exception
+ importer.import_all()
+
+ def test_missing_keys_in_desktop_file(self):
+ """Test: Import plugin whose destkop file is missing needed keys."""
+
+ self.zip_plugin('fail_missing_keys_desktop_file')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(PluginReadError):
+ # We expect an exception
+ importer.import_all()
+
+ def test_no_matching_plugindir(self):
+ """Test: Import plugin whose destkop file is missing needed keys."""
+
+ self.zip_plugin('fail_no_matching_plugindir')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(NoPluginsFoundException):
+ # We expect an exception
+ importer.import_all()
+
+ def test_no_init_file(self):
+ """Test: Import plugin whose python module is missing the __init__.py
+ file."""
+
+ self.zip_plugin('fail_no_init_file')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(NoPluginsFoundException):
+ # We expect an exception
+ importer.import_all()
+
+ def test_unparsable_action_file(self):
+ """Test: Import plugin whose action file isn't parsable."""
+
+ self.zip_plugin('fail_unparsable_action_file')
+ importer = PluginImporter(self.zip_filename,
+ self.resources_dir.name,
+ lambda x: True)
+ with pytest.raises(PluginReadError):
+ # We expect an exception
+ importer.import_all()