Beispiel #1
0
    def notify_delete(self, item_id):  # pragma: no cover
        '''Adds an deleted notification.

        Notification is added for every listener that is listening on
        the updated item id.
        '''

        with self._dbconn.transaction() as t:
            ro = self._create_resource_ro_storage(
                self._listener_table, listener_prototype)
            listener_resources = ro.search(t, [
                qvarn.create_search_param(u'exact', u'listen_on', item_id),
            ], [])
            wildcard_listener_resources = ro.search(t, [
                qvarn.create_search_param(u'exact', u'listen_on_all', True),
            ], [])
            listeners = listener_resources[u'resources']
            listeners.extend(wildcard_listener_resources[u'resources'])

            wo = self._create_resource_wo_storage(
                self._notification_table, notification_prototype)
            for listener in listeners:
                notification = {
                    u'type': u'notification',
                    u'listener_id': listener[u'id'],
                    u'resource_id': item_id,
                    u'resource_revision': None,
                    u'resource_change': u'deleted',
                    u'last_modified': int(time.time() * 1000000)
                }
                wo.add_item(t, notification)
Beispiel #2
0
 def dont_test_search_multiple_conditions_from_different_rows(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(
             t,
             [
                 qvarn.create_search_param(u'exact', u'baz', u'bling'),
                 qvarn.create_search_param(u'exact', u'baz', u'blang'),
             ],
             [])
     self.assertIn(new_id, search_result[u'resources'][0][u'id'])
Beispiel #3
0
 def dont_test_search_multiple_conditions_from_same_table(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(
             t,
             [
                 qvarn.create_search_param(u'exact', u'foo', u'foobar'),
                 qvarn.create_search_param(u'exact', u'type', u'yo'),
             ],
             [])
     self.assertIn(new_id, search_result[u'resources'][0][u'id'])
Beispiel #4
0
    def notify_create(self, item_id, item_revision):
        '''Adds a created notification.

        Notification is added for every listener that has notify_of_new
        enabled.
        '''

        with self._dbconn.transaction() as t:
            ro = self._create_resource_ro_storage(
                self._listener_table, listener_prototype)
            listener_resources = ro.search(t, [
                qvarn.create_search_param(u'exact', u'notify_of_new', True),
            ], [])

            wo = self._create_resource_wo_storage(
                self._notification_table, notification_prototype)
            for listener in listener_resources[u'resources']:
                notification = {
                    u'type': u'notification',
                    u'listener_id': listener[u'id'],
                    u'resource_id': item_id,
                    u'resource_revision': item_revision,
                    u'resource_change': u'created',
                    u'last_modified': int(time.time() * 1000000)
                }
                wo.add_item(t, notification)
Beispiel #5
0
 def test_case_search_bad_key(self):
     with self.assertRaises(qvarn.FieldNotInResource):
         with self._dbconn.transaction() as t:
             self.wo.add_item(t, self.item)
             self.ro.search(
                 t, [qvarn.create_search_param(u'exact', u'KEY', u'BANG')],
                 [u'show_all'])
Beispiel #6
0
 def dont_test_search_main_list(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(
             t, [qvarn.create_search_param('exact', u'bars', u'bar1')], {})
     self.assertIn(new_id, search_result[u'resources'][0][u'id'])
Beispiel #7
0
 def dont_test_search_with_boolean(self):
     with self._dbconn.transaction() as t:
         self.wo.add_item(t, self.item)
         search_result = self.ro.search(
             t, [qvarn.create_search_param(u'exact', u'bool', 'false')],
             [u'show_all'])
     match_list = search_result[u'resources']
     self.assertEqual(match_list, [])
Beispiel #8
0
 def dont_test_search_main_item(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(t, [
             qvarn.create_search_param(u'exact', u'foo', u'foobar'),
         ], [])
     self.assertEqual(search_result, {u'resources': [{u'id': new_id}]})
Beispiel #9
0
 def dont_test_case_insensitive_search(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(
             t, [qvarn.create_search_param(u'exact', u'bar', u'BANG')],
             [u'show_all'])
     match_list = search_result[u'resources']
     self.assertIn(new_id, match_list[0][u'id'])
Beispiel #10
0
 def dont_test_search_condition_with_multiple_targets(self):
     with self._dbconn.transaction() as t:
         added = self.wo.add_item(t, self.item)
         new_id = added[u'id']
         search_result = self.ro.search(t, [
             qvarn.create_search_param(u'exact', u'bar', u'barbaz'),
         ], [])
     match_list = search_result[u'resources']
     self.assertIsNot(0, len(match_list))
     self.assertIn(new_id, match_list[0][u'id'])
Beispiel #11
0
    def get_notifications(self, listener_id):
        '''Serve GET /foos/listeners/123/notifications.

        Lists all notifications.
        '''
        ro = self._create_resource_ro_storage(
            self._notification_table, notification_prototype)
        with self._dbconn.transaction() as t:
            result = ro.search(t, [
                qvarn.create_search_param(u'exact', u'listener_id',
                                          listener_id),
            ], [], sort_params=[u'last_modified'])
        return result
Beispiel #12
0
    def delete_listener(self, listener_id):  # pragma: no cover
        '''Serve DELETE /foos/listeners/123 to delete a listener.'''
        with self._dbconn.transaction() as t:
            wo_listener = self._create_resource_wo_storage(
                self._listener_table, listener_prototype)
            wo_listener.delete_item(t, listener_id)

            ro = self._create_resource_ro_storage(
                self._notification_table, notification_prototype)
            notification_resources = ro.search(t, [
                qvarn.create_search_param(u'exact', u'listener_id',
                                          listener_id),
            ], [])

            wo_notification = self._create_resource_wo_storage(
                self._notification_table, notification_prototype)
            for notification in notification_resources[u'resources']:
                try:
                    wo_notification.delete_item(t, notification[u'id'])
                except qvarn.ItemDoesNotExist:
                    # Try to delete all anyway
                    pass
Beispiel #13
0
    def get_matching_items(self, search_criteria):  # pragma: no cover
        '''Serve GET /foos/search to list items matching search criteria.'''

        # We need criteria to be encoded so that when we split by slash (/),
        # we split the criteria correctly and keep the slashes in the
        # condition values.
        # We use REQUEST_URI provided by uWSGI instead of bottle's default
        # that uses decoded PATH_INFO.
        request_uri = bottle.request.environ['REQUEST_URI']
        # Split at the first "/search/" and take the part after it
        search_criteria = request_uri.split('/search/', 1)[1]

        criteria = [urllib.unquote(c).decode('utf8')
                    for c in search_criteria.split('/')]

        search_params = []
        show_params = []
        sort_params = []
        limit = None
        offset = None
        search_any = False

        any_opers = [
            u'exact',
            u'startswith',
            u'contains',
        ]

        opers = [
            u'exact',
            u'gt',
            u'ge',
            u'lt',
            u'le',
            u'ne',
            u'startswith',
            u'contains',
        ]
        i = 0
        while i < len(criteria):
            part = criteria[i]
            if part in opers:
                if i + 2 >= len(criteria):
                    raise BadSearchCondition()
                matching_rule = part
                search_field = criteria[i + 1]
                search_value = criteria[i + 2]
                if search_any:
                    try:
                        search_value = json.loads(search_value)
                    except ValueError as e:
                        raise BadAnySearchValue(error=str(e))
                    if not isinstance(search_value, list):
                        raise BadAnySearchValue(
                            error=u"%r is not a list" % search_value)
                search_param = qvarn.create_search_param(
                    matching_rule, search_field, search_value,
                    any=search_any,
                )
                search_params.append(search_param)
                search_any = False
                i += 3
            elif part == u'show_all':
                show_params.append(part)
                i += 1
            elif part == u'show':
                if i + 1 >= len(criteria):
                    raise BadSearchCondition()
                show_params.append((part, criteria[i + 1]))
                i += 2
            elif part == u'sort':
                sort_field = criteria[i + 1]
                sort_params.append(sort_field)
                i += 2
            elif part == u'limit':
                try:
                    limit = int(criteria[i + 1])
                except ValueError as e:
                    raise BadLimitValue(error=str(e))
                if limit < 0:
                    raise BadLimitValue(error="should be positive integer")
                i += 2
            elif part == u'offset':
                try:
                    offset = int(criteria[i + 1])
                except ValueError as e:
                    raise BadOffsetValue(error=str(e))
                if offset < 0:
                    raise BadOffsetValue(error="should be positive integer")
                i += 2
            elif part == u'any':
                if (i + 1) >= len(criteria):
                    raise MissingAnyOperator()
                elif criteria[i + 1] not in any_opers:
                    raise InvalidAnyOperator(
                        allowed_operators=', '.join(any_opers),
                        given_operator=criteria[i + 1],
                    )
                search_any = True
                i += 1
            else:
                raise BadSearchCondition()

        if (limit is not None or offset is not None) and not sort_params:
            raise LimitWithoutSortError()

        ro = self._create_ro_storage()
        with self._dbconn.transaction() as t:
            return ro.search(t, search_params, show_params, sort_params,
                             limit=limit, offset=offset)