def test_map_into_course_asset_location(self): original_course = CourseKey.from_string('org/course/run') new_course = CourseKey.from_string('edX/toy/2012_Fall') loc = AssetLocator(original_course, 'asset', 'foo.bar') self.assertEqual( AssetLocator(new_course, 'asset', 'foo.bar', deprecated=True), loc.map_into_course(new_course))
class CachingTestCase(TestCase): """ Tests for https://edx.lighthouseapp.com/projects/102637/tickets/112-updating-asset-does-not-refresh-the-cached-copy """ unicodeLocation = AssetLocator(CourseLocator(u'c4x', u'mitX', u'800'), u'thumbnail', u'monsters.jpg') # Note that some of the parts are strings instead of unicode strings nonUnicodeLocation = AssetLocator(CourseLocator('c4x', u'mitX', u'800'), 'thumbnail', 'monsters.jpg') mockAsset = Content(unicodeLocation, 'my content') def test_put_and_get(self): set_cached_content(self.mockAsset) self.assertEqual(self.mockAsset.content, get_cached_content(self.unicodeLocation).content, 'should be stored in cache with unicodeLocation') self.assertEqual(self.mockAsset.content, get_cached_content(self.nonUnicodeLocation).content, 'should be stored in cache with nonUnicodeLocation') def test_delete(self): set_cached_content(self.mockAsset) del_cached_content(self.nonUnicodeLocation) self.assertEqual(None, get_cached_content(self.unicodeLocation), 'should not be stored in cache with unicodeLocation') self.assertEqual( None, get_cached_content(self.nonUnicodeLocation), 'should not be stored in cache with nonUnicodeLocation')
def test_contentstore_attrs(self): """ Test getting, setting, and defaulting the locked attr and arbitrary attrs. """ location = BlockUsageLocator(CourseLocator('edX', 'toy', '2012_Fall', deprecated=True), 'course', '2012_Fall', deprecated=True) course_content, __ = self.content_store.get_all_content_for_course(location.course_key) assert len(course_content) > 0 filter_params = _build_requested_filter('Images') filtered_course_content, __ = self.content_store.get_all_content_for_course( location.course_key, filter_params=filter_params) assert len(filtered_course_content) < len(course_content) # a bit overkill, could just do for content[0] for content in course_content: assert not content.get('locked', False) asset_key = AssetLocator._from_deprecated_son(content.get('content_son', content['_id']), location.run) assert not self.content_store.get_attr(asset_key, 'locked', False) attrs = self.content_store.get_attrs(asset_key) assert 'uploadDate' in attrs assert not attrs.get('locked', False) self.content_store.set_attr(asset_key, 'locked', True) assert self.content_store.get_attr(asset_key, 'locked', False) attrs = self.content_store.get_attrs(asset_key) assert 'locked' in attrs assert attrs['locked'] is True self.content_store.set_attrs(asset_key, {'miscel': 99}) assert self.content_store.get_attr(asset_key, 'miscel') == 99 asset_key = AssetLocator._from_deprecated_son( course_content[0].get('content_son', course_content[0]['_id']), location.run ) with pytest.raises(AttributeError): self.content_store.set_attr(asset_key, 'md5', 'ff1532598830e3feac91c2449eaa60d6') with pytest.raises(AttributeError): self.content_store.set_attrs(asset_key, {'foo': 9, 'md5': 'ff1532598830e3feac91c2449eaa60d6'}) with pytest.raises(NotFoundError): self.content_store.get_attr( BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'), 'displayname' ) with pytest.raises(NotFoundError): self.content_store.set_attr( BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'), 'displayname', 'hello' ) with pytest.raises(NotFoundError): self.content_store.get_attrs(BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus')) with pytest.raises(NotFoundError): self.content_store.set_attrs( BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus'), 'asset', 'bogus'), {'displayname': 'hello'} ) with pytest.raises(NotFoundError): self.content_store.set_attrs( BlockUsageLocator(CourseLocator('bogus', 'bogus', 'bogus', deprecated=True), 'asset', None, deprecated=True), {'displayname': 'hello'} )
def test_map_into_course_asset_location(self): original_course = CourseKey.from_string('org/course/run') new_course = CourseKey.from_string('edX/toy/2012_Fall') loc = AssetLocator(original_course, 'asset', 'foo.bar') self.assertEquals( AssetLocator(new_course, 'asset', 'foo.bar', deprecated=True), loc.map_into_course(new_course) )
def test_old_charset(self): # merely not raising InvalidKeyError suffices AssetLocator(CourseLocator('a', 'b', 'c'), 'asset', 'subs_%20S2x5jhbWl_o.srt.sjson') AssetLocator(CourseLocator('a', 'b', 'c'), 'asset', 'subs_%20S2x5jhbWl_o.srt.sjson', deprecated=True)
def test_generate_thumbnail_image(self, original_filename, thumbnail_filename): content_store = ContentStore() content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', original_filename), None) (thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content) self.assertIsNone(thumbnail_content) self.assertEqual( AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename), thumbnail_file_location )
def test_generate_thumbnail_image(self, original_filename, thumbnail_filename): content_store = ContentStore() content = Content( AssetLocator(CourseLocator('mitX', '800', 'ignore_run'), 'asset', original_filename), None) (thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content) assert thumbnail_content is None assert AssetLocator(CourseLocator('mitX', '800', 'ignore_run'), 'thumbnail', thumbnail_filename) ==\ thumbnail_file_location
def test_store_svg_as_thumbnail(self): # We had a bug that caused generate_thumbnail to attempt to pass SVG to PIL to generate a thumbnail. # SVG files should be stored in original form for thumbnail purposes. content_store = ContentStore() content_store.save = Mock() thumbnail_filename = u'test.svg' content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', u'test.svg'), 'image/svg+xml') content.data = 'mock svg file' (thumbnail_content, thumbnail_file_location) = content_store.generate_thumbnail(content) self.assertEqual(thumbnail_content.data.read(), b'mock svg file') self.assertEqual( AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'thumbnail', thumbnail_filename), thumbnail_file_location )
def test_get_location_from_path(self): asset_location = StaticContent.get_location_from_path( '/c4x/a/b/asset/images_course_image.jpg') assert AssetLocator(CourseLocator('a', 'b', None, deprecated=True), 'asset', 'images_course_image.jpg', deprecated=True) == asset_location
def test_get_location_from_path(self): asset_location = StaticContent.get_location_from_path(u'/c4x/a/b/asset/images_course_image.jpg') self.assertEqual( AssetLocator(CourseLocator(u'a', u'b', None, deprecated=True), u'asset', u'images_course_image.jpg', deprecated=True), asset_location )
def test_compute_location(self): # We had a bug that __ got converted into a single _. Make sure that substitution of INVALID_CHARS (like space) # still happen. asset_location = StaticContent.compute_location( CourseKey.from_string('mitX/400/ignore'), 'subs__1eo_jXvZnE .srt.sjson') assert AssetLocator( CourseLocator('mitX', '400', 'ignore', deprecated=True), 'asset', 'subs__1eo_jXvZnE_.srt.sjson') == asset_location
def get_track_zh(self, obj): _value = obj.transcripts.get('zh', '') if _value: cleaned_value = AssetLocator.clean_keeping_underscores(_value) if self.course_key.deprecated: value = '/c4x/%s/%s/asset/%s' % (self.course_key.org, self.course_key.course, cleaned_value) else: value = '/asset-v1:%s+%s+%s+type@asset+block@%s' % ( self.course_key.org, self.course_key.course, self.course_key.run, cleaned_value) return _normalizeUrl(value) else: return ''
def test_image_is_closed_when_generating_thumbnail(self, image_class_mock): # We used to keep the Image's file descriptor open when generating a thumbnail. # It should be closed after being used. mock_image = MockImage() image_class_mock.open.return_value = mock_image content_store = ContentStore() content = Content(AssetLocator(CourseLocator(u'mitX', u'800', u'ignore_run'), u'asset', "monsters.jpg"), "image/jpeg") content.data = 'mock data' content_store.generate_thumbnail(content) self.assertTrue(image_class_mock.open.called, "Image.open not called") self.assertTrue(mock_image.close.called, "mock_image.close not called")
def compute_location(course_key, path, revision=None, is_thumbnail=False): """ Constructs a location object for static content. - course_key: the course that this asset belongs to - path: is the name of the static asset - revision: is the object's revision information - is_thumbnail: is whether or not we want the thumbnail version of this asset """ path = path.replace('/', '_') return course_key.make_asset_key( 'asset' if not is_thumbnail else 'thumbnail', AssetLocator.clean_keeping_underscores(path)).for_branch(None)
def compute_location(course_key, path, revision=None, is_thumbnail=False): """ Constructs a location object for static content. - course_key: the course that this asset belongs to - path: is the name of the static asset - revision: is the object's revision information - is_thumbnail: is whether or not we want the thumbnail version of this asset """ path = path.replace('/', '_') return course_key.make_asset_key( 'asset' if not is_thumbnail else 'thumbnail', AssetLocator.clean_keeping_underscores(path) ).for_branch(None)
def compute_location(course_key, path, revision=None, is_thumbnail=False): """ Constructs a location object for static content. - course_key: the course that this asset belongs to - path: is the name of the static asset - revision: is the object's revision information - is_thumbnail: is whether or not we want the thumbnail version of this asset """ path = path.replace('/', '_') # todo: new coursekeys behave weirdly with assets, will break if title is non ascii # if an asset path is empty (i.e. course image url is empty) split mongo course assets will # throw exceptions. thus we bypass that and just return an empty key if len(path) == 0 and not course_key.deprecated: return "" return course_key.make_asset_key( 'asset' if not is_thumbnail else 'thumbnail', AssetLocator.clean_keeping_underscores(path) ).for_branch(None)
def test_make_asset_key(self): course = CourseKey.from_string('org/course/run') self.assertEqual( AssetLocator(course, 'asset', 'foo.bar', deprecated=True), course.make_asset_key('asset', 'foo.bar'))
def make_asset_key(self, asset_type, path): return AssetLocator(self.to_course_locator(), asset_type, path, deprecated=False)
def _from_deprecated_son(cls, id_dict, run): """Deprecated. See BlockUsageLocator._from_deprecated_son""" cls._deprecation_warning() return AssetLocator._from_deprecated_son(id_dict, run)
def _from_deprecated_string(cls, serialized): """Deprecated. See AssetLocator._from_deprecated_string""" cls._deprecation_warning() return AssetLocator._from_deprecated_string(serialized)
def test_make_asset_key(self): lib_key = CourseKey.from_string('library-v1:TestX+lib1') self.assertEqual(AssetLocator(lib_key, 'asset', 'foo.bar'), lib_key.make_asset_key('asset', 'foo.bar'))