diff --git a/swh/web/api/apiresponse.py b/swh/web/api/apiresponse.py --- a/swh/web/api/apiresponse.py +++ b/swh/web/api/apiresponse.py @@ -18,10 +18,11 @@ from swh.web.config import get_config -def compute_link_header(rv, options): +def compute_link_header(request, rv, options): """Add Link header in returned value results. Args: + request: a DRF Request object rv (dict): dictionary with keys: - headers: potential headers with 'link-next' and 'link-prev' @@ -43,10 +44,10 @@ if 'link-next' in rv_headers: link_headers.append('<%s>; rel="next"' % ( - rv_headers['link-next'])) + request.build_absolute_uri(rv_headers['link-next']))) if 'link-prev' in rv_headers: link_headers.append('<%s>; rel="previous"' % ( - rv_headers['link-prev'])) + request.build_absolute_uri(rv_headers['link-prev']))) if link_headers: link_header_str = ','.join(link_headers) @@ -108,7 +109,7 @@ """ if data: - options['headers'] = compute_link_header(data, options) + options['headers'] = compute_link_header(request, data, options) data = transform(data) data = filter_by_fields(request, data) doc_env = doc_data diff --git a/swh/web/tests/api/test_apiresponse.py b/swh/web/tests/api/test_apiresponse.py --- a/swh/web/tests/api/test_apiresponse.py +++ b/swh/web/tests/api/test_apiresponse.py @@ -5,42 +5,49 @@ import json -from rest_framework.test import APIRequestFactory - from swh.web.api.apiresponse import ( compute_link_header, transform, make_api_response, filter_by_fields ) -api_request_factory = APIRequestFactory() - -def test_compute_link_header(): +def test_compute_link_header(api_request_factory): + next_link = '/api/endpoint/next' + prev_link = '/api/endpoint/prev' rv = { - 'headers': {'link-next': 'foo', 'link-prev': 'bar'}, + 'headers': {'link-next': next_link, 'link-prev': prev_link}, 'results': [1, 2, 3] } options = {} - headers = compute_link_header(rv, options) + request = api_request_factory.get('/api/endpoint/') + + headers = compute_link_header(request, rv, options) - assert headers == {'Link': '; rel="next",; rel="previous"'} + assert headers == { + 'Link': (f'<{request.build_absolute_uri(next_link)}>; rel="next",' + f'<{request.build_absolute_uri(prev_link)}>; rel="previous"') + } -def test_compute_link_header_nothing_changed(): +def test_compute_link_header_nothing_changed(api_request_factory): rv = {} options = {} - headers = compute_link_header(rv, options) + request = api_request_factory.get('/api/test/path/') + + headers = compute_link_header(request, rv, options) assert headers == {} -def test_compute_link_header_nothing_changed_2(): +def test_compute_link_header_nothing_changed_2(api_request_factory): rv = {'headers': {}} options = {} - headers = compute_link_header(rv, options) + request = api_request_factory.get('/api/test/path/') + + headers = compute_link_header(request, rv, options) assert headers == {} @@ -71,7 +78,7 @@ assert transform(rv) == {'some-key': 'some-value'} -def test_swh_multi_response_mimetype(mocker): +def test_swh_multi_response_mimetype(mocker, api_request_factory): mock_shorten_path = mocker.patch('swh.web.api.apiresponse.shorten_path') mock_filter = mocker.patch('swh.web.api.apiresponse.filter_by_fields') mock_json = mocker.patch('swh.web.api.apiresponse.json') @@ -123,7 +130,7 @@ assert rv.template_name == 'api/apidoc.html' -def test_swh_filter_renderer_do_nothing(): +def test_swh_filter_renderer_do_nothing(api_request_factory): input_data = {'a': 'some-data'} request = api_request_factory.get('/api/test/path/', data={}) @@ -134,7 +141,7 @@ assert actual_data == input_data -def test_swh_filter_renderer_do_filter(mocker): +def test_swh_filter_renderer_do_filter(mocker, api_request_factory): mock_ffk = mocker.patch('swh.web.api.apiresponse.utils.filter_field_keys') mock_ffk.return_value = {'a': 'some-data'} diff --git a/swh/web/tests/api/views/test_content.py b/swh/web/tests/api/views/test_content.py --- a/swh/web/tests/api/views/test_content.py +++ b/swh/web/tests/api/views/test_content.py @@ -117,10 +117,11 @@ query_params={'per_page': 2}) rv = api_client.get(url) - next_url = reverse('api-1-content-symbol', - url_args={'q': contents_with_ctags['symbol_name']}, - query_params={'last_sha1': rv.data[1]['sha1'], - 'per_page': 2}) + next_url = rv.wsgi_request.build_absolute_uri( + reverse('api-1-content-symbol', + url_args={'q': contents_with_ctags['symbol_name']}, + query_params={'last_sha1': rv.data[1]['sha1'], + 'per_page': 2})) assert rv['Link'] == '<%s>; rel="next"' % next_url diff --git a/swh/web/tests/api/views/test_revision.py b/swh/web/tests/api/views/test_revision.py --- a/swh/web/tests/api/views/test_revision.py +++ b/swh/web/tests/api/views/test_revision.py @@ -89,10 +89,10 @@ if has_next: assert 'Link' in rv - next_log_url = reverse( - 'api-1-revision-log', - url_args={'sha1_git': expected_log[-1]['id']}, - query_params={'per_page': per_page}) + next_log_url = rv.wsgi_request.build_absolute_uri( + reverse('api-1-revision-log', + url_args={'sha1_git': expected_log[-1]['id']}, + query_params={'per_page': per_page})) assert next_log_url in rv['Link'] diff --git a/swh/web/tests/api/views/test_snapshot.py b/swh/web/tests/api/views/test_snapshot.py --- a/swh/web/tests/api/views/test_snapshot.py +++ b/swh/web/tests/api/views/test_snapshot.py @@ -72,11 +72,11 @@ whole_snapshot['branches'].update(expected_data['branches']) if branches_offset < len(snapshot_branches): - next_url = reverse( - 'api-1-snapshot', - url_args={'snapshot_id': snapshot}, - query_params={'branches_from': next_branch, - 'branches_count': branches_count}) + next_url = rv.wsgi_request.build_absolute_uri( + reverse('api-1-snapshot', + url_args={'snapshot_id': snapshot}, + query_params={'branches_from': next_branch, + 'branches_count': branches_count})) assert rv['Link'] == '<%s>; rel="next"' % next_url else: assert not rv.has_header('Link') diff --git a/swh/web/tests/conftest.py b/swh/web/tests/conftest.py --- a/swh/web/tests/conftest.py +++ b/swh/web/tests/conftest.py @@ -14,7 +14,7 @@ from django.core.cache import cache from hypothesis import settings, HealthCheck -from rest_framework.test import APIClient +from rest_framework.test import APIClient, APIRequestFactory from swh.model.hashutil import ALGORITHMS, hash_to_bytes from swh.web.common import converters @@ -89,6 +89,12 @@ return APIClient() +# Fixture to get API request factory from Django REST Framework +@pytest.fixture(scope='module') +def api_request_factory(): + return APIRequestFactory() + + # Initialize tests data @pytest.fixture(autouse=True) def tests_data():