Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: certificate url in export #195

Merged
merged 1 commit into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions futurex_openedx_extensions/helpers/export_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import boto3
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.urls import resolve
Expand Down Expand Up @@ -47,7 +48,7 @@ def _get_view_class_instance(path: str) -> Any:
)


def _get_mocked_request(url_with_query_str: str, fx_info: dict) -> Request:
def _get_mocked_request(url_with_query_str: str, fx_info: dict, site: Site) -> Request:
"""Create mocked request"""
if not url_with_query_str.startswith('http'):
raise FXCodedException(
Expand All @@ -59,6 +60,7 @@ def _get_mocked_request(url_with_query_str: str, fx_info: dict) -> Request:
mocked_request = factory.get(url_with_query_str, HTTP_HOST=urlparse(url_with_query_str).hostname)
mocked_request.user = fx_info['user']
mocked_request.fx_permission_info = fx_info
mocked_request.site = site
return mocked_request


Expand Down Expand Up @@ -105,7 +107,7 @@ def _paginated_response_generator(
url = f'{view_data["url"]}'
start_time = datetime.now()
while url and not view_data['end_page']:
mocked_request = _get_mocked_request(url, fx_info)
mocked_request = _get_mocked_request(url, fx_info, view_data['site'])
response = view_instance(mocked_request, **kwargs)
data, total_records = _get_response_data(response)
processed_records += len(data)
Expand Down Expand Up @@ -334,7 +336,8 @@ def export_data_to_csv(
view_data.update({
'url': url_with_query_str,
'page_size': page_size,
'view_instance': view_instance
'view_instance': view_instance,
'site': Site.objects.get(domain=view_data['site_domain'])
})

return _generate_csv_with_tracked_progress(
Expand Down
1 change: 1 addition & 0 deletions futurex_openedx_extensions/helpers/export_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ def generate_csv_url_response(self) -> dict:
'kwargs': self.kwargs, # type: ignore[attr-defined]
'path': self.request.path, # type: ignore[attr-defined]
'start_page': 1,
'site_domain': self.request.site.domain, # type: ignore[attr-defined]
'end_page': None,
}
tenant_id = self.request.fx_permission_info[ # type: ignore[attr-defined]
Expand Down
1 change: 1 addition & 0 deletions test_utils/test_settings_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def root(*args):
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.sessions',
# 'futurex_openedx_extensions.dashboard',
'futurex_openedx_extensions.helpers',
Expand Down
45 changes: 30 additions & 15 deletions tests/test_helpers/test_export_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import pytest
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.core.files.storage import default_storage
from django.test import override_settings
from storages.backends.s3boto3 import S3Boto3Storage
Expand Down Expand Up @@ -43,6 +44,12 @@ def fx_task():
)


@pytest.fixture
def site():
"""Fixture for DataExportTask."""
return Site.objects.create(domain='abc.example.com')


@pytest.mark.django_db
@pytest.mark.parametrize('user_id', [
('0'),
Expand Down Expand Up @@ -86,24 +93,24 @@ def test_export_data_to_csv_invalid_path(path, base_data): # pylint: disable=un

@pytest.mark.django_db
@override_settings(ALLOWED_HOSTS=['test-url.somthing'])
def test_get_mocked_request(base_data): # pylint: disable=unused-argument
def test_get_mocked_request(base_data, site): # pylint: disable=unused-argument, redefined-outer-name
"""Test _get_mocked_request creates a mocked request properly."""
user = get_user_model().objects.get(id=30)
fx_info = {'role': 'admin', 'user': user}
url = 'http://test-url.somthing/?test=123'
request = _get_mocked_request(url, fx_info)
request = _get_mocked_request(url, fx_info, site)
assert request.method == 'GET'
assert request.user == user
assert request.fx_permission_info == fx_info


@pytest.mark.django_db
def test_get_mocked_request_invalid_url(base_data): # pylint: disable=unused-argument
def test_get_mocked_request_invalid_url(base_data, site): # pylint: disable=unused-argument, redefined-outer-name
"""Test _get_mocked_request creates a mocked request properly."""
fx_info = {'role': 'admin', 'user': get_user_model().objects.get(id=30)}
url = '/test-url/?test=123'
with pytest.raises(FXCodedException) as exc_info:
_get_mocked_request(url, fx_info)
_get_mocked_request(url, fx_info, site)
assert str(exc_info.value) == f'CSV Export: invalid URL used when mocking the request: {url}'
assert exc_info.value.code == 6007

Expand Down Expand Up @@ -142,11 +149,14 @@ def test_get_response_data_failure(
@pytest.mark.django_db
@override_settings(ALLOWED_HOSTS=['example.com'])
@patch('futurex_openedx_extensions.helpers.export_csv._get_response_data')
def test_paginated_response_generator(mock_get_response_data, view_data):
def test_paginated_response_generator(
mock_get_response_data, view_data, site
): # pylint: disable=redefined-outer-name
"""Test _paginated_response_generator"""
url = 'http://example.com/api/data'
fx_info = {'role': 'admin', 'user': get_user_model().objects.get(id=30)}
view_data['url'] = f'{url}?test=value'
view_data['site'] = site
mocked_response_1 = MagicMock()
mocked_response_1.status_code = 200
mocked_response_1.data = {
Expand Down Expand Up @@ -191,10 +201,11 @@ def test_paginated_response_generator(mock_get_response_data, view_data):
@override_settings(ALLOWED_HOSTS=['example.com'])
@patch('futurex_openedx_extensions.helpers.export_csv._get_response_data')
def test_paginated_response_generator_for_empty_response_data(
mock_get_response_data, base_data, view_data,
): # pylint: disable=unused-argument
mock_get_response_data, base_data, view_data, site
): # pylint: disable=unused-argument, redefined-outer-name
"""Test _paginated_response_generator for empty response when there are no records"""
fx_info = {'role': 'admin', 'user': get_user_model().objects.get(id=30)}
view_data['site'] = site
mocked_response = MagicMock()
mocked_response.status_code = 200
mocked_response.data = {'count': 0, 'next': None, 'results': []}
Expand Down Expand Up @@ -447,8 +458,8 @@ def test_generate_csv_with_tracked_progress_for_last_partial_export(
@patch('futurex_openedx_extensions.helpers.export_csv._get_view_class_instance')
@patch('futurex_openedx_extensions.helpers.export_csv._generate_csv_with_tracked_progress')
def test_export_data_to_csv(
mock_generate_csv, mock_get_view, fx_task, base_data, view_data,
): # pylint: disable=redefined-outer-name, unused-argument
mock_generate_csv, mock_get_view, fx_task, base_data, view_data, site
): # pylint: disable=redefined-outer-name, unused-argument, too-many-arguments
"""Test _export_data_to_csv"""
user = get_user_model().objects.get(id=30)
mock_view_instance = MagicMock()
Expand All @@ -459,6 +470,7 @@ def test_export_data_to_csv(
fake_storage_path = f'{settings.FX_DASHBOARD_STORAGE_DIR}/{_FILENAME}'
mock_generate_csv.return_value = fake_storage_path
expected_url = f'{url}?page={view_data["start_page"]}&page_size=50'
view_data['site_domain'] = site.domain
result = export_data_to_csv(fx_task.id, url, view_data, fx_permission_info, _FILENAME)
assert result == fake_storage_path
assert fx_permission_info['user'] == user
Expand All @@ -475,8 +487,8 @@ def test_export_data_to_csv(
@patch('futurex_openedx_extensions.helpers.export_csv._get_view_class_instance')
@patch('futurex_openedx_extensions.helpers.export_csv._generate_csv_with_tracked_progress')
def test_export_data_to_csv_for_default_page_size(
mock_generate_csv, mock_get_view, fx_task, base_data, view_data,
): # pylint: disable=redefined-outer-name, unused-argument
mock_generate_csv, mock_get_view, fx_task, base_data, view_data, site
): # pylint: disable=redefined-outer-name, unused-argument, too-many-arguments
"""Test _export_data_to_csv"""
user = get_user_model().objects.get(id=30)
fake_storage_path = f'{settings.FX_DASHBOARD_STORAGE_DIR}/{_FILENAME}'
Expand All @@ -487,6 +499,7 @@ def test_export_data_to_csv_for_default_page_size(
fx_permission_info = {'user_id': user.id, 'role': 'admin'}
mock_generate_csv.return_value = fake_storage_path
expected_url = f'{url}?page={view_data["start_page"]}&page_size=100'
view_data['site_domain'] = site.domain
result = export_data_to_csv(fx_task.id, url, view_data, fx_permission_info, _FILENAME)
assert result == fake_storage_path
assert view_data['url'] == expected_url
Expand All @@ -497,8 +510,8 @@ def test_export_data_to_csv_for_default_page_size(
@patch('futurex_openedx_extensions.helpers.export_csv._get_view_class_instance')
@patch('futurex_openedx_extensions.helpers.export_csv._generate_csv_with_tracked_progress')
def test_export_data_to_csv_for_missing_pagination_class(
mock_generate_csv, mock_get_view, fx_task, base_data, view_data,
): # pylint: disable=redefined-outer-name, unused-argument
mock_generate_csv, mock_get_view, fx_task, base_data, view_data, site
): # pylint: disable=redefined-outer-name, unused-argument, too-many-arguments
"""Test _export_data_to_csv"""
user = get_user_model().objects.get(id=30)
fake_storage_path = f'{settings.FX_DASHBOARD_STORAGE_DIR}/{_FILENAME}'
Expand All @@ -509,6 +522,7 @@ def test_export_data_to_csv_for_missing_pagination_class(
fx_permission_info = {'user_id': user.id, 'role': 'admin'}
mock_generate_csv.return_value = fake_storage_path
expected_url = f'{url}?page={view_data["start_page"]}&page_size=100'
view_data['site_domain'] = site.domain
result = export_data_to_csv(fx_task.id, url, view_data, fx_permission_info, _FILENAME)
assert result == fake_storage_path
assert view_data['url'] == expected_url
Expand All @@ -519,14 +533,15 @@ def test_export_data_to_csv_for_missing_pagination_class(
@patch('futurex_openedx_extensions.helpers.export_csv._get_view_class_instance')
@patch('futurex_openedx_extensions.helpers.export_csv._generate_csv_with_tracked_progress')
def test_export_data_to_csv_for_filename_extension(
mock_generate_csv, mock_get_view, fx_task, base_data, view_data
): # pylint: disable=redefined-outer-name, unused-argument
mock_generate_csv, mock_get_view, fx_task, base_data, view_data, site
): # pylint: disable=redefined-outer-name, unused-argument, too-many-arguments
"""Test _export_data_to_csv"""
filename = 'test'
mock_view_instance = MagicMock()
mock_get_view.return_value = mock_view_instance
fx_permission_info = {'user_id': 30, 'role': 'admin'}
mock_generate_csv.return_value = 'randome/path/test.csv'
view_data['site_domain'] = site.domain
export_data_to_csv(fx_task.id, 'http://example.com/api', view_data, fx_permission_info, filename)
mock_generate_csv.assert_called_once_with(
fx_task.id, fx_permission_info, view_data, f'{filename}.csv', mock_view_instance
Expand Down
3 changes: 3 additions & 0 deletions tests/test_helpers/test_export_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import pytest
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from rest_framework import status as http_status
from rest_framework.test import APIRequestFactory

Expand All @@ -22,6 +23,7 @@ def export_csv_mixin():
view_instance = TestView()
request = APIRequestFactory().get('/')
request.user = get_user_model().objects.get(username='user30')
request.site = Site.objects.create(domain='abc.example.com')
request.fx_permission_info = {
'user': request.user,
'view_allowed_tenant_ids_any_access': [1],
Expand Down Expand Up @@ -99,6 +101,7 @@ def test_generate_csv_url_response(
'path': '/',
'start_page': 1,
'end_page': None,
'site_domain': 'abc.example.com',
}
with patch(
'futurex_openedx_extensions.helpers.export_mixins.ExportCSVMixin.export_filename',
Expand Down