예제 #1
0
 def test_popProperties(self):
     expected = ['prop1', 'prop2']
     rs = resultspec.ResultSpec(
         properties=[resultspec.Property(b'property', 'eq', expected)])
     self.assertEqual(len(rs.properties), 1)
     self.assertEqual(rs.popProperties(), expected)
     self.assertEqual(len(rs.properties), 0)
예제 #2
0
 def test_properties_injection(self):
     resultSpec = resultspec.OptimisedResultSpec(
         properties=[resultspec.Property(b'property', 'eq', 'reason')])
     build = yield self.callGet(('builders', 77, 'builds', 3),
                                resultSpec=resultSpec)
     self.validateData(build)
     self.assertIn('reason', build['properties'])
 def testGetProperties(self):
     prop = resultspec.Property(b'property', 'eq', '*')
     buildrequest = yield self.callGet(('buildrequests', 44),
                        resultSpec=resultspec.ResultSpec(properties=[prop]))
     self.assertEqual(buildrequest['buildrequestid'], 44)
     self.assertEqual(buildrequest['properties'],
         {u'prop1': (u'one', u'fake1'), u'prop2': (u'two', u'fake2')})
예제 #4
0
    def test_properties_injection(self):
        resultSpec = resultspec.OptimisedResultSpec(
            properties=[resultspec.Property(b'property', 'eq', 'reason')])
        builds = yield self.callGet(('builds', ), resultSpec=resultSpec)

        for build in builds:
            self.validateData(build)

        self.assertTrue(any(('reason' in b['properties']) for b in builds))
 def testGetProperties(self):
     self.master.db.insertTestData([
         fakedb.BuildsetProperty(buildsetid=8822, property_name='prop1',
                                 property_value='["one", "fake1"]'),
         fakedb.BuildsetProperty(buildsetid=8822, property_name='prop2',
                                 property_value='["two", "fake2"]'),
     ])
     prop = resultspec.Property(b'property', 'eq', '*')
     buildrequests = yield self.callGet(('builders', 78, 'buildrequests'),
                        resultSpec=resultspec.ResultSpec(properties=[prop]))
     self.assertEqual(len(buildrequests), 1)
     self.assertEqual(buildrequests[0]['buildrequestid'], 46)
     self.assertEqual(buildrequests[0]['properties'],
         {u'prop1': (u'one', u'fake1'), u'prop2': (u'two', u'fake2')})
예제 #6
0
파일: rest.py 프로젝트: dhouck/buildbot
    def decodeResultSpec(self, request, endpoint):
        reqArgs = request.args

        def checkFields(fields, negOk=False):
            for k in fields:
                if k[0] == '-' and negOk:
                    k = k[1:]
                if k not in entityType.fieldNames:
                    raise BadRequest("no such field %r" % (k, ))

        entityType = endpoint.rtype.entityType
        limit = offset = order = fields = None
        filters, properties = [], []
        for arg in reqArgs:
            if arg == 'order':
                order = reqArgs[arg]
                checkFields(order, True)
                continue
            elif arg == 'field':
                fields = reqArgs[arg]
                checkFields(fields, False)
                continue
            elif arg == 'limit':
                try:
                    limit = int(reqArgs[arg][0])
                except Exception:
                    raise BadRequest('invalid limit')
                continue
            elif arg == 'offset':
                try:
                    offset = int(reqArgs[arg][0])
                except Exception:
                    raise BadRequest('invalid offset')
                continue
            elif arg == 'property':
                try:
                    props = [v.decode('utf-8') for v in reqArgs[arg]]
                except Exception:
                    raise BadRequest('invalid property value for %s' % arg)
                properties.append(resultspec.Property(arg, 'eq', props))
                continue
            elif arg in entityType.fieldNames:
                field = entityType.fields[arg]
                try:
                    values = [field.valueFromString(v) for v in reqArgs[arg]]
                except Exception:
                    raise BadRequest('invalid filter value for %s' % arg)

                filters.append(resultspec.Filter(arg, 'eq', values))
                continue
            elif '__' in arg:
                field, op = arg.rsplit('__', 1)
                args = reqArgs[arg]
                operators = (resultspec.Filter.singular_operators if len(args)
                             == 1 else resultspec.Filter.plural_operators)
                if op in operators and field in entityType.fieldNames:
                    fieldType = entityType.fields[field]
                    try:
                        values = [
                            fieldType.valueFromString(v) for v in reqArgs[arg]
                        ]
                    except Exception:
                        raise BadRequest('invalid filter value for %s' % arg)
                    filters.append(resultspec.Filter(field, op, values))
                    continue
            raise BadRequest("unrecognized query parameter '%s'" % (arg, ))

        # if ordering or filtering is on a field that's not in fields, bail out
        if fields:
            fieldsSet = set(fields)
            if order and set(order) - fieldsSet:
                raise BadRequest("cannot order on un-selected fields")
            for filter in filters:
                if filter.field not in fieldsSet:
                    raise BadRequest("cannot filter on un-selected fields")

        # build the result spec
        rspec = resultspec.ResultSpec(fields=fields,
                                      limit=limit,
                                      offset=offset,
                                      order=order,
                                      filters=filters,
                                      properties=properties)

        # for singular endpoints, only allow fields
        if not endpoint.isCollection:
            if rspec.filters:
                raise BadRequest("this is not a collection")

        return rspec
예제 #7
0
    def resultspec_from_jsonapi(self, req_args, entityType, is_collection):
        def checkFields(fields, negOk=False):
            for field in fields:
                k = bytes2unicode(field)
                if k[0] == '-' and negOk:
                    k = k[1:]
                if k not in entityType.fieldNames:
                    raise exceptions.InvalidQueryParameter(
                        "no such field '{}'".format(k))

        limit = offset = order = fields = None
        filters, properties = [], []
        limit = offset = order = fields = None
        filters, properties = [], []
        for arg in req_args:
            argStr = bytes2unicode(arg)
            if argStr == 'order':
                order = tuple([bytes2unicode(o) for o in req_args[arg]])
                checkFields(order, True)
            elif argStr == 'field':
                fields = req_args[arg]
                checkFields(fields, False)
            elif argStr == 'limit':
                try:
                    limit = int(req_args[arg][0])
                except Exception as e:
                    raise exceptions.InvalidQueryParameter(
                        'invalid limit') from e
            elif argStr == 'offset':
                try:
                    offset = int(req_args[arg][0])
                except Exception as e:
                    raise exceptions.InvalidQueryParameter(
                        'invalid offset') from e
            elif argStr == 'property':
                try:
                    props = []
                    for v in req_args[arg]:
                        if not isinstance(v, (bytes, str)):
                            raise TypeError("Invalid type {} for {}".format(
                                type(v), v))
                        props.append(bytes2unicode(v))
                except Exception as e:
                    raise exceptions.InvalidQueryParameter(
                        'invalid property value for {}'.format(arg)) from e
                properties.append(resultspec.Property(arg, 'eq', props))
            elif argStr in entityType.fieldNames:
                field = entityType.fields[argStr]
                try:
                    values = [field.valueFromString(v) for v in req_args[arg]]
                except Exception as e:
                    raise exceptions.InvalidQueryParameter(
                        'invalid filter value for {}'.format(argStr)) from e

                filters.append(resultspec.Filter(argStr, 'eq', values))
            elif '__' in argStr:
                field, op = argStr.rsplit('__', 1)
                args = req_args[arg]
                operators = (resultspec.Filter.singular_operators if len(args)
                             == 1 else resultspec.Filter.plural_operators)
                if op in operators and field in entityType.fieldNames:
                    fieldType = entityType.fields[field]
                    try:
                        values = [
                            fieldType.valueFromString(v) for v in req_args[arg]
                        ]
                    except Exception as e:
                        raise exceptions.InvalidQueryParameter(
                            'invalid filter value for {}'.format(
                                argStr)) from e
                    filters.append(resultspec.Filter(field, op, values))
            else:
                raise exceptions.InvalidQueryParameter(
                    "unrecognized query parameter '{}'".format(argStr))

        # if ordering or filtering is on a field that's not in fields, bail out
        if fields:
            fields = [bytes2unicode(f) for f in fields]
            fieldsSet = set(fields)
            if order and {o.lstrip('-') for o in order} - fieldsSet:
                raise exceptions.InvalidQueryParameter(
                    "cannot order on un-selected fields")
            for filter in filters:
                if filter.field not in fieldsSet:
                    raise exceptions.InvalidQueryParameter(
                        "cannot filter on un-selected fields")

        # build the result spec
        rspec = resultspec.ResultSpec(fields=fields,
                                      limit=limit,
                                      offset=offset,
                                      order=order,
                                      filters=filters,
                                      properties=properties)

        # for singular endpoints, only allow fields
        if not is_collection:
            if rspec.filters:
                raise exceptions.InvalidQueryParameter(
                    "this is not a collection")

        return rspec