Merge pull request #1133 from edx/jkarni/fix/customtag-error
Jkarni/fix/customtag error
This commit is contained in:
20
cms/djangoapps/contentstore/features/course_import.py
Normal file
20
cms/djangoapps/contentstore/features/course_import.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import os
|
||||
from lettuce import world
|
||||
from django.conf import settings
|
||||
|
||||
def import_file(filename):
|
||||
world.browser.execute_script("$('input.file-input').css('display', 'block')")
|
||||
path = os.path.join(settings.COMMON_TEST_DATA_ROOT, "imports", filename)
|
||||
world.browser.attach_file('course-data', os.path.abspath(path))
|
||||
world.css_click('input.submit-button')
|
||||
# Go to course outline
|
||||
world.click_course_content()
|
||||
outline_css = 'li.nav-course-courseware-outline a'
|
||||
world.css_click(outline_css)
|
||||
|
||||
|
||||
def go_to_import():
|
||||
menu_css = 'li.nav-course-tools'
|
||||
import_css = 'li.nav-course-tools-import a'
|
||||
world.css_click(menu_css)
|
||||
world.css_click(import_css)
|
||||
@@ -89,3 +89,13 @@ Feature: CMS.Problem Editor
|
||||
When I edit and compile the High Level Source
|
||||
Then my change to the High Level Source is persisted
|
||||
And when I view the High Level Source I see my changes
|
||||
|
||||
Scenario: Exceptions don't cause problem to be uneditable (bug STUD-786)
|
||||
Given I have an empty course
|
||||
And I go to the import page
|
||||
And I import the file "get_html_exception_test.tar.gz"
|
||||
When I go to the unit "Probability and BMI"
|
||||
And I click on "edit a draft"
|
||||
Then I see a message that says "We're having trouble rendering your component"
|
||||
And I can edit the problem
|
||||
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
# disable missing docstring
|
||||
#pylint: disable=C0111
|
||||
|
||||
import os
|
||||
import json
|
||||
from lettuce import world, step
|
||||
from nose.tools import assert_equal, assert_true # pylint: disable=E0611
|
||||
from common import type_in_codemirror
|
||||
from common import type_in_codemirror, open_new_course
|
||||
from course_import import import_file, go_to_import
|
||||
|
||||
|
||||
DISPLAY_NAME = "Display Name"
|
||||
MAXIMUM_ATTEMPTS = "Maximum Attempts"
|
||||
@@ -24,7 +28,7 @@ def i_created_blank_common_problem(step):
|
||||
|
||||
|
||||
@step('I edit and select Settings$')
|
||||
def i_edit_and_select_settings(step):
|
||||
def i_edit_and_select_settings(_step):
|
||||
world.edit_component_and_select_settings()
|
||||
|
||||
|
||||
@@ -41,7 +45,7 @@ def i_see_advanced_settings_with_values(step):
|
||||
|
||||
|
||||
@step('I can modify the display name')
|
||||
def i_can_modify_the_display_name(step):
|
||||
def i_can_modify_the_display_name(_step):
|
||||
# Verifying that the display name can be a string containing a floating point value
|
||||
# (to confirm that we don't throw an error because it is of the wrong type).
|
||||
index = world.get_setting_entry_index(DISPLAY_NAME)
|
||||
@@ -58,7 +62,7 @@ def my_display_name_change_is_persisted_on_save(step):
|
||||
|
||||
|
||||
@step('I can specify special characters in the display name')
|
||||
def i_can_modify_the_display_name_with_special_chars(step):
|
||||
def i_can_modify_the_display_name_with_special_chars(_step):
|
||||
index = world.get_setting_entry_index(DISPLAY_NAME)
|
||||
world.css_fill('.wrapper-comp-setting .setting-input', "updated ' \" &", index=index)
|
||||
if world.is_firefox():
|
||||
@@ -73,7 +77,7 @@ def special_chars_persisted_on_save(step):
|
||||
|
||||
|
||||
@step('I can revert the display name to unset')
|
||||
def can_revert_display_name_to_unset(step):
|
||||
def can_revert_display_name_to_unset(_step):
|
||||
world.revert_setting_entry(DISPLAY_NAME)
|
||||
verify_unset_display_name()
|
||||
|
||||
@@ -85,7 +89,7 @@ def my_display_name_is_persisted_on_save(step):
|
||||
|
||||
|
||||
@step('I can select Per Student for Randomization')
|
||||
def i_can_select_per_student_for_randomization(step):
|
||||
def i_can_select_per_student_for_randomization(_step):
|
||||
world.browser.select(RANDOMIZATION, "Per Student")
|
||||
verify_modified_randomization()
|
||||
|
||||
@@ -104,7 +108,7 @@ def i_can_revert_to_default_for_randomization(step):
|
||||
|
||||
|
||||
@step('I can set the weight to "(.*)"?')
|
||||
def i_can_set_weight(step, weight):
|
||||
def i_can_set_weight(_step, weight):
|
||||
set_weight(weight)
|
||||
verify_modified_weight()
|
||||
|
||||
@@ -175,14 +179,14 @@ def create_latex_problem(step):
|
||||
|
||||
|
||||
@step('I edit and compile the High Level Source')
|
||||
def edit_latex_source(step):
|
||||
def edit_latex_source(_step):
|
||||
open_high_level_source()
|
||||
type_in_codemirror(1, "hi")
|
||||
world.css_click('.hls-compile')
|
||||
|
||||
|
||||
@step('my change to the High Level Source is persisted')
|
||||
def high_level_source_persisted(step):
|
||||
def high_level_source_persisted(_step):
|
||||
def verify_text(driver):
|
||||
css_sel = '.problem div>span'
|
||||
return world.css_text(css_sel) == 'hi'
|
||||
@@ -191,11 +195,53 @@ def high_level_source_persisted(step):
|
||||
|
||||
|
||||
@step('I view the High Level Source I see my changes')
|
||||
def high_level_source_in_editor(step):
|
||||
def high_level_source_in_editor(_step):
|
||||
open_high_level_source()
|
||||
assert_equal('hi', world.css_value('.source-edit-box'))
|
||||
|
||||
|
||||
@step(u'I have an empty course')
|
||||
def i_have_empty_course(step):
|
||||
open_new_course()
|
||||
|
||||
|
||||
@step(u'I go to the import page')
|
||||
def i_go_to_import(_step):
|
||||
go_to_import()
|
||||
|
||||
|
||||
@step(u'I import the file "([^"]*)"$')
|
||||
def i_import_the_file(_step, filename):
|
||||
import_file(filename)
|
||||
|
||||
|
||||
@step(u'I click on "edit a draft"$')
|
||||
def i_edit_a_draft(_step):
|
||||
world.css_click("a.create-draft")
|
||||
|
||||
|
||||
@step(u'I go to the vertical "([^"]*)"$')
|
||||
def i_go_to_vertical(_step, vertical):
|
||||
world.css_click("span:contains('{0}')".format(vertical))
|
||||
|
||||
|
||||
@step(u'I go to the unit "([^"]*)"$')
|
||||
def i_go_to_unit(_step, unit):
|
||||
loc = "window.location = $(\"span:contains('{0}')\").closest('a').attr('href')".format(unit)
|
||||
world.browser.execute_script(loc)
|
||||
|
||||
|
||||
@step(u'I see a message that says "([^"]*)"$')
|
||||
def i_can_see_message(_step, msg):
|
||||
msg = json.dumps(msg) # escape quotes
|
||||
world.css_has_text("h2.title", msg)
|
||||
|
||||
|
||||
@step(u'I can edit the problem$')
|
||||
def i_can_edit_problem(_step):
|
||||
world.edit_component()
|
||||
|
||||
|
||||
def verify_high_level_source_links(step, visible):
|
||||
if visible:
|
||||
assert_true(world.is_css_present('.launch-latex-compiler'),
|
||||
|
||||
@@ -193,6 +193,7 @@ def import_course(request, org, course, name):
|
||||
if not dirpath:
|
||||
return JsonResponse(
|
||||
{
|
||||
|
||||
'ErrMsg': _('Could not find the course.xml file in the package.'),
|
||||
'Stage': 2
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ from django.conf import settings
|
||||
from django.http import HttpResponse, Http404, HttpResponseBadRequest, HttpResponseForbidden
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from mitxmako.shortcuts import render_to_response
|
||||
from mitxmako.shortcuts import render_to_response, render_to_string
|
||||
|
||||
from xmodule_modifiers import replace_static_urls, wrap_xmodule
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
@@ -79,9 +79,17 @@ def preview_component(request, location):
|
||||
# can bind to it correctly
|
||||
component.runtime.wrappers.append(partial(wrap_xmodule, 'xmodule_edit.html'))
|
||||
|
||||
try:
|
||||
content = component.render('studio_view').content
|
||||
# catch exceptions indiscriminately, since after this point they escape the
|
||||
# dungeon and surface as uneditable, unsaveable, and undeletable
|
||||
# component-goblins.
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
content = render_to_string('html_error.html', {'message': str(exc)})
|
||||
|
||||
return render_to_response('component.html', {
|
||||
'preview': get_preview_html(request, component, 0),
|
||||
'editor': component.render('studio_view').content,
|
||||
'editor': content
|
||||
})
|
||||
|
||||
|
||||
@@ -157,4 +165,8 @@ def get_preview_html(request, descriptor, idx):
|
||||
specified by the descriptor and idx.
|
||||
"""
|
||||
module = load_preview_module(request, str(idx), descriptor)
|
||||
return module.render("student_view").content
|
||||
try:
|
||||
content = module.render("student_view").content
|
||||
except Exception as exc: # pylint: disable=W0703
|
||||
content = render_to_string('html_error.html', {'message': str(exc)})
|
||||
return content
|
||||
|
||||
@@ -355,6 +355,20 @@ body.course.unit,.view-unit {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper-alert-error {
|
||||
margin-top: ($baseline*1.25);
|
||||
box-shadow: none;
|
||||
border-top: 5px solid $red-l1;
|
||||
|
||||
.copy,
|
||||
.title {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
cms/templates/html_error.html
Normal file
26
cms/templates/html_error.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
|
||||
<%block name="content">
|
||||
<div class="wrapper wrapper-alert wrapper-alert-error is-shown">
|
||||
<div class="error">
|
||||
|
||||
<div class="copy">
|
||||
<h2 class="title">
|
||||
<i class="icon-warning-sign"></i>
|
||||
${_("We're having trouble rendering your component")}
|
||||
</h2>
|
||||
|
||||
<p>${_("Students will not be able to access this component. Re-edit your component to fix the error.")}</p>
|
||||
|
||||
% if message:
|
||||
<p class="description">
|
||||
${_("Error:")}
|
||||
${message | h}
|
||||
</p>
|
||||
% endif
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</%block>
|
||||
BIN
common/test/data/imports/get_html_exception_test.tar.gz
Normal file
BIN
common/test/data/imports/get_html_exception_test.tar.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user