def test_returns_show_all_if_specified(self): p = qvarn.SearchParser() sp = p.parse('exact/foo/bar/show_all') self.assertEqual(sp.sort_keys, []) self.assertEqual(sp.show_all, True) self.assertTrue(isinstance(sp.cond, qvarn.Equal)) self.assertEqual(sp.cond.name, 'foo') self.assertEqual(sp.cond.pattern, 'bar')
def test_returns_exact_condition(self): p = qvarn.SearchParser() sp = p.parse('exact/foo/bar') self.assertEqual(sp.sort_keys, []) self.assertEqual(sp.show_fields, []) self.assertEqual(sp.show_all, False) self.assertTrue(isinstance(sp.cond, qvarn.Equal)) self.assertEqual(sp.cond.name, 'foo') self.assertEqual(sp.cond.pattern, 'bar')
def test_handles_url_encoded_slash(self): p = qvarn.SearchParser() sp = p.parse('exact/operating_system/gnu%2Flinux') self.assertEqual(sp.sort_keys, []) self.assertEqual(sp.show_fields, []) self.assertEqual(sp.show_all, False) self.assertTrue(isinstance(sp.cond, qvarn.Equal)) self.assertEqual(sp.cond.name, 'operating_system') self.assertEqual(sp.cond.pattern, 'gnu/linux')
def test_returns_all_condition(self): p = qvarn.SearchParser() sp = p.parse('exact/foo/bar/exact/foobar/yo') self.assertEqual(sp.sort_keys, []) self.assertEqual(sp.show_fields, []) self.assertTrue(isinstance(sp.cond, qvarn.All)) self.assertEqual(len(sp.cond.conds), 2) first, second = sp.cond.conds self.assertTrue(isinstance(first, qvarn.Equal)) self.assertEqual(first.name, 'foo') self.assertEqual(first.pattern, 'bar') self.assertTrue(isinstance(second, qvarn.Equal)) self.assertEqual(second.name, 'foobar') self.assertEqual(second.pattern, 'yo')
def search(self, search_criteria, claims=None, access_params=None): if not search_criteria: raise NoSearchCriteria() p = qvarn.SearchParser() sp = p.parse(search_criteria) if sp.cond is None: sp.cond = qvarn.Equal('type', self.get_type_name()) def pick_all(obj): return obj def pick_id(obj): return { 'id': obj['id'], } def pick_some_from_object(obj, fields): return { key: obj[key] for key in obj if key in fields } def pick_some(fields): return lambda obj: pick_some_from_object(obj, fields) if sp.show_all: pick_fields = pick_all elif sp.show_fields: show_what = sp.show_fields + ['id'] pick_fields = pick_some(show_what) else: pick_fields = pick_id # FIXME: This is needed because Qvarn API stupidly requires # all fields to actually be defined by the resource type. If # we drop that, we can drop this check, but that needs to be a # managed transition, and for now we can't just drop it. self._check_fields_are_allowed(sp.cond) unsorted = self._find_matches( sp.cond, claims=claims, access_params=access_params) if sp.sort_keys: result = self._sort_objects(unsorted, sp.sort_keys) else: result = unsorted if sp.offset is None and sp.limit is None: chosen = result elif sp.offset is None and sp.limit is not None: chosen = result[:sp.limit] elif sp.offset is not None and sp.limit is None: chosen = result[sp.offset:] elif sp.offset is not None and sp.limit is not None: chosen = result[sp.offset:sp.offset+sp.limit] picked = [pick_fields(o) for o in chosen] qvarn.log.log( 'trace', msg_text='Collection.search, sorted', result=picked) return picked
def test_returns_sort_keys(self): p = qvarn.SearchParser() sp = p.parse('exact/foo/bar/exact/foobar/yo/sort/a/sort/b') self.assertEqual(sp.sort_keys, ['a', 'b'])
def test_raises_error_if_show_specified_but_without_operand(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.SearchParserError): p.parse('exact/foo/bar/show')
def test_raises_error_if_both_show_and_show_all_specified(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.SearchParserError): p.parse('exact/foo/bar/show_all/show/foo')
def test_raises_error_if_only_show_specified(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.SearchParserError): p.parse('show')
def test_raises_error_if_condition_is_unknown(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.SearchParserError): p.parse('unknown/foo/bar')
def test_raises_error_path_is_empty(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.SearchParserError): p.parse('')
def test_accepts_limit_without_offset(self): p = qvarn.SearchParser() sp = p.parse('sort/x/limit/1') self.assertEqual(sp.offset, None) self.assertEqual(sp.limit, 1)
def test_raises_error_for_limit_without_sort(self): p = qvarn.SearchParser() with self.assertRaises(qvarn.NeedSortOperator): p.parse('limit/1')
def test_sets_offset_and_limit(self): p = qvarn.SearchParser() sp = p.parse('exact/foo/bar/sort/a/offset/42/limit/128') self.assertEqual(sp.offset, 42) self.assertEqual(sp.limit, 128)