Commit 0a839436 by Martyn James

Changes as a result of feedback

parent 90399e79
......@@ -17,9 +17,18 @@ from xblockutils.resources import ResourceLoader
LOG = logging.getLogger(__name__)
RESOURCE_LOADER = ResourceLoader(__name__)
# Classes ###########################################################
# Constants ###########################################################
DEFAULT_CALENDAR_ID = "edx.org_lom804qe3ttspplj1bgeu1l3ak@group.calendar.google.com"
CALENDAR_TEMPLATE = "/templates/html/google_calendar.html"
CALENDAR_EDIT_TEMPLATE = "/templates/html/google_calendar_edit.html"
CALENDAR_IFRAME = (
'<iframe src="https://www.google.com/calendar/embed'
'?mode={}&amp;src={}&amp;showCalendars=0" title="{}"></iframe>'
)
# Classes ###########################################################
class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-many-ancestors
"""
XBlock providing a google calendar view for a specific calendar
......@@ -38,7 +47,7 @@ class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"open Settings and copy the ID from the Calendar Address section into this field."
),
scope=Scope.settings,
default="edx.org_lom804qe3ttspplj1bgeu1l3ak@group.calendar.google.com"
default=DEFAULT_CALENDAR_ID
)
default_view = Integer(
......@@ -55,19 +64,12 @@ class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"""
Player view, displayed to the student
"""
fragment = Fragment()
view = self.views[self.default_view][1]
iframe = CALENDAR_IFRAME.format(view, self.calendar_id, self.display_name)
iframe = (
'<iframe src="https://www.google.com/calendar/embed'
'?mode={}&amp;src={}&amp;showCalendars=0" title="{}"></iframe>'
).format(
view, self.calendar_id, self.display_name
)
fragment.add_content(RESOURCE_LOADER.render_template('/templates/html/google_calendar.html', {
fragment.add_content(RESOURCE_LOADER.render_template(CALENDAR_TEMPLATE, {
"self": self,
"iframe": iframe
}))
......@@ -85,7 +87,7 @@ class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"""
fragment = Fragment()
# Need to access protected members of fields to get their default value
fragment.add_content(RESOURCE_LOADER.render_template('/templates/html/google_calendar_edit.html', {
fragment.add_content(RESOURCE_LOADER.render_template(CALENDAR_EDIT_TEMPLATE, {
'self': self,
'defaultName': self.fields['display_name']._default, # pylint: disable=protected-access
'defaultID': self.fields['calendar_id']._default # pylint: disable=protected-access
......
......@@ -19,9 +19,23 @@ from xblockutils.resources import ResourceLoader
LOG = logging.getLogger(__name__)
RESOURCE_LOADER = ResourceLoader(__name__)
# Classes ###########################################################
# Constants ###########################################################
DEFAULT_EMBED_CODE = textwrap.dedent("""
<iframe
src="https://docs.google.com/presentation/d/1x2ZuzqHsMoh1epK8VsGAlanSo7r9z55ualwQlj-ofBQ/embed?start=true&loop=true&delayms=10000"
frameborder="0"
width="960"
height="569"
allowfullscreen="true"
mozallowfullscreen="true"
webkitallowfullscreen="true">
</iframe>
""")
DOCUMENT_TEMPLATE = "/templates/html/google_docs.html"
DOCUMENT_EDIT_TEMPLATE = "/templates/html/google_docs_edit.html"
# Classes ###########################################################
class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-many-ancestors
"""
XBlock providing a google document embed link
......@@ -41,17 +55,8 @@ class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"Publish, and copy the embed code into this field."
),
scope=Scope.settings,
default=textwrap.dedent("""
<iframe
src="https://docs.google.com/presentation/d/1x2ZuzqHsMoh1epK8VsGAlanSo7r9z55ualwQlj-ofBQ/embed?start=true&loop=true&delayms=10000"
frameborder="0"
width="960"
height="569"
allowfullscreen="true"
mozallowfullscreen="true"
webkitallowfullscreen="true">
</iframe>
"""))
default=DEFAULT_EMBED_CODE
)
alt_text = String(
display_name="Alternative Text",
......@@ -68,10 +73,9 @@ class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"""
Player view, displayed to the student
"""
fragment = Fragment()
fragment.add_content(RESOURCE_LOADER.render_template('/templates/html/google_docs.html', {"self": self}))
fragment.add_content(RESOURCE_LOADER.render_template(DOCUMENT_TEMPLATE, {"self": self}))
fragment.add_css(RESOURCE_LOADER.load_unicode('public/css/google_docs.css'))
fragment.add_javascript(RESOURCE_LOADER.load_unicode('public/js/google_docs.js'))
......@@ -86,7 +90,7 @@ class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-man
"""
fragment = Fragment()
# Need to access protected members of fields to get their default value
fragment.add_content(RESOURCE_LOADER.render_template('/templates/html/google_docs_edit.html', {
fragment.add_content(RESOURCE_LOADER.render_template(DOCUMENT_EDIT_TEMPLATE, {
'self': self,
'defaultName': self.fields['display_name']._default # pylint: disable=protected-access
}))
......
/* Javascript for GoogleDocumentBlock. */
function GoogleCalendarBlock(runtime, element) {
$('iframe', element).load(function(){
var iframe_url = $(this).attr('src');
$.ajax({
......
/* Javascript for GoogleDocumentBlock. */
function GoogleDocumentBlock(runtime, element) {
var iframe = $('iframe', element);
var image = $('img', element);
var xblock_wrapper = $('.google-docs-xblock-wrapper', element);
......
function GoogleDocumentEditBlock(runtime, element) {
var clear_name_button = $('.clear-display-name', element);
var save_button = $('.save-button', element);
var validation_alert = $('.validation_alert', element);
......
""" Put tests here """
""" Unit and integration tests for google drive components """
""" Unit tests for google drive components """
""" Integration tests for google drive components """
""" Unit tests for google document components """
import json
import unittest
from mock import Mock
from nose.tools import assert_equals, assert_in
from workbench.runtime import WorkbenchRuntime
from xblock.runtime import KvsFieldData, DictKeyValueStore
from google_drive import GoogleCalendarBlock
from google_drive.tests.unit.test_utils import generate_scope_ids, make_request
class TestGoogleCalendarBlock(unittest.TestCase):
""" Tests for GoogleCalendarBlock """
@classmethod
def make_calendar_block(cls):
""" helper to construct a GoogleCalendarBlock """
runtime = WorkbenchRuntime()
key_store = DictKeyValueStore()
db_model = KvsFieldData(key_store)
ids = generate_scope_ids(runtime, 'google_calendar')
return GoogleCalendarBlock(runtime, db_model, scope_ids=ids)
def test_calendar_template_content(self): # pylint: disable=no-self-use
""" Test content of GoogleCalendarBlock's rendered views """
block = TestGoogleCalendarBlock.make_calendar_block()
block.usage_id = Mock()
student_fragment = block.render('student_view', Mock())
# pylint: disable=no-value-for-parameter
assert_in('<div class="google-calendar-xblock-wrapper">', student_fragment.content)
assert_in(
(
'https://www.google.com/calendar/embed?mode=Month&amp;src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&amp;showCalendars=0'
),
student_fragment.content
)
assert_in('Google Calendar', student_fragment.content)
studio_fragment = block.render('studio_view', Mock())
assert_in(
'<div class="wrapper-comp-settings is-active editor-with-buttons google-edit-wrapper" id="settings-tab">',
studio_fragment.content
)
assert_in('<div class="user-inputs-and-validation">', studio_fragment.content)
assert_in('<div class="xblock-inputs editor_content_wrapper">', studio_fragment.content)
assert_in('<div class="xblock-actions">', studio_fragment.content)
def test_calendar_document_submit(self): # pylint: disable=no-self-use
""" Test studio submission of GoogleCalendarBlock """
block = TestGoogleCalendarBlock.make_calendar_block()
body = json.dumps({
'display_name': "Google Calendar",
'calendar_id': "google1234",
'default_view': 1
})
res = block.handle('studio_submit', make_request(body))
# pylint: disable=no-value-for-parameter
assert_equals(json.loads(res.body), {'result': 'success'})
assert_equals(block.display_name, "Google Calendar")
assert_equals(block.calendar_id, "google1234")
assert_equals(block.default_view, 1)
def test_calendar_publish_event(self): # pylint: disable=no-self-use
""" Test event publishing in GoogleCalendarBlock"""
block = TestGoogleCalendarBlock.make_calendar_block()
body = json.dumps({
'url': (
'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&showCalendars=0'
),
'displayed_in': 'iframe',
'event_type': 'edx.googlecomponent.calendar.displayed'
})
res = block.handle('publish_event', make_request(body))
# pylint: disable=no-value-for-parameter
assert_equals(json.loads(res.body), {'result': 'success'})
body = json.dumps({
'url': (
'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&showCalendars=0'
),
'displayed_in': 'iframe',
})
res = block.handle('publish_event', make_request(body))
assert_equals(json.loads(res.body), {'result': 'error', 'message': 'Missing event_type in JSON data'})
""" Tests for google drive components """
""" Unit tests for google document components """
import json
import unittest
from webob import Request
from mock import Mock
from nose.tools import assert_equals, assert_in
from workbench.runtime import WorkbenchRuntime
from xblock.runtime import KvsFieldData, DictKeyValueStore
from xblock.fields import ScopeIds
from google_drive import GoogleDocumentBlock, GoogleCalendarBlock
from nose.tools import assert_equals, assert_in
def generate_scope_ids(runtime, block_type):
""" helper to generate scope IDs for an XBlock """
def_id = runtime.id_generator.create_definition(block_type)
usage_id = runtime.id_generator.create_usage(def_id)
return ScopeIds('user', block_type, def_id, usage_id)
def make_request(body, method='POST'):
""" helper to make a request """
request = Request.blank('/')
request.method = 'POST'
request.body = body.encode('utf-8')
request.method = method
return request
from google_drive import GoogleDocumentBlock
from google_drive.tests.unit.test_utils import generate_scope_ids, make_request
class TestGoogleDocumentBlock(unittest.TestCase):
......@@ -155,86 +136,3 @@ class TestGoogleDocumentBlock(unittest.TestCase):
res = block.handle('publish_event', make_request(body))
assert_equals(json.loads(res.body), {'result': 'error', 'message': 'Missing event_type in JSON data'})
class TestGoogleCalendarBlock(unittest.TestCase):
""" Tests for GoogleCalendarBlock """
@classmethod
def make_calendar_block(cls):
""" helper to construct a GoogleCalendarBlock """
runtime = WorkbenchRuntime()
key_store = DictKeyValueStore()
db_model = KvsFieldData(key_store)
ids = generate_scope_ids(runtime, 'google_calendar')
return GoogleCalendarBlock(runtime, db_model, scope_ids=ids)
def test_calendar_template_content(self): # pylint: disable=no-self-use
""" Test content of GoogleCalendarBlock's rendered views """
block = TestGoogleCalendarBlock.make_calendar_block()
block.usage_id = Mock()
student_fragment = block.render('student_view', Mock())
# pylint: disable=no-value-for-parameter
assert_in('<div class="google-calendar-xblock-wrapper">', student_fragment.content)
assert_in(
(
'https://www.google.com/calendar/embed?mode=Month&amp;src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&amp;showCalendars=0'
),
student_fragment.content
)
assert_in('Google Calendar', student_fragment.content)
studio_fragment = block.render('studio_view', Mock())
assert_in(
'<div class="wrapper-comp-settings is-active editor-with-buttons google-edit-wrapper" id="settings-tab">',
studio_fragment.content
)
assert_in('<div class="user-inputs-and-validation">', studio_fragment.content)
assert_in('<div class="xblock-inputs editor_content_wrapper">', studio_fragment.content)
assert_in('<div class="xblock-actions">', studio_fragment.content)
def test_calendar_document_submit(self): # pylint: disable=no-self-use
""" Test studio submission of GoogleCalendarBlock """
block = TestGoogleCalendarBlock.make_calendar_block()
body = json.dumps({
'display_name': "Google Calendar",
'calendar_id': "google1234",
'default_view': 1
})
res = block.handle('studio_submit', make_request(body))
# pylint: disable=no-value-for-parameter
assert_equals(json.loads(res.body), {'result': 'success'})
assert_equals(block.display_name, "Google Calendar")
assert_equals(block.calendar_id, "google1234")
assert_equals(block.default_view, 1)
def test_calendar_publish_event(self): # pylint: disable=no-self-use
""" Test event publishing in GoogleCalendarBlock"""
block = TestGoogleCalendarBlock.make_calendar_block()
body = json.dumps({
'url': (
'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&showCalendars=0'
),
'displayed_in': 'iframe',
'event_type': 'edx.googlecomponent.calendar.displayed'
})
res = block.handle('publish_event', make_request(body))
# pylint: disable=no-value-for-parameter
assert_equals(json.loads(res.body), {'result': 'success'})
body = json.dumps({
'url': (
'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak'
'@group.calendar.google.com&showCalendars=0'
),
'displayed_in': 'iframe',
})
res = block.handle('publish_event', make_request(body))
assert_equals(json.loads(res.body), {'result': 'error', 'message': 'Missing event_type in JSON data'})
""" Utility functions used within unit tests """
from webob import Request
from xblock.fields import ScopeIds
def generate_scope_ids(runtime, block_type):
""" helper to generate scope IDs for an XBlock """
def_id = runtime.id_generator.create_definition(block_type)
usage_id = runtime.id_generator.create_usage(def_id)
return ScopeIds('user', block_type, def_id, usage_id)
def make_request(body, method='POST'):
""" helper to make a request """
request = Request.blank('/')
request.method = 'POST'
request.body = body.encode('utf-8')
request.method = method
return request
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