360 lines
16 KiB
Ruby
360 lines
16 KiB
Ruby
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
|
|
require 'nokogiri'
|
|
|
|
describe FilesController do
|
|
before :each do
|
|
user_with_pseudonym(:active_all => true)
|
|
end
|
|
|
|
context "should support Submission as a context" do
|
|
before(:each) do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
host!("test.host")
|
|
login_as
|
|
@me = @user
|
|
submission_model
|
|
@submission.attachment = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png')
|
|
@submission.save!
|
|
end
|
|
|
|
it "with safefiles" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/files/#{@submission.attachment.id}/download", :inline => '1', :verifier => @submission.attachment.uuid
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/files/#{@submission.attachment.id}/download"
|
|
expect(@me.valid_access_verifier?(qs['ts'], qs['sf_verifier'])).to be_truthy
|
|
expect(qs['verifier']).to eq @submission.attachment.uuid
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
it "without safefiles" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['test.host', Shard.default])
|
|
get "http://test.host/files/#{@submission.attachment.id}/download", :inline => '1', :verifier => @submission.attachment.uuid
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
expect(response['Pragma']).to be_nil
|
|
expect(response['Cache-Control']).not_to match(/no-cache/)
|
|
end
|
|
end
|
|
|
|
context "should support User as a context" do
|
|
before(:each) do
|
|
host!("test.host")
|
|
login_as
|
|
@me = @user
|
|
@att = @me.attachments.create(:uploaded_data => stub_png_data('my-pic.png'))
|
|
end
|
|
|
|
it "with safefiles" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/users/#{@me.id}/files/#{@att.id}/download"
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
# redirects to a relative url, since relative files are available in user context
|
|
expect(uri.path).to eq "/users/#{@me.id}/files/#{@att.id}/my%20files/unfiled/my-pic.png"
|
|
expect(@me.valid_access_verifier?(qs['ts'], qs['sf_verifier'])).to be_truthy
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
it "without safefiles" do
|
|
HostUrl.stubs(:file_host).returns('test.host')
|
|
get "http://test.host/users/#{@me.id}/files/#{@att.id}/download"
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
expect(response['Pragma']).to be_nil
|
|
expect(response['Cache-Control']).not_to match(/no-cache/)
|
|
end
|
|
|
|
context "with inlineable html files" do
|
|
before do
|
|
@att = @me.attachments.create(:uploaded_data => stub_file_data("ohai.html", "<html><body>ohai</body></html>", "text/html"))
|
|
end
|
|
|
|
it "with safefiles" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/users/#{@me.id}/files/#{@att.id}/download", :wrap => '1'
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'test.host'
|
|
expect(uri.path).to eq "/users/#{@me.id}/files/#{@att.id}"
|
|
location = response['Location']
|
|
|
|
get location
|
|
# the response will be on the main domain, with an iframe pointing to the files domain and the actual uploaded html file
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'text/html'
|
|
doc = Nokogiri::HTML::DocumentFragment.parse(response.body)
|
|
expect(doc.at_css('iframe#file_content')['src']).to match %r{^http://files-test.host/users/#{@me.id}/files/#{@att.id}/my%20files/unfiled/ohai.html}
|
|
end
|
|
|
|
it "without safefiles" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['test.host', Shard.default])
|
|
get "http://test.host/users/#{@me.id}/files/#{@att.id}/download", :wrap => '1'
|
|
expect(response).to be_redirect
|
|
location = response['Location']
|
|
expect(URI.parse(location).path).to eq "/users/#{@me.id}/files/#{@att.id}"
|
|
get location
|
|
expect(response.content_type).to eq 'text/html'
|
|
doc = Nokogiri::HTML::DocumentFragment.parse(response.body)
|
|
expect(doc.at_css('iframe#file_content')['src']).to match %r{^http://test.host/users/#{@me.id}/files/#{@att.id}/my%20files/unfiled/ohai.html}
|
|
end
|
|
|
|
it "should not inline the file if passed download_frd param" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/users/#{@me.id}/files/#{@att.id}/download?download_frd=1&verifier=#{@att.uuid}"
|
|
expect(response).to be_redirect
|
|
get response['Location']
|
|
expect(response.headers['Content-Disposition']).to match /attachment/
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
it "should use relative urls for safefiles in course context" do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
host!("test.host")
|
|
login_as
|
|
a1 = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png', :context => @course)
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/courses/#{@course.id}/files/#{a1.id}/download", :inline => '1'
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/courses/#{@course.id}/files/#{a1.id}/course%20files/test%20my%20file%3F%20hai!%26.png"
|
|
expect(@user.valid_access_verifier?(qs['ts'], qs['sf_verifier'])).to be_truthy
|
|
expect(qs['verifier']).to be_nil
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
it "logs user access with safefiles" do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
host!("test.host")
|
|
login_as
|
|
a1 = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png', :context => @course)
|
|
|
|
get "http://test.host/courses/#{@course.id}/files/#{a1.id}/download", :inline => '1'
|
|
expect(response).to be_redirect
|
|
location = response['Location']
|
|
reset!
|
|
|
|
Setting.set('enable_page_views', 'db')
|
|
get location
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
access = AssetUserAccess.for_user(@user).first
|
|
expect(access).to_not be_nil
|
|
expect(access.asset).to eq a1
|
|
end
|
|
|
|
it "should be able to use verifier in course context" do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
a1 = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png', :context => @course)
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/courses/#{@course.id}/files/#{a1.id}/download?verifier=#{a1.uuid}"
|
|
expect(response).to be_redirect
|
|
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/courses/#{@course.id}/files/#{a1.id}/course%20files/test%20my%20file%3F%20hai!%26.png"
|
|
expect(qs['verifier']).to eq a1.uuid
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
it "should be able to directly download in course context preview links with verifier" do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
a1 = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png', :context => @course)
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/courses/#{@course.id}/files/#{a1.id}/preview?verifier=#{a1.uuid}"
|
|
expect(response).to be_redirect
|
|
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/courses/#{@course.id}/files/#{a1.id}/course%20files/test%20my%20file%3F%20hai!%26.png"
|
|
expect(qs['verifier']).to eq a1.uuid
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
it "should update module progressions for html safefiles iframe" do
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
course_with_student(:active_all => true, :user => @user)
|
|
host!("test.host")
|
|
login_as
|
|
@att = @course.attachments.create(:uploaded_data => stub_file_data("ohai.html", "<html><body>ohai</body></html>", "text/html"))
|
|
@module = @course.context_modules.create!(:name => "module")
|
|
@tag = @module.add_item({:type => 'attachment', :id => @att.id})
|
|
@module.reload
|
|
hash = {}
|
|
hash[@tag.id.to_s] = {:type => 'must_view'}
|
|
@module.completion_requirements = hash
|
|
@module.save!
|
|
expect(@module.evaluate_for(@user).state).to eql(:unlocked)
|
|
|
|
# the response will be on the main domain, with an iframe pointing to the files domain and the actual uploaded html file
|
|
get "http://test.host/courses/#{@course.id}/files/#{@att.id}"
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'text/html'
|
|
doc = Nokogiri::HTML::DocumentFragment.parse(response.body)
|
|
location = doc.at_css('iframe#file_content')['src']
|
|
|
|
# now reset the user session (simulating accessing via a separate domain), grab the document,
|
|
# and verify the module progress was recorded
|
|
reset!
|
|
get location
|
|
expect(response).to be_success
|
|
expect(@module.evaluate_for(@user).state).to eql(:completed)
|
|
end
|
|
|
|
context "should support AssessmentQuestion as a context" do
|
|
before do
|
|
course_with_teacher(:active_all => true, :user => @user)
|
|
host!("test.host")
|
|
login_as
|
|
bank = @course.assessment_question_banks.create!
|
|
@aq = assessment_question_model(:bank => bank)
|
|
@att = @aq.attachments.create!(:uploaded_data => stub_png_data)
|
|
end
|
|
|
|
def do_with_safefiles_test(url)
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get url
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/files/#{@att.id}/download"
|
|
expect(@user.valid_access_verifier?(qs['ts'], qs['sf_verifier'])).to be_truthy
|
|
expect(qs['verifier']).to eq @att.uuid
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
# ensure that the user wasn't logged in by the normal means
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
end
|
|
|
|
context "with safefiles" do
|
|
it "with new url style" do
|
|
do_with_safefiles_test("http://test.host/assessment_questions/#{@aq.id}/files/#{@att.id}/#{@att.uuid}")
|
|
end
|
|
|
|
it "with old url style" do
|
|
do_with_safefiles_test("http://test.host/assessment_questions/#{@aq.id}/files/#{@att.id}/download?verifier=#{@att.uuid}")
|
|
end
|
|
end
|
|
|
|
def do_without_safefiles_test(url)
|
|
HostUrl.stubs(:file_host).returns('test.host')
|
|
get url
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
expect(response['Pragma']).to be_nil
|
|
expect(response['Cache-Control']).not_to match(/no-cache/)
|
|
end
|
|
|
|
context "without safefiles" do
|
|
it "with new url style" do
|
|
do_without_safefiles_test("http://test.host/assessment_questions/#{@aq.id}/files/#{@att.id}/#{@att.uuid}")
|
|
end
|
|
|
|
it "with old url style" do
|
|
do_without_safefiles_test("http://test.host/assessment_questions/#{@aq.id}/files/#{@att.id}/download?verifier=#{@att.uuid}")
|
|
end
|
|
end
|
|
end
|
|
|
|
it "should allow access to non-logged-in user agent if it has the right :verifier (lets google docs preview submissions in speedGrader)" do
|
|
submission_model
|
|
@submission.attachment = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png')
|
|
@submission.save!
|
|
HostUrl.stubs(:file_host_with_shard).returns(['files-test.host', Shard.default])
|
|
get "http://test.host/users/#{@submission.user.id}/files/#{@submission.attachment.id}/download", :verifier => @submission.attachment.uuid
|
|
|
|
expect(response).to be_redirect
|
|
uri = URI.parse response['Location']
|
|
qs = Rack::Utils.parse_nested_query(uri.query)
|
|
expect(uri.host).to eq 'files-test.host'
|
|
expect(uri.path).to eq "/files/#{@submission.attachment.id}/download"
|
|
expect(qs['verifier']).to eq @submission.attachment.uuid
|
|
location = response['Location']
|
|
reset!
|
|
|
|
get location
|
|
expect(response).to be_success
|
|
expect(response.content_type).to eq 'image/png'
|
|
expect(controller.instance_variable_get(:@current_user)).to be_nil
|
|
expect(controller.instance_variable_get(:@context)).to be_nil
|
|
end
|
|
|
|
it "shouldn't use relative urls for safefiles in other contexts" do
|
|
course_with_teacher_logged_in(:active_all => true)
|
|
a1 = attachment_model(:uploaded_data => stub_png_data, :content_type => 'image/png', :context => @course)
|
|
end
|
|
|
|
it "should return the dynamically generated thumbnail of the size given" do
|
|
attachment_model(:uploaded_data => stub_png_data)
|
|
sz = "640x>"
|
|
@attachment.any_instantiation.expects(:create_or_update_thumbnail).with(anything, sz, sz).returns { @attachment.thumbnails.create!(:thumbnail => "640x>", :uploaded_data => stub_png_data) }
|
|
get "/images/thumbnails/#{@attachment.id}/#{@attachment.uuid}?size=640x#{URI.encode '>'}"
|
|
thumb = @attachment.thumbnails.where(thumbnail: "640x>").first
|
|
expect(response).to redirect_to(thumb.authenticated_s3_url)
|
|
end
|
|
|
|
it "should reorder files" do
|
|
course_with_teacher_logged_in(:active_all => true, :user => @user)
|
|
att1 = attachment_model(:uploaded_data => stub_png_data, :context => @course)
|
|
att2 = attachment_model(:uploaded_data => stub_png_data("file2.png"), :context => @course)
|
|
|
|
post "/courses/#{@course.id}/files/reorder", {:order => "#{att2.id}, #{att1.id}", :folder_id => @folder.id}
|
|
expect(response).to be_success
|
|
|
|
expect(@folder.file_attachments.by_position_then_display_name).to eq [att2, att1]
|
|
end
|
|
end
|