Commit cbc0406d by cahrens

Merge branch 'feature/cas/manual-policy-merged' of github.com:MITx/mitx into…

Merge branch 'feature/cas/manual-policy-merged' of github.com:MITx/mitx into feature/cas/manual-policy-merged
parents 305f0b2a 2bde448f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
[run] [run]
data_file = reports/cms/.coverage data_file = reports/cms/.coverage
source = cms,common/djangoapps source = cms,common/djangoapps
omit = cms/envs/*, cms/manage.py, common/djangoapps/*/migrations/* omit = cms/envs/*, cms/manage.py, common/djangoapps/terrain/*, common/djangoapps/*/migrations/*
[report] [report]
ignore_errors = True ignore_errors = True
......
...@@ -147,10 +147,11 @@ def add_section(name='My Section'): ...@@ -147,10 +147,11 @@ def add_section(name='My Section'):
span_css = 'span.section-name-span' span_css = 'span.section-name-span'
assert_true(world.browser.is_element_present_by_css(span_css, 5)) assert_true(world.browser.is_element_present_by_css(span_css, 5))
def add_subsection(name='Subsection One'): def add_subsection(name='Subsection One'):
css = 'a.new-subsection-item' css = 'a.new-subsection-item'
css_click(css) css_click(css)
name_css = 'input.new-subsection-name-input' name_css = 'input.new-subsection-name-input'
save_css = 'input.new-subsection-name-save' save_css = 'input.new-subsection-name-save'
css_fill(name_css, name) css_fill(name_css, name)
css_click(save_css) css_click(save_css)
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
[run] [run]
data_file = reports/lms/.coverage data_file = reports/lms/.coverage
source = lms,common/djangoapps source = lms,common/djangoapps
omit = lms/envs/*, lms/djangoapps/portal/*, lms/djangoapps/terrain/*, common/djangoapps/*/migrations/* omit = lms/envs/*, common/djangoapps/terrain/*, common/djangoapps/*/migrations/*
[report] [report]
ignore_errors = True ignore_errors = True
......
from lettuce import world, step # , before, after from lettuce import world, step
from factories import *
from django.core.management import call_command 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
......
...@@ -9,7 +9,6 @@ logger = getLogger(__name__) ...@@ -9,7 +9,6 @@ logger = getLogger(__name__)
## support functions ## support functions
def get_courses(): def get_courses():
''' '''
Returns dict of lists of courses available, keyed by course.org (ie university). Returns dict of lists of courses available, keyed by course.org (ie university).
...@@ -20,29 +19,6 @@ def get_courses(): ...@@ -20,29 +19,6 @@ def get_courses():
courses = sorted(courses, key=lambda course: course.number) courses = sorted(courses, key=lambda course: course.number)
return courses return courses
# def get_courseware(course_id):
# """
# Given a course_id (string), return a courseware array of dictionaries for the
# top two levels of navigation. Example:
# [
# {'chapter_name': 'Overview',
# 'sections': ['Welcome', 'System Usage Sequence', 'Lab0: Using the tools', 'Circuit Sandbox']
# },
# {'chapter_name': 'Week 1',
# 'sections': ['Administrivia and Circuit Elements', 'Basic Circuit Analysis', 'Resistor Divider', 'Week 1 Tutorials']
# },
# {'chapter_name': 'Midterm Exam',
# 'sections': ['Midterm Exam']
# }
# ]
# """
# course = get_course_by_id(course_id)
# chapters = course.get_children()
# courseware = [ {'chapter_name':c.display_name, 'sections':[s.display_name for s in c.get_children()]} for c in chapters]
# return courseware
def get_courseware_with_tabs(course_id): def get_courseware_with_tabs(course_id):
""" """
...@@ -106,8 +82,8 @@ def get_courseware_with_tabs(course_id): ...@@ -106,8 +82,8 @@ 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 chapter.metadata.get('hide_from_toc', 'false').lower() != 'true'] chapters = [chapter for chapter in course.get_children() if chapter.metadata.get('hide_from_toc', 'false').lower() != 'true']
courseware = [{'chapter_name': c.display_name, courseware = [{'chapter_name': c.display_name,
'sections': [{'section_name': s.display_name, 'sections': [{'section_name': s.display_name,
'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()]}
......
...@@ -9,10 +9,3 @@ Feature: View the Courseware Tab ...@@ -9,10 +9,3 @@ Feature: View the Courseware Tab
And I click on View Courseware And I click on View Courseware
When I click on the "Courseware" tab When I click on the "Courseware" tab
Then the "Courseware" tab is active Then the "Courseware" tab is active
# TODO: fix this one? Not sure whether you should get a 404.
# Scenario: I cannot get to the courseware tab when not logged in
# Given I am not logged in
# And I visit the homepage
# When I visit the courseware URL
# Then the login dialog is visible
...@@ -34,7 +34,6 @@ def click_the_dropdown(step): ...@@ -34,7 +34,6 @@ def click_the_dropdown(step):
#### helper functions #### helper functions
def user_is_an_unactivated_user(uname): def user_is_an_unactivated_user(uname):
u = User.objects.get(username=uname) u = User.objects.get(username=uname)
u.is_active = False u.is_active = False
......
...@@ -3,31 +3,35 @@ Feature: Open ended grading ...@@ -3,31 +3,35 @@ Feature: Open ended grading
In order to complete the courseware questions In order to complete the courseware questions
I want the machine learning grading to be functional I want the machine learning grading to be functional
Scenario: An answer that is too short is rejected # Commenting these all out right now until we can
Given I navigate to an openended question # make a reference implementation for a course with
And I enter the answer "z" # an open ended grading problem that is always available
When I press the "Check" button #
And I wait for "8" seconds # Scenario: An answer that is too short is rejected
And I see the grader status "Submitted for grading" # Given I navigate to an openended question
And I press the "Recheck for Feedback" button # And I enter the answer "z"
Then I see the red X # When I press the "Check" button
And I see the grader score "0" # And I wait for "8" seconds
# And I see the grader status "Submitted for grading"
# And I press the "Recheck for Feedback" button
# Then I see the red X
# And I see the grader score "0"
Scenario: An answer with too many spelling errors is rejected # Scenario: An answer with too many spelling errors is rejected
Given I navigate to an openended question # Given I navigate to an openended question
And I enter the answer "az" # And I enter the answer "az"
When I press the "Check" button # When I press the "Check" button
And I wait for "8" seconds # And I wait for "8" seconds
And I see the grader status "Submitted for grading" # And I see the grader status "Submitted for grading"
And I press the "Recheck for Feedback" button # And I press the "Recheck for Feedback" button
Then I see the red X # Then I see the red X
And I see the grader score "0" # And I see the grader score "0"
When I click the link for full output # When I click the link for full output
Then I see the spelling grading message "More spelling errors than average." # Then I see the spelling grading message "More spelling errors than average."
Scenario: An answer makes its way to the instructor dashboard # Scenario: An answer makes its way to the instructor dashboard
Given I navigate to an openended question as staff # Given I navigate to an openended question as staff
When I submit the answer "I love Chemistry." # When I submit the answer "I love Chemistry."
And I wait for "8" seconds # And I wait for "8" seconds
And I visit the staff grading page # And I visit the staff grading page
Then my answer is queued for instructor grading # Then my answer is queued for instructor grading
\ No newline at end of file
...@@ -14,4 +14,4 @@ Feature: Register for a course ...@@ -14,4 +14,4 @@ Feature: Register for a course
And I visit the dashboard And I visit the dashboard
When I click the link with the text "Unregister" When I click the link with the text "Unregister"
And I press the "Unregister" button in the Unenroll dialog And I press the "Unregister" button in the Unenroll dialog
Then I should see "Looks like you haven't registered for any courses yet." somewhere in the page Then I should see "Looks like you haven't registered for any courses yet." somewhere in the page
\ No newline at end of file
...@@ -4,7 +4,7 @@ from lettuce import world, step ...@@ -4,7 +4,7 @@ from lettuce import world, step
@step('I register for the course numbered "([^"]*)"$') @step('I register for the course numbered "([^"]*)"$')
def i_register_for_the_course(step, course): def i_register_for_the_course(step, course):
courses_section = world.browser.find_by_css('section.courses') courses_section = world.browser.find_by_css('section.courses')
course_link_css = 'article[id*="%s"] a' % course course_link_css = 'article[id*="%s"] > div' % course
course_link = courses_section.find_by_css(course_link_css).first course_link = courses_section.find_by_css(course_link_css).first
course_link.click() course_link.click()
...@@ -25,3 +25,4 @@ def i_should_see_that_course_in_my_dashboard(step, course): ...@@ -25,3 +25,4 @@ def i_should_see_that_course_in_my_dashboard(step, course):
def i_press_the_button_in_the_unenroll_dialog(step, value): def i_press_the_button_in_the_unenroll_dialog(step, value):
button_css = 'section#unenroll-modal input[value="%s"]' % value button_css = 'section#unenroll-modal input[value="%s"]' % value
world.browser.find_by_css(button_css).click() world.browser.find_by_css(button_css).click()
assert world.browser.is_element_present_by_css('section.container.dashboard')
...@@ -23,37 +23,41 @@ Feature: There are courses on the homepage ...@@ -23,37 +23,41 @@ Feature: There are courses on the homepage
As an acceptance test As an acceptance test
I want to count all the chapters, sections, and tabs for each course I want to count all the chapters, sections, and tabs for each course
Scenario: Navigate through course MITx/3.091x/2012_Fall # Commenting these all out for now because they don't always run,
Given I am registered for course "MITx/3.091x/2012_Fall" # they have too many prerequesites, e.g. the course exists, and
And I log in # is within the start and end dates, etc.
Then I verify all the content of each course
# Scenario: Navigate through course MITx/3.091x/2012_Fall
Scenario: Navigate through course MITx/6.002x/2012_Fall # Given I am registered for course "MITx/3.091x/2012_Fall"
Given I am registered for course "MITx/6.002x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
# Scenario: Navigate through course MITx/6.002x/2012_Fall
Scenario: Navigate through course MITx/6.00x/2012_Fall # Given I am registered for course "MITx/6.002x/2012_Fall"
Given I am registered for course "MITx/6.00x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
# Scenario: Navigate through course MITx/6.00x/2012_Fall
Scenario: Navigate through course HarvardX/PH207x/2012_Fall # Given I am registered for course "MITx/6.00x/2012_Fall"
Given I am registered for course "HarvardX/PH207x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
# Scenario: Navigate through course HarvardX/PH207x/2012_Fall
Scenario: Navigate through course BerkeleyX/CS169.1x/2012_Fall # Given I am registered for course "HarvardX/PH207x/2012_Fall"
Given I am registered for course "BerkeleyX/CS169.1x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
# Scenario: Navigate through course BerkeleyX/CS169.1x/2012_Fall
Scenario: Navigate through course BerkeleyX/CS169.2x/2012_Fall # Given I am registered for course "BerkeleyX/CS169.1x/2012_Fall"
Given I am registered for course "BerkeleyX/CS169.2x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
# Scenario: Navigate through course BerkeleyX/CS169.2x/2012_Fall
Scenario: Navigate through course BerkeleyX/CS184.1x/2012_Fall # Given I am registered for course "BerkeleyX/CS169.2x/2012_Fall"
Given I am registered for course "BerkeleyX/CS184.1x/2012_Fall" # And I log in
And I log in # Then I verify all the content of each course
Then I verify all the content of each course
\ No newline at end of file # Scenario: Navigate through course BerkeleyX/CS184.1x/2012_Fall
# Given I am registered for course "BerkeleyX/CS184.1x/2012_Fall"
# And I log in
# Then I verify all the content of each course
\ No newline at end of file
## acceptance_testing
This fake django app is here to support acceptance testing using <a href="http://lettuce.it/">lettuce</a> +
<a href="http://splinter.cobrateam.info/">splinter</a> (which wraps <a href="http://selenium.googlecode.com/svn/trunk/docs/api/py/index.html">selenium</a>).
First you need to make sure that you've installed the requirements.
This includes lettuce, selenium, splinter, etc.
Do this with:
```pip install -r test-requirements.txt```
The settings.py environment file used is named acceptance.py.
It uses a test SQLite database defined as ../db/test-mitx.db.
You need to first start up the server separately, then run the lettuce scenarios.
Full documentation can be found on the wiki at <a href="https://edx-wiki.atlassian.net/wiki/display/ENG/Lettuce+Acceptance+Testing">this link</a>.
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 = 'Jack Foo'
level_of_education = None
gender = 'm'
mailing_address = None
goals = 'World domination'
class RegistrationFactory(factory.Factory):
FACTORY_FOR = Registration
user = None
activation_key = uuid.uuid4().hex
class UserFactory(factory.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)
...@@ -38,4 +38,4 @@ MITX_FEATURES['STUB_VIDEO_FOR_TESTING'] = True ...@@ -38,4 +38,4 @@ MITX_FEATURES['STUB_VIDEO_FOR_TESTING'] = True
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command # Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
INSTALLED_APPS += ('lettuce.django',) INSTALLED_APPS += ('lettuce.django',)
LETTUCE_APPS = ('portal',) # dummy app covers the home page, login, registration, and course enrollment LETTUCE_APPS = ('courseware',)
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