def test_field_less_than_criteria(): """with_field with less_than is translated as expected for date and non-date types """ publish_date = datetime.datetime(2019, 8, 27, 0, 0, 0) c1 = Criteria.with_field("num_field", Matcher.less_than(5)) c2 = Criteria.with_field("date_field", Matcher.less_than(publish_date)) assert filters_for_criteria(c1) == {"num_field": {"$lt": 5}} assert filters_for_criteria(c2) == { "date_field": {"$lt": {"$date": "2019-08-27T00:00:00Z"}} }
def test_field_or_criteria(): """or is translated to a mongo fragment as expected.""" c1 = Criteria.with_field("f1", "v1") c2 = Criteria.with_field("f2", "v2") assert filters_for_criteria(Criteria.or_(c1, c2)) == { "$or": [{"f1": {"$eq": "v1"}}, {"f2": {"$eq": "v2"}}] }
def test_type(): """type is mapped correctly""" crit = Criteria.with_field("type", Matcher.regex("foobar")) assert filters_for_criteria(crit, Repository) == { "notes._repo-type": { "$regex": "foobar" } }
def test_is_temporary(): """is_temporary is mapped correctly""" crit = Criteria.with_field("is_temporary", True) assert filters_for_criteria(crit, Repository) == { "notes.pub_temp_repo": { "$eq": True } }
def search_distributor(self, criteria=None): criteria = criteria or Criteria.true() distributors = [] filters_for_criteria(criteria, Distributor) try: for repo in self._repositories: for distributor in repo.distributors: if match_object(criteria, distributor): distributors.append( attr.evolve(distributor, repo_id=repo.id)) except Exception as ex: # pylint: disable=broad-except return f_return_error(ex) random.shuffle(distributors) return self._prepare_pages(distributors)
def test_field_in_criteria(): """with_field_in is translated to a mongo fragment as expected.""" assert filters_for_criteria( Criteria.with_field_in("some.field", ["val1", "val2"])) == { "some.field": { "$in": ["val1", "val2"] } }
def test_field_exists_criteria(): """with_field using 'exists' is translated to a mongo fragment as expected.""" assert filters_for_criteria( Criteria.with_field("some.field", Criteria.exists)) == { "some.field": { "$exists": True } }
def test_field_eq_criteria(): """with_field is translated to a mongo fragment as expected.""" assert filters_for_criteria(Criteria.with_field("some.field", "someval")) == { "some.field": { "$eq": "someval" } }
def test_eng_product_in(): """eng_product is mapped correctly""" crit = Criteria.with_field_in("eng_product_id", [12, 34, 56]) assert filters_for_criteria(crit, Repository) == { "notes.eng_product": { "$in": ["12", "34", "56"] } }
def test_signing_keys(): """signing_keys are mapped correctly""" crit = Criteria.with_field("signing_keys", ["abc", "def", "123"]) assert filters_for_criteria(crit, Repository) == { "notes.signatures": { "$eq": "abc,def,123" } }
def test_field_regex_criteria(): """with_field with regex is translated to a mongo fragment as expected.""" assert filters_for_criteria( Criteria.with_field("some.field", Matcher.regex("abc"))) == { "some.field": { "$regex": "abc" } }
def test_dict_matcher_value(): """criteria using a dict as matcher value""" crit = Criteria.with_field( "created", Matcher.less_than({"created_date": datetime.datetime(2019, 9, 4, 0, 0, 0)}), ) assert filters_for_criteria(crit) == { "created": {"$lt": {"created_date": {"$date": "2019-09-04T00:00:00Z"}}} }
def search_repository(self, criteria=None): criteria = criteria or Criteria.true() repos = [] # Pass the criteria through the code used by the real client to build # up the Pulp query. We don't actually *use* the resulting query since # we're not accessing a real Pulp server. The point is to ensure the # same validation and error behavior as used by the real client also # applies to the fake. filters_for_criteria(criteria, Repository) try: for repo in self._repositories: if match_object(criteria, repo): repos.append(self._attach(repo)) except Exception as ex: # pylint: disable=broad-except return f_return_error(ex) # callers should not make any assumption about the order of returned # values. Encourage that by returning output in unpredictable order random.shuffle(repos) # Split it into pages page_data = [] current_page_data = [] while repos: next_elem = repos.pop() current_page_data.append(next_elem) if len(current_page_data) == self._PAGE_SIZE and repos: page_data.append(current_page_data) current_page_data = [] page_data.append(current_page_data) page = Page() next_page = None for batch in reversed(page_data): page = Page(data=batch, next=next_page) next_page = f_return(page) return f_return(page)
def search_repository(self, criteria=None): criteria = criteria or Criteria.true() repos = [] # Pass the criteria through the code used by the real client to build # up the Pulp query. We don't actually *use* the resulting query since # we're not accessing a real Pulp server. The point is to ensure the # same validation and error behavior as used by the real client also # applies to the fake. filters_for_criteria(criteria, Repository) try: for repo in self._repositories: if match_object(criteria, repo): repos.append(self._attach_repo(repo)) except Exception as ex: # pylint: disable=broad-except return f_return_error(ex) # callers should not make any assumption about the order of returned # values. Encourage that by returning output in unpredictable order random.shuffle(repos) return self._prepare_pages(repos)
def test_created(): """created is mapped correctly""" # TODO: there is no datetime => string implicit conversion right now. # # Should we do that? Right now, it doesn't seem all that useful because # there's probably no usecase to search for an exact datetime anyway. # # In practice, searching by datetime probably is useful only with $lt # or $gt, which is not supported by this library at all, at the time # of writing. crit = Criteria.with_field("created", "20190814T15:16Z") assert filters_for_criteria(crit, Repository) == { "notes.created": { "$eq": "20190814T15:16Z" } }
def test_null_criteria(): """Searching for None or True translates to empty filters.""" assert filters_for_criteria(None) == {} assert filters_for_criteria(Criteria.true()) == {}
def test_unsearchable(): """passing a field which can't be mapped directly to Pulp raises an error""" crit = Criteria.with_field("relative_url", "foobar") with pytest.raises(NotImplementedError) as exc: filters_for_criteria(crit, Repository) assert "Searching on field relative_url is not supported" in str(exc.value)