Commit 11ab81ce by Calen Pennington

Add tests of javascript children methods to AcidBlock

parent aa95a3c1
......@@ -4,7 +4,8 @@ import logging
import pkg_resources
import random
import webob
from itertools import chain
from lazy import lazy
from mako.lookup import TemplateLookup
from xblock.core import XBlock
from xblock.fields import Scope, Dict, Boolean
......@@ -55,6 +56,7 @@ class AcidBlock(XBlock):
"""
A testing block that checks the behavior of the container.
"""
has_children = True
SUCCESS_CLASS = 'fa fa-check-square-o fa-lg pass'
FAILURE_CLASS = 'fa fa-times fa-lg fail'
......@@ -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):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
......@@ -116,9 +137,6 @@ class AcidBlock(XBlock):
This view is used by the Acid XBlock to test various features of
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 = (
scope
for scope in Scope.scopes()
......@@ -130,23 +148,40 @@ class AcidBlock(XBlock):
for scope in scopes:
try:
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)
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,
success_class=self.SUCCESS_CLASS,
failure_class=self.FAILURE_CLASS,
unknown_class=self.UNKNOWN_CLASS,
storage_tests='\n'.join(
storage_test_template.format(
alt="alt" if idx % 2 else "",
unknown_class=self.UNKNOWN_CLASS,
**context
)
for idx, context in enumerate(scope_test_contexts)
),
acid_child_values=child_values,
acid_child_count=len([child for child in children if child.scope_ids.block_type == 'acid']),
rendered_children=(fragment.content for fragment in rendered_children),
storage_tests=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/acid.js'))
......@@ -220,9 +255,10 @@ class AcidBlock(XBlock):
("XBlock Acid test",
"""\
<vertical_demo>
<acid/>
<acid/>
<acid/>
<acid name='parent'>
<acid name='left-child'/>
<acid name='right-child'/>
</acid>
</vertical_demo>
""")
]
......@@ -35,4 +35,10 @@ table.storage-tests, .storage-tests th {
text-align: center;
padding: 5px;
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. */
function AcidBlock(runtime, element) {
function mark(result, selector, subelem) {
var elems = $(selector, subelem || element)
function acidData(key) {
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) {
$("<i/>", {
'class': $('.acid-block', element).data(result + '-class')
}).appendTo(elems.empty());
symbol = $("<i/>", {
'class': acidData(result + '-class')
});
if (msg) {
symbol = symbol.after(": " + msg)
}
symbol.appendTo(elems.empty());
} else {
$("<i/>", {
'class': $('.acid-block', element).data('error-class')
'class': acidData('error-class')
}).after("ASSERTION FAILURE: Can only mark single elements").appendTo(elems.empty())
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 ($) {
mark('success', '.document-ready-run');
var childValues = JSON.parse($('.acid-child-values', element).html());
$.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() {
var $this = $(this);
$.ajaxq("acid_queue", {
$.ajaxq("acid-queue", {
type: "POST",
data: {"VALUE": $this.data('value')},
url: $this.data('handler-url'),
......@@ -31,7 +56,7 @@ function AcidBlock(runtime, element) {
if (ret.status == "ok") {
mark('success', '.server-storage-test-succeeded', $this);
$.ajaxq("acid_queue", {
$.ajaxq("acid-queue", {
type: "POST",
data: {"VALUE": ret.value},
url: runtime.handlerUrl(element, "check_storage", ret.suffix, ret.query),
......@@ -41,15 +66,26 @@ function AcidBlock(runtime, element) {
if (ret.status == "ok") {
mark('success', '.client-storage-test-succeeded', $this);
} else {
mark('failure', '.client-storage-test-succeeded', ret.message, $this);
mark('failure', '.client-storage-test-succeeded', $this, ret.message);
}
}
});
} 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(
],
install_requires=[
'XBlock',
'Mako',
'lazy',
],
entry_points={
'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