diff --git a/cms/djangoapps/contentstore/views/tests/test_assets.py b/cms/djangoapps/contentstore/views/tests/test_assets.py index 6ee861888809..3f468e3f39cf 100644 --- a/cms/djangoapps/contentstore/views/tests/test_assets.py +++ b/cms/djangoapps/contentstore/views/tests/test_assets.py @@ -27,6 +27,7 @@ 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 from xmodule.modulestore.xml_importer import import_course_from_xml # lint-amnesty, pylint: disable=wrong-import-order +from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT @@ -41,6 +42,9 @@ class AssetsTestCase(CourseTestCase): """ Parent class for all asset tests. """ + + MODULESTORE = TEST_DATA_SPLIT_MODULESTORE + def setUp(self): super().setUp() self.url = reverse_course_url('assets_handler', self.course.id) @@ -96,6 +100,7 @@ def test_pdf_asset(self): TEST_DATA_DIR, ['toy'], static_content_store=contentstore(), + create_if_not_present=True, verbose=True ) course = course_items[0] @@ -103,8 +108,8 @@ def test_pdf_asset(self): # Test valid contentType for pdf asset (textbook.pdf) resp = self.client.get(url, HTTP_ACCEPT='application/json') - self.assertContains(resp, "/c4x/edX/toy/asset/textbook.pdf") - asset_location = AssetKey.from_string('/c4x/edX/toy/asset/textbook.pdf') + self.assertContains(resp, "/asset-v1:edX+toy+2012_Fall+type@asset+block@textbook.pdf") + asset_location = AssetKey.from_string('asset-v1:edX+toy+2012_Fall+type@asset+block@textbook.pdf') content = contentstore().find(asset_location) # Check after import textbook.pdf has valid contentType ('application/pdf') @@ -450,7 +455,8 @@ def test_locking(self): """ def verify_asset_locked_state(locked): """ Helper method to verify lock state in the contentstore """ - asset_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/sample_static.html') + asset_location = StaticContent.get_location_from_path( + 'asset-v1:edX+toy+2012_Fall+type@asset+block@sample_static.html') content = contentstore().find(asset_location) self.assertEqual(content.locked, locked) @@ -483,6 +489,7 @@ def post_asset_update(lock, course): TEST_DATA_DIR, ['toy'], static_content_store=contentstore(), + create_if_not_present=True, verbose=True ) course = course_items[0] @@ -513,15 +520,15 @@ def setUp(self): response = self.client.post(self.url, {"name": self.asset_name, "file": self.asset}) self.assertEqual(response.status_code, 200) - self.uploaded_url = json.loads(response.content.decode('utf-8'))['asset']['url'] + self.uploaded_id = json.loads(response.content.decode('utf-8'))['asset']['id'] - self.asset_location = AssetKey.from_string(self.uploaded_url) + self.asset_location = AssetKey.from_string(self.uploaded_id) self.content = contentstore().find(self.asset_location) def test_delete_asset(self): """ Tests the happy path :) """ test_url = reverse_course_url( - 'assets_handler', self.course.id, kwargs={'asset_key_string': str(self.uploaded_url)}) + 'assets_handler', self.course.id, kwargs={'asset_key_string': self.uploaded_id}) resp = self.client.delete(test_url, HTTP_ACCEPT="application/json") self.assertEqual(resp.status_code, 204) @@ -533,7 +540,7 @@ def test_delete_image_type_asset(self): # upload image response = self.client.post(self.url, {"name": "delete_image_test", "file": image_asset}) self.assertEqual(response.status_code, 200) - uploaded_image_url = json.loads(response.content.decode('utf-8'))['asset']['url'] + uploaded_image_url = json.loads(response.content.decode('utf-8'))['asset']['id'] # upload image thumbnail response = self.client.post(self.url, {"name": "delete_image_thumb_test", "file": thumbnail_image_asset}) @@ -558,7 +565,7 @@ def test_delete_asset_with_invalid_asset(self): """ Tests the sad path :( """ test_url = reverse_course_url( 'assets_handler', - self.course.id, kwargs={'asset_key_string': "/c4x/edX/toy/asset/invalid.pdf"} + self.course.id, kwargs={'asset_key_string': "asset-v1:edX+toy+2012_Fall+type@asset+block@invalid.pdf"} ) resp = self.client.delete(test_url, HTTP_ACCEPT="application/json") self.assertEqual(resp.status_code, 404) @@ -566,8 +573,9 @@ def test_delete_asset_with_invalid_asset(self): def test_delete_asset_with_invalid_thumbnail(self): """ Tests the sad path :( """ test_url = reverse_course_url( - 'assets_handler', self.course.id, kwargs={'asset_key_string': str(self.uploaded_url)}) - self.content.thumbnail_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/invalid') + 'assets_handler', self.course.id, kwargs={'asset_key_string': self.uploaded_id}) + self.content.thumbnail_location = StaticContent.get_location_from_path( + '/asset-v1:edX+toy+2012_Fall+type@asset+block@invalid.pdf') contentstore().save(self.content) resp = self.client.delete(test_url, HTTP_ACCEPT="application/json") self.assertEqual(resp.status_code, 204) diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py index 0f98eb26b7cc..8c4fb25c8a73 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py @@ -6,10 +6,11 @@ import pytest import ddt +from pytz import UTC from xmodule.data import CertificatesDisplayBehaviors from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_AMNESTY_MODULESTORE, ModuleStoreTestCase +from xmodule.modulestore.tests.django_utils import TEST_DATA_ONLY_SPLIT_MODULESTORE_DRAFT_PREFERRED, ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls from ..models import CourseOverview @@ -23,13 +24,12 @@ class CourseOverviewSignalsTestCase(ModuleStoreTestCase): """ Tests for CourseOverview signals. """ - MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE + MODULESTORE = TEST_DATA_ONLY_SPLIT_MODULESTORE_DRAFT_PREFERRED ENABLED_SIGNALS = ['course_deleted', 'course_published'] - TODAY = datetime.datetime.utcnow() + TODAY = datetime.datetime.utcnow().replace(tzinfo=UTC) NEXT_WEEK = TODAY + datetime.timedelta(days=7) - @ddt.data(ModuleStoreEnum.Type.split) - def test_caching(self, modulestore_type): + def test_caching(self): """ Tests that CourseOverview structures are actually getting cached. @@ -38,14 +38,13 @@ def test_caching(self, modulestore_type): course in. """ # Creating a new course will trigger a publish event and the course will be cached - course = CourseFactory.create(default_store=modulestore_type, emit_signals=True) + course = CourseFactory.create(emit_signals=True) # The cache will be hit and mongo will not be queried with check_mongo_calls(0): CourseOverview.get_from_id(course.id) - @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split) - def test_cache_invalidation(self, modulestore_type): + def test_cache_invalidation(self): """ Tests that when a course is published or deleted, the corresponding course_overview is removed from the cache. @@ -54,28 +53,26 @@ def test_cache_invalidation(self, modulestore_type): modulestore_type (ModuleStoreEnum.Type): type of store to create the course in. """ - with self.store.default_store(modulestore_type): - - # Create a course where mobile_available is True. - course = CourseFactory.create(mobile_available=True, default_store=modulestore_type) - course_overview_1 = CourseOverview.get_from_id(course.id) - assert course_overview_1.mobile_available - - # Set mobile_available to False and update the course. - # This fires a course_published signal, which should be caught in signals.py, which should in turn - # delete the corresponding CourseOverview from the cache. - course.mobile_available = False - with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): - self.store.update_item(course, ModuleStoreEnum.UserID.test) + # Create a course where mobile_available is True. + course = CourseFactory.create(mobile_available=True) + course_overview_1 = CourseOverview.get_from_id(course.id) + assert course_overview_1.mobile_available + + # Set mobile_available to False and update the course. + # This fires a course_published signal, which should be caught in signals.py, which should in turn + # delete the corresponding CourseOverview from the cache. + course.mobile_available = False + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + self.store.update_item(course, ModuleStoreEnum.UserID.test) - # Make sure that when we load the CourseOverview again, mobile_available is updated. - course_overview_2 = CourseOverview.get_from_id(course.id) - assert not course_overview_2.mobile_available + # Make sure that when we load the CourseOverview again, mobile_available is updated. + course_overview_2 = CourseOverview.get_from_id(course.id) + assert not course_overview_2.mobile_available - # Verify that when the course is deleted, the corresponding CourseOverview is deleted as well. - with pytest.raises(CourseOverview.DoesNotExist): - self.store.delete_course(course.id, ModuleStoreEnum.UserID.test) - CourseOverview.get_from_id(course.id) + # Verify that when the course is deleted, the corresponding CourseOverview is deleted as well. + with pytest.raises(CourseOverview.DoesNotExist): + self.store.delete_course(course.id, ModuleStoreEnum.UserID.test) + CourseOverview.get_from_id(course.id) def assert_changed_signal_sent(self, changes, mock_signal): # lint-amnesty, pylint: disable=missing-function-docstring course = CourseFactory.create( @@ -86,7 +83,7 @@ def assert_changed_signal_sent(self, changes, mock_signal): # lint-amnesty, pyl # changing display name doesn't fire the signal with self.captureOnCommitCallbacks(execute=True) as callbacks: course.display_name = course.display_name + 'changed' - self.store.update_item(course, ModuleStoreEnum.UserID.test) + course = self.store.update_item(course, ModuleStoreEnum.UserID.test) assert not mock_signal.called # changing the given field fires the signal