845 lines
34 KiB
Ruby
845 lines
34 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__) + '/../sharding_spec_helper.rb')
|
|
|
|
describe Account do
|
|
|
|
it "should provide a list of courses" do
|
|
@account = Account.new
|
|
lambda{@account.courses}.should_not raise_error
|
|
end
|
|
|
|
context "equella_settings" do
|
|
it "should respond to :equella_settings" do
|
|
Account.new.should respond_to(:equella_settings)
|
|
Account.new.equella_settings.should be_nil
|
|
end
|
|
|
|
it "should return the equella_settings data if defined" do
|
|
a = Account.new
|
|
a.equella_endpoint = "http://oer.equella.com/signon.do"
|
|
a.equella_settings.should_not be_nil
|
|
a.equella_settings.endpoint.should eql("http://oer.equella.com/signon.do")
|
|
a.equella_settings.default_action.should_not be_nil
|
|
end
|
|
end
|
|
|
|
# it "should have an atom feed" do
|
|
# account_model
|
|
# @a.to_atom.should be_is_a(Atom::Entry)
|
|
# end
|
|
|
|
context "course lists" do
|
|
before(:each) do
|
|
@account = Account.create!
|
|
process_csv_data_cleanly([
|
|
"user_id,login_id,first_name,last_name,email,status",
|
|
"U001,user1,User,One,user1@example.com,active",
|
|
"U002,user2,User,Two,user2@example.com,active",
|
|
"U003,user3,User,Three,user3@example.com,active",
|
|
"U004,user4,User,Four,user4@example.com,active",
|
|
"U005,user5,User,Five,user5@example.com,active",
|
|
"U006,user6,User,Six,user6@example.com,active",
|
|
"U007,user7,User,Seven,user7@example.com,active",
|
|
"U008,user8,User,Eight,user8@example.com,active",
|
|
"U009,user9,User,Nine,user9@example.com,active",
|
|
"U010,user10,User,Ten,user10@example.com,active",
|
|
"U011,user11,User,Eleven,user11@example.com,deleted"
|
|
])
|
|
process_csv_data_cleanly([
|
|
"term_id,name,status,start_date,end_date",
|
|
"T001,Term 1,active,,",
|
|
"T002,Term 2,active,,",
|
|
"T003,Term 3,active,,"
|
|
])
|
|
process_csv_data_cleanly([
|
|
"course_id,short_name,long_name,account_id,term_id,status",
|
|
"C001,C001,Test Course 1,,T001,active",
|
|
"C002,C002,Test Course 2,,T001,deleted",
|
|
"C003,C003,Test Course 3,,T002,deleted",
|
|
"C004,C004,Test Course 4,,T002,deleted",
|
|
"C005,C005,Test Course 5,,T003,active",
|
|
"C006,C006,Test Course 6,,T003,active",
|
|
"C007,C007,Test Course 7,,T003,active",
|
|
"C008,C008,Test Course 8,,T003,active",
|
|
"C009,C009,Test Course 9,,T003,active",
|
|
"C001S,C001S,Test search Course 1,,T001,active",
|
|
"C002S,C002S,Test search Course 2,,T001,deleted",
|
|
"C003S,C003S,Test search Course 3,,T002,deleted",
|
|
"C004S,C004S,Test search Course 4,,T002,deleted",
|
|
"C005S,C005S,Test search Course 5,,T003,active",
|
|
"C006S,C006S,Test search Course 6,,T003,active",
|
|
"C007S,C007S,Test search Course 7,,T003,active",
|
|
"C008S,C008S,Test search Course 8,,T003,active",
|
|
"C009S,C009S,Test search Course 9,,T003,active"
|
|
])
|
|
process_csv_data_cleanly([
|
|
"section_id,course_id,name,start_date,end_date,status",
|
|
"S001,C001,Sec1,,,active",
|
|
"S002,C002,Sec2,,,active",
|
|
"S003,C003,Sec3,,,active",
|
|
"S004,C004,Sec4,,,active",
|
|
"S005,C005,Sec5,,,active",
|
|
"S006,C006,Sec6,,,active",
|
|
"S007,C007,Sec7,,,deleted",
|
|
"S008,C001,Sec8,,,deleted",
|
|
"S009,C008,Sec9,,,active",
|
|
"S001S,C001S,Sec1,,,active",
|
|
"S002S,C002S,Sec2,,,active",
|
|
"S003S,C003S,Sec3,,,active",
|
|
"S004S,C004S,Sec4,,,active",
|
|
"S005S,C005S,Sec5,,,active",
|
|
"S006S,C006S,Sec6,,,active",
|
|
"S007S,C007S,Sec7,,,deleted",
|
|
"S008S,C001S,Sec8,,,deleted",
|
|
"S009S,C008S,Sec9,,,active"
|
|
])
|
|
process_csv_data_cleanly([
|
|
"course_id,user_id,role,section_id,status,associated_user_id",
|
|
",U001,student,S001,active,",
|
|
",U002,student,S002,active,",
|
|
",U003,student,S003,active,",
|
|
",U004,student,S004,active,",
|
|
",U005,student,S005,active,",
|
|
",U006,student,S006,deleted,",
|
|
",U007,student,S007,active,",
|
|
",U008,student,S008,active,",
|
|
",U009,student,S005,deleted,",
|
|
",U001,student,S001S,active,",
|
|
",U002,student,S002S,active,",
|
|
",U003,student,S003S,active,",
|
|
",U004,student,S004S,active,",
|
|
",U005,student,S005S,active,",
|
|
",U006,student,S006S,deleted,",
|
|
",U007,student,S007S,active,",
|
|
",U008,student,S008S,active,",
|
|
",U009,student,S005S,deleted,"
|
|
])
|
|
|
|
end
|
|
|
|
context "fast list" do
|
|
it "should list associated courses" do
|
|
@account.fast_all_courses.map(&:sis_source_id).sort.should == [
|
|
"C001", "C005", "C006", "C007", "C008", "C009",
|
|
"C001S", "C005S", "C006S", "C007S", "C008S", "C009S", ].sort
|
|
end
|
|
|
|
it "should list associated courses by term" do
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T001")}).map(&:sis_source_id).sort.should == ["C001", "C001S"]
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T002")}).map(&:sis_source_id).sort.should == []
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T003")}).map(&:sis_source_id).sort.should == ["C005", "C006", "C007", "C008", "C009", "C005S", "C006S", "C007S", "C008S", "C009S"].sort
|
|
end
|
|
|
|
it "should list associated nonenrollmentless courses" do
|
|
@account.fast_all_courses({:hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C001", "C005", "C007", "C001S", "C005S", "C007S"].sort #C007 probably shouldn't be here, cause the enrollment section is deleted, but we kinda want to minimize database traffic
|
|
end
|
|
|
|
it "should list associated nonenrollmentless courses by term" do
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T001"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C001", "C001S"]
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T002"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == []
|
|
@account.fast_all_courses({:term => EnrollmentTerm.find_by_sis_source_id("T003"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C005", "C007", "C005S", "C007S"].sort
|
|
end
|
|
end
|
|
|
|
context "name searching" do
|
|
it "should list associated courses" do
|
|
@account.courses_name_like("search").map(&:sis_source_id).sort.should == [
|
|
"C001S", "C005S", "C006S", "C007S", "C008S", "C009S"]
|
|
end
|
|
|
|
it "should list associated courses by term" do
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T001")}).map(&:sis_source_id).sort.should == ["C001S"]
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T002")}).map(&:sis_source_id).sort.should == []
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T003")}).map(&:sis_source_id).sort.should == ["C005S", "C006S", "C007S", "C008S", "C009S"]
|
|
end
|
|
|
|
it "should list associated nonenrollmentless courses" do
|
|
@account.courses_name_like("search", {:hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C001S", "C005S", "C007S"] #C007 probably shouldn't be here, cause the enrollment section is deleted, but we kinda want to minimize database traffic
|
|
end
|
|
|
|
it "should list associated nonenrollmentless courses by term" do
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T001"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C001S"]
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T002"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == []
|
|
@account.courses_name_like("search", {:term => EnrollmentTerm.find_by_sis_source_id("T003"), :hide_enrollmentless_courses => true}).map(&:sis_source_id).sort.should == ["C005S", "C007S"]
|
|
end
|
|
end
|
|
end
|
|
|
|
context "services" do
|
|
before(:each) do
|
|
@a = Account.new
|
|
end
|
|
it "should be able to specify a list of enabled services" do
|
|
@a.allowed_services = 'facebook,twitter'
|
|
@a.service_enabled?(:facebook).should be_true
|
|
@a.service_enabled?(:twitter).should be_true
|
|
@a.service_enabled?(:diigo).should be_false
|
|
@a.service_enabled?(:avatars).should be_false
|
|
end
|
|
|
|
it "should not enable services off by default" do
|
|
@a.service_enabled?(:facebook).should be_true
|
|
@a.service_enabled?(:avatars).should be_false
|
|
end
|
|
|
|
it "should add and remove services from the defaults" do
|
|
@a.allowed_services = '+avatars,-facebook'
|
|
@a.service_enabled?(:avatars).should be_true
|
|
@a.service_enabled?(:twitter).should be_true
|
|
@a.service_enabled?(:facebook).should be_false
|
|
end
|
|
|
|
it "should allow settings services" do
|
|
lambda {@a.enable_service(:completly_bogs)}.should raise_error
|
|
|
|
@a.disable_service(:twitter)
|
|
@a.service_enabled?(:twitter).should be_false
|
|
|
|
@a.enable_service(:twitter)
|
|
@a.service_enabled?(:twitter).should be_true
|
|
end
|
|
|
|
it "should use + and - by default when setting service availabilty" do
|
|
@a.enable_service(:twitter)
|
|
@a.service_enabled?(:twitter).should be_true
|
|
@a.allowed_services.should be_nil
|
|
|
|
@a.disable_service(:twitter)
|
|
@a.allowed_services.should match('\-twitter')
|
|
|
|
@a.disable_service(:avatars)
|
|
@a.service_enabled?(:avatars).should be_false
|
|
@a.allowed_services.should_not match('avatars')
|
|
|
|
@a.enable_service(:avatars)
|
|
@a.service_enabled?(:avatars).should be_true
|
|
@a.allowed_services.should match('\+avatars')
|
|
end
|
|
|
|
it "should be able to set service availibity for previously hard-coded values" do
|
|
@a.allowed_services = 'avatars,facebook'
|
|
|
|
@a.enable_service(:twitter)
|
|
@a.service_enabled?(:twitter).should be_true
|
|
@a.allowed_services.should match(/twitter/)
|
|
@a.allowed_services.should_not match(/[+-]/)
|
|
|
|
@a.disable_service(:facebook)
|
|
@a.allowed_services.should_not match(/facebook/)
|
|
@a.allowed_services.should_not match(/[+-]/)
|
|
|
|
@a.disable_service(:avatars)
|
|
@a.disable_service(:twitter)
|
|
@a.allowed_services.should be_nil
|
|
end
|
|
|
|
it "should not wipe out services that are substrings of each other" do
|
|
@a.disable_service('google_docs_previews')
|
|
@a.disable_service('google_docs')
|
|
@a.allowed_services.should == '-google_docs_previews,-google_docs'
|
|
end
|
|
|
|
describe "services_exposed_to_ui_hash" do
|
|
it "should return all ui services by default" do
|
|
Account.services_exposed_to_ui_hash.keys.should == Account.allowable_services.reject { |h,k| !k[:expose_to_ui] }.keys
|
|
end
|
|
|
|
it "should return services of a type if specified" do
|
|
Account.services_exposed_to_ui_hash(:setting).keys.should == Account.allowable_services.reject { |h,k| k[:expose_to_ui] != :setting }.keys
|
|
end
|
|
end
|
|
|
|
describe "plugin services" do
|
|
before do
|
|
Account.register_service(:myplugin, { :name => "My Plugin", :description => "", :expose_to_ui => :setting, :default => false })
|
|
end
|
|
|
|
it "should return the service" do
|
|
Account.allowable_services.keys.should be_include(:myplugin)
|
|
end
|
|
|
|
it "should allow setting the service" do
|
|
@a.service_enabled?(:myplugin).should be_false
|
|
|
|
@a.enable_service(:myplugin)
|
|
@a.service_enabled?(:myplugin).should be_true
|
|
@a.allowed_services.should match(/\+myplugin/)
|
|
|
|
@a.disable_service(:myplugin)
|
|
@a.service_enabled?(:myplugin).should be_false
|
|
@a.allowed_services.should be_blank
|
|
end
|
|
|
|
describe "services_exposed_to_ui_hash" do
|
|
it "should return services defined in a plugin" do
|
|
Account.services_exposed_to_ui_hash().keys.should be_include(:myplugin)
|
|
Account.services_exposed_to_ui_hash(:setting).keys.should be_include(:myplugin)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "settings=" do
|
|
it "should filter disabled settings" do
|
|
a = Account.new
|
|
a.root_account_id = 1
|
|
a.settings = {'global_javascript' => 'something'}.with_indifferent_access
|
|
a.settings[:global_javascript].should eql(nil)
|
|
|
|
a.root_account_id = nil
|
|
a.settings = {'global_javascript' => 'something'}.with_indifferent_access
|
|
a.settings[:global_javascript].should eql(nil)
|
|
|
|
a.settings[:global_includes] = true
|
|
a.settings = {'global_javascript' => 'something'}.with_indifferent_access
|
|
a.settings[:global_javascript].should eql('something')
|
|
|
|
a.settings = {'error_reporting' => 'string'}.with_indifferent_access
|
|
a.settings[:error_reporting].should eql(nil)
|
|
|
|
a.settings = {'error_reporting' => {
|
|
'action' => 'email',
|
|
'email' => 'bob@yahoo.com',
|
|
'extra' => 'something'
|
|
}}.with_indifferent_access
|
|
a.settings[:error_reporting].should be_is_a(Hash)
|
|
a.settings[:error_reporting][:action].should eql('email')
|
|
a.settings[:error_reporting][:email].should eql('bob@yahoo.com')
|
|
a.settings[:error_reporting][:extra].should eql(nil)
|
|
end
|
|
end
|
|
|
|
context "turnitin secret" do
|
|
it "should decrypt the turnitin secret to the original value" do
|
|
a = Account.new
|
|
a.turnitin_shared_secret = "asdf"
|
|
a.turnitin_shared_secret.should eql("asdf")
|
|
a.turnitin_shared_secret = "2t87aot72gho8a37gh4g[awg'waegawe-,v-3o7fya23oya2o3"
|
|
a.turnitin_shared_secret.should eql("2t87aot72gho8a37gh4g[awg'waegawe-,v-3o7fya23oya2o3")
|
|
end
|
|
end
|
|
|
|
it "should make a default enrollment term if necessary" do
|
|
a = Account.create!(:name => "nada")
|
|
a.enrollment_terms.size.should == 1
|
|
a.enrollment_terms.first.name.should == EnrollmentTerm::DEFAULT_TERM_NAME
|
|
|
|
# don't create a new default term for sub-accounts
|
|
a2 = a.all_accounts.create!(:name => "sub")
|
|
a2.enrollment_terms.size.should == 0
|
|
end
|
|
|
|
def account_with_admin_and_restricted_user(account)
|
|
account.add_account_membership_type('Restricted Admin')
|
|
admin = User.create
|
|
user = User.create
|
|
account.account_users.create(:user => admin, :membership_type => 'AccountAdmin')
|
|
account.account_users.create(:user => user, :membership_type => 'Restricted Admin')
|
|
[ admin, user ]
|
|
end
|
|
|
|
|
|
it "should set up access policy correctly" do
|
|
# stub out any "if" permission conditions
|
|
RoleOverride.permissions.each do |k, v|
|
|
next unless v[:if]
|
|
Account.any_instance.stubs(v[:if]).returns(true)
|
|
end
|
|
|
|
# Set up a hierarchy of 4 accounts - a root account, a sub account,
|
|
# a sub sub account, and SiteAdmin account. Create a 'Restricted Admin'
|
|
# role in each one, and create an admin user and a user in the restricted
|
|
# admin role for each one
|
|
root_account = Account.create
|
|
sub_account = Account.create(:parent_account => root_account)
|
|
sub_sub_account = Account.create(:parent_account => sub_account)
|
|
|
|
hash = {}
|
|
hash[:site_admin] = { :account => Account.site_admin}
|
|
hash[:root] = { :account => root_account}
|
|
hash[:sub] = { :account => sub_account}
|
|
hash[:sub_sub] = { :account => sub_sub_account}
|
|
|
|
hash.each do |k, v|
|
|
v[:account].update_attribute(:settings, {:no_enrollments_can_create_courses => false})
|
|
admin, user = account_with_admin_and_restricted_user(v[:account])
|
|
hash[k][:admin] = admin
|
|
hash[k][:user] = user
|
|
end
|
|
|
|
limited_access = [ :read, :manage, :update, :delete, :read_outcomes ]
|
|
full_access = RoleOverride.permissions.map { |k, v| k } + limited_access
|
|
index = full_access.index(:manage_courses)
|
|
full_access = full_access[0..index] + [:create_courses] + full_access[index+1..-1]
|
|
# site admin has access to everything everywhere
|
|
hash.each do |k, v|
|
|
account = v[:account]
|
|
account.check_policy(hash[:site_admin][:admin]).should == full_access + (k == :site_admin ? [:read_global_outcomes] : [])
|
|
account.check_policy(hash[:site_admin][:user]).should == limited_access + (k == :site_admin ? [:read_global_outcomes] : [])
|
|
end
|
|
|
|
# root admin has access to everything except site admin
|
|
account = hash[:site_admin][:account]
|
|
account.check_policy(hash[:root][:admin]).should == [:read_global_outcomes]
|
|
account.check_policy(hash[:root][:user]).should == [:read_global_outcomes]
|
|
hash.each do |k, v|
|
|
next if k == :site_admin
|
|
account = v[:account]
|
|
account.check_policy(hash[:root][:admin]).should == full_access
|
|
account.check_policy(hash[:root][:user]).should == limited_access
|
|
end
|
|
|
|
# sub account has access to sub and sub_sub
|
|
hash.each do |k, v|
|
|
next unless k == :site_admin || k == :root
|
|
account = v[:account]
|
|
account.check_policy(hash[:sub][:admin]).should == (k == :site_admin ? [:read_global_outcomes] : [:read_outcomes])
|
|
account.check_policy(hash[:sub][:user]).should == (k == :site_admin ? [:read_global_outcomes] : [:read_outcomes])
|
|
end
|
|
hash.each do |k, v|
|
|
next if k == :site_admin || k == :root
|
|
account = v[:account]
|
|
account.check_policy(hash[:sub][:admin]).should == full_access
|
|
account.check_policy(hash[:sub][:user]).should == limited_access
|
|
end
|
|
|
|
# Grant 'Restricted Admin' a specific permission, and re-check everything
|
|
some_access = [:read_reports] + limited_access
|
|
hash.each do |k, v|
|
|
account = v[:account]
|
|
account.role_overrides.create(:permission => 'read_reports', :enrollment_type => 'Restricted Admin', :enabled => true)
|
|
end
|
|
RoleOverride.clear_cached_contexts
|
|
hash.each do |k, v|
|
|
account = v[:account]
|
|
account.check_policy(hash[:site_admin][:admin]).should == full_access + (k == :site_admin ? [:read_global_outcomes] : [])
|
|
account.check_policy(hash[:site_admin][:user]).should == some_access + (k == :site_admin ? [:read_global_outcomes] : [])
|
|
end
|
|
|
|
account = hash[:site_admin][:account]
|
|
account.check_policy(hash[:root][:admin]).should == [:read_global_outcomes]
|
|
account.check_policy(hash[:root][:user]).should == [:read_global_outcomes]
|
|
hash.each do |k, v|
|
|
next if k == :site_admin
|
|
account = v[:account]
|
|
account.check_policy(hash[:root][:admin]).should == full_access
|
|
account.check_policy(hash[:root][:user]).should == some_access
|
|
end
|
|
|
|
# sub account has access to sub and sub_sub
|
|
hash.each do |k, v|
|
|
next unless k == :site_admin || k == :root
|
|
account = v[:account]
|
|
account.check_policy(hash[:sub][:admin]).should == (k == :site_admin ? [:read_global_outcomes] : [:read_outcomes])
|
|
account.check_policy(hash[:sub][:user]).should == (k == :site_admin ? [:read_global_outcomes] : [:read_outcomes])
|
|
end
|
|
hash.each do |k, v|
|
|
next if k == :site_admin || k == :root
|
|
account = v[:account]
|
|
account.check_policy(hash[:sub][:admin]).should == full_access
|
|
account.check_policy(hash[:sub][:user]).should == some_access
|
|
end
|
|
end
|
|
|
|
it "should correctly return sub-accounts as options" do
|
|
a = Account.default
|
|
sub = Account.create!(:name => 'sub', :parent_account => a)
|
|
sub2 = Account.create!(:name => 'sub2', :parent_account => a)
|
|
sub2_1 = Account.create!(:name => 'sub2-1', :parent_account => sub2)
|
|
options = a.sub_accounts_as_options
|
|
options.should ==
|
|
[
|
|
["Default Account", a.id],
|
|
[" sub", sub.id],
|
|
[" sub2", sub2.id],
|
|
[" sub2-1", sub2_1.id]
|
|
]
|
|
end
|
|
|
|
it "should return the correct user count" do
|
|
a = Account.default
|
|
a.all_users.count.should == a.user_count
|
|
a.user_count.should == 0
|
|
|
|
u = User.create!
|
|
a.add_user(u)
|
|
a.all_users.count.should == a.user_count(:reload)
|
|
a.user_count.should == 1
|
|
|
|
course_with_teacher
|
|
@teacher.update_account_associations
|
|
a.all_users.count.should == a.user_count(:reload)
|
|
a.user_count.should == 2
|
|
|
|
a2 = a.sub_accounts.create!
|
|
course_with_teacher(:account => a2)
|
|
@teacher.update_account_associations
|
|
a.all_users.count.should == a.user_count(:reload)
|
|
a.user_count.should == 3
|
|
|
|
user_with_pseudonym
|
|
a.all_users.count.should == a.user_count(:reload)
|
|
a.user_count.should == 4
|
|
|
|
end
|
|
|
|
it "group_categories should not include deleted categories" do
|
|
account = Account.default
|
|
account.group_categories.count.should == 0
|
|
category1 = account.group_categories.create(:name => 'category 1')
|
|
category2 = account.group_categories.create(:name => 'category 2')
|
|
account.group_categories.count.should == 2
|
|
category1.destroy
|
|
account.reload
|
|
account.group_categories.count.should == 1
|
|
account.group_categories.to_a.should == [category2]
|
|
end
|
|
|
|
it "all_group_categories should include deleted categories" do
|
|
account = Account.default
|
|
account.all_group_categories.count.should == 0
|
|
category1 = account.group_categories.create(:name => 'category 1')
|
|
category2 = account.group_categories.create(:name => 'category 2')
|
|
account.all_group_categories.count.should == 2
|
|
category1.destroy
|
|
account.reload
|
|
account.all_group_categories.count.should == 2
|
|
end
|
|
|
|
it "should return correct values for login_handle_name based on authorization_config" do
|
|
account = Account.default
|
|
account.login_handle_name.should == "Email"
|
|
|
|
config = account.account_authorization_configs.create(:auth_type => 'cas')
|
|
account.login_handle_name.should == "Login"
|
|
|
|
config.auth_type = 'saml'
|
|
config.save
|
|
account.reload.login_handle_name.should == "Login"
|
|
|
|
config.auth_type = 'ldap'
|
|
config.save
|
|
account.reload.login_handle_name.should == "Email"
|
|
config.login_handle_name = "LDAP Login"
|
|
config.save
|
|
account.reload.login_handle_name.should == "LDAP Login"
|
|
end
|
|
|
|
context "users_not_in_groups" do
|
|
before :each do
|
|
@account = Account.default
|
|
@user1 = account_admin_user(:account => @account)
|
|
@user2 = account_admin_user(:account => @account)
|
|
@user3 = account_admin_user(:account => @account)
|
|
end
|
|
|
|
it "should not include deleted users" do
|
|
@user1.destroy
|
|
@account.users_not_in_groups([]).size.should == 2
|
|
end
|
|
|
|
it "should not include users in one of the groups" do
|
|
group = @account.groups.create
|
|
group.add_user(@user1)
|
|
users = @account.users_not_in_groups([group])
|
|
users.size.should == 2
|
|
users.should_not be_include(@user1)
|
|
end
|
|
|
|
it "should include users otherwise" do
|
|
group = @account.groups.create
|
|
group.add_user(@user1)
|
|
users = @account.users_not_in_groups([group])
|
|
users.should be_include(@user2)
|
|
users.should be_include(@user3)
|
|
end
|
|
end
|
|
|
|
it "should order results of paginate_users_not_in_groups by user's sortable name" do
|
|
@account = Account.default
|
|
@user1 = account_admin_user(:account => @account); @user1.sortable_name = 'jonny'; @user1.save
|
|
@user2 = account_admin_user(:account => @account); @user2.sortable_name = 'bob'; @user2.save
|
|
@user3 = account_admin_user(:account => @account); @user3.sortable_name = 'richard'; @user3.save
|
|
users = @account.paginate_users_not_in_groups([], 1)
|
|
users.map{ |u| u.id }.should == [@user2.id, @user1.id, @user3.id]
|
|
end
|
|
|
|
context "tabs_available" do
|
|
it "should include 'Developer Keys' for the authorized users of the site_admin account" do
|
|
account_admin_user(:account => Account.site_admin)
|
|
tabs = Account.site_admin.tabs_available(@admin)
|
|
tabs.map{|t| t[:id] }.should be_include(Account::TAB_DEVELOPER_KEYS)
|
|
|
|
tabs = Account.site_admin.tabs_available(nil)
|
|
tabs.map{|t| t[:id] }.should_not be_include(Account::TAB_DEVELOPER_KEYS)
|
|
end
|
|
|
|
it "should not include 'Developer Keys' for non-site_admin accounts" do
|
|
@account = Account.default.sub_accounts.create!(:name => "sub-account")
|
|
tabs = @account.tabs_available(nil)
|
|
tabs.map{|t| t[:id] }.should_not be_include(Account::TAB_DEVELOPER_KEYS)
|
|
|
|
tabs = @account.root_account.tabs_available(nil)
|
|
tabs.map{|t| t[:id] }.should_not be_include(Account::TAB_DEVELOPER_KEYS)
|
|
end
|
|
|
|
it "should not include external tools if not configured for course navigation" do
|
|
@account = Account.default.sub_accounts.create!(:name => "sub-account")
|
|
tool = @account.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob", :domain => "example.com")
|
|
tool.settings[:user_navigation] = {:url => "http://www.example.com", :text => "Example URL"}
|
|
tool.save!
|
|
tool.has_account_navigation.should == false
|
|
tabs = @account.tabs_available(nil)
|
|
tabs.map{|t| t[:id] }.should_not be_include(tool.asset_string)
|
|
end
|
|
|
|
it "should include active external tools if configured on the account" do
|
|
@account = Account.default.sub_accounts.create!(:name => "sub-account")
|
|
tools = []
|
|
2.times do |n|
|
|
t = @account.context_external_tools.new(
|
|
:name => "bob",
|
|
:consumer_key => "bob",
|
|
:shared_secret => "bob",
|
|
:domain => "example.com"
|
|
)
|
|
t.account_navigation = {
|
|
:text => "Example URL",
|
|
:url => "http://www.example.com",
|
|
}
|
|
t.save!
|
|
tools << t
|
|
end
|
|
tool1, tool2 = tools
|
|
tool2.destroy
|
|
|
|
tools.each { |t| t.has_account_navigation.should == true }
|
|
|
|
tabs = @account.tabs_available
|
|
tab_ids = tabs.map{|t| t[:id] }
|
|
tab_ids.should be_include(tool1.asset_string)
|
|
tab_ids.should_not be_include(tool2.asset_string)
|
|
tab = tabs.detect{|t| t[:id] == tool1.asset_string }
|
|
tab[:label].should == tool1.settings[:account_navigation][:text]
|
|
tab[:href].should == :account_external_tool_path
|
|
tab[:args].should == [@account.id, tool1.id]
|
|
end
|
|
|
|
it "should include external tools if configured on the root account" do
|
|
@account = Account.default.sub_accounts.create!(:name => "sub-account")
|
|
tool = @account.context_external_tools.new(:name => "bob", :consumer_key => "bob", :shared_secret => "bob", :domain => "example.com")
|
|
tool.settings[:account_navigation] = {:url => "http://www.example.com", :text => "Example URL"}
|
|
tool.save!
|
|
tool.has_account_navigation.should == true
|
|
tabs = @account.tabs_available(nil)
|
|
tabs.map{|t| t[:id] }.should be_include(tool.asset_string)
|
|
tab = tabs.detect{|t| t[:id] == tool.asset_string }
|
|
tab[:label].should == tool.settings[:account_navigation][:text]
|
|
tab[:href].should == :account_external_tool_path
|
|
tab[:args].should == [@account.id, tool.id]
|
|
end
|
|
end
|
|
|
|
describe "fast_all_users" do
|
|
it "should preserve sortable_name" do
|
|
user_with_pseudonym(:active_all => 1)
|
|
@user.update_attributes(:name => "John St. Clair", :sortable_name => "St. Clair, John")
|
|
@johnstclair = @user
|
|
user_with_pseudonym(:active_all => 1, :username => 'jt@instructure.com', :name => 'JT Olds')
|
|
@jtolds = @user
|
|
Account.default.fast_all_users.should == [@jtolds, @johnstclair]
|
|
end
|
|
end
|
|
|
|
it "should not allow setting an sis id for a root account" do
|
|
@account = Account.create!
|
|
@account.sis_source_id = 'abc'
|
|
@account.save.should be_false
|
|
end
|
|
|
|
describe "user_list_search_mode_for" do
|
|
it "should be preferred for anyone if open registration is turned on" do
|
|
account = Account.default
|
|
account.settings = { :open_registration => true }
|
|
account.user_list_search_mode_for(nil).should == :preferred
|
|
account.user_list_search_mode_for(user).should == :preferred
|
|
end
|
|
|
|
it "should be preferred for account admins" do
|
|
account = Account.default
|
|
account.user_list_search_mode_for(nil).should == :closed
|
|
account.user_list_search_mode_for(user).should == :closed
|
|
user
|
|
account.add_user(@user)
|
|
account.user_list_search_mode_for(@user).should == :preferred
|
|
end
|
|
end
|
|
|
|
context "settings" do
|
|
describe ":condition" do
|
|
it "should not allow setting things where condition is false" do
|
|
account = Account.default
|
|
account.stubs(:global_includes?).returns(false)
|
|
account.settings = { :global_javascript => 'bob' }
|
|
account.settings[:global_javascript].should be_nil
|
|
account.stubs(:global_includes?).returns(true)
|
|
account.settings = { :global_javascript => 'bob' }
|
|
account.settings[:global_javascript].should == 'bob'
|
|
end
|
|
end
|
|
end
|
|
|
|
context "sharding" do
|
|
it_should_behave_like "sharding"
|
|
|
|
it "should properly return site admin permissions regardless of active shard" do
|
|
enable_cache do
|
|
user
|
|
site_admin = Account.site_admin
|
|
site_admin.add_user(@user)
|
|
|
|
@shard1.activate do
|
|
site_admin.grants_right?(@user, nil, :manage_site_settings).should be_true
|
|
end
|
|
site_admin.grants_right?(@user, nil, :manage_site_settings).should be_true
|
|
|
|
user
|
|
@shard1.activate do
|
|
site_admin.grants_right?(@user, nil, :manage_site_settings).should be_false
|
|
end
|
|
site_admin.grants_right?(@user, nil, :manage_site_settings).should be_false
|
|
end
|
|
end
|
|
end
|
|
|
|
context "permissions" do
|
|
it "should grant :read_sis to teachers" do
|
|
user_with_pseudonym(:active_all => 1)
|
|
Account.default.grants_right?(@user, :read_sis).should be_false
|
|
@course = Account.default.courses.create!
|
|
@course.enroll_teacher(@user).accept!
|
|
Account.default.grants_right?(@user, :read_sis).should be_true
|
|
end
|
|
|
|
it "should grant :read_global_outcomes to any user iff site_admin" do
|
|
@site_admin = Account.site_admin
|
|
@site_admin.grants_right?(User.new, :read_global_outcomes).should be_true
|
|
|
|
@subaccount = @site_admin.sub_accounts.create!
|
|
@subaccount.grants_right?(User.new, :read_global_outcomes).should be_false
|
|
end
|
|
|
|
it "should not grant :read_outcomes to user's outside the account" do
|
|
Account.default.grants_right?(User.new, :read_outcomes).should be_false
|
|
end
|
|
|
|
it "should grant :read_outcomes to account admins" do
|
|
account_admin_user(:account => Account.default)
|
|
Account.default.grants_right?(@admin, :read_outcomes).should be_true
|
|
end
|
|
|
|
it "should grant :read_outcomes to subaccount admins" do
|
|
account_admin_user(:account => Account.default.sub_accounts.create!)
|
|
Account.default.grants_right?(@admin, :read_outcomes).should be_true
|
|
end
|
|
|
|
it "should grant :read_outcomes to enrollees in account courses" do
|
|
course(:account => Account.default)
|
|
teacher_in_course
|
|
student_in_course
|
|
Account.default.grants_right?(@teacher, :read_outcomes).should be_true
|
|
Account.default.grants_right?(@student, :read_outcomes).should be_true
|
|
end
|
|
|
|
it "should grant :read_outcomes to enrollees in subaccount courses" do
|
|
course(:account => Account.default.sub_accounts.create!)
|
|
teacher_in_course
|
|
student_in_course
|
|
Account.default.grants_right?(@teacher, :read_outcomes).should be_true
|
|
Account.default.grants_right?(@student, :read_outcomes).should be_true
|
|
end
|
|
end
|
|
|
|
describe "canvas_authentication?" do
|
|
it "should be true if there's not an AAC" do
|
|
Account.default.settings[:canvas_authentication] = false
|
|
Account.default.canvas_authentication?.should be_true
|
|
Account.default.account_authorization_configs.create!(:auth_type => 'ldap')
|
|
Account.default.canvas_authentication?.should be_false
|
|
end
|
|
end
|
|
|
|
context "manually created courses account" do
|
|
it "should still work with existing manually created courses accounts" do
|
|
acct = Account.default
|
|
sub = acct.sub_accounts.create!(:name => "Manually-Created Courses")
|
|
manual_courses_account = acct.manually_created_courses_account
|
|
manual_courses_account.id.should == sub.id
|
|
acct.reload.settings[:manually_created_courses_account_id].should == sub.id
|
|
end
|
|
|
|
it "should not create a duplicate manual courses account when locale changes" do
|
|
acct = Account.default
|
|
sub1 = acct.manually_created_courses_account
|
|
I18n.locale = "es"
|
|
sub2 = acct.manually_created_courses_account
|
|
I18n.locale = "en"
|
|
sub1.id.should == sub2.id
|
|
end
|
|
|
|
it "should work if the saved account id doesn't exist" do
|
|
acct = Account.default
|
|
acct.settings[:manually_created_courses_account_id] = acct.id + 1000
|
|
acct.save!
|
|
acct.manually_created_courses_account.should be_present
|
|
end
|
|
|
|
it "should work if the saved account id is not a sub-account" do
|
|
acct = Account.default
|
|
bad_acct = Account.create!
|
|
acct.settings[:manually_created_courses_account_id] = bad_acct.id
|
|
acct.save!
|
|
manual_course_account = acct.manually_created_courses_account
|
|
manual_course_account.id.should_not == bad_acct.id
|
|
end
|
|
end
|
|
|
|
describe "account_users_for" do
|
|
it "should be cache coherent for site admin" do
|
|
enable_cache do
|
|
user
|
|
sa = Account.site_admin
|
|
sa.account_users_for(@user).should == []
|
|
|
|
au = sa.add_user(@user)
|
|
# out-of-proc cache should clear, but we have to manually clear
|
|
# the in-proc cache
|
|
sa = Account.find(sa)
|
|
sa.account_users_for(@user).should == [au]
|
|
|
|
au.destroy
|
|
#ditto
|
|
sa = Account.find(sa)
|
|
sa.account_users_for(@user).should == []
|
|
end
|
|
end
|
|
end
|
|
end
|