Convert PollModule to PollBlock.
This commit is contained in:
committed by
David Ormsbee
parent
60ef705944
commit
48290cf837
@@ -7,7 +7,6 @@ XMODULES = [
|
||||
"customtag = xmodule.template_module:CustomTagDescriptor",
|
||||
"discuss = xmodule.backcompat_module:TranslateCustomTagDescriptor",
|
||||
"image = xmodule.backcompat_module:TranslateCustomTagDescriptor",
|
||||
"poll_question = xmodule.poll_module:PollDescriptor",
|
||||
"section = xmodule.backcompat_module:SemanticSectionDescriptor",
|
||||
"slides = xmodule.backcompat_module:TranslateCustomTagDescriptor",
|
||||
"videodev = xmodule.backcompat_module:TranslateCustomTagDescriptor",
|
||||
@@ -29,6 +28,7 @@ XBLOCKS = [
|
||||
"library_sourced = xmodule.library_sourced_block:LibrarySourcedBlock",
|
||||
"lti = xmodule.lti_module:LTIBlock",
|
||||
"nonstaff_error = xmodule.error_module:NonStaffErrorBlock",
|
||||
"poll_question = xmodule.poll_module:PollBlock",
|
||||
"problem = xmodule.capa_module:ProblemBlock",
|
||||
"problemset = xmodule.seq_module:SequenceBlock",
|
||||
"randomize = xmodule.randomize_module:RandomizeBlock",
|
||||
|
||||
@@ -14,19 +14,38 @@ from collections import OrderedDict
|
||||
from copy import deepcopy
|
||||
|
||||
from pkg_resources import resource_string
|
||||
from web_fragments.fragment import Fragment
|
||||
|
||||
from lxml import etree
|
||||
from openedx.core.djangolib.markup import Text, HTML
|
||||
from xblock.fields import Boolean, Dict, List, Scope, String # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.mako_module import MakoModuleDescriptor
|
||||
from xmodule.mako_module import MakoTemplateBlockBase
|
||||
from xmodule.stringify import stringify_children
|
||||
from xmodule.x_module import XModule
|
||||
from xmodule.xml_module import XmlDescriptor
|
||||
from xmodule.util.xmodule_django import add_webpack_to_fragment
|
||||
from xmodule.x_module import (
|
||||
HTMLSnippet,
|
||||
ResourceTemplates,
|
||||
shim_xmodule_js,
|
||||
XModuleMixin,
|
||||
XModuleDescriptorToXBlockMixin,
|
||||
XModuleToXBlockMixin,
|
||||
)
|
||||
from xmodule.xml_module import XmlMixin
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
_ = lambda text: text
|
||||
|
||||
|
||||
class PollFields(object): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class PollBlock(
|
||||
MakoTemplateBlockBase,
|
||||
XmlMixin,
|
||||
XModuleDescriptorToXBlockMixin,
|
||||
XModuleToXBlockMixin,
|
||||
HTMLSnippet,
|
||||
ResourceTemplates,
|
||||
XModuleMixin,
|
||||
): # pylint: disable=abstract-method
|
||||
"""Poll Module"""
|
||||
# Name of poll to use in links to this poll
|
||||
display_name = String(
|
||||
help=_("The display name for this component."),
|
||||
@@ -61,18 +80,33 @@ class PollFields(object): # lint-amnesty, pylint: disable=missing-class-docstri
|
||||
default=''
|
||||
)
|
||||
|
||||
resources_dir = None
|
||||
uses_xmodule_styles_setup = True
|
||||
|
||||
class PollModule(PollFields, XModule):
|
||||
"""Poll Module"""
|
||||
js = {
|
||||
preview_view_js = {
|
||||
'js': [
|
||||
resource_string(__name__, 'js/src/javascript_loader.js'),
|
||||
resource_string(__name__, 'js/src/poll/poll.js'),
|
||||
resource_string(__name__, 'js/src/poll/poll_main.js')
|
||||
]
|
||||
],
|
||||
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
|
||||
}
|
||||
preview_view_css = {
|
||||
'scss': [
|
||||
resource_string(__name__, 'css/poll/display.scss')
|
||||
],
|
||||
}
|
||||
|
||||
# There is no studio_view() for this XBlock but this is needed to make the
|
||||
# the static_content command happy.
|
||||
studio_view_js = {
|
||||
'js': [],
|
||||
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
|
||||
}
|
||||
|
||||
studio_view_css = {
|
||||
'scss': []
|
||||
}
|
||||
css = {'scss': [resource_string(__name__, 'css/poll/display.scss')]}
|
||||
js_module_name = "Poll"
|
||||
|
||||
def handle_ajax(self, dispatch, data): # lint-amnesty, pylint: disable=unused-argument
|
||||
"""Ajax handler.
|
||||
@@ -103,7 +137,7 @@ class PollModule(PollFields, XModule):
|
||||
'total': sum(self.poll_answers.values())
|
||||
})
|
||||
elif dispatch == 'reset_poll' and self.voted and \
|
||||
self.descriptor.xml_attributes.get('reset', 'True').lower() != 'false':
|
||||
self.xml_attributes.get('reset', 'True').lower() != 'false':
|
||||
self.voted = False
|
||||
|
||||
# FIXME: fix this, when xblock will support mutable types.
|
||||
@@ -117,16 +151,21 @@ class PollModule(PollFields, XModule):
|
||||
else: # return error message
|
||||
return json.dumps({'error': 'Unknown Command!'})
|
||||
|
||||
def get_html(self):
|
||||
"""Renders parameters to template."""
|
||||
def student_view(self, _context):
|
||||
"""
|
||||
Renders the student view.
|
||||
"""
|
||||
fragment = Fragment()
|
||||
params = {
|
||||
'element_id': self.location.html_id(),
|
||||
'element_class': self.location.block_type,
|
||||
'ajax_url': self.system.ajax_url,
|
||||
'ajax_url': self.ajax_url,
|
||||
'configuration_json': self.dump_poll(),
|
||||
}
|
||||
self.content = self.system.render_template('poll.html', params) # lint-amnesty, pylint: disable=attribute-defined-outside-init
|
||||
return self.content
|
||||
fragment.add_content(self.system.render_template('poll.html', params))
|
||||
add_webpack_to_fragment(fragment, 'PollBlockPreview')
|
||||
shim_xmodule_js(fragment, 'Poll')
|
||||
return fragment
|
||||
|
||||
def dump_poll(self):
|
||||
"""Dump poll information.
|
||||
@@ -160,17 +199,12 @@ class PollModule(PollFields, XModule):
|
||||
'poll_answer': self.poll_answer,
|
||||
'poll_answers': self.poll_answers if self.voted else {},
|
||||
'total': sum(self.poll_answers.values()) if self.voted else 0,
|
||||
'reset': str(self.descriptor.xml_attributes.get('reset', 'true')).lower()
|
||||
'reset': str(self.xml_attributes.get('reset', 'true')).lower()
|
||||
})
|
||||
|
||||
|
||||
class PollDescriptor(PollFields, MakoModuleDescriptor, XmlDescriptor): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
_tag_name = 'poll_question'
|
||||
_child_tag_name = 'answer'
|
||||
|
||||
module_class = PollModule
|
||||
resources_dir = None
|
||||
|
||||
@classmethod
|
||||
def definition_from_xml(cls, xml_object, system):
|
||||
"""Pull out the data into dictionary.
|
||||
|
||||
@@ -26,6 +26,7 @@ from xmodule.conditional_module import ConditionalBlock
|
||||
from xmodule.html_module import AboutBlock, CourseInfoBlock, HtmlBlock, StaticTabBlock
|
||||
from xmodule.library_content_module import LibraryContentBlock
|
||||
from xmodule.lti_module import LTIBlock
|
||||
from xmodule.poll_module import PollBlock
|
||||
from xmodule.seq_module import SequenceBlock
|
||||
from xmodule.split_test_module import SplitTestBlock
|
||||
from xmodule.word_cloud_module import WordCloudBlock
|
||||
@@ -77,6 +78,7 @@ XBLOCK_CLASSES = [
|
||||
HtmlBlock,
|
||||
LibraryContentBlock,
|
||||
LTIBlock,
|
||||
PollBlock,
|
||||
ProblemBlock,
|
||||
SequenceBlock,
|
||||
SplitTestBlock,
|
||||
|
||||
@@ -191,29 +191,6 @@ class ModelsTest(unittest.TestCase): # lint-amnesty, pylint: disable=missing-cl
|
||||
assert str(vc) == vc_str
|
||||
|
||||
|
||||
class LogicTest(unittest.TestCase):
|
||||
"""Base class for testing xmodule logic."""
|
||||
descriptor_class = None
|
||||
raw_field_data = {}
|
||||
|
||||
def setUp(self):
|
||||
super(LogicTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.system = get_test_system()
|
||||
self.descriptor = Mock(name="descriptor", url_name='', category='test')
|
||||
|
||||
self.xmodule_class = self.descriptor_class.module_class
|
||||
usage_key = self.system.course_id.make_usage_key(self.descriptor.category, 'test_loc')
|
||||
# ScopeIds has 4 fields: user_id, block_type, def_id, usage_id
|
||||
scope_ids = ScopeIds(1, self.descriptor.category, usage_key, usage_key)
|
||||
self.xmodule = self.xmodule_class(
|
||||
self.descriptor, self.system, DictFieldData(self.raw_field_data), scope_ids
|
||||
)
|
||||
|
||||
def ajax_request(self, dispatch, data):
|
||||
"""Call Xmodule.handle_ajax."""
|
||||
return json.loads(self.xmodule.handle_ajax(dispatch, data))
|
||||
|
||||
|
||||
def map_references(value, field, actual_course_key):
|
||||
"""
|
||||
Map the references in value to actual_course_key and return value
|
||||
|
||||
@@ -1,24 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Test for Poll Xmodule functional logic."""
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from mock import Mock
|
||||
|
||||
from xmodule.poll_module import PollDescriptor
|
||||
from xblock.field_data import DictFieldData
|
||||
from xblock.fields import ScopeIds
|
||||
from xmodule.poll_module import PollBlock
|
||||
|
||||
from . import LogicTest
|
||||
from . import get_test_system
|
||||
from .test_import import DummySystem
|
||||
|
||||
|
||||
class PollModuleTest(LogicTest):
|
||||
class PollBlockTest(unittest.TestCase):
|
||||
"""Logic tests for Poll Xmodule."""
|
||||
descriptor_class = PollDescriptor
|
||||
|
||||
raw_field_data = {
|
||||
'poll_answers': {'Yes': 1, 'Dont_know': 0, 'No': 0},
|
||||
'voted': False,
|
||||
'poll_answer': ''
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.system = get_test_system()
|
||||
usage_key = self.system.course_id.make_usage_key(PollBlock.category, 'test_loc')
|
||||
# ScopeIds has 4 fields: user_id, block_type, def_id, usage_id
|
||||
scope_ids = ScopeIds(1, PollBlock.category, usage_key, usage_key)
|
||||
self.xmodule = PollBlock(
|
||||
self.system, DictFieldData(self.raw_field_data), scope_ids
|
||||
)
|
||||
|
||||
def ajax_request(self, dispatch, data):
|
||||
"""Call Xmodule.handle_ajax."""
|
||||
return json.loads(self.xmodule.handle_ajax(dispatch, data))
|
||||
|
||||
def test_bad_ajax_request(self):
|
||||
# Make sure that answer for incorrect request is error json.
|
||||
response = self.ajax_request('bad_answer', {})
|
||||
@@ -52,7 +70,7 @@ class PollModuleTest(LogicTest):
|
||||
</poll_question>
|
||||
'''
|
||||
|
||||
output = PollDescriptor.from_xml(sample_poll_xml, module_system, id_generator)
|
||||
output = PollBlock.from_xml(sample_poll_xml, module_system, id_generator)
|
||||
# Update the answer with invalid character.
|
||||
invalid_characters_poll_answer = output.answers[0]
|
||||
# Invalid less-than character.
|
||||
|
||||
@@ -34,7 +34,7 @@ from xmodule.annotatable_module import AnnotatableBlock
|
||||
from xmodule.conditional_module import ConditionalBlock
|
||||
from xmodule.course_module import CourseBlock
|
||||
from xmodule.html_module import HtmlBlock
|
||||
from xmodule.poll_module import PollDescriptor
|
||||
from xmodule.poll_module import PollBlock
|
||||
from xmodule.randomize_module import RandomizeBlock
|
||||
from xmodule.seq_module import SequenceBlock
|
||||
from xmodule.tests import get_test_descriptor_system, get_test_system
|
||||
@@ -57,7 +57,7 @@ from xmodule.x_module import (
|
||||
LEAF_XMODULES = {
|
||||
AnnotatableBlock: [{}],
|
||||
HtmlBlock: [{}],
|
||||
PollDescriptor: [{'display_name': 'Poll Display Name'}],
|
||||
PollBlock: [{'display_name': 'Poll Display Name'}],
|
||||
WordCloudBlock: [{}],
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ CONTAINER_XMODULES = {
|
||||
|
||||
# These modules are not editable in studio yet
|
||||
NOT_STUDIO_EDITABLE = (
|
||||
PollDescriptor,
|
||||
PollBlock,
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user