354 lines
16 KiB
Ruby
Executable File
354 lines
16 KiB
Ruby
Executable File
require File.expand_path(File.dirname(__FILE__) + '/common')
|
|
|
|
describe "assignments" do
|
|
it_should_behave_like "in-process server selenium tests"
|
|
|
|
context "as a student" do
|
|
|
|
def update_assignment_attributes(assignment, attribute, values, click_submit_link = true)
|
|
assignment.update_attributes(attribute => values)
|
|
get "/courses/#{@course.id}/assignments/#{assignment.id}"
|
|
f('.submit_assignment_link').click if click_submit_link
|
|
end
|
|
|
|
def click_away_accept_alert
|
|
f('#section-tabs .home').click
|
|
driver.switch_to.alert.accept # doing this step and the step above to avoid the alert from failing other selenium specs
|
|
end
|
|
|
|
before (:each) do
|
|
@due_date = Time.now.utc + 2.days
|
|
course_with_student_logged_in
|
|
@assignment = @course.assignments.create!(:title => 'assignment 1', :name => 'assignment 1', :due_at => @due_date)
|
|
@second_assignment = @course.assignments.create!(:title => 'assignment 2', :name => 'assignment 2', :due_at => nil)
|
|
@third_assignment = @course.assignments.create!(:title => 'assignment 3', :name => 'assignment 3', :due_at => nil)
|
|
@fourth_assignment = @course.assignments.create!(:title => 'assignment 4', :name => 'assignment 4', :due_at => @due_date - 1.day)
|
|
end
|
|
|
|
it "should not sort undated assignments first and it should order them by title" do
|
|
get "/courses/#{@course.id}/assignments"
|
|
titles = ff('.title')
|
|
titles[2].text.should == @second_assignment.title
|
|
titles[3].text.should == @third_assignment.title
|
|
end
|
|
|
|
it "should order upcoming assignments starting with first due" do
|
|
get "/courses/#{@course.id}/assignments"
|
|
titles = ff('.title')
|
|
titles[0].text.should == @fourth_assignment.title
|
|
titles[1].text.should == @assignment.title
|
|
end
|
|
|
|
it "should expand the comments box on click" do
|
|
@assignment = @course.assignments.create!(
|
|
:name => 'test assignment',
|
|
:due_at => Time.now.utc + 2.days,
|
|
:submission_types => 'online_upload')
|
|
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
|
|
f('.submit_assignment_link').click
|
|
wait_for_ajaximations
|
|
driver.execute_script("return $('#submission_comment').height()").should == 20
|
|
driver.execute_script("$('#submission_comment').focus()")
|
|
wait_for_ajaximations
|
|
driver.execute_script("return $('#submission_comment').height()").should == 72
|
|
|
|
# navigate off the page and dismiss the alert box to avoid problems
|
|
# with other selenium tests
|
|
f('#section-tabs .home').click
|
|
driver.switch_to.alert.accept
|
|
driver.switch_to.default_content
|
|
end
|
|
|
|
it "should highlight mini-calendar dates where stuff is due" do
|
|
get "/courses/#{@course.id}/assignments/syllabus"
|
|
wait_for_ajaximations
|
|
f(".mini_calendar_day.date_#{@due_date.strftime("%m_%d_%Y")}").should have_class('has_event')
|
|
end
|
|
|
|
it "should not show submission data when muted" do
|
|
@assignment.update_attributes(:submission_types => "online_url,online_upload")
|
|
@submission = @assignment.submit_homework(@student)
|
|
@submission.submission_type = "online_url"
|
|
@submission.save!
|
|
|
|
@submission.add_comment(:author => @teacher, :comment => "comment before muting")
|
|
@assignment.mute!
|
|
@assignment.update_submission(@student, :hidden => true, :comment => "comment after muting")
|
|
|
|
outcome_with_rubric
|
|
@rubric.associate_with(@assignment, @course, :purpose => "grading")
|
|
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
details = f(".details")
|
|
details.should include_text('comment before muting')
|
|
details.should_not include_text('comment after muting')
|
|
end
|
|
|
|
it "should have group comment checkboxes for group assignments" do
|
|
@u1 = @user
|
|
student_in_course(:course => @course)
|
|
@u2 = @user
|
|
@assignment = @course.assignments.create!(:title => "some assignment", :submission_types => "online_url,online_upload,online_text_entry", :group_category => GroupCategory.create!(:name => "groups", :context => @course), :grade_group_students_individually => true)
|
|
@group = @assignment.group_category.groups.create!(:name => 'g1', :context => @course)
|
|
@group.users << @u1
|
|
@group.users << @user
|
|
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
|
|
ffj('.formtable input[name="submission[group_comment]"]').size.should == 4
|
|
end
|
|
|
|
it "should not show assignments in an unpublished course" do
|
|
new_course = Course.create!(:name => 'unpublished course')
|
|
assignment = new_course.assignments.create!(:title => "some assignment")
|
|
new_course.enroll_user(@user, 'StudentEnrollment')
|
|
get "/courses/#{new_course.id}/assignments/#{assignment.id}"
|
|
|
|
f('.ui-state-error').should be_displayed
|
|
f('#assignment_show').should be_nil
|
|
end
|
|
|
|
it "should verify student creatable group creation" do
|
|
new_group_name = 'student created group'
|
|
get "/courses/#{@course.id}/groups"
|
|
|
|
f('.add_group_link').click
|
|
wait_for_animations
|
|
f('#group_name').send_keys(new_group_name)
|
|
submit_form('#add_group_form')
|
|
wait_for_ajaximations
|
|
f('.group_list').should include_text(new_group_name)
|
|
Group.find_by_name(new_group_name).should be_present
|
|
end
|
|
|
|
it "should verify lock until date is enforced" do
|
|
assignment_name = 'locked assignment'
|
|
unlock_time = 1.day.from_now
|
|
locked_assignment = @course.assignments.create!(:name => assignment_name, :unlock_at => unlock_time)
|
|
|
|
get "/courses/#{@course.id}/assignments/#{locked_assignment.id}"
|
|
f('#content').should include_text(unlock_time.strftime("%b %-d"))
|
|
locked_assignment.update_attributes(:unlock_at => Time.now)
|
|
refresh_page # to show the updated assignment
|
|
f('#content').should_not include_text('This assignment is locked until')
|
|
end
|
|
|
|
it "should verify due date is enforced" do
|
|
due_date_assignment = @course.assignments.create!(:name => 'due date assignment', :due_at => 5.days.ago)
|
|
driver.current_url
|
|
get "/courses/#{@course.id}/assignments"
|
|
ffj('.assignment_list:visible').last.should include_text(due_date_assignment.title)
|
|
due_date_assignment.update_attributes(:due_at => 2.days.from_now)
|
|
refresh_page # to show the updated assignment
|
|
ffj('.assignment_list:visible').first.should include_text(due_date_assignment.title)
|
|
end
|
|
|
|
it "should validate an assignment created with the type of discussion" do
|
|
@fourth_assignment.update_attributes(:submission_types => 'discussion_topic')
|
|
get "/courses/#{@course.id}/assignments/#{@fourth_assignment.id}"
|
|
|
|
driver.current_url.should match %r{/courses/\d+/discussion_topics/\d+}
|
|
f('div.discussion-title').should include_text(@fourth_assignment.title)
|
|
end
|
|
|
|
it "should validate an assignment created with the type of external tool" do
|
|
t1 = factory_with_protected_attributes(@course.context_external_tools, :url => "http://www.example.com/tool1", :shared_secret => 'test123', :consumer_key => 'test123', :name => 'tool 1')
|
|
external_tool_assignment = assignment_model(:course => @course, :title => "test2", :submission_types => 'external_tool')
|
|
external_tool_assignment.create_external_tool_tag(:url => t1.url)
|
|
external_tool_assignment.external_tool_tag.update_attribute(:content_type, 'ContextExternalTool')
|
|
get "/courses/#{@course.id}/assignments/#{external_tool_assignment.id}"
|
|
|
|
f('#tool_content').should be_displayed
|
|
end
|
|
|
|
it "should validate an assignment created with the type of not graded" do
|
|
@fourth_assignment.update_attributes(:submission_types => 'not_graded')
|
|
get "/courses/#{@course.id}/assignments/#{@fourth_assignment.id}"
|
|
|
|
f('.submit_assignment_link').should be_nil
|
|
end
|
|
|
|
it "should validate on paper submission assignment type" do
|
|
update_assignment_attributes(@fourth_assignment, :submission_types, 'on_paper', false)
|
|
f('.submit_assignment_link').should be_nil
|
|
end
|
|
|
|
it "should validate no submission assignment type" do
|
|
update_assignment_attributes(@fourth_assignment, :submission_types, nil, false)
|
|
f('.submit_assignment_link').should be_nil
|
|
end
|
|
|
|
context "overridden lock_at" do
|
|
before :each do
|
|
setup_sections_and_overrides_all_future
|
|
@course.enroll_user(@student, 'StudentEnrollment', :section => @section2, :enrollment_state => 'active')
|
|
end
|
|
|
|
it "should show overridden lock dates for student" do
|
|
extend TextHelper
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
expected_unlock = datetime_string(@override.unlock_at).gsub(/\s+/, ' ')
|
|
expected_lock_at = datetime_string(@override.lock_at).gsub(/\s+/, ' ')
|
|
f('#content').should include_text "locked until #{expected_unlock}."
|
|
end
|
|
|
|
it "should allow submission when within override locks" do
|
|
@assignment.update_attributes(:submission_types => 'online_text_entry')
|
|
# Change unlock dates to be valid for submission
|
|
@override.unlock_at = Time.now.utc - 1.days # available now
|
|
@override.save!
|
|
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
f('.submit_assignment_link').click
|
|
wait_for_ajaximations
|
|
assignment_form = f('#submit_online_text_entry_form')
|
|
wait_for_tiny(assignment_form)
|
|
wait_for_ajaximations
|
|
expect {
|
|
type_in_tiny('#submission_body', 'something to submit')
|
|
wait_for_ajaximations
|
|
submit_form(assignment_form)
|
|
wait_for_ajaximations
|
|
}.to change(Submission, :count).by(1)
|
|
end
|
|
end
|
|
|
|
context "click_away_accept_alert" do #this context exits to handle the click_away_accept_alert method call after each spec that needs it even if it fails early to prevent other specs from failing
|
|
after(:each) do
|
|
click_away_accept_alert
|
|
end
|
|
|
|
it "should validate file upload restrictions" do
|
|
filename_txt, fullpath_txt, data_txt, tempfile_txt = get_file("testfile4.txt")
|
|
filename_zip, fullpath_zip, data_zip, tempfile_zip = get_file("testfile5.zip")
|
|
@fourth_assignment.update_attributes(:submission_types => 'online_upload', :allowed_extensions => '.txt')
|
|
get "/courses/#{@course.id}/assignments/#{@fourth_assignment.id}"
|
|
f('.submit_assignment_link').click
|
|
|
|
submit_file_button = f('#submit_file_button')
|
|
submission_input = f('.submission_attachment input')
|
|
ext_error = f('.bad_ext_msg')
|
|
|
|
keep_trying_until do
|
|
submission_input.send_keys(fullpath_txt)
|
|
ext_error.should_not be_displayed
|
|
submit_file_button.should_not have_class('disabled')
|
|
submission_input.send_keys(fullpath_zip)
|
|
ext_error.should be_displayed
|
|
submit_file_button.should have_class('disabled')
|
|
end
|
|
end
|
|
|
|
it "should validate that website url submissions are allowed" do
|
|
update_assignment_attributes(@fourth_assignment, :submission_types, 'online_url')
|
|
f('#submission_url').should be_displayed
|
|
end
|
|
|
|
it "should validate that text entry submissions are allowed" do
|
|
update_assignment_attributes(@fourth_assignment, :submission_types, 'online_text_entry')
|
|
f('.submit_online_text_entry_option').should be_displayed
|
|
end
|
|
|
|
it "should allow an assignment with all 3 online submission types" do
|
|
update_assignment_attributes(@fourth_assignment, :submission_types, 'online_text_entry, online_url, online_upload')
|
|
f('.submit_online_text_entry_option').should be_displayed
|
|
f('.submit_online_url_option').should be_displayed
|
|
f('.submit_online_upload_option').should be_displayed
|
|
end
|
|
end
|
|
end
|
|
|
|
context "as observer" do
|
|
before :each do
|
|
@course = course(:active_all => true)
|
|
@student = user(:active_all => true, :active_state => 'active')
|
|
@observer = user(:active_all => true, :active_state => 'active')
|
|
user_session(@observer)
|
|
|
|
@due_date = Time.now.utc + 12.days
|
|
@assignment = @course.assignments.create!(:title => 'assignment 1', :name => 'assignment 1', :due_at => @due_date)
|
|
|
|
setup_sections_and_overrides_all_future
|
|
end
|
|
|
|
context "when not linked to student" do
|
|
before :each do
|
|
@course.enroll_user(@observer, 'ObserverEnrollment', :section => @section2, :enrollment_state => 'active')
|
|
end
|
|
|
|
it "should see own section's lock dates" do
|
|
extend TextHelper
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
expected_unlock = datetime_string(@override.unlock_at).gsub(/\s+/, ' ')
|
|
expected_lock_at = datetime_string(@override.lock_at).gsub(/\s+/, ' ')
|
|
f('#content').should include_text "locked until #{expected_unlock}."
|
|
end
|
|
|
|
context "with multiple section enrollments in same course" do
|
|
it "should have the earliest 'lock until' date and the latest 'lock after' date" do
|
|
@assignment.update_attributes :lock_at => @lock_at + 22.days
|
|
@course.enroll_user(@observer, 'ObserverEnrollment', :section => @section1, :enrollment_state => 'active')
|
|
extend TextHelper
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
expected_unlock = datetime_string(@override.unlock_at).gsub(/\s+/, ' ')
|
|
expected_lock_at = datetime_string(@assignment.lock_at).gsub(/\s+/, ' ') # later than section2
|
|
f('#content').should include_text "locked until #{expected_unlock}."
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when linked to student" do
|
|
before :each do
|
|
@student_enrollment = @course.enroll_user(@student, 'StudentEnrollment', :enrollment_state => 'active', :section => @section2)
|
|
@observer_enrollment = @course.enroll_user(@observer, 'ObserverEnrollment', :enrollment_state => 'active', :section => @section2)
|
|
@observer_enrollment.update_attribute(:associated_user_id, @student.id)
|
|
end
|
|
|
|
it "should return student's lock dates" do
|
|
extend TextHelper
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
expected_unlock = datetime_string(@override.unlock_at).gsub(/\s+/, ' ')
|
|
expected_lock_at = datetime_string(@override.lock_at).gsub(/\s+/, ' ')
|
|
f('#content').should include_text "locked until #{expected_unlock}."
|
|
end
|
|
|
|
context "overridden lock_at" do
|
|
before :each do
|
|
setup_sections_and_overrides_all_future
|
|
@course.enroll_user(@student, 'StudentEnrollment', :section => @section2, :enrollment_state => 'active')
|
|
end
|
|
|
|
it "should show overridden lock dates for student" do
|
|
extend TextHelper
|
|
get "/courses/#{@course.id}/assignments/#{@assignment.id}"
|
|
expected_unlock = datetime_string(@override.unlock_at).gsub(/\s+/, ' ')
|
|
expected_lock_at = datetime_string(@override.lock_at).gsub(/\s+/, ' ')
|
|
f('#content').should include_text "locked until #{expected_unlock}."
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def setup_sections_and_overrides_all_future
|
|
# All in the future by default
|
|
@unlock_at = Time.now.utc + 6.days
|
|
@due_at = Time.now.utc + 10.days
|
|
@lock_at = Time.now.utc + 11.days
|
|
|
|
@assignment.due_at = @due_at
|
|
@assignment.unlock_at = @unlock_at
|
|
@assignment.lock_at = @lock_at
|
|
@assignment.save!
|
|
# 2 course sections, student in second section.
|
|
@section1 = @course.course_sections.create!(:name => 'Section A')
|
|
@section2 = @course.course_sections.create!(:name => 'Section B')
|
|
@course.student_enrollments.delete_all # get rid of existing student enrollments, mess up section enrollment
|
|
# Overridden lock dates for 2nd section - different dates, but still in future
|
|
@override = assignment_override_model(:assignment => @assignment, :set => @section2,
|
|
:lock_at => @lock_at + 12.days,
|
|
:unlock_at => Time.now.utc + 3.days)
|
|
end
|