canvas-lms/spec/models/enrollment_spec.rb

404 lines
14 KiB
Ruby

#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
describe Enrollment do
before(:each) do
@user = User.create! #mock_model(User)
@course = Course.create! #mock_model(Course)
@enrollment = Enrollment.new(valid_enrollment_attributes)
end
it "should be valid" do
@enrollment.should be_valid
end
it "should have an interesting state machine" do
enrollment_model
list = {}
list.stub!(:find_all_by_context_id_and_context_type).and_return([])
@user.stub!(:dashboard_messages).and_return(list)
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.state.should eql(:active)
@enrollment.reject
@enrollment.state.should eql(:rejected)
enrollment_model
@enrollment.complete
@enrollment.state.should eql(:completed)
enrollment_model
@enrollment.reject
@enrollment.state.should eql(:rejected)
enrollment_model
@enrollment.accept
@enrollment.state.should eql(:active)
end
it "should find students" do
@student_list = mock('student list')
@student_list.stub!(:map).and_return(['student list'])
Enrollment.should_receive(:find).and_return(@student_list)
Enrollment.students.should eql(['student list'])
end
it "should be pending if it is invited or creation_pending" do
enrollment_model(:workflow_state => 'invited')
@enrollment.should be_pending
enrollment_model(:workflow_state => 'creation_pending')
@enrollment.should be_pending
end
it "should have a context_id as the course_id" do
@enrollment.course.id.should_not be_nil
@enrollment.context_id.should eql(@enrollment.course.id)
end
it "should have a readable_type of Teacher for a TeacherEnrollment" do
e = TeacherEnrollment.new
e.type = 'TeacherEnrollment'
e.readable_type.should eql('Teacher')
end
it "should have a readable_type of Student for a StudentEnrollment" do
e = StudentEnrollment.new
e.type = 'StudentEnrollment'
e.readable_type.should eql('Student')
end
it "should have a readable_type of TaEnrollment for a TA" do
e = TaEnrollment.new(valid_enrollment_attributes)
e.type = 'TaEnrollment'
e.readable_type.should eql('TA')
end
it "should have a defalt readable_type of Student" do
e = Enrollment.new
e.type = 'Other'
e.readable_type.should eql('Student')
end
it "should not allow read permission on a course if inactive" do
course_with_student(:active_all => true)
@enrollment.start_at = 2.days.ago
@enrollment.end_at = 2.days.from_now
@enrollment.workflow_state = 'inactive'
@enrollment.save!
@course.grants_right?(@enrollment.user, nil, :read).should eql(false)
end
context "typed_enrollment" do
it "should allow StudentEnrollment" do
Enrollment.typed_enrollment('StudentEnrollment').should eql(StudentEnrollment)
end
it "should allow TeacherEnrollment" do
Enrollment.typed_enrollment('TeacherEnrollment').should eql(TeacherEnrollment)
end
it "should allow TaEnrollment" do
Enrollment.typed_enrollment('TaEnrollment').should eql(TaEnrollment)
end
it "should allow ObserverEnrollment" do
Enrollment.typed_enrollment('ObserverEnrollment').should eql(ObserverEnrollment)
end
it "should allow DesignerEnrollment" do
Enrollment.typed_enrollment('DesignerEnrollment').should eql(DesignerEnrollment)
end
it "should allow not NothingEnrollment" do
Enrollment.typed_enrollment('NothingEnrollment').should eql(nil)
end
end
context "drop scores" do
before(:each) do
course_with_student
@group = @course.assignment_groups.create!(:name => "some group", :group_weight => 50, :rules => "drop_lowest:1")
@assignment = @group.assignments.build(:title => "some assignments", :points_possible => 10)
@assignment.context = @course
@assignment.save!
@assignment2 = @group.assignments.build(:title => "some assignment 2", :points_possible => 40)
@assignment2.context = @course
@assignment2.save!
end
it "should drop high scores for groups when specified" do
@group.update_attribute(:rules, "drop_highest:1")
@user.enrollments.first.computed_current_score.should eql(nil)
@submission = @assignment.grade_student(@user, :grade => "9")
@submission[0].score.should eql(9.0)
@user.enrollments.should_not be_empty
@user.enrollments.first.computed_current_score.should eql(90.0)
@submission2 = @assignment2.grade_student(@user, :grade => "20")
@submission2[0].score.should eql(20.0)
@user.reload
@user.enrollments.first.computed_current_score.should eql(50.0)
@group.reload
@group.rules = nil
@group.save
@user.reload
@user.enrollments.first.computed_current_score.should eql(58.0)
end
it "should drop low scores for groups when specified" do
@user.enrollments.first.computed_current_score.should eql(nil)
@submission = @assignment.grade_student(@user, :grade => "9")
@submission2 = @assignment2.grade_student(@user, :grade => "20")
@submission2[0].score.should eql(20.0)
@user.reload
@user.enrollments.first.computed_current_score.should eql(90.0)
@group.update_attribute(:rules, "")
@user.reload
@user.enrollments.first.computed_current_score.should eql(58.0)
end
it "should not drop the last score for a group, even if the settings say it should be dropped" do
@group.update_attribute(:rules, "drop_lowest:2")
@user.enrollments.first.computed_current_score.should eql(nil)
@submission = @assignment.grade_student(@user, :grade => "9")
@submission[0].score.should eql(9.0)
@user.enrollments.should_not be_empty
@user.enrollments.first.computed_current_score.should eql(90.0)
@submission2 = @assignment2.grade_student(@user, :grade => "20")
@submission2[0].score.should eql(20.0)
@user.reload
@user.enrollments.first.computed_current_score.should eql(90.0)
end
end
context "notifications" do
it "should send out invitations if the course is already published" do
Notification.create!(:name => "Enrollment Registration")
course_with_teacher(:active_all => true)
user_with_pseudonym
e = @course.enroll_student(@user)
e.messages_sent.should be_include("Enrollment Registration")
end
it "should not send out invitations if the course is not yet published" do
Notification.create!(:name => "Enrollment Registration")
course_with_teacher
user_with_pseudonym
e = @course.enroll_student(@user)
e.messages_sent.should_not be_include("Enrollment Registration")
end
it "should send out invitations for previously-created enrollments when the course is published" do
n = Notification.create(:name => "Enrollment Registration", :category => "Registration")
course_with_teacher
user_with_pseudonym
e = @course.enroll_student(@user)
e.messages_sent.should_not be_include("Enrollment Registration")
@user.pseudonym.should_not be_nil
@course.offer
e.reload
e.should be_invited
e.user.should_not be_nil
e.user.pseudonym.should_not be_nil
Message.last.should_not be_nil
Message.last.notification.should eql(n)
Message.last.to.should eql(@user.email)
end
end
context "atom" do
it "should use the course and user name to derive a title" do
@enrollment.to_atom.title.should eql("#{@enrollment.user.name} in #{@enrollment.course.name}")
end
it "should link to the enrollment" do
link_path = @enrollment.to_atom.links.first.to_s
link_path.should eql("/courses/#{@enrollment.course.id}/enrollments/#{@enrollment.id}")
end
end
context "permissions" do
it "should be able to read grades if the course grants management rights to the enrollment" do
@new_user = user_model
@enrollment.grants_rights?(@new_user, nil, :read_grades)[:read_grades].should be_false
@course.admins << @new_user
@course.save!
@enrollment.grants_rights?(@user, nil, :read_grades).should be_true
end
it "should allow the user itself to read its own grades" do
@enrollment.grants_rights?(@user, nil, :read_grades).should be_true
end
end
context "accept" do
it "should accept into the right state based on availability dates on enrollment" do
course_with_student(:active_all => true)
@enrollment.start_at = 2.days.ago
@enrollment.end_at = 2.days.from_now
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.state.should eql(:active)
@enrollment.start_at = 4.days.ago
@enrollment.end_at = 2.days.ago
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.state.should eql(:completed)
@enrollment.start_at = 2.days.from_now
@enrollment.end_at = 4.days.from_now
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.state.should eql(:inactive)
end
it "should accept into the right state based on availability dates on course_section" do
course_with_student(:active_all => true)
@section = @course.course_sections.first
@section.should_not be_nil
@enrollment.course_section = @section
@enrollment.workflow_state = 'invited'
@enrollment.save!
@section.start_at = 2.days.ago
@section.end_at = 2.days.from_now
@section.restrict_enrollments_to_section_dates = true
@section.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.state.should eql(:active)
@section.start_at = 4.days.ago
@section.end_at = 2.days.ago
@section.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:completed)
@section.start_at = 2.days.from_now
@section.end_at = 4.days.from_now
@section.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:inactive)
end
it "should accept into the right state based on availability dates on course" do
course_with_student(:active_all => true)
@course.start_at = 2.days.ago
@course.conclude_at = 2.days.from_now
@course.restrict_enrollments_to_course_dates = true
@course.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:active)
@course.start_at = 4.days.ago
@course.conclude_at = 2.days.ago
@course.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:completed)
@course.start_at = 2.days.from_now
@course.conclude_at = 4.days.from_now
@course.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:inactive)
end
it "should accept into the right state based on availability dates on enrollment_term" do
course_with_student(:active_all => true)
@term = @course.enrollment_term
@term.should_not be_nil
@term.start_at = 2.days.ago
@term.end_at = 2.days.from_now
@term.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:active)
@term.start_at = 4.days.ago
@term.end_at = 2.days.ago
@term.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:completed)
@term.start_at = 2.days.from_now
@term.end_at = 4.days.from_now
@term.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:inactive)
end
it "should accept into the right state based on availability dates on enrollment_dates_override" do
course_with_student(:active_all => true)
@term = @course.enrollment_term
@term.should_not be_nil
@term.save!
@override = @term.enrollment_dates_overrides.create!(:enrollment_type => 'StudentEnrollment', :enrollment_term_id => @term.id)
@override.start_at = 2.days.ago
@override.end_at = 2.days.from_now
@override.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:active)
@override.start_at = 4.days.ago
@override.end_at = 2.days.ago
@override.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:completed)
@override.start_at = 2.days.from_now
@override.end_at = 4.days.from_now
@override.save!
@enrollment.workflow_state = 'invited'
@enrollment.save!
@enrollment.state.should eql(:invited)
@enrollment.accept
@enrollment.reload.state.should eql(:inactive)
end
end
end