Commit 11ab81ce by Calen Pennington

Add tests of javascript children methods to AcidBlock

parent aa95a3c1
...@@ -4,7 +4,8 @@ import logging ...@@ -4,7 +4,8 @@ import logging
import pkg_resources import pkg_resources
import random import random
import webob import webob
from itertools import chain from lazy import lazy
from mako.lookup import TemplateLookup
from xblock.core import XBlock from xblock.core import XBlock
from xblock.fields import Scope, Dict, Boolean from xblock.fields import Scope, Dict, Boolean
...@@ -55,6 +56,7 @@ class AcidBlock(XBlock): ...@@ -55,6 +56,7 @@ class AcidBlock(XBlock):
""" """
A testing block that checks the behavior of the container. A testing block that checks the behavior of the container.
""" """
has_children = True
SUCCESS_CLASS = 'fa fa-check-square-o fa-lg pass' SUCCESS_CLASS = 'fa fa-check-square-o fa-lg pass'
FAILURE_CLASS = 'fa fa-times fa-lg fail' FAILURE_CLASS = 'fa fa-times fa-lg fail'
...@@ -70,6 +72,25 @@ class AcidBlock(XBlock): ...@@ -70,6 +72,25 @@ class AcidBlock(XBlock):
} }
) )
@lazy
def template_lookup(self):
return TemplateLookup(
directories=[pkg_resources.resource_filename(__name__, 'static')],
)
def render_template(self, path, **kwargs):
"""
Render the template at `path`, supplying `kwargs`.
"""
return self.template_lookup.get_template(path).render_unicode(**kwargs)
@lazy
def parent_value(self):
"""
This value is used to test that AcidBlock are visible to their parents.
"""
return random.randint(0, 9999)
def resource_string(self, path): def resource_string(self, path):
"""Handy helper for getting resources from our kit.""" """Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path) data = pkg_resources.resource_string(__name__, path)
...@@ -116,9 +137,6 @@ class AcidBlock(XBlock): ...@@ -116,9 +137,6 @@ class AcidBlock(XBlock):
This view is used by the Acid XBlock to test various features of This view is used by the Acid XBlock to test various features of
the runtime it is contained in the runtime it is contained in
""" """
block_template = self.resource_string("static/html/acid.html")
storage_test_template = self.resource_string('static/html/scope_storage_test.html')
scopes = ( scopes = (
scope scope
for scope in Scope.scopes() for scope in Scope.scopes()
...@@ -130,23 +148,40 @@ class AcidBlock(XBlock): ...@@ -130,23 +148,40 @@ class AcidBlock(XBlock):
for scope in scopes: for scope in scopes:
try: try:
scope_test_contexts.append(self.setup_storage(scope.name)) scope_test_contexts.append(self.setup_storage(scope.name))
except Exception as exc: except Exception:
logging.warning('Unable to use scope in acid test', exc_info=True) logging.warning('Unable to use scope in acid test', exc_info=True)
frag = Fragment(block_template.format( # Save the changes to our fields so that they are visible to our children
self.save()
children = [
self.runtime.get_block(child_id)
for child_id in self.children
]
rendered_children = [
self.runtime.render_child(child, view_name, context=context)
for child in children
]
child_values = {
child.name: child.parent_value
for child in children
if child.scope_ids.block_type == 'acid' and child.name is not None
}
frag = Fragment(self.render_template(
'html/acid.html.mako',
error_class=self.ERROR_CLASS, error_class=self.ERROR_CLASS,
success_class=self.SUCCESS_CLASS, success_class=self.SUCCESS_CLASS,
failure_class=self.FAILURE_CLASS, failure_class=self.FAILURE_CLASS,
unknown_class=self.UNKNOWN_CLASS, unknown_class=self.UNKNOWN_CLASS,
storage_tests='\n'.join( acid_child_values=child_values,
storage_test_template.format( acid_child_count=len([child for child in children if child.scope_ids.block_type == 'acid']),
alt="alt" if idx % 2 else "", rendered_children=(fragment.content for fragment in rendered_children),
unknown_class=self.UNKNOWN_CLASS, storage_tests=scope_test_contexts,
**context
)
for idx, context in enumerate(scope_test_contexts)
),
)) ))
frag.add_frags_resources(rendered_children)
frag.add_javascript(self.resource_string("static/js/jquery.ajaxq-0.0.1.js")) frag.add_javascript(self.resource_string("static/js/jquery.ajaxq-0.0.1.js"))
frag.add_javascript(self.resource_string('static/js/acid.js')) frag.add_javascript(self.resource_string('static/js/acid.js'))
...@@ -220,9 +255,10 @@ class AcidBlock(XBlock): ...@@ -220,9 +255,10 @@ class AcidBlock(XBlock):
("XBlock Acid test", ("XBlock Acid test",
"""\ """\
<vertical_demo> <vertical_demo>
<acid/> <acid name='parent'>
<acid/> <acid name='left-child'/>
<acid/> <acid name='right-child'/>
</acid>
</vertical_demo> </vertical_demo>
""") """)
] ]
...@@ -35,4 +35,10 @@ table.storage-tests, .storage-tests th { ...@@ -35,4 +35,10 @@ table.storage-tests, .storage-tests th {
text-align: center; text-align: center;
padding: 5px; padding: 5px;
border-top: 1px solid lightgrey; border-top: 1px solid lightgrey;
}
.acid-children {
border-top: 3px solid lightgrey;
margin: 5px;
padding-left: 30px;
} }
\ No newline at end of file
<div class="acid-block"
data-success-class="{success_class}"
data-failure-class="{failure_class}"
data-error-class="{error_class}"
data-unknown-class="{unknown_class}">
<p>Acid XBlock</p>
<p>JS init function run:
<span class="js-init-run">
<i class="fa fa-question-circle fa-lg unknown"></i>
</span>
</p>
<p>Document-ready function run:
<span class="document-ready-run">
<i class="fa fa-question-circle fa-lg unknown"></i>
</span>
</p>
<table class='storage-tests'>
<tr>
<th>Scope</th>
<th>Server-side<br>handler_url<br>returned</th>
<th>Server-side<br>handler_url<br>succeeded</th>
<th>Client-side<br>handler_url<br>returned</th>
<th>Client-side<br>handler_url<br>succeeded</th>
</tr>
{storage_tests}
</table>
</div>
<%! import json %>
<div class="acid-block"
data-success-class="${success_class}"
data-failure-class="${failure_class}"
data-error-class="${error_class}"
data-unknown-class="${unknown_class}"
data-acid-child-count="${acid_child_count}"
>
<script class="acid-child-values" type="application/json">
${json.dumps(acid_child_values)}
</script>
<p>Acid XBlock</p>
<p>JS init function run:
<span class="js-init-run">
<i class="${unknown_class}"></i>
</span>
</p>
<p>Document-ready function run:
<span class="document-ready-run">
<i class="${unknown_class}"></i>
</span>
</p>
<p>Acid Child counts match:
<span class="child-counts-match">
<i class="${unknown_class}"></i>
</span>
</p>
<p>Acid Child values match:
<span class="child-values-match">
<i class="${unknown_class}"></i>
</span>
</p>
<table class='storage-tests'>
<tr>
<th>Scope</th>
<th>Server-side<br>handler_url<br>returned</th>
<th>Server-side<br>handler_url<br>succeeded</th>
<th>Client-side<br>handler_url<br>returned</th>
<th>Client-side<br>handler_url<br>succeeded</th>
</tr>
% for test in storage_tests:
<tr class="scope-storage-test scope-${test['scope']} ${loop.cycle('', 'alt')}"
data-handler-url="${test['handler_url']}"
data-scope="${test['scope']}"
data-value="${test['value']}"
>
<td>${test['scope']}</td>
<td>
<span class="server-storage-test-returned">
<i class="${unknown_class}"></i>
</span>
</td>
<td>
<span class="server-storage-test-succeeded">
<i class="${unknown_class}"></i>
</span>
</td>
<td>
<span class="client-storage-test-returned">
<i class="${unknown_class}"></i>
</span>
</td>
<td>
<span class="client-storage-test-succeeded">
<i class="${unknown_class}"></i>
</span>
</td>
</tr>
% endfor
</table>
<div class='acid-children'>
% for child in rendered_children:
${child}
% endfor
</div>
</div>
/* Javascript for the Acid XBlock. */ /* Javascript for the Acid XBlock. */
function AcidBlock(runtime, element) { function AcidBlock(runtime, element) {
function mark(result, selector, subelem) { function acidData(key) {
var elems = $(selector, subelem || element) return $('.acid-block', element).data(key);
}
function mark(result, selector, subelem, msg) {
subelem = subelem || element;
msg = msg || "";
var elems = $(selector, subelem || element).not($('.acid-children *', element))
if (elems.length == 1) { if (elems.length == 1) {
$("<i/>", { symbol = $("<i/>", {
'class': $('.acid-block', element).data(result + '-class') 'class': acidData(result + '-class')
}).appendTo(elems.empty()); });
if (msg) {
symbol = symbol.after(": " + msg)
}
symbol.appendTo(elems.empty());
} else { } else {
$("<i/>", { $("<i/>", {
'class': $('.acid-block', element).data('error-class') 'class': acidData('error-class')
}).after("ASSERTION FAILURE: Can only mark single elements").appendTo(elems.empty()) }).after("ASSERTION FAILURE: Can only mark single elements").appendTo(elems.empty())
console.log(elems); console.log(elems);
} }
} }
mark('success', '.js-init-run'); function childTests() {
if (acidData('acid-child-count') == runtime.children(element).length) {
mark('success', '.child-counts-match');
}
$(function ($) { var childValues = JSON.parse($('.acid-child-values', element).html());
mark('success', '.document-ready-run'); $.each(childValues, function(name, value) {
var child_value = runtime.childMap(element, name).parentValue;
if (child_value != value) {
mark(
'failure', '.child-values-match', element,
'Child ' + name + ' had value ' + child_value + ' but expected ' + value
);
return;
}
});
mark('success', '.child-values-match');
}
function scopeTests() {
$('.scope-storage-test', element).each(function() { $('.scope-storage-test', element).each(function() {
var $this = $(this); var $this = $(this);
$.ajaxq("acid_queue", { $.ajaxq("acid-queue", {
type: "POST", type: "POST",
data: {"VALUE": $this.data('value')}, data: {"VALUE": $this.data('value')},
url: $this.data('handler-url'), url: $this.data('handler-url'),
...@@ -31,7 +56,7 @@ function AcidBlock(runtime, element) { ...@@ -31,7 +56,7 @@ function AcidBlock(runtime, element) {
if (ret.status == "ok") { if (ret.status == "ok") {
mark('success', '.server-storage-test-succeeded', $this); mark('success', '.server-storage-test-succeeded', $this);
$.ajaxq("acid_queue", { $.ajaxq("acid-queue", {
type: "POST", type: "POST",
data: {"VALUE": ret.value}, data: {"VALUE": ret.value},
url: runtime.handlerUrl(element, "check_storage", ret.suffix, ret.query), url: runtime.handlerUrl(element, "check_storage", ret.suffix, ret.query),
...@@ -41,15 +66,26 @@ function AcidBlock(runtime, element) { ...@@ -41,15 +66,26 @@ function AcidBlock(runtime, element) {
if (ret.status == "ok") { if (ret.status == "ok") {
mark('success', '.client-storage-test-succeeded', $this); mark('success', '.client-storage-test-succeeded', $this);
} else { } else {
mark('failure', '.client-storage-test-succeeded', ret.message, $this); mark('failure', '.client-storage-test-succeeded', $this, ret.message);
} }
} }
}); });
} else { } else {
mark('failure', '.server-storage-test-succeeded', ret.message, $this); mark('failure', '.server-storage-test-succeeded', $this, ret.message);
} }
} }
}); });
}); });
}
mark('success', '.js-init-run');
$(function ($) {
mark('success', '.document-ready-run');
childTests();
scopeTests();
}); });
return {parentValue: acidData('parent-value')}
} }
...@@ -11,6 +11,8 @@ setup( ...@@ -11,6 +11,8 @@ setup(
], ],
install_requires=[ install_requires=[
'XBlock', 'XBlock',
'Mako',
'lazy',
], ],
entry_points={ entry_points={
'xblock.v1': [ 'xblock.v1': [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment