Esempio n. 1
0
 def test_no_sorting_default_to_modified_field(self):
     token = self.resource._build_pagination_token([('last_modified', -1)],
                                                   self.record,
                                                   42)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertDictEqual(tokeninfo['last_record'],
                          {"last_modified": 1234})
Esempio n. 2
0
    def _extract_pagination_rules_from_token(self, limit, sorting):
        """Get pagination params."""
        token = self.request.validated['querystring'].get('_token', None)
        filters = []
        offset = 0
        if token:
            error_msg = None
            try:
                tokeninfo = json.loads(decode64(token))
                if not isinstance(tokeninfo, dict):
                    raise ValueError()
                last_record = tokeninfo['last_record']
                offset = tokeninfo['offset']
                nonce = tokeninfo['nonce']
            except (ValueError, KeyError, TypeError):
                error_msg = '_token has invalid content'

            # We don't want pagination tokens to be reused several times (#1171).
            # The cache backend is used to keep track of "nonces".
            if self.request.method.lower() == 'delete' and error_msg is None:
                registry = self.request.registry
                deleted = registry.cache.delete(nonce)
                if deleted is None:
                    error_msg = '_token was already used or has expired.'

            if error_msg:
                error_details = {
                    'location': 'querystring',
                    'description': error_msg
                }
                raise_invalid(self.request, **error_details)

            filters = self._build_pagination_rules(sorting, last_record)

        return filters, offset
Esempio n. 3
0
 def test_disambiguate_fieldname_containing_dots(self):
     token = self.resource._build_pagination_token([
         ('nested.other.subvalue', -1),
         ('title', 1),
     ], self.record, 88)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {'title': 'Title', 'nested.other.subvalue': 43})
Esempio n. 4
0
 def test_sorting_on_nested_field(self):
     token = self.resource._build_pagination_token([
         ('nested.subvalue', -1),
         ('title', 1),
     ], self.record, 88)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {'title': 'Title', 'nested.subvalue': 42})
Esempio n. 5
0
 def test_strip_malformed_sort_field(self):
     token = self.resource._build_pagination_token([
         ('non.existent', -1),
         ('title', 1),
     ], self.record, 88)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {'title': 'Title'})
Esempio n. 6
0
 def test_multiple_sorting_keep_all(self):
     token = self.resource._build_pagination_token(
         [("status", 1), ("title", -1), ("last_modified", -1)], self.record, 31
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(
         tokeninfo["last_record"], {"last_modified": 1234, "status": 2, "title": "Title"}
     )
Esempio n. 7
0
 def test_sorting_handle_ordering_direction(self):
     token = self.resource._build_pagination_token([
         ('status', 1),
         ('last_modified', 1)
     ], self.record, 32)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {"last_modified": 1234, "status": 2})
Esempio n. 8
0
 def delete(self, key):
     query = 'DELETE FROM cache WHERE key = :key RETURNING value;'
     with self.client.connect() as conn:
         result = conn.execute(query, dict(key=self.prefix + key))
         if result.rowcount > 0:
             value = result.fetchone()['value']
             return json.loads(value)
     return None
Esempio n. 9
0
 def get(self, key):
     purge = "DELETE FROM cache WHERE ttl IS NOT NULL AND now() > ttl;"
     query = "SELECT value FROM cache WHERE key = :key;"
     with self.client.connect() as conn:
         conn.execute(purge)
         result = conn.execute(query, dict(key=self.prefix + key))
         if result.rowcount > 0:
             value = result.fetchone()['value']
             return json.loads(value)
Esempio n. 10
0
 def test_can_build_while_sorting_on_missing_field(self):
     token = self.resource._build_pagination_token([
         ('unknown', 1),
         ('title', -1),
         ('last_modified', -1)
     ], self.record, 31)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {"last_modified": 1234, "title": "Title"})
Esempio n. 11
0
 def test_multiple_sorting_keep_all(self):
     token = self.resource._build_pagination_token([
         ('status', 1),
         ('title', -1),
         ('last_modified', -1)
     ], self.record, 31)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['last_record'],
                      {"last_modified": 1234, "status": 2,
                       'title': 'Title'})
Esempio n. 12
0
    def test_standard_entries_are_filled(self):
        with mock.patch('kinto.core.utils.msec_time', return_value=12):
            value = self.renderer(self.logger, 'debug', {})

        log = json.loads(value)
        self.assertDictEqual(log, {
            'EnvVersion': '2.0',
            'Hostname': os.uname()[1],
            'Logger': '',
            'Pid': os.getpid(),
            'Severity': 7,
            'Timestamp': 12000000,
            'Type': '',
            'Fields': {}
        })
Esempio n. 13
0
 def get(self, key):
     purge = """
     DELETE FROM cache c
     USING (
         SELECT key
         FROM cache
         WHERE ttl IS NOT NULL AND now() > ttl
         ORDER BY key ASC
         FOR UPDATE
     ) del
     WHERE del.key = c.key;"""
     query = 'SELECT value FROM cache WHERE key = :key AND now() < ttl;'
     with self.client.connect() as conn:
         conn.execute(purge)
         result = conn.execute(query, dict(key=self.prefix + key))
         if result.rowcount > 0:
             value = result.fetchone()['value']
             return json.loads(value)
Esempio n. 14
0
    def test_returns_alert_if_eos_in_the_future(self):
        # Set an end of service date in the future.
        tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
        with mock.patch.dict(self.app.app.registry.settings, [
                             ('eos', tomorrow.isoformat()),
                             ('eos_url', 'http://eos-url'),
                             ('eos_message',
                              'This service will soon be decommissioned')]):
            response = self.app.get('/')

            # Requests should work as usual and contain an
            # Alert header, with the service end of life information.
            self.assertIn('Alert', response.headers)
            self.assertDictEqual(json.loads(response.headers['Alert']), {
                'code': 'soft-eol',
                'url': 'http://eos-url',
                'message': 'This service will soon be decommissioned'
            })
Esempio n. 15
0
    def _extract_pagination_rules_from_token(self, limit, sorting):
        """Get pagination params."""
        queryparams = self.request.GET
        token = queryparams.get("_token", None)
        filters = []
        offset = 0
        if token:
            try:
                tokeninfo = json.loads(decode64(token))
                if not isinstance(tokeninfo, dict):
                    raise ValueError()
                last_record = tokeninfo["last_record"]
                offset = tokeninfo["offset"]
            except (ValueError, KeyError, TypeError):
                error_msg = "_token has invalid content"
                error_details = {"location": "querystring", "description": error_msg}
                raise_invalid(self.request, **error_details)

            filters = self._build_pagination_rules(sorting, last_record)
        return filters, offset
Esempio n. 16
0
 def test_returns_410_if_eos_in_the_past(self):
     # Set an end of service date in the past.
     yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
     with mock.patch.dict(self.app.app.registry.settings, [
                          ('eos', yesterday.isoformat()),
                          ('eos_url', 'http://eos-url'),
                          ('eos_message',
                           'This service had been decommissioned')]):
         response = self.app.get('/', status=410)
         self.assertIn('Alert', response.headers)
         self.assertDictEqual(json.loads(response.headers['Alert']), {
             'code': 'hard-eol',
             'url': 'http://eos-url',
             'message': 'This service had been decommissioned'
         })
         self.assertDictEqual(response.json, {
             "errno": ERRORS.SERVICE_DEPRECATED.value,
             "message": "The service you are trying to connect no longer "
                        "exists at this location.",
             "code": 410,
             "error": "Gone"
         })
Esempio n. 17
0
 def test_type_comes_from_structlog_event(self):
     value = self.renderer(self.logger, 'debug', {'event': 'booh'})
     log = json.loads(value)
     self.assertEqual(log['Type'], 'booh')
Esempio n. 18
0
 def test_sorting_handle_both_rules(self):
     token = self.resource._build_pagination_token(
         [("status", -1), ("last_modified", -1)], self.record, 34
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertDictEqual(tokeninfo["last_record"], {"last_modified": 1234, "status": 2})
Esempio n. 19
0
 def get(self, key):
     value = self._client.get(self.prefix + key)
     if value:
         value = value.decode('utf-8')
         return json.loads(value)
Esempio n. 20
0
 def test_list_of_string_values_are_not_serialized(self):
     list_values = ['life', 'of', 'pi']
     logged = self.renderer(self.logger, 'info', {'params': list_values})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], list_values)
Esempio n. 21
0
 def test_objects_values_are_serialized_as_string(self):
     querystring = {'_sort': 'name'}
     logged = self.renderer(self.logger, 'info', {'params': querystring})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], json.dumps(querystring))
Esempio n. 22
0
 def test_sorting_on_nested_field(self):
     token = self.resource._build_pagination_token(
         [("nested.subvalue", -1), ("title", 1)], self.record, 88
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_record"], {"title": "Title", "nested.subvalue": 42})
Esempio n. 23
0
 def test_list_of_string_values_are_not_serialized(self):
     list_values = ['life', 'of', 'pi']
     logged = self.renderer(self.logger, 'info', {'params': list_values})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], list_values)
Esempio n. 24
0
 def test_list_of_homogeneous_values_are_serialized_as_string(self):
     list_values = ['life', 'of', 'pi', 3.14]
     logged = self.renderer(self.logger, 'info', {'params': list_values})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], json.dumps(list_values))
Esempio n. 25
0
 def test_objects_values_are_serialized_as_string(self):
     querystring = {'_sort': 'name'}
     logged = self.renderer(self.logger, 'info', {'params': querystring})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], json.dumps(querystring))
Esempio n. 26
0
 def test_fields_can_be_provided_directly(self):
     value = self.renderer(self.logger, 'critical', {'Fields': {'win': 11}})
     log = json.loads(value)
     self.assertEqual(log['Fields'], {'win': 11})
Esempio n. 27
0
 def test_unknown_fields_are_moved_to_fields_entry(self):
     value = self.renderer(self.logger, 'critical', {'win': 11})
     log = json.loads(value)
     self.assertEqual(log['Fields'], {'win': 11})
Esempio n. 28
0
 def test_severity_comes_from_logger_name(self):
     value = self.renderer(self.logger, 'critical', {})
     log = json.loads(value)
     self.assertEqual(log['Severity'], 0)
Esempio n. 29
0
 def test_unknown_fields_are_moved_to_fields_entry(self):
     value = self.renderer(self.logger, 'critical', {'win': 11})
     log = json.loads(value)
     self.assertEqual(log['Fields'], {'win': 11})
Esempio n. 30
0
 def test_fields_can_be_provided_directly(self):
     value = self.renderer(self.logger, 'critical', {'Fields': {'win': 11}})
     log = json.loads(value)
     self.assertEqual(log['Fields'], {'win': 11})
Esempio n. 31
0
 def test_strip_malformed_sort_field(self):
     token = self.resource._build_pagination_token(
         [("non.existent", -1), ("title", 1)], self.record, 88
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_record"], {"title": "Title"})
Esempio n. 32
0
 def test_list_of_homogeneous_values_are_serialized_as_string(self):
     list_values = ['life', 'of', 'pi', 3.14]
     logged = self.renderer(self.logger, 'info', {'params': list_values})
     log = json.loads(logged)
     self.assertEqual(log['Fields']['params'], json.dumps(list_values))
Esempio n. 33
0
 def test_no_sorting_default_to_modified_field(self):
     token = self.resource._build_pagination_token([('last_modified', -1)],
                                                   self.record, 42)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertDictEqual(tokeninfo['last_record'], {"last_modified": 1234})
Esempio n. 34
0
 def _get(self, key):
     value = self._client.get(self.prefix + key)
     if not value:
         return None, 0
     data = json.loads(value)
     return data["value"], data["ttl"]
Esempio n. 35
0
 def test_strip_malformed_sort_field(self):
     token = self.resource._build_pagination_token([("non.existent", -1),
                                                    ("title", 1)],
                                                   self.record, 88)
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_record"], {"title": "Title"})
Esempio n. 36
0
 def _get(self, key):
     value = self._client.get(self.prefix + key)
     if not value:
         return None, 0
     data = json.loads(value)
     return data['value'], data['ttl']
Esempio n. 37
0
 def test_sorting_on_nested_field(self):
     token = self.resource._build_pagination_token(
         [("nested.subvalue", -1), ("title", 1)], self.obj, 88
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_object"], {"title": "Title", "nested.subvalue": 42})
Esempio n. 38
0
 def test_token_contains_current_offset(self):
     token = self.resource._build_pagination_token([('last_modified', -1)],
                                                   self.record, 42)
     tokeninfo = json.loads(b64decode(token).decode('ascii'))
     self.assertEqual(tokeninfo['offset'], 42)
Esempio n. 39
0
 def test_type_comes_from_structlog_event(self):
     value = self.renderer(self.logger, 'debug', {'event': 'booh'})
     log = json.loads(value)
     self.assertEqual(log['Type'], 'booh')
Esempio n. 40
0
 def test_token_contains_current_offset(self):
     token = self.resource._build_pagination_token([("last_modified", -1)], self.record, 42)
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["offset"], 42)
Esempio n. 41
0
 def test_severity_comes_from_logger_name(self):
     value = self.renderer(self.logger, 'critical', {})
     log = json.loads(value)
     self.assertEqual(log['Severity'], 0)
Esempio n. 42
0
 def test_sorting_handle_ordering_direction(self):
     token = self.resource._build_pagination_token(
         [("status", 1), ("last_modified", 1)], self.obj, 32
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_object"], {"last_modified": 1234, "status": 2})
Esempio n. 43
0
 def test_standard_entries_are_not_overwritten(self):
     value = self.renderer(self.logger, 'debug', {'Hostname': 'her'})
     log = json.loads(value)
     self.assertEqual(log['Hostname'], 'her')
Esempio n. 44
0
 def test_disambiguate_fieldname_containing_dots(self):
     token = self.resource._build_pagination_token(
         [("nested.other.subvalue", -1), ("title", 1)], self.record, 88
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_record"], {"title": "Title", "nested.other.subvalue": 43})
Esempio n. 45
0
 def test_token_contains_current_offset(self):
     token = self.resource._build_pagination_token([("last_modified", -1)], self.obj, 42)
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["offset"], 42)
Esempio n. 46
0
 def test_can_build_while_sorting_on_missing_field(self):
     token = self.resource._build_pagination_token(
         [("unknown", 1), ("title", -1), ("last_modified", -1)], self.record, 31
     )
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertEqual(tokeninfo["last_record"], {"last_modified": 1234, "title": "Title"})
Esempio n. 47
0
 def test_no_sorting_default_to_modified_field(self):
     token = self.resource._build_pagination_token([("last_modified", -1)], self.obj, 42)
     tokeninfo = json.loads(b64decode(token).decode("ascii"))
     self.assertDictEqual(tokeninfo["last_object"], {"last_modified": 1234})