229 lines
7.3 KiB
Python
229 lines
7.3 KiB
Python
# pylint: disable=missing-docstring
|
|
# pylint: disable=redefined-outer-name
|
|
|
|
from lettuce import world, step
|
|
from lettuce.django import django_url
|
|
from django.conf import settings
|
|
import requests
|
|
import string
|
|
import random
|
|
import os
|
|
from django.contrib.auth.models import User
|
|
from student.models import CourseEnrollment
|
|
from nose.tools import assert_equal, assert_not_equal
|
|
|
|
TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
|
|
ASSET_NAMES_CSS = 'td.name-col > span.title > a.filename'
|
|
|
|
|
|
@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 a'
|
|
world.css_click(menu_css)
|
|
world.css_click(uploads_css)
|
|
|
|
|
|
@step(u'I upload the( test)? file "([^"]*)"$')
|
|
def upload_file(_step, is_test_file, file_name, button_text=None):
|
|
if button_text:
|
|
world.click_link(button_text)
|
|
else:
|
|
world.click_link('Upload New File')
|
|
|
|
if not is_test_file:
|
|
_write_test_file(file_name, "test file")
|
|
|
|
# uploading the file itself
|
|
path = os.path.join(TEST_ROOT, 'uploads/', file_name)
|
|
world.browser.execute_script("$('input.file-input').css('display', 'block')")
|
|
world.browser.attach_file('file', os.path.abspath(path))
|
|
close_css = 'a.close-button'
|
|
world.css_click(close_css)
|
|
|
|
|
|
@step(u'I upload the file "([^"]*)" by clicking "([^"]*)"')
|
|
def upload_file_on_button_press(_step, file_name, button_text=None):
|
|
upload_file(_step, '', file_name, button_text)
|
|
|
|
|
|
@step(u'I upload the files "([^"]*)"$')
|
|
def upload_files(_step, files_string):
|
|
# files_string should be comma separated with no spaces.
|
|
files = files_string.split(",")
|
|
upload_css = 'a.upload-button'
|
|
world.css_click(upload_css)
|
|
|
|
# uploading the files
|
|
for filename in files:
|
|
_write_test_file(filename, "test file")
|
|
path = os.path.join(TEST_ROOT, 'uploads/', filename)
|
|
world.browser.execute_script("$('input.file-input').css('display', 'block')")
|
|
world.browser.attach_file('file', os.path.abspath(path))
|
|
|
|
close_css = 'a.close-button'
|
|
world.css_click(close_css)
|
|
|
|
|
|
@step(u'I should not see the file "([^"]*)" was uploaded$')
|
|
def check_not_there(_step, file_name):
|
|
# Either there are no files, or there are files but
|
|
# not the one I expect not to exist.
|
|
|
|
# Since our only test for deletion right now deletes
|
|
# the only file that was uploaded, our success criteria
|
|
# will be that there are no files.
|
|
# In the future we can refactor if necessary.
|
|
assert world.is_css_not_present(ASSET_NAMES_CSS)
|
|
|
|
|
|
@step(u'I should see the file "([^"]*)" was uploaded$')
|
|
def check_upload(_step, file_name):
|
|
index = get_index(file_name)
|
|
assert_not_equal(index, -1)
|
|
|
|
|
|
@step(u'The url for the file "([^"]*)" is valid$')
|
|
def check_url(_step, file_name):
|
|
r = get_file(file_name)
|
|
assert_equal(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)
|
|
world.confirm_studio_prompt()
|
|
|
|
|
|
@step(u'I should see only one "([^"]*)"$')
|
|
def no_duplicate(_step, file_name):
|
|
all_names = world.css_find(ASSET_NAMES_CSS)
|
|
only_one = False
|
|
for i in range(len(all_names)):
|
|
if file_name == world.css_html(ASSET_NAMES_CSS, index=i):
|
|
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
|
|
# resetting the file back to its original state
|
|
_write_test_file(file_name, "This is an arbitrary file for testing uploads")
|
|
|
|
|
|
def _write_test_file(file_name, text):
|
|
path = os.path.join(TEST_ROOT, 'uploads/', file_name)
|
|
# resetting the file back to its original state
|
|
with open(os.path.abspath(path), 'w') as cur_file:
|
|
cur_file.write(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))
|
|
_write_test_file(file_name, new_text)
|
|
|
|
|
|
@step(u'I upload an asset$')
|
|
def upload_an_asset(step):
|
|
step.given('I upload the file "asset.html"')
|
|
|
|
|
|
@step(u'I (lock|unlock) the asset$')
|
|
def lock_unlock_file(_step, _lock_state):
|
|
index = get_index('asset.html')
|
|
assert index != -1, 'Expected to find an asset but could not.'
|
|
|
|
# Warning: this is a misnomer, it really only toggles the
|
|
# lock state. TODO: fix it.
|
|
lock_css = "input.lock-checkbox"
|
|
world.css_find(lock_css)[index].click()
|
|
|
|
|
|
@step(u'the user "([^"]*)" is enrolled in the course$')
|
|
def user_foo_is_enrolled_in_the_course(step, name):
|
|
world.create_user(name, 'test')
|
|
user = User.objects.get(username=name)
|
|
|
|
course_id = world.scenario_dict['COURSE'].id
|
|
CourseEnrollment.enroll(user, course_id)
|
|
|
|
|
|
@step(u'Then the asset is (locked|unlocked)$')
|
|
def verify_lock_unlock_file(_step, lock_state):
|
|
index = get_index('asset.html')
|
|
assert index != -1, 'Expected to find an asset but could not.'
|
|
lock_css = "input.lock-checkbox"
|
|
checked = world.css_find(lock_css)[index]._element.get_attribute('checked')
|
|
assert_equal(lock_state == "locked", bool(checked))
|
|
|
|
|
|
@step(u'I am at the files and upload page of a Studio course')
|
|
def at_upload_page(step):
|
|
step.given('I have opened a new course in studio')
|
|
step.given('I go to the files and uploads page')
|
|
|
|
|
|
@step(u'I have created a course with a (locked|unlocked) asset$')
|
|
def open_course_with_locked(step, lock_state):
|
|
step.given('I am at the files and upload page of a Studio course')
|
|
step.given('I upload the file "asset.html"')
|
|
|
|
if lock_state == "locked":
|
|
step.given('I lock the asset')
|
|
step.given('I reload the page')
|
|
|
|
|
|
@step(u'Then the asset is (viewable|protected)$')
|
|
def view_asset(_step, status):
|
|
asset_loc = world.scenario_dict['COURSE'].id.make_asset_key(asset_type='asset', path='asset.html')
|
|
svr_loc = django_url()
|
|
asset_url = unicode(asset_loc)
|
|
divider = '/'
|
|
if asset_url[0] == '/':
|
|
divider = ''
|
|
url = '{}{}{}'.format(svr_loc, divider, asset_url)
|
|
if status == 'viewable':
|
|
expected_text = 'test file'
|
|
else:
|
|
expected_text = 'Unauthorized'
|
|
|
|
# Note that world.visit would trigger a 403 error instead of displaying "Unauthorized"
|
|
# Instead, we can drop back into the selenium driver get command.
|
|
world.browser.driver.get(url)
|
|
assert_equal(world.css_text('body'), expected_text)
|
|
|
|
|
|
@step('I see a confirmation that the file was deleted$')
|
|
def i_see_a_delete_confirmation(_step):
|
|
alert_css = '#notification-confirmation'
|
|
assert world.is_css_present(alert_css)
|
|
|
|
|
|
def get_index(file_name):
|
|
all_names = world.css_find(ASSET_NAMES_CSS)
|
|
for i in range(len(all_names)):
|
|
if file_name == world.css_html(ASSET_NAMES_CSS, index=i):
|
|
return i
|
|
return -1
|
|
|
|
|
|
def get_file(file_name):
|
|
index = get_index(file_name)
|
|
assert index != -1
|
|
url_css = 'a.filename'
|
|
|
|
def get_url():
|
|
return world.css_find(url_css)[index]._element.get_attribute('href')
|
|
url = world.retry_on_exception(get_url)
|
|
return requests.get(url)
|