aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-06-28 17:44:16 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-06-28 17:44:16 +0000
commitbeffb77e05bf3c192e798587812105458146df32 (patch)
treee51ff71df80264ad08447719d842929ef1e9fd8e /actionpack/test
parent62ed6950c9119c12e6b17a68c79c45c77a7b1ca4 (diff)
downloadrails-beffb77e05bf3c192e798587812105458146df32.tar.gz
rails-beffb77e05bf3c192e798587812105458146df32.tar.bz2
rails-beffb77e05bf3c192e798587812105458146df32.zip
Added support for upload progress indicators in Apache and lighttpd 1.4.x (won't work in WEBrick or lighttpd 1.3.x) #1475 [Sean Treadway]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1553 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack/test')
-rw-r--r--actionpack/test/controller/multipart_progress_test.rb365
-rw-r--r--actionpack/test/controller/upload_progress_test.rb89
-rw-r--r--actionpack/test/template/upload_progress_helper_test.rb272
3 files changed, 726 insertions, 0 deletions
diff --git a/actionpack/test/controller/multipart_progress_test.rb b/actionpack/test/controller/multipart_progress_test.rb
new file mode 100644
index 0000000000..ed2bdc9f6c
--- /dev/null
+++ b/actionpack/test/controller/multipart_progress_test.rb
@@ -0,0 +1,365 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+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
diff --git a/actionpack/test/controller/upload_progress_test.rb b/actionpack/test/controller/upload_progress_test.rb
new file mode 100644
index 0000000000..48b4251f1d
--- /dev/null
+++ b/actionpack/test/controller/upload_progress_test.rb
@@ -0,0 +1,89 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+require 'test/unit'
+require 'cgi'
+require 'stringio'
+
+class UploadProgressTest < Test::Unit::TestCase
+ def test_remaining
+ progress = new_progress(20000)
+ assert_equal(0, progress.received_bytes)
+ assert_equal(20000, progress.remaining_bytes)
+ progress.update!(10000, 1.0)
+ assert_equal(10000, progress.remaining_bytes)
+ assert_equal(1.0, progress.remaining_seconds)
+ assert_equal(50, progress.completed_percent)
+ assert_equal(true, progress.started?)
+ assert_equal(false, progress.finished?)
+ assert_equal(false, progress.stalled?)
+ progress.update!(10000, 2.0)
+ assert_equal(true, progress.finished?)
+ assert_equal(0.0, progress.remaining_seconds)
+ end
+
+ def test_stalled
+ progress = new_progress(10000)
+ assert_equal(false, progress.stalled?)
+ progress.update!(100, 1.0)
+ assert_equal(false, progress.stalled?)
+ progress.update!(100, 20.0)
+ assert_equal(true, progress.stalled?)
+ assert_in_delta(0.0, progress.bitrate, 0.001)
+ progress.update!(100, 21.0)
+ assert_equal(false, progress.stalled?)
+ end
+
+ def test_elapsed
+ progress = new_progress(10000)
+ (1..5).each do |t|
+ progress.update!(1000, Float(t))
+ end
+ assert_in_delta(5.0, progress.elapsed_seconds, 0.001)
+ assert_equal(10000, progress.total_bytes)
+ assert_equal(5000, progress.received_bytes)
+ assert_equal(5000, progress.remaining_bytes)
+ end
+
+ def test_overflow
+ progress = new_progress(10000)
+ progress.update!(20000, 1.0)
+ assert_equal(10000, progress.received_bytes)
+ end
+
+ def test_zero
+ progress = new_progress(0)
+ assert_equal(0, progress.total_bytes)
+ assert_equal(0, progress.remaining_bytes)
+ assert_equal(false, progress.started?)
+ assert_equal(true, progress.finished?)
+ assert_equal(0, progress.bitrate)
+ assert_equal(0, progress.completed_percent)
+ assert_equal(0, progress.remaining_seconds)
+ end
+
+ def test_finished
+ progress = new_progress(10000)
+ (1..9).each do |t|
+ progress.update!(1000, Float(t))
+ assert_equal(false, progress.finished?)
+ assert_equal(1000.0, progress.bitrate)
+ assert_equal(false, progress.stalled?)
+ end
+ assert_equal(false, progress.finished?)
+ progress.update!(1000, 10.0)
+ assert_equal(true, progress.finished?)
+ end
+
+ def test_rapid_samples
+ progress = new_progress(10000)
+ (1..1000).each do |t|
+ progress.update!(10, t/100.0)
+ end
+ assert_in_delta(1000.0, progress.bitrate, 0.001)
+ assert_equal(true, progress.finished?)
+ end
+
+ private
+ def new_progress(total)
+ ActionController::UploadProgress::Progress.new(total)
+ end
+end
diff --git a/actionpack/test/template/upload_progress_helper_test.rb b/actionpack/test/template/upload_progress_helper_test.rb
new file mode 100644
index 0000000000..361aa4bb08
--- /dev/null
+++ b/actionpack/test/template/upload_progress_helper_test.rb
@@ -0,0 +1,272 @@
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/date_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/number_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/asset_tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/form_tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/javascript_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/upload_progress_helper'
+require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/hash' #for stringify keys
+
+class MockProgress
+ def initialize(started, finished)
+ @started, @finished = [started, finished]
+ end
+
+ def started?
+ @started
+ end
+
+ def finished?
+ @finished
+ end
+
+ def message
+ "A message"
+ end
+
+ def method_missing(meth, *args)
+ # Just return some consitant number
+ meth.to_s.hash.to_i.abs + args.hash.to_i.abs
+ end
+end
+
+class UploadProgressHelperTest < Test::Unit::TestCase
+ include ActionView::Helpers::DateHelper
+ include ActionView::Helpers::NumberHelper
+ include ActionView::Helpers::AssetTagHelper
+ include ActionView::Helpers::FormTagHelper
+ include ActionView::Helpers::TagHelper
+ include ActionView::Helpers::UrlHelper
+ include ActionView::Helpers::JavascriptHelper
+ include ActionView::Helpers::UploadProgressHelper
+
+ def next_upload_id; @upload_id = last_upload_id.succ; end
+ def last_upload_id; @upload_id ||= 0; end
+ def current_upload_id; last_upload_id; end
+ def upload_progress(upload_id = nil); @upload_progress or MockProgress.new(false, true); end
+
+ def setup
+ @controller = Class.new do
+ def url_for(options, *parameters_for_method_reference)
+ "http://www.example.com"
+ end
+ end
+ @controller = @controller.new
+ end
+
+ def test_upload_status_tag
+ assert_equal(
+ '<div class="progressBar" id="UploadProgressBar0"><div class="border"><div class="background"><div class="foreground"></div></div></div></div><div class="uploadStatus" id="UploadStatus0"></div>',
+ upload_status_tag
+ )
+ end
+
+ def test_upload_status_text_tag
+ assert_equal(
+ '<div class="my-upload" id="my-id">Starting</div>',
+ upload_status_text_tag('Starting', :class => 'my-upload', :id => 'my-id')
+ )
+ end
+
+
+ def test_upload_progress_text
+ @upload_progress = MockProgress.new(false, false)
+ assert_equal(
+ "Upload starting...",
+ upload_progress_text
+ )
+
+ @upload_progress = MockProgress.new(true, false)
+ assert_equal(
+ "828.7 MB of 456.2 MB at 990.1 MB/s; 10227 days remaining",
+ upload_progress_text
+ )
+
+ @upload_progress = MockProgress.new(true, true)
+ assert_equal(
+ "Upload finished. A message",
+ upload_progress_text
+ )
+ end
+
+ def test_upload_progress_update_bar_js
+ assert_equal(
+ "$('UploadProgressBar0').firstChild.firstChild.style.width='0%';",
+ upload_progress_update_bar_js
+ )
+
+ assert_equal(
+ "$('UploadProgressBar0').firstChild.firstChild.style.width='50%';",
+ upload_progress_update_bar_js(50)
+ )
+ end
+
+ def test_finish_upload_status
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status
+ )
+
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop(123);\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status(:client_js_argument => 123)
+ )
+
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\nparent.location.replace('/redirected/');\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status(:redirect_to => '/redirected/')
+ )
+ end
+
+ def test_form_tag_with_upload_progress
+ assert_equal(
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=1'; }this.target = 'UploadTarget1';$('UploadProgressBar1').firstChild.firstChild.style.width='0%';; document.uploadStatus1 = new Ajax.PeriodicalUpdater('UploadStatus1','http://www.example.com',{script:true, onComplete:function(request){$('UploadProgressBar1').firstChild.firstChild.style.width='100%';; }, asynchronous:true}.extend({decay:1.8,freqency:2.0})); return true\"><iframe id=\"UploadTarget1\" name=\"UploadTarget1\" src=\"\" style=\"width:0px;height:0px;border:0\"></iframe>",
+ form_tag_with_upload_progress
+ )
+ end
+
+ def test_form_tag_with_upload_progress_custom
+ assert_equal(
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=5'; }this.target = 'awindow';$('UploadProgressBar0').firstChild.firstChild.style.width='0%';; alert('foo'); document.uploadStatus0 = new Ajax.PeriodicalUpdater('UploadStatus0','http://www.example.com',{script:true, onComplete:function(request){$('UploadProgressBar0').firstChild.firstChild.style.width='100%';; alert('bar'); alert('bar')}, asynchronous:true}.extend({decay:7,freqency:6})); return true\" target=\"awindow\">",
+ form_tag_with_upload_progress({:upload_id => 5}, {:begin => "alert('foo')", :finish => "alert('bar')", :frequency => 6, :decay => 7, :target => 'awindow'})
+ )
+ end
+end
+require File.dirname(__FILE__) + '/../abstract_unit'
+
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/date_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/number_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/asset_tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/form_tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/tag_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/javascript_helper'
+require File.dirname(__FILE__) + '/../../lib/action_view/helpers/upload_progress_helper'
+require File.dirname(__FILE__) + '/../../../activesupport/lib/active_support/core_ext/hash' #for stringify keys
+
+class MockProgress
+ def initialize(started, finished)
+ @started, @finished = [started, finished]
+ end
+
+ def started?
+ @started
+ end
+
+ def finished?
+ @finished
+ end
+
+ def message
+ "A message"
+ end
+
+ def method_missing(meth, *args)
+ # Just return some consitant number
+ meth.to_s.hash.to_i.abs + args.hash.to_i.abs
+ end
+end
+
+class UploadProgressHelperTest < Test::Unit::TestCase
+ include ActionView::Helpers::DateHelper
+ include ActionView::Helpers::NumberHelper
+ include ActionView::Helpers::AssetTagHelper
+ include ActionView::Helpers::FormTagHelper
+ include ActionView::Helpers::TagHelper
+ include ActionView::Helpers::UrlHelper
+ include ActionView::Helpers::JavascriptHelper
+ include ActionView::Helpers::UploadProgressHelper
+
+ def next_upload_id; @upload_id = last_upload_id.succ; end
+ def last_upload_id; @upload_id ||= 0; end
+ def current_upload_id; last_upload_id; end
+ def upload_progress(upload_id = nil); @upload_progress ||= MockProgress.new(false, true); end
+
+ def setup
+ @controller = Class.new do
+ def url_for(options, *parameters_for_method_reference)
+ "http://www.example.com"
+ end
+ end
+ @controller = @controller.new
+ end
+
+ def test_upload_status_tag
+ assert_equal(
+ '<div class="progressBar" id="UploadProgressBar0"><div class="border"><div class="background"><div class="foreground"></div></div></div></div><div class="uploadStatus" id="UploadStatus0"></div>',
+ upload_status_tag
+ )
+ end
+
+ def test_upload_status_text_tag
+ assert_equal(
+ '<div class="my-upload" id="my-id">Starting</div>',
+ upload_status_text_tag('Starting', :class => 'my-upload', :id => 'my-id')
+ )
+ end
+
+
+ def test_upload_progress_text
+ @upload_progress = MockProgress.new(false, false)
+ assert_equal(
+ "Upload starting...",
+ upload_progress_text
+ )
+
+ @upload_progress = MockProgress.new(true, false)
+ assert_equal(
+ "828.7 MB of 456.2 MB at 990.1 MB/s; 10227 days remaining",
+ upload_progress_text
+ )
+
+ @upload_progress = MockProgress.new(true, true)
+ assert_equal(
+ "A message",
+ upload_progress_text
+ )
+ end
+
+ def test_upload_progress_update_bar_js
+ assert_equal(
+ "$('UploadProgressBar0').firstChild.firstChild.style.width='0%'",
+ upload_progress_update_bar_js
+ )
+
+ assert_equal(
+ "$('UploadProgressBar0').firstChild.firstChild.style.width='50%'",
+ upload_progress_update_bar_js(50)
+ )
+ end
+
+ def test_finish_upload_status
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status
+ )
+
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop(123);\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status(:client_js_argument => 123)
+ )
+
+ assert_equal(
+ "<html><head><script language=\"javascript\" type=\"text/javascript\">function finish() { if (parent.document.uploadStatus0) { parent.document.uploadStatus0.stop();\nparent.location.replace('/redirected/');\n }\n }</script></head><body onload=\"finish()\"></body></html>",
+ finish_upload_status(:redirect_to => '/redirected/')
+ )
+ end
+
+ def test_form_tag_with_upload_progress
+ assert_equal(
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=1'; }this.target = 'UploadTarget1';$('UploadStatus1').innerHTML='Upload starting...'; $('UploadProgressBar1').firstChild.firstChild.style.width='0%'; if (document.uploadStatus1) { document.uploadStatus1.stop(); }document.uploadStatus1 = new Ajax.PeriodicalUpdater('UploadStatus1','http://www.example.com', {script:true, onComplete:function(request){$('UploadStatus1').innerHTML='A message';$('UploadProgressBar1').firstChild.firstChild.style.width='100%';document.uploadStatus1 = null}, asynchronous:true}.extend({decay:1.8,freqency:2.0})); return true\"><iframe id=\"UploadTarget1\" name=\"UploadTarget1\" src=\"\" style=\"width:0px;height:0px;border:0\"></iframe>",
+ form_tag_with_upload_progress
+ )
+ end
+
+ def test_form_tag_with_upload_progress_custom
+ assert_equal(
+ "<form action=\"http://www.example.com\" enctype=\"multipart/form-data\" method=\"post\" onsubmit=\"if (this.action.indexOf('upload_id') &lt; 0){ this.action += '?upload_id=5'; }this.target = 'awindow';$('UploadStatus0').innerHTML='Upload starting...'; $('UploadProgressBar0').firstChild.firstChild.style.width='0%'; alert('foo'); if (document.uploadStatus0) { document.uploadStatus0.stop(); }document.uploadStatus0 = new Ajax.PeriodicalUpdater('UploadStatus0','http://www.example.com', {script:true, onComplete:function(request){$('UploadStatus0').innerHTML='A message';$('UploadProgressBar0').firstChild.firstChild.style.width='100%';document.uploadStatus0 = null; alert('bar')}, asynchronous:true}.extend({decay:7,freqency:6})); return true\" target=\"awindow\">",
+ form_tag_with_upload_progress({:upload_id => 5}, {:begin => "alert('foo')", :finish => "alert('bar')", :frequency => 6, :decay => 7, :target => 'awindow'})
+ )
+ end
+end