diff --git a/cms/djangoapps/contentstore/views/assets.py b/cms/djangoapps/contentstore/views/assets.py index b1da60bbbc..fd77774dae 100644 --- a/cms/djangoapps/contentstore/views/assets.py +++ b/cms/djangoapps/contentstore/views/assets.py @@ -121,8 +121,7 @@ def _assets_json(request, course_key): asset_json = [] for asset in assets: - asset_id = asset.get('content_son', asset['_id']) - asset_location = StaticContent.compute_location(course_key, asset_id['name']) + asset_location = asset['asset_key'] # note, due to the schema change we may not have a 'thumbnail_location' in the result set thumbnail_location = asset.get('thumbnail_location', None) if thumbnail_location: diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 84bc8b768f..b8dc24cf68 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -125,11 +125,6 @@ class CapaDescriptor(CapaFields, RawDescriptor): ] } - # Capa modules have some additional metadata: - # TODO (vshnayder): do problems have any other metadata? Do they - # actually use type and points? - metadata_attributes = RawDescriptor.metadata_attributes + ('type', 'points') - # The capa format specifies that what we call max_attempts in the code # is the attribute `attempts`. This will do that conversion metadata_translations = dict(RawDescriptor.metadata_translations) diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py index ee48c8cbe7..11eece3e1d 100644 --- a/common/lib/xmodule/xmodule/combined_open_ended_module.py +++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py @@ -497,8 +497,6 @@ class CombinedOpenEndedDescriptor(CombinedOpenEndedFields, RawDescriptor): #Specify whether or not to pass in open ended interface needs_open_ended_interface = True - metadata_attributes = RawDescriptor.metadata_attributes - js = {'coffee': [resource_string(__name__, 'js/src/combinedopenended/edit.coffee')]} js_module_name = "OpenEndedMarkdownEditingDescriptor" css = {'scss': [resource_string(__name__, 'css/editor/edit.scss'), resource_string(__name__, 'css/combinedopenended/edit.scss')]} diff --git a/common/lib/xmodule/xmodule/contentstore/content.py b/common/lib/xmodule/xmodule/contentstore/content.py index 3bb0a5e5d5..a6c092d900 100644 --- a/common/lib/xmodule/xmodule/contentstore/content.py +++ b/common/lib/xmodule/xmodule/contentstore/content.py @@ -188,23 +188,13 @@ class ContentStore(object): Returns a list of static assets for a course, followed by the total number of assets. By default all assets are returned, but start and maxresults can be provided to limit the query. - The return format is a list of dictionary elements. Example: - - [ - - {u'displayname': u'profile.jpg', u'chunkSize': 262144, u'length': 85374, - u'uploadDate': datetime.datetime(2012, 10, 3, 5, 41, 54, 183000), u'contentType': u'image/jpeg', - u'_id': {u'category': u'asset', u'name': u'profile.jpg', u'course': u'6.002x', u'tag': u'c4x', - u'org': u'MITx', u'revision': None}, u'md5': u'36dc53519d4b735eb6beba51cd686a0e'}, - - {u'displayname': u'profile.thumbnail.jpg', u'chunkSize': 262144, u'length': 4073, - u'uploadDate': datetime.datetime(2012, 10, 3, 5, 41, 54, 196000), u'contentType': u'image/jpeg', - u'_id': {u'category': u'asset', u'name': u'profile.thumbnail.jpg', u'course': u'6.002x', u'tag': u'c4x', - u'org': u'MITx', u'revision': None}, u'md5': u'ff1532598830e3feac91c2449eaa60d6'}, - - .... - - ] + The return format is a list of asset data dictionaries. + The asset data dictionaries have the following keys: + asset_key (:class:`opaque_keys.edx.AssetKey`): The key of the asset + displayname: The human-readable name of the asset + uploadDate (datetime.datetime): The date and time that the file was uploadDate + contentType: The mimetype string of the asset + md5: An md5 hash of the asset content ''' raise NotImplementedError diff --git a/common/lib/xmodule/xmodule/contentstore/mongo.py b/common/lib/xmodule/xmodule/contentstore/mongo.py index 7ae258c421..c3e7571efa 100644 --- a/common/lib/xmodule/xmodule/contentstore/mongo.py +++ b/common/lib/xmodule/xmodule/contentstore/mongo.py @@ -146,9 +146,6 @@ class MongoContentStore(ContentStore): assets, __ = self.get_all_content_for_course(course_key) for asset in assets: - asset_id = asset.get('content_son', asset['_id']) - # assuming course_key's deprecated flag is controlling rather than presence or absence of 'run' in _id - asset_location = course_key.make_asset_key(asset_id['category'], asset_id['name']) # TODO: On 6/19/14, I had to put a try/except around this # to export a course. The course failed on JSON files in # the /static/ directory placed in it with an import. @@ -157,10 +154,10 @@ class MongoContentStore(ContentStore): # # When debugging course exports, this might be a good place # to look. -- pmitros - self.export(asset_location, output_directory) + self.export(asset['asset_key'], output_directory) for attr, value in asset.iteritems(): - if attr not in ['_id', 'md5', 'uploadDate', 'length', 'chunkSize']: - policy.setdefault(asset_location.name, {})[attr] = value + if attr not in ['_id', 'md5', 'uploadDate', 'length', 'chunkSize', 'asset_key']: + policy.setdefault(asset['asset_key'].name, {})[attr] = value with open(assets_policy_file, 'w') as f: json.dump(policy, f) @@ -175,23 +172,14 @@ class MongoContentStore(ContentStore): def _get_all_content_for_course(self, course_key, get_thumbnails=False, start=0, maxresults=-1, sort=None): ''' - Returns a list of all static assets for a course. The return format is a list of dictionary elements. Example: + Returns a list of all static assets for a course. The return format is a list of asset data dictionary elements. - [ - - {u'displayname': u'profile.jpg', u'chunkSize': 262144, u'length': 85374, - u'uploadDate': datetime.datetime(2012, 10, 3, 5, 41, 54, 183000), u'contentType': u'image/jpeg', - u'_id': {u'category': u'asset', u'name': u'profile.jpg', u'course': u'6.002x', u'tag': u'c4x', - u'org': u'MITx', u'revision': None}, u'md5': u'36dc53519d4b735eb6beba51cd686a0e'}, - - {u'displayname': u'profile.thumbnail.jpg', u'chunkSize': 262144, u'length': 4073, - u'uploadDate': datetime.datetime(2012, 10, 3, 5, 41, 54, 196000), u'contentType': u'image/jpeg', - u'_id': {u'category': u'asset', u'name': u'profile.thumbnail.jpg', u'course': u'6.002x', u'tag': u'c4x', - u'org': u'MITx', u'revision': None}, u'md5': u'ff1532598830e3feac91c2449eaa60d6'}, - - .... - - ] + The asset data dictionaries have the following keys: + asset_key (:class:`opaque_keys.edx.AssetKey`): The key of the asset + displayname: The human-readable name of the asset + uploadDate (datetime.datetime): The date and time that the file was uploadDate + contentType: The mimetype string of the asset + md5: An md5 hash of the asset content ''' if maxresults > 0: items = self.fs_files.find( @@ -203,7 +191,14 @@ class MongoContentStore(ContentStore): query_for_course(course_key, "asset" if not get_thumbnails else "thumbnail"), sort=sort ) count = items.count() - return list(items), count + assets = list(items) + + # We're constructing the asset key immediately after retrieval from the database so that + # callers are insulated from knowing how our identifiers are stored. + for asset in assets: + asset_id = asset.get('content_son', asset['_id']) + asset['asset_key'] = course_key.make_asset_key(asset_id['category'], asset_id['name']) + return assets, count def set_attr(self, asset_key, attr, value=True): """ diff --git a/common/lib/xmodule/xmodule/modulestore/django.py b/common/lib/xmodule/xmodule/modulestore/django.py index cd69fb1c7a..58e1a7acf4 100644 --- a/common/lib/xmodule/xmodule/modulestore/django.py +++ b/common/lib/xmodule/xmodule/modulestore/django.py @@ -70,6 +70,7 @@ def create_modulestore_instance(engine, content_store, doc_store_config, options doc_store_config=doc_store_config, i18n_service=i18n_service or ModuleI18nService(), branch_setting_func=_get_modulestore_branch_setting, + create_modulestore_instance=create_modulestore_instance, **_options ) diff --git a/common/lib/xmodule/xmodule/modulestore/mixed.py b/common/lib/xmodule/xmodule/modulestore/mixed.py index 4811163429..34a19dd2c0 100644 --- a/common/lib/xmodule/xmodule/modulestore/mixed.py +++ b/common/lib/xmodule/xmodule/modulestore/mixed.py @@ -12,7 +12,6 @@ from opaque_keys import InvalidKeyError from . import ModuleStoreWriteBase from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.django import create_modulestore_instance from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator from xmodule.modulestore.exceptions import ItemNotFoundError from opaque_keys.edx.keys import CourseKey, UsageKey @@ -30,13 +29,16 @@ class MixedModuleStore(ModuleStoreWriteBase): """ ModuleStore knows how to route requests to the right persistence ms """ - def __init__(self, contentstore, mappings, stores, i18n_service=None, **kwargs): + def __init__(self, contentstore, mappings, stores, i18n_service=None, create_modulestore_instance=None, **kwargs): """ Initialize a MixedModuleStore. Here we look into our passed in kwargs which should be a collection of other modulestore configuration information """ super(MixedModuleStore, self).__init__(contentstore, **kwargs) + if create_modulestore_instance is None: + raise ValueError('MixedModuleStore constructor must be passed a create_modulestore_instance function') + self.modulestores = [] self.mappings = {} diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index 01c67a3821..52865e1993 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -54,6 +54,9 @@ SORT_REVISION_FAVOR_DRAFT = ('_id.revision', pymongo.DESCENDING) # sort order that returns PUBLISHED items first SORT_REVISION_FAVOR_PUBLISHED = ('_id.revision', pymongo.ASCENDING) +BLOCK_TYPES_WITH_CHILDREN = list(set( + name for name, class_ in XBlock.load_classes() if getattr(class_, 'has_children', False) +)) class MongoRevisionKey(object): """ @@ -460,14 +463,11 @@ class MongoModuleStore(ModuleStoreWriteBase): # note this is a bit ugly as when we add new categories of containers, we have to add it here course_id = self.fill_in_run(course_id) - block_types_with_children = set( - name for name, class_ in XBlock.load_classes() if getattr(class_, 'has_children', False) - ) query = SON([ ('_id.tag', 'i4x'), ('_id.org', course_id.org), ('_id.course', course_id.course), - ('_id.category', {'$in': list(block_types_with_children)}) + ('_id.category', {'$in': BLOCK_TYPES_WITH_CHILDREN}) ]) # we just want the Location, children, and inheritable metadata record_filter = {'_id': 1, 'definition.children': 1} diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/draft.py b/common/lib/xmodule/xmodule/modulestore/mongo/draft.py index 9e26c211dc..98cdc9fad7 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/draft.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/draft.py @@ -50,7 +50,8 @@ class DraftModuleStore(MongoModuleStore): def __init__(self, *args, **kwargs): """ Args: - branch_setting_func: a function that returns the branch setting to use for this store's operations + branch_setting_func: a function that returns the branch setting to use for this store's operations. + This should be an attribute from ModuleStoreEnum.Branch """ super(DraftModuleStore, self).__init__(*args, **kwargs) self.branch_setting_func = kwargs.pop('branch_setting_func', lambda: ModuleStoreEnum.Branch.published_only) diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py index 82c0f83bda..015a915f48 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py @@ -374,7 +374,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): ''' Gets the course descriptor for the course identified by the locator ''' - assert(isinstance(course_id, CourseLocator)) + if not isinstance(course_id, CourseLocator): + # The supplied CourseKey is of the wrong type, so it can't possibly be stored in this modulestore. + raise ItemNotFoundError(course_id) + course_entry = self._lookup_course(course_id) root = course_entry['structure']['root'] result = self._load_items(course_entry, [root], 0, lazy=True) @@ -389,7 +392,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): Note: we return the course_id instead of a boolean here since the found course may have a different id than the given course_id when ignore_case is True. ''' - assert(isinstance(course_id, CourseLocator)) + if not isinstance(course_id, CourseLocator): + # The supplied CourseKey is of the wrong type, so it can't possibly be stored in this modulestore. + return False + course_index = self.db_connection.get_course_index(course_id, ignore_case) return CourseLocator(course_index['org'], course_index['course'], course_index['run'], course_id.branch) if course_index else None @@ -432,7 +438,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): descendants. raises InsufficientSpecificationError or ItemNotFoundError """ - assert isinstance(usage_key, BlockUsageLocator) + if not isinstance(usage_key, BlockUsageLocator): + # The supplied UsageKey is of the wrong type, so it can't possibly be stored in this modulestore. + raise ItemNotFoundError(usage_key) + course = self._lookup_course(usage_key) items = self._load_items(course, [usage_key.block_id], depth, lazy=True) if len(items) == 0: @@ -1375,7 +1384,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase): change to this item, it raises a VersionConflictError unless force is True. In the force case, it forks the course but leaves the head pointer where it is (this change will not be in the course head). """ - assert isinstance(usage_locator, BlockUsageLocator) + if not isinstance(usage_locator, BlockUsageLocator): + # The supplied UsageKey is of the wrong type, so it can't possibly be stored in this modulestore. + raise ItemNotFoundError(usage_locator) + original_structure = self._lookup_course(usage_locator.course_key)['structure'] if original_structure['root'] == usage_locator.block_id: raise ValueError("Cannot delete the root of a course") diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py new file mode 100644 index 0000000000..0ea2fae369 --- /dev/null +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py @@ -0,0 +1,319 @@ +""" +This suite of tests verifies that courses exported from one modulestore can be imported into +another modulestore and the result will be identical (ignoring changes to identifiers that are +the result of being imported into a course with a different course id). + +It does this by providing facilities for creating and cleaning up each of the modulestore types, +and then for each combination of modulestores, performing the sequence: + 1) use xml_importer to read a course from xml from disk into the first modulestore (called the source) + 2) use xml_exporter to dump the course from the source modulestore to disk + 3) use xml_importer to read the dumped course into a second modulestore (called the destination) + 4) Compare all modules in the source and destination modulestores to make sure that they line up + +""" + +import ddt +import itertools +import random +from contextlib import contextmanager, nested +from unittest import SkipTest +from shutil import rmtree +from tempfile import mkdtemp +from opaque_keys.edx.locations import SlashSeparatedCourseKey + +from xmodule.tests import CourseComparisonTest + +from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore +from xmodule.modulestore.mongo.base import ModuleStoreEnum +from xmodule.modulestore.mongo.draft import DraftModuleStore +from xmodule.modulestore.mixed import MixedModuleStore +from xmodule.contentstore.mongo import MongoContentStore +from xmodule.modulestore.xml_importer import import_from_xml +from xmodule.modulestore.xml_exporter import export_to_xml + +COMMON_DOCSTORE_CONFIG = { + 'host': 'localhost' +} + + +class MemoryCache(object): + """ + This fits the metadata_inheritance_cache_subsystem interface used by + the modulestore, and stores the data in a dictionary in memory. + """ + def __init__(self): + self._data = {} + + def get(self, key, default=None): + """ + Get a key from the cache. + + Args: + key: The key to update. + default: The value to return if the key hasn't been set previously. + """ + return self._data.get(key, default) + + def set(self, key, value): + """ + Set a key in the cache. + + Args: + key: The key to update. + value: The value change the key to. + """ + self._data[key] = value + + +class MongoModulestoreBuilder(object): + """ + A builder class for a DraftModuleStore. + """ + @contextmanager + def build(self, contentstore): + """ + A contextmanager that returns an isolated mongo modulestore, and then deletes + all of its data at the end of the context. + + Args: + contentstore: The contentstore that this modulestore should use to store + all of its assets. + """ + doc_store_config = dict( + db='modulestore{}'.format(random.randint(0, 10000)), + collection='xmodule', + **COMMON_DOCSTORE_CONFIG + ) + + # Set up a temp directory for storing filesystem content created during import + fs_root = mkdtemp() + + modulestore = DraftModuleStore( + contentstore, + doc_store_config, + fs_root, + render_template=repr, + branch_setting_func=lambda: ModuleStoreEnum.Branch.draft_preferred, + metadata_inheritance_cache_subsystem=MemoryCache(), + ) + + try: + yield modulestore + finally: + # Delete the created database + db = modulestore.database + db.connection.drop_database(db) + db.connection.close() + + # Delete the created directory on the filesystem + rmtree(fs_root) + + def __repr__(self): + return 'MongoModulestoreBuilder()' + + +class VersioningModulestoreBuilder(object): + """ + A builder class for a VersioningModuleStore. + """ + @contextmanager + def build(self, contentstore): + """ + A contextmanager that returns an isolated versioning modulestore, and then deletes + all of its data at the end of the context. + + Args: + contentstore: The contentstore that this modulestore should use to store + all of its assets. + """ + # pylint: disable=unreachable + raise SkipTest("DraftVersioningModuleStore doesn't yet support the same interface as the rest of the modulestores") + doc_store_config = dict( + db='modulestore{}'.format(random.randint(0, 10000)), + collection='split_module', + **COMMON_DOCSTORE_CONFIG + ) + # Set up a temp directory for storing filesystem content created during import + fs_root = mkdtemp() + + modulestore = SplitMongoModuleStore( + contentstore, + doc_store_config, + fs_root, + render_template=repr, + ) + + try: + yield modulestore + finally: + # Delete the created database + db = modulestore.db + db.connection.drop_database(db) + db.connection.close() + + # Delete the created directory on the filesystem + rmtree(fs_root) + + def __repr__(self): + return 'SplitModulestoreBuilder()' + + +class MixedModulestoreBuilder(object): + """ + A builder class for a MixedModuleStore. + """ + def __init__(self, store_builders, mappings=None): + """ + Args: + store_builders: A list of modulestore builder objects. These will be instantiated, in order, + as the backing stores for the MixedModuleStore. + mappings: Any course mappings to pass to the MixedModuleStore on instantiation. + """ + self.store_builders = store_builders + self.mappings = mappings or {} + + @contextmanager + def build(self, contentstore): + """ + A contextmanager that returns a mixed modulestore built on top of modulestores + generated by other builder classes. + + Args: + contentstore: The contentstore that this modulestore should use to store + all of its assets. + """ + names, generators = zip(*self.store_builders) + + with nested(*(gen.build(contentstore) for gen in generators)) as modulestores: + # Make the modulestore creation function just return the already-created modulestores + store_iterator = iter(modulestores) + create_modulestore_instance = lambda *args, **kwargs: store_iterator.next() + + # Generate a fake list of stores to give the already generated stores appropriate names + stores = [{'NAME': name, 'ENGINE': 'This space deliberately left blank'} for name in names] + + modulestore = MixedModuleStore(contentstore, self.mappings, stores, create_modulestore_instance=create_modulestore_instance) + + yield modulestore + + def __repr__(self): + return 'MixedModulestoreBuilder({!r}, {!r})'.format(self.store_builders, self.mappings) + + +class MongoContentstoreBuilder(object): + """ + A builder class for a MongoContentStore. + """ + @contextmanager + def build(self): + """ + A contextmanager that returns a MongoContentStore, and deletes its contents + when the context closes. + """ + contentstore = MongoContentStore( + db='contentstore{}'.format(random.randint(0, 10000)), + collection='content', + **COMMON_DOCSTORE_CONFIG + ) + + try: + yield contentstore + finally: + # Delete the created database + db = contentstore.fs_files.database + db.connection.drop_database(db) + db.connection.close() + + def __repr__(self): + return 'MongoContentstoreBuilder()' + + +MODULESTORE_SETUPS = ( + MongoModulestoreBuilder(), + VersioningModulestoreBuilder(), + MixedModulestoreBuilder([('draft', MongoModulestoreBuilder())]), + MixedModulestoreBuilder([('split', VersioningModulestoreBuilder())]), +) +CONTENTSTORE_SETUPS = (MongoContentstoreBuilder(),) +COURSE_DATA_NAMES = ('toy', 'manual-testing-complete') + + +@ddt.ddt +class CrossStoreXMLRoundtrip(CourseComparisonTest): + """ + This class exists to test XML import and export between different modulestore + classes. + """ + + def setUp(self): + super(CrossStoreXMLRoundtrip, self).setUp() + self.export_dir = mkdtemp() + self.addCleanup(rmtree, self.export_dir) + + @ddt.data(*itertools.product( + MODULESTORE_SETUPS, + MODULESTORE_SETUPS, + CONTENTSTORE_SETUPS, + CONTENTSTORE_SETUPS, + COURSE_DATA_NAMES, + )) + @ddt.unpack + def test_round_trip(self, source_builder, dest_builder, source_content_builder, dest_content_builder, course_data_name): + source_course_key = SlashSeparatedCourseKey('source', 'course', 'key') + dest_course_key = SlashSeparatedCourseKey('dest', 'course', 'key') + + # Construct the contentstore for storing the first import + with source_content_builder.build() as source_content: + # Construct the modulestore for storing the first import (using the previously created contentstore) + with source_builder.build(source_content) as source_store: + # Construct the contentstore for storing the second import + with dest_content_builder.build() as dest_content: + # Construct the modulestore for storing the second import (using the second contentstore) + with dest_builder.build(dest_content) as dest_store: + import_from_xml( + source_store, + 'test_user', + 'common/test/data', + course_dirs=[course_data_name], + static_content_store=source_content, + target_course_id=source_course_key, + create_new_course_if_not_present=True, + ) + + export_to_xml( + source_store, + source_content, + source_course_key, + self.export_dir, + 'exported_course', + ) + + import_from_xml( + dest_store, + 'test_user', + self.export_dir, + static_content_store=dest_content, + target_course_id=dest_course_key, + create_new_course_if_not_present=True, + ) + + self.exclude_field(source_course_key.make_usage_key('course', 'key'), 'wiki_slug') + self.exclude_field(None, 'xml_attributes') + self.ignore_asset_key('_id') + self.ignore_asset_key('uploadDate') + self.ignore_asset_key('content_son') + self.ignore_asset_key('thumbnail_location') + + self.assertCoursesEqual( + source_store, + source_course_key, + dest_store, + dest_course_key, + ) + + self.assertAssetsEqual( + source_content, + source_course_key, + dest_content, + dest_course_key, + ) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 7dc251b4e1..1c4f94d102 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -104,12 +104,6 @@ class TestMixedModuleStore(unittest.TestCase): self.addCleanup(self.connection.close) super(TestMixedModuleStore, self).setUp() - patcher = patch.multiple( - 'xmodule.modulestore.mixed', - create_modulestore_instance=create_modulestore_instance, - ) - patcher.start() - self.addCleanup(patcher.stop) self.addTypeEqualityFunc(BlockUsageLocator, '_compareIgnoreVersion') self.addTypeEqualityFunc(CourseLocator, '_compareIgnoreVersion') # define attrs which get set in initdb to quell pylint @@ -207,7 +201,7 @@ class TestMixedModuleStore(unittest.TestCase): if index > 0: store_configs[index], store_configs[0] = store_configs[0], store_configs[index] break - self.store = MixedModuleStore(None, **self.options) + self.store = MixedModuleStore(None, create_modulestore_instance=create_modulestore_instance, **self.options) self.addCleanup(self.store.close_all_connections) # convert to CourseKeys diff --git a/common/lib/xmodule/xmodule/modulestore/xml_importer.py b/common/lib/xmodule/xmodule/modulestore/xml_importer.py index 2de6a9b01a..158c9001d8 100644 --- a/common/lib/xmodule/xmodule/modulestore/xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/xml_importer.py @@ -151,7 +151,6 @@ def import_from_xml( # If we're going to remap the course_id, then we can only do that with # a single course - if target_course_id: assert(len(xml_module_store.modules) == 1) diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index d79bd4366c..824652fcf1 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -19,7 +19,7 @@ from xblock.field_data import DictFieldData from xblock.fields import ScopeIds from xmodule.x_module import ModuleSystem, XModuleDescriptor, XModuleMixin -from xmodule.modulestore.inheritance import InheritanceMixin +from xmodule.modulestore.inheritance import InheritanceMixin, own_metadata from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.mako_module import MakoDescriptorSystem from xmodule.error_module import ErrorDescriptor @@ -154,3 +154,156 @@ class LogicTest(unittest.TestCase): def ajax_request(self, dispatch, data): """Call Xmodule.handle_ajax.""" return json.loads(self.xmodule.handle_ajax(dispatch, data)) + + +class CourseComparisonTest(unittest.TestCase): + """ + Mixin that has methods for comparing courses for equality. + """ + + def setUp(self): + self.field_exclusions = set() + self.ignored_asset_keys = set() + + def exclude_field(self, usage_id, field_name): + """ + Mark field ``field_name`` of expected block usage ``usage_id`` as ignored + + Args: + usage_id (:class:`opaque_keys.edx.UsageKey` or ``None``). If ``None``, skip, this field in all blocks + field_name (string): The name of the field to skip + """ + self.field_exclusions.add((usage_id, field_name)) + + def ignore_asset_key(self, key_name): + """ + Add an asset key to the list of keys to be ignored when comparing assets. + + Args: + key_name: The name of the key to ignore. + """ + self.ignored_asset_keys.add(key_name) + + def assertCoursesEqual(self, expected_store, expected_course_key, actual_store, actual_course_key): + """ + Assert that the courses identified by ``expected_course_key`` in ``expected_store`` and + ``actual_course_key`` in ``actual_store`` are identical (ignore differences related + owing to the course_keys being different). + + Any field value mentioned in ``self.field_exclusions`` by the key (usage_id, field_name) + will be ignored for the purpose of equality checking. + """ + expected_items = expected_store.get_items(expected_course_key) + actual_items = actual_store.get_items(actual_course_key) + self.assertGreater(len(expected_items), 0) + self.assertEqual(len(expected_items), len(actual_items)) + + actual_item_map = {item.location: item for item in actual_items} + + for expected_item in expected_items: + actual_item_location = expected_item.location.map_into_course(actual_course_key) + if expected_item.location.category == 'course': + actual_item_location = actual_item_location.replace(name=actual_item_location.run) + actual_item = actual_item_map.get(actual_item_location) + + # compare published state + exp_pub_state = expected_store.compute_publish_state(expected_item) + act_pub_state = actual_store.compute_publish_state(actual_item) + self.assertEqual( + exp_pub_state, + act_pub_state, + 'Published states for usages {} and {} differ: {!r} != {!r}'.format( + expected_item.location, + actual_item.location, + exp_pub_state, + act_pub_state + ) + ) + + # compare fields + self.assertEqual(expected_item.fields, actual_item.fields) + + for field_name in expected_item.fields: + if (expected_item.scope_ids.usage_id, field_name) in self.field_exclusions: + continue + + if (None, field_name) in self.field_exclusions: + continue + + # Children are handled specially + if field_name == 'children': + continue + + exp_value = getattr(expected_item, field_name) + actual_value = getattr(actual_item, field_name) + self.assertEqual( + exp_value, + actual_value, + "Field {!r} doesn't match between usages {} and {}: {!r} != {!r}".format( + field_name, + expected_item.scope_ids.usage_id, + actual_item.scope_ids.usage_id, + exp_value, + actual_value, + ) + ) + + # compare children + self.assertEqual(expected_item.has_children, actual_item.has_children) + if expected_item.has_children: + expected_children = [] + for course1_item_child in expected_item.children: + expected_children.append( + course1_item_child.map_into_course(actual_course_key) + ) + self.assertEqual(expected_children, actual_item.children) + + def assertAssetEqual(self, expected_course_key, expected_asset, actual_course_key, actual_asset): + """ + Assert that two assets are equal, allowing for differences related to their being from different courses. + """ + for key in self.ignored_asset_keys: + if key in expected_asset: + del expected_asset[key] + if key in actual_asset: + del actual_asset[key] + + expected_key = expected_asset.pop('asset_key') + actual_key = actual_asset.pop('asset_key') + self.assertEqual(expected_key.map_into_course(actual_course_key), actual_key) + self.assertEqual(expected_key, actual_key.map_into_course(expected_course_key)) + + expected_filename = expected_asset.pop('filename') + actual_filename = actual_asset.pop('filename') + self.assertEqual(expected_key.to_deprecated_string(), expected_filename) + self.assertEqual(actual_key.to_deprecated_string(), actual_filename) + self.assertEqual(expected_asset, actual_asset) + + def _assertAssetsEqual(self, expected_course_key, expected_assets, actual_course_key, actual_assets): # pylint: disable=invalid-name + """ + Private helper method for assertAssetsEqual + """ + self.assertEqual(len(expected_assets), len(actual_assets)) + + actual_assets_map = {asset['asset_key']: asset for asset in actual_assets} + for expected_item in expected_assets: + actual_item = actual_assets_map[expected_item['asset_key'].map_into_course(actual_course_key)] + self.assertAssetEqual(expected_course_key, expected_item, actual_course_key, actual_item) + + def assertAssetsEqual(self, expected_store, expected_course_key, actual_store, actual_course_key): + """ + Assert that the course assets identified by ``expected_course_key`` in ``expected_store`` and + ``actual_course_key`` in ``actual_store`` are identical, allowing for differences related + to their being from different course keys. + """ + + expected_content, expected_count = expected_store.get_all_content_for_course(expected_course_key) + actual_content, actual_count = actual_store.get_all_content_for_course(actual_course_key) + + self.assertEqual(expected_count, actual_count) + self._assertAssetsEqual(expected_course_key, expected_content, actual_course_key, actual_content) + + expected_thumbs = expected_store.get_all_content_thumbnails_for_course(expected_course_key) + actual_thumbs = actual_store.get_all_content_thumbnails_for_course(actual_course_key) + + self._assertAssetsEqual(expected_course_key, expected_thumbs, actual_course_key, actual_thumbs) diff --git a/common/lib/xmodule/xmodule/xml_module.py b/common/lib/xmodule/xmodule/xml_module.py index 1092765821..4676b14159 100644 --- a/common/lib/xmodule/xmodule/xml_module.py +++ b/common/lib/xmodule/xmodule/xml_module.py @@ -123,17 +123,6 @@ class XmlDescriptor(XModuleDescriptor): # Note -- url_name isn't in this list because it's handled specially on # import and export. - # TODO (vshnayder): Do we need a list of metadata we actually - # understand? And if we do, is this the place? - # Related: What's the right behavior for clean_metadata? - metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize', - 'start', 'due', 'graded', 'display_name', 'url_name', 'hide_from_toc', - 'ispublic', # if True, then course is listed for all users; see - 'xqa_key', # for xqaa server access - 'giturl', # url of git server for origin of file - # VS[compat] Remove once unused. - 'name', 'slug') - metadata_to_strip = ('data_dir', 'tabs', 'grading_policy', 'published_by', 'published_date', 'discussion_blackouts', @@ -157,12 +146,12 @@ class XmlDescriptor(XModuleDescriptor): @classmethod def clean_metadata_from_xml(cls, xml_object): """ - Remove any attribute named in cls.metadata_attributes from the supplied + Remove any attribute named for a field with scope Scope.settings from the supplied xml_object """ - for attr in cls.metadata_attributes: - if xml_object.get(attr) is not None: - del xml_object.attrib[attr] + for field_name, field in cls.fields.items(): + if field.scope == Scope.settings and xml_object.get(field_name) is not None: + del xml_object.attrib[field_name] @classmethod def file_to_xml(cls, file_object): @@ -220,6 +209,9 @@ class XmlDescriptor(XModuleDescriptor): definition_xml = cls.load_file(filepath, system.resources_fs, def_id) + # Add the attributes from the pointer node + definition_xml.attrib.update(xml_object.attrib) + definition_metadata = get_metadata_from_xml(definition_xml) cls.clean_metadata_from_xml(definition_xml) definition, children = cls.definition_from_xml(definition_xml, system) diff --git a/common/test/data/manual-testing-complete/about/overview.html b/common/test/data/manual-testing-complete/about/overview.html new file mode 100644 index 0000000000..33911ae1ee --- /dev/null +++ b/common/test/data/manual-testing-complete/about/overview.html @@ -0,0 +1,47 @@ +
+

About This Course

+

Include your long course description here. The long course description should contain 150-400 words.

+ +

This is paragraph 2 of the long course description. Add more paragraphs as needed. Make sure to enclose them in paragraph tags.

+
+ +
+

Prerequisites

+

Add information about course prerequisites here.

+
+ +
+

Course Staff

+
+
+ Course Staff Image #1 +
+ +

Staff Member #1

+

Biography of instructor/staff member #1

+
+ +
+
+ Course Staff Image #2 +
+ +

Staff Member #2

+

Biography of instructor/staff member #2

+
+
+ +
+
+

Frequently Asked Questions

+
+

Do I need to buy a textbook?

+

No, a free online version of Chemistry: Principles, Patterns, and Applications, First Edition by Bruce Averill and Patricia Eldredge will be available, though you can purchase a printed version (published by FlatWorld Knowledge) if you’d like.

+
+ +
+

Question #2

+

Your answer would be displayed here.

+
+
+
diff --git a/common/test/data/manual-testing-complete/about/short_description.html b/common/test/data/manual-testing-complete/about/short_description.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/common/test/data/manual-testing-complete/annotatable/0edc5e96bacc449eaae9fe8b5be75994.xml b/common/test/data/manual-testing-complete/annotatable/0edc5e96bacc449eaae9fe8b5be75994.xml new file mode 100644 index 0000000000..2984d94bd4 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/0edc5e96bacc449eaae9fe8b5be75994.xml @@ -0,0 +1,15 @@ + + +

Enter your (optional) instructions for the exercise in HTML format.

+

Annotations are specified by an <annotation> tag which may may have the following attributes:

+ +
+

Add your HTML with annotation spans here.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

+

Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

+
diff --git a/common/test/data/manual-testing-complete/annotatable/0f9fc83830694ffc8fead4fcf7aa8d39.xml b/common/test/data/manual-testing-complete/annotatable/0f9fc83830694ffc8fead4fcf7aa8d39.xml new file mode 100644 index 0000000000..2984d94bd4 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/0f9fc83830694ffc8fead4fcf7aa8d39.xml @@ -0,0 +1,15 @@ + + +

Enter your (optional) instructions for the exercise in HTML format.

+

Annotations are specified by an <annotation> tag which may may have the following attributes:

+ +
+

Add your HTML with annotation spans here.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

+

Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

+
diff --git a/common/test/data/manual-testing-complete/annotatable/473ab1a4c5064c919ae483ecc86a8df7.xml b/common/test/data/manual-testing-complete/annotatable/473ab1a4c5064c919ae483ecc86a8df7.xml new file mode 100644 index 0000000000..ed2bd7edc7 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/473ab1a4c5064c919ae483ecc86a8df7.xml @@ -0,0 +1,5 @@ + +

This is an example annotation.

+

This page is required to post a comment These are one of the tags. Thanks

+

Check this. This is something else. Specialized problems are advanced problems such as annotations, open response assessments, and word clouds. These problems are available through the Advanced component

+
diff --git a/common/test/data/manual-testing-complete/annotatable/5b18cea952a84fb1a34db345a476175a.xml b/common/test/data/manual-testing-complete/annotatable/5b18cea952a84fb1a34db345a476175a.xml new file mode 100644 index 0000000000..40c0ca737a --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/5b18cea952a84fb1a34db345a476175a.xml @@ -0,0 +1,20 @@ + + +

Enter your (optional) instructions for the exercise in HTML format.

+

Annotations are specified by an <annotation> tag which may may have the following attributes:

+ +
+

Add your HTML with annotation spans here.

+

+ + The Stanford Hills + +

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

+

Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

+
diff --git a/common/test/data/manual-testing-complete/annotatable/90e352a0316a4dc68baaca0308f002e3.xml b/common/test/data/manual-testing-complete/annotatable/90e352a0316a4dc68baaca0308f002e3.xml new file mode 100644 index 0000000000..49fd850aa1 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/90e352a0316a4dc68baaca0308f002e3.xml @@ -0,0 +1,26 @@ + + +

+ Hour 1 has four separate (two-part) annotation questions. To complete an Annotation Exercise in this course, hover your mouse over each highlighted portion of the focus text. When the Instructor prompt appears, read the question and click "Reply to Annotation." This will take you to a two-part task: an open-ended response question, and a question that will be answered by choosing one of multiple semantic tags. +

+

Each of these exercises, one per hour, is meant to improve your understanding of the given text (in this case, Hour 1 Text C) by helping you analyze the context after you finish your slow reading of the text. But these exercises of annotation after slow reading do much more than that. They will build up your ability to understand not only the context but also [[1]] all other texts that contain similar contexts and [[2]] all the texts you will be reading in general. I can make this big promise because the texts that you are analyzing are part of a system, and the systematic thinking that went into the original texts can be decoded by analyzing the building blocks of the system. The way you analyze these building blocks is by trying to figure out how they are connected to the other building blocks in the system. That is what these annotation exercises are all about: they help you figure out the connections. And the more things you figure out, the more mental connections you can make on your own. But the exercise of making such connections through your annotations is a gradual process, and you need to be patient with yourself. You will get better and better at it, I am sure. The more connections you are able to make, the more powerful will be your reading ability. That is the beauty of analyzing something that was created by way of systematic thinking in an ancient tradition that took many centuries to develop (I estimate at least ten centuries). The tradition actually helps you think about the tradition. It will help you figure things out.

+

By now you have seen that I really like the expression figure out: it puts the emphasis on reading out of the text, not into the text. When you read into the text, you lose sight of the system that had built that text.

+

In the next exercise, I will switch metaphors in describing the system that had built the text. In the present exercise, I have been using the metaphor of building a structure with building blocks. In the next exercise I will start using the metaphor of weaving a fabric.

+

(Here is a working definition of metaphor: it is an expression of meaning where one thing is substituted for another thing. For example, when we use the metaphor “thread of thought,” the idea of a thread, as used by someone who is weaving or sewing, is substituted for the idea of a way of thinking. For another example: when Nietzsche speaks about reading with delicate fingers, the idea of a goldsmith touching gold is substituted for the idea of reading a text with the eyes.)

+

The main goal of this first exercise is to start practicing the art of slow reading. The best way to make a start, I think, is to read a story within a story. The inner story in this exercise is the story of the hero Hēraklēs, as retold by Agamemnon and as quoted by “Homer” in lines 78-138 of Iliad XIX. The outer story is the story of the Iliad itself, as retold by “Homer.”

+

So the story within a story is 60 lines long, while the story of the Iliad itself is over 15,000 lines long. Your task in this exercise is to do a close reading of the short story of 60 lines, which is embedded in the long story of the Iliad.

+

You can perform this task even if you haven’t started reading the Iliad, since I can summarize for you all 15,000+ lines of this huge epic in just three sentences here:

+

+

    +
  1. Achilles experiences a cosmic kind of anger, mēnis, after being insulted in a quarrel with Agamemnon, who is superior to Achilles socially but is inferior to him as a hero.
  2. +
    +
  3. As Achilles sits out the war, staying in his shelter, the Achaeans (= Danaans = Argives) are in danger of becoming the losers while the Trojans become the winners.
  4. +
    +
  5. The Achaeans are demoralized, and many of their leaders are wounded, including Agamemnon, who finally decides to settle his quarrel with Achilles.
  6. +
+

+

Now that you have the “big picture” of the Iliad as the outer story, you can have a very interesting experience as you do your slow reading of the inner story, contained in the 60 lines spoken by Agamemnon and telling the story of Hēraklēs.

+

Here is something to keep in mind. The research of the great literary critic I. A. Richards, who was once a professor at Harvard University (he retired in 1963 and died in 1979), shows that the relationship of any kind of an outer story to any kind of an inner story is not necessarily a “one-way street,” as it were, leading from the outer into the inner story: there can also be a “two-way street,” with the inner story communicating with the outer story as well as the other way around. Where I use the expressions “outer story” and “inner story,” Richards used the terms “tenor” and “vehicle.” I have always found those terms rather forbidding, but, as you see, they stand for things that are fairly easy to explain.

+
+

|76 Then Agamemnon, the king of men, spoke up at their meeting, |77 right there from the place where he was sitting, not even standing up in the middle of the assembly. |78 “Near and dear ones,” said he, “Danaan [= Achaean] heroes, attendants [therapontes] of Arēs! |79 It is a good thing to listen when a man stands up to speak, and it is not seemly |80 to speak in relay after him. It would be hard for someone to do that, even if he is a practiced speaker. |81 For how could any man in an assembly either hear anything when there is an uproar |82 or say anything? Even a public speaker who speaks clearly will be disconcerted by it. |83 What I will do is to make a declaration addressed to [Achilles] the son of Peleus. As for the rest of you |84 Argives [= Achaeans], you should understand and know well, each one of you, the words [mūthos] that I say for the record. |85 By now the Achaeans have been saying these words [mūthos] to me many times, |86 and they have been blaming me. But I am not responsible [aitios]. |87 No, those who are really responsible are Zeus and Fate [Moira] and the Fury [Erinys] who roams in the mist. |88 They are the ones who, at the public assembly, had put savage derangement [atē] into my thinking [phrenes] |89 on that day when I myself deprived Achilles of his honorific portion [geras]. |90 But what could I do? The god is the one who brings everything to its fulfillment [teleutân]. |91 That goddess atē, senior daughter of Zeus - she makes everyone veer off-course [aâsthai], |92 that disastrous one [oulomenē], the one who has delicate steps. She never makes contact with the ground of the threshold, |93 never even going near it, but instead she hovers over the heads of men, bringing harm to mortals. |94 In her harmfulness, she has incapacitated others as well [besides me], and I have in mind one person in particular. |95 Yes, once upon a time even Zeus veered off-course [aâsthai], who is said to be the best |96 among men and gods. Even he |97 was deceived; Hērā did it, with her devious ways of thinking, female that she is. |98 It happened on the day when the mighty Hērakleēs |99 was about to be born of Alkmene in Thebes, the city garlanded by good walls. |100 He [= Zeus], making a formal declaration [eukhesthai], spoke up at a meeting of all the gods and said: |101 “hear me, all gods and all goddesses, |102 and let me say to you what the heart [thūmos] in my chest tells me to say. |103 Today the goddess who presides over the pains of childbirth, Eileithuia, will help bring forth a man into the light, |104 revealing him, and he will be king over all the people who live around him. |105 He comes from an ancestral line of men who are descended from blood that comes from me.” |106 Thinking devious thoughts, the goddess Hērā addressed him [= Zeus]: |107 “You will be mistaken, and you will not be able to make a fulfillment [telos] of the words [mūthos] that you have spoken for the record. |108 But come, Olympian god, swear for me a binding oath: |109 swear that he will really be king over all the people who live around him, |110 I mean, the one who on this day shall fall to the ground between the legs of a woman |111 who is descended from men who come from your line of ancestry, from blood that comes from you.” |112 So she spoke. And Zeus did not at all notice [noeîn] her devious thinking, |113 but he swore a great oath. And right then and there, he veered off-course [aâsthai] in a big way. |114 Meanwhile, Hērā sped off, leaving the ridges of Olympus behind, |115 and swiftly she reached Achaean Argos. She knew that she would find there |116 the strong wife of Sthenelos son of Perseus. |117 She was pregnant with a dear son, and she was in her eighth month. |118 And she brought him forth into the light, even though he was still one month short. |119 Meanwhile she put a pause on the time of delivery for Alkmene, holding back the divine powers of labor, the Eileithuiai. |120 And then she herself went to tell the news to Zeus the son of Kronos, saying: |121 “Zeus the father, you with the gleaming thunderbolt, I will put a word into your thoughts: |122 there has just been born a man, a noble one, who will be king over the Argives. |123 He is Eurystheus son of Sthenelos son of Perseus. |124 He is from your line of ancestry, and it is not unseemly for him to be king over the Argives.” |125 So she spoke, and he was struck in his mind [phrēn] with a sharp sorrow [akhos]. |126 And right away she grabbed the goddess atē by the head - that head covered with luxuriant curls - |127 since he was angry in his thinking [phrenes], and he swore a binding oath |128 that never will she come to Olympus and to the starry sky |129 never again will she come back, that goddess atē, who makes everyone veer off-course [aâsthai]. |130 And so saying he threw her down from the starry sky, |131 having whirled her around in his hand. And then she [= atē] came to the fields where mortals live and work. |132 He [= Zeus] always mourned the fact that she ever existed, every time he saw how his own dear son |133 was having one of his degrading Labors [āthloi] to work on. |134 So also I [= Agamemnon], while the great Hector, the one with the gleaming helmet, |135 was destroying the Argives [= Achaeans] at the sterns of the beached ships, |136 was not able to keep out of my mind the veering [atē] I experienced once I veered off-course [aâsthai]. |137 But since I did veer off-course [aâsthai] and since Zeus took away from me my thinking, |138 I now want to make amends, and to give untold amounts of compensation.

Iliad XIX 76-138

+
diff --git a/common/test/data/manual-testing-complete/annotatable/c0a3b20598dc4ebba704a51a309251db.xml b/common/test/data/manual-testing-complete/annotatable/c0a3b20598dc4ebba704a51a309251db.xml new file mode 100644 index 0000000000..2984d94bd4 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/c0a3b20598dc4ebba704a51a309251db.xml @@ -0,0 +1,15 @@ + + +

Enter your (optional) instructions for the exercise in HTML format.

+

Annotations are specified by an <annotation> tag which may may have the following attributes:

+ +
+

Add your HTML with annotation spans here.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

+

Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

+
diff --git a/common/test/data/manual-testing-complete/annotatable/e13a327cc54f4e56bda64c5e9627edd1.xml b/common/test/data/manual-testing-complete/annotatable/e13a327cc54f4e56bda64c5e9627edd1.xml new file mode 100644 index 0000000000..2984d94bd4 --- /dev/null +++ b/common/test/data/manual-testing-complete/annotatable/e13a327cc54f4e56bda64c5e9627edd1.xml @@ -0,0 +1,15 @@ + + +

Enter your (optional) instructions for the exercise in HTML format.

+

Annotations are specified by an <annotation> tag which may may have the following attributes:

+ +
+

Add your HTML with annotation spans here.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut sodales laoreet est, egestas gravida felis egestas nec. Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.

+

Nulla facilisi. Pellentesque id vestibulum libero. Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.

+
diff --git a/common/test/data/manual-testing-complete/chapter/2df1fe87253549199f30cabb19e14b7c.xml b/common/test/data/manual-testing-complete/chapter/2df1fe87253549199f30cabb19e14b7c.xml new file mode 100644 index 0000000000..72595ba4fa --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/2df1fe87253549199f30cabb19e14b7c.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/3d216a50442f4cd5a1d4171c68f13f58.xml b/common/test/data/manual-testing-complete/chapter/3d216a50442f4cd5a1d4171c68f13f58.xml new file mode 100644 index 0000000000..985cb080a3 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/3d216a50442f4cd5a1d4171c68f13f58.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/5bb7a5ab824f460580a756a4f347377c.xml b/common/test/data/manual-testing-complete/chapter/5bb7a5ab824f460580a756a4f347377c.xml new file mode 100644 index 0000000000..6732315eb5 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/5bb7a5ab824f460580a756a4f347377c.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/60989ac1589241ed9dbca0f2070276fd.xml b/common/test/data/manual-testing-complete/chapter/60989ac1589241ed9dbca0f2070276fd.xml new file mode 100644 index 0000000000..28fc110a11 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/60989ac1589241ed9dbca0f2070276fd.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/common/test/data/manual-testing-complete/chapter/a0178ff300514e24829e239604dce12c.xml b/common/test/data/manual-testing-complete/chapter/a0178ff300514e24829e239604dce12c.xml new file mode 100644 index 0000000000..a985c184de --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/a0178ff300514e24829e239604dce12c.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/a64a6f63f75d430aa71e6ce113c5b4d2.xml b/common/test/data/manual-testing-complete/chapter/a64a6f63f75d430aa71e6ce113c5b4d2.xml new file mode 100644 index 0000000000..603bb7c275 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/a64a6f63f75d430aa71e6ce113c5b4d2.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/common/test/data/manual-testing-complete/chapter/ab97a6dbfafd48868c36bed4c8c5391d.xml b/common/test/data/manual-testing-complete/chapter/ab97a6dbfafd48868c36bed4c8c5391d.xml new file mode 100644 index 0000000000..5d4591374c --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/ab97a6dbfafd48868c36bed4c8c5391d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/be8a64868f2f460ea490e001a25e588d.xml b/common/test/data/manual-testing-complete/chapter/be8a64868f2f460ea490e001a25e588d.xml new file mode 100644 index 0000000000..b9ba8bda9a --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/be8a64868f2f460ea490e001a25e588d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/ce2fd991d84b4a5ca75350eb8e350627.xml b/common/test/data/manual-testing-complete/chapter/ce2fd991d84b4a5ca75350eb8e350627.xml new file mode 100644 index 0000000000..932cb607d8 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/ce2fd991d84b4a5ca75350eb8e350627.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/chapter/d68c2861c10a4c9d92a679b4cfc0f924.xml b/common/test/data/manual-testing-complete/chapter/d68c2861c10a4c9d92a679b4cfc0f924.xml new file mode 100644 index 0000000000..a68da5ff12 --- /dev/null +++ b/common/test/data/manual-testing-complete/chapter/d68c2861c10a4c9d92a679b4cfc0f924.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/common/test/data/manual-testing-complete/combinedopenended/3b04d935c8d945c3900708279fb24892.xml b/common/test/data/manual-testing-complete/combinedopenended/3b04d935c8d945c3900708279fb24892.xml new file mode 100644 index 0000000000..4d0d3ceb22 --- /dev/null +++ b/common/test/data/manual-testing-complete/combinedopenended/3b04d935c8d945c3900708279fb24892.xml @@ -0,0 +1,93 @@ + + +

Censorship in the Libraries

+

'All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.' --Katherine Paterson, Author +

+

+ Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading. +

+
+ + + + +Ideas + + + + + + + + +Content + + + + + + + + +Organization + + + + + + + +Style + + + + + + + +Voice + + + + + + + + + + +
diff --git a/common/test/data/manual-testing-complete/combinedopenended/b3aa2db471a9412fbc96302f2e5ea983.xml b/common/test/data/manual-testing-complete/combinedopenended/b3aa2db471a9412fbc96302f2e5ea983.xml new file mode 100644 index 0000000000..3586beaa2e --- /dev/null +++ b/common/test/data/manual-testing-complete/combinedopenended/b3aa2db471a9412fbc96302f2e5ea983.xml @@ -0,0 +1,99 @@ + + +

Censorship in the Libraries

+

'All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.' --Katherine Paterson, Author +

+

+ Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading. +

+
+ + + + +Ideas + + + + + + + + +Content + + + + + + + + +Organization + + + + + + + +Style + + + + + + + +Voice + + + + + + + + + + + Enter essay here. + This is the answer. + {"grader_settings" : "peer_grading.conf", "problem_id" : "6.002x/Welcome/OETest"} + + + +
diff --git a/common/test/data/manual-testing-complete/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml b/common/test/data/manual-testing-complete/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml new file mode 100644 index 0000000000..b135c09760 --- /dev/null +++ b/common/test/data/manual-testing-complete/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml @@ -0,0 +1,93 @@ + + +

Censorship in the Libraries

+

'All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.' --Katherine Paterson, Author +

+

+ Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading. +

+
+ + + + +Ideas + + + + + + + + +Content + + + + + + + + +Organization + + + + + + + +Style + + + + + + + +Voice + + + + + + + + + + +
diff --git a/common/test/data/manual-testing-complete/course.xml b/common/test/data/manual-testing-complete/course.xml new file mode 100644 index 0000000000..5c50015291 --- /dev/null +++ b/common/test/data/manual-testing-complete/course.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/course/2014.xml b/common/test/data/manual-testing-complete/course/2014.xml new file mode 100644 index 0000000000..8c88a504cb --- /dev/null +++ b/common/test/data/manual-testing-complete/course/2014.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/common/test/data/manual-testing-complete/drafts/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml b/common/test/data/manual-testing-complete/drafts/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml new file mode 100644 index 0000000000..4d0d3ceb22 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/combinedopenended/ecfe4fa774ff48d089ae84daa1f6cc75.xml @@ -0,0 +1,93 @@ + + +

Censorship in the Libraries

+

'All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.' --Katherine Paterson, Author +

+

+ Write a persuasive essay to a newspaper reflecting your views on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading. +

+
+ + + + +Ideas + + + + + + + + +Content + + + + + + + + +Organization + + + + + + + +Style + + + + + + + +Voice + + + + + + + + + + +
diff --git a/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.html b/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.html new file mode 100644 index 0000000000..83a8ca8360 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.html @@ -0,0 +1 @@ +

What is edX?
An organization established by MIT and Harvard University that will develop an open-source technology platform to deliver online courses. EdX will support Harvard and MIT faculty in conducting research on teaching and learning on campus through tools that enrich classroom and laboratory experiences. At the same time, edX will also reach learners around the world through online course materials. The edX website will begin by hosting MITx and Harvardx content, with the goal of adding content from other universities interested in joining the platform. edX will also support the Harvard and MIT faculty in conducting research on teaching and learning.

\ No newline at end of file diff --git a/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.xml b/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.xml new file mode 100644 index 0000000000..36d335e266 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/html/fd120d9503334db5a2ce53c2e0162128.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/problem/29fe8cca3a99412c801c5b9ce53780c5.xml b/common/test/data/manual-testing-complete/drafts/problem/29fe8cca3a99412c801c5b9ce53780c5.xml new file mode 100644 index 0000000000..f2091dc558 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/problem/29fe8cca3a99412c801c5b9ce53780c5.xml @@ -0,0 +1,20 @@ + + +

Some problems may ask for a particular chemical equation. You can practice this technique by writing out the following reaction in the box below.

+
\( \text{H}_2\text{SO}_4 \longrightarrow \text{ H}^+ + \text{ HSO}_4^-\)
+
+ + + + +if chemcalc.chemical_equations_equal(submission[0], 'H2SO4 -> H^+ + HSO4^-'): + correct = ['correct'] +else: + correct = ['incorrect'] + + + +

Some tips:

  • Only real element symbols are permitted.
  • Subscripts are entered with plain text.
  • Superscripts are indicated with a caret (^).
  • The reaction arrow (\(\longrightarrow\)) is indicated with "->".
+ So, you can enter "H2SO4 -> H^+ + HSO4^-".

+ +
diff --git a/common/test/data/manual-testing-complete/drafts/problem/370cfd42f00843578f50e32545356ef1.xml b/common/test/data/manual-testing-complete/drafts/problem/370cfd42f00843578f50e32545356ef1.xml new file mode 100644 index 0000000000..97938ed9f3 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/problem/370cfd42f00843578f50e32545356ef1.xml @@ -0,0 +1,22 @@ + +

+A multiple choice problem presents radio buttons for student +input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.

+

One of the main elements that goes into a good multiple choice question is the existence of good distractors. That is, each of the alternate responses presented to the student should be the result of a plausible mistake that a student might make. +

+

What Apple device competed with the portable CD player?

+ + + The iPad + Napster + The iPod + The vegetable peeler + + + +
+

Explanation

+

The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks.

+
+
+
diff --git a/common/test/data/manual-testing-complete/drafts/problem/5904f30aba7a41d3ab1609e58bb5a6c2.xml b/common/test/data/manual-testing-complete/drafts/problem/5904f30aba7a41d3ab1609e58bb5a6c2.xml new file mode 100644 index 0000000000..3ed441e60d --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/problem/5904f30aba7a41d3ab1609e58bb5a6c2.xml @@ -0,0 +1,3 @@ + +

Sample Choice Response

+
diff --git a/common/test/data/manual-testing-complete/drafts/problem/5c49dcff565848b8a4834ee8b3beeebc.xml b/common/test/data/manual-testing-complete/drafts/problem/5c49dcff565848b8a4834ee8b3beeebc.xml new file mode 100644 index 0000000000..4cd65a4ca3 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/problem/5c49dcff565848b8a4834ee8b3beeebc.xml @@ -0,0 +1,21 @@ + +

+ +A text input problem accepts a line of text from the +student, and evaluates the input for correctness based on an expected +answer. +

+

+The answer is correct if it matches every character of the expected answer. This can be a problem with international spelling, dates, or anything where the format of the answer is not clear. +

+

Which US state has Lansing as its capital?

+ + + + +
+

Explanation

+

Lansing is the capital of Michigan, although it is not Michigan's largest city, or even the seat of the county in which it resides.

+
+
+
diff --git a/common/test/data/manual-testing-complete/drafts/problem/7e39859879f24e8689861024d4f7cb1e.xml b/common/test/data/manual-testing-complete/drafts/problem/7e39859879f24e8689861024d4f7cb1e.xml new file mode 100644 index 0000000000..8083106a8b --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/problem/7e39859879f24e8689861024d4f7cb1e.xml @@ -0,0 +1,33 @@ + + +

+The shapes below can be selected (yellow) or unselected (cyan). +Clicking on them repeatedly will cycle through these two states. +

+

+If the cone is selected (and not the cube), a correct answer will be +generated after pressing "Check". Clicking on either "Check" or "Save" +will register the current state. +

+ + + +
diff --git a/common/test/data/manual-testing-complete/drafts/vertical/006fa27802794e20a0e04e146a7e4e66.xml b/common/test/data/manual-testing-complete/drafts/vertical/006fa27802794e20a0e04e146a7e4e66.xml new file mode 100644 index 0000000000..ac8a439fd4 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/006fa27802794e20a0e04e146a7e4e66.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/084d74e8d1494817ac5661ae5893fd61.xml b/common/test/data/manual-testing-complete/drafts/vertical/084d74e8d1494817ac5661ae5893fd61.xml new file mode 100644 index 0000000000..a7d630ddec --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/084d74e8d1494817ac5661ae5893fd61.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml b/common/test/data/manual-testing-complete/drafts/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml new file mode 100644 index 0000000000..d748ee34fe --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/11b926ee2cde42259b5165b918de0493.xml b/common/test/data/manual-testing-complete/drafts/vertical/11b926ee2cde42259b5165b918de0493.xml new file mode 100644 index 0000000000..6c452a4a1e --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/11b926ee2cde42259b5165b918de0493.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/14d2052331234fd68fdbd984a2ec8396.xml b/common/test/data/manual-testing-complete/drafts/vertical/14d2052331234fd68fdbd984a2ec8396.xml new file mode 100644 index 0000000000..d1bbfee48a --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/14d2052331234fd68fdbd984a2ec8396.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml b/common/test/data/manual-testing-complete/drafts/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml new file mode 100644 index 0000000000..442e9a48b9 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/32b9f88c4c164dd69ae87a0754516267.xml b/common/test/data/manual-testing-complete/drafts/vertical/32b9f88c4c164dd69ae87a0754516267.xml new file mode 100644 index 0000000000..5d6894e29d --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/32b9f88c4c164dd69ae87a0754516267.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/38105f0357534b4999bbc1dcf82c9148.xml b/common/test/data/manual-testing-complete/drafts/vertical/38105f0357534b4999bbc1dcf82c9148.xml new file mode 100644 index 0000000000..adfd04475d --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/38105f0357534b4999bbc1dcf82c9148.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/4755fc0ee7ff4ed19a720b61810064d1.xml b/common/test/data/manual-testing-complete/drafts/vertical/4755fc0ee7ff4ed19a720b61810064d1.xml new file mode 100644 index 0000000000..86b7af628c --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/4755fc0ee7ff4ed19a720b61810064d1.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/47735fdcfbf1444dbabbd5a09df1a790.xml b/common/test/data/manual-testing-complete/drafts/vertical/47735fdcfbf1444dbabbd5a09df1a790.xml new file mode 100644 index 0000000000..32dd168a5a --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/47735fdcfbf1444dbabbd5a09df1a790.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml b/common/test/data/manual-testing-complete/drafts/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml new file mode 100644 index 0000000000..573af5cb85 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/5bac2ffd65ea4f988bcf474fe93257e6.xml b/common/test/data/manual-testing-complete/drafts/vertical/5bac2ffd65ea4f988bcf474fe93257e6.xml new file mode 100644 index 0000000000..6b81989a78 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/5bac2ffd65ea4f988bcf474fe93257e6.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/7897479a19e24871bbbdc02457aa3c0b.xml b/common/test/data/manual-testing-complete/drafts/vertical/7897479a19e24871bbbdc02457aa3c0b.xml new file mode 100644 index 0000000000..607b4bca7e --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/7897479a19e24871bbbdc02457aa3c0b.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/90c15baa6c004d3f90b43af405968de3.xml b/common/test/data/manual-testing-complete/drafts/vertical/90c15baa6c004d3f90b43af405968de3.xml new file mode 100644 index 0000000000..caee607697 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/90c15baa6c004d3f90b43af405968de3.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/9a63361c946c4b6486e233d21b4947be.xml b/common/test/data/manual-testing-complete/drafts/vertical/9a63361c946c4b6486e233d21b4947be.xml new file mode 100644 index 0000000000..3753a4fdf4 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/9a63361c946c4b6486e233d21b4947be.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/a4bfead3b0204b15a988d77a5d7f58f2.xml b/common/test/data/manual-testing-complete/drafts/vertical/a4bfead3b0204b15a988d77a5d7f58f2.xml new file mode 100644 index 0000000000..2e5b189b83 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/a4bfead3b0204b15a988d77a5d7f58f2.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/drafts/vertical/ccc9fb7ada404ba0986b3fca4056b831.xml b/common/test/data/manual-testing-complete/drafts/vertical/ccc9fb7ada404ba0986b3fca4056b831.xml new file mode 100644 index 0000000000..34e05e4c14 --- /dev/null +++ b/common/test/data/manual-testing-complete/drafts/vertical/ccc9fb7ada404ba0986b3fca4056b831.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.html b/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.html new file mode 100644 index 0000000000..6e7c8bb51e --- /dev/null +++ b/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.html @@ -0,0 +1,33 @@ +

Link rewrite tests:

+

+ Jump to Sports Problem + Jump to Sports Problem by ID +

+ +

ZOOMING DIAGRAMS

+

Some edX classes use extremely large, extremely detailed graphics. To make it easier to understand we can offer two versions of those graphics, with the zoomed section showing when you click on the main view.

+

The example below is from 7.00x: Introduction to Biology and shows a subset of the biochemical reactions that cells carry out.

+

You can view the chemical structures of the molecules by clicking on them. The magnified view also lists the enzymes involved in each step.

+

Press spacebar to open the magifier.

+
+ + magnify + +
+
+ +
diff --git a/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.xml b/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.xml new file mode 100644 index 0000000000..0cbfd76cc9 --- /dev/null +++ b/common/test/data/manual-testing-complete/html/82e9d374eeb944489d5decdb6b8fbd76.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/info/handouts.html b/common/test/data/manual-testing-complete/info/handouts.html new file mode 100644 index 0000000000..c62c811243 --- /dev/null +++ b/common/test/data/manual-testing-complete/info/handouts.html @@ -0,0 +1 @@ +
    Testing
\ No newline at end of file diff --git a/common/test/data/manual-testing-complete/info/updates.html b/common/test/data/manual-testing-complete/info/updates.html new file mode 100644 index 0000000000..4e00610272 --- /dev/null +++ b/common/test/data/manual-testing-complete/info/updates.html @@ -0,0 +1 @@ +

July 15, 2014

Testing
\ No newline at end of file diff --git a/common/test/data/manual-testing-complete/info/updates.items.json b/common/test/data/manual-testing-complete/info/updates.items.json new file mode 100644 index 0000000000..91e099bd06 --- /dev/null +++ b/common/test/data/manual-testing-complete/info/updates.items.json @@ -0,0 +1 @@ +[{"date": "July 15, 2014", "content": "Testing", "status": "visible", "id": 1}] \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/lti/b05c0297100f41e888ddadf82b3ce1b2.xml b/common/test/data/manual-testing-complete/lti/b05c0297100f41e888ddadf82b3ce1b2.xml new file mode 100644 index 0000000000..ae8bed35c1 --- /dev/null +++ b/common/test/data/manual-testing-complete/lti/b05c0297100f41e888ddadf82b3ce1b2.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/policies/2014/grading_policy.json b/common/test/data/manual-testing-complete/policies/2014/grading_policy.json new file mode 100644 index 0000000000..272cb4fec6 --- /dev/null +++ b/common/test/data/manual-testing-complete/policies/2014/grading_policy.json @@ -0,0 +1 @@ +{"GRADER": [{"short_label": "HW", "min_count": 12, "type": "Homework", "drop_count": 2, "weight": 0.15}, {"min_count": 12, "type": "Lab", "drop_count": 2, "weight": 0.15}, {"short_label": "Midterm", "min_count": 1, "type": "Midterm Exam", "drop_count": 0, "weight": 0.3}, {"short_label": "Final", "min_count": 1, "type": "Final Exam", "drop_count": 0, "weight": 0.4}], "GRADE_CUTOFFS": {"Pass": 0.5}} \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/policies/2014/policy.json b/common/test/data/manual-testing-complete/policies/2014/policy.json new file mode 100644 index 0000000000..6fd03ef7e8 --- /dev/null +++ b/common/test/data/manual-testing-complete/policies/2014/policy.json @@ -0,0 +1 @@ +{"course/2014": {"advanced_modules": ["annotatable", "combinedopenended", "peergrading", "lti", "word_cloud"], "show_calculator": true, "display_name": "Manual Smoke Test Course 1", "tabs": [{"type": "courseware", "name": "Courseware"}, {"type": "course_info", "name": "Course Info"}, {"type": "textbooks", "name": "Textbooks"}, {"type": "discussion", "name": "Discussion"}, {"type": "wiki", "name": "Wiki"}, {"type": "progress", "name": "Progress"}, {"type": "pdf_textbooks", "name": "Textbooks"}, {"type": "open_ended", "name": "Open Ended Panel"}], "discussion_topics": {"General": {"id": "i4x-ManTestX-ManTest1-course-2014"}}, "start": "2014-06-26T00:00:00Z", "pdf_textbooks": [{"tab_title": "An Example Paper", "id": "0An_Example_Paper", "chapters": [{"url": "/static/1.pdf", "title": "Introduction "}]}], "lti_passports": ["ims:12345:secret"], "show_chat": true}} \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/policies/assets.json b/common/test/data/manual-testing-complete/policies/assets.json new file mode 100644 index 0000000000..98bc4e162b --- /dev/null +++ b/common/test/data/manual-testing-complete/policies/assets.json @@ -0,0 +1 @@ +{"1.pdf": {"contentType": "application/pdf", "displayname": "1.pdf", "locked": false, "filename": "/c4x/ManTestX/ManTest1/asset/1.pdf", "import_path": null, "thumbnail_location": null}, "subs_OEoXaMPEzfM.srt.sjson": {"contentType": "application/json", "displayname": "subs_OEoXaMPEzfM.srt.sjson", "locked": false, "filename": "/c4x/ManTestX/ManTest1/asset/subs_OEoXaMPEzfM.srt.sjson", "import_path": null, "thumbnail_location": null}, "Screen_Shot_2013-04-16_at_1.43.36_PM.png": {"contentType": "image/png", "displayname": "Screen Shot 2013-04-16 at 1.43.36 PM.png", "locked": false, "filename": "/c4x/ManTestX/ManTest1/asset/Screen_Shot_2013-04-16_at_1.43.36_PM.png", "import_path": null, "thumbnail_location": ["c4x", "ManTestX", "ManTest1", "thumbnail", "Screen_Shot_2013-04-16_at_1.43.36_PM.jpg", null]}} \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/problem/009f9b6b79404206a2c316117099fed5.xml b/common/test/data/manual-testing-complete/problem/009f9b6b79404206a2c316117099fed5.xml new file mode 100644 index 0000000000..688dd90050 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/009f9b6b79404206a2c316117099fed5.xml @@ -0,0 +1,13 @@ + +

Which of the following are in door sports:

+

1- Football

+

2- Squash

+

3- Badminton

+ + + option 1 and 2 + option 1 and 3 + option 2 and 3 + + +
diff --git a/common/test/data/manual-testing-complete/problem/11bbd906f12d4cbdbca3050d68cea79f.xml b/common/test/data/manual-testing-complete/problem/11bbd906f12d4cbdbca3050d68cea79f.xml new file mode 100644 index 0000000000..3b2a91ceda --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/11bbd906f12d4cbdbca3050d68cea79f.xml @@ -0,0 +1,32 @@ + + Here's an example of a "Drag and Drop" question set. Click and drag each word in the scrollbar below, up to the numbered bucket which matches the number of letters in the word. + +correct_answer = { + '1': [[70, 150], 121], + '6': [[190, 150], 121], + '8': [[190, 150], 121], + '2': [[310, 150], 121], + '9': [[310, 150], 121], + '11': [[310, 150], 121], + '4': [[420, 150], 121], + '7': [[420, 150], 121], + '3': [[550, 150], 121], + '5': [[550, 150], 121], + '10': [[550, 150], 121]} +if draganddrop.grade(submission[0], correct_answer): + correct = ['correct'] +else: + correct = ['incorrect'] + +

Drag and Drop with Outline

Please label hydrogen atoms connected with left carbon atom.

+correct_answer = [{ + 'draggables': ['1', '2'], + 'targets': ['t2', 't3', 't4' ], + 'rule':'anyof' +}] +if draganddrop.grade(submission[0], correct_answer): + correct = ['correct'] +else: + correct = ['incorrect'] +
+
diff --git a/common/test/data/manual-testing-complete/problem/29fe8cca3a99412c801c5b9ce53780c5.xml b/common/test/data/manual-testing-complete/problem/29fe8cca3a99412c801c5b9ce53780c5.xml new file mode 100644 index 0000000000..f2091dc558 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/29fe8cca3a99412c801c5b9ce53780c5.xml @@ -0,0 +1,20 @@ + + +

Some problems may ask for a particular chemical equation. You can practice this technique by writing out the following reaction in the box below.

+
\( \text{H}_2\text{SO}_4 \longrightarrow \text{ H}^+ + \text{ HSO}_4^-\)
+
+ + + + +if chemcalc.chemical_equations_equal(submission[0], 'H2SO4 -> H^+ + HSO4^-'): + correct = ['correct'] +else: + correct = ['incorrect'] + + + +

Some tips:

  • Only real element symbols are permitted.
  • Subscripts are entered with plain text.
  • Superscripts are indicated with a caret (^).
  • The reaction arrow (\(\longrightarrow\)) is indicated with "->".
+ So, you can enter "H2SO4 -> H^+ + HSO4^-".

+ +
diff --git a/common/test/data/manual-testing-complete/problem/2f7da8477d8748f0aad0f7fc2134b84f.xml b/common/test/data/manual-testing-complete/problem/2f7da8477d8748f0aad0f7fc2134b84f.xml new file mode 100644 index 0000000000..21d1dd7ad8 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/2f7da8477d8748f0aad0f7fc2134b84f.xml @@ -0,0 +1,32 @@ + + Please make a voltage divider that splits the provided voltage evenly. + +
+dc_value = "dc analysis not found" +for response in submission[0]: + if response[0] == 'dc': + for node in response[1:]: + dc_value = node['output'] + +if dc_value == .5: + correct = ['correct'] +else: + correct = ['incorrect'] +
+

Make a high pass filter

+ac_values = None +for response in submission[0]: + if response[0] == 'ac': + for node in response[1:]: + ac_values = node['NodeA'] +print "the ac analysis value:", ac_values +if ac_values == None: + correct = ['incorrect'] +elif ac_values[0][1] < ac_values[1][1]: + correct = ['correct'] +else: + correct = ['incorrect'] +
+ +

Explanation

A voltage divider that evenly divides the input voltage can be formed with two identically valued resistors, with the sampled voltage taken in between the two.

A simple high-pass filter without any further constaints can be formed by simply putting a resister in series with a capacitor. The actual values of the components do not really matter in order to meet the constraints of the problem.

+
diff --git a/common/test/data/manual-testing-complete/problem/35501134637b4c2b8cfe07ba5e6492bb.xml b/common/test/data/manual-testing-complete/problem/35501134637b4c2b8cfe07ba5e6492bb.xml new file mode 100644 index 0000000000..8083106a8b --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/35501134637b4c2b8cfe07ba5e6492bb.xml @@ -0,0 +1,33 @@ + + +

+The shapes below can be selected (yellow) or unselected (cyan). +Clicking on them repeatedly will cycle through these two states. +

+

+If the cone is selected (and not the cube), a correct answer will be +generated after pressing "Check". Clicking on either "Check" or "Save" +will register the current state. +

+ + + +
diff --git a/common/test/data/manual-testing-complete/problem/39bb74b14f674ea1ab25f52bac9eb83b.xml b/common/test/data/manual-testing-complete/problem/39bb74b14f674ea1ab25f52bac9eb83b.xml new file mode 100644 index 0000000000..7cc0dc7dee --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/39bb74b14f674ea1ab25f52bac9eb83b.xml @@ -0,0 +1,92 @@ + +

+ A JSDraw problem lets the user use the JSDraw editor component to draw a + new molecule or update an existing drawing and then submit their work. + Answers are specified as SMILES strings. +

+

+ I was trying to draw my favorite molecule, caffeine. Unfortunately, + I'm not a very good biochemist. Can you correct my molecule? +

+ + + + JSDraw201081410342D + + 12 13 0 0 0 0 0 V2000 + 12.0000 -6.7600 0.0000 N 0 0 0 0 0 0 0 + 10.6490 -5.9800 0.0000 C 0 0 0 0 0 0 0 + 10.6490 -4.4200 0.0000 N 0 0 0 0 0 0 0 + 12.0000 -3.6400 0.0000 C 0 0 0 0 0 0 0 + 13.3510 -4.4200 0.0000 C 0 0 0 0 0 0 0 + 13.3510 -5.9800 0.0000 C 0 0 0 0 0 0 0 + 14.8347 -6.4620 0.0000 N 0 0 0 0 0 0 0 + 15.7515 -5.1998 0.0000 C 0 0 0 0 0 0 0 + 14.8346 -3.9379 0.0000 N 0 0 0 0 0 0 0 + 15.3166 -2.4542 0.0000 C 0 0 0 0 0 0 0 + 9.2980 -3.6400 0.0000 C 0 0 0 0 0 0 0 + 9.2980 -6.7600 0.0000 O 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 6 2 0 0 0 0 + 6 1 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 1 0 0 0 0 + 9 5 1 0 0 0 0 + 9 10 1 0 0 0 0 + 3 11 1 0 0 0 0 + 2 12 1 0 0 0 0 + M END + + + JSDraw203201413042D + + 14 15 0 0 0 0 0 V2000 + 12.9049 -6.2400 0.0000 N 0 0 0 0 0 0 0 + 11.5539 -5.4600 0.0000 C 0 0 0 0 0 0 0 + 11.5539 -3.9000 0.0000 N 0 0 0 0 0 0 0 + 12.9049 -3.1200 0.0000 C 0 0 0 0 0 0 0 + 14.2558 -3.9000 0.0000 C 0 0 0 0 0 0 0 + 14.2558 -5.4600 0.0000 C 0 0 0 0 0 0 0 + 15.7395 -5.9420 0.0000 N 0 0 0 0 0 0 0 + 16.6563 -4.6798 0.0000 C 0 0 0 0 0 0 0 + 15.7394 -3.4179 0.0000 N 0 0 0 0 0 0 0 + 16.2214 -1.9342 0.0000 C 0 0 0 0 0 0 0 + 10.2029 -3.1200 0.0000 C 0 0 0 0 0 0 0 + 10.2029 -6.2400 0.0000 O 0 0 0 0 0 0 0 + 12.9049 -7.8000 0.0000 C 0 0 0 0 0 0 0 + 12.9050 -1.5600 0.0000 O 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 6 2 0 0 0 0 + 6 1 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 2 0 0 0 0 + 8 9 1 0 0 0 0 + 9 5 1 0 0 0 0 + 9 10 1 0 0 0 0 + 3 11 1 0 0 0 0 + 2 12 2 0 0 0 0 + 1 13 1 0 0 0 0 + 4 14 2 0 0 0 0 + M END + + + C8H10N4O2 + + +
+

Explanation

+

+ Some scholars have hypothesized that the renaissance was made possible + by the introduction of coffee to Italy. Likewise scholars have linked + the Enlightenment with the rise of coffee houses in England. +

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/3a1e2c95f8a54bc98b65e9373dafc86e.xml b/common/test/data/manual-testing-complete/problem/3a1e2c95f8a54bc98b65e9373dafc86e.xml new file mode 100644 index 0000000000..85e1f81426 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/3a1e2c95f8a54bc98b65e9373dafc86e.xml @@ -0,0 +1,26 @@ + +

+A custom python-evaluated input problem accepts one or more lines of text input from the +student, and evaluates the inputs for correctness based on evaluation using a +python script embedded within the problem. +

+ +

Nice university, whose name begins with "s"...

+ + + + +
+

Explanation

+

Stanford

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/427a1515100a4d08b959ba5852a1630d.xml b/common/test/data/manual-testing-complete/problem/427a1515100a4d08b959ba5852a1630d.xml new file mode 100644 index 0000000000..4150db5102 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/427a1515100a4d08b959ba5852a1630d.xml @@ -0,0 +1,6 @@ + +

Capital of France is Paris:

+ + + +
diff --git a/common/test/data/manual-testing-complete/problem/440e298f5b804377bc31d06a3f783a5c.xml b/common/test/data/manual-testing-complete/problem/440e298f5b804377bc31d06a3f783a5c.xml new file mode 100644 index 0000000000..4cd65a4ca3 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/440e298f5b804377bc31d06a3f783a5c.xml @@ -0,0 +1,21 @@ + +

+ +A text input problem accepts a line of text from the +student, and evaluates the input for correctness based on an expected +answer. +

+

+The answer is correct if it matches every character of the expected answer. This can be a problem with international spelling, dates, or anything where the format of the answer is not clear. +

+

Which US state has Lansing as its capital?

+ + + + +
+

Explanation

+

Lansing is the capital of Michigan, although it is not Michigan's largest city, or even the seat of the county in which it resides.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/45c30a061c3f473499a32d7e14f4a750.xml b/common/test/data/manual-testing-complete/problem/45c30a061c3f473499a32d7e14f4a750.xml new file mode 100644 index 0000000000..899e8a0a62 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/45c30a061c3f473499a32d7e14f4a750.xml @@ -0,0 +1,21 @@ + +

The Dopamine molecule, as shown, cannot make ionic bonds. Edit the dopamine molecule so it can make ionic bonds. +

+

+ When you are ready, click "Check.” If you need to start over, click + "Reset.” +

+ + + + + + + + +
diff --git a/common/test/data/manual-testing-complete/problem/45c317cb93d447f293ce982a2eccd77d.xml b/common/test/data/manual-testing-complete/problem/45c317cb93d447f293ce982a2eccd77d.xml new file mode 100644 index 0000000000..db34051c2b --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/45c317cb93d447f293ce982a2eccd77d.xml @@ -0,0 +1,31 @@ + + + + + + + +

Be sure to click "Fold" to fold your protein before you click "Check".

+ +

+ There are many protein sequences that will fold to the shape we asked you + about. Here is a sample sequence that will work. You can play around with + it if you are curious. +

+
    +
  • + Stick: RRRRRRR +
  • +
+
+
diff --git a/common/test/data/manual-testing-complete/problem/5c49dcff565848b8a4834ee8b3beeebc.xml b/common/test/data/manual-testing-complete/problem/5c49dcff565848b8a4834ee8b3beeebc.xml new file mode 100644 index 0000000000..4cd65a4ca3 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/5c49dcff565848b8a4834ee8b3beeebc.xml @@ -0,0 +1,21 @@ + +

+ +A text input problem accepts a line of text from the +student, and evaluates the input for correctness based on an expected +answer. +

+

+The answer is correct if it matches every character of the expected answer. This can be a problem with international spelling, dates, or anything where the format of the answer is not clear. +

+

Which US state has Lansing as its capital?

+ + + + +
+

Explanation

+

Lansing is the capital of Michigan, although it is not Michigan's largest city, or even the seat of the county in which it resides.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/5e3b300353974a42875052a21823e39b.xml b/common/test/data/manual-testing-complete/problem/5e3b300353974a42875052a21823e39b.xml new file mode 100644 index 0000000000..5b3353e3e9 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/5e3b300353974a42875052a21823e39b.xml @@ -0,0 +1,20 @@ + + + + Annotation Exercise + They are the ones who, at the public assembly, had put savage derangement [atē] into my thinking [phrenes] |89 on that day when I myself deprived Achilles of his honorific portion [geras] + Agamemnon says that atē or ‘derangement’ was the cause of his actions: why could Zeus say the same thing? + Type your response below: + In your answer to A) and considering the way atē or 'derangement' works in the Iliad as a whole, did you describe atē as: + + + + + + + + +

If you answered “a cause,” you would be following the logic of the speaker, Agamemnon. But there is another logic at work here, and that is the superhuman logic that operates the cosmos. According to that logic, you have to look at the consequences of what you have done, not only the causes, and only then can you figure out the meaning of it all. If you answered “both a cause and an effect,” you would be reading out of the text in a more complete way. If you answered “an effect,” however, the reading would be less complete. Yes, you would still be reading out of the text, since the basic logic of the story is that a disaster happened. But it would be an incomplete reading, since the story is also about the need for explaining why the disaster happened.

+

Going back to the answer “a cause,” the problem with this reading is that you would have simply taken Agamemnon’s words at face value. It is tempting, I admit, for us to see things the way Agamemnon sees things, since his world view in many ways resembles our own view of the Iliad when we read it for the very first time. Agamemnon is saying: I made a mistake, but it is not my fault, since a god made me do it. In Homeric poetry, we too see the gods intervening in the lives of humans. Yes, but we also see humans making their own free choices. If we forget about the free choice of Agamemnon, then we are simply reading into the text and not paying full attention to what the text says in its entirety.

+
+
diff --git a/common/test/data/manual-testing-complete/problem/70257670b9dd45c8afd5abd3c9fe606f.xml b/common/test/data/manual-testing-complete/problem/70257670b9dd45c8afd5abd3c9fe606f.xml new file mode 100644 index 0000000000..3b2a91ceda --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/70257670b9dd45c8afd5abd3c9fe606f.xml @@ -0,0 +1,32 @@ + + Here's an example of a "Drag and Drop" question set. Click and drag each word in the scrollbar below, up to the numbered bucket which matches the number of letters in the word. + +correct_answer = { + '1': [[70, 150], 121], + '6': [[190, 150], 121], + '8': [[190, 150], 121], + '2': [[310, 150], 121], + '9': [[310, 150], 121], + '11': [[310, 150], 121], + '4': [[420, 150], 121], + '7': [[420, 150], 121], + '3': [[550, 150], 121], + '5': [[550, 150], 121], + '10': [[550, 150], 121]} +if draganddrop.grade(submission[0], correct_answer): + correct = ['correct'] +else: + correct = ['incorrect'] + +

Drag and Drop with Outline

Please label hydrogen atoms connected with left carbon atom.

+correct_answer = [{ + 'draggables': ['1', '2'], + 'targets': ['t2', 't3', 't4' ], + 'rule':'anyof' +}] +if draganddrop.grade(submission[0], correct_answer): + correct = ['correct'] +else: + correct = ['incorrect'] +
+
diff --git a/common/test/data/manual-testing-complete/problem/7eff0366d53045c1b423ee988d344a13.xml b/common/test/data/manual-testing-complete/problem/7eff0366d53045c1b423ee988d344a13.xml new file mode 100644 index 0000000000..c79eeacdc4 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/7eff0366d53045c1b423ee988d344a13.xml @@ -0,0 +1,92 @@ + +

+ A JSDraw problem lets the user use the JSDraw editor component to draw a + new molecule or update an existing drawing and then submit their work. + Answers are specified as SMILES strings. +

+

+ I was trying to draw my favorite molecule, caffeine. Unfortunately, + I'm not a very good biochemist. Can you correct my molecule? +

+ + + + JSDraw201081410342D + + 12 13 0 0 0 0 0 V2000 + 12.0000 -6.7600 0.0000 N 0 0 0 0 0 0 0 + 10.6490 -5.9800 0.0000 C 0 0 0 0 0 0 0 + 10.6490 -4.4200 0.0000 N 0 0 0 0 0 0 0 + 12.0000 -3.6400 0.0000 C 0 0 0 0 0 0 0 + 13.3510 -4.4200 0.0000 C 0 0 0 0 0 0 0 + 13.3510 -5.9800 0.0000 C 0 0 0 0 0 0 0 + 14.8347 -6.4620 0.0000 N 0 0 0 0 0 0 0 + 15.7515 -5.1998 0.0000 C 0 0 0 0 0 0 0 + 14.8346 -3.9379 0.0000 N 0 0 0 0 0 0 0 + 15.3166 -2.4542 0.0000 C 0 0 0 0 0 0 0 + 9.2980 -3.6400 0.0000 C 0 0 0 0 0 0 0 + 9.2980 -6.7600 0.0000 O 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 6 2 0 0 0 0 + 6 1 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 1 0 0 0 0 + 9 5 1 0 0 0 0 + 9 10 1 0 0 0 0 + 3 11 1 0 0 0 0 + 2 12 1 0 0 0 0 + M END + + + JSDraw203201413042D + + 14 15 0 0 0 0 0 V2000 + 12.9049 -6.2400 0.0000 N 0 0 0 0 0 0 0 + 11.5539 -5.4600 0.0000 C 0 0 0 0 0 0 0 + 11.5539 -3.9000 0.0000 N 0 0 0 0 0 0 0 + 12.9049 -3.1200 0.0000 C 0 0 0 0 0 0 0 + 14.2558 -3.9000 0.0000 C 0 0 0 0 0 0 0 + 14.2558 -5.4600 0.0000 C 0 0 0 0 0 0 0 + 15.7395 -5.9420 0.0000 N 0 0 0 0 0 0 0 + 16.6563 -4.6798 0.0000 C 0 0 0 0 0 0 0 + 15.7394 -3.4179 0.0000 N 0 0 0 0 0 0 0 + 16.2214 -1.9342 0.0000 C 0 0 0 0 0 0 0 + 10.2029 -3.1200 0.0000 C 0 0 0 0 0 0 0 + 10.2029 -6.2400 0.0000 O 0 0 0 0 0 0 0 + 12.9049 -7.8000 0.0000 C 0 0 0 0 0 0 0 + 12.9050 -1.5600 0.0000 O 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 6 2 0 0 0 0 + 6 1 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 2 0 0 0 0 + 8 9 1 0 0 0 0 + 9 5 1 0 0 0 0 + 9 10 1 0 0 0 0 + 3 11 1 0 0 0 0 + 2 12 2 0 0 0 0 + 1 13 1 0 0 0 0 + 4 14 2 0 0 0 0 + M END + + + C8H10N4O2 + + +
+

Explanation

+

+ Some scholars have hypothesized that the renaissance was made possible + by the introduction of coffee to Italy. Likewise scholars have linked + the Enlightenment with the rise of coffee houses in England. +

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/8a5a7653bf804a968c17d398cb91aa4e.xml b/common/test/data/manual-testing-complete/problem/8a5a7653bf804a968c17d398cb91aa4e.xml new file mode 100644 index 0000000000..dace2e32d4 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/8a5a7653bf804a968c17d398cb91aa4e.xml @@ -0,0 +1,17 @@ + +

+ An image mapped input problem presents an image for the student. + Input is given by the location of mouse clicks on the image. + Correctness of input can be evaluated based on expected dimensions of a rectangle. +

+

Which animal shown below is a kitten?

+ + + + +
+

Explanation

+

The animal on the right is a kitten. The animal on the left is a puppy, not a kitten.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/9497fab9cc6f4187ba17d23731b614bf.xml b/common/test/data/manual-testing-complete/problem/9497fab9cc6f4187ba17d23731b614bf.xml new file mode 100644 index 0000000000..91192df8d8 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/9497fab9cc6f4187ba17d23731b614bf.xml @@ -0,0 +1,14 @@ + +

A numerical input problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.

+

The answer is correct if it is within a specified numerical tolerance of the expected answer.

+

Enter the number of fingers on a human hand

+ + + + +
+

Explanation

+

If you look at your hand, you can count that you have five fingers.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/9992192a14ce47fcb71f77d7e77c821c.xml b/common/test/data/manual-testing-complete/problem/9992192a14ce47fcb71f77d7e77c821c.xml new file mode 100644 index 0000000000..97938ed9f3 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/9992192a14ce47fcb71f77d7e77c821c.xml @@ -0,0 +1,22 @@ + +

+A multiple choice problem presents radio buttons for student +input. Students can only select a single option presented. Multiple Choice questions have been the subject of many areas of research due to the early invention and adoption of bubble sheets.

+

One of the main elements that goes into a good multiple choice question is the existence of good distractors. That is, each of the alternate responses presented to the student should be the result of a plausible mistake that a student might make. +

+

What Apple device competed with the portable CD player?

+ + + The iPad + Napster + The iPod + The vegetable peeler + + + +
+

Explanation

+

The release of the iPod allowed consumers to carry their entire music library with them in a format that did not rely on fragile and energy-intensive spinning disks.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/a473cecce312487a8339995bde24be53.xml b/common/test/data/manual-testing-complete/problem/a473cecce312487a8339995bde24be53.xml new file mode 100644 index 0000000000..d3f54f20c2 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/a473cecce312487a8339995bde24be53.xml @@ -0,0 +1,11 @@ + +

A checkboxes problem presents checkbox buttons for student input. Students can select more than one option presented.

+

Select the answer that matches

+ + + correct + incorrect + correct + + +
diff --git a/common/test/data/manual-testing-complete/problem/a5ca9b0f09cc4798bb53e5840e625301.xml b/common/test/data/manual-testing-complete/problem/a5ca9b0f09cc4798bb53e5840e625301.xml new file mode 100644 index 0000000000..3b2de21ac3 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/a5ca9b0f09cc4798bb53e5840e625301.xml @@ -0,0 +1,10 @@ + +

Which of the following equations is the most complex

+ + + \(E = m c^2 \) + \(A = \pi r^2\) + + +

+
diff --git a/common/test/data/manual-testing-complete/problem/b6b80c6b383f4c3c80efc32b968368dc.xml b/common/test/data/manual-testing-complete/problem/b6b80c6b383f4c3c80efc32b968368dc.xml new file mode 100644 index 0000000000..3a6beae668 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/b6b80c6b383f4c3c80efc32b968368dc.xml @@ -0,0 +1,37 @@ + +

+A math expression input problem accepts a line of text representing a mathematical expression from the +student, and evaluates the input for equivalence to a mathematical expression provided by the +grader. Correctness is based on numerical sampling of the symbolic expressions. +

+

+The answer is correct if both the student provided response and the grader's mathematical +expression are equivalent to specified numerical tolerance, over a specified range of values for each +variable. +

+

This kind of response checking can handle symbolic expressions, but places an extra burden +on the problem author to specify the allowed variables in the expression, and the +numerical ranges over which the variables must be sampled in order to test for correctness.

+ +

Give an equation for the relativistic energy of an object with mass m. Explicitly indicate multiplication with a * symbol.

+ + +
+ E = + +
+

The answer to this question is (R_1*R_2)/R_3.

+ + + + + +
+

Explanation

+

The mathematical summary of many of the theory of relativity developed by Einstein is that the amount of energy contained in a mass m is the mass time the speed of light squared.

+

As you can see with the formula entry, the answer is \(\frac{R_1*R_2}{R_3}\)

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/c2ee6e8917fe4c97ac99d7b616ff0b89.xml b/common/test/data/manual-testing-complete/problem/c2ee6e8917fe4c97ac99d7b616ff0b89.xml new file mode 100644 index 0000000000..cf9ee3d8a0 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/c2ee6e8917fe4c97ac99d7b616ff0b89.xml @@ -0,0 +1,162 @@ + + +

We are searching for + the smallest monthly payment such that we can pay off the + entire balance of a loan within a year.

+

The following values might be useful when writing your solution

+
+

Monthly interest rate += (Annual interest rate) / 12
+Monthly payment lower bound += Balance / 12
+ +Monthly payment upper bound = (Balance x + (1 + Monthly interest rate)12) / 12 +

+
+

The following variables contain values as described below:

+
    +
  1. +

    balance - the outstanding balance on the credit card

    +
  2. +
  3. +

    annualInterestRate - annual interest rate as a decimal

    +
  4. +
+

Write a program that uses these bounds and bisection + search (for more info check out the Wikipedia page + on bisection search) + to find the smallest monthly payment to the cent + such that we can pay off the + debt within a year.

+

Note that if you do not use bisection search, your code will not run - your code only has + 30 seconds to run on our servers. If you get a message that states "Your submission could not be graded. Please recheck your + submission and try again. If the problem persists, please notify the course staff.", check to be + sure your code doesn't take too long to run.

+

The code you paste into the following box should not specify the values for the variables balance + or annualInterestRate - our test code will define those values + before testing your submission.

+
+ + + + + +monthlyInterestRate = annualInterestRate/12 +lowerBound = balance/12 +upperBound = (balance * (1+annualInterestRate/12)**12)/12 +originalBalance = balance + +# Keep testing new payment values +# until the balance is +/- $0.02 +while abs(balance) > .02: + # Reset the value of balance to its original value + balance = originalBalance + # Calculate a new monthly payment value from the bounds + payment = (upperBound - lowerBound)/2 + lowerBound + + # Test if this payment value is sufficient to pay off the + # entire balance in 12 months + for month in range(12): + balance -= payment + balance *= 1+monthlyInterestRate + + # Reset bounds based on the final value of balance + if balance > 0: + # If the balance is too big, need higher payment + # so we increase the lower bound + lowerBound = payment + else: + # If the balance is too small, we need a lower + # payment, so we decrease the upper bound + upperBound = payment + +# When the while loop terminates, we know we have +# our answer! +print "Lowest Payment:", round(payment, 2) + + +{"grader": "ps02/bisect/grade_bisect.py"} + + + + +
+ Note: +

Depending on where, and how frequently, you round during + this function, your answers may be off a few cents in + either direction. Try rounding as few times as possible + in order to increase the accuracy of your result.

+
+
+

Hints

+
+
+ Test Cases to test your code with. Be sure to test these on your own machine - + and that you get the same output! - before running your code on this webpage! +
+
+

Note: The automated tests are lenient - if your answers are off by a few cents + in either direction, your code is OK.

+

Test Cases:

+

+

+              
+      Test Case 1:
+      balance = 320000
+      annualInterestRate = 0.2
+
+      Result Your Code Should Generate:
+      -------------------
+      Lowest Payment: 29157.09
+
+            
+

+

+

+              
+      Test Case 2:
+      balance = 999999
+      annualInterestRate = 0.18
+
+      Result Your Code Should Generate:
+      -------------------
+      Lowest Payment: 90325.07
+
+            
+

+
+
+
+
+ The autograder says, "Your submission could not be graded." Help! +
+
+

If the autograder gives you the following message:

+
+Your submission could not be graded.
+Please recheck your submission and try again. If the problem persists, please notify the course staff.
+      
+

Don't panic! There are a few things that might be wrong with your code that you should + check out. The number one reason this message appears is because your code timed out. + You only get 30 seconds of computation time on our servers. If your code times out, + you probably have an infinite loop. What to do?

+

The number 1 thing to do is that you need to run this code in your own local + environment. Your code should print one line at the end of the loop. If your code never prints anything + out - you have an infinite loop!

+

To debug your infinite loop - check your loop conditional. When will it stop? + Try inserting print statements inside your loop that prints out information (like variables) - are you + incrementing or decrementing your loop counter correctly? + Search the forum for people with similar issues. If your search turns up nothing, + make a new post and paste in your loop conditional for others to help you out with.

+

Please don't email the course staff unless your code legitimately works and prints out the + correct answers in your local environment. In that case, please email your code file, + a screenshot of the code printing out the correct answers in your local environment, + and a screenshot of the exact same code not working on the tutor. The course staff is + otherwise unable to help debug your problem set via email - we can only address platform issues.

+
+
+
+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/d0bdd7c3487d4f94b7bcd207f110c20a.xml b/common/test/data/manual-testing-complete/problem/d0bdd7c3487d4f94b7bcd207f110c20a.xml new file mode 100644 index 0000000000..db34051c2b --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/d0bdd7c3487d4f94b7bcd207f110c20a.xml @@ -0,0 +1,31 @@ + + + + + + + +

Be sure to click "Fold" to fold your protein before you click "Check".

+ +

+ There are many protein sequences that will fold to the shape we asked you + about. Here is a sample sequence that will work. You can play around with + it if you are curious. +

+
    +
  • + Stick: RRRRRRR +
  • +
+
+
diff --git a/common/test/data/manual-testing-complete/problem/d30b3812201a46af88d30bd4c7c009e6.xml b/common/test/data/manual-testing-complete/problem/d30b3812201a46af88d30bd4c7c009e6.xml new file mode 100644 index 0000000000..fb96600806 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/d30b3812201a46af88d30bd4c7c009e6.xml @@ -0,0 +1,15 @@ + +

A numerical input problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.

+

The answer is correct if it is within a specified numerical tolerance of the expected answer.

+

Enter the numerical value of Pi:

+ + + + + +
+

Explanation

+

Pi, or the the ratio between a circle's circumference to its diameter, is an irrational number known to extreme precision. It is value is approximately equal to 3.14.

+
+
+
diff --git a/common/test/data/manual-testing-complete/problem/dcada38f8944442799ac2fed42201641.xml b/common/test/data/manual-testing-complete/problem/dcada38f8944442799ac2fed42201641.xml new file mode 100644 index 0000000000..d3f54f20c2 --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/dcada38f8944442799ac2fed42201641.xml @@ -0,0 +1,11 @@ + +

A checkboxes problem presents checkbox buttons for student input. Students can select more than one option presented.

+

Select the answer that matches

+ + + correct + incorrect + correct + + +
diff --git a/common/test/data/manual-testing-complete/problem/eb248c5260254ce094c157ffb8352d16.xml b/common/test/data/manual-testing-complete/problem/eb248c5260254ce094c157ffb8352d16.xml new file mode 100644 index 0000000000..62426e3dcf --- /dev/null +++ b/common/test/data/manual-testing-complete/problem/eb248c5260254ce094c157ffb8352d16.xml @@ -0,0 +1,15 @@ + +

A numerical input problem accepts a line of text input from the student, and evaluates the input for correctness based on its numerical value.

+

The answer is correct if it is within a specified numerical tolerance of the expected answer.

+

Enter the approximate value of 502*9:

+ + + + + +
+

Explanation

+

Although you can get an exact value by typing 502*9 into a calculator, the result will be close to 500*10, or 5,000. The grader accepts any response within 15% of the true value, 4518, so that you can use any estimation technique that you like.

+
+
+
diff --git a/common/test/data/manual-testing-complete/sequential/01a66b857fad4221b01f742ec0e86c49.xml b/common/test/data/manual-testing-complete/sequential/01a66b857fad4221b01f742ec0e86c49.xml new file mode 100644 index 0000000000..3cd056e3cf --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/01a66b857fad4221b01f742ec0e86c49.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/0aa765632f4d4b84ad8d96f41cec5825.xml b/common/test/data/manual-testing-complete/sequential/0aa765632f4d4b84ad8d96f41cec5825.xml new file mode 100644 index 0000000000..251d4e99d2 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/0aa765632f4d4b84ad8d96f41cec5825.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/0cd40e13b4a045aba07d4f626c8b32de.xml b/common/test/data/manual-testing-complete/sequential/0cd40e13b4a045aba07d4f626c8b32de.xml new file mode 100644 index 0000000000..4672616210 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/0cd40e13b4a045aba07d4f626c8b32de.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/0d0e69d08e95436fbbf1be4c6dfec48a.xml b/common/test/data/manual-testing-complete/sequential/0d0e69d08e95436fbbf1be4c6dfec48a.xml new file mode 100644 index 0000000000..7dac57b9a7 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/0d0e69d08e95436fbbf1be4c6dfec48a.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/0e86943b2cb54a56a1a14c13da3f388d.xml b/common/test/data/manual-testing-complete/sequential/0e86943b2cb54a56a1a14c13da3f388d.xml new file mode 100644 index 0000000000..d4d5ca9a8f --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/0e86943b2cb54a56a1a14c13da3f388d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/158963ff751747e3945f3834dd30e5fb.xml b/common/test/data/manual-testing-complete/sequential/158963ff751747e3945f3834dd30e5fb.xml new file mode 100644 index 0000000000..3aa27d6c3e --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/158963ff751747e3945f3834dd30e5fb.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/17d39634673a4151b6f337a5c216eb52.xml b/common/test/data/manual-testing-complete/sequential/17d39634673a4151b6f337a5c216eb52.xml new file mode 100644 index 0000000000..42ee54df6d --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/17d39634673a4151b6f337a5c216eb52.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/1dd8f4178f2a4b9cb09f37c5d6230f9d.xml b/common/test/data/manual-testing-complete/sequential/1dd8f4178f2a4b9cb09f37c5d6230f9d.xml new file mode 100644 index 0000000000..b041f06d80 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/1dd8f4178f2a4b9cb09f37c5d6230f9d.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/21b1a19dbe264a98b06ce9567a3e4171.xml b/common/test/data/manual-testing-complete/sequential/21b1a19dbe264a98b06ce9567a3e4171.xml new file mode 100644 index 0000000000..6d252afd8c --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/21b1a19dbe264a98b06ce9567a3e4171.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/2db8efb4573842c8854648a3ac9e52a4.xml b/common/test/data/manual-testing-complete/sequential/2db8efb4573842c8854648a3ac9e52a4.xml new file mode 100644 index 0000000000..b0f0d8c6f7 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/2db8efb4573842c8854648a3ac9e52a4.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/2e23db09e8b5472cbae9624208e3e1d7.xml b/common/test/data/manual-testing-complete/sequential/2e23db09e8b5472cbae9624208e3e1d7.xml new file mode 100644 index 0000000000..4595060c55 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/2e23db09e8b5472cbae9624208e3e1d7.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/30e61af5a8d74833bb66e19ccea1e5d8.xml b/common/test/data/manual-testing-complete/sequential/30e61af5a8d74833bb66e19ccea1e5d8.xml new file mode 100644 index 0000000000..af867d7014 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/30e61af5a8d74833bb66e19ccea1e5d8.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/313d1bb9031c4d529c7018248d6fff52.xml b/common/test/data/manual-testing-complete/sequential/313d1bb9031c4d529c7018248d6fff52.xml new file mode 100644 index 0000000000..03f3db0c36 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/313d1bb9031c4d529c7018248d6fff52.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/345d618ca88944668d86586f83bff338.xml b/common/test/data/manual-testing-complete/sequential/345d618ca88944668d86586f83bff338.xml new file mode 100644 index 0000000000..707078e637 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/345d618ca88944668d86586f83bff338.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/363603b2c7d34d26a3baa9de29be2211.xml b/common/test/data/manual-testing-complete/sequential/363603b2c7d34d26a3baa9de29be2211.xml new file mode 100644 index 0000000000..6e3a3190c8 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/363603b2c7d34d26a3baa9de29be2211.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/3aa3759deca94e1783b7dc9c148cd483.xml b/common/test/data/manual-testing-complete/sequential/3aa3759deca94e1783b7dc9c148cd483.xml new file mode 100644 index 0000000000..08146bc68e --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/3aa3759deca94e1783b7dc9c148cd483.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/3b115f75b12b42699a3148ea0ffee76b.xml b/common/test/data/manual-testing-complete/sequential/3b115f75b12b42699a3148ea0ffee76b.xml new file mode 100644 index 0000000000..b5e39c5bde --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/3b115f75b12b42699a3148ea0ffee76b.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/4026dba735fe450faf81f766c63bef8b.xml b/common/test/data/manual-testing-complete/sequential/4026dba735fe450faf81f766c63bef8b.xml new file mode 100644 index 0000000000..711000448d --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/4026dba735fe450faf81f766c63bef8b.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/47b7432f998c45abad9f79effeda60bf.xml b/common/test/data/manual-testing-complete/sequential/47b7432f998c45abad9f79effeda60bf.xml new file mode 100644 index 0000000000..678663dced --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/47b7432f998c45abad9f79effeda60bf.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/4cd0b5b3dd3343b5937fea80ec5005cc.xml b/common/test/data/manual-testing-complete/sequential/4cd0b5b3dd3343b5937fea80ec5005cc.xml new file mode 100644 index 0000000000..73b8226041 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/4cd0b5b3dd3343b5937fea80ec5005cc.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/4eadf76912cd436b9d698c8759784d8d.xml b/common/test/data/manual-testing-complete/sequential/4eadf76912cd436b9d698c8759784d8d.xml new file mode 100644 index 0000000000..798ad29ca0 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/4eadf76912cd436b9d698c8759784d8d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/508e5fa820b643b1a329e2ab5dd59393.xml b/common/test/data/manual-testing-complete/sequential/508e5fa820b643b1a329e2ab5dd59393.xml new file mode 100644 index 0000000000..5cfa0c52ac --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/508e5fa820b643b1a329e2ab5dd59393.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/589cf38cfb22450a901818b48d4b7ff5.xml b/common/test/data/manual-testing-complete/sequential/589cf38cfb22450a901818b48d4b7ff5.xml new file mode 100644 index 0000000000..3b6d8b55ac --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/589cf38cfb22450a901818b48d4b7ff5.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/5c33f2c2b3aa45f5bfbf7bf7f9bcb2ff.xml b/common/test/data/manual-testing-complete/sequential/5c33f2c2b3aa45f5bfbf7bf7f9bcb2ff.xml new file mode 100644 index 0000000000..57d9bf8664 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/5c33f2c2b3aa45f5bfbf7bf7f9bcb2ff.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/613404c6df1445ed81f12883dde30a41.xml b/common/test/data/manual-testing-complete/sequential/613404c6df1445ed81f12883dde30a41.xml new file mode 100644 index 0000000000..0533172843 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/613404c6df1445ed81f12883dde30a41.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/67c9c6cd94fe498fb1dc965c35eca3d3.xml b/common/test/data/manual-testing-complete/sequential/67c9c6cd94fe498fb1dc965c35eca3d3.xml new file mode 100644 index 0000000000..00591dc9c5 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/67c9c6cd94fe498fb1dc965c35eca3d3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/6c4c10b89cc449fcbde0006c47e3ee26.xml b/common/test/data/manual-testing-complete/sequential/6c4c10b89cc449fcbde0006c47e3ee26.xml new file mode 100644 index 0000000000..9ba24fe529 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/6c4c10b89cc449fcbde0006c47e3ee26.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/7942fe1a06aa439092aabe3615d91b15.xml b/common/test/data/manual-testing-complete/sequential/7942fe1a06aa439092aabe3615d91b15.xml new file mode 100644 index 0000000000..05910b7dfb --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/7942fe1a06aa439092aabe3615d91b15.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/7a598df4cc4345138332c1d19ecd963d.xml b/common/test/data/manual-testing-complete/sequential/7a598df4cc4345138332c1d19ecd963d.xml new file mode 100644 index 0000000000..38d3b6ee78 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/7a598df4cc4345138332c1d19ecd963d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/7fe9686bb8fe4edba75867ddd1d7b1c5.xml b/common/test/data/manual-testing-complete/sequential/7fe9686bb8fe4edba75867ddd1d7b1c5.xml new file mode 100644 index 0000000000..9c712c8c5f --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/7fe9686bb8fe4edba75867ddd1d7b1c5.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/8ad25eec767f40ae81bcc7555778c91e.xml b/common/test/data/manual-testing-complete/sequential/8ad25eec767f40ae81bcc7555778c91e.xml new file mode 100644 index 0000000000..e6728b209c --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/8ad25eec767f40ae81bcc7555778c91e.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/948737f132254c2aa65f6024edee7e68.xml b/common/test/data/manual-testing-complete/sequential/948737f132254c2aa65f6024edee7e68.xml new file mode 100644 index 0000000000..077d2aeff6 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/948737f132254c2aa65f6024edee7e68.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/aa338c6acd1e498ca8d4ccf6ded72f9b.xml b/common/test/data/manual-testing-complete/sequential/aa338c6acd1e498ca8d4ccf6ded72f9b.xml new file mode 100644 index 0000000000..96fe5d82a7 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/aa338c6acd1e498ca8d4ccf6ded72f9b.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/ac37154b78454cecaad080221cf1dbd5.xml b/common/test/data/manual-testing-complete/sequential/ac37154b78454cecaad080221cf1dbd5.xml new file mode 100644 index 0000000000..46a24fa381 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/ac37154b78454cecaad080221cf1dbd5.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/b7ebe0f048e9466e9ef32e7815fb5a93.xml b/common/test/data/manual-testing-complete/sequential/b7ebe0f048e9466e9ef32e7815fb5a93.xml new file mode 100644 index 0000000000..d88f4d68b3 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/b7ebe0f048e9466e9ef32e7815fb5a93.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/b857bc7d37c74e38b51741340da91dcd.xml b/common/test/data/manual-testing-complete/sequential/b857bc7d37c74e38b51741340da91dcd.xml new file mode 100644 index 0000000000..febff369c4 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/b857bc7d37c74e38b51741340da91dcd.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/bb9bc5a7d0d945cea2a77e3d85f28c41.xml b/common/test/data/manual-testing-complete/sequential/bb9bc5a7d0d945cea2a77e3d85f28c41.xml new file mode 100644 index 0000000000..87337e7daf --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/bb9bc5a7d0d945cea2a77e3d85f28c41.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/bba59b360c344a1db0eb3239e2381484.xml b/common/test/data/manual-testing-complete/sequential/bba59b360c344a1db0eb3239e2381484.xml new file mode 100644 index 0000000000..d5a6bc025c --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/bba59b360c344a1db0eb3239e2381484.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/bd0b30ef8bea48ff86559be1cbe2fa49.xml b/common/test/data/manual-testing-complete/sequential/bd0b30ef8bea48ff86559be1cbe2fa49.xml new file mode 100644 index 0000000000..ce6298a1a8 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/bd0b30ef8bea48ff86559be1cbe2fa49.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/c18b834531e14a3fb070dabf16380541.xml b/common/test/data/manual-testing-complete/sequential/c18b834531e14a3fb070dabf16380541.xml new file mode 100644 index 0000000000..5e24d39dea --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/c18b834531e14a3fb070dabf16380541.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/c59bd9a5a7ec4b31a95515c14bb9f552.xml b/common/test/data/manual-testing-complete/sequential/c59bd9a5a7ec4b31a95515c14bb9f552.xml new file mode 100644 index 0000000000..b72f3de81d --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/c59bd9a5a7ec4b31a95515c14bb9f552.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/c681c865017d4c0ea931f7345aa79277.xml b/common/test/data/manual-testing-complete/sequential/c681c865017d4c0ea931f7345aa79277.xml new file mode 100644 index 0000000000..91e37bde1e --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/c681c865017d4c0ea931f7345aa79277.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/c76b46a765e24c1f9f51de2b49131be0.xml b/common/test/data/manual-testing-complete/sequential/c76b46a765e24c1f9f51de2b49131be0.xml new file mode 100644 index 0000000000..481dd08d6e --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/c76b46a765e24c1f9f51de2b49131be0.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/ca6fc483ef064fa7b275f9e712f041f6.xml b/common/test/data/manual-testing-complete/sequential/ca6fc483ef064fa7b275f9e712f041f6.xml new file mode 100644 index 0000000000..b492861b07 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/ca6fc483ef064fa7b275f9e712f041f6.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/d0e7879a63a4429fb1223a22443681b9.xml b/common/test/data/manual-testing-complete/sequential/d0e7879a63a4429fb1223a22443681b9.xml new file mode 100644 index 0000000000..da22046b84 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/d0e7879a63a4429fb1223a22443681b9.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/d49ee0959c564c8d8b55660ca5fa9bcd.xml b/common/test/data/manual-testing-complete/sequential/d49ee0959c564c8d8b55660ca5fa9bcd.xml new file mode 100644 index 0000000000..fcf01cad05 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/d49ee0959c564c8d8b55660ca5fa9bcd.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/d6d7e96bf6a441a4b4e7c7eac0d0e573.xml b/common/test/data/manual-testing-complete/sequential/d6d7e96bf6a441a4b4e7c7eac0d0e573.xml new file mode 100644 index 0000000000..b1193fe697 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/d6d7e96bf6a441a4b4e7c7eac0d0e573.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/d7d631967807476485aa26ba0c39a992.xml b/common/test/data/manual-testing-complete/sequential/d7d631967807476485aa26ba0c39a992.xml new file mode 100644 index 0000000000..12351c2deb --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/d7d631967807476485aa26ba0c39a992.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/d912a92ed03d4f818661a1636b8a6f9b.xml b/common/test/data/manual-testing-complete/sequential/d912a92ed03d4f818661a1636b8a6f9b.xml new file mode 100644 index 0000000000..c90e36d75c --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/d912a92ed03d4f818661a1636b8a6f9b.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/dc2b88afd57241f9bcd2dcbd03c6c2f3.xml b/common/test/data/manual-testing-complete/sequential/dc2b88afd57241f9bcd2dcbd03c6c2f3.xml new file mode 100644 index 0000000000..74aae8caa4 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/dc2b88afd57241f9bcd2dcbd03c6c2f3.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/f09502cf408742c2aa3c92705ab1dce7.xml b/common/test/data/manual-testing-complete/sequential/f09502cf408742c2aa3c92705ab1dce7.xml new file mode 100644 index 0000000000..120bf200b8 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/f09502cf408742c2aa3c92705ab1dce7.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/f0e52b8eec5647ffb6013aef62b3d309.xml b/common/test/data/manual-testing-complete/sequential/f0e52b8eec5647ffb6013aef62b3d309.xml new file mode 100644 index 0000000000..9e5efda883 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/f0e52b8eec5647ffb6013aef62b3d309.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/f585fca58e5c4fe8ab231a5f62701de3.xml b/common/test/data/manual-testing-complete/sequential/f585fca58e5c4fe8ab231a5f62701de3.xml new file mode 100644 index 0000000000..7ba184b516 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/f585fca58e5c4fe8ab231a5f62701de3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/f58fd90cbd794cad881692d3b6e5cdbf.xml b/common/test/data/manual-testing-complete/sequential/f58fd90cbd794cad881692d3b6e5cdbf.xml new file mode 100644 index 0000000000..a53cc4f3c7 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/f58fd90cbd794cad881692d3b6e5cdbf.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/sequential/f9372e3b199a4986a46c8d18e094b931.xml b/common/test/data/manual-testing-complete/sequential/f9372e3b199a4986a46c8d18e094b931.xml new file mode 100644 index 0000000000..7d3a1d5f40 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/f9372e3b199a4986a46c8d18e094b931.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/sequential/fbbe37e2980c4f0d96b0b8ac45c0378b.xml b/common/test/data/manual-testing-complete/sequential/fbbe37e2980c4f0d96b0b8ac45c0378b.xml new file mode 100644 index 0000000000..fbcd044de9 --- /dev/null +++ b/common/test/data/manual-testing-complete/sequential/fbbe37e2980c4f0d96b0b8ac45c0378b.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/static/1.pdf b/common/test/data/manual-testing-complete/static/1.pdf new file mode 100644 index 0000000000..ab5db00688 Binary files /dev/null and b/common/test/data/manual-testing-complete/static/1.pdf differ diff --git a/common/test/data/manual-testing-complete/static/Screen Shot 2013-04-16 at 1.43.36 PM.png b/common/test/data/manual-testing-complete/static/Screen Shot 2013-04-16 at 1.43.36 PM.png new file mode 100644 index 0000000000..b85eee2692 Binary files /dev/null and b/common/test/data/manual-testing-complete/static/Screen Shot 2013-04-16 at 1.43.36 PM.png differ diff --git a/common/test/data/manual-testing-complete/static/subs_OEoXaMPEzfM.srt.sjson b/common/test/data/manual-testing-complete/static/subs_OEoXaMPEzfM.srt.sjson new file mode 100644 index 0000000000..7dc7a7c91e --- /dev/null +++ b/common/test/data/manual-testing-complete/static/subs_OEoXaMPEzfM.srt.sjson @@ -0,0 +1,143 @@ +{ + "start": [ + 270, + 2720, + 5430, + 7160, + 10830, + 12880, + 15890, + 19000, + 22070, + 25170, + 27890, + 30590, + 32920, + 36360, + 39630, + 41170, + 42790, + 44590, + 47320, + 50250, + 51880, + 54320, + 57410, + 59160, + 62320, + 65099, + 68430, + 71360, + 73640, + 76580, + 78660, + 81480, + 83940, + 86230, + 88570, + 90520, + 93430, + 95940, + 99090, + 100910, + 103740, + 105610, + 108310, + 111100, + 112360 + ], + "end": [ + 2720, + 5430, + 7160, + 10830, + 12880, + 15890, + 19000, + 22070, + 25170, + 27890, + 30590, + 32920, + 36360, + 39630, + 41170, + 42790, + 44590, + 47320, + 50250, + 51880, + 54320, + 57410, + 59160, + 62320, + 65099, + 68430, + 71360, + 73640, + 76580, + 78660, + 81480, + 83940, + 86230, + 88570, + 90520, + 93430, + 95940, + 99090, + 100910, + 103740, + 105610, + 108310, + 111100, + 112360, + 114220 + ], + "text": [ + "LILA FISHER: Hi, welcome to Edx.", + "I'm Lila Fisher, an Edx fellow helping to put", + "together these courses.", + "As you know, our courses are entirely online.", + "So before we start learning about the subjects that", + "brought you here, let's learn about the tools that you will", + "use to navigate through the course material.", + "Let's start with what is on your screen right now.", + "You are watching a video of me talking.", + "You have several tools associated with these videos.", + "Some of them are standard video buttons, like the play", + "Pause Button on the bottom left.", + "Like most video players, you can see how far you are into", + "this particular video segment and how long the entire video", + "segment is.", + "Something that you might not be used to", + "is the speed option.", + "While you are going through the videos, you can speed up", + "or slow down the video player with these buttons.", + "Go ahead and try that now.", + "Make me talk faster and slower.", + "If you ever get frustrated by the pace of speech, you can", + "adjust it this way.", + "Another great feature is the transcript on the side.", + "This will follow along with everything that I am saying as", + "I am saying it, so you can read along if you like.", + "You can also click on any of the words, and you will notice", + "that the video jumps to that word.", + "The video slider at the bottom of the video will let you", + "navigate through the video quickly.", + "If you ever find the transcript distracting, you", + "can toggle the captioning button in order to make it go", + "away or reappear.", + "Now that you know about the video player, I want to point", + "out the sequence navigator.", + "Right now you're in a lecture sequence, which interweaves", + "many videos and practice exercises.", + "You can see how far you are in a particular sequence by", + "observing which tab you're on.", + "You can navigate directly to any video or exercise by", + "clicking on the appropriate tab.", + "You can also progress to the next element by pressing the", + "Arrow button, or by clicking on the next tab.", + "Try that now.", + "The tutorial will continue in the next video." + ] +} \ No newline at end of file diff --git a/common/test/data/manual-testing-complete/tabs/8e4cce2b4aaf4ba28b1220804619e41f.html b/common/test/data/manual-testing-complete/tabs/8e4cce2b4aaf4ba28b1220804619e41f.html new file mode 100644 index 0000000000..db06449a3c --- /dev/null +++ b/common/test/data/manual-testing-complete/tabs/8e4cce2b4aaf4ba28b1220804619e41f.html @@ -0,0 +1 @@ +

static 463139

\ No newline at end of file diff --git a/common/test/data/manual-testing-complete/vertical/0a1602f0f191422ba5ed727f903627b2.xml b/common/test/data/manual-testing-complete/vertical/0a1602f0f191422ba5ed727f903627b2.xml new file mode 100644 index 0000000000..5e79288fbd --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/0a1602f0f191422ba5ed727f903627b2.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/0b693c2547674645a8afd0be4c57b8b7.xml b/common/test/data/manual-testing-complete/vertical/0b693c2547674645a8afd0be4c57b8b7.xml new file mode 100644 index 0000000000..f8bdfab245 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/0b693c2547674645a8afd0be4c57b8b7.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/manual-testing-complete/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml b/common/test/data/manual-testing-complete/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml new file mode 100644 index 0000000000..42144cfeb2 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/0b73083f132c4ecb8ea24a363efcbc68.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/18b50987e2d84bcca2cfc74ef6b25275.xml b/common/test/data/manual-testing-complete/vertical/18b50987e2d84bcca2cfc74ef6b25275.xml new file mode 100644 index 0000000000..34823d0ceb --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/18b50987e2d84bcca2cfc74ef6b25275.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/193fbc9bb9184ba685d01430cb2025d3.xml b/common/test/data/manual-testing-complete/vertical/193fbc9bb9184ba685d01430cb2025d3.xml new file mode 100644 index 0000000000..c61914e0a4 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/193fbc9bb9184ba685d01430cb2025d3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml b/common/test/data/manual-testing-complete/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml new file mode 100644 index 0000000000..1ad9bcdabc --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/1f17ac7c38b2421b8c6027c3652366c6.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/224cff129b784243a79f08dd7203151c.xml b/common/test/data/manual-testing-complete/vertical/224cff129b784243a79f08dd7203151c.xml new file mode 100644 index 0000000000..07040d1769 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/224cff129b784243a79f08dd7203151c.xml @@ -0,0 +1,3 @@ + + diff --git a/common/test/data/manual-testing-complete/vertical/3a7305c59c254ce9814093f98b913e8a.xml b/common/test/data/manual-testing-complete/vertical/3a7305c59c254ce9814093f98b913e8a.xml new file mode 100644 index 0000000000..d260d6cbdc --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/3a7305c59c254ce9814093f98b913e8a.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/4502126328484ed58c87e7ba3b0fa21d.xml b/common/test/data/manual-testing-complete/vertical/4502126328484ed58c87e7ba3b0fa21d.xml new file mode 100644 index 0000000000..974d81d1ad --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/4502126328484ed58c87e7ba3b0fa21d.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/4aeec80b652c4cc2bf38c248d6440c9f.xml b/common/test/data/manual-testing-complete/vertical/4aeec80b652c4cc2bf38c248d6440c9f.xml new file mode 100644 index 0000000000..6d6be1767d --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/4aeec80b652c4cc2bf38c248d6440c9f.xml @@ -0,0 +1,4 @@ + + + + diff --git a/common/test/data/manual-testing-complete/vertical/50c89b9bf3bc40c2bb723fc7d1c756d1.xml b/common/test/data/manual-testing-complete/vertical/50c89b9bf3bc40c2bb723fc7d1c756d1.xml new file mode 100644 index 0000000000..87da8a8979 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/50c89b9bf3bc40c2bb723fc7d1c756d1.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/53142c50e5284f9798e8e0cab8471528.xml b/common/test/data/manual-testing-complete/vertical/53142c50e5284f9798e8e0cab8471528.xml new file mode 100644 index 0000000000..5d17de072c --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/53142c50e5284f9798e8e0cab8471528.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/536b3582ce354e9da79f157077172bb3.xml b/common/test/data/manual-testing-complete/vertical/536b3582ce354e9da79f157077172bb3.xml new file mode 100644 index 0000000000..abef6523e9 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/536b3582ce354e9da79f157077172bb3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/572f898249da49bc9ee426804302aa24.xml b/common/test/data/manual-testing-complete/vertical/572f898249da49bc9ee426804302aa24.xml new file mode 100644 index 0000000000..37bd577363 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/572f898249da49bc9ee426804302aa24.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml b/common/test/data/manual-testing-complete/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml new file mode 100644 index 0000000000..a34af38eb8 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/5887a034ad17480393c5ebca4b8fd1d4.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/6b1a4d545905465ca491f0115b6e759b.xml b/common/test/data/manual-testing-complete/vertical/6b1a4d545905465ca491f0115b6e759b.xml new file mode 100644 index 0000000000..633db3180a --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/6b1a4d545905465ca491f0115b6e759b.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/6b54ae89dc554f77b4dd94e1d9911df6.xml b/common/test/data/manual-testing-complete/vertical/6b54ae89dc554f77b4dd94e1d9911df6.xml new file mode 100644 index 0000000000..11891b6a20 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/6b54ae89dc554f77b4dd94e1d9911df6.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/6cb018f4cc884e98b9df621b4cc54a29.xml b/common/test/data/manual-testing-complete/vertical/6cb018f4cc884e98b9df621b4cc54a29.xml new file mode 100644 index 0000000000..9c4b4a1cfe --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/6cb018f4cc884e98b9df621b4cc54a29.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/81323bb6c1cd4b83b8cd1e9b8fb119a7.xml b/common/test/data/manual-testing-complete/vertical/81323bb6c1cd4b83b8cd1e9b8fb119a7.xml new file mode 100644 index 0000000000..3cfa07b8c5 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/81323bb6c1cd4b83b8cd1e9b8fb119a7.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/856a9709ac974c92b539710bb64fb4c5.xml b/common/test/data/manual-testing-complete/vertical/856a9709ac974c92b539710bb64fb4c5.xml new file mode 100644 index 0000000000..0856a7f82b --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/856a9709ac974c92b539710bb64fb4c5.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/93113ad02cac43659c0e1833880408f3.xml b/common/test/data/manual-testing-complete/vertical/93113ad02cac43659c0e1833880408f3.xml new file mode 100644 index 0000000000..3258e5bd90 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/93113ad02cac43659c0e1833880408f3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/999c7e94329144cdb844aec9671fc8ca.xml b/common/test/data/manual-testing-complete/vertical/999c7e94329144cdb844aec9671fc8ca.xml new file mode 100644 index 0000000000..c86200a7e2 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/999c7e94329144cdb844aec9671fc8ca.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/99ab6b79e2b6426f9bc7e07e8540a655.xml b/common/test/data/manual-testing-complete/vertical/99ab6b79e2b6426f9bc7e07e8540a655.xml new file mode 100644 index 0000000000..31090c9895 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/99ab6b79e2b6426f9bc7e07e8540a655.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/a99ab4f608de41e9927d281dcfbd4343.xml b/common/test/data/manual-testing-complete/vertical/a99ab4f608de41e9927d281dcfbd4343.xml new file mode 100644 index 0000000000..44ee10968b --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/a99ab4f608de41e9927d281dcfbd4343.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/b34ef5e4257b4a34a60c2679aeeb5455.xml b/common/test/data/manual-testing-complete/vertical/b34ef5e4257b4a34a60c2679aeeb5455.xml new file mode 100644 index 0000000000..f157dcad32 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/b34ef5e4257b4a34a60c2679aeeb5455.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/bcb995ca53934a7b8aee27f81d96d189.xml b/common/test/data/manual-testing-complete/vertical/bcb995ca53934a7b8aee27f81d96d189.xml new file mode 100644 index 0000000000..97463568b8 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/bcb995ca53934a7b8aee27f81d96d189.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/be87d2061b8f41be87293fcc643514c7.xml b/common/test/data/manual-testing-complete/vertical/be87d2061b8f41be87293fcc643514c7.xml new file mode 100644 index 0000000000..743e2e2a79 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/be87d2061b8f41be87293fcc643514c7.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/c641d8fe821440bea1781287d05fdc82.xml b/common/test/data/manual-testing-complete/vertical/c641d8fe821440bea1781287d05fdc82.xml new file mode 100644 index 0000000000..1e592847ad --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/c641d8fe821440bea1781287d05fdc82.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/c7c39a80da5f4ac4935ab83790528063.xml b/common/test/data/manual-testing-complete/vertical/c7c39a80da5f4ac4935ab83790528063.xml new file mode 100644 index 0000000000..9613a1fa6b --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/c7c39a80da5f4ac4935ab83790528063.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/c87ff358615846b08b85f66ebce94fb3.xml b/common/test/data/manual-testing-complete/vertical/c87ff358615846b08b85f66ebce94fb3.xml new file mode 100644 index 0000000000..db491fd838 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/c87ff358615846b08b85f66ebce94fb3.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/cd6b719c0f9c46e7abd2d44c37d49cd8.xml b/common/test/data/manual-testing-complete/vertical/cd6b719c0f9c46e7abd2d44c37d49cd8.xml new file mode 100644 index 0000000000..ee18a9951e --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/cd6b719c0f9c46e7abd2d44c37d49cd8.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/da4f07aceaf542f5b1807c779a719067.xml b/common/test/data/manual-testing-complete/vertical/da4f07aceaf542f5b1807c779a719067.xml new file mode 100644 index 0000000000..5f5766c6ba --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/da4f07aceaf542f5b1807c779a719067.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/ddd289f35194456eaa470a3fd0d08ca2.xml b/common/test/data/manual-testing-complete/vertical/ddd289f35194456eaa470a3fd0d08ca2.xml new file mode 100644 index 0000000000..92b8e86dae --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/ddd289f35194456eaa470a3fd0d08ca2.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/de8fb6b7e0904de3a39db9d4bfaab6a2.xml b/common/test/data/manual-testing-complete/vertical/de8fb6b7e0904de3a39db9d4bfaab6a2.xml new file mode 100644 index 0000000000..7d3f90395d --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/de8fb6b7e0904de3a39db9d4bfaab6a2.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/e34798bf546a4178ab76afe3a5f729af.xml b/common/test/data/manual-testing-complete/vertical/e34798bf546a4178ab76afe3a5f729af.xml new file mode 100644 index 0000000000..8147a41ae3 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/e34798bf546a4178ab76afe3a5f729af.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/e81c7ddcf5434387a2a6163ca973520c.xml b/common/test/data/manual-testing-complete/vertical/e81c7ddcf5434387a2a6163ca973520c.xml new file mode 100644 index 0000000000..1e78ad0509 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/e81c7ddcf5434387a2a6163ca973520c.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/e8a308821e204375905bedc227fa769f.xml b/common/test/data/manual-testing-complete/vertical/e8a308821e204375905bedc227fa769f.xml new file mode 100644 index 0000000000..a27a6879c6 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/e8a308821e204375905bedc227fa769f.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/e9c213fb60134b93a3b1b4ba882cb1a7.xml b/common/test/data/manual-testing-complete/vertical/e9c213fb60134b93a3b1b4ba882cb1a7.xml new file mode 100644 index 0000000000..e96dcc7f0c --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/e9c213fb60134b93a3b1b4ba882cb1a7.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/ec70919ea9c24ed192e37e7d022d4133.xml b/common/test/data/manual-testing-complete/vertical/ec70919ea9c24ed192e37e7d022d4133.xml new file mode 100644 index 0000000000..0fc5148b4a --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/ec70919ea9c24ed192e37e7d022d4133.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/vertical/f3387cc263aa4e2e9070b6954a9c1b90.xml b/common/test/data/manual-testing-complete/vertical/f3387cc263aa4e2e9070b6954a9c1b90.xml new file mode 100644 index 0000000000..097d4b0e93 --- /dev/null +++ b/common/test/data/manual-testing-complete/vertical/f3387cc263aa4e2e9070b6954a9c1b90.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/manual-testing-complete/video/37ec61cf011c429db8cb5f49b47681f7.xml b/common/test/data/manual-testing-complete/video/37ec61cf011c429db8cb5f49b47681f7.xml new file mode 100644 index 0000000000..70b1c66bca --- /dev/null +++ b/common/test/data/manual-testing-complete/video/37ec61cf011c429db8cb5f49b47681f7.xml @@ -0,0 +1 @@ +