Commit a3525875 by Jay Zoldak

Merge pull request #1138 from edx/zoldak/locked-asset-tests

Refactor upload tests and add locked asset tests for registered user
parents 67722f1a 6e3ece92
...@@ -5,17 +5,16 @@ Feature: CMS.Upload Files ...@@ -5,17 +5,16 @@ Feature: CMS.Upload Files
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can upload files Scenario: Users can upload files
Given I have opened a new course in Studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page
When I upload the file "test" When I upload the file "test"
Then I should see the file "test" was uploaded Then I should see the file "test" was uploaded
And The url for the file "test" is valid And The url for the file "test" is valid
# Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can upload multiple files Scenario: Users can upload multiple files
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page When I upload the files "test,test2"
When I upload the files "test","test2"
Then I should see the file "test" was uploaded Then I should see the file "test" was uploaded
And I should see the file "test2" was uploaded And I should see the file "test2" was uploaded
And The url for the file "test2" is valid And The url for the file "test2" is valid
...@@ -24,8 +23,7 @@ Feature: CMS.Upload Files ...@@ -24,8 +23,7 @@ Feature: CMS.Upload Files
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can update files Scenario: Users can update files
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page
When I upload the file "test" When I upload the file "test"
And I upload the file "test" And I upload the file "test"
Then I should see only one "test" Then I should see only one "test"
...@@ -33,8 +31,7 @@ Feature: CMS.Upload Files ...@@ -33,8 +31,7 @@ Feature: CMS.Upload Files
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can delete uploaded files Scenario: Users can delete uploaded files
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page
When I upload the file "test" When I upload the file "test"
And I delete the file "test" And I delete the file "test"
Then I should not see the file "test" was uploaded Then I should not see the file "test" was uploaded
...@@ -43,16 +40,14 @@ Feature: CMS.Upload Files ...@@ -43,16 +40,14 @@ Feature: CMS.Upload Files
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can download files Scenario: Users can download files
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page
When I upload the file "test" When I upload the file "test"
Then I can download the correct "test" file Then I can download the correct "test" file
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can download updated files Scenario: Users can download updated files
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page
When I upload the file "test" When I upload the file "test"
And I modify "test" And I modify "test"
And I reload the page And I reload the page
...@@ -62,57 +57,59 @@ Feature: CMS.Upload Files ...@@ -62,57 +57,59 @@ Feature: CMS.Upload Files
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can lock assets through asset index Scenario: Users can lock assets through asset index
Given I have opened a new course in studio Given I am at the files and upload page of a Studio course
And I go to the files and uploads page When I upload an asset
When I upload the file "test" And I lock the asset
And I lock "test" Then the asset is locked
Then "test" is locked
And I see a "saving" notification And I see a "saving" notification
And I reload the page And I reload the page
Then "test" is locked Then the asset is locked
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Users can unlock assets through asset index Scenario: Users can unlock assets through asset index
Given I have opened a course with a locked asset "test" Given I have created a course with a locked asset
And I unlock "test" When I unlock the asset
Then "test" is unlocked Then the asset is unlocked
And I see a "saving" notification And I see a "saving" notification
And I reload the page And I reload the page
Then "test" is unlocked Then the asset is unlocked
# Uploading isn't working on safari with sauce labs
@skip_safari
Scenario: Locked assets can't be viewed if logged in as an unregistered user
Given I have created a course with a locked asset
And the user "bob" exists
When "bob" logs in
Then the asset is protected
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
# TODO: work with Jay @skip_safari
# @skip_safari Scenario: Locked assets can be viewed if logged in as a registered user
# Scenario: Locked assets can't be viewed if logged in as unregistered user Given I have created a course with a locked asset
# Given I have opened a course with a locked asset "locked.html" And the user "bob" exists
# Then the asset "locked.html" can be clicked from the asset index And the user "bob" is enrolled in the course
# And the user "bob" exists When "bob" logs in
# And "bob" logs in Then the asset is viewable
# Then the asset "locked.html" is protected
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Locked assets can't be viewed if logged out Scenario: Locked assets can't be viewed if logged out
Given I have opened a course with a locked asset "locked.html" Given I have created a course with a locked asset
# Note that logging out doesn't really matter at the moment- When I log out
# the asset will be protected because the user sent to middleware is the anonymous user. Then the asset is protected
# Need to work with Jay.
And I log out
Then the asset "locked.html" is protected
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Locked assets can be viewed with is_staff account Scenario: Locked assets can be viewed with is_staff account
Given I have opened a course with a locked asset "locked.html" Given I have created a course with a locked asset
And the user "staff" exists as a course is_staff And the user "staff" exists as a course is_staff
And "staff" logs in When "staff" logs in
Then the asset "locked.html" can be clicked from the asset index Then the asset is viewable
# Uploading isn't working on safari with sauce labs # Uploading isn't working on safari with sauce labs
@skip_safari @skip_safari
Scenario: Unlocked assets can be viewed by anyone Scenario: Unlocked assets can be viewed by anyone
Given I have opened a course with a unlocked asset "unlocked.html" Given I have created a course with a unlocked asset
Then the asset "unlocked.html" can be clicked from the asset index When I log out
And I log out Then the asset is viewable
Then the asset "unlocked.html" is viewable
...@@ -2,14 +2,17 @@ ...@@ -2,14 +2,17 @@
#pylint: disable=W0621 #pylint: disable=W0621
from lettuce import world, step from lettuce import world, step
from lettuce.django import django_url
from django.conf import settings from django.conf import settings
import requests import requests
import string import string
import random import random
import os import os
from django.contrib.auth.models import User
from student.models import CourseEnrollment
from splinter.request_handler.status_code import HttpResponseError
from nose.tools import assert_equal, assert_not_equal # pylint: disable=E0611 from nose.tools import assert_equal, assert_not_equal # pylint: disable=E0611
TEST_ROOT = settings.COMMON_TEST_DATA_ROOT TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
ASSET_NAMES_CSS = 'td.name-col > span.title > a.filename' ASSET_NAMES_CSS = 'td.name-col > span.title > a.filename'
...@@ -26,7 +29,10 @@ def go_to_uploads(_step): ...@@ -26,7 +29,10 @@ def go_to_uploads(_step):
def upload_file(_step, file_name): def upload_file(_step, file_name):
upload_css = 'a.upload-button' upload_css = 'a.upload-button'
world.css_click(upload_css) world.css_click(upload_css)
#uploading the file itself
_write_test_file(file_name, "test file")
# uploading the file itself
path = os.path.join(TEST_ROOT, 'uploads/', file_name) path = os.path.join(TEST_ROOT, 'uploads/', file_name)
world.browser.execute_script("$('input.file-input').css('display', 'block')") world.browser.execute_script("$('input.file-input').css('display', 'block')")
world.browser.attach_file('file', os.path.abspath(path)) world.browser.attach_file('file', os.path.abspath(path))
...@@ -34,19 +40,20 @@ def upload_file(_step, file_name): ...@@ -34,19 +40,20 @@ def upload_file(_step, file_name):
world.css_click(close_css) world.css_click(close_css)
@step(u'I upload the files (".*")$') @step(u'I upload the files "([^"]*)"$')
def upload_files(_step, files_string): def upload_files(_step, files_string):
# Turn files_string to a list of file names # files_string should be comma separated with no spaces.
files = files_string.split(",") files = files_string.split(",")
files = map(lambda x: string.strip(x, ' "\''), files)
upload_css = 'a.upload-button' upload_css = 'a.upload-button'
world.css_click(upload_css) world.css_click(upload_css)
#uploading the files
for f in files: # uploading the files
path = os.path.join(TEST_ROOT, 'uploads/', f) 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.execute_script("$('input.file-input').css('display', 'block')")
world.browser.attach_file('file', os.path.abspath(path)) world.browser.attach_file('file', os.path.abspath(path))
close_css = 'a.close-button' close_css = 'a.close-button'
world.css_click(close_css) world.css_click(close_css)
...@@ -104,13 +111,13 @@ def check_download(_step, file_name): ...@@ -104,13 +111,13 @@ def check_download(_step, file_name):
r = get_file(file_name) r = get_file(file_name)
downloaded_text = r.text downloaded_text = r.text
assert cur_text == downloaded_text assert cur_text == downloaded_text
#resetting the file back to its original state # resetting the file back to its original state
_write_test_file(file_name, "This is an arbitrary file for testing uploads") _write_test_file(file_name, "This is an arbitrary file for testing uploads")
def _write_test_file(file_name, text): def _write_test_file(file_name, text):
path = os.path.join(TEST_ROOT, 'uploads/', file_name) path = os.path.join(TEST_ROOT, 'uploads/', file_name)
#resetting the file back to its original state # resetting the file back to its original state
with open(os.path.abspath(path), 'w') as cur_file: with open(os.path.abspath(path), 'w') as cur_file:
cur_file.write(text) cur_file.write(text)
...@@ -121,68 +128,68 @@ def modify_upload(_step, file_name): ...@@ -121,68 +128,68 @@ def modify_upload(_step, file_name):
_write_test_file(file_name, new_text) _write_test_file(file_name, new_text)
@step(u'I (lock|unlock) "([^"]*)"$') @step(u'I upload an asset$')
def lock_unlock_file(_step, _lock_state, file_name): def upload_an_asset(step):
index = get_index(file_name) step.given('I upload the file "asset.html"')
assert index != -1
@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" lock_css = "input.lock-checkbox"
world.css_find(lock_css)[index].click() world.css_find(lock_css)[index].click()
@step(u'Then "([^"]*)" is (locked|unlocked)$') @step(u'the user "([^"]*)" is enrolled in the course$')
def verify_lock_unlock_file(_step, file_name, lock_state): def user_foo_is_enrolled_in_the_course(step, name):
index = get_index(file_name) world.create_user(name, 'test')
assert index != -1 user = User.objects.get(username=name)
course_id = world.scenario_dict['COURSE'].location.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" lock_css = "input.lock-checkbox"
checked = world.css_find(lock_css)[index]._element.get_attribute('checked') checked = world.css_find(lock_css)[index]._element.get_attribute('checked')
assert_equal(lock_state == "locked", bool(checked)) assert_equal(lock_state == "locked", bool(checked))
@step(u'I have opened a course with a (locked|unlocked) asset "([^"]*)"$') @step(u'I am at the files and upload page of a Studio course')
def open_course_with_locked(step, lock_state, file_name): def at_upload_page(step):
step.given('I have opened a new course in studio') step.given('I have opened a new course in studio')
step.given('I go to the files and uploads page') step.given('I go to the files and uploads page')
_write_test_file(file_name, "test file")
step.given('I upload the file "' + file_name + '"')
@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": if lock_state == "locked":
step.given('I lock "' + file_name + '"') step.given('I lock the asset')
step.given('I reload the page') step.given('I reload the page')
@step(u'Then the asset "([^"]*)" is (viewable|protected)$') @step(u'Then the asset is (viewable|protected)$')
def view_asset(_step, file_name, status): def view_asset(_step, status):
url = '/c4x/MITx/999/asset/' + file_name url = django_url('/c4x/MITx/999/asset/asset.html')
if status == 'viewable': if status == 'viewable':
world.visit(url) expected_text = 'test file'
_verify_body_text()
else: else:
error_thrown = False expected_text = 'Unauthorized'
try:
world.visit(url)
except Exception as e:
assert e.status_code == 403
error_thrown = True
assert error_thrown
@step(u'Then the asset "([^"]*)" can be clicked from the asset index$')
def click_asset_from_index(step, file_name):
# This is not ideal, but I'm having trouble with the middleware not having
# the same user in the request when I hit the URL directly.
course_link_css = 'a.course-link'
world.css_click(course_link_css)
step.given("I go to the files and uploads page")
index = get_index(file_name)
assert index != -1
world.css_click('a.filename', index=index)
_verify_body_text()
def _verify_body_text():
def verify_text(driver):
return world.css_text('body') == 'test file'
world.wait_for(verify_text) # 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$') @step('I see a confirmation that the file was deleted$')
......
...@@ -2,17 +2,10 @@ ...@@ -2,17 +2,10 @@
# pylint: disable=W0621 # pylint: disable=W0621
from lettuce import world from lettuce import world
from .factories import *
from django.conf import settings
from django.http import HttpRequest
from django.contrib.auth.models import User from django.contrib.auth.models import User
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 student.models import CourseEnrollment
from xmodule.modulestore.django import editable_modulestore from xmodule.modulestore.django import editable_modulestore
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from urllib import quote_plus
@world.absorb @world.absorb
...@@ -22,7 +15,7 @@ def create_user(uname, password): ...@@ -22,7 +15,7 @@ def create_user(uname, password):
if len(User.objects.filter(username=uname)) > 0: if len(User.objects.filter(username=uname)) > 0:
return return
portal_user = UserFactory.build(username=uname, email=uname + '@edx.org') portal_user = world.UserFactory.build(username=uname, email=uname + '@edx.org')
portal_user.set_password(password) portal_user.set_password(password)
portal_user.save() portal_user.save()
...@@ -30,7 +23,7 @@ def create_user(uname, password): ...@@ -30,7 +23,7 @@ def create_user(uname, password):
registration.register(portal_user) registration.register(portal_user)
registration.activate() registration.activate()
user_profile = world.UserProfileFactory(user=portal_user) world.UserProfileFactory(user=portal_user)
@world.absorb @world.absorb
......
This is an arbitrary file for testing uploads
\ 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