Beispiel #1
0
    def test_etag_check_etag(self, app, schemas):

        etag_schema = schemas.DocEtagSchema
        old_item = {'item_id': 1, 'db_field': 0}
        new_item = {'item_id': 1, 'db_field': 1}

        old_etag = _generate_etag(old_item)
        old_etag_with_schema = _generate_etag(old_item, etag_schema)

        with app.test_request_context('/', headers={'If-Match': old_etag}):
            check_etag(old_item)
            if is_etag_enabled(app):
                with pytest.raises(PreconditionFailed):
                    check_etag(new_item)
            else:
                check_etag(new_item)
            disable_etag_for_request()
            check_etag(old_item)
            check_etag(new_item)
        with app.test_request_context(
                '/', headers={'If-Match': old_etag_with_schema}):
            check_etag(old_item, etag_schema)
            if is_etag_enabled(app):
                with pytest.raises(PreconditionFailed):
                    check_etag(new_item, etag_schema)
            else:
                check_etag(new_item)
            disable_etag_for_request()
            check_etag(old_item)
            check_etag(new_item)
Beispiel #2
0
    def test_etag_set_etag(self, app, schemas):

        etag_schema = schemas.DocEtagSchema
        item = {'item_id': 1, 'db_field': 0}

        etag = _generate_etag(item)
        etag_with_schema = _generate_etag(item, etag_schema)

        with app.test_request_context('/'):
            set_etag(item)
            if is_etag_enabled(app):
                assert _get_etag_ctx()['etag'] == etag
                del _get_etag_ctx()['etag']
            else:
                assert 'etag' not in _get_etag_ctx()
            disable_etag_for_request()
            set_etag(item)
            assert 'etag' not in _get_etag_ctx()
        with app.test_request_context('/', headers={'If-None-Match': etag}):
            if is_etag_enabled(app):
                with pytest.raises(NotModified):
                    set_etag(item)
            else:
                set_etag(item)
                assert 'etag' not in _get_etag_ctx()
            disable_etag_for_request()
            set_etag(item)
            assert 'etag' not in _get_etag_ctx()
        with app.test_request_context(
                '/', headers={'If-None-Match': etag_with_schema}):
            if is_etag_enabled(app):
                with pytest.raises(NotModified):
                    set_etag(item, etag_schema)
            else:
                set_etag(item, etag_schema)
                assert 'etag' not in _get_etag_ctx()
            disable_etag_for_request()
            set_etag(item, etag_schema)
            assert 'etag' not in _get_etag_ctx()
        with app.test_request_context('/', headers={'If-None-Match': 'dummy'}):
            if is_etag_enabled(app):
                set_etag(item)
                assert _get_etag_ctx()['etag'] == etag
                del _get_etag_ctx()['etag']
                set_etag(item, etag_schema)
                assert _get_etag_ctx()['etag'] == etag_with_schema
                del _get_etag_ctx()['etag']
            else:
                set_etag(item)
                assert 'etag' not in _get_etag_ctx()
                set_etag(item, etag_schema)
                assert 'etag' not in _get_etag_ctx()
            disable_etag_for_request()
            set_etag(item)
            assert 'etag' not in _get_etag_ctx()
            set_etag(item, etag_schema)
            assert 'etag' not in _get_etag_ctx()
Beispiel #3
0
    def test_etag_set_etag_in_response(self, app, schemas, paginate):

        etag_schema = schemas.DocEtagSchema
        item = {'item_id': 1, 'db_field': 0}
        extra_data = ('Dummy pagination header', ) if paginate else tuple()
        etag = _generate_etag(item, extra_data=extra_data)
        etag_with_schema = _generate_etag(item,
                                          etag_schema,
                                          extra_data=extra_data)

        with app.test_request_context('/'):
            resp = Response()
            if extra_data:
                resp.headers['X-Pagination'] = 'Dummy pagination header'
            if is_etag_enabled(app):
                set_etag_in_response(resp, item, None)
                assert resp.get_etag() == (etag, False)
                set_etag_in_response(resp, item, etag_schema)
                assert resp.get_etag() == (etag_with_schema, False)
            else:
                set_etag_in_response(resp, item, None)
                assert resp.get_etag() == (None, None)
                set_etag_in_response(resp, item, etag_schema)
                assert resp.get_etag() == (None, None)
            disable_etag_for_request()
            resp = Response()
            set_etag_in_response(resp, item, None)
            assert resp.get_etag() == (None, None)
            set_etag_in_response(resp, item, etag_schema)
            assert resp.get_etag() == (None, None)
Beispiel #4
0
    def test_etag_verify_check_etag_warning(self, app, method):

        old_item = {'item_id': 1, 'db_field': 0}
        old_etag = _generate_etag(old_item)

        with mock.patch.object(app.logger, 'warning') as mock_warning:
            with app.test_request_context('/',
                                          method=method,
                                          headers={'If-Match': old_etag}):
                verify_check_etag()
                if (is_etag_enabled(app)
                        and method in ['PUT', 'PATCH', 'DELETE']):
                    assert mock_warning.called
                    mock_warning.reset_mock()
                else:
                    assert not mock_warning.called
                check_etag(old_item)
                verify_check_etag()
                assert not mock_warning.called
                disable_etag_for_request()
                verify_check_etag()
                assert not mock_warning.called
                check_etag(old_item)
                verify_check_etag()
                assert not mock_warning.called
Beispiel #5
0
    def test_etag_is_etag_enabled_for_request(self, app):

        with app.test_request_context('/'):
            assert (
                is_etag_enabled_for_request() == is_etag_enabled(current_app))
            disable_etag_for_request()
            assert not is_etag_enabled_for_request()
Beispiel #6
0
    def test_etag_check_precondition(self, app, method):

        with app.test_request_context('/', method=method):
            if method in ['PUT', 'PATCH', 'DELETE'] and is_etag_enabled(app):
                with pytest.raises(PreconditionRequired):
                    check_precondition()
            else:
                check_precondition()
            disable_etag_for_request()
            check_precondition()
Beispiel #7
0
    def test_etag_verify_check_etag_exception(self, app, method, debug,
                                              testing):

        app.config['DEBUG'] = debug
        app.config['TESTING'] = testing

        with NoLoggingContext(app):
            with app.test_request_context('/', method=method):
                if ((debug or testing) and is_etag_enabled(app)
                        and method in ['PUT', 'PATCH', 'DELETE']):
                    with pytest.raises(
                            CheckEtagNotCalledError,
                            match='ETag enabled but not checked in endpoint'):
                        verify_check_etag()
                else:
                    verify_check_etag()
Beispiel #8
0
    def test_etag_operations_etag_disabled(self, app_with_etag):

        client = app_with_etag.test_client()
        assert not is_etag_enabled(app_with_etag)

        # GET without ETag: OK
        response = client.get('/test/')
        assert response.status_code == 200

        # GET with whatever ETag: OK (dummy ETag ignored)
        response = client.get('/test/',
                              headers={'If-None-Match': 'dummy_etag'})
        assert response.status_code == 200

        # POST item_1
        item_1_data = {'field': 0}
        response = client.post('/test/',
                               data=json.dumps(item_1_data),
                               content_type='application/json')
        assert response.status_code == 201
        item_1_id = response.json['item_id']

        # GET by ID: OK
        response = client.get('/test/{}'.format(item_1_id))
        assert response.status_code == 200

        # GET by ID with whatever ETag: OK (dummy ETag ignored)
        response = client.get('/test/{}'.format(item_1_id),
                              headers={'If-None-Match': 'dummy_etag'})
        assert response.status_code == 200

        # PUT without ETag: OK
        item_1_data['field'] = 1
        response = client.put('/test/{}'.format(item_1_id),
                              data=json.dumps(item_1_data),
                              content_type='application/json')
        assert response.status_code == 200

        # PUT with whatever ETag: OK (dummy ETag ignored)
        item_1_data['field'] = 2
        response = client.put('/test/{}'.format(item_1_id),
                              data=json.dumps(item_1_data),
                              content_type='application/json')
        assert response.status_code == 200

        # POST item_2
        item_2_data = {'field': 9}
        response = client.post('/test/',
                               data=json.dumps(item_2_data),
                               content_type='application/json')
        assert response.status_code == 201
        item_2_id = response.json['item_id']

        # DELETE without ETag: No Content (dummy ETag ignored)
        response = client.delete('/test/{}'.format(item_1_id))
        assert response.status_code == 204

        # DELETE with whatever ETag: No Content (dummy ETag ignored)
        response = client.delete('/test/{}'.format(item_2_id),
                                 headers={'If-Match': 'dummy_etag'})
        assert response.status_code == 204
Beispiel #9
0
    def test_etag_operations_etag_enabled(self, app_with_etag):

        client = app_with_etag.test_client()
        assert is_etag_enabled(app_with_etag)

        # GET without ETag: OK
        response = client.get('/test/')
        assert response.status_code == 200
        list_etag = response.headers['ETag']

        # GET with correct ETag: Not modified
        response = client.get('/test/', headers={'If-None-Match': list_etag})
        assert response.status_code == 304

        # POST item_1
        item_1_data = {'field': 0}
        response = client.post('/test/',
                               data=json.dumps(item_1_data),
                               content_type='application/json')
        assert response.status_code == 201
        item_1_id = response.json['item_id']

        # GET with wrong/outdated ETag: OK
        response = client.get('/test/', headers={'If-None-Match': list_etag})
        assert response.status_code == 200

        # GET by ID without ETag: OK
        response = client.get('/test/{}'.format(item_1_id))
        assert response.status_code == 200
        item_etag = response.headers['ETag']

        # GET by ID with correct ETag: Not modified
        response = client.get('/test/{}'.format(item_1_id),
                              headers={'If-None-Match': item_etag})
        assert response.status_code == 304

        # PUT without ETag: Precondition required error
        item_1_data['field'] = 1
        response = client.put('/test/{}'.format(item_1_id),
                              data=json.dumps(item_1_data),
                              content_type='application/json')
        assert response.status_code == 428

        # PUT with correct ETag: OK
        response = client.put('/test/{}'.format(item_1_id),
                              data=json.dumps(item_1_data),
                              content_type='application/json',
                              headers={'If-Match': item_etag})
        assert response.status_code == 200
        new_item_etag = response.headers['ETag']

        # PUT with wrong/outdated ETag: Precondition failed error
        item_1_data['field'] = 2
        response = client.put('/test/{}'.format(item_1_id),
                              data=json.dumps(item_1_data),
                              content_type='application/json',
                              headers={'If-Match': item_etag})
        assert response.status_code == 412

        # GET by ID with wrong/outdated ETag: OK
        response = client.get('/test/{}'.format(item_1_id),
                              headers={'If-None-Match': item_etag})
        assert response.status_code == 200

        # DELETE without ETag: Precondition required error
        response = client.delete('/test/{}'.format(item_1_id))
        assert response.status_code == 428

        # DELETE with wrong/outdated ETag: Precondition failed error
        response = client.delete('/test/{}'.format(item_1_id),
                                 headers={'If-Match': item_etag})
        assert response.status_code == 412

        # DELETE with correct ETag: No Content
        response = client.delete('/test/{}'.format(item_1_id),
                                 headers={'If-Match': new_item_etag})
        assert response.status_code == 204