Commit 6728f16a by Will Daly

Merge branch 'feature/zoldak/refactor-factories' into feature/will/speed_up_lettuce_tests

Conflicts:
	lms/djangoapps/courseware/features/problems.py
parents 2fc96d5f 23364d8b
...@@ -7,8 +7,6 @@ from selenium.common.exceptions import WebDriverException, StaleElementReference ...@@ -7,8 +7,6 @@ from selenium.common.exceptions import WebDriverException, StaleElementReference
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from terrain.factories import UserFactory, RegistrationFactory, UserProfileFactory
from terrain.factories import CourseFactory, GroupFactory
from xmodule.modulestore.django import _MODULESTORES, modulestore from xmodule.modulestore.django import _MODULESTORES, modulestore
from xmodule.templates import update_templates from xmodule.templates import update_templates
from auth.authz import get_user_by_email from auth.authz import get_user_by_email
...@@ -61,7 +59,7 @@ def create_studio_user( ...@@ -61,7 +59,7 @@ def create_studio_user(
email='robot+studio@edx.org', email='robot+studio@edx.org',
password='test', password='test',
is_staff=False): is_staff=False):
studio_user = UserFactory.build( studio_user = world.UserFactory.build(
username=uname, username=uname,
email=email, email=email,
password=password, password=password,
...@@ -69,11 +67,11 @@ def create_studio_user( ...@@ -69,11 +67,11 @@ def create_studio_user(
studio_user.set_password(password) studio_user.set_password(password)
studio_user.save() studio_user.save()
registration = RegistrationFactory(user=studio_user) registration = world.RegistrationFactory(user=studio_user)
registration.register(studio_user) registration.register(studio_user)
registration.activate() registration.activate()
user_profile = UserProfileFactory(user=studio_user) user_profile = world.UserProfileFactory(user=studio_user)
def flush_xmodule_store(): def flush_xmodule_store():
...@@ -175,11 +173,11 @@ def log_into_studio( ...@@ -175,11 +173,11 @@ def log_into_studio(
def create_a_course(): def create_a_course():
c = CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') c = world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
# Add the user to the instructor group of the course # Add the user to the instructor group of the course
# so they will have the permissions to see it in studio # so they will have the permissions to see it in studio
g = GroupFactory.create(name='instructor_MITx/999/Robot_Super_Course') g = world.GroupFactory.create(name='instructor_MITx/999/Robot_Super_Course')
u = get_user_by_email('robot+studio@edx.org') u = get_user_by_email('robot+studio@edx.org')
u.groups.add(g) u.groups.add(g)
u.save() u.save()
......
import factory
from student.models import User, UserProfile, Registration
from datetime import datetime
import uuid
class UserProfileFactory(factory.Factory):
FACTORY_FOR = UserProfile
user = None
name = 'Robot Studio'
courseware = 'course.xml'
class RegistrationFactory(factory.Factory):
FACTORY_FOR = Registration
user = None
activation_key = uuid.uuid4().hex
class UserFactory(factory.Factory):
FACTORY_FOR = User
username = 'robot-studio'
email = 'robot+studio@edx.org'
password = 'test'
first_name = 'Robot'
last_name = 'Studio'
is_staff = False
is_active = True
is_superuser = False
last_login = datetime.now()
date_joined = datetime.now()
from lettuce import world, step from lettuce import world, step
from terrain.factories import *
from common import * from common import *
from nose.tools import assert_true, assert_false, assert_equal from nose.tools import assert_true, assert_false, assert_equal
...@@ -10,15 +9,15 @@ logger = getLogger(__name__) ...@@ -10,15 +9,15 @@ logger = getLogger(__name__)
@step(u'I have a course with no sections$') @step(u'I have a course with no sections$')
def have_a_course(step): def have_a_course(step):
clear_courses() clear_courses()
course = CourseFactory.create() course = world.CourseFactory.create()
@step(u'I have a course with 1 section$') @step(u'I have a course with 1 section$')
def have_a_course_with_1_section(step): def have_a_course_with_1_section(step):
clear_courses() clear_courses()
course = CourseFactory.create() course = world.CourseFactory.create()
section = ItemFactory.create(parent_location=course.location) section = world.ItemFactory.create(parent_location=course.location)
subsection1 = ItemFactory.create( subsection1 = world.ItemFactory.create(
parent_location=section.location, parent_location=section.location,
template='i4x://edx/templates/sequential/Empty', template='i4x://edx/templates/sequential/Empty',
display_name='Subsection One',) display_name='Subsection One',)
...@@ -27,20 +26,20 @@ def have_a_course_with_1_section(step): ...@@ -27,20 +26,20 @@ def have_a_course_with_1_section(step):
@step(u'I have a course with multiple sections$') @step(u'I have a course with multiple sections$')
def have_a_course_with_two_sections(step): def have_a_course_with_two_sections(step):
clear_courses() clear_courses()
course = CourseFactory.create() course = world.CourseFactory.create()
section = ItemFactory.create(parent_location=course.location) section = world.ItemFactory.create(parent_location=course.location)
subsection1 = ItemFactory.create( subsection1 = world.ItemFactory.create(
parent_location=section.location, parent_location=section.location,
template='i4x://edx/templates/sequential/Empty', template='i4x://edx/templates/sequential/Empty',
display_name='Subsection One',) display_name='Subsection One',)
section2 = ItemFactory.create( section2 = world.ItemFactory.create(
parent_location=course.location, parent_location=course.location,
display_name='Section Two',) display_name='Section Two',)
subsection2 = ItemFactory.create( subsection2 = world.ItemFactory.create(
parent_location=section2.location, parent_location=section2.location,
template='i4x://edx/templates/sequential/Empty', template='i4x://edx/templates/sequential/Empty',
display_name='Subsection Alpha',) display_name='Subsection Alpha',)
subsection3 = ItemFactory.create( subsection3 = world.ItemFactory.create(
parent_location=section2.location, parent_location=section2.location,
template='i4x://edx/templates/sequential/Empty', template='i4x://edx/templates/sequential/Empty',
display_name='Subsection Beta',) display_name='Subsection Beta',)
......
from student.models import (User, UserProfile, Registration,
CourseEnrollmentAllowed, CourseEnrollment)
from django.contrib.auth.models import Group
from datetime import datetime
from factory import Factory, SubFactory
from uuid import uuid4
class GroupFactory(Factory):
FACTORY_FOR = Group
name = 'staff_MITx/999/Robot_Super_Course'
class UserProfileFactory(Factory):
FACTORY_FOR = UserProfile
user = None
name = 'Robot Test'
level_of_education = None
gender = 'm'
mailing_address = None
goals = 'World domination'
class RegistrationFactory(Factory):
FACTORY_FOR = Registration
user = None
activation_key = uuid4().hex
class UserFactory(Factory):
FACTORY_FOR = User
username = 'robot'
email = 'robot+test@edx.org'
password = 'test'
first_name = 'Robot'
last_name = 'Test'
is_staff = False
is_active = True
is_superuser = False
last_login = datetime(2012, 1, 1)
date_joined = datetime(2011, 1, 1)
class CourseEnrollmentFactory(Factory):
FACTORY_FOR = CourseEnrollment
user = SubFactory(UserFactory)
course_id = 'edX/toy/2012_Fall'
class CourseEnrollmentAllowedFactory(Factory):
FACTORY_FOR = CourseEnrollmentAllowed
email = 'test@edx.org'
course_id = 'edX/test/2012_Fall'
...@@ -9,8 +9,8 @@ import logging ...@@ -9,8 +9,8 @@ import logging
from django.test import TestCase from django.test import TestCase
from mock import Mock from mock import Mock
from .models import unique_id_for_user from student.models import unique_id_for_user
from .views import process_survey_link, _cert_info from student.views import process_survey_link, _cert_info
COURSE_1 = 'edX/toy/2012_Fall' COURSE_1 = 'edX/toy/2012_Fall'
COURSE_2 = 'edx/full/6.002_Spring_2012' COURSE_2 = 'edx/full/6.002_Spring_2012'
......
from lettuce import before, after, world from lettuce import before, after, world
from splinter.browser import Browser from splinter.browser import Browser
from logging import getLogger from logging import getLogger
import time
# Let the LMS and CMS do their one-time setup # Let the LMS and CMS do their one-time setup
# For example, setting up mongo caches # For example, setting up mongo caches
...@@ -16,6 +15,9 @@ from django.core.management import call_command ...@@ -16,6 +15,9 @@ from django.core.management import call_command
@before.harvest @before.harvest
def initial_setup(server): def initial_setup(server):
'''
Launch the browser once before executing the tests
'''
# Launch the browser app (choose one of these below) # Launch the browser app (choose one of these below)
world.browser = Browser('chrome') world.browser = Browser('chrome')
# world.browser = Browser('phantomjs') # world.browser = Browser('phantomjs')
...@@ -24,14 +26,18 @@ def initial_setup(server): ...@@ -24,14 +26,18 @@ def initial_setup(server):
@before.each_scenario @before.each_scenario
def reset_data(scenario): def reset_data(scenario):
# Clean out the django test database defined in the '''
# envs/acceptance.py file: mitx_all/db/test_mitx.db Clean out the django test database defined in the
envs/acceptance.py file: mitx_all/db/test_mitx.db
'''
logger.debug("Flushing the test database...") logger.debug("Flushing the test database...")
call_command('flush', interactive=False) call_command('flush', interactive=False)
@after.all @after.all
def teardown_browser(total): def teardown_browser(total):
# Quit firefox '''
Quit the browser after executing the tests
'''
world.browser.quit() world.browser.quit()
pass pass
from student.models import User, UserProfile, Registration '''
from django.contrib.auth.models import Group Factories are defined in other modules and absorbed here into the
from datetime import datetime lettuce world so that they can be used by both unit tests
from factory import Factory and integration / BDD tests.
from xmodule.modulestore import Location '''
from xmodule.modulestore.django import modulestore import student.tests.factories as sf
from time import gmtime import xmodule.modulestore.tests.factories as xf
from uuid import uuid4 from lettuce import world
from xmodule.timeparse import stringify_time
from xmodule.modulestore.inheritance import own_metadata
@world.absorb
class UserFactory(sf.UserFactory):
class GroupFactory(Factory):
FACTORY_FOR = Group
name = 'staff_MITx/999/Robot_Super_Course'
class UserProfileFactory(Factory):
FACTORY_FOR = UserProfile
user = None
name = 'Robot Test'
level_of_education = None
gender = 'm'
mailing_address = None
goals = 'World domination'
class RegistrationFactory(Factory):
FACTORY_FOR = Registration
user = None
activation_key = uuid4().hex
class UserFactory(Factory):
FACTORY_FOR = User
username = 'robot'
email = 'robot+test@edx.org'
password = 'test'
first_name = 'Robot'
last_name = 'Test'
is_staff = False
is_active = True
is_superuser = False
last_login = datetime(2012, 1, 1)
date_joined = datetime(2011, 1, 1)
def XMODULE_COURSE_CREATION(class_to_create, **kwargs):
return XModuleCourseFactory._create(class_to_create, **kwargs)
def XMODULE_ITEM_CREATION(class_to_create, **kwargs):
return XModuleItemFactory._create(class_to_create, **kwargs)
class XModuleCourseFactory(Factory):
""" """
Factory for XModule courses. User account for lms / cms
""" """
ABSTRACT_FACTORY = True
_creation_function = (XMODULE_COURSE_CREATION,)
@classmethod
def _create(cls, target_class, *args, **kwargs):
template = Location('i4x', 'edx', 'templates', 'course', 'Empty')
org = kwargs.get('org')
number = kwargs.get('number')
display_name = kwargs.get('display_name')
location = Location('i4x', org, number,
'course', Location.clean(display_name))
store = modulestore('direct')
# Write the data to the mongo datastore
new_course = store.clone_item(template, location)
# This metadata code was copied from cms/djangoapps/contentstore/views.py
if display_name is not None:
new_course.display_name = display_name
new_course.lms.start = gmtime()
new_course.tabs = [{"type": "courseware"},
{"type": "course_info", "name": "Course Info"},
{"type": "discussion", "name": "Discussion"},
{"type": "wiki", "name": "Wiki"},
{"type": "progress", "name": "Progress"}]
# Update the data in the mongo datastore
store.update_metadata(new_course.location.url(), own_metadata(new_course))
return new_course
class Course:
pass pass
class CourseFactory(XModuleCourseFactory): @world.absorb
FACTORY_FOR = Course class UserProfileFactory(sf.UserProfileFactory):
template = 'i4x://edx/templates/course/Empty'
org = 'MITx'
number = '999'
display_name = 'Robot Super Course'
class XModuleItemFactory(Factory):
""" """
Factory for XModule items. Demographics etc for the User
""" """
pass
ABSTRACT_FACTORY = True
_creation_function = (XMODULE_ITEM_CREATION,)
@classmethod
def _create(cls, target_class, *args, **kwargs):
"""
Uses *kwargs*:
*parent_location* (required): the location of the parent module
(e.g. the parent course or section)
*template* (required): the template to create the item from
(e.g. i4x://templates/section/Empty)
*data* (optional): the data for the item
(e.g. XML problem definition for a problem item)
*display_name* (optional): the display name of the item
*metadata* (optional): dictionary of metadata attributes
*target_class* is ignored
"""
DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info']
parent_location = Location(kwargs.get('parent_location'))
template = Location(kwargs.get('template'))
data = kwargs.get('data')
display_name = kwargs.get('display_name')
metadata = kwargs.get('metadata', {})
store = modulestore('direct')
# This code was based off that in cms/djangoapps/contentstore/views.py
parent = store.get_item(parent_location)
# If a display name is set, use that
dest_name = display_name.replace(" ", "_") if display_name is not None else uuid4().hex
dest_location = parent_location._replace(category=template.category,
name=dest_name)
new_item = store.clone_item(template, dest_location)
# replace the display name with an optional parameter passed in from the caller @world.absorb
if display_name is not None: class RegistrationFactory(sf.RegistrationFactory):
new_item.display_name = display_name """
Activation key for registering the user account
"""
pass
# Add additional metadata or override current metadata
item_metadata = own_metadata(new_item)
item_metadata.update(metadata)
store.update_metadata(new_item.location.url(), item_metadata)
# replace the data with the optional *data* parameter @world.absorb
if data is not None: class GroupFactory(sf.GroupFactory):
store.update_item(new_item.location, data) """
Groups for user permissions for courses
"""
pass
if new_item.location.category not in DETACHED_CATEGORIES:
store.update_children(parent_location, parent.children + [new_item.location.url()])
return new_item @world.absorb
class CourseEnrollmentAllowedFactory(sf.CourseEnrollmentAllowed):
"""
Users allowed to enroll in the course outside of the usual window
"""
pass
class Item: @world.absorb
class CourseFactory(xf.CourseFactory):
"""
Courseware courses
"""
pass pass
class ItemFactory(XModuleItemFactory): @world.absorb
FACTORY_FOR = Item class ItemFactory(xf.ItemFactory):
"""
parent_location = 'i4x://MITx/999/course/Robot_Super_Course' Everything included inside a course
template = 'i4x://edx/templates/chapter/Empty' """
display_name = 'Section One' pass
...@@ -125,11 +125,11 @@ def create_user(uname): ...@@ -125,11 +125,11 @@ def create_user(uname):
portal_user.set_password('test') portal_user.set_password('test')
portal_user.save() portal_user.save()
registration = RegistrationFactory(user=portal_user) registration = world.RegistrationFactory(user=portal_user)
registration.register(portal_user) registration.register(portal_user)
registration.activate() registration.activate()
user_profile = UserProfileFactory(user=portal_user) user_profile = world.UserProfileFactory(user=portal_user)
@world.absorb @world.absorb
......
...@@ -25,8 +25,7 @@ class XModuleCourseFactory(Factory): ...@@ -25,8 +25,7 @@ class XModuleCourseFactory(Factory):
@classmethod @classmethod
def _create(cls, target_class, *args, **kwargs): def _create(cls, target_class, *args, **kwargs):
# This logic was taken from the create_new_course method in
# cms/djangoapps/contentstore/views.py
template = Location('i4x', 'edx', 'templates', 'course', 'Empty') template = Location('i4x', 'edx', 'templates', 'course', 'Empty')
org = kwargs.get('org') org = kwargs.get('org')
number = kwargs.get('number') number = kwargs.get('number')
...@@ -43,8 +42,7 @@ class XModuleCourseFactory(Factory): ...@@ -43,8 +42,7 @@ class XModuleCourseFactory(Factory):
if display_name is not None: if display_name is not None:
new_course.display_name = display_name new_course.display_name = display_name
new_course.start = gmtime() new_course.lms.start = gmtime()
new_course.tabs = [{"type": "courseware"}, new_course.tabs = [{"type": "courseware"},
{"type": "course_info", "name": "Course Info"}, {"type": "course_info", "name": "Course Info"},
{"type": "discussion", "name": "Discussion"}, {"type": "discussion", "name": "Discussion"},
...@@ -81,21 +79,41 @@ class XModuleItemFactory(Factory): ...@@ -81,21 +79,41 @@ class XModuleItemFactory(Factory):
@classmethod @classmethod
def _create(cls, target_class, *args, **kwargs): def _create(cls, target_class, *args, **kwargs):
""" """
kwargs must include parent_location, template. Can contain display_name Uses *kwargs*:
target_class is ignored
*parent_location* (required): the location of the parent module
(e.g. the parent course or section)
*template* (required): the template to create the item from
(e.g. i4x://templates/section/Empty)
*data* (optional): the data for the item
(e.g. XML problem definition for a problem item)
*display_name* (optional): the display name of the item
*metadata* (optional): dictionary of metadata attributes
*target_class* is ignored
""" """
DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info'] DETACHED_CATEGORIES = ['about', 'static_tab', 'course_info']
parent_location = Location(kwargs.get('parent_location')) parent_location = Location(kwargs.get('parent_location'))
template = Location(kwargs.get('template')) template = Location(kwargs.get('template'))
data = kwargs.get('data')
display_name = kwargs.get('display_name') display_name = kwargs.get('display_name')
metadata = kwargs.get('metadata', {})
store = modulestore('direct') store = modulestore('direct')
# This code was based off that in cms/djangoapps/contentstore/views.py # This code was based off that in cms/djangoapps/contentstore/views.py
parent = store.get_item(parent_location) parent = store.get_item(parent_location)
dest_location = parent_location._replace(category=template.category, name=uuid4().hex)
# If a display name is set, use that
dest_name = display_name.replace(" ", "_") if display_name is not None else uuid4().hex
dest_location = parent_location._replace(category=template.category,
name=dest_name)
new_item = store.clone_item(template, dest_location) new_item = store.clone_item(template, dest_location)
...@@ -103,7 +121,14 @@ class XModuleItemFactory(Factory): ...@@ -103,7 +121,14 @@ class XModuleItemFactory(Factory):
if display_name is not None: if display_name is not None:
new_item.display_name = display_name new_item.display_name = display_name
store.update_metadata(new_item.location.url(), own_metadata(new_item)) # Add additional metadata or override current metadata
item_metadata = own_metadata(new_item)
item_metadata.update(metadata)
store.update_metadata(new_item.location.url(), item_metadata)
# replace the data with the optional *data* parameter
if data is not None:
store.update_item(new_item.location, data)
if new_item.location.category not in DETACHED_CATEGORIES: if new_item.location.category not in DETACHED_CATEGORIES:
store.update_children(parent_location, parent.children + [new_item.location.url()]) store.update_children(parent_location, parent.children + [new_item.location.url()])
......
from lettuce import world, step from lettuce import world, step
from django.core.management import call_command
from nose.tools import assert_equals, assert_in from nose.tools import assert_equals, assert_in
from lettuce.django import django_url from lettuce.django import django_url
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from student.models import CourseEnrollment from student.models import CourseEnrollment
from terrain.factories import CourseFactory, ItemFactory
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.modulestore.django import _MODULESTORES, modulestore from xmodule.modulestore.django import _MODULESTORES, modulestore
from xmodule.templates import update_templates from xmodule.templates import update_templates
...@@ -102,17 +99,17 @@ def create_course(step, course): ...@@ -102,17 +99,17 @@ def create_course(step, course):
# Create the course # Create the course
# We always use the same org and display name, # We always use the same org and display name,
# but vary the course identifier (e.g. 600x or 191x) # but vary the course identifier (e.g. 600x or 191x)
course = CourseFactory.create(org=TEST_COURSE_ORG, course = world.CourseFactory.create(org=TEST_COURSE_ORG,
number=course, number=course,
display_name=TEST_COURSE_NAME) display_name=TEST_COURSE_NAME)
# Add a section to the course to contain problems # Add a section to the course to contain problems
section = ItemFactory.create(parent_location=course.location, section = world.ItemFactory.create(parent_location=course.location,
display_name=TEST_SECTION_NAME) display_name=TEST_SECTION_NAME)
problem_section = ItemFactory.create(parent_location=section.location, problem_section = world.ItemFactory.create(parent_location=section.location,
template='i4x://edx/templates/sequential/Empty', template='i4x://edx/templates/sequential/Empty',
display_name=TEST_SECTION_NAME) display_name=TEST_SECTION_NAME)
@step(u'I am registered for the course "([^"]*)"$') @step(u'I am registered for the course "([^"]*)"$')
...@@ -125,6 +122,7 @@ def i_am_registered_for_the_course(step, course): ...@@ -125,6 +122,7 @@ def i_am_registered_for_the_course(step, course):
u = User.objects.get(username='robot') u = User.objects.get(username='robot')
# If the user is not already enrolled, enroll the user. # If the user is not already enrolled, enroll the user.
# TODO: change to factory
CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(course)) CourseEnrollment.objects.get_or_create(user=u, course_id=course_id(course))
world.log_in('robot', 'test') world.log_in('robot', 'test')
...@@ -132,9 +130,9 @@ def i_am_registered_for_the_course(step, course): ...@@ -132,9 +130,9 @@ def i_am_registered_for_the_course(step, course):
@step(u'The course "([^"]*)" has extra tab "([^"]*)"$') @step(u'The course "([^"]*)" has extra tab "([^"]*)"$')
def add_tab_to_course(step, course, extra_tab_name): def add_tab_to_course(step, course, extra_tab_name):
section_item = ItemFactory.create(parent_location=course_location(course), section_item = world.ItemFactory.create(parent_location=course_location(course),
template="i4x://edx/templates/static_tab/Empty", template="i4x://edx/templates/static_tab/Empty",
display_name=str(extra_tab_name)) display_name=str(extra_tab_name))
@step(u'I am an edX user$') @step(u'I am an edX user$')
...@@ -162,7 +160,7 @@ def flush_xmodule_store(): ...@@ -162,7 +160,7 @@ def flush_xmodule_store():
def course_id(course_num): def course_id(course_num):
return "%s/%s/%s" % (TEST_COURSE_ORG, course_num, return "%s/%s/%s" % (TEST_COURSE_ORG, course_num,
TEST_COURSE_NAME.replace(" ", "_")) TEST_COURSE_NAME.replace(" ", "_"))
def course_location(course_num): def course_location(course_num):
......
...@@ -83,13 +83,13 @@ def get_courseware_with_tabs(course_id): ...@@ -83,13 +83,13 @@ def get_courseware_with_tabs(course_id):
course = get_course_by_id(course_id) course = get_course_by_id(course_id)
chapters = [chapter for chapter in course.get_children() if not chapter.lms.hide_from_toc] chapters = [chapter for chapter in course.get_children() if not chapter.lms.hide_from_toc]
courseware = [{'chapter_name': c.display_name_with_default, courseware = [{'chapter_name': c.display_name_with_default,
'sections': [{'section_name': s.display_name_with_default, 'sections': [{'section_name': s.display_name_with_default,
'clickable_tab_count': len(s.get_children()) if (type(s) == seq_module.SequenceDescriptor) else 0, 'clickable_tab_count': len(s.get_children()) if (type(s) == seq_module.SequenceDescriptor) else 0,
'tabs': [{'children_count': len(t.get_children()) if (type(t) == vertical_module.VerticalDescriptor) else 0, 'tabs': [{'children_count': len(t.get_children()) if (type(t) == vertical_module.VerticalDescriptor) else 0,
'class': t.__class__.__name__} 'class': t.__class__.__name__}
for t in s.get_children()]} for t in s.get_children()]}
for s in c.get_children() if not s.lms.hide_from_toc]} for s in c.get_children() if not s.lms.hide_from_toc]}
for c in chapters] for c in chapters]
return courseware return courseware
...@@ -168,7 +168,6 @@ def process_section(element, num_tabs=0): ...@@ -168,7 +168,6 @@ def process_section(element, num_tabs=0):
assert False, "Class for element not recognized!!" assert False, "Class for element not recognized!!"
def process_problem(element, problem_id): def process_problem(element, problem_id):
''' '''
Process problem attempts to Process problem attempts to
......
...@@ -4,12 +4,11 @@ import random ...@@ -4,12 +4,11 @@ import random
import textwrap import textwrap
import time import time
from common import i_am_registered_for_the_course, TEST_SECTION_NAME, section_location from common import i_am_registered_for_the_course, TEST_SECTION_NAME, section_location
from terrain.factories import ItemFactory
from capa.tests.response_xml_factory import OptionResponseXMLFactory, \ from capa.tests.response_xml_factory import OptionResponseXMLFactory, \
ChoiceResponseXMLFactory, MultipleChoiceResponseXMLFactory, \ ChoiceResponseXMLFactory, MultipleChoiceResponseXMLFactory, \
StringResponseXMLFactory, NumericalResponseXMLFactory, \ StringResponseXMLFactory, NumericalResponseXMLFactory, \
FormulaResponseXMLFactory, CustomResponseXMLFactory, \ FormulaResponseXMLFactory, CustomResponseXMLFactory, \
CodeResponseXMLFactory CodeResponseXMLFactory
# Factories from capa.tests.response_xml_factory that we will use # Factories from capa.tests.response_xml_factory that we will use
# to generate the problem XML, with the keyword args used to configure # to generate the problem XML, with the keyword args used to configure
...@@ -99,11 +98,11 @@ def add_problem_to_course(course, problem_type): ...@@ -99,11 +98,11 @@ def add_problem_to_course(course, problem_type):
# Create a problem item using our generated XML # Create a problem item using our generated XML
# We set rerandomize=always in the metadata so that the "Reset" button # We set rerandomize=always in the metadata so that the "Reset" button
# will appear. # will appear.
problem_item = ItemFactory.create(parent_location=section_location(course), problem_item = world.ItemFactory.create(parent_location=section_location(course),
template="i4x://edx/templates/problem/Blank_Common_Problem", template="i4x://edx/templates/problem/Blank_Common_Problem",
display_name=str(problem_type), display_name=str(problem_type),
data=problem_xml, data=problem_xml,
metadata={'rerandomize': 'always'}) metadata={'rerandomize': 'always'})
@step(u'I am viewing a "([^"]*)" problem') @step(u'I am viewing a "([^"]*)" problem')
...@@ -275,7 +274,6 @@ def assert_answer_mark(step, problem_type, correctness): ...@@ -275,7 +274,6 @@ def assert_answer_mark(step, problem_type, correctness):
# Expect that we found the expected selector # Expect that we found the expected selector
assert(has_expected) assert(has_expected)
def inputfield(problem_type, choice=None, input_num=1): def inputfield(problem_type, choice=None, input_num=1):
""" Return the <input> element for *problem_type*. """ Return the <input> element for *problem_type*.
For example, if problem_type is 'string', return For example, if problem_type is 'string', return
...@@ -285,7 +283,7 @@ def inputfield(problem_type, choice=None, input_num=1): ...@@ -285,7 +283,7 @@ def inputfield(problem_type, choice=None, input_num=1):
of checkboxes. """ of checkboxes. """
sel = ("input#input_i4x-edx-model_course-problem-%s_2_%s" % sel = ("input#input_i4x-edx-model_course-problem-%s_2_%s" %
(problem_type.replace(" ", "_"), str(input_num))) (problem_type.replace(" ", "_"), str(input_num)))
if choice is not None: if choice is not None:
base = "_choice_" if problem_type == "multiple choice" else "_" base = "_choice_" if problem_type == "multiple choice" else "_"
......
...@@ -81,7 +81,7 @@ def browse_course(course_id): ...@@ -81,7 +81,7 @@ def browse_course(course_id):
num_rendered_sections = len(rendered_sections) num_rendered_sections = len(rendered_sections)
msg = ('%d sections expected, %d sections found on page, %s - %d - %s' % msg = ('%d sections expected, %d sections found on page, %s - %d - %s' %
(num_sections, num_rendered_sections, course_id, chapter_it, chapters[chapter_it]['chapter_name'])) (num_sections, num_rendered_sections, course_id, chapter_it, chapters[chapter_it]['chapter_name']))
#logger.debug(msg) #logger.debug(msg)
assert num_sections == num_rendered_sections, msg assert num_sections == num_rendered_sections, msg
...@@ -112,7 +112,7 @@ def browse_course(course_id): ...@@ -112,7 +112,7 @@ def browse_course(course_id):
num_rendered_tabs = 0 num_rendered_tabs = 0
msg = ('%d tabs expected, %d tabs found, %s - %d - %s' % msg = ('%d tabs expected, %d tabs found, %s - %d - %s' %
(num_tabs, num_rendered_tabs, course_id, section_it, sections[section_it]['section_name'])) (num_tabs, num_rendered_tabs, course_id, section_it, sections[section_it]['section_name']))
#logger.debug(msg) #logger.debug(msg)
# Save the HTML to a file for later comparison # Save the HTML to a file for later comparison
...@@ -137,7 +137,7 @@ def browse_course(course_id): ...@@ -137,7 +137,7 @@ def browse_course(course_id):
rendered_items = world.browser.find_by_css('div#seq_content > section > ol > li > section') rendered_items = world.browser.find_by_css('div#seq_content > section > ol > li > section')
num_rendered_items = len(rendered_items) num_rendered_items = len(rendered_items)
msg = ('%d items expected, %d items found, %s - %d - %s - tab %d' % msg = ('%d items expected, %d items found, %s - %d - %s - tab %d' %
(tab_children, num_rendered_items, course_id, section_it, sections[section_it]['section_name'], tab_it)) (tab_children, num_rendered_items, course_id, section_it, sections[section_it]['section_name'], tab_it))
#logger.debug(msg) #logger.debug(msg)
assert tab_children == num_rendered_items, msg assert tab_children == num_rendered_items, msg
......
...@@ -29,6 +29,14 @@ MODULESTORE = { ...@@ -29,6 +29,14 @@ MODULESTORE = {
} }
} }
CONTENTSTORE = {
'ENGINE': 'xmodule.contentstore.mongo.MongoContentStore',
'OPTIONS': {
'host': 'localhost',
'db': 'test_xcontent',
}
}
# Set this up so that rake lms[acceptance] and running the # Set this up so that rake lms[acceptance] and running the
# harvest command both use the same (test) database # harvest command both use the same (test) database
# which they can flush without messing up your dev db # which they can flush without messing up your dev db
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment