def set_up_managers(self): super(HistoryFiltersTestCase, self).set_up_managers() self.history_manager = HistoryManager(self.app) self.filter_parser = HistoryFilters(self.app)
class HistoryFiltersTestCase(BaseTestCase): def set_up_managers(self): super(HistoryFiltersTestCase, self).set_up_managers() self.history_manager = HistoryManager(self.app) self.filter_parser = HistoryFilters(self.app) # ---- functional and orm filter splitting and resolution def test_parse_filters(self): filters = self.filter_parser.parse_filters([ ('name', 'eq', 'wot'), ('deleted', 'eq', 'True'), ('annotation', 'has', 'hrrmm') ]) self.log('both orm and fn filters should be parsed and returned') self.assertEqual(len(filters), 3) self.log('values should be parsed') self.assertIsInstance(filters[1].right, sqlalchemy.sql.elements.True_) def test_parse_filters_invalid_filters(self): self.log('should error on non-column attr') self.assertRaises(exceptions.RequestParameterInvalidException, self.filter_parser.parse_filters, [ ('merp', 'eq', 'wot'), ]) self.log('should error on non-whitelisted attr') self.assertRaises(exceptions.RequestParameterInvalidException, self.filter_parser.parse_filters, [ ('user_id', 'eq', 'wot'), ]) self.log('should error on non-whitelisted op') self.assertRaises(exceptions.RequestParameterInvalidException, self.filter_parser.parse_filters, [ ('name', 'lt', 'wot'), ]) self.log('should error on non-listed fn op') self.assertRaises(exceptions.RequestParameterInvalidException, self.filter_parser.parse_filters, [ ('annotation', 'like', 'wot'), ]) self.log('should error on val parsing error') self.assertRaises(exceptions.RequestParameterInvalidException, self.filter_parser.parse_filters, [ ('deleted', 'eq', 'true'), ]) def test_orm_filter_parsing(self): user2 = self.user_manager.create(**user2_data) history1 = self.history_manager.create(name='history1', user=user2) history2 = self.history_manager.create(name='history2', user=user2) history3 = self.history_manager.create(name='history3', user=user2) filters = self.filter_parser.parse_filters([ ('name', 'like', 'history%'), ]) histories = self.history_manager.list(filters=filters) # for h in histories: # print h.name self.assertEqual(histories, [history1, history2, history3]) filters = self.filter_parser.parse_filters([('name', 'like', '%2'), ]) self.assertEqual(self.history_manager.list(filters=filters), [history2]) filters = self.filter_parser.parse_filters([('name', 'eq', 'history2'), ]) self.assertEqual(self.history_manager.list(filters=filters), [history2]) self.history_manager.update(history1, dict(deleted=True)) filters = self.filter_parser.parse_filters([('deleted', 'eq', 'True'), ]) self.assertEqual(self.history_manager.list(filters=filters), [history1]) filters = self.filter_parser.parse_filters([('deleted', 'eq', 'False'), ]) self.assertEqual(self.history_manager.list(filters=filters), [history2, history3]) self.assertEqual(self.history_manager.list(), [history1, history2, history3]) self.history_manager.update(history3, dict(deleted=True)) self.history_manager.update(history1, dict(importable=True)) self.history_manager.update(history2, dict(importable=True)) filters = self.filter_parser.parse_filters([ ('deleted', 'eq', 'True'), ('importable', 'eq', 'True'), ]) self.assertEqual(self.history_manager.list(filters=filters), [history1]) self.assertEqual(self.history_manager.list(), [history1, history2, history3]) def test_fn_filter_parsing(self): user2 = self.user_manager.create(**user2_data) history1 = self.history_manager.create(name='history1', user=user2) history2 = self.history_manager.create(name='history2', user=user2) history3 = self.history_manager.create(name='history3', user=user2) filters = self.filter_parser.parse_filters([('annotation', 'has', 'no play'), ]) anno_filter = filters[0] history3.add_item_annotation(self.trans.sa_session, user2, history3, "All work and no play") self.trans.sa_session.flush() self.assertTrue(anno_filter(history3)) self.assertFalse(anno_filter(history2)) self.assertEqual(self.history_manager.list(filters=filters), [history3]) self.log('should allow combinations of orm and fn filters') self.history_manager.update(history3, dict(importable=True)) self.history_manager.update(history2, dict(importable=True)) history1.add_item_annotation(self.trans.sa_session, user2, history1, "All work and no play") self.trans.sa_session.flush() shining_examples = self.history_manager.list(filters=self.filter_parser.parse_filters([ ('importable', 'eq', 'True'), ('annotation', 'has', 'no play'), ])) self.assertEqual(shining_examples, [history3]) def test_fn_filter_currying(self): self.filter_parser.fn_filter_parsers = { 'name_len': {'op': {'lt': lambda i, v: len(i.name) < v}, 'val': int} } self.log('should be 2 filters now') self.assertEqual(len(self.filter_parser.fn_filter_parsers), 1) filters = self.filter_parser.parse_filters([ ('name_len', 'lt', '4') ]) self.log('should have parsed out a single filter') self.assertEqual(len(filters), 1) filter_ = filters[0] fake = galaxy_mock.OpenObject() fake.name = '123' self.log('123 should return true through the filter') self.assertTrue(filter_(fake)) fake.name = '1234' self.log('1234 should return false through the filter') self.assertFalse(filter_(fake)) def test_list(self): """ Test limit and offset in conjunction with both orm and fn filtering. """ user2 = self.user_manager.create(**user2_data) history1 = self.history_manager.create(name='history1', user=user2) history2 = self.history_manager.create(name='history2', user=user2) history3 = self.history_manager.create(name='history3', user=user2) history4 = self.history_manager.create(name='history4', user=user2) self.history_manager.delete(history1) self.history_manager.delete(history2) self.history_manager.delete(history3) test_annotation = "testing" history2.add_item_annotation(self.trans.sa_session, user2, history2, test_annotation) self.trans.sa_session.flush() history3.add_item_annotation(self.trans.sa_session, user2, history3, test_annotation) self.trans.sa_session.flush() history3.add_item_annotation(self.trans.sa_session, user2, history4, test_annotation) self.trans.sa_session.flush() all_histories = [history1, history2, history3, history4] deleted_and_annotated = [history2, history3] self.log("no offset, no limit should work") self.assertEqual(self.history_manager.list(offset=None, limit=None), all_histories) self.assertEqual(self.history_manager.list(), all_histories) self.log("no offset, limit should work") self.assertEqual(self.history_manager.list(limit=2), [history1, history2]) self.log("offset, no limit should work") self.assertEqual(self.history_manager.list(offset=1), [history2, history3, history4]) self.log("offset, limit should work") self.assertEqual(self.history_manager.list(offset=1, limit=1), [history2]) self.log("zero limit should return empty list") self.assertEqual(self.history_manager.list(limit=0), []) self.log("past len offset should return empty list") self.assertEqual(self.history_manager.list(offset=len(all_histories)), []) self.log("negative limit should return full list") self.assertEqual(self.history_manager.list(limit=-1), all_histories) self.log("negative offset should return full list") self.assertEqual(self.history_manager.list(offset=-1), all_histories) filters = [model.History.deleted == true()] self.log("orm filtered, no offset, no limit should work") found = self.history_manager.list(filters=filters) self.assertEqual(found, [history1, history2, history3]) self.log("orm filtered, no offset, limit should work") found = self.history_manager.list(filters=filters, limit=2) self.assertEqual(found, [history1, history2]) self.log("orm filtered, offset, no limit should work") found = self.history_manager.list(filters=filters, offset=1) self.assertEqual(found, [history2, history3]) self.log("orm filtered, offset, limit should work") found = self.history_manager.list(filters=filters, offset=1, limit=1) self.assertEqual(found, [history2]) filters = self.filter_parser.parse_filters([('annotation', 'has', test_annotation)]) self.log("fn filtered, no offset, no limit should work") found = self.history_manager.list(filters=filters) self.assertEqual(found, [history2, history3, history4]) self.log("fn filtered, no offset, limit should work") found = self.history_manager.list(filters=filters, limit=2) self.assertEqual(found, [history2, history3]) self.log("fn filtered, offset, no limit should work") found = self.history_manager.list(filters=filters, offset=1) self.assertEqual(found, [history3, history4]) self.log("fn filtered, offset, limit should work") found = self.history_manager.list(filters=filters, offset=1, limit=1) self.assertEqual(found, [history3]) filters = self.filter_parser.parse_filters([ ('deleted', 'eq', 'True'), ('annotation', 'has', test_annotation) ]) self.log("orm and fn filtered, no offset, no limit should work") found = self.history_manager.list(filters=filters) self.assertEqual(found, [history2, history3]) self.log("orm and fn filtered, no offset, limit should work") found = self.history_manager.list(filters=filters, limit=1) self.assertEqual(found, [history2]) self.log("orm and fn filtered, offset, no limit should work") found = self.history_manager.list(filters=filters, offset=1) self.assertEqual(found, [history3]) self.log("orm and fn filtered, offset, limit should work") found = self.history_manager.list(filters=filters, offset=1, limit=1) self.assertEqual(found, [history3]) self.log("orm and fn filtered, zero limit should return empty list") found = self.history_manager.list(filters=filters, limit=0) self.assertEqual(found, []) self.log("orm and fn filtered, past len offset should return empty list") found = self.history_manager.list(filters=filters, offset=len(deleted_and_annotated)) self.assertEqual(found, []) self.log("orm and fn filtered, negative limit should return full list") found = self.history_manager.list(filters=filters, limit=-1) self.assertEqual(found, deleted_and_annotated) self.log("orm and fn filtered, negative offset should return full list") found = self.history_manager.list(filters=filters, offset=-1) self.assertEqual(found, deleted_and_annotated)