From e7f395a92c0a267ec13532849788708ea31f8488 Mon Sep 17 00:00:00 2001 From: "Stefan Hagen (Individual)" Date: Mon, 11 Dec 2017 14:00:43 +0100 Subject: [PATCH 1/3] enhance coverage and fix en passant with focus on api --- pymisp/api.py | 7 +++++-- tests/test_offline.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pymisp/api.py b/pymisp/api.py index 9806f1d..2aaa35f 100644 --- a/pymisp/api.py +++ b/pymisp/api.py @@ -189,8 +189,11 @@ class PyMISP(object): messages = [] if response.get('error'): if isinstance(response['error'], list): - for e in response['errors']: - messages.append(e['error']['value'][0]) + for e in response['error']: + if isinstance(e, dict): + messages.append(e['error']['value'][0]) + else: + messages.append(e) else: messages.append(['error']) elif response.get('errors'): diff --git a/tests/test_offline.py b/tests/test_offline.py index 992fb80..50c1cae 100644 --- a/tests/test_offline.py +++ b/tests/test_offline.py @@ -269,6 +269,39 @@ class TestOffline(unittest.TestCase): self.assertTrue(sd['to_ids'] in [0, 1]) self.assertTrue(sd['default_category'] in categories) + def test_flatten_error_messages_singular(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + error = pymisp.get(1) + response = self.auth_error_msg + response['error'] = ['foo', 'bar', 'baz'] + messages = pymisp.flatten_error_messages(response) + self.assertEqual(["foo", "bar", "baz"], messages) + + def test_flatten_error_messages_plural(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + error = pymisp.get(1) + response = self.auth_error_msg + response['errors'] = {'foo': 42, 'bar': False, 'baz': ['oo', 'ka']} + messages = pymisp.flatten_error_messages(response) + self.assertEqual(['42 (foo)', 'False (bar)', 'oo', 'ka'], messages) + + def test_flatten_error_messages_nested(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + error = pymisp.get(1) + response = self.auth_error_msg + response['errors'] = { + 'fo': {'o': 42}, 'ba': {'r': True}, 'b': {'a': ['z']}, 'd': {'e': {'e': ['p']}}} + messages = pymisp.flatten_error_messages(response) + self.assertEqual(['Error in o: 42', 'Error in r: True', 'Error in a: z', "Error in e: {'e': ['p']}"], messages) + + def test_test_connection(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertTrue(pymisp.test_connection()) + if __name__ == '__main__': unittest.main() From 635c02eadce9d1b834a534e2e4367976cc0dcc39 Mon Sep 17 00:00:00 2001 From: "Stefan Hagen (Individual)" Date: Mon, 11 Dec 2017 14:18:06 +0100 Subject: [PATCH 2/3] changed asserts from dict usecases to set comparison to workaround non 3.6 behavior --- tests/test_offline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_offline.py b/tests/test_offline.py index 7a4e563..91d767d 100644 --- a/tests/test_offline.py +++ b/tests/test_offline.py @@ -313,7 +313,7 @@ class TestOffline(unittest.TestCase): response = self.auth_error_msg response['errors'] = {'foo': 42, 'bar': False, 'baz': ['oo', 'ka']} messages = pymisp.flatten_error_messages(response) - self.assertEqual(['42 (foo)', 'False (bar)', 'oo', 'ka'], messages) + self.assertEqual(set(['42 (foo)', 'False (bar)', 'oo', 'ka']), set(messages)) def test_flatten_error_messages_nested(self, m): self.initURI(m) @@ -323,7 +323,7 @@ class TestOffline(unittest.TestCase): response['errors'] = { 'fo': {'o': 42}, 'ba': {'r': True}, 'b': {'a': ['z']}, 'd': {'e': {'e': ['p']}}} messages = pymisp.flatten_error_messages(response) - self.assertEqual(['Error in o: 42', 'Error in r: True', 'Error in a: z', "Error in e: {'e': ['p']}"], messages) + self.assertEqual(set(['Error in o: 42', 'Error in r: True', 'Error in a: z', "Error in e: {'e': ['p']}"]), set(messages)) def test_test_connection(self, m): self.initURI(m) From f68faf7c6193063add0c3f0f81ac3b99bb490719 Mon Sep 17 00:00:00 2001 From: "Stefan Hagen (Individual)" Date: Mon, 11 Dec 2017 15:27:50 +0100 Subject: [PATCH 3/3] further tests added (for public methods) --- tests/test_offline.py | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/test_offline.py b/tests/test_offline.py index 91d767d..15f99b0 100644 --- a/tests/test_offline.py +++ b/tests/test_offline.py @@ -51,6 +51,13 @@ class TestOffline(unittest.TestCase): m.register_uri('DELETE', self.domain + 'events/3', json={'errors': ['Invalid event'], 'message': 'Invalid event', 'name': 'Invalid event', 'url': '/events/3'}) m.register_uri('GET', self.domain + 'attributes/delete/2', json={'message': 'Attribute deleted.'}) m.register_uri('POST', self.domain + 'events/index', json=self.search_index_result) + m.register_uri('POST', self.domain + 'attributes/edit/' + self.key, json={}) + m.register_uri('GET', self.domain + 'shadow_attributes/view/None', json={}) + m.register_uri('GET', self.domain + 'shadow_attributes/view/1', json={}) + m.register_uri('POST', self.domain + 'events/freeTextImport/1', json={}) + m.register_uri('POST', self.domain + 'attributes/restSearch', json={}) + m.register_uri('POST', self.domain + 'attributes/downloadSample', json={}) + m.register_uri('GET', self.domain + 'tags', json={'Tag': 'foo'}) def test_getEvent(self, m): self.initURI(m) @@ -330,6 +337,64 @@ class TestOffline(unittest.TestCase): pymisp = PyMISP(self.domain, self.key) self.assertTrue(pymisp.test_connection()) + def test_change_toids(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual({}, pymisp.change_toids(self.key, 1)) + + def test_change_toids_invalid(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + try: + _ = pymisp.change_toids(self.key, 42) + self.assertFalse('Exception required for off domain value') + except Exception: + pass + + def test_proposal_view_default(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual({}, pymisp.proposal_view()) + + def test_proposal_view_event_1(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual({}, pymisp.proposal_view(event_id=1)) + + def test_proposal_view_event_overdetermined(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertTrue(pymisp.proposal_view(event_id=1, proposal_id=42).get('error') is not None) + + def test_freetext(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual({}, pymisp.freetext(1, 'foo', adhereToWarninglists=True, distribution=42)) + + def test_freetext_offdomain(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + try: + _ = pymisp.freetext(1, None, adhereToWarninglists='hard') + self.assertFalse('Exception required for off domain value') + except Exception: + pass + + def test_get_yara(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual((False, None), pymisp.get_yara(1)) + + def test_download_samples(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual((False, None), pymisp.download_samples()) + + def test_get_all_tags(self, m): + self.initURI(m) + pymisp = PyMISP(self.domain, self.key) + self.assertEqual({'Tag': 'foo'}, pymisp.get_all_tags()) + if __name__ == '__main__': unittest.main()