class AddonPromotedQueryParam(AddonQueryMultiParam): query_param = 'promoted' reverse_dict = PROMOTED_API_NAME_TO_IDS valid_values = PROMOTED_API_NAME_TO_IDS.values() def get_values(self): values = super().get_values() # The values are lists of ids so flatten into a single list return list({y for x in values for y in x}) def get_app(self): return (AddonAppQueryParam(self.request).get_value() if AddonAppQueryParam.query_param in self.request.GET else None) def get_es_query(self): query = [Q(self.operator, **{'promoted.group_id': self.get_values()})] if app := self.get_app(): # If a specific application isn't set then application_id is None, # but ES doesn't store None values - it just doesn't store the # field for that record - so we have to use NOT 'exists' to check # for None. query.append( Q('term', **{'promoted.application_id': app}) | ~Q('exists', field='promoted.application_id')) return query
def test_search_by_promoted(self): with self.assertRaises(serializers.ValidationError) as context: self._filter(data={'promoted': 'foo'}) assert context.exception.detail == ['Invalid "promoted" parameter.'] for api_name, ids in PROMOTED_API_NAME_TO_IDS.items(): qs = self._filter(data={'promoted': api_name}) filter_ = qs['query']['bool']['filter'] assert [{'terms': {'promoted.group_id': ids}}] == filter_ qs = self._filter(data={'promoted': api_name, 'app': 'firefox'}) filter_ = qs['query']['bool']['filter'] assert {'terms': {'promoted.group_id': ids}} in filter_ assert { 'term': { 'promoted.approved_for_apps': amo.FIREFOX.id } } in filter_ # test multiple param values qs = self._filter(data={'promoted': 'recommended,line'}) filter_ = qs['query']['bool']['filter'] assert [{ 'terms': { 'promoted.group_id': [RECOMMENDED.id, LINE.id] } }] == filter_ # test combining multiple values with the meta "badged" group qs = self._filter(data={'promoted': 'badged,recommended,strategic'}) filter_ = qs['query']['bool']['filter'] assert [{ 'terms': { 'promoted.group_id': [ # recommended shouldn't be there twice RECOMMENDED.id, SPONSORED.id, VERIFIED.id, LINE.id, STRATEGIC.id, ] } }] == filter_
class AddonPromotedQueryParam(AddonQueryMultiParam): query_param = 'promoted' reverse_dict = PROMOTED_API_NAME_TO_IDS valid_values = PROMOTED_API_NAME_TO_IDS.values() def get_values(self): values = super().get_values() # The values are lists of ids so flatten into a single list return list({y for x in values for y in x}) def get_app(self): return (AddonAppQueryParam(self.query_data).get_value() if AddonAppQueryParam.query_param in self.query_data else None) def get_es_query(self): query = [Q(self.operator, **{'promoted.group_id': self.get_values()})] if app := self.get_app(): query.append(Q('term', **{'promoted.approved_for_apps': app})) return query