def test_missing_op(self):
        encoded = '%28a%253D1%29%28b%253D2%29%26%28c%253D3%29'
        readable = '(a%3D1)(b%3D2)&(c%3D3)'

        self.assertEqual(encode(readable), encoded)

        with self.assertRaises(ValidationError) as exc:
            decode_complex_ops(encoded)

        self.assertEqual(exc.exception.detail,
                         ["Invalid querystring operator. Matched: ''."])
    def test_duplicate_negation(self):
        encoded = '%28a%253D1%29%20%26%20~~%28b%253D2%29'
        readable = '(a%3D1) & ~~(b%3D2)'

        self.assertEqual(encode(readable), encoded)

        with self.assertRaises(ValidationError) as exc:
            decode_complex_ops(encoded)

        self.assertEqual(exc.exception.detail,
                         ["Invalid querystring operator. Matched: ' & ~'."])
示例#3
0
    def test_missing_closing_paren(self):
        encoded = '%28a%253D1'
        readable = '(a%3D1'

        self.assertEqual(encode(readable), encoded)

        with self.assertRaises(ValidationError) as exc:
            decode_complex_ops(encoded)

        self.assertEqual(exc.exception.detail, [
            "Unable to parse querystring. Decoded: '(a%3D1'.",
        ])
示例#4
0
    def test_tilde_decoding(self):
        # Ensure decoding handles both RFC 2396 & 3986
        encoded_rfc3986 = '~%28a%253D1%29'
        encoded_rfc2396 = '%7E%28a%253D1%29'
        readable = '~(a%3D1)'
        result = [
            ('a=1', True, None),
        ]

        self.assertEqual(encode(readable), encoded_rfc3986)
        self.assertEqual(decode_complex_ops(encoded_rfc3986), result)
        self.assertEqual(decode_complex_ops(encoded_rfc2396), result)
示例#5
0
    def test_invalid_ops(self):
        encoded = '%28a%253D1%29asdf%28b%253D2%29qwerty%28c%253D3%29%26'
        readable = '(a%3D1)asdf(b%3D2)qwerty(c%3D3)&'

        self.assertEqual(encode(readable), encoded)

        with self.assertRaises(ValidationError) as exc:
            decode_complex_ops(encoded)

        self.assertEqual(exc.exception.detail, [
            "Invalid querystring operator. Matched: 'asdf'.",
            "Invalid querystring operator. Matched: 'qwerty'.",
            "Ending querystring must not have trailing characters. Matched: '&'.",
        ])
示例#6
0
    def filter_membership(self, qs, name, value):
        # Decode complex membership query
        try:
            complex_ops = decode_complex_ops(value, filter_operators(), True)
        except ValidationError as exc:
            raise ValidationError({'membership': exc.detail})

        # Collect the individual filtered membership querysets
        querystrings = [op.querystring for op in complex_ops]
        ms_queryset = vendors.PoolMembership.objects.all()
        ms_querysets = []
        errors = []

        for qstring in querystrings:
            query = qstring.split('=')

            try:
                ms_querysets.append(ms_queryset.filter(**{query[0]: query[1]}))
            except ValidationError as exc:
                errors[qstring] = exc.detail

        if errors:
            raise ValidationError(errors)

        # Retrieve a list of membership ids matching query
        ms_queryset = combine_complex_queryset(ms_querysets, complex_ops)
        ms_ids = list(ms_queryset.values_list('id', flat=True))

        # Filter vendors by membership
        if len(querystrings) > 0:
            qs = qs.filter(pools__id__in=ms_ids)

        return qs
示例#7
0
    def test_single_op(self):
        encoded = '%28a%253D1%29'
        readable = '(a%3D1)'
        result = [
            ('a=1', False, None),
        ]

        self.assertEqual(encode(readable), encoded)
        self.assertEqual(decode_complex_ops(encoded), result)
示例#8
0
    def test_only_negation(self):
        encoded = '~%28a%253D1%29'
        readable = '~(a%3D1)'
        result = [
            ('a=1', True, None),
        ]

        self.assertEqual(encode(readable), encoded)
        self.assertEqual(decode_complex_ops(encoded), result)
示例#9
0
    def filter_membership(self, qs, name, value):

        try:
            complex_ops = decode_complex_ops(value, filter_operators(), True)
        except ValidationError as exc:
            raise ValidationError({'membership': exc.detail})

        # Collect the individual filtered membership querysets
        querystrings = [op.querystring for op in complex_ops]
        ms_queryset = vendors.PoolMembership.objects.all()
        ms_querysets = []
        errors = []
        poolIds = []
        queryParameters = {}
        self.logger.error(" one  ")
        for qstring in querystrings:
            query = qstring.split('=')
            try:
                if 'pool__id__in' == query[0]:
                    poolIds = query[1].split(",")
                    query[1] = poolIds
                queryParameters[query[0]] = query[1]
                ms_querysets.append(ms_queryset.filter(**{query[0]: query[1]}))
            except ValidationError as exc:
                errors[qstring] = exc.detail

        if (len(poolIds) <= 1):
            try:
                ms_queryset = combine_complex_queryset(ms_querysets,
                                                       complex_ops)
                ms_ids = list(ms_queryset.values_list('id', flat=True))
                self.logger.error(" ms_ids if  {} ".format(ms_ids))
                self.logger.error(" query if {} ".format(ms_queryset.query))
            except ValidationError as exc:
                errors[qstring] = exc.detail
        else:
            try:
                self.logger.error(" poolIds else {} ".format(poolIds))
                ms_queryset = combine_complex_queryset(ms_querysets,
                                                       complex_ops)
                ms_ids = self.getMebershipIds(ms_queryset)
                self.logger.error(" ms_ids else {} ".format(ms_ids))
                if len(ms_ids) == 0:
                    qs = qs.filter(pools__id=0)
                    return qs

            except ValidationError as exc:
                errors[qstring] = exc.detail

        if errors:
            raise ValidationError(errors)

        if len(querystrings) > 0:
            qs = qs.filter(pools__id__in=ms_ids)

        return qs
示例#10
0
    def test_op_spacing(self):
        encoded = '%28a%253D1%29%20%26%20%28b%253D2%29'
        readable = '(a%3D1) & (b%3D2)'
        result = [
            ('a=1', False, QuerySet.__and__),
            ('b=2', False, None),
        ]

        self.assertEqual(encode(readable), encoded)
        self.assertEqual(decode_complex_ops(encoded), result)
示例#11
0
    def test_docstring(self):
        encoded = '%28a%253D1%29%20%26%20%28b%253D2%29%20%7C%20~%28c%253D3%29'
        readable = '(a%3D1) & (b%3D2) | ~(c%3D3)'
        result = [
            ('a=1', False, QuerySet.__and__),
            ('b=2', False, QuerySet.__or__),
            ('c=3', True, None),
        ]

        self.assertEqual(encode(readable), encoded)
        self.assertEqual(decode_complex_ops(encoded), result)