canvas-lms/spec/models/grading_period_group_spec.rb

442 lines
14 KiB
Ruby

#
# Copyright (C) 2011 - present 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_relative '../spec_helper'
describe GradingPeriodGroup do
let(:group_helper) { Factories::GradingPeriodGroupHelper.new }
let(:valid_attributes) { { title: "A Title" } }
let(:account) { Account.default }
# after dev lands in master, re add this title validation
# it { is_expected.to validate_presence_of(:title) }
it { is_expected.to belong_to(:course) }
it { is_expected.to have_many(:enrollment_terms).inverse_of(:grading_period_group) }
it { is_expected.to have_many(:grading_periods).dependent(:destroy) }
describe ".for" do
context "when given a root account" do
it "fetches sets on a root account" do
set = account.grading_period_groups.create!(valid_attributes)
sets = GradingPeriodGroup.for(account)
expect(sets.count).to eql 1
expect(sets).to include set
end
it "uses the root account when given sub accounts" do
set = account.grading_period_groups.create!(valid_attributes)
sub_account = account.sub_accounts.create!
sets = GradingPeriodGroup.for(sub_account)
expect(sets.count).to eql 1
expect(sets).to include set
end
end
context "when given a course" do
it "is expected to fail" do
course = account.courses.create!
expect {
GradingPeriodGroup.for(course)
}.to raise_error(ArgumentError)
end
end
end
describe '.for_course' do
before(:once) do
@course = account.courses.create!
end
it 'returns the set associated with the course' do
set = account.grading_period_groups.create!(valid_attributes)
set.enrollment_terms << @course.enrollment_term
expect(GradingPeriodGroup.for_course(@course)).to eq(set)
end
it 'returns nil if no set is associated with the course' do
expect(GradingPeriodGroup.for_course(@course)).to be_nil
end
it 'returns nil if the associated set is soft-deleted' do
set = account.grading_period_groups.create!(valid_attributes)
set.enrollment_terms << @course.enrollment_term
set.destroy
expect(GradingPeriodGroup.for_course(@course)).to be_nil
end
context 'legacy grading periods support' do
before(:once) do
@set = Factories::GradingPeriodGroupHelper.new.legacy_create_for_course(@course)
end
it 'returns the set associated with the course' do
expect(GradingPeriodGroup.for_course(@course)).to eq(@set)
end
it 'returns nil if the associated set is soft-deleted' do
@set.destroy
expect(GradingPeriodGroup.for_course(@course)).to be_nil
end
end
end
describe "validation" do
let(:group) { GradingPeriodGroup.new valid_attributes }
it "is valid with an account" do
group = account.grading_period_groups.build(title: "Example Group")
expect(group).to be_valid
end
it "is valid with a course" do
course = Course.create!(account: Account.default)
group = course.grading_period_groups.build(title: "Example Group")
expect(group).to be_valid
end
it "is not valid with a sub-account" do
sub_account = account.sub_accounts.create!
group = sub_account.grading_period_groups.build(title: "Example Group")
expect(group).not_to be_valid
end
it "is not valid with only an enrollment term" do
group.enrollment_terms << account.enrollment_terms.create!
expect(group).not_to be_valid
end
it "is not valid without an account or a course" do
expect(group).not_to be_valid
end
it "cannot be created for a soft-deleted account" do
account.update_attribute(:workflow_state, 'deleted')
group = account.grading_period_groups.build(title: "Example Group")
expect(group).not_to be_valid
end
it "cannot be created for a soft-deleted course" do
course = Course.create!(account: Account.default)
course.update_attribute(:workflow_state, 'deleted')
group = course.grading_period_groups.build(title: "Example Group")
expect(group).not_to be_valid
end
it "can belong to a soft-deleted account when also soft-deleted" do
group = group_helper.create_for_account(account)
account.update_attribute(:workflow_state, 'deleted')
group.reload
expect(group).not_to be_valid
group.workflow_state = 'deleted'
expect(group).to be_valid
end
it "can belong to a soft-deleted course when also soft-deleted" do
course = Course.create!(account: Account.default)
group = group_helper.legacy_create_for_course(course)
course.update_attribute(:workflow_state, 'deleted')
group.reload
expect(group).not_to be_valid
group.workflow_state = 'deleted'
expect(group).to be_valid
end
end
it_behaves_like "soft deletion" do
let(:course) { Course.create!(account: account) }
let(:creation_arguments) { {title: "A title"} }
subject { course.grading_period_groups }
end
describe "deletion" do
let(:account) { Account.default }
let(:term_1) { account.enrollment_terms.create! }
let(:term_2) { account.enrollment_terms.create! }
let(:group) { group_helper.create_for_account(account) }
it "removes associations from related enrollment terms" do
group.enrollment_terms = [term_1, term_2]
expect(term_1.reload.grading_period_group).to eql group
expect(term_2.reload.grading_period_group).to eql group
group.destroy
expect(term_1.reload.grading_period_group).to be_nil
expect(term_2.reload.grading_period_group).to be_nil
end
it "removes associations from soft-deleted enrollment terms" do
group.enrollment_terms = [term_1, term_2]
term_1.destroy
expect(term_1.reload.grading_period_group).to eql group
expect(term_2.reload.grading_period_group).to eql group
group.destroy
expect(term_1.reload.grading_period_group).to be_nil
expect(term_2.reload.grading_period_group).to be_nil
end
end
describe "permissions" do
let(:permissions) { [:read, :create, :update, :delete] }
context "course belonging to root account" do
before :once do
@root_account = Account.default
@sub_account = @root_account.sub_accounts.create!
course_with_teacher(account: @root_account, active_all: true)
course_with_student(course: @course, active_all: true)
@root_account_group = group_helper.create_for_account(@root_account)
@course_group = group_helper.legacy_create_for_course(@course)
end
context "root-account admin" do
before :once do
account_admin_user(account: @root_account)
@root_account_admin = @admin
end
it "can read, create, update, and delete root-account " \
"grading period groups" do
expect(@root_account_group.rights_status(@root_account_admin, *permissions)).to eq({
read: true,
create: true,
update: true,
delete: true
})
end
it "can read, update, and delete but NOT create course level " \
"grading period groups" do
expect(@course_group.rights_status(@root_account_admin, *permissions)).to eq({
read: true,
create: false,
update: true,
delete: true
})
end
end
context "sub-account admin" do
before(:once) do
account_admin_user(account: @sub_account)
@sub_account_admin = @admin
end
it "can read but NOT create, update, not delete root-account " \
"grading period groups", priority: "1", test_id: 2528644 do
expect(@root_account_group.
rights_status(@sub_account_admin, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "cannot read, create, update, delete course " \
"grading period groups, when the course is under a root-account" do
expect(@course_group.
rights_status(@sub_account_admin, *permissions)).to eq({
read: false,
create: false,
update: false,
delete: false
})
end
end
context "teacher" do
it "can read but NOT create, update, nor delete root-account " \
"grading period groups", priority: "1", test_id: 2528645 do
expect(@root_account_group.
rights_status(@teacher, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "can read, update, and delete but NOT create course " \
"grading period groups" do
expect(@course_group.
rights_status(@teacher, *permissions)).to eq({
read: true,
create: false,
update: true,
delete: true
})
end
end
context "student" do
it "can only read root account grading period groups" do
expect(@root_account_group.
rights_status(@student, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "can only read course grading period groups" do
expect(@course_group.
rights_status(@student, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
end
end
context "course belonging to sub-account" do
before(:once) do
@root_account = Account.default
@sub_account = @root_account.sub_accounts.create!
course_with_teacher(account: @sub_account, active_all: true)
course_with_student(course: @course, active_all: true)
@root_account_group = group_helper.create_for_account(@root_account)
@course_group = group_helper.legacy_create_for_course(@course)
end
context "root-account admin" do
before(:once) do
account_admin_user(account: @root_account)
@root_account_admin = @admin
end
it "can read, create, update, and delete root-account " \
"grading period groups" do
expect(@root_account_group.
rights_status(@root_account_admin, *permissions)).to eq({
read: true,
create: true,
update: true,
delete: true
})
end
it "can read, update, and destroy but NOT create course " \
"grading period groups" do
expect(@course_group.
rights_status(@root_account_admin, *permissions)).to eq({
read: true,
create: false,
update: true,
delete: true
})
end
end
context "sub-account admin" do
before(:once) do
account_admin_user(account: @sub_account)
@sub_account_admin = @admin
end
it "can only read root-account grading period groups" do
expect(@root_account_group.
rights_status(@sub_account_admin, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "can read, update, and delete but NOT create course grading " \
"period groups when the course is under the sub-account" do
expect(@course_group.
rights_status(@sub_account_admin, *permissions)).to eq({
read: true,
create: false,
update: true,
delete: true
})
end
end
context "teacher" do
it "can only read root-account grading period groups" do
expect(@root_account_group.
rights_status(@teacher, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "can read, update and delete but NOT create course " \
"grading period groups" do
expect(@course_group.
rights_status(@teacher, *permissions)).to eq({
read: true,
create: false,
update: true,
delete: true
})
end
end
context "student" do
it "can only read root-account grading period groups" do
expect(@root_account_group.
rights_status(@student, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
it "can only read sub-account grading period groups" do
expect(@course_group.
rights_status(@student, *permissions)).to eq({
read: true,
create: false,
update: false,
delete: false
})
end
end
end
end
describe 'computation of course scores' do
before(:once) do
@grading_period_set = account.grading_period_groups.create!(valid_attributes)
term = account.enrollment_terms.create!
@grading_period_set.enrollment_terms << term
account.courses.create!(enrollment_term: term)
end
it 'recomputes course scores when the weighted attribute is changed' do
Enrollment.expects(:recompute_final_score).once
@grading_period_set.update!(weighted: true)
end
it 'does not recompute course scores when the weighted attribute is not changed' do
Enrollment.expects(:recompute_final_score).never
@grading_period_set.update!(title: 'The Best Set')
end
end
end