multipart_progress_testx.rb
上传用户:netsea168
上传日期:2022-07-22
资源大小:4652k
文件大小:10k
源码类别:
Ajax
开发平台:
Others
- require 'logger'
- require 'test/unit'
- require 'cgi'
- require 'stringio'
- DEBUG=false
- def test_logger
- if DEBUG then ActionController::Base.logger = Logger.new(STDERR)
- else ActionController::Base.logger = Logger.new(StringIO.new)
- end
- end
- # Provide a static version of the Controllers module instead of the auto-loading version.
- # We don't want these tests to fail when dependencies are to blame.
- module Controllers
- class EmptyController < ActionController::Base
- end
- class ApplicationController < ActionController::Base
- end
- class MockController < ActionController::Base
- def initialize
- super
- @session = {:uploads => {}}
- @params = {}
- end
- end
- class SingleUploadController < ActionController::Base
- upload_status_for :one
- def one; end
- end
- class DoubleUploadController < ActionController::Base
- upload_status_for :one, :two
- def one; end
- def two; end
- end
- class DoubleStatusUploadController < ActionController::Base
- upload_status_for :one, :two, :status => :custom_status
- def one; end
- def two; end
- end
- class DoubleSeperateController < ActionController::Base
- upload_status_for :one
- upload_status_for :two
- def one; end
- def two; end
- end
- class UploadController < ActionController::Base
- upload_status_for :norendered, :rendered, :redirected, :finish_param_dict, :finish_param_string, :finish_param_number
- def norendered
- end
- def rendered
- render_text("rendered")
- end
- def redirected
- redirect_to "/redirected/"
- end
- def finish_param_dict
- finish_upload_status "{a: 'b'}"
- end
- def finish_param_string
- finish_upload_status "'a string'"
- end
- def finish_param_number
- finish_upload_status 123
- end
- def finish_param_number_redirect
- redirect_to "/redirected/"
- finish_upload_status 123
- end
- end
- end
- class MockIO < StringIO
- def initialize(data='', &block)
- test_logger.debug("MockIO inializing data: #{data[0..20]}")
- @block = block
- super(data)
- end
- def write(data)
- test_logger.debug("MockIO write #{data.size} data: #{data[0..20]}")
- super
- end
- def read(size)
- test_logger.debug("MockIO getting data from super")
- data = super
- test_logger.debug("Calling read callback")
- @block.call
- test_logger.debug("Returning data: #{data.size}")
- data
- end
- end
- class MockCGI < CGI
- BOUNDARY = '----------0xKhTmLbOuNdArY'
- FILENAME = 'dummy.nul'
- attr_reader :upload_id, :session_options, :session_id
- def initialize(size=1000, url='/test', &block)
- @url = url
- @env = {}
- @sio = MockIO.new('') { block.call(self) if block_given? }
- @upload_id = '1'
- add_param('param1', 'value1')
- add_data(size)
- add_param('param1', 'value2')
- add_end_boundary
- init_env
- @sio.rewind
- super()
- end
- #def stdinput_without_progress
- # @sio
- #end
- def stdinput
- @sio
- end
- def env_table
- @env
- end
- private
- def init_env
- @env['HTTP_HOST'] = 'localhost'
- @env['SERVER_PORT'] = '80'
- @env['REQUEST_METHOD'] = "POST"
- @env['QUERY_STRING'] = @url.split('?')[1] || "upload_id=#{upload_id}&query_param=query_value"
- @env['REQUEST_URI'] = @url
- @env['SCRIPT_NAME'] = @url.split('?').first.split('/').last
- @env['PATH_INFO'] = @url.split('?').first
- @env['CONTENT_TYPE'] = "multipart/form-data; boundary=#{BOUNDARY}"
- @env['CONTENT_LENGTH'] = @sio.tell - EOL.size
- @session_options = ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.inject({}) { |options, pair|
- options[pair.first.to_s] = pair.last; options
- }
- session = CGI::Session.new({}, @session_options.merge({'new_session' => true}))
- @session_id = session.session_id
- @env['COOKIE'] = "_session_id=#{session.session_id}"
- session.close
- end
- def add_param(name, value)
- add_boundary
- @sio << "Content-Disposition: form-data; name="#{name}"" << EOL << EOL
- @sio << value.to_s << EOL
- end
- def add_data(size)
- add_boundary
- @sio << "Content-Disposition: form-data; name="file"; filename="#{FILENAME}"" << EOL
- @sio << "Content-Type: application/octet-stream" << EOL << EOL
- @sio << "." * size
- @sio << EOL
- end
- def add_boundary
- @sio << "--" << BOUNDARY << EOL
- end
- def add_end_boundary
- @sio << "--" << BOUNDARY << "--" << EOL
- end
- end
- class MultipartProgressTest < Test::Unit::TestCase
- def test_domain_language_single
- c = Controllers::SingleUploadController.new
- assert_respond_to(c, :one)
- assert_respond_to(c, :upload_status)
- assert_respond_to(c, :finish_upload_status)
- end
- def test_domain_language_double
- c = Controllers::DoubleUploadController.new
- assert_respond_to(c, :one)
- assert_respond_to(c, :two)
- assert_respond_to(c, :upload_status)
- assert_respond_to(c, :finish_upload_status)
- end
- def test_domain_language_double_status
- c = Controllers::DoubleStatusUploadController.new
- assert_respond_to(c, :one)
- assert_respond_to(c, :two)
- assert_respond_to(c, :custom_status)
- assert_respond_to(c, :finish_upload_status)
- end
- def test_domain_language_double_seperate
- c = Controllers::DoubleSeperateController.new
- assert_respond_to(c, :one)
- assert_respond_to(c, :two)
- assert_respond_to(c, :upload_status)
- assert_respond_to(c, :finish_upload_status)
- end
- def test_finish_status_norendered
- # Fails to render the upload finish script because there is no view associated with this action
- test_logger.debug('test_finish_status_norendered')
- res = process(:action => 'norendered', :upload_id => 1)
- assert_match(/ActionView::ActionViewError/s, res.body)
- res = process(:action => :upload_status, :upload_id => 1)
- assert_match(/Upload finished/s, res.body)
- res = process(:action => :norendered)
- assert_match(/ActionView::ActionViewError/s, res.body)
- end
- def test_finish_status_rendered
- test_logger.debug('test_finish_status_rendered')
- res = process(:action => :rendered, :upload_id => 1)
- assert_match(/stop()/s, res.body)
- assert_no_match(/rendered/s, res.body)
- res = process(:action => :upload_status, :upload_id => 1)
- assert_match(/Upload finished/s, res.body)
- res = process(:action => :rendered)
- assert_no_match(/stop()/s, res.body)
- assert_match(/rendered/, res.body)
- end
- def test_finish_status_redirected
- test_logger.debug('test_finish_status_redirected')
- res = process(:action => :redirected, :upload_id => 1)
- assert_match(/location.replace/s, res.body)
- res = process(:action => :redirected)
- assert_no_match(/location.replace/s, res.body)
- assert_match(//redirected//s, res.headers['location'])
- assert_match(/302 .*$/, res.headers['Status'])
- res = process(:action => :upload_status, :upload_id => 1)
- assert_match(/Upload finished/s, res.body)
- end
- def test_finish_status_finish_param
- test_logger.debug('test_finish_status_param')
- res = process(:action => :finish_param_string, :upload_id => 1)
- assert_match(/stop('a string')/s, res.body)
- assert_no_redirect res
- res = process(:action => :finish_param_dict, :upload_id => 1)
- assert_match(/stop({a: 'b'})/s, res.body)
- assert_no_redirect res
- res = process(:action => :finish_param_number, :upload_id => 1)
- assert_match(/stop(123)/s, res.body)
- assert_no_redirect res
- res = process(:action => :finish_param_number_redirect, :upload_id => 1)
- test_logger.debug('test_finish_status_param: ' + res.body)
- assert_match(/stop(123)/s, res.body)
- assert_match(/replace('http://localhost/redirected/').*?/s, res.body)
- assert_no_redirect res
- end
- def test_basic_setup
- test_logger.debug('test_basic_setup')
- cgi, request, response = new_request(100000)
- assert_not_nil(request.session)
- assert_not_nil(request.session[:uploads], "uploads collection not set")
- assert_not_nil(request.session[:uploads][cgi.upload_id], "upload id not set")
- progress = request.session[:uploads][cgi.upload_id]
- assert_equal(true, progress.finished?)
- end
- def test_params
- test_logger.debug('test_params')
- cgi, request, response = new_request(1000)
- assert(!request.params.empty?)
- assert(!request.params['param1'].empty?)
- end
- def test_share_session
- cgi, request, response = new_request(100000) do |cgi, req|
- if cgi.stdinput.tell > 50000
- # force a save
- cgi.stdinput.save_progress rescue flunk('Something else is wrong, our wrapper isnt setup, is ActionController::Base.logger set?')
- other_session = CGI::Session.new(cgi, cgi.session_options.merge({'session_id' => cgi.session_id}))
- assert_not_nil(other_session[:uploads])
- assert_not_nil(other_session[:uploads][cgi.upload_id])
- assert_in_delta(cgi.stdinput.session[:uploads][cgi.upload_id].bitrate, other_session[:uploads][cgi.upload_id].bitrate, 1000.0, "Seperate session does not share data from original session")
- other_session.close
- end
- end
- end
- def test_upload_ids
- c = Controllers::MockController.new
- (1..222).each do |id|
- c.params = {}
- assert_equal((id-1).to_s, c.last_upload_id, "last_upload_id is out of sync")
- assert_equal(id.to_s, c.next_upload_id, "next_upload_id is out of sync")
- assert_equal(id.to_s, c.current_upload_id, "current_upload_id is out of sync")
- c.params = {:upload_id => (id-1).to_s}
- assert_equal((id-1).to_s, c.current_upload_id, "current_upload_id is out of sync")
- c.session[:uploads][id] = {}
- end
- end
- private
- def new_request(size=1000, url='/test', &block)
- test_logger.debug('Creating MockCGI')
- cgi = MockCGI.new(size, url) do |cgi|
- block.call(cgi) if block_given?
- end
- assert(cgi.private_methods.include?("read_multipart_with_progress"))
- return [cgi, ActionController::CgiRequest.new(cgi), ActionController::CgiResponse.new(cgi)]
- end
- def process(options = {})
- Controllers::UploadController.process(*(new_request(1000, '/upload?' + options.map {|k,v| "#{k}=#{v}"}.join('&'))[1..2]))
- end
- def assert_no_redirect(res)
- assert_nil(res.redirected_to)
- assert_nil(res.headers['location'])
- assert_match(/200 .*$/, res.headers['Status'])
- end
- end