Exemple #1
0
 def test_delete_a_record_update_collection_timestamp(self):
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     old_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     self.app.delete(self.record_url, headers=self.headers, status=200)
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     new_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     assert old_timestamp < new_timestamp
Exemple #2
0
 def test_delete_a_record_update_collection_timestamp(self):
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     old_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     self.app.delete(self.record_url,
                     headers=self.headers,
                     status=200)
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     new_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     assert old_timestamp < new_timestamp
Exemple #3
0
    def _raise_412_if_modified(self, record=None):
        """Raise 412 if current timestamp is superior to the one
        specified in headers.

        :raises:
            :exc:`~pyramid:pyramid.httpexceptions.HTTPPreconditionFailed`
        """
        if_match = self.request.headers.get('If-Match')
        if_none_match = self.request.headers.get('If-None-Match')

        if not if_match and not if_none_match:
            return

        if_match = decode_header(if_match) if if_match else None

        if record and if_none_match and decode_header(if_none_match) == '*':
            if record.get(self.model.deleted_field, False):
                # Tombstones should not prevent creation.
                return
            modified_since = -1  # Always raise.
        elif if_match:
            try:
                if not (if_match[0] == if_match[-1] == '"'):
                    raise ValueError()
                modified_since = int(if_match[1:-1])
            except (IndexError, ValueError):
                message = ("Invalid value for If-Match. The value should "
                           "be integer between double quotes.")
                error_details = {
                    'location': 'headers',
                    'description': message
                }
                raise_invalid(self.request, **error_details)
        else:
            # In case _raise_304_if_not_modified() did not raise.
            return

        if record:
            current_timestamp = record[self.model.modified_field]
        else:
            current_timestamp = self.model.timestamp()

        if current_timestamp > modified_since:
            error_msg = 'Resource was modified meanwhile'
            details = {'existing': record} if record else {}
            response = http_error(HTTPPreconditionFailed(),
                                  errno=ERRORS.MODIFIED_MEANWHILE,
                                  message=error_msg,
                                  details=details)
            self._add_timestamp_header(response, timestamp=current_timestamp)
            raise response
Exemple #4
0
 def test_create_a_record_update_collection_timestamp(self):
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     old_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     self.app.post_json(self.collection_url,
                        MINIMALIST_RECORD,
                        headers=self.headers,
                        status=201)
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     new_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     assert old_timestamp < new_timestamp
Exemple #5
0
 def test_create_a_record_update_collection_timestamp(self):
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     old_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     self.app.post_json(self.collection_url,
                        MINIMALIST_RECORD,
                        headers=self.headers,
                        status=201)
     collection_resp = self.app.get(self.collection_url,
                                    headers=self.headers)
     new_timestamp = int(
         decode_header(json.loads(collection_resp.headers['ETag'])))
     assert old_timestamp < new_timestamp
Exemple #6
0
    def _raise_412_if_modified(self, record=None):
        """Raise 412 if current timestamp is superior to the one
        specified in headers.

        :raises:
            :exc:`~pyramid:pyramid.httpexceptions.HTTPPreconditionFailed`
        """
        if_match = self.request.headers.get('If-Match')
        if_none_match = self.request.headers.get('If-None-Match')

        if not if_match and not if_none_match:
            return

        if_match = decode_header(if_match) if if_match else None

        if record and if_none_match and decode_header(if_none_match) == '*':
            if record.get(self.model.deleted_field, False):
                # Tombstones should not prevent creation.
                return
            modified_since = -1  # Always raise.
        elif if_match:
            try:
                if not (if_match[0] == if_match[-1] == '"'):
                    raise ValueError()
                modified_since = int(if_match[1:-1])
            except (IndexError, ValueError):
                message = ("Invalid value for If-Match. The value should "
                           "be integer between double quotes.")
                error_details = {'location': 'headers', 'description': message}
                raise_invalid(self.request, **error_details)
        else:
            # In case _raise_304_if_not_modified() did not raise.
            return

        if record:
            current_timestamp = record[self.model.modified_field]
        else:
            current_timestamp = self.model.timestamp()

        if current_timestamp > modified_since:
            error_msg = 'Resource was modified meanwhile'
            details = {'existing': record} if record else {}
            response = http_error(HTTPPreconditionFailed(),
                                  errno=ERRORS.MODIFIED_MEANWHILE,
                                  message=error_msg,
                                  details=details)
            self._add_timestamp_header(response, timestamp=current_timestamp)
            raise response
Exemple #7
0
    def _raise_304_if_not_modified(self, record=None):
        """Raise 304 if current timestamp is inferior to the one specified
        in headers.

        :raises: :exc:`~pyramid:pyramid.httpexceptions.HTTPNotModified`
        """
        if_none_match = self.request.headers.get('If-None-Match')

        if not if_none_match:
            return

        if_none_match = decode_header(if_none_match)

        try:
            if not (if_none_match[0] == if_none_match[-1] == '"'):
                raise ValueError()
            modified_since = int(if_none_match[1:-1])
        except (IndexError, ValueError):
            if if_none_match == '*':
                return
            error_details = {
                'location': 'headers',
                'description': "Invalid value for If-None-Match"
            }
            raise_invalid(self.request, **error_details)

        if record:
            current_timestamp = record[self.model.modified_field]
        else:
            current_timestamp = self.model.timestamp()

        if current_timestamp <= modified_since:
            response = HTTPNotModified()
            self._add_timestamp_header(response, timestamp=current_timestamp)
            raise response
Exemple #8
0
    def _raise_304_if_not_modified(self, record=None):
        """Raise 304 if current timestamp is inferior to the one specified
        in headers.

        :raises: :exc:`~pyramid:pyramid.httpexceptions.HTTPNotModified`
        """
        if_none_match = self.request.headers.get('If-None-Match')

        if not if_none_match:
            return

        if_none_match = decode_header(if_none_match)

        try:
            if not (if_none_match[0] == if_none_match[-1] == '"'):
                raise ValueError()
            modified_since = int(if_none_match[1:-1])
        except (IndexError, ValueError):
            if if_none_match == '*':
                return
            error_details = {
                'location': 'headers',
                'description': "Invalid value for If-None-Match"
            }
            raise_invalid(self.request, **error_details)

        if record:
            current_timestamp = record[self.model.modified_field]
        else:
            current_timestamp = self.model.timestamp()

        if current_timestamp <= modified_since:
            response = HTTPNotModified()
            self._add_timestamp_header(response, timestamp=current_timestamp)
            raise response
Exemple #9
0
 def test_filter_with__to_return_an_alert_header(self):
     self.resource.request.GET = {'_to': '3'}
     self.resource.collection_get()
     self.assertIn('Alert', self.resource.request.response.headers)
     alert = self.resource.request.response.headers['Alert']
     self.assertDictEqual(
         decode_header(json.loads(alert)),
         {
             'code': 'soft-eol',
             'message': ('_to is now deprecated, '
                         'you should use _before instead'),
             'url': ('http://cliquet.rtfd.org/en/2.4.0/api/resource'
                     '.html#list-of-available-url-parameters')
         })
Exemple #10
0
 def test_filter_with__to_return_an_alert_header(self):
     self.resource.request.GET = {'_to': '3'}
     self.resource.collection_get()
     self.assertIn('Alert', self.resource.request.response.headers)
     alert = self.resource.request.response.headers['Alert']
     self.assertDictEqual(
         decode_header(json.loads(alert)), {
             'code':
             'soft-eol',
             'message': ('_to is now deprecated, '
                         'you should use _before instead'),
             'url': ('http://cliquet.rtfd.org/en/2.4.0/api/resource'
                     '.html#list-of-available-url-parameters')
         })
Exemple #11
0
 def test_returns_an_unicode__string_if_passed_bytes_and_encoding(self):
     entry = 'Rémy'.encode('latin-1')
     value = decode_header(entry, 'latin-1')
     self.assertEqual(type(value), six.text_type)
Exemple #12
0
 def test_returns_an_unicode__string_if_passed_bytes(self):
     entry = 'Toto'.encode('utf-8')
     value = decode_header(entry)
     self.assertEqual(type(value), six.text_type)
Exemple #13
0
 def test_returns_an_unicode__string_if_passed_bytes(self):
     entry = 'Toto'.encode('utf-8')
     value = decode_header(entry)
     self.assertEqual(type(value), six.text_type)
Exemple #14
0
 def verify_alert_header(self, request, expected):
     self.assertIn('Alert', request.response.headers)
     alert = request.response.headers['Alert']
     self.assertDictEqual(decode_header(json.loads(alert)), expected)
Exemple #15
0
 def verify_alert_header(self, request, expected):
     self.assertIn('Alert', request.response.headers)
     alert = request.response.headers['Alert']
     self.assertDictEqual(
         decode_header(json.loads(alert)),
         expected)
Exemple #16
0
 def test_returns_an_unicode__string_if_passed_bytes_and_encoding(self):
     entry = 'Rémy'.encode('latin-1')
     value = decode_header(entry, 'latin-1')
     self.assertEqual(type(value), six.text_type)
Exemple #17
0
 def test_returns_an_unicode_string_if_passed_a_string(self):
     entry = 'Toto'
     value = decode_header(entry)
     self.assertEqual(entry, value)
Exemple #18
0
 def test_returns_an_unicode_string_if_passed_a_string(self):
     entry = 'Toto'
     value = decode_header(entry)
     self.assertEqual(entry, value)