diff --git a/README.md b/README.md deleted file mode 100644 index 213860a..0000000 --- a/README.md +++ /dev/null @@ -1,125 +0,0 @@ -Google Drive & Calendar XBlock [![Build Status](https://travis-ci.org/edx-solutions/xblock-google-drive.svg?branch=master)](https://travis-ci.org/edx-solutions/xblock-google-drive) ------------------------------- - -This XBlock allows embedding of Google documents and calendar, -within an edX course. - -Installation ------------- - -Install the requirements into the python virtual environment of your -`edx-platform` installation by running the following command from the -root folder: - -```bash -$ pip install -r requirements.txt -``` - -Enabling in Studio ------------------- - -You can enable the Google Drive & Calendar XBlock in studio through the advanced -settings. - -1. From the main page of a specific course, navigate to `Settings -> - Advanced Settings` from the top menu. -2. Check for the `advanced_modules` policy key, and add `"google-document"` and - `"google-calendar"` to the policy value list. -3. Click the "Save changes" button. - -Workbench installation and settings ------------------------------------ - -Install to the workbench's virtualenv by running the following command form the google-drive repo root: - -```bash -pip install -r requirements.txt -``` - -Running the workbench ---------------------- - -```bash -$ ./manage.py runserver 8000 -``` - -Access it at [http://localhost:8000/](http://localhost:8000). - -Running tests -------------- - -From google-drive directory, run the tests with the -following command: - -```bash -$ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/* -``` - -If you want to run only the integration or the unit tests, append the directory to the command. You can also run separate modules in this manner. - -```bash -$ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/unit -``` - -To see the coverage, run the tests using the following command: - -```bash -$ DJANGO_SETTINGS_MODULE="settings" nosetests --with-coverage --cover-package="google_drive" --with-django -``` - -If you have not installed the xblock-sdk in the active virtualenv, -you might also have to prepend `PYTHONPATH=".:/path/to/xblock"` to the command above. -(`/path/to/xblock` is the path to the xblock-sdk, where the workbench resides). - -Changes to be documented ------------------------- - -1. Calendar width is set to 100% of parent element's width; this optimizes the display of google document content within the LMS user interface -2. Max width of Google images is set to 100% to prevent images from overflowing outside the parent element's boundaries -3. Since Google WordProcessing documents and Spreadsheets don't allow users to explicitly define width and height, their width is set to 100%. Also, min height is set to 450px, so that documents and/or spreadsheets with larger number of rows are displayed in their natural size. Overflow scroll is automatically turned on when the height of the document becomes larger than the height of the parent. - -Validation ----------- - -Each time a character is added to or removed from Google Calendar ID, validation takes place. -Analogically, validation takes place for embedded code of Google Drive File. - -1. Google calendar IDs are being validated against a regular expression. IDs must contain at least one '@' character, with at least one character on each side of it, ie. 'a@a'. - -2. Embedded code of Google Drive file is being validated on the server side, by checking the status code of the HTTP response. - Since error status codes start with 400, it's assumed that each status code that's larger than or equal to 400 states that file is invalid. - If for any reason exception occurs while getting an HTTP response, error code is returned, thus overriding default signalization that is invoked by edx platform when the 500 status code is reported. - -Accessibility (a11y) ----- - -For users with a visual impairment: - -1. Iframes in which Google calendars and Google Drive files (except images) are shown now have title attribute with alternative text content which describes what the iframe contains. -2. Images have alt attribute which contains alternative text that has the same purpose as the title attribute of an iframe has - -Analytics ---------- - -For analytics purposes, each time an image or iframe containing a calendar or Google Drive file is loaded, an event will be triggered. - -There are two types of events: - -1. edx.googlecomponent.calendar.displayed (if an iframe containing a Google calendar is loaded) -2. edx.googlecomponent.document.displayed (if an image or an iframe containing a Google Drive File is loaded) - -License -------- - -The Google Drive & Calendar XBlocks are available under the GNU Affero General -Public License (AGPLv3). - -## Installation Troubleshooting -On a Mac, some people have received errors when installing lxml, trying to find a specific header file for the compiler - -Try the following if you encounter a problem: -``` -CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2 CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments pip install lxml -``` - - diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..e8f7efe --- /dev/null +++ b/README.rst @@ -0,0 +1,155 @@ +Google Drive & Calendar XBlock |Build Status| +--------------------------------------------- + +This XBlock allows embedding of Google documents and calendar, within an +edX course. + +Installation +------------ + +Install the requirements into the python virtual environment of your +``edx-platform`` installation by running the following command from the +root folder: + +.. code:: bash + + $ pip install -r requirements.txt + +Enabling in Studio +------------------ + +You can enable the Google Drive & Calendar XBlock in studio through the +advanced settings. + +1. From the main page of a specific course, navigate to + ``Settings -> Advanced Settings`` from the top menu. +2. Check for the ``advanced_modules`` policy key, and add + ``"google-document"`` and ``"google-calendar"`` to the policy value + list. +3. Click the "Save changes" button. + +Workbench installation and settings +----------------------------------- + +Install to the workbench's virtualenv by running the following command +form the google-drive repo root: + +.. code:: bash + + pip install -r requirements.txt + +Running the workbench +--------------------- + +.. code:: bash + + $ ./manage.py runserver 8000 + +Access it at `http://localhost:8000/ `__. + +Running tests +------------- + +From google-drive directory, run the tests with the following command: + +.. code:: bash + + $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/* + +If you want to run only the integration or the unit tests, append the +directory to the command. You can also run separate modules in this +manner. + +.. code:: bash + + $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-django tests/unit + +To see the coverage, run the tests using the following command: + +.. code:: bash + + $ DJANGO_SETTINGS_MODULE="settings" nosetests --with-coverage --cover-package="google_drive" --with-django + +If you have not installed the xblock-sdk in the active virtualenv, you +might also have to prepend ``PYTHONPATH=".:/path/to/xblock"`` to the +command above. (``/path/to/xblock`` is the path to the xblock-sdk, where +the workbench resides). + +Changes to be documented +------------------------ + +1. Calendar width is set to 100% of parent element's width; this + optimizes the display of google document content within the LMS user + interface +2. Max width of Google images is set to 100% to prevent images from + overflowing outside the parent element's boundaries +3. Since Google WordProcessing documents and Spreadsheets don't allow + users to explicitly define width and height, their width is set to + 100%. Also, min height is set to 450px, so that documents and/or + spreadsheets with larger number of rows are displayed in their + natural size. Overflow scroll is automatically turned on when the + height of the document becomes larger than the height of the parent. + +Validation +---------- + +Each time a character is added to or removed from Google Calendar ID, +validation takes place. Analogically, validation takes place for +embedded code of Google Drive File. + +1. Google calendar IDs are being validated against a regular expression. + IDs must contain at least one '@' character, with at least one + character on each side of it, ie. 'a@a'. + +2. Embedded code of Google Drive file is being validated on the server + side, by checking the status code of the HTTP response. Since error + status codes start with 400, it's assumed that each status code + that's larger than or equal to 400 states that file is invalid. If + for any reason exception occurs while getting an HTTP response, error + code is returned, thus overriding default signalization that is + invoked by edx platform when the 500 status code is reported. + +Accessibility (a11y) +-------------------- + +For users with a visual impairment: + +1. Iframes in which Google calendars and Google Drive files (except + images) are shown now have title attribute with alternative text + content which describes what the iframe contains. +2. Images have alt attribute which contains alternative text that has + the same purpose as the title attribute of an iframe has + +Analytics +--------- + +For analytics purposes, each time an image or iframe containing a +calendar or Google Drive file is loaded, an event will be triggered. + +There are two types of events: + +1. edx.googlecomponent.calendar.displayed (if an iframe containing a + Google calendar is loaded) +2. edx.googlecomponent.document.displayed (if an image or an iframe + containing a Google Drive File is loaded) + +License +------- + +The Google Drive & Calendar XBlocks are available under the GNU Affero +General Public License (AGPLv3). + +Installation Troubleshooting +---------------------------- + +On a Mac, some people have received errors when installing lxml, trying +to find a specific header file for the compiler + +Try the following if you encounter a problem: + +:: + + CPATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/libxml2 CFLAGS=-Qunused-arguments CPPFLAGS=-Qunused-arguments pip install lxml + +.. |Build Status| image:: https://travis-ci.org/edx-solutions/xblock-google-drive.svg?branch=master + :target: https://travis-ci.org/edx-solutions/xblock-google-drive diff --git a/google_drive/google_calendar.py b/google_drive/google_calendar.py index a51e2a9..1c83b56 100644 --- a/google_drive/google_calendar.py +++ b/google_drive/google_calendar.py @@ -15,9 +15,10 @@ LOG = logging.getLogger(__name__) RESOURCE_LOADER = ResourceLoader(__name__) - # Constants ########################################################### DEFAULT_CALENDAR_ID = "edx.org_lom804qe3ttspplj1bgeu1l3ak@group.calendar.google.com" +DEFAULT_CALENDAR_URL = ( + 'https://www.google.com/calendar/embed?mode=Month&src={}&showCalendars=0'.format(DEFAULT_CALENDAR_ID)) CALENDAR_TEMPLATE = "/templates/html/google_calendar.html" CALENDAR_EDIT_TEMPLATE = "/templates/html/google_calendar_edit.html" @@ -33,7 +34,6 @@ class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-man scope=Scope.settings, default="Google Calendar" ) - calendar_id = String( display_name="Public Calendar ID", help=( @@ -43,14 +43,12 @@ class GoogleCalendarBlock(XBlock, PublishEventMixin): # pylint: disable=too-man scope=Scope.settings, default=DEFAULT_CALENDAR_ID ) - default_view = Integer( display_name="Default View", help="The calendar view that students see by default. A student can change this view.", scope=Scope.settings, default=1 ) - views = [(0, 'Week'), (1, 'Month'), (2, 'Agenda')] # Context argument is specified for xblocks, but we are not using herein diff --git a/google_drive/google_docs.py b/google_drive/google_docs.py index 5c2a38c..92d03c9 100644 --- a/google_drive/google_docs.py +++ b/google_drive/google_docs.py @@ -1,6 +1,4 @@ -""" -Google Document XBlock implementation -""" +""" Google Document XBlock implementation """ # -*- coding: utf-8 -*- # @@ -20,17 +18,21 @@ RESOURCE_LOADER = ResourceLoader(__name__) # Constants ########################################################### +DEFAULT_DOCUMENT_URL = ( + 'https://docs.google.com/presentation/d/1x2ZuzqHsMoh1epK8VsGAlanSo7r9z55ualwQlj-ofBQ/embed?' + 'start=true&loop=true&delayms=10000' +) DEFAULT_EMBED_CODE = textwrap.dedent(""" - - """) + +""") .format(DEFAULT_DOCUMENT_URL) DOCUMENT_TEMPLATE = "/templates/html/google_docs.html" DOCUMENT_EDIT_TEMPLATE = "/templates/html/google_docs_edit.html" @@ -46,7 +48,6 @@ class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-man scope=Scope.settings, default="Google Document" ) - embed_code = String( display_name="Embed Code", help=( @@ -57,13 +58,9 @@ class GoogleDocumentBlock(XBlock, PublishEventMixin): # pylint: disable=too-man scope=Scope.settings, default=DEFAULT_EMBED_CODE ) - alt_text = String( display_name="Alternative Text", - help=( - "In situations where image is not available to the reader, the alternative " - "text ensures that no information or functionality is lost." - ), + help="Alternative text describes an image and appears if the image is unavailable.", scope=Scope.settings, default="" ) diff --git a/google_drive/templates/html/google_docs_edit.html b/google_drive/templates/html/google_docs_edit.html index d728463..aa1247d 100644 --- a/google_drive/templates/html/google_docs_edit.html +++ b/google_drive/templates/html/google_docs_edit.html @@ -35,7 +35,7 @@

{% trans "Invalid Google Document" %}

- {% trans "In situations where image is not available to the reader, the alternative text ensures that no information or functionality is lost." %} + {% trans "Alternative text describes an image and appears if the image is unavailable." %} diff --git a/google_drive/tests/integration/base_test.py b/google_drive/tests/integration/base_test.py index 3f7ac45..aef313f 100644 --- a/google_drive/tests/integration/base_test.py +++ b/google_drive/tests/integration/base_test.py @@ -1,7 +1,12 @@ """ Base classes for integration tests """ +# -*- coding: utf-8 -*- +# + +# Imports ########################################################### from xblockutils.base_test import SeleniumBaseTest +# Classes ########################################################### class GoogleCalendarBaseTest(SeleniumBaseTest): # pylint: disable=too-many-ancestors, too-few-public-methods """ Base class for Google Calendar integration tests """ module_name = __name__ diff --git a/google_drive/tests/integration/studio_scenarios.py b/google_drive/tests/integration/studio_scenarios.py index 5baa121..59dd9b4 100644 --- a/google_drive/tests/integration/studio_scenarios.py +++ b/google_drive/tests/integration/studio_scenarios.py @@ -1,6 +1,10 @@ """ Contains a list of lists that will be used as the DDT arguments for the studio test. """ +# -*- coding: utf-8 -*- +# + +# Constants ########################################################### CALENDAR_SCENARIOS = [ [ 'Calendar', diff --git a/google_drive/tests/integration/test_publish.py b/google_drive/tests/integration/test_publish.py index e2128b8..5bbd014 100644 --- a/google_drive/tests/integration/test_publish.py +++ b/google_drive/tests/integration/test_publish.py @@ -1,7 +1,12 @@ """ Runs tests for publish event functionality """ +# -*- coding: utf-8 -*- +# + +# Imports ########################################################### from .base_test import GoogleCalendarBaseTest, GoogleDocumentBaseTest +# Classes ########################################################### class GoogleCalendarPublishTestCase(GoogleCalendarBaseTest): # pylint: disable=too-few-public-methods, too-many-ancestors """ Tests for Google Calendar event publishing functionality. diff --git a/google_drive/tests/integration/test_studio.py b/google_drive/tests/integration/test_studio.py index dc904c8..fe54187 100644 --- a/google_drive/tests/integration/test_studio.py +++ b/google_drive/tests/integration/test_studio.py @@ -1,24 +1,17 @@ """ Runs tests for the studio views """ +# -*- coding: utf-8 -*- +# +# Imports ########################################################### from ddt import ddt, unpack, data from .base_test import GoogleCalendarBaseTest, GoogleDocumentBaseTest from .studio_scenarios import CALENDAR_SCENARIOS, DOCUMENT_SCENARIOS, IMAGE_SCENARIOS - -DEFAULT_CALENDAR_SRC = ( - 'https://www.google.com/calendar/embed?' - 'mode=Month&' - 'src=edx.org_lom804qe3ttspplj1bgeu1l3ak@group.calendar.google.com&' - 'showCalendars=0' -) - -DEFAULT_DOCUMENT_SRC = ( - 'https://docs.google.com/presentation/d/1x2ZuzqHsMoh1epK8VsGAlanSo7r9z55ualwQlj-ofBQ/embed?' - 'start=true&loop=true&delayms=10000' -) - -TEST_IMAGE_SRC = 'https://docs.google.com/drawings/d/1lmmxboBM5c_0WCTjhAxBdkpqQb3T8VSwtuG0TRR1ODQ/pub?w=960&h=720' +from google_drive.google_calendar import DEFAULT_CALENDAR_URL +from google_drive.google_docs import DEFAULT_DOCUMENT_URL +from google_drive.tests.test_const import TEST_IMAGE_URL +# Classes ########################################################### @ddt # pylint: disable=too-many-ancestors class GoogleCalendarStudioTest(GoogleCalendarBaseTest): """ @@ -65,7 +58,7 @@ def test_save_calendar(self, page_name): self.go_to_page(page_name, css_selector='div.google-calendar-xblock-wrapper') calendar_iframe = self.browser.find_element_by_css_selector('iframe') # Expecting that default calendar is the one loaded in the IFrame - self.assertEqual(calendar_iframe.get_attribute("src"), DEFAULT_CALENDAR_SRC) + self.assertEqual(calendar_iframe.get_attribute("src"), DEFAULT_CALENDAR_URL) # Expecting that the new display name is the title of the IFrame self.assertEqual(calendar_iframe.get_attribute("title"), 'My Meetings') @@ -102,7 +95,7 @@ def test_save_document(self, page_name): self.go_to_page(page_name, css_selector='div.google-docs-xblock-wrapper') document_iframe = self.browser.find_element_by_css_selector('iframe') # Expecting that default calendar is the one loaded in the IFrame - self.assertEqual(document_iframe.get_attribute("src"), DEFAULT_DOCUMENT_SRC) + self.assertEqual(document_iframe.get_attribute("src"), DEFAULT_DOCUMENT_URL) # Expecting that the new display name is the title of the IFrame self.assertEqual(document_iframe.get_attribute("title"), 'My Document') @@ -130,6 +123,6 @@ def test_save_image(self, page_name): self.go_to_page(page_name, css_selector='div.google-docs-xblock-wrapper') image_iframe = self.browser.find_element_by_css_selector('img') # Expecting that default calendar is the one loaded in the IFrame - self.assertEqual(image_iframe.get_attribute("src"), TEST_IMAGE_SRC) + self.assertEqual(image_iframe.get_attribute("src"), TEST_IMAGE_URL) # Expecting that the new display name is the title of the IFrame self.assertEqual(image_iframe.get_attribute("alt"), 'Alternative text for my image') diff --git a/google_drive/tests/test_const.py b/google_drive/tests/test_const.py new file mode 100644 index 0000000..60ddcde --- /dev/null +++ b/google_drive/tests/test_const.py @@ -0,0 +1,18 @@ +""" Constants used within tests """ +# -*- coding: utf-8 -*- +# +# Constants ########################################################### +STUDIO_EDIT_WRAPPER = '
' +USER_INPUTS_WRAPPER = '
' +BUTTONS_WRAPPER = '
' + +RESULT_SUCCESS = {'result': 'success'} +RESULT_ERROR = {'result': 'error'} +RESULT_MISSING_EVENT_TYPE = {'result': 'error', 'message': 'Missing event_type in JSON data'} + +STATUS_CODE_200 = {'status_code': 200} +STATUS_CODE_400 = {'status_code': 400} +STATUS_CODE_404 = {'status_code': 404} + +TEST_IMAGE_URL = 'https://docs.google.com/drawings/d/1lmmxboBM5c_0WCTjhAxBdkpqQb3T8VSwtuG0TRR1ODQ/pub?w=960&h=720' diff --git a/google_drive/tests/unit/test_calendar.py b/google_drive/tests/unit/test_calendar.py index a67a8c8..cd13672 100644 --- a/google_drive/tests/unit/test_calendar.py +++ b/google_drive/tests/unit/test_calendar.py @@ -1,6 +1,11 @@ -""" Unit tests for google document components """ +""" Unit tests for google calendar components """ +# -*- coding: utf-8 -*- +# + +# Imports ########################################################### import json import unittest +import cgi from mock import Mock from nose.tools import assert_equals, assert_in @@ -8,9 +13,35 @@ from xblock.runtime import KvsFieldData, DictKeyValueStore from google_drive import GoogleCalendarBlock +from google_drive.google_calendar import DEFAULT_CALENDAR_URL from google_drive.tests.unit.test_utils import generate_scope_ids, make_request - - +from google_drive.tests.test_const import STUDIO_EDIT_WRAPPER, VALIDATION_WRAPPER, USER_INPUTS_WRAPPER, BUTTONS_WRAPPER +from google_drive.tests.test_const import RESULT_SUCCESS, RESULT_ERROR, RESULT_MISSING_EVENT_TYPE + +# Constants ########################################################### +TEST_SUBMIT_DATA = { + 'display_name': "Google Calendar", + 'calendar_id': "google1234", + 'default_view': 1 +} +TEST_COMPLETE_PUBLISH_DATA = { + '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' +} +TEST_INCOMPLETE_PUBLISH_DATA = { + 'url': ( + 'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak' + '@group.calendar.google.com&showCalendars=0' + ), + 'displayed_in': 'iframe' +} + + +# Classes ########################################################### class TestGoogleCalendarBlock(unittest.TestCase): """ Tests for GoogleCalendarBlock """ @@ -31,72 +62,43 @@ def test_calendar_template_content(self): # pylint: disable=no-self-use student_fragment = block.render('student_view', Mock()) # pylint: disable=no-value-for-parameter assert_in('
', student_fragment.content) - assert_in( - ( - 'https://www.google.com/calendar/embed?mode=Month&src=edx.org_lom804qe3ttspplj1bgeu1l3ak' - '@group.calendar.google.com&showCalendars=0' - ), - student_fragment.content - ) + assert_in(cgi.escape(DEFAULT_CALENDAR_URL), student_fragment.content) assert_in('Google Calendar', student_fragment.content) studio_fragment = block.render('studio_view', Mock()) - assert_in( - ( - '
' - ), - studio_fragment.content - ) - assert_in('
', studio_fragment.content) - assert_in('
', studio_fragment.content) - assert_in('
', studio_fragment.content) + assert_in(STUDIO_EDIT_WRAPPER, studio_fragment.content) + assert_in(VALIDATION_WRAPPER, studio_fragment.content) + assert_in(USER_INPUTS_WRAPPER, studio_fragment.content) + assert_in(BUTTONS_WRAPPER, 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 - }) + body = json.dumps(TEST_SUBMIT_DATA) res = block.handle('studio_submit', make_request(body)) # pylint: disable=no-value-for-parameter - assert_equals(json.loads(res.body), {'result': 'success'}) + 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) + assert_equals(block.display_name, TEST_SUBMIT_DATA['display_name']) + assert_equals(block.calendar_id, TEST_SUBMIT_DATA['calendar_id']) + assert_equals(block.default_view, TEST_SUBMIT_DATA['default_view']) body = json.dumps('') res = block.handle('studio_submit', make_request(body)) # pylint: disable=no-value-for-parameter - assert_equals(json.loads(res.body), {'result': 'error'}) + assert_equals(json.loads(res.body), RESULT_ERROR) 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' - }) + body = json.dumps(TEST_COMPLETE_PUBLISH_DATA) 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', - }) + assert_equals(json.loads(res.body), RESULT_SUCCESS) + + body = json.dumps(TEST_INCOMPLETE_PUBLISH_DATA) res = block.handle('publish_event', make_request(body)) - assert_equals(json.loads(res.body), {'result': 'error', 'message': 'Missing event_type in JSON data'}) + assert_equals(json.loads(res.body), RESULT_MISSING_EVENT_TYPE) diff --git a/google_drive/tests/unit/test_docs.py b/google_drive/tests/unit/test_docs.py index 9cce78a..9a824ae 100644 --- a/google_drive/tests/unit/test_docs.py +++ b/google_drive/tests/unit/test_docs.py @@ -1,4 +1,8 @@ """ Unit tests for google document components """ +# -*- coding: utf-8 -*- +# + +# Imports ########################################################### import json import unittest from mock import Mock @@ -8,9 +12,48 @@ from xblock.runtime import KvsFieldData, DictKeyValueStore from google_drive import GoogleDocumentBlock +from google_drive.google_docs import DEFAULT_EMBED_CODE, DEFAULT_DOCUMENT_URL from google_drive.tests.unit.test_utils import generate_scope_ids, make_request - - +from google_drive.tests.test_const import STUDIO_EDIT_WRAPPER, VALIDATION_WRAPPER, USER_INPUTS_WRAPPER, BUTTONS_WRAPPER +from google_drive.tests.test_const import RESULT_SUCCESS, RESULT_ERROR, RESULT_MISSING_EVENT_TYPE +from google_drive.tests.test_const import STATUS_CODE_200, STATUS_CODE_400, STATUS_CODE_404 +from google_drive.tests.test_const import TEST_IMAGE_URL + +# Constants ########################################################### +TEST_SUBMIT_DATA = { + 'display_name': "Google Document", + 'embed_code': "