Skip to content

Commit

Permalink
fix: fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NiedielnitsevIvan committed Feb 14, 2025
1 parent 32fcd2a commit 64c3177
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 121 deletions.
1 change: 1 addition & 0 deletions cms/envs/production.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def get_env_setting(setting):
ENTERPRISE_CONSENT_API_URL = ENV_TOKENS.get('ENTERPRISE_CONSENT_API_URL', LMS_INTERNAL_ROOT_URL + '/consent/api/v1/')
AUTHORING_API_URL = ENV_TOKENS.get('AUTHORING_API_URL', '')
# Note that FEATURES['PREVIEW_LMS_BASE'] gets read in from the environment file.

CHAT_COMPLETION_API = ENV_TOKENS.get('CHAT_COMPLETION_API', '')
CHAT_COMPLETION_API_KEY = ENV_TOKENS.get('CHAT_COMPLETION_API_KEY', '')
LEARNER_ENGAGEMENT_PROMPT_FOR_ACTIVE_CONTRACT = ENV_TOKENS.get('LEARNER_ENGAGEMENT_PROMPT_FOR_ACTIVE_CONTRACT', '')
Expand Down
26 changes: 0 additions & 26 deletions lms/djangoapps/mobile_api/tests/test_course_info_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
from lms.djangoapps.mobile_api.utils import API_V05, API_V1, API_V2, API_V3, API_V4
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.features.course_experience import ENABLE_COURSE_GOALS
from openedx.features.offline_mode.constants import DEFAULT_OFFLINE_SUPPORTED_XBLOCKS
from openedx.features.offline_mode.toggles import ENABLE_OFFLINE_MODE
from xmodule.html_block import CourseInfoBlock # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
Expand Down Expand Up @@ -489,30 +487,6 @@ def test_not_extend_block_info_with_offline_data_for_version_less_v4_and_any_waf
for block_info in response.data['blocks'].values():
self.assertNotIn('offline_download', block_info)

@override_waffle_flag(ENABLE_OFFLINE_MODE, active=True)
@patch('openedx.features.offline_mode.html_manipulator.save_mathjax_to_xblock_assets')
def test_create_offline_content_integration_test(self, save_mathjax_to_xblock_assets_mock: MagicMock) -> None:
UserFactory.create(username='offline_mode_worker', password='password', is_staff=True)
handle_course_published_url = reverse('offline_mode:handle_course_published')
self.client.login(username='offline_mode_worker', password='password')

handler_response = self.client.post(handle_course_published_url, {'course_id': str(self.course.id)})
self.assertEqual(handler_response.status_code, status.HTTP_200_OK)

url = reverse('blocks_info_in_course', kwargs={'api_version': API_V4})

response = self.verify_response(url=url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
for block_info in response.data['blocks'].values():
if block_type := block_info.get('type'):
if block_type in DEFAULT_OFFLINE_SUPPORTED_XBLOCKS:
expected_offline_content_url = f'/uploads/{self.course.id}/{block_info["block_id"]}.zip'
self.assertIn('offline_download', block_info)
self.assertIn('file_url', block_info['offline_download'])
self.assertIn('last_modified', block_info['offline_download'])
self.assertIn('file_size', block_info['offline_download'])
self.assertEqual(expected_offline_content_url, block_info['offline_download']['file_url'])


class TestCourseEnrollmentDetailsView(MobileAPITestCase, MilestonesTestCaseMixin): # lint-amnesty, pylint: disable=test-inherits-tests
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def test_block_storage_path_exists(self) -> None:

result = block_storage_path(xblock_mock)

self.assertEqual(result, 'course_key_mock/')
self.assertEqual(result, 'offline_content/course_key_mock/')

def test_block_storage_path_does_not_exists(self) -> None:
result = block_storage_path()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,13 @@ def setUp(self):
def test_generate_offline_content(self, save_mathjax_to_xblock_assets_mock):
OfflineContentGenerator(self.html_block, self.html_data).generate_offline_content()

expected_offline_content_path = 'test_root/uploads/course-v1:RaccoonGang+1+2024/HTML_xblock_for_Offline.zip'
expected_offline_content_path = (
'test_root/uploads/offline_content/course-v1:RaccoonGang+1+2024/HTML_xblock_for_Offline.zip'
)

save_mathjax_to_xblock_assets_mock.assert_called_once()
self.assertTrue(os.path.exists(expected_offline_content_path))
shutil.rmtree('test_root/uploads/course-v1:RaccoonGang+1+2024', ignore_errors=True)
shutil.rmtree('test_root/uploads/offline_content/course-v1:RaccoonGang+1+2024', ignore_errors=True)

def test_save_xblock_html_to_temp_dir(self):
shutil.rmtree('test_root/assets', ignore_errors=True)
Expand Down
133 changes: 41 additions & 92 deletions openedx/features/offline_mode/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,140 +2,89 @@
Tests for the testing Offline Mode tacks.
"""

from unittest import TestCase
import pytest
from unittest.mock import MagicMock, Mock, call, patch

from ddt import data, ddt, unpack
from django.conf import settings
from django.http.response import Http404
from opaque_keys.edx.keys import CourseKey, UsageKey
from openedx.features.offline_mode.constants import MAX_RETRY_ATTEMPTS, OFFLINE_SUPPORTED_XBLOCKS
from common.djangoapps.student.tests.factories import UserFactory
from openedx.features.offline_mode.tasks import (
generate_offline_content_for_block,
generate_offline_content_for_course,
)

from .base import CourseForOfflineTestCase

@ddt
class GenerateOfflineContentTasksTestCase(TestCase):

@pytest.mark.django_db
class GenerateOfflineContentTasksTestCase(CourseForOfflineTestCase):
"""
Test case for the testing generating offline content tacks.
"""

def setUp(self) -> None:
self.user = UserFactory(username=settings.OFFLINE_SERVICE_WORKER_USERNAME)
super().setUp()

@patch('openedx.features.offline_mode.tasks.OfflineContentGenerator')
@patch('openedx.features.offline_mode.tasks.modulestore')
@patch('openedx.features.offline_mode.tasks.is_modified', return_value=True)
def test_generate_offline_content_for_block_success(
self,
modulestore_mock: MagicMock,
is_modified_mock: MagicMock,
offline_content_generator_mock: MagicMock,
) -> None:
block_id_mock = 'block-v1:a+a+a+type@problem+block@fb81e4dbfd4945cb9318d6bc460a956c'

generate_offline_content_for_block(block_id_mock)
generate_offline_content_for_block(str(self.html_block.location))

modulestore_mock.assert_called_once_with()
modulestore_mock.return_value.get_item.assert_called_once_with(UsageKey.from_string(block_id_mock))
offline_content_generator_mock.assert_called_once_with(modulestore_mock.return_value.get_item.return_value)
offline_content_generator_mock.return_value.generate_offline_content.assert_called_once_with()
is_modified_mock.assert_called()
offline_content_generator_mock.assert_called_once()
offline_content_generator_mock.return_value.generate_offline_content.assert_called_once()

@patch('openedx.features.offline_mode.tasks.OfflineContentGenerator')
@patch('openedx.features.offline_mode.tasks.modulestore', side_effect=Http404)
def test_generate_offline_content_for_block_with_exception_in_modulestore(
self,
modulestore_mock: MagicMock,
offline_content_generator_mock: MagicMock,
) -> None:
block_id_mock = 'block-v1:a+a+a+type@problem+block@fb81e4dbfd4945cb9318d6bc460a956c'

generate_offline_content_for_block.delay(block_id_mock)

self.assertEqual(modulestore_mock.call_count, MAX_RETRY_ATTEMPTS + 1)
offline_content_generator_mock.assert_not_called()

@patch('openedx.features.offline_mode.tasks.OfflineContentGenerator', side_effect=Http404)
@patch('openedx.features.offline_mode.tasks.modulestore')
def test_generate_offline_content_for_block_with_exception_in_offline_content_generation(
self,
modulestore_mock: MagicMock,
offline_content_generator_mock: MagicMock,
) -> None:
block_id_mock = 'block-v1:a+a+a+type@problem+block@fb81e4dbfd4945cb9318d6bc460a956c'

generate_offline_content_for_block.delay(block_id_mock)
with pytest.raises(Http404):
generate_offline_content_for_block(str(self.html_block.location))

self.assertEqual(modulestore_mock.call_count, MAX_RETRY_ATTEMPTS + 1)
self.assertEqual(offline_content_generator_mock.call_count, MAX_RETRY_ATTEMPTS + 1)
modulestore_mock.assert_called_once()
offline_content_generator_mock.assert_not_called()
offline_content_generator_mock.return_value.generate_offline_content.assert_not_called()

@patch('openedx.features.offline_mode.tasks.generate_offline_content_for_block')
@patch('openedx.features.offline_mode.tasks.is_modified')
@patch('openedx.features.offline_mode.tasks.modulestore')
def test_generate_offline_content_for_course_supported_block_types(
self,
modulestore_mock: MagicMock,
is_modified_mock: MagicMock,
generate_offline_content_for_block_mock: MagicMock,
) -> None:
course_id_mock = 'course-v1:a+a+a'
xblock_location_mock = 'xblock_location_mock'
modulestore_mock.return_value.get_items.return_value = [
Mock(location=xblock_location_mock, closed=Mock(return_value=False))
]

expected_call_args_for_modulestore_get_items = [
call(CourseKey.from_string(course_id_mock), qualifiers={'category': offline_supported_block_type})
for offline_supported_block_type in OFFLINE_SUPPORTED_XBLOCKS
]
expected_call_args_is_modified_mock = [
call(modulestore_mock.return_value.get_items.return_value[0]) for _ in OFFLINE_SUPPORTED_XBLOCKS
]
expected_call_args_for_generate_offline_content_for_block_mock = [
call([xblock_location_mock]) for _ in OFFLINE_SUPPORTED_XBLOCKS
]

generate_offline_content_for_course(course_id_mock)

self.assertEqual(modulestore_mock.call_count, len(OFFLINE_SUPPORTED_XBLOCKS))
self.assertListEqual(
modulestore_mock.return_value.get_items.call_args_list, expected_call_args_for_modulestore_get_items
)
self.assertListEqual(is_modified_mock.call_args_list, expected_call_args_is_modified_mock)
self.assertListEqual(
generate_offline_content_for_block_mock.apply_async.call_args_list,
expected_call_args_for_generate_offline_content_for_block_mock
is_modified_mock.return_value = True

generate_offline_content_for_course(str(self.course.id))

generate_offline_content_for_block_mock.assert_has_calls(
[
call.apply_async([str(self.html_block.location)]),
call.apply_async([str(self.problem_block.location)]),
],
)

@patch('openedx.features.offline_mode.tasks.generate_offline_content_for_block')
@patch('openedx.features.offline_mode.tasks.is_modified')
@patch('openedx.features.offline_mode.tasks.modulestore')
@data(
(False, False),
(True, False),
(False, True),
)
@unpack
def test_generate_offline_content_for_course_supported_block_types_for_closed_or_not_modified_xblock(
@patch('openedx.features.offline_mode.tasks.get_course_blocks')
def test_generate_offline_content_for_course_unsupported_block_type(
self,
is_modified_value_mock: bool,
is_closed_value_mock: bool,
modulestore_mock: MagicMock,
get_course_blocks_mock: MagicMock,
is_modified_mock: MagicMock,
generate_offline_content_for_block_mock: MagicMock,
) -> None:
course_id_mock = 'course-v1:a+a+a'
xblock_location_mock = 'xblock_location_mock'
modulestore_mock.return_value.get_items.return_value = [
Mock(location=xblock_location_mock, closed=Mock(return_value=is_closed_value_mock))
]
is_modified_mock.return_value = is_modified_value_mock

expected_call_args_for_modulestore_get_items = [
call(CourseKey.from_string(course_id_mock), qualifiers={'category': offline_supported_block_type})
for offline_supported_block_type in OFFLINE_SUPPORTED_XBLOCKS
]

generate_offline_content_for_course(course_id_mock)

self.assertEqual(modulestore_mock.call_count, len(OFFLINE_SUPPORTED_XBLOCKS))
self.assertListEqual(
modulestore_mock.return_value.get_items.call_args_list, expected_call_args_for_modulestore_get_items
)
is_modified_mock.return_value = True
xblock_mock = Mock(closed=Mock(return_value=False))
get_course_blocks_mock().get_item.return_value = xblock_mock
xblock_mock.block_type = 'unsupported_block_type'

generate_offline_content_for_course(str(self.course.id))

generate_offline_content_for_block_mock.assert_not_called()

0 comments on commit 64c3177

Please sign in to comment.