Commit 26a05f2a by Jonah Stanley

Merge pull request #140 from edx/jonahstanley/add-courseteam-tests

Jonahstanley/add courseteam tests
parents a36aee5b d632ffe9
......@@ -3,7 +3,6 @@
from lettuce import world, step
from nose.tools import assert_true
from nose.tools import assert_equal
from auth.authz import get_user_by_email
......@@ -13,8 +12,13 @@ import time
from logging import getLogger
logger = getLogger(__name__)
_COURSE_NAME = 'Robot Super Course'
_COURSE_NUM = '999'
_COURSE_ORG = 'MITx'
########### STEP HELPERS ##############
@step('I (?:visit|access|open) the Studio homepage$')
def i_visit_the_studio_homepage(_step):
# To make this go to port 8001, put
......@@ -54,6 +58,7 @@ def i_have_opened_a_new_course(_step):
####### HELPER FUNCTIONS ##############
def open_new_course():
world.clear_courses()
create_studio_user()
log_into_studio()
create_a_course()
......@@ -73,10 +78,11 @@ def create_studio_user(
registration.register(studio_user)
registration.activate()
def fill_in_course_info(
name='Robot Super Course',
org='MITx',
num='101'):
name=_COURSE_NAME,
org=_COURSE_ORG,
num=_COURSE_NUM):
world.css_fill('.new-course-name', name)
world.css_fill('.new-course-org', org)
world.css_fill('.new-course-number', num)
......@@ -85,10 +91,7 @@ def fill_in_course_info(
def log_into_studio(
uname='robot',
email='robot+studio@edx.org',
password='test',
is_staff=False):
create_studio_user(uname=uname, email=email, is_staff=is_staff)
password='test'):
world.browser.cookies.delete()
world.visit('/')
......@@ -106,14 +109,14 @@ def log_into_studio(
def create_a_course():
world.CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
world.CourseFactory.create(org=_COURSE_ORG, course=_COURSE_NUM, display_name=_COURSE_NAME)
# Add the user to the instructor group of the course
# so they will have the permissions to see it in studio
g = world.GroupFactory.create(name='instructor_MITx/999/Robot_Super_Course')
u = get_user_by_email('robot+studio@edx.org')
u.groups.add(g)
u.save()
course = world.GroupFactory.create(name='instructor_MITx/{course_num}/{course_name}'.format(course_num=_COURSE_NUM, course_name=_COURSE_NAME.replace(" ", "_")))
user = get_user_by_email('robot+studio@edx.org')
user.groups.add(course)
user.save()
world.browser.reload()
course_link_css = 'span.class-name'
......
Feature: Course Team
As a course author, I want to be able to add others to my team
Scenario: Users can add other users
Given I have opened a new course in Studio
And the user "alice" exists
And I am viewing the course team settings
When I add "alice" to the course team
And "alice" logs in
Then she does see the course on her page
Scenario: Added users cannot delete or add other users
Given I have opened a new course in Studio
And the user "bob" exists
And I am viewing the course team settings
When I add "bob" to the course team
And "bob" logs in
Then he cannot delete users
And he cannot add users
Scenario: Users can delete other users
Given I have opened a new course in Studio
And the user "carol" exists
And I am viewing the course team settings
When I add "carol" to the course team
And I delete "carol" from the course team
And "carol" logs in
Then she does not see the course on her page
Scenario: Users cannot add users that do not exist
Given I have opened a new course in Studio
And I am viewing the course team settings
When I add "dennis" to the course team
Then I should see "Could not find user by email address" somewhere on the page
#pylint: disable=C0111
#pylint: disable=W0621
from lettuce import world, step
from common import create_studio_user, log_into_studio, _COURSE_NAME
PASSWORD = 'test'
EMAIL_EXTENSION = '@edx.org'
@step(u'I am viewing the course team settings')
def view_grading_settings(_step):
world.click_course_settings()
link_css = 'li.nav-course-settings-team a'
world.css_click(link_css)
@step(u'the user "([^"]*)" exists$')
def create_other_user(_step, name):
create_studio_user(uname=name, password=PASSWORD, email=(name + EMAIL_EXTENSION))
@step(u'I add "([^"]*)" to the course team')
def add_other_user(_step, name):
new_user_css = 'a.new-user-button'
world.css_click(new_user_css)
email_css = 'input.email-input'
f = world.css_find(email_css)
f._element.send_keys(name, EMAIL_EXTENSION)
confirm_css = '#add_user'
world.css_click(confirm_css)
@step(u'I delete "([^"]*)" from the course team')
def delete_other_user(_step, name):
to_delete_css = 'a.remove-user[data-id="{name}{extension}"]'.format(name=name, extension=EMAIL_EXTENSION)
world.css_click(to_delete_css)
@step(u'"([^"]*)" logs in$')
def other_user_login(_step, name):
log_into_studio(uname=name, password=PASSWORD, email=name + EMAIL_EXTENSION)
@step(u's?he does( not)? see the course on (his|her) page')
def see_course(_step, doesnt_see_course, gender):
class_css = 'span.class-name'
all_courses = world.css_find(class_css)
all_names = [item.html for item in all_courses]
if doesnt_see_course:
assert not _COURSE_NAME in all_names
else:
assert _COURSE_NAME in all_names
@step(u's?he cannot delete users')
def cannot_delete(_step):
to_delete_css = 'a.remove-user'
assert world.is_css_not_present(to_delete_css)
@step(u's?he cannot add users')
def cannot_add(_step):
add_css = 'a.new-user'
assert world.is_css_not_present(add_css)
Feature: Course updates
As a course author, I want to be able to provide updates to my students
Scenario: Users can add updates
Given I have opened a new course in Studio
And I go to the course updates page
When I add a new update with the text "Hello"
Then I should see the update "Hello"
Scenario: Users can edit updates
Given I have opened a new course in Studio
And I go to the course updates page
When I add a new update with the text "Hello"
And I modify the text to "Goodbye"
Then I should see the update "Goodbye"
Scenario: Users can delete updates
Given I have opened a new course in Studio
And I go to the course updates page
And I add a new update with the text "Hello"
When I will confirm all alerts
And I delete the update
Then I should not see the update "Hello"
Scenario: Users can edit update dates
Given I have opened a new course in Studio
And I go to the course updates page
And I add a new update with the text "Hello"
When I edit the date to "June 1, 2013"
Then I should see the date "June 1, 2013"
Scenario: Users can change handouts
Given I have opened a new course in Studio
And I go to the course updates page
When I modify the handout to "<ol>Test</ol>"
Then I see the handout "Test"
#pylint: disable=C0111
#pylint: disable=W0621
from lettuce import world, step
from selenium.webdriver.common.keys import Keys
from common import type_in_codemirror
@step(u'I go to the course updates page')
def go_to_updates(_step):
menu_css = 'li.nav-course-courseware'
updates_css = 'li.nav-course-courseware-updates'
world.css_click(menu_css)
world.css_click(updates_css)
@step(u'I add a new update with the text "([^"]*)"$')
def add_update(_step, text):
update_css = 'a.new-update-button'
world.css_click(update_css)
change_text(text)
@step(u'I should( not)? see the update "([^"]*)"$')
def check_update(_step, doesnt_see_update, text):
update_css = 'div.update-contents'
update = world.css_find(update_css)
if doesnt_see_update:
assert len(update) == 0 or not text in update.html
else:
assert text in update.html
@step(u'I modify the text to "([^"]*)"$')
def modify_update(_step, text):
button_css = 'div.post-preview a.edit-button'
world.css_click(button_css)
change_text(text)
@step(u'I delete the update$')
def click_button(_step):
button_css = 'div.post-preview a.delete-button'
world.css_click(button_css)
@step(u'I edit the date to "([^"]*)"$')
def change_date(_step, new_date):
button_css = 'div.post-preview a.edit-button'
world.css_click(button_css)
date_css = 'input.date'
date = world.css_find(date_css)
for i in range(len(date.value)):
date._element.send_keys(Keys.END, Keys.BACK_SPACE)
date._element.send_keys(new_date)
save_css = 'a.save-button'
world.css_click(save_css)
@step(u'I should see the date "([^"]*)"$')
def check_date(_step, date):
date_css = 'span.date-display'
date_html = world.css_find(date_css)
assert date == date_html.html
@step(u'I modify the handout to "([^"]*)"$')
def edit_handouts(_step, text):
edit_css = 'div.course-handouts > a.edit-button'
world.css_click(edit_css)
change_text(text)
@step(u'I see the handout "([^"]*)"$')
def check_handout(_step, handout):
handout_css = 'div.handouts-content'
handouts = world.css_find(handout_css)
assert handout in handouts.html
def change_text(text):
type_in_codemirror(0, text)
save_css = 'a.save-button'
world.css_click(save_css)
......@@ -10,6 +10,7 @@ from common import *
@step('There are no courses$')
def no_courses(step):
world.clear_courses()
create_studio_user()
@step('I click the New Course button$')
......
Feature: Static Pages
As a course author, I want to be able to add static pages
Scenario: Users can add static pages
Given I have opened a new course in Studio
And I go to the static pages page
When I add a new page
Then I should see a "Empty" static page
Scenario: Users can delete static pages
Given I have opened a new course in Studio
And I go to the static pages page
And I add a new page
When I will confirm all alerts
And I "delete" the "Empty" page
Then I should not see a "Empty" static page
Scenario: Users can edit static pages
Given I have opened a new course in Studio
And I go to the static pages page
And I add a new page
When I "edit" the "Empty" page
And I change the name to "New"
Then I should see a "New" static page
#pylint: disable=C0111
#pylint: disable=W0621
from lettuce import world, step
from selenium.webdriver.common.keys import Keys
@step(u'I go to the static pages page')
def go_to_static(_step):
menu_css = 'li.nav-course-courseware'
static_css = 'li.nav-course-courseware-pages'
world.css_find(menu_css).click()
world.css_find(static_css).click()
@step(u'I add a new page')
def add_page(_step):
button_css = 'a.new-button'
world.css_find(button_css).click()
@step(u'I should( not)? see a "([^"]*)" static page$')
def see_page(_step, doesnt, page):
index = get_index(page)
if doesnt:
assert index == -1
else:
assert index != -1
@step(u'I "([^"]*)" the "([^"]*)" page$')
def click_edit_delete(_step, edit_delete, page):
button_css = 'a.%s-button' % edit_delete
index = get_index(page)
assert index != -1
world.css_find(button_css)[index].click()
@step(u'I change the name to "([^"]*)"$')
def change_name(_step, new_name):
settings_css = '#settings-mode'
world.css_find(settings_css).click()
input_css = 'input.setting-input'
name_input = world.css_find(input_css)
old_name = name_input.value
for count in range(len(old_name)):
name_input._element.send_keys(Keys.END, Keys.BACK_SPACE)
name_input._element.send_keys(new_name)
save_button = 'a.save-button'
world.css_find(save_button).click()
def get_index(name):
page_name_css = 'section[data-type="HTMLModule"]'
all_pages = world.css_find(page_name_css)
for i in range(len(all_pages)):
if all_pages[i].html == '\n {name}\n'.format(name=name):
return i
return -1
......@@ -50,7 +50,8 @@ def have_a_course_with_two_sections(step):
@step(u'I navigate to the course overview page$')
def navigate_to_the_course_overview_page(step):
log_into_studio(is_staff=True)
create_studio_user(is_staff=True)
log_into_studio()
course_locator = '.class-name'
world.css_click(course_locator)
......
Feature: Upload Files
As a course author, I want to be able to upload files for my students
Scenario: Users can upload files
Given I have opened a new course in Studio
And I go to the files and uploads page
When I upload the file "test"
Then I should see the file "test" was uploaded
And The url for the file "test" is valid
Scenario: Users can update files
Given I have opened a new course in studio
And I go to the files and uploads page
When I upload the file "test"
And I upload the file "test"
Then I should see only one "test"
Scenario: Users can delete uploaded files
Given I have opened a new course in studio
And I go to the files and uploads page
When I upload the file "test"
And I delete the file "test"
Then I should not see the file "test" was uploaded
Scenario: Users can download files
Given I have opened a new course in studio
And I go to the files and uploads page
When I upload the file "test"
Then I can download the correct "test" file
Scenario: Users can download updated files
Given I have opened a new course in studio
And I go to the files and uploads page
When I upload the file "test"
And I modify "test"
And I reload the page
And I upload the file "test"
Then I can download the correct "test" file
#pylint: disable=C0111
#pylint: disable=W0621
from lettuce import world, step
from django.conf import settings
import requests
import string
import random
import os
TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
HTTP_PREFIX = "http://localhost:8001"
@step(u'I go to the files and uploads page')
def go_to_uploads(_step):
menu_css = 'li.nav-course-courseware'
uploads_css = 'li.nav-course-courseware-uploads'
world.css_find(menu_css).click()
world.css_find(uploads_css).click()
@step(u'I upload the file "([^"]*)"$')
def upload_file(_step, file_name):
upload_css = 'a.upload-button'
world.css_find(upload_css).click()
file_css = 'input.file-input'
upload = world.css_find(file_css)
#uploading the file itself
path = os.path.join(TEST_ROOT, 'uploads/', file_name)
upload._element.send_keys(os.path.abspath(path))
close_css = 'a.close-button'
world.css_find(close_css).click()
@step(u'I should( not)? see the file "([^"]*)" was uploaded$')
def check_upload(_step, do_not_see_file, file_name):
index = get_index(file_name)
if do_not_see_file:
assert index == -1
else:
assert index != -1
@step(u'The url for the file "([^"]*)" is valid$')
def check_url(_step, file_name):
r = get_file(file_name)
assert r.status_code == 200
@step(u'I delete the file "([^"]*)"$')
def delete_file(_step, file_name):
index = get_index(file_name)
assert index != -1
delete_css = "a.remove-asset-button"
world.css_click(delete_css, index=index)
prompt_confirm_css = 'li.nav-item > a.action-primary'
world.css_click(prompt_confirm_css)
@step(u'I should see only one "([^"]*)"$')
def no_duplicate(_step, file_name):
names_css = 'td.name-col > a.filename'
all_names = world.css_find(names_css)
only_one = False
for i in range(len(all_names)):
if file_name == all_names[i].html:
only_one = not only_one
assert only_one
@step(u'I can download the correct "([^"]*)" file$')
def check_download(_step, file_name):
path = os.path.join(TEST_ROOT, 'uploads/', file_name)
with open(os.path.abspath(path), 'r') as cur_file:
cur_text = cur_file.read()
r = get_file(file_name)
downloaded_text = r.text
assert cur_text == downloaded_text
@step(u'I modify "([^"]*)"$')
def modify_upload(_step, file_name):
new_text = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(10))
path = os.path.join(TEST_ROOT, 'uploads/', file_name)
with open(os.path.abspath(path), 'w') as cur_file:
cur_file.write(new_text)
def get_index(file_name):
names_css = 'td.name-col > a.filename'
all_names = world.css_find(names_css)
for i in range(len(all_names)):
if file_name == all_names[i].html:
return i
return -1
def get_file(file_name):
index = get_index(file_name)
assert index != -1
url_css = 'input.embeddable-xml-input'
url = world.css_find(url_css)[index].value
return requests.get(HTTP_PREFIX + url)
......@@ -10,7 +10,8 @@ from django.contrib.auth import authenticate, login
from django.contrib.auth.middleware import AuthenticationMiddleware
from django.contrib.sessions.middleware import SessionMiddleware
from student.models import CourseEnrollment
from xmodule.modulestore.django import _MODULESTORES, modulestore
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from xmodule.templates import update_templates
from bs4 import BeautifulSoup
import os.path
......@@ -110,7 +111,6 @@ def save_the_course_content(path='/tmp'):
u = world.browser.url
section_url = u[u.find('courseware/') + 11:]
if not os.path.exists(path):
os.makedirs(path)
......@@ -129,6 +129,6 @@ def clear_courses():
# (though it shouldn't), do this manually
# from the bash shell to drop it:
# $ mongo test_xmodule --eval "db.dropDatabase()"
_MODULESTORES = {}
modulestore().collection.drop()
update_templates(modulestore('direct'))
contentstore().fs_files.drop()
R2FUIGM88K
\ No newline at end of file
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