2011-02-01 09:57:29 +08:00
|
|
|
#
|
|
|
|
# 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/>.
|
|
|
|
#
|
|
|
|
|
|
|
|
ENV["RAILS_ENV"] = 'test'
|
|
|
|
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
|
|
|
require 'spec'
|
|
|
|
# require 'spec/autorun'
|
|
|
|
require 'spec/rails'
|
|
|
|
require 'webrat'
|
2011-10-26 07:15:30 +08:00
|
|
|
require 'mocha'
|
2011-02-01 09:57:29 +08:00
|
|
|
|
|
|
|
Dir.glob("#{File.dirname(__FILE__).gsub(/\\/, "/")}/factories/*.rb").each { |file| require file }
|
|
|
|
|
2011-09-29 14:50:20 +08:00
|
|
|
ALL_MODELS = (ActiveRecord::Base.send(:subclasses) +
|
|
|
|
Dir["#{RAILS_ROOT}/app/models/*", "#{RAILS_ROOT}/vendor/plugins/*/app/models/*"].collect { |file|
|
|
|
|
model = File.basename(file, ".*").camelize.constantize
|
|
|
|
next unless model < ActiveRecord::Base
|
|
|
|
model
|
|
|
|
}).compact.uniq.reject { |model| model.superclass != ActiveRecord::Base || model == Tableless }
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2011-02-10 01:16:29 +08:00
|
|
|
# rspec aliases :describe to :context in a way that it's pretty much defined
|
|
|
|
# globally on every object. :context is already heavily used in our application,
|
|
|
|
# so we remove rspec's definition.
|
|
|
|
module Spec::DSL::Main
|
|
|
|
remove_method :context
|
|
|
|
end
|
|
|
|
|
2011-06-06 23:32:11 +08:00
|
|
|
def truncate_table(model)
|
|
|
|
case model.connection.adapter_name
|
|
|
|
when "SQLite"
|
|
|
|
model.delete_all
|
|
|
|
else
|
|
|
|
model.connection.execute("TRUNCATE TABLE #{model.connection.quote_table_name(model.table_name)}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# wipe out the test db, in case some non-transactional tests crapped out before
|
|
|
|
# cleaning up after themselves
|
|
|
|
ALL_MODELS.each { |m| truncate_table(m) }
|
|
|
|
|
2011-10-01 04:22:22 +08:00
|
|
|
|
|
|
|
# Make AR not puke if MySQL auto-commits the transaction
|
|
|
|
class ActiveRecord::ConnectionAdapters::MysqlAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter
|
|
|
|
def outside_transaction?
|
|
|
|
# MySQL ignores creation of savepoints outside of a transaction; so if we can create one
|
|
|
|
# and then can't release it because it doesn't exist, we're not in a transaction
|
|
|
|
execute('SAVEPOINT outside_transaction')
|
|
|
|
!!execute('RELEASE SAVEPOINT outside_transaction') rescue true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
Spec::Runner.configure do |config|
|
|
|
|
# If you're not using ActiveRecord you should remove these
|
|
|
|
# lines, delete config/database.yml and disable :active_record
|
|
|
|
# in your config/boot.rb
|
|
|
|
config.use_transactional_fixtures = true
|
|
|
|
config.use_instantiated_fixtures = false
|
|
|
|
config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
|
2011-10-26 07:15:30 +08:00
|
|
|
config.mock_with :mocha
|
2011-02-01 09:57:29 +08:00
|
|
|
|
|
|
|
config.include Webrat::Matchers, :type => :views
|
|
|
|
|
2011-02-09 04:34:00 +08:00
|
|
|
config.before :each do
|
|
|
|
Time.zone = 'UTC'
|
|
|
|
Account.default.update_attribute(:default_time_zone, 'UTC')
|
2011-09-02 23:34:12 +08:00
|
|
|
Setting.reset_cache!
|
2011-02-09 04:34:00 +08:00
|
|
|
end
|
|
|
|
|
2011-11-01 06:41:20 +08:00
|
|
|
def use_remote_services; ENV['ACTUALLY_TALK_TO_REMOTE_SERVICES'].to_i > 0; end
|
|
|
|
|
2011-04-08 07:01:32 +08:00
|
|
|
def account_with_cas(opts={})
|
2011-10-28 02:51:15 +08:00
|
|
|
@account = opts[:account]
|
|
|
|
@account ||= Account.create!
|
2011-04-08 07:01:32 +08:00
|
|
|
config = AccountAuthorizationConfig.new
|
|
|
|
cas_url = opts[:cas_url] || "https://localhost/cas"
|
|
|
|
config.auth_type = "cas"
|
|
|
|
config.auth_base = cas_url
|
2011-05-16 06:27:44 +08:00
|
|
|
config.log_in_url = opts[:cas_log_in_url] if opts[:cas_log_in_url]
|
2011-10-28 02:51:15 +08:00
|
|
|
@account.account_authorization_configs << config
|
|
|
|
@account
|
2011-04-08 07:01:32 +08:00
|
|
|
end
|
|
|
|
|
2011-06-30 05:54:34 +08:00
|
|
|
def account_with_saml(opts={})
|
2011-10-28 02:51:15 +08:00
|
|
|
@account = opts[:account]
|
|
|
|
@account ||= Account.create!
|
2011-06-30 05:54:34 +08:00
|
|
|
config = AccountAuthorizationConfig.new
|
|
|
|
config.auth_type = "saml"
|
|
|
|
config.log_in_url = opts[:saml_log_in_url] if opts[:saml_log_in_url]
|
2011-10-28 02:51:15 +08:00
|
|
|
@account.account_authorization_configs << config
|
|
|
|
@account
|
2011-06-30 05:54:34 +08:00
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
def course(opts={})
|
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
|
|
|
@course = Course.create!(:name => opts[:course_name], :account => opts[:account])
|
2011-02-01 09:57:29 +08:00
|
|
|
@course.offer! if opts[:active_course] || opts[:active_all]
|
|
|
|
if opts[:active_all]
|
|
|
|
u = User.create!
|
|
|
|
u.register!
|
|
|
|
e = @course.enroll_teacher(u)
|
2011-02-24 13:26:39 +08:00
|
|
|
e.workflow_state = 'active'
|
|
|
|
e.save!
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
|
|
|
@course
|
|
|
|
end
|
|
|
|
|
2011-06-01 04:47:28 +08:00
|
|
|
def account_admin_user_with_role_changes(opts={})
|
|
|
|
account = opts[:account] || Account.default
|
|
|
|
if opts[:role_changes]
|
|
|
|
opts[:role_changes].each_pair do |permission, enabled|
|
2011-09-01 05:23:47 +08:00
|
|
|
account.role_overrides.create(:permission => permission.to_s, :enrollment_type => opts[:membership_type] || 'AccountAdmin', :enabled => enabled)
|
2011-06-01 04:47:28 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
account_admin_user(opts)
|
|
|
|
end
|
|
|
|
|
2011-05-05 07:06:29 +08:00
|
|
|
def account_admin_user(opts={})
|
|
|
|
user(opts)
|
2011-08-12 04:50:02 +08:00
|
|
|
@admin = @user
|
2011-06-01 04:47:28 +08:00
|
|
|
@user.account_users.create(:account => opts[:account] || Account.default, :membership_type => opts[:membership_type] || 'AccountAdmin')
|
2011-05-05 07:06:29 +08:00
|
|
|
@user
|
|
|
|
end
|
|
|
|
|
2011-10-19 00:35:41 +08:00
|
|
|
def site_admin_user(opts={})
|
|
|
|
user(opts)
|
|
|
|
@admin = @user
|
|
|
|
Account.site_admin.add_user(@user, opts[:membership_type] || 'AccountAdmin')
|
|
|
|
@user
|
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
def user(opts={})
|
2011-07-08 05:30:27 +08:00
|
|
|
@user = User.create!(:name => opts[:name])
|
2011-02-01 09:57:29 +08:00
|
|
|
@user.register! if opts[:active_user] || opts[:active_all]
|
|
|
|
@user
|
|
|
|
end
|
|
|
|
|
|
|
|
def user_with_pseudonym(opts={})
|
2011-03-05 07:34:38 +08:00
|
|
|
user(opts) unless opts[:user]
|
|
|
|
user = opts[:user] || @user
|
2011-02-01 09:57:29 +08:00
|
|
|
username = opts[:username] || "nobody@example.com"
|
|
|
|
password = opts[:password] || "asdfasdf"
|
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
|
|
|
password = nil if password == :autogenerate
|
|
|
|
@pseudonym = user.pseudonyms.create!(:account => opts[:account] || Account.default, :unique_id => username, :password => password, :password_confirmation => password)
|
|
|
|
@cc = @pseudonym.communication_channel = user.communication_channels.create!(:path_type => 'email', :path => username) do |cc|
|
|
|
|
cc.workflow_state = 'active' if opts[:active_cc] || opts[:active_all]
|
|
|
|
cc.workflow_state = opts[:cc_state] if opts[:cc_state]
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
@cc.should_not be_nil
|
|
|
|
@cc.should_not be_new_record
|
2011-03-05 07:34:38 +08:00
|
|
|
user
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def course_with_student(opts={})
|
|
|
|
course(opts)
|
2011-05-20 04:40:55 +08:00
|
|
|
student_in_course(opts)
|
|
|
|
end
|
|
|
|
|
|
|
|
def course_with_student_logged_in(opts={})
|
|
|
|
course_with_student(opts)
|
|
|
|
user_session(@user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def student_in_course(opts={})
|
|
|
|
@course ||= opts[:course] || course(opts)
|
2011-08-12 04:50:02 +08:00
|
|
|
@student = @user = opts[:user] || user(opts)
|
2011-02-01 09:57:29 +08:00
|
|
|
@enrollment = @course.enroll_student(@user)
|
2011-08-26 02:56:57 +08:00
|
|
|
@enrollment.course = @course
|
2011-02-24 13:26:39 +08:00
|
|
|
if opts[:active_enrollment] || opts[:active_all]
|
|
|
|
@enrollment.workflow_state = 'active'
|
|
|
|
@enrollment.save!
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
@course.reload
|
|
|
|
@enrollment
|
|
|
|
end
|
|
|
|
|
|
|
|
def course_with_teacher(opts={})
|
2011-11-01 06:03:05 +08:00
|
|
|
@course = opts[:course] || course(opts)
|
2011-02-01 09:57:29 +08:00
|
|
|
@user = opts[:user] || user(opts)
|
2011-03-24 06:36:58 +08:00
|
|
|
@teacher = @user
|
2011-02-01 09:57:29 +08:00
|
|
|
@enrollment = @course.enroll_teacher(@user)
|
2011-08-26 02:56:57 +08:00
|
|
|
# set the reverse association
|
|
|
|
@enrollment.course = @course
|
2011-02-01 09:57:29 +08:00
|
|
|
@enrollment.accept! if opts[:active_enrollment] || opts[:active_all]
|
|
|
|
@enrollment
|
|
|
|
end
|
|
|
|
|
|
|
|
def course_with_teacher_logged_in(opts={})
|
|
|
|
course_with_teacher(opts)
|
|
|
|
user_session(@user)
|
|
|
|
end
|
|
|
|
|
|
|
|
def group(opts={})
|
|
|
|
if opts[:group_context]
|
|
|
|
opts[:group_context].groups.create!
|
|
|
|
else
|
|
|
|
@group = Group.create!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def group_with_user(opts={})
|
|
|
|
group(opts)
|
|
|
|
user(opts)
|
2011-05-26 00:38:32 +08:00
|
|
|
@group.participating_users << @user
|
|
|
|
end
|
|
|
|
|
|
|
|
def group_with_user_logged_in(opts={})
|
|
|
|
group_with_user(opts)
|
|
|
|
user_session(@user)
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def user_session(user, pseudonym=nil)
|
2011-10-26 07:15:30 +08:00
|
|
|
pseudonym ||= mock()
|
|
|
|
pseudonym.stubs(:record).returns(user)
|
|
|
|
pseudonym.stubs(:user_id).returns(user.id)
|
|
|
|
pseudonym.stubs(:user).returns(user)
|
|
|
|
pseudonym.stubs(:login_count).returns(1)
|
|
|
|
session = mock()
|
|
|
|
session.stubs(:record).returns(pseudonym)
|
|
|
|
session.stubs(:session_credentials).returns(nil)
|
|
|
|
PseudonymSession.stubs(:find).returns(session)
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
|
|
|
|
2011-08-25 03:40:15 +08:00
|
|
|
def login_as(username = "nobody@example.com", password = "asdfasdf")
|
|
|
|
post_via_redirect "/login",
|
|
|
|
"pseudonym_session[unique_id]" => username,
|
|
|
|
"pseudonym_session[password]" => password
|
|
|
|
assert_response :success
|
|
|
|
path.should eql("/?login_success=1")
|
|
|
|
end
|
|
|
|
|
2011-08-04 23:48:19 +08:00
|
|
|
def outcome_with_rubric(opts={})
|
2011-08-11 23:13:00 +08:00
|
|
|
@outcome_group ||= LearningOutcomeGroup.default_for(@course)
|
|
|
|
@outcome = @course.created_learning_outcomes.create!(:description => '<p>This is <b>awesome</b>.</p>', :short_description => 'new outcome')
|
|
|
|
@outcome_group.add_item(@outcome)
|
|
|
|
@outcome_group.save!
|
|
|
|
|
2011-08-04 23:48:19 +08:00
|
|
|
@rubric = Rubric.new(:title => 'My Rubric', :context => @course)
|
|
|
|
@rubric.data = [
|
|
|
|
{
|
|
|
|
:points => 3,
|
|
|
|
:description => "Outcome row",
|
|
|
|
:long_description => @outcome.description,
|
|
|
|
:id => 1,
|
|
|
|
:ratings => [
|
|
|
|
{
|
|
|
|
:points => 3,
|
|
|
|
:description => "Rockin'",
|
|
|
|
:criterion_id => 1,
|
|
|
|
:id => 2
|
|
|
|
},
|
|
|
|
{
|
|
|
|
:points => 0,
|
|
|
|
:description => "Lame",
|
|
|
|
:criterion_id => 1,
|
|
|
|
:id => 3
|
|
|
|
}
|
|
|
|
],
|
|
|
|
:learning_outcome_id => @outcome.id
|
2011-08-11 23:13:00 +08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
:points => 5,
|
|
|
|
:description => "no outcome row",
|
|
|
|
:long_description => 'non outcome criterion',
|
|
|
|
:id => 2,
|
|
|
|
:ratings => [
|
|
|
|
{
|
|
|
|
:points => 5,
|
|
|
|
:description => "Amazing",
|
|
|
|
:criterion_id => 2,
|
|
|
|
:id => 4
|
|
|
|
},
|
|
|
|
{
|
|
|
|
:points => 3,
|
|
|
|
:description => "not too bad",
|
|
|
|
:criterion_id => 2,
|
|
|
|
:id => 5
|
|
|
|
},
|
|
|
|
{
|
|
|
|
:points => 0,
|
|
|
|
:description => "no bueno",
|
|
|
|
:criterion_id => 2,
|
|
|
|
:id => 6
|
|
|
|
}
|
|
|
|
]
|
2011-08-04 23:48:19 +08:00
|
|
|
}
|
|
|
|
]
|
|
|
|
@rubric.instance_variable_set('@outcomes_changed', true)
|
|
|
|
@rubric.save!
|
2011-08-11 23:13:00 +08:00
|
|
|
@rubric.update_outcome_tags
|
2011-08-04 23:48:19 +08:00
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
def eportfolio(opts={})
|
|
|
|
user(opts)
|
|
|
|
@portfolio = @user.eportfolios.create!
|
|
|
|
end
|
|
|
|
def eportfolio_with_user(opts={})
|
|
|
|
eportfolio(opts)
|
|
|
|
end
|
|
|
|
def eportfolio_with_user_logged_in(opts={})
|
|
|
|
eportfolio_with_user(opts)
|
|
|
|
user_session(@user)
|
|
|
|
end
|
|
|
|
|
2011-09-23 03:27:37 +08:00
|
|
|
def conversation(*users)
|
|
|
|
options = users.last.is_a?(Hash) ? users.pop : {}
|
|
|
|
@conversation = (options.delete(:sender) || @me || users.shift).initiate_conversation(users.map(&:id))
|
|
|
|
@conversation.add_message('test')
|
|
|
|
@conversation.update_attributes(options)
|
|
|
|
@conversation.reload
|
|
|
|
end
|
|
|
|
|
2011-10-08 05:41:19 +08:00
|
|
|
def media_object(opts={})
|
|
|
|
mo = MediaObject.new
|
|
|
|
mo.media_id = opts[:media_id] || "1234"
|
|
|
|
mo.media_type = opts[:media_type] || "video"
|
|
|
|
mo.context = opts[:context] || @user || @course
|
|
|
|
mo.user = opts[:user] || @user
|
|
|
|
mo.save!
|
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
def assert_status(status=500)
|
|
|
|
response.status.to_i.should eql(status)
|
|
|
|
end
|
|
|
|
|
|
|
|
def assert_unauthorized
|
|
|
|
assert_status(401) #unauthorized
|
|
|
|
# response.headers['Status'].should eql('401 Unauthorized')
|
|
|
|
response.should render_template("shared/unauthorized")
|
|
|
|
end
|
|
|
|
|
|
|
|
def assert_require_login
|
|
|
|
response.should be_redirect
|
|
|
|
flash[:notice].should eql("You must be logged in to access this page")
|
|
|
|
end
|
|
|
|
|
|
|
|
def default_uploaded_data
|
|
|
|
require 'action_controller'
|
|
|
|
require 'action_controller/test_process.rb'
|
|
|
|
ActionController::TestUploadedFile.new(File.expand_path(File.dirname(__FILE__) + '/fixtures/scribd_docs/doc.doc'), 'application/msword', true)
|
|
|
|
end
|
|
|
|
|
|
|
|
def valid_gradebook_csv_content
|
|
|
|
File.read(File.expand_path(File.join(File.dirname(__FILE__), %w(fixtures default_gradebook.csv))))
|
|
|
|
end
|
|
|
|
|
|
|
|
def factory_with_protected_attributes(ar_klass, attrs, do_save = true)
|
2011-05-21 06:29:34 +08:00
|
|
|
obj = ar_klass.respond_to?(:new) ? ar_klass.new : ar_klass.build
|
|
|
|
attrs.each { |k,v| obj.send("#{k}=", attrs[k]) }
|
2011-02-01 09:57:29 +08:00
|
|
|
obj.save! if do_save
|
|
|
|
obj
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_with_protected_attributes!(ar_instance, attrs)
|
|
|
|
attrs.each { |k,v| ar_instance.send("#{k}=", attrs[k]) }
|
|
|
|
ar_instance.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_with_protected_attributes(ar_instance, attrs)
|
|
|
|
update_with_protected_attributes!(ar_instance, attrs) rescue false
|
|
|
|
end
|
|
|
|
|
2011-09-22 01:36:45 +08:00
|
|
|
def process_csv_data(*lines_or_opts)
|
2011-06-14 04:39:15 +08:00
|
|
|
account_model unless @account
|
|
|
|
|
2011-09-22 01:36:45 +08:00
|
|
|
lines = lines_or_opts.reject{|thing| thing.is_a? Hash}
|
|
|
|
opts = lines_or_opts.select{|thing| thing.is_a? Hash}.inject({:allow_printing => false}, :merge)
|
|
|
|
|
2011-06-14 04:39:15 +08:00
|
|
|
tmp = Tempfile.new("sis_rspec")
|
|
|
|
path = "#{tmp.path}.csv"
|
|
|
|
tmp.close!
|
2011-09-27 07:19:39 +08:00
|
|
|
File.open(path, "w+") { |f| f.puts lines.flatten.join "\n" }
|
2011-09-22 01:36:45 +08:00
|
|
|
opts[:files] = [path]
|
2011-06-14 04:39:15 +08:00
|
|
|
|
2011-09-22 01:36:45 +08:00
|
|
|
importer = SIS::CSV::Import.process(@account, opts)
|
2011-06-14 04:39:15 +08:00
|
|
|
|
|
|
|
File.unlink path
|
|
|
|
|
|
|
|
importer
|
|
|
|
end
|
|
|
|
|
2011-09-22 01:36:45 +08:00
|
|
|
def process_csv_data_cleanly(*lines_or_opts)
|
|
|
|
importer = process_csv_data(*lines_or_opts)
|
2011-06-14 04:39:15 +08:00
|
|
|
importer.errors.should == []
|
|
|
|
importer.warnings.should == []
|
|
|
|
end
|
|
|
|
|
2011-07-16 00:30:31 +08:00
|
|
|
def enable_cache
|
|
|
|
old_cache = RAILS_CACHE
|
2011-10-22 06:36:39 +08:00
|
|
|
new_cache = ActiveSupport::Cache::MemoryStore.new
|
|
|
|
ActionController::Base.cache_store = new_cache
|
|
|
|
silence_warnings { Object.const_set(:RAILS_CACHE, new_cache) }
|
|
|
|
old_perform_caching = ActionController::Base.perform_caching
|
|
|
|
ActionController::Base.perform_caching = true
|
2011-07-16 00:30:31 +08:00
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
silence_warnings { Object.const_set(:RAILS_CACHE, old_cache) }
|
2011-10-22 06:36:39 +08:00
|
|
|
ActionController::Base.cache_store = old_cache
|
|
|
|
ActionController::Base.perform_caching = old_perform_caching
|
2011-07-16 00:30:31 +08:00
|
|
|
end
|
|
|
|
|
2011-07-20 01:47:59 +08:00
|
|
|
# enforce forgery protection, so we can verify usage of the authenticity token
|
|
|
|
def enable_forgery_protection
|
|
|
|
ActionController::Base.class_eval { alias_method :_old_protect, :allow_forgery_protection; def allow_forgery_protection; true; end }
|
|
|
|
yield
|
|
|
|
ensure
|
|
|
|
ActionController::Base.class_eval { alias_method :allow_forgery_protection, :_old_protect }
|
|
|
|
end
|
|
|
|
|
2011-08-12 00:51:57 +08:00
|
|
|
def start_test_http_server
|
|
|
|
post_lines = []
|
|
|
|
server = TCPServer.open(0)
|
|
|
|
port = server.addr[1]
|
|
|
|
post_lines = []
|
|
|
|
server_thread = Thread.new(server, post_lines) do |server, post_lines|
|
|
|
|
client = server.accept
|
|
|
|
content_length = 0
|
|
|
|
loop do
|
|
|
|
line = client.readline
|
|
|
|
post_lines << line.strip unless line =~ /\AHost: localhost:|\AContent-Length: /
|
|
|
|
content_length = line.split(":")[1].to_i if line.strip =~ /\AContent-Length: [0-9]+\z/
|
|
|
|
if line.strip.blank?
|
|
|
|
post_lines << client.read(content_length)
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
client.puts("HTTP/1.1 200 OK\nContent-Length: 0\n\n")
|
|
|
|
client.close
|
|
|
|
server.close
|
|
|
|
end
|
|
|
|
return server, server_thread, post_lines
|
|
|
|
end
|
2011-09-28 02:15:28 +08:00
|
|
|
|
|
|
|
def stub_kaltura
|
|
|
|
# trick kaltura into being activated
|
2011-10-26 07:15:30 +08:00
|
|
|
Kaltura::ClientV3.stubs(:config).returns({
|
2011-09-28 03:14:48 +08:00
|
|
|
'domain' => 'kaltura.example.com',
|
|
|
|
'resource_domain' => 'kaltura.example.com',
|
|
|
|
'partner_id' => '100',
|
|
|
|
'subpartner_id' => '10000',
|
|
|
|
'secret_key' => 'fenwl1n23k4123lk4hl321jh4kl321j4kl32j14kl321',
|
|
|
|
'user_secret_key' => '1234821hrj3k21hjk4j3kl21j4kl321j4kl3j21kl4j3k2l1',
|
|
|
|
'player_ui_conf' => '1',
|
|
|
|
'kcw_ui_conf' => '1',
|
|
|
|
'upload_ui_conf' => '1'
|
2011-09-28 02:15:28 +08:00
|
|
|
})
|
|
|
|
end
|
2011-08-12 00:51:57 +08:00
|
|
|
|
2011-10-21 03:52:36 +08:00
|
|
|
def attachment_obj_with_context(obj, opts={})
|
|
|
|
@attachment = factory_with_protected_attributes(Attachment, valid_attachment_attributes.merge(opts))
|
|
|
|
@attachment.context = obj
|
|
|
|
@attachment
|
|
|
|
end
|
|
|
|
|
|
|
|
def attachment_with_context(obj, opts={})
|
|
|
|
attachment_obj_with_context(obj, opts)
|
|
|
|
@attachment.save!
|
|
|
|
@attachment
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|