class ExtensionsTest(TestCase): def create_app(self): self.app = Flask("test_extensions") self.dir = os.path.join(os.path.dirname(__file__)) self.senpy = Senpy(plugin_folder=self.dir, default_plugins=False) self.senpy.init_app(self.app) self.senpy.activate_plugin("Dummy", sync=True) return self.app def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember assert self.dir in self.senpy._search_folders print(self.senpy.plugins) assert "Dummy" in self.senpy.plugins def test_enabling(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins) == 2 assert self.senpy.plugins["Sleep"].is_activated def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.plugins["Dummy"].is_activated assert not self.senpy.plugins["Sleep"].is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "Dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) self.assertRaises(Error, partial(self.senpy.analyse, input="tupni")) def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = self.senpy.analyse( algorithm="Dummy", input="tupni", output="tuptuo") r2 = self.senpy.analyse(input="tupni", output="tuptuo") assert r1.analysis[0].id[:5] == "Dummy" assert r2.analysis[0].id[:5] == "Dummy" def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.filter_plugins(name="Dummy")) > 0 assert not len(self.senpy.filter_plugins(name="notdummy")) assert self.senpy.filter_plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len( self.senpy.filter_plugins(name="Dummy", is_activated=True))
class ExtensionsTest(TestCase): def setUp(self): self.app = Flask("test_extensions") self.dir = os.path.join(os.path.dirname(__file__)) self.senpy = Senpy(plugin_folder=self.dir, default_plugins=False) self.senpy.init_app(self.app) self.senpy.activate_plugin("Dummy", sync=True) def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember assert self.dir in self.senpy._search_folders print(self.senpy.plugins) assert "Dummy" in self.senpy.plugins def test_enabling(self): """ Enabling a plugin """ info = { 'name': 'TestPip', 'module': 'dummy', 'requirements': ['noop'], 'version': 0 } root = os.path.join(self.dir, 'dummy_plugin') name, module = self.senpy._load_plugin_from_info(info, root=root) assert name == 'TestPip' assert module import noop def test_installing(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins) == 2 assert self.senpy.plugins["Sleep"].is_activated def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.plugins["Dummy"].is_activated assert not self.senpy.plugins["Sleep"].is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "Dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) self.assertRaises(Error, partial(self.senpy.analyse, input="tupni")) def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = self.senpy.analyse(algorithm="Dummy", input="tupni", output="tuptuo") r2 = self.senpy.analyse(input="tupni", output="tuptuo") assert r1.analysis[0].id[:5] == "Dummy" assert r2.analysis[0].id[:5] == "Dummy" def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.filter_plugins(name="Dummy")) > 0 assert not len(self.senpy.filter_plugins(name="notdummy")) assert self.senpy.filter_plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len( self.senpy.filter_plugins(name="Dummy", is_activated=True))
class ExtensionsTest(TestCase): def setUp(self): self.app = Flask('test_extensions') self.dir = os.path.dirname(__file__) self.senpy = Senpy(plugin_folder=self.dir, app=self.app, default_plugins=False) self.senpy.activate_plugin("Dummy", sync=True) def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember assert self.dir in self.senpy._search_folders print(self.senpy.plugins) assert "Dummy" in self.senpy.plugins def test_installing(self): """ Installing a plugin """ info = { 'name': 'TestPip', 'module': 'dummy', 'description': None, 'requirements': ['noop'], 'version': 0 } root = os.path.join(self.dir, 'plugins', 'dummy_plugin') module = plugins.load_plugin_from_info(info, root=root) plugins.install_deps(info) assert module.name == 'TestPip' assert module import noop dir(noop) def test_enabling(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins) >= 3 assert self.senpy.plugins["Sleep"].is_activated def test_installing_nonexistent(self): """ Fail if the dependencies cannot be met """ info = { 'name': 'TestPipFail', 'module': 'dummy', 'description': None, 'requirements': ['IAmMakingThisPackageNameUpToFail'], 'version': 0 } with self.assertRaises(Error): plugins.install_deps(info) def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.plugins["Dummy"].is_activated assert not self.senpy.plugins["Sleep"].is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "Dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) self.assertRaises(Error, partial(analyse, self.senpy, input="tupni")) def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = analyse(self.senpy, algorithm="Dummy", input="tupni", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.analysis[0] == "plugins/Dummy_0.1" assert r2.analysis[0] == "plugins/Dummy_0.1" assert r1.entries[0]['nif:iString'] == 'input' def test_analyse_jsonld(self): """ Using a plugin with JSON-LD input""" js_input = '''{ "@id": "prueba", "@type": "results", "entries": [ {"@id": "entry1", "nif:isString": "tupni", "@type": "entry" } ] }''' r1 = analyse(self.senpy, algorithm="Dummy", input=js_input, informat="json-ld", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.analysis[0] == "plugins/Dummy_0.1" assert r2.analysis[0] == "plugins/Dummy_0.1" assert r1.entries[0]['nif:iString'] == 'input' def test_analyse_error(self): mm = mock.MagicMock() mm.id = 'magic_mock' mm.is_activated = True mm.analyse_entries.side_effect = Error('error in analysis', status=500) self.senpy.plugins['MOCK'] = mm try: analyse(self.senpy, input='nothing', algorithm='MOCK') assert False except Error as ex: assert 'error in analysis' in ex['message'] assert ex['status'] == 500 mm.analyse.side_effect = Exception('generic exception on analysis') mm.analyse_entries.side_effect = Exception( 'generic exception on analysis') try: analyse(self.senpy, input='nothing', algorithm='MOCK') assert False except Error as ex: assert 'generic exception on analysis' in ex['message'] assert ex['status'] == 500 def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.filter_plugins(name="Dummy")) > 0 assert not len(self.senpy.filter_plugins(name="notdummy")) assert self.senpy.filter_plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len( self.senpy.filter_plugins(name="Dummy", is_activated=True)) def test_load_default_plugins(self): senpy = Senpy(plugin_folder=self.dir, default_plugins=True) assert len(senpy.plugins) > 1 def test_convert_emotions(self): self.senpy.activate_all(sync=True) plugin = Plugin({ 'id': 'imaginary', 'onyx:usesEmotionModel': 'emoml:fsre-dimensions' }) eSet1 = EmotionSet() eSet1.prov__wasGeneratedBy = plugin['@id'] eSet1['onyx:hasEmotion'].append(Emotion({ 'emoml:arousal': 1, 'emoml:potency': 0, 'emoml:valence': 0 })) response = Results({ 'analysis': [{'plugin': plugin}], 'entries': [Entry({ 'nif:iString': 'much ado about nothing', 'emotions': [eSet1] })] }) params = {'emotionModel': 'emoml:big6', 'conversion': 'full'} r1 = deepcopy(response) r1.parameters = params self.senpy.convert_emotions(r1) assert len(r1.entries[0].emotions) == 2 params['conversion'] = 'nested' r2 = deepcopy(response) r2.parameters = params self.senpy.convert_emotions(r2) assert len(r2.entries[0].emotions) == 1 assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1 params['conversion'] = 'filtered' r3 = deepcopy(response) r3.parameters = params self.senpy.convert_emotions(r3) assert len(r3.entries[0].emotions) == 1 r3.jsonld()
class ExtensionsTest(TestCase): def setUp(self): self.app = Flask('test_extensions') self.examples_dir = os.path.join(os.path.dirname(__file__), '..', 'example-plugins') self.senpy = Senpy(plugin_folder=self.examples_dir, app=self.app, default_plugins=False) self.senpy.deactivate_all() self.senpy.activate_plugin("Dummy", sync=True) self.app.config['TESTING'] = True # Tell Flask not to catch Exceptions def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember print(self.senpy.plugins()) assert self.senpy.get_plugin("dummy") def test_add_delete(self): '''Should be able to add and delete new plugins. ''' new = plugins.Analyser(name='new', description='new', version=0) self.senpy.add_plugin(new) assert new in self.senpy.plugins(is_activated=False) self.senpy.delete_plugin(new) assert new not in self.senpy.plugins(is_activated=False) def test_adding_folder(self): """ It should be possible for senpy to look for plugins in more folders. """ senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False) assert not senpy.analysis_plugins() senpy.add_folder(self.examples_dir) assert senpy.plugins(plugin_type=plugins.Analyser, is_activated=False) self.assertRaises(AttributeError, senpy.add_folder, 'DOES NOT EXIST') def test_installing(self): """ Installing a plugin """ info = { 'name': 'TestPip', 'module': 'mynoop', 'description': None, 'requirements': ['noop'], 'version': 0 } module = plugins.from_info(info, root=self.examples_dir, install=True) assert module.name == 'TestPip' assert module import noop dir(noop) def test_enabling(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins()) >= 3 assert self.senpy.get_plugin("Sleep").is_activated def test_installing_nonexistent(self): """ Fail if the dependencies cannot be met """ info = { 'name': 'TestPipFail', 'module': 'dummy', 'description': None, 'requirements': ['IAmMakingThisPackageNameUpToFail'], 'version': 0 } with self.assertRaises(Error): plugins.install_deps(info) def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.get_plugin("dummy").is_activated assert not self.senpy.get_plugin("sleep").is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) self.assertRaises(Error, partial(analyse, self.senpy, input="tupni")) def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = analyse(self.senpy, algorithm="Dummy", input="tupni", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r1.entries[0]['nif:isString'] == 'input' def test_analyse_empty(self): """ Trying to analyse when no plugins are installed should raise an error.""" senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False) self.assertRaises(Error, senpy.analyse, Results(), []) def test_analyse_wrong(self): """ Trying to analyse with a non-existent plugin should raise an error.""" self.assertRaises(Error, analyse, self.senpy, algorithm='DOES NOT EXIST', input='test') def test_analyse_jsonld(self): """ Using a plugin with JSON-LD input""" js_input = '''{ "@id": "prueba", "@type": "results", "entries": [ {"@id": "entry1", "nif:isString": "tupni", "@type": "entry" } ] }''' r1 = analyse(self.senpy, algorithm="Dummy", input=js_input, informat="json-ld", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r1.entries[0]['nif:isString'] == 'input' def test_analyse_error(self): class ErrorPlugin(plugins.Analyser): author = 'nobody' version = 0 ex = Error() def process(self, *args, **kwargs): raise self.ex m = ErrorPlugin(ex=Error('error in analysis', status=500)) self.senpy.add_plugin(m) try: analyse(self.senpy, input='nothing', algorithm='ErrorPlugin') assert False except Error as ex: assert 'error in analysis' in ex['message'] assert ex['status'] == 500 m.ex = Exception('generic exception on analysis') try: analyse(self.senpy, input='nothing', algorithm='ErrorPlugin') assert False except Exception as ex: assert 'generic exception on analysis' in str(ex) def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.plugins(name="Dummy")) > 0 assert not len(self.senpy.plugins(name="NotDummy")) assert self.senpy.plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len(self.senpy.plugins(name="Dummy", is_activated=True)) def test_load_default_plugins(self): senpy = Senpy(plugin_folder=self.examples_dir, default_plugins=True) assert len(senpy.plugins(is_activated=False)) > 1 def test_convert_emotions(self): self.senpy.activate_all(sync=True) plugin = Plugin({ 'id': 'imaginary', 'onyx:usesEmotionModel': 'emoml:fsre-dimensions' }) eSet1 = EmotionSet() activity = plugin.activity() eSet1.prov(activity) eSet1['onyx:hasEmotion'].append( Emotion({ 'emoml:arousal': 1, 'emoml:potency': 0, 'emoml:valence': 0 })) response = Results({ 'activities': [activity], 'entries': [ Entry({ 'nif:isString': 'much ado about nothing', 'onyx:hasEmotionSet': [eSet1] }) ] }) params = { 'emotion-model': 'emoml:big6', 'algorithm': ['conversion'], 'conversion': 'full' } r1 = deepcopy(response) r1.parameters = params self.senpy.analyse(r1) assert len(r1.entries[0].emotions) == 2 params['conversion'] = 'nested' r2 = deepcopy(response) r2.parameters = params self.senpy.analyse(r2) assert len(r2.entries[0].emotions) == 1 assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1 params['conversion'] = 'filtered' r3 = deepcopy(response) r3.parameters = params self.senpy.analyse(r3) assert len(r3.entries[0].emotions) == 1 r3.jsonld()
class BlueprintsTest(TestCase): def setUp(self): self.app = Flask("test_extensions") self.client = self.app.test_client() self.senpy = Senpy() self.senpy.init_app(self.app) self.dir = os.path.join(os.path.dirname(__file__), "..") self.senpy.add_folder(self.dir) self.senpy.activate_plugin("Dummy", sync=True) self.senpy.activate_plugin("DummyRequired", sync=True) self.senpy.default_plugin = 'Dummy' def assertCode(self, resp, code): self.assertEqual(resp.status_code, code) def test_home(self): """ Calling with no arguments should ask the user for more arguments """ resp = self.client.get("/api/") self.assertCode(resp, 400) js = parse_resp(resp) logging.debug(js) assert js["status"] == 400 atleast = { "status": 400, "message": "Missing or invalid parameters", } assert check_dict(js, atleast) def test_analysis(self): """ The dummy plugin returns an empty response,\ it should contain the context """ resp = self.client.get("/api/?i=My aloha mohame") self.assertCode(resp, 200) js = parse_resp(resp) logging.debug("Got response: %s", js) assert "@context" in js assert "entries" in js def test_analysis_extra(self): """ Extra params that have a default should """ resp = self.client.get("/api/?i=My aloha mohame&algo=Dummy") self.assertCode(resp, 200) js = parse_resp(resp) logging.debug("Got response: %s", js) assert "@context" in js assert "entries" in js def test_analysis_extra_required(self): """ Extra params that have a required argument that does not have a default should raise an error. """ resp = self.client.get("/api/?i=My aloha mohame&algo=DummyRequired") self.assertCode(resp, 400) js = parse_resp(resp) logging.debug("Got response: %s", js) assert isinstance(js, models.Error) def test_error(self): """ The dummy plugin returns an empty response,\ it should contain the context """ resp = self.client.get("/api/?i=My aloha mohame&algo=DOESNOTEXIST") self.assertCode(resp, 404) js = parse_resp(resp) logging.debug("Got response: %s", js) assert isinstance(js, models.Error) def test_list(self): """ List the plugins """ resp = self.client.get("/api/plugins/") self.assertCode(resp, 200) js = parse_resp(resp) logging.debug(js) assert 'plugins' in js plugins = js['plugins'] assert len(plugins) > 1 assert list(p for p in plugins if p['name'] == "Dummy") assert "@context" in js def test_headers(self): for i, j in product(["/api/plugins/?nothing=", "/api/?i=test&"], ["inHeaders"]): resp = self.client.get("%s" % (i)) js = parse_resp(resp) assert "@context" in js resp = self.client.get("%s&%s=0" % (i, j)) js = parse_resp(resp) assert "@context" in js resp = self.client.get("%s&%s=1" % (i, j)) js = parse_resp(resp) assert "@context" not in js resp = self.client.get("%s&%s=true" % (i, j)) js = parse_resp(resp) assert "@context" not in js def test_detail(self): """ Show only one plugin""" resp = self.client.get("/api/plugins/Dummy/") self.assertCode(resp, 200) js = parse_resp(resp) logging.debug(js) assert "@id" in js assert js["@id"] == "plugins/Dummy_0.1" def test_default(self): """ Show only one plugin""" resp = self.client.get("/api/plugins/default/") self.assertCode(resp, 200) js = parse_resp(resp) logging.debug(js) assert "@id" in js assert js["@id"] == "plugins/Dummy_0.1" def test_context(self): resp = self.client.get("/api/contexts/context.jsonld") self.assertCode(resp, 200) js = parse_resp(resp) assert "@context" in js assert check_dict( js["@context"], {"marl": "http://www.gsi.dit.upm.es/ontologies/marl/ns#"}) def test_schema(self): resp = self.client.get("/api/schemas/definitions.json") self.assertCode(resp, 200) js = parse_resp(resp) assert "$schema" in js
class BlueprintsTest(TestCase): def create_app(self): self.app = Flask("test_extensions") self.senpy = Senpy() self.senpy.init_app(self.app) self.dir = os.path.join(os.path.dirname(__file__), "..") self.senpy.add_folder(self.dir) self.senpy.activate_plugin("Dummy", sync=True) return self.app def test_home(self): """ Calling with no arguments should ask the user for more arguments """ resp = self.client.get("/") self.assert404(resp) logging.debug(resp.json) assert resp.json["status"] == 404 atleast = { "status": 404, "message": "Missing or invalid parameters", } assert check_dict(resp.json, atleast) def test_analysis(self): """ The dummy plugin returns an empty response,\ it should contain the context """ resp = self.client.get("/?i=My aloha mohame") self.assert200(resp) logging.debug("Got response: %s", resp.json) assert "@context" in resp.json assert check_dict( resp.json["@context"], {"marl": "http://www.gsi.dit.upm.es/ontologies/marl/ns#"}) assert "entries" in resp.json def test_list(self): """ List the plugins """ resp = self.client.get("/plugins/") self.assert200(resp) logging.debug(resp.json) assert "Dummy" in resp.json assert "@context" in resp.json def test_headers(self): for i, j in product(["/plugins/?nothing=", "/?i=test&"], ["headers", "inHeaders"]): resp = self.client.get("%s" % (i)) assert "@context" in resp.json resp = self.client.get("%s&%s=0" % (i, j)) assert "@context" in resp.json resp = self.client.get("%s&%s=1" % (i, j)) assert "@context" not in resp.json resp = self.client.get("%s&%s=true" % (i, j)) assert "@context" not in resp.json def test_detail(self): """ Show only one plugin""" resp = self.client.get("/plugins/Dummy") self.assert200(resp) logging.debug(resp.json) assert "@id" in resp.json assert resp.json["@id"] == "Dummy_0.1" def test_activate(self): """ Activate and deactivate one plugin """ resp = self.client.get("/plugins/Dummy/deactivate") self.assert200(resp) sleep(0.5) resp = self.client.get("/plugins/Dummy") self.assert200(resp) assert "is_activated" in resp.json assert resp.json["is_activated"] == False resp = self.client.get("/plugins/Dummy/activate") self.assert200(resp) sleep(0.5) resp = self.client.get("/plugins/Dummy") self.assert200(resp) assert "is_activated" in resp.json assert resp.json["is_activated"] == True def test_default(self): """ Show only one plugin""" resp = self.client.get("/default") self.assert200(resp) logging.debug(resp.json) assert "@id" in resp.json assert resp.json["@id"] == "Dummy_0.1" resp = self.client.get("/plugins/Dummy/deactivate") self.assert200(resp) sleep(0.5) resp = self.client.get("/default") self.assert404(resp)
class BlueprintsTest(TestCase): def create_app(self): self.app = Flask("test_extensions") self.senpy = Senpy() self.senpy.init_app(self.app) self.dir = os.path.join(os.path.dirname(__file__), "..") self.senpy.add_folder(self.dir) self.senpy.activate_plugin("Dummy", sync=True) return self.app def test_home(self): """ Calling with no arguments should ask the user for more arguments """ resp = self.client.get("/api/") self.assert404(resp) logging.debug(resp.json) assert resp.json["status"] == 404 atleast = { "status": 404, "message": "Missing or invalid parameters", } assert check_dict(resp.json, atleast) def test_analysis(self): """ The dummy plugin returns an empty response,\ it should contain the context """ resp = self.client.get("/api/?i=My aloha mohame") self.assert200(resp) logging.debug("Got response: %s", resp.json) assert "@context" in resp.json assert "entries" in resp.json def test_list(self): """ List the plugins """ resp = self.client.get("/api/plugins/") self.assert200(resp) logging.debug(resp.json) assert 'plugins' in resp.json plugins = resp.json['plugins'] assert len(plugins) > 1 assert list(p for p in plugins if p['name'] == "Dummy") assert "@context" in resp.json def test_headers(self): for i, j in product(["/api/plugins/?nothing=", "/api/?i=test&"], ["inHeaders"]): resp = self.client.get("%s" % (i)) assert "@context" in resp.json resp = self.client.get("%s&%s=0" % (i, j)) assert "@context" in resp.json resp = self.client.get("%s&%s=1" % (i, j)) assert "@context" not in resp.json resp = self.client.get("%s&%s=true" % (i, j)) assert "@context" not in resp.json def test_detail(self): """ Show only one plugin""" resp = self.client.get("/api/plugins/Dummy/") self.assert200(resp) logging.debug(resp.json) assert "@id" in resp.json assert resp.json["@id"] == "Dummy_0.1" def test_activate(self): """ Activate and deactivate one plugin """ resp = self.client.get("/api/plugins/Dummy/deactivate") self.assert200(resp) sleep(0.5) resp = self.client.get("/api/plugins/Dummy/") self.assert200(resp) assert "is_activated" in resp.json assert resp.json["is_activated"] == False resp = self.client.get("/api/plugins/Dummy/activate") self.assert200(resp) sleep(0.5) resp = self.client.get("/api/plugins/Dummy/") self.assert200(resp) assert "is_activated" in resp.json assert resp.json["is_activated"] == True def test_default(self): """ Show only one plugin""" resp = self.client.get("/api/plugins/default/") self.assert200(resp) logging.debug(resp.json) assert "@id" in resp.json assert resp.json["@id"] == "Dummy_0.1" resp = self.client.get("/api/plugins/Dummy/deactivate") self.assert200(resp) sleep(0.5) resp = self.client.get("/api/plugins/default/") self.assert404(resp) def test_context(self): resp = self.client.get("/api/contexts/context.jsonld") self.assert200(resp) assert "@context" in resp.json assert check_dict( resp.json["@context"], {"marl": "http://www.gsi.dit.upm.es/ontologies/marl/ns#"}) def test_schema(self): resp = self.client.get("/api/schemas/definitions.json") self.assert200(resp) assert "$schema" in resp.json
class ExtensionsTest(TestCase): def setUp(self): self.app = Flask('test_extensions') self.examples_dir = os.path.join(os.path.dirname(__file__), '..', 'example-plugins') self.senpy = Senpy(plugin_folder=self.examples_dir, app=self.app, default_plugins=False) self.senpy.deactivate_all() self.senpy.activate_plugin("Dummy", sync=True) self.app.config['TESTING'] = True # Tell Flask not to catch Exceptions def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember print(self.senpy.plugins()) assert self.senpy.get_plugin("dummy") def test_add_delete(self): '''Should be able to add and delete new plugins. ''' new = plugins.Analyser(name='new', description='new', version=0) self.senpy.add_plugin(new) assert new in self.senpy.plugins(is_activated=False) self.senpy.delete_plugin(new) assert new not in self.senpy.plugins(is_activated=False) def test_adding_folder(self): """ It should be possible for senpy to look for plugins in more folders. """ senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False) assert not senpy.analysis_plugins() senpy.add_folder(self.examples_dir) assert senpy.plugins(plugin_type=plugins.Analyser, is_activated=False) self.assertRaises(AttributeError, senpy.add_folder, 'DOES NOT EXIST') def test_installing(self): """ Installing a plugin """ info = { 'name': 'TestPip', 'module': 'mynoop', 'description': None, 'requirements': ['noop'], 'version': 0 } module = plugins.from_info(info, root=self.examples_dir, install=True) assert module.name == 'TestPip' assert module import noop dir(noop) def test_enabling(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins()) >= 3 assert self.senpy.get_plugin("Sleep").is_activated def test_installing_nonexistent(self): """ Fail if the dependencies cannot be met """ info = { 'name': 'TestPipFail', 'module': 'dummy', 'description': None, 'requirements': ['IAmMakingThisPackageNameUpToFail'], 'version': 0 } with self.assertRaises(Error): plugins.install_deps(info) def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.get_plugin("dummy").is_activated assert not self.senpy.get_plugin("sleep").is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) self.assertRaises(Error, partial(analyse, self.senpy, input="tupni")) def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = analyse(self.senpy, algorithm="Dummy", input="tupni", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r1.entries[0]['nif:isString'] == 'input' def test_analyse_empty(self): """ Trying to analyse when no plugins are installed should raise an error.""" senpy = Senpy(plugin_folder=None, app=self.app, default_plugins=False) self.assertRaises(Error, senpy.analyse, Results(), []) def test_analyse_wrong(self): """ Trying to analyse with a non-existent plugin should raise an error.""" self.assertRaises(Error, analyse, self.senpy, algorithm='DOES NOT EXIST', input='test') def test_analyse_jsonld(self): """ Using a plugin with JSON-LD input""" js_input = '''{ "@id": "prueba", "@type": "results", "entries": [ {"@id": "entry1", "nif:isString": "tupni", "@type": "entry" } ] }''' r1 = analyse(self.senpy, algorithm="Dummy", input=js_input, informat="json-ld", output="tuptuo") r2 = analyse(self.senpy, input="tupni", output="tuptuo") assert r1.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r2.activities[0].algorithm == "endpoint:plugins/dummy_0.1" assert r1.entries[0]['nif:isString'] == 'input' def test_analyse_error(self): class ErrorPlugin(plugins.Analyser): author = 'nobody' version = 0 ex = Error() def process(self, *args, **kwargs): raise self.ex m = ErrorPlugin(ex=Error('error in analysis', status=500)) self.senpy.add_plugin(m) try: analyse(self.senpy, input='nothing', algorithm='ErrorPlugin') assert False except Error as ex: assert 'error in analysis' in ex['message'] assert ex['status'] == 500 m.ex = Exception('generic exception on analysis') try: analyse(self.senpy, input='nothing', algorithm='ErrorPlugin') assert False except Exception as ex: assert 'generic exception on analysis' in str(ex) def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.plugins(name="Dummy")) > 0 assert not len(self.senpy.plugins(name="NotDummy")) assert self.senpy.plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len(self.senpy.plugins(name="Dummy", is_activated=True)) def test_load_default_plugins(self): senpy = Senpy(plugin_folder=self.examples_dir, default_plugins=True) assert len(senpy.plugins(is_activated=False)) > 1 def test_convert_emotions(self): self.senpy.activate_all(sync=True) plugin = Plugin({ 'id': 'imaginary', 'onyx:usesEmotionModel': 'emoml:fsre-dimensions' }) eSet1 = EmotionSet() activity = plugin.activity() eSet1.prov(activity) eSet1['onyx:hasEmotion'].append(Emotion({ 'emoml:arousal': 1, 'emoml:potency': 0, 'emoml:valence': 0 })) response = Results({ 'activities': [activity], 'entries': [Entry({ 'nif:isString': 'much ado about nothing', 'onyx:hasEmotionSet': [eSet1] })] }) params = {'emotion-model': 'emoml:big6', 'algorithm': ['conversion'], 'conversion': 'full'} r1 = deepcopy(response) r1.parameters = params self.senpy.analyse(r1) assert len(r1.entries[0].emotions) == 2 params['conversion'] = 'nested' r2 = deepcopy(response) r2.parameters = params self.senpy.analyse(r2) assert len(r2.entries[0].emotions) == 1 assert r2.entries[0].emotions[0]['prov:wasDerivedFrom'] == eSet1 params['conversion'] = 'filtered' r3 = deepcopy(response) r3.parameters = params self.senpy.analyse(r3) assert len(r3.entries[0].emotions) == 1 r3.jsonld()
class ExtensionsTest(TestCase): def create_app(self): self.app = Flask("test_extensions") self.dir = os.path.join(os.path.dirname(__file__), "..") self.senpy = Senpy(plugin_folder=self.dir, default_plugins=False) self.senpy.init_app(self.app) self.senpy.activate_plugin("Dummy", sync=True) return self.app def test_init(self): """ Initialising the app with the extension. """ assert hasattr(self.app, "senpy") tapp = Flask("temp app") self.senpy.init_app(tapp) assert hasattr(tapp, "senpy") def test_discovery(self): """ Discovery of plugins in given folders. """ # noinspection PyProtectedMember assert self.dir in self.senpy._search_folders print self.senpy.plugins assert "Dummy" in self.senpy.plugins def test_enabling(self): """ Enabling a plugin """ self.senpy.activate_all(sync=True) assert len(self.senpy.plugins) == 2 assert self.senpy.plugins["Sleep"].is_activated def test_disabling(self): """ Disabling a plugin """ self.senpy.deactivate_all(sync=True) assert not self.senpy.plugins["Dummy"].is_activated assert not self.senpy.plugins["Sleep"].is_activated def test_default(self): """ Default plugin should be set """ assert self.senpy.default_plugin assert self.senpy.default_plugin.name == "Dummy" self.senpy.deactivate_all(sync=True) logging.debug("Default: {}".format(self.senpy.default_plugin)) assert self.senpy.default_plugin is None def test_noplugin(self): """ Don't analyse if there isn't any plugin installed """ self.senpy.deactivate_all(sync=True) resp = self.senpy.analyse(input="tupni") logging.debug("Response: {}".format(resp)) assert resp["status"] == 404 def test_analyse(self): """ Using a plugin """ # I was using mock until plugin started inheriting # Leaf (defaultdict with __setattr__ and __getattr__. r1 = self.senpy.analyse( algorithm="Dummy", input="tupni", output="tuptuo") r2 = self.senpy.analyse(input="tupni", output="tuptuo") assert r1.analysis[0].id[:5] == "Dummy" assert r2.analysis[0].id[:5] == "Dummy" for plug in self.senpy.plugins: self.senpy.deactivate_plugin(plug, sync=True) resp = self.senpy.analyse(input="tupni") logging.debug("Response: {}".format(resp)) assert resp["status"] == 404 def test_filtering(self): """ Filtering plugins """ assert len(self.senpy.filter_plugins(name="Dummy")) > 0 assert not len(self.senpy.filter_plugins(name="notdummy")) assert self.senpy.filter_plugins(name="Dummy", is_activated=True) self.senpy.deactivate_plugin("Dummy", sync=True) assert not len( self.senpy.filter_plugins(name="Dummy", is_activated=True))