-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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 import errors with unicode filenames #830
Changes from all commits
1813b22
1cfad39
d54b197
0208506
af64621
9d3395e
3e62c5e
2aaade0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,10 @@ | |
# pylint: disable=E0611 | ||
from nose.tools import assert_equals, assert_raises, \ | ||
assert_not_equals, assert_false | ||
from itertools import ifilter | ||
# pylint: enable=E0611 | ||
import pymongo | ||
import logging | ||
from uuid import uuid4 | ||
|
||
from xblock.fields import Scope | ||
|
@@ -19,6 +21,7 @@ | |
|
||
from xmodule.modulestore.tests.test_modulestore import check_path_to_location | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
HOST = 'localhost' | ||
PORT = 27017 | ||
|
@@ -59,7 +62,7 @@ def initdb(): | |
# | ||
draft_store = DraftModuleStore(HOST, DB, COLLECTION, FS_ROOT, RENDER_TEMPLATE, default_class=DEFAULT_CLASS) | ||
# Explicitly list the courses to load (don't want the big one) | ||
courses = ['toy', 'simple', 'simple_with_draft'] | ||
courses = ['toy', 'simple', 'simple_with_draft', 'test_unicode'] | ||
import_from_xml(store, DATA_DIR, courses, draft_store=draft_store, static_content_store=content_store) | ||
|
||
# also test a course with no importing of static content | ||
|
@@ -86,6 +89,19 @@ def setUp(self): | |
def tearDown(self): | ||
pass | ||
|
||
def get_course_by_id(self, name): | ||
""" | ||
Returns the first course with `id` of `name`, or `None` if there are none. | ||
""" | ||
courses = self.store.get_courses() | ||
return next(ifilter(lambda x: x.id == name, courses), None) | ||
|
||
def course_with_id_exists(self, name): | ||
""" | ||
Returns true iff there exists some course with `id` of `name`. | ||
""" | ||
return (self.get_course_by_id(name) is not None) | ||
|
||
def test_init(self): | ||
'''Make sure the db loads, and print all the locations in the db. | ||
Call this directly from failing tests to see what is loaded''' | ||
|
@@ -100,12 +116,12 @@ def test_mongo_modulestore_type(self): | |
def test_get_courses(self): | ||
'''Make sure the course objects loaded properly''' | ||
courses = self.store.get_courses() | ||
assert_equals(len(courses), 4) | ||
courses.sort(key=lambda c: c.id) | ||
assert_equals(courses[0].id, 'edX/simple/2012_Fall') | ||
assert_equals(courses[1].id, 'edX/simple_with_draft/2012_Fall') | ||
assert_equals(courses[2].id, 'edX/test_import_course/2012_Fall') | ||
assert_equals(courses[3].id, 'edX/toy/2012_Fall') | ||
assert_equals(len(courses), 5) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does the list of courses in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fifth course gets imported in a separate call to Not sure about calculating the number: we obviously shouldn't just do |
||
assert self.course_with_id_exists('edX/simple/2012_Fall') | ||
assert self.course_with_id_exists('edX/simple_with_draft/2012_Fall') | ||
assert self.course_with_id_exists('edX/test_import_course/2012_Fall') | ||
assert self.course_with_id_exists('edX/test_unicode/2012_Fall') | ||
assert self.course_with_id_exists('edX/toy/2012_Fall') | ||
|
||
def test_loads(self): | ||
assert_not_equals( | ||
|
@@ -120,6 +136,22 @@ def test_loads(self): | |
self.store.get_item("i4x://edX/toy/video/Welcome"), | ||
None) | ||
|
||
def test_unicode_loads(self): | ||
assert_not_equals( | ||
self.store.get_item("i4x://edX/test_unicode/course/2012_Fall"), | ||
None) | ||
# All items with ascii-only filenames should load properly. | ||
assert_not_equals( | ||
self.store.get_item("i4x://edX/test_unicode/video/Welcome"), | ||
None) | ||
assert_not_equals( | ||
self.store.get_item("i4x://edX/test_unicode/video/Welcome"), | ||
None) | ||
assert_not_equals( | ||
self.store.get_item("i4x://edX/test_unicode/chapter/Overview"), | ||
None) | ||
|
||
|
||
def test_find_one(self): | ||
assert_not_equals( | ||
self.store._find_one(Location("i4x://edX/toy/course/2012_Fall")), | ||
|
@@ -153,15 +185,15 @@ def test_get_courses_has_no_templates(self): | |
) | ||
|
||
def test_static_tab_names(self): | ||
courses = self.store.get_courses() | ||
|
||
def get_tab_name(index): | ||
""" | ||
Helper function for pulling out the name of a given static tab. | ||
|
||
Assumes the information is desired for courses[1] ('toy' course). | ||
Assumes the information is desired for courses[4] ('toy' course). | ||
""" | ||
return courses[2].tabs[index]['name'] | ||
course = self.get_course_by_id('edX/toy/2012_Fall') | ||
return course.tabs[index]['name'] | ||
|
||
# There was a bug where model.save was not getting called after the static tab name | ||
# was set set for tabs that have a URL slug. 'Syllabus' and 'Resources' fall into that | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
TBD |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<chapter display_name="åñ html ƒile"> | ||
<sequential display_name="åñ html ƒile"> | ||
<html display_name="åñ html ƒile"> | ||
<p> This is upside down text:</p> | ||
<p>˙ʇxəʇ uʍop əpısdn sı sıɥʇ</p> | ||
</html> | ||
</sequential> | ||
</chapter> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Loving it! How did you get upside down text? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. seems like a good solution to the issue @nedbat - we should be able to tell whether the unicode characters are right. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<course org="edX" course="test_unicode" url_name="2012_Fall"/> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<course> | ||
<chapter display_name="Overview"> | ||
<video url_name="Welcome" youtube_id_1_0="p2Q6BrNhdh8" display_name="Welcome"/> | ||
</chapter> | ||
<chapter url_name="sîmple_√ideo"/> | ||
<chapter url_name="simple_html"/> | ||
<chapter url_name="vertical_container"/> | ||
</course> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"course/2012_Fall": { | ||
"graceperiod": "2 days 5 hours 59 minutes 59 seconds", | ||
"start": "2015-07-17T12:00", | ||
"display_name": "Üñîçø∂e †es† Course", | ||
"graded": "true", | ||
"tabs": [ | ||
{"type": "courseware"}, | ||
{"type": "course_info", "name": "Course Info"}, | ||
{"type": "static_tab", "url_slug": "syllabus", "name": "ßyllabus"}, | ||
{"type": "static_tab", "url_slug": "resources", "name": "®esources"}, | ||
{"type": "discussion", "name": "∂iscussion"}, | ||
{"type": "wiki", "name": "∑iki"}, | ||
{"type": "progress", "name": "πrogress"} | ||
] | ||
}, | ||
"chapter/Overview": { | ||
"display_name": "O√erview" | ||
}, | ||
"video/Welcome": { | ||
"display_name": "Welcome" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<sequential> | ||
<vertical filename="vertical_test" slug="vertical_test" /> | ||
<html slug="unicode">…</html> | ||
</sequential> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
Upside down unicode text (http://www.sunnyneo.com/upsidedowntext.php?) | ||
|
||
˙ʇʇɐld uoɯəl plos əɥs ˙pəʌıl əuɹʎq ʎʇʇəq əɹəɥʍ pɐoɹ əɥʇ uʍop əɯɐɔ ʍoɔ-ooɯ əɥʇ | ||
˙ooʞɔnʇ ʎqɐq sɐʍ əɥ ˙əɔɐɟ ʎɹıɐɥ ɐ pɐɥ əɥ :ssɐlƃ ɐ ɥƃnoɹɥʇ ɯıɥ ʇɐ pəʞool ɹəɥʇɐɟ | ||
sıɥ :ʎɹoʇs ʇɐɥʇ ɯıɥ ploʇ ɹəɥʇɐɟ sıɥ | ||
|
||
˙˙˙ooʞɔnʇ ʎqɐq pəɯɐu ʎoq əlʇʇıl suəɔıu ɐ ʇəɯ pɐoɹ əɥʇ ƃuolɐ uʍop ƃuıɯoɔ sɐʍ ʇɐɥʇ | ||
ʍoɔ-ooɯ sıɥʇ puɐ pɐoɹ əɥʇ ƃuolɐ uʍop ƃuıɯoɔ ʍoɔ-ooɯ ɐ sɐʍ əɹəɥʇ sɐʍ ʇı əɯıʇ pooƃ | ||
ʎɹəʌ ɐ puɐ əɯıʇ ɐ uodn əɔuo |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<div>resources!</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<vertical> | ||
<video url_name="separate_file_video"/> | ||
</vertical> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,5 +16,5 @@ | |
# Our libraries: | ||
-e git+https://github.com/edx/XBlock.git@aa0d60627#egg=XBlock | ||
-e git+https://github.com/edx/codejail.git@0a1b468#egg=codejail | ||
-e git+https://github.com/edx/diff-cover.git@v0.2.2#egg=diff_cover | ||
-e git+https://github.com/edx/diff-cover.git@v0.2.3#egg=diff_cover | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, why the new dependency version? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because diff-cover had an issue with diffing unicode filenames (the regex that was being used would break); I sent a PR for that and it's been merged with a version bump. |
||
-e git+https://github.com/edx/js-test-tool.git@v0.0.7#egg=js_test_tool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder what people will expect for a directory name from a non-ascii course title? This should prevent errors, but may still produce odd results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean non-unicode dirnames will raise issues elsewhere? I think that's probably true, but presumably we should fix those issues too.