diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3330f6be..00000000 --- a/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -test/public/vendor/jquery.js -*.swp -*.swo -.#* -.bundle -.DS_Store -*~ diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index fe03033a..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,45 +0,0 @@ -CHANGELOG -========= - -Here is a non-exhaustive list of notable changes to jquery-ujs (oldest -to newest): - -- [`085d910a5ec07b69`](https://github.com/rails/jquery-ujs/commit/085d910a5ec07b69f31beabce286141aa26f3005) last version before callback names updated -- [`72d875a8d57c6bb4`](https://github.com/rails/jquery-ujs/commit/72d875a8d57c6bb466170980a5142c66ac74e8f0) callback name updates completed -- [`e076121248913143`](https://github.com/rails/jquery-ujs/commit/e0761212489131437402a92fa8f548a78f685ae2) dropped support for jQuery 1.4, 1.4.1, 1.4.2 (separate [v1.4 branch](https://github.com/rails/jquery-ujs/commits/v1.4) created) -- [`498b35e24cdb14f2`](https://github.com/rails/jquery-ujs/commit/498b35e24cdb14f2d94486e8a1f4a1f661091426) last version before `.callRemote()` removed -- [`ec96408a746d3b06`](https://github.com/rails/jquery-ujs/commit/ec96408a746d3b0692da9249f218a3943fbffc28) `ACCEPTS` header data-type default changed to prefer `:js` but not require it -- [`fc639928d1e15c88`](https://github.com/rails/jquery-ujs/commit/fc639928d1e15c885b85de5b517346db7f963f44) default form method changed from `POST` to `GET` -- [`e9311550fdb3afeb`](https://github.com/rails/jquery-ujs/commit/e9311550fdb3afeb2917bcb1fef39767bf715003) added CSRF Protection to remote requests -- [`a284dd706e7d76e8`](https://github.com/rails/jquery-ujs/commit/a284dd706e7d76e85471ef39ab3efdf07feef374) CSRF fixed - changed to only add if token is present -- [`f9b21b3a3c7c4684`](https://github.com/rails/jquery-ujs/commit/f9b21b3a3c7c46840fed8127a90def26911fad3d) `ajax:before` added back -- [`7f2acc1811f62877`](https://github.com/rails/jquery-ujs/commit/7f2acc1811f62877611e16451530728b5e13dbe7) last version before file-upload aborting behavior added -- [`ca575e184e93b3ef`](https://github.com/rails/jquery-ujs/commit/ca575e184e93b3efe1a858cf598f8a37f0a760cc) added `ajax:aborted:required` and `ajax:aborted:file` event hooks -- [`d2abd6f9df4e4a42`](https://github.com/rails/jquery-ujs/commit/d2abd6f9df4e4a426c17c218b7d5e05004c768d0) fixed submit and bubbling behavior for IE -- [`d59144177d867908`](https://github.com/rails/jquery-ujs/commit/d59144177d86790891fdb99b0e3437312e04fda2) created external api via `$.rails` object -- [`cd357e492de14747`](https://github.com/rails/jquery-ujs/commit/cd357e492de147472a8a2524575acce5d923e640) added support for jQuery 1.6 and dropped support for jQuery 1.4.3 -- [`50c06dcc02c1b08c`](https://github.com/rails/jquery-ujs/commit/50c06dcc02c1b08cb7a9b4b8eced54ed685c1c93) added `confirm:complete` event hook which is passed result from confirm dialog -- [`8063d1d47ea6a08e`](https://github.com/rails/jquery-ujs/commit/8063d1d47ea6a08e545e9a6ba3e84af584200e41) made $.rails.confirm and $.rails.ajax functions available in $.rails object -- [`a96c4e9b074998c6`](https://github.com/rails/jquery-ujs/commit/a96c4e9b074998c6b6d102e4573b81c8a76f07a7) added support for jQuery 1.6.1 -- [`dad6982dc5926866`](https://github.com/rails/jquery-ujs/commit/dad6982dc592686677e6845e681233c40d2ead27) added support for `data-params` attribute on remote links -- [`5433841d01622345`](https://github.com/rails/jquery-ujs/commit/5433841d01622345f734f22f82394ac035c2f783) removed support for jQuery 1.4.4 and 1.5.x, and added support for jQuery 1.6.2 -- [`cd619df9f0daad33`](https://github.com/rails/jquery-ujs/commit/cd619df9f0daad3303aacd4f992fff19158b1e5d) added support for html5 `novalidate` attribute, so required fields validation is not enforced -- [`840ab6ac76b2d5ab`](https://github.com/rails/jquery-ujs/commit/840ab6ac76b2d5ab931841bc3d8567e5b57f183e) added support for jQuery 1.6.3 -- [`ba5808e73111fb65`](https://github.com/rails/jquery-ujs/commit/ba5808e73111fb65e91610b078577bb014d9b6d8) added `data-remote` support for checkboxes -- [`6e9a06d45eaf2da1`](https://github.com/rails/jquery-ujs/commit/6e9a06d45eaf2da1036d4c2ead25ff57d0127d03) added `data-disable-with` support for links -- [`89396108ce574080`](https://github.com/rails/jquery-ujs/commit/89396108ce574080f9b877cad74573c5d1ae9aa2) added `data-remote` support for all input types -- [`c01215c3d48ebb9f`](https://github.com/rails/jquery-ujs/commit/c01215c3d48ebb9f9f1059f26efa0c0c9092da2b) added support for jQuery 1.6.4 -- [`17f4004310b6ece3`](https://github.com/rails/jquery-ujs/commit/17f4004310b6ece3cb240914932b4d6d46032c24) added support for jQuery 1.7 -- [`cb54ae287f5c7320`](https://github.com/rails/jquery-ujs/commit/cb54ae287f5c73207aef2891cdf22212aea5fb86) added support for jQuery 1.7.1 -- [`dbb1b5f72a62e59f`](https://github.com/rails/jquery-ujs/commit/dbb1b5f72a62e59f34f6b5be4bee291ee7f3318f) added support for jQuery 1.7.2 -- [`8100cf3b2462f144`](https://github.com/rails/jquery-ujs/commit/8100cf3b2462f144e6a0bcef7cb78d05be41755d) created `rails:attachBindings` to allow for customization of - $.rails object settings -- [`e4ca2045b202cd7a`](https://github.com/rails/jquery-ujs/commit/e4ca2045b202cd7ade97d78c20caa2822c5c28da) created `ajax:send` event to provide access to jqXHR object from - ajax requests -- [`4382f580766fcdd1`](https://github.com/rails/jquery-ujs/commit/4382f580766fcdd14201c204f43ca5aeb0928501) added support for `data-with-credentials` -- [`12da9fc2f175c8e4`](https://github.com/rails/jquery-ujs/commit/12da9fc2f175c8e445413b15cf6b685deb271d6e) added support for jQuery 1.8.0, removed support for jquery 1.6.x -- [`faeb0ad734ff6867`](https://github.com/rails/jquery-ujs/commit/faeb0ad734ff6867149b8522f9a29081734442e6) added support for jQuery 1.8.1 -- [`b6dae4ef4a2d031a`](https://github.com/rails/jquery-ujs/commit/b6dae4ef4a2d031a222627c7f6a4284602f99160) added support for jQuery 1.8.2 -- [`6927b82cadf3146c`](https://github.com/rails/jquery-ujs/commit/6927b82cadf3146c2b9ae3028e9b197af64011ca) added support for jQuery 1.8.3 -- [`cc356656cc3edf15`](https://github.com/rails/jquery-ujs/commit/cc356656cc3edf1596fd685265187d2f75d1bc7c) added support for jQuery 1.9.0 -- [`2f8ccdf26eac199a`](https://github.com/rails/jquery-ujs/commit/2f8ccdf26eac199a11aa1a893a8909bb4650d0fb) added support for jQuery 1.9.1 diff --git a/Gemfile b/Gemfile deleted file mode 100644 index e32e523b..00000000 --- a/Gemfile +++ /dev/null @@ -1,6 +0,0 @@ -source 'http://rubygems.org' - -gem 'sinatra', '~> 1.0' -gem 'shotgun', :group => :reloadable -gem 'thin', :group => :reloadable -gem 'json' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 42460e58..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,26 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - daemons (1.1.0) - eventmachine (0.12.10) - json (1.4.6) - rack (1.2.1) - shotgun (0.8) - rack (>= 1.0) - sinatra (1.1.2) - rack (~> 1.1) - tilt (~> 1.2) - thin (1.2.7) - daemons (>= 1.0.9) - eventmachine (>= 0.12.6) - rack (>= 1.0.0) - tilt (1.2.1) - -PLATFORMS - ruby - -DEPENDENCIES - json - shotgun - sinatra (~> 1.0) - thin diff --git a/Rakefile b/Rakefile deleted file mode 100644 index e0e44e67..00000000 --- a/Rakefile +++ /dev/null @@ -1,47 +0,0 @@ -desc %(Starts the test server and opens it in a web browser) -multitask :default => ['test:server', 'test:open'] - -PORT = 4567 - -namespace :test do - desc %(Starts the test server) - task :server do - system 'bundle exec ruby test/server.rb' - end - - desc %(Starts the test server which reloads everything on each refresh) - task :reloadable do - exec "bundle exec shotgun test/config.ru -p #{PORT} --server thin" - end - - task :open do - url = "http://localhost:#{PORT}" - puts "Opening test app at #{url} ..." - sleep 3 - system( *browse_cmd(url) ) - end -end - -# Returns an array e.g.: ['open', 'http://example.com'] -def browse_cmd(url) - require 'rbconfig' - browser = ENV['BROWSER'] || - (RbConfig::CONFIG['host_os'].include?('darwin') && 'open') || - (RbConfig::CONFIG['host_os'] =~ /msdos|mswin|djgpp|mingw|windows/ && 'start') || - %w[xdg-open x-www-browser firefox opera mozilla netscape].find { |comm| which comm } - - abort('ERROR: no web browser detected') unless browser - Array(browser) << url -end - -# which('ruby') #=> /usr/bin/ruby -def which cmd - exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] - ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| - exts.each { |ext| - exe = "#{path}/#{cmd}#{ext}" - return exe if File.executable? exe - } - end - return nil -end diff --git a/test/config.ru b/test/config.ru deleted file mode 100644 index 44fb4f03..00000000 --- a/test/config.ru +++ /dev/null @@ -1,3 +0,0 @@ -$LOAD_PATH.unshift File.expand_path('..', __FILE__) -require 'server' -run Sinatra::Application diff --git a/test/public/test/call-remote-callbacks.js b/test/public/test/call-remote-callbacks.js deleted file mode 100644 index 60bff422..00000000 --- a/test/public/test/call-remote-callbacks.js +++ /dev/null @@ -1,391 +0,0 @@ -(function(){ - -module('call-remote-callbacks', { - setup: function() { - $('#qunit-fixture').append($('
', { - action: '/echo', method: 'get', 'data-remote': 'true' - })); - }, - teardown: function() { - $(document).undelegate('form[data-remote]', 'ajax:beforeSend'); - $(document).undelegate('form[data-remote]', 'ajax:before'); - $(document).undelegate('form[data-remote]', 'ajax:complete'); - $(document).undelegate('form[data-remote]', 'ajax:success'); - $(document).unbind('ajaxStop'); - $(document).unbind('iframe:loading'); - } -}); - -function submit(fn) { - var form = $('form') - .bind('ajax:complete', function(){ - ok(true, 'ajax:complete'); - start(); - }); - - if (fn) fn(form); - form.trigger('submit'); -} - -asyncTest('modifying form fields with "ajax:before" sends modified data in request', 4, function(){ - $('form[data-remote]') - .append($('')) - .append($('')) - .bind('ajax:before', function() { - var form = $(this); - form - .append($('',{name: 'other_user_name',value: 'jonathan'})) - .find('input[name="removed_user_name"]').remove(); - form - .find('input[name="user_name"]').val('steve'); - }); - - submit(function(form) { - form.bind('ajax:success', function(e, data, status, xhr) { - equal(data.params.user_name, 'steve', 'modified field value should have been submitted'); - equal(data.params.other_user_name, 'jonathan', 'added field value should have been submitted'); - equal(data.params.removed_user_name, undefined, 'removed field value should be undefined'); - }); - }); -}); - -asyncTest('modifying data("type") with "ajax:before" requests new dataType in request', 2, function(){ - $('form[data-remote]').data('type','html') - .bind('ajax:before', function() { - var form = $(this); - form.data('type','xml') - }); - - submit(function(form) { - form.bind('ajax:beforeSend', function(e, xhr, settings) { - equal(settings.dataType, 'xml', 'modified dataType should have been requested'); - }); - }); -}); - -asyncTest('setting data("cross-domain",true) with "ajax:before" uses new setting in request', 2, function(){ - $('form[data-remote]').data('cross-domain',false) - .bind('ajax:before', function() { - var form = $(this); - form.data('cross-domain',true) - }); - - submit(function(form) { - form.bind('ajax:beforeSend', function(e, xhr, settings) { - equal(settings.crossDomain, true, 'setting modified in ajax:before should have forced cross-domain request'); - }); - }); -}); - -asyncTest('setting data("with-credentials",true) with "ajax:before" uses new setting in request', 2, function(){ - $('form[data-remote]').data('with-credentials',false) - .bind('ajax:before', function() { - var form = $(this); - form.data('with-credentials',true); - }); - - submit(function(form) { - form.bind('ajax:beforeSend', function(e, xhr, settings) { - equal(settings.xhrFields && settings.xhrFields.withCredentials, true, 'setting modified in ajax:before should have forced withCredentials request'); - }); - }); -}); - -asyncTest('stopping the "ajax:beforeSend" event aborts the request', 1, function() { - submit(function(form) { - form.bind('ajax:beforeSend', function() { - ok(true, 'aborting request in ajax:beforeSend') - return false; - }); - form.unbind('ajax:complete').bind('ajax:complete', function() { - ok(false, 'ajax:complete should not run'); - }); - form.bind('ajax:error', function(e, xhr, status, error) { - ok(false, 'ajax:error should not run'); - }); - $(document).bind('ajaxStop', function() { - start(); - }); - }); -}); - -asyncTest('blank required form input field should abort request and trigger "ajax:aborted:required" event', 5, function() { - $(document).bind('iframe:loading', function() { - ok(false, 'form should not get submitted'); - }); - - var form = $('form[data-remote]') - .append($('')) - .append($('')) - .bind('ajax:beforeSend', function() { - ok(false, 'ajax:beforeSend should not run'); - }) - .bind('ajax:aborted:required', function(e,data){ - ok(data.length == 2, 'ajax:aborted:required event is passed all blank required inputs (jQuery objects)'); - ok(data.first().is('input[name="user_name"]') , 'ajax:aborted:required adds blank required input to data'); - ok(data.last().is('textarea[name="user_bio"]'), 'ajax:aborted:required adds blank required textarea to data'); - ok(true, 'ajax:aborted:required should run'); - }) - .trigger('submit'); - - setTimeout(function() { - form.find('input[required],textarea[required]').val('Tyler'); - form.unbind('ajax:beforeSend'); - submit(); - }, 13); -}); - -asyncTest('blank required form input for non-remote form should abort normal submission', 1, function() { - var form = $('form[data-remote]') - .append($('')) - .removeAttr('data-remote') - .bind('ujs:everythingStopped', function() { - ok(true, 'ujs:everythingStopped should run'); - }) - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -asyncTest('form should be submitted with blank required fields if handler is bound to "ajax:aborted:required" event that returns false', 1, function(){ - var form = $('form[data-remote]') - .append($('')) - .bind('ajax:beforeSend', function() { - ok(true, 'ajax:beforeSend should run'); - }) - .bind('ajax:aborted:required', function() { - return false; - }) - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -asyncTest('disabled fields should not be included in blank required check', 2, function() { - var form = $('form[data-remote]') - .append($('')) - .append($('')) - .bind('ajax:beforeSend', function() { - ok(true, 'ajax:beforeSend should run'); - }) - .bind('ajax:aborted:required', function() { - ok(false, 'ajax:aborted:required should not run'); - }); - - submit(); -}); - -asyncTest('form should be submitted with blank required fields if it has the "novalidate" attribute', 2, function(){ - var form = $('form[data-remote]') - .append($('')) - .attr("novalidate", "novalidate") - .bind('ajax:beforeSend', function() { - ok(true, 'ajax:beforeSend should run'); - }) - .bind('ajax:aborted:required', function() { - ok(false, 'ajax:aborted:required should not run'); - }); - - submit(); -}); - -asyncTest('blank required form input for non-remote form with "novalidate" attribute should not abort normal submission', 1, function() { - $(document).bind('iframe:loading', function() { - ok(true, 'form should get submitted'); - }); - - var form = $('form[data-remote]') - .append($('')) - .removeAttr('data-remote') - .attr("novalidate","novalidate") - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -asyncTest('unchecked required checkbox should abort form submission', 1, function() { - var form = $('form[data-remote]') - .append($('')) - .removeAttr('data-remote') - .bind('ujs:everythingStopped', function() { - ok(true, 'ujs:everythingStopped should run'); - }) - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -asyncTest('unchecked required radio should abort form submission', 1, function() { - var form = $('form[data-remote]') - .append($('')) - .append($('')) - .removeAttr('data-remote') - .bind('ujs:everythingStopped', function() { - ok(true, 'ujs:everythingStopped should run'); - }) - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -asyncTest('required radio should only require one to be checked', 1, function() { - $(document).bind('iframe:loading', function() { - ok(true, 'form should get submitted'); - }); - - var form = $('form[data-remote]') - .append($('')) - .append($('')) - .removeAttr('data-remote') - .bind('ujs:everythingStopped', function() { - ok(false, 'ujs:everythingStopped should not run'); - }) - .find('#checkme').prop('checked', true) - .end() - .trigger('submit'); - - setTimeout(function() { - start(); - }, 13); -}); - -function skipIt() { - // This test cannot work due to the security feature in browsers which makes the value - // attribute of file input fields readonly, so it cannot be set with default value. - // This is what the test would look like though if browsers let us automate this test. - asyncTest('non-blank file form input field should abort remote request, but submit normally', 5, function() { - var form = $('form[data-remote]') - .append($('')) - .bind('ajax:beforeSend', function() { - ok(false, 'ajax:beforeSend should not run'); - }) - .bind('iframe:loading', function() { - ok(true, 'form should get submitted'); - }) - .bind('ajax:aborted:file', function(e,data) { - ok(data.length == 1, 'ajax:aborted:file event is passed all non-blank file inputs (jQuery objects)'); - ok(data.first().is('input[name="attachment"]') , 'ajax:aborted:file adds non-blank file input to data'); - ok(true, 'ajax:aborted:file event should run'); - }) - .trigger('submit'); - - setTimeout(function() { - form.find('input[type="file"]').val(''); - form.unbind('ajax:beforeSend'); - submit(); - }, 13); - }); - - asyncTest('blank file input field should abort request entirely if handler bound to "ajax:aborted:file" event that returns false', 1, function() { - var form = $('form[data-remote]') - .append($('')) - .bind('ajax:beforeSend', function() { - ok(false, 'ajax:beforeSend should not run'); - }) - .bind('iframe:loading', function() { - ok(false, 'form should not get submitted'); - }) - .bind('ajax:aborted:file', function() { - return false; - }) - .trigger('submit'); - - setTimeout(function() { - form.find('input[type="file"]').val(''); - form.unbind('ajax:beforeSend'); - submit(); - }, 13); - }); -} - -asyncTest('"ajax:beforeSend" can be observed and stopped with event delegation', 1, function() { - $(document).delegate('form[data-remote]', 'ajax:beforeSend', function() { - ok(true, 'ajax:beforeSend observed with event delegation'); - return false; - }); - - submit(function(form) { - form.unbind('ajax:complete').bind('ajax:complete', function() { - ok(false, 'ajax:complete should not run'); - }); - $(document).bind('ajaxStop', function() { - start(); - }); - }); -}); - -asyncTest('"ajax:beforeSend", "ajax:success" and "ajax:complete" are triggered', 8, function() { - submit(function(form) { - form.bind('ajax:beforeSend', function(e, xhr, settings) { - ok(xhr.setRequestHeader, 'first argument to "ajax:beforeSend" should be an XHR object'); - equal(settings.url, '/echo', 'second argument to "ajax:beforeSend" should be a settings object'); - }); - form.bind('ajax:success', function(e, data, status, xhr) { - ok(data.REQUEST_METHOD, 'first argument to ajax:success should be a data object'); - equal(status, 'success', 'second argument to ajax:success should be a status string'); - ok(xhr.getResponseHeader, 'third argument to "ajax:success" should be an XHR object'); - }); - form.bind('ajax:complete', function(e, xhr, status) { - ok(xhr.getResponseHeader, 'first argument to "ajax:complete" should be an XHR object'); - equal(status, 'success', 'second argument to ajax:complete should be a status string'); - }); - }); -}); - -asyncTest('"ajax:beforeSend", "ajax:error" and "ajax:complete" are triggered on error', 6, function() { - submit(function(form) { - form.attr('action', '/error'); - form.bind('ajax:beforeSend', function(arg) { ok(true, 'ajax:beforeSend') }); - form.bind('ajax:error', function(e, xhr, status, error) { - ok(xhr.getResponseHeader, 'first argument to "ajax:error" should be an XHR object'); - equal(status, 'error', 'second argument to ajax:error should be a status string'); - // Firefox 8 returns "Forbidden " with trailing space - equal($.trim(error), 'Forbidden', 'third argument to ajax:error should be an HTTP status response'); - // Opera returns "0" for HTTP code - equal(xhr.status, window.opera ? 0 : 403, 'status code should be 403'); - }); - }); -}); - -// IF THIS TEST IS FAILING, TRY INCREASING THE TIMEOUT AT THE BOTTOM TO > 100 -asyncTest('binding to ajax callbacks via .delegate() triggers handlers properly', 3, function() { - $(document) - .delegate('form[data-remote]', 'ajax:beforeSend', function() { - ok(true, 'ajax:beforeSend handler is triggered'); - }) - .delegate('form[data-remote]', 'ajax:complete', function() { - ok(true, 'ajax:complete handler is triggered'); - }) - .delegate('form[data-remote]', 'ajax:success', function() { - ok(true, 'ajax:success handler is triggered'); - }); - $('form[data-remote]').trigger('submit'); - - setTimeout(function() { - start(); - }, 63); -}); - -asyncTest('binding to ajax:send event to call jquery methods on ajax object', 2, function() { - $('form[data-remote]') - .bind('ajax:send', function(e, xhr) { - ok(true, 'event should fire'); - equal(typeof(xhr.abort), 'function', 'event should pass jqXHR object'); - xhr.abort(); - }) - .trigger('submit'); - - setTimeout(function() { start(); }, 35); -}); - -})(); diff --git a/test/public/test/call-remote.js b/test/public/test/call-remote.js deleted file mode 100644 index ef998a8b..00000000 --- a/test/public/test/call-remote.js +++ /dev/null @@ -1,175 +0,0 @@ -(function(){ - -function build_form(attrs) { - attrs = $.extend({ action: '/echo', 'data-remote': 'true' }, attrs); - - $('#qunit-fixture').append($('', attrs)) - .find('form').append($('')); -}; - -module('call-remote'); - -function submit(fn) { - $('form') - .bind('ajax:success', fn) - .bind('ajax:complete', function() { start() }) - .trigger('submit'); -} - -asyncTest('form method is read from "method" and not from "data-method"', 1, function() { - build_form({ method: 'post', 'data-method': 'get' }); - - submit(function(e, data, status, xhr) { - App.assert_post_request(data); - }); -}); - -asyncTest('form method is not read from "data-method" attribute in case of missing "method"', 1, function() { - build_form({ 'data-method': 'put' }); - - submit(function(e, data, status, xhr) { - App.assert_get_request(data); - }); -}); - -asyncTest('form default method is GET', 1, function() { - build_form(); - - submit(function(e, data, status, xhr) { - App.assert_get_request(data); - }); -}); - -asyncTest('form url is picked up from "action"', 1, function() { - build_form({ method: 'post' }); - - submit(function(e, data, status, xhr) { - App.assert_request_path(data, '/echo'); - }); -}); - -asyncTest('form url is read from "action" not "href"', 1, function() { - build_form({ method: 'post', href: '/echo2' }); - - submit(function(e, data, status, xhr) { - App.assert_request_path(data, '/echo'); - }); -}); - -asyncTest('prefer JS, but accept any format', 1, function() { - build_form({ method: 'post' }); - - submit(function(e, data, status, xhr) { - var accept = data.HTTP_ACCEPT; - ok(accept.indexOf('*/*;q=0.5, text/javascript, application/javascript') === 0, 'Accept: ' + accept); - }); -}); - -asyncTest('accept application/json if "data-type" is json', 1, function() { - build_form({ method: 'post', 'data-type': 'json' }); - - submit(function(e, data, status, xhr) { - equal(data.HTTP_ACCEPT, 'application/json, text/javascript, */*; q=0.01'); - }); -}); - -asyncTest('allow empty "data-remote" attribute', 1, function() { - var form = $('#qunit-fixture').append($('')).find('form'); - - submit(function() { - ok(true, 'form with empty "data-remote" attribute is also allowed'); - }); -}); - -asyncTest('allow empty form "action"', 1, function() { - var currentLocation, ajaxLocation; - - build_form({ action: '' }); - - $('#qunit-fixture').find('form') - .bind('ajax:beforeSend', function(e, xhr, settings) { - // Get current location (the same way jQuery does) - try { - currentLocation = location.href; - } catch(e) { - currentLocation = document.createElement( "a" ); - currentLocation.href = ""; - currentLocation = currentLocation.href; - } - currentLocation = currentLocation.replace(/\?$/, ''); - - // Actual location (strip out settings.data that jQuery serializes and appends) - // HACK: can no longer use settings.data below to see what was appended to URL, as of - // jQuery 1.6.3 (see http://bugs.jquery.com/ticket/10202 and https://github.com/jquery/jquery/pull/544) - ajaxLocation = settings.url.replace("user_name=john","").replace(/&$/, "").replace(/\?$/, ""); - equal(ajaxLocation.match(/^(.*)/)[1], currentLocation, 'URL should be current page by default'); - - // Prevent the request from actually getting sent to the current page and - // causing an error. - return false; - }) - .trigger('submit'); - - setTimeout(function() { start(); }, 13); -}); - -asyncTest('sends CSRF token in custom header', 1, function() { - build_form({ method: 'post' }); - $('#qunit-fixture').append(''); - - submit(function(e, data, status, xhr) { - equal(data.HTTP_X_CSRF_TOKEN, 'cf50faa3fe97702ca1ae', 'X-CSRF-Token header should be sent'); - }); -}); - -asyncTest('does not send CSRF token in custom header if crossDomain', 1, function() { - build_form({ 'data-cross-domain': 'true' }); - $('#qunit-fixture').append(''); - - // Manually set request header to be XHR, since setting crossDomain: true in .ajax() - // causes jQuery to skip setting the request header, to prevent our test/server.rb from - // raising an an error (when request.xhr? is false). - $('#qunit-fixture').find('form').bind('ajax:beforeSend', function(e, xhr) { - xhr.setRequestHeader('X-Requested-With', "XMLHttpRequest"); - }); - - submit(function(e, data, status, xhr) { - equal(data.HTTP_X_CSRF_TOKEN, undefined, 'X-CSRF-Token header should NOT be sent'); - }); -}); - -asyncTest('intelligently guesses crossDomain behavior when target URL is a different domain', 1, function(e, xhr) { - - // Don't set data-cross-domain here, just set action to be a different domain than localhost - build_form({ action: 'http://www.alfajango.com' }); - $('#qunit-fixture').append(''); - - $('#qunit-fixture').find('form') - .bind('ajax:beforeSend', function(e, xhr, settings) { - - equal(settings.crossDomain, true, 'crossDomain should be set to true'); - - // prevent request from actually getting sent off-domain - return false; - }) - .trigger('submit'); - - setTimeout(function() { start(); }, 13); -}); - -asyncTest('does not set crossDomain if explicitly set to false on element', 1, function() { - build_form({ action: 'http://www.alfajango.com', 'data-cross-domain': false }); - $('#qunit-fixture').append(''); - - $('#qunit-fixture').find('form') - .bind('ajax:beforeSend', function(e, xhr, settings) { - equal(settings.crossDomain, false, 'crossDomain should be set to false'); - // prevent request from actually getting sent off-domain - return false; - }) - .trigger('submit'); - - setTimeout(function() { start(); }, 13); -}); - -})(); diff --git a/test/public/test/data-confirm.js b/test/public/test/data-confirm.js deleted file mode 100644 index 68784b84..00000000 --- a/test/public/test/data-confirm.js +++ /dev/null @@ -1,101 +0,0 @@ -module('data-confirm', { - setup: function() { - $('#qunit-fixture').append($('', { - href: '/echo', - 'data-remote': 'true', - 'data-confirm': 'Are you absolutely sure?', - text: 'my social security number' - })); - - this.windowConfirm = window.confirm; - }, - teardown: function() { - window.confirm = this.windowConfirm; - } -}); - -asyncTest('clicking on a link with data-confirm attribute. Confirm yes.', 6, function() { - var message; - // auto-confirm: - window.confirm = function(msg) { message = msg; return true }; - - $('a[data-confirm]') - .bind('confirm:complete', function(e, data) { - App.assert_callback_invoked('confirm:complete'); - ok(data == true, 'confirm:complete passes in confirm answer (true)'); - }) - .bind('ajax:success', function(e, data, status, xhr) { - App.assert_callback_invoked('ajax:success'); - App.assert_request_path(data, '/echo'); - App.assert_get_request(data); - - equal(message, 'Are you absolutely sure?'); - start(); - }) - .trigger('click'); -}); - -asyncTest('clicking on a link with data-confirm attribute. Confirm No.', 3, function() { - var message; - // auto-decline: - window.confirm = function(msg) { message = msg; return false }; - - $('a[data-confirm]') - .bind('confirm:complete', function(e, data) { - App.assert_callback_invoked('confirm:complete'); - ok(data == false, 'confirm:complete passes in confirm answer (false)'); - }) - .bind('ajax:beforeSend', function(e, data, status, xhr) { - App.assert_callback_not_invoked('ajax:beforeSend'); - }) - .trigger('click'); - - setTimeout(function() { - equal(message, 'Are you absolutely sure?'); - start(); - }, 50); -}); - - -asyncTest('binding to confirm event and returning false', 1, function() { - // redefine confirm function so we can make sure it's not called - window.confirm = function(msg) { - ok(false, 'confirm dialog should not be called'); - }; - - $('a[data-confirm]') - .bind('confirm', function() { - App.assert_callback_invoked('confirm'); - return false; - }) - .bind('confirm:complete', function() { - App.assert_callback_not_invoked('confirm:complete') - }) - .trigger('click'); - - setTimeout(function() { - start(); - }, 50); -}); - -asyncTest('binding to confirm:complete event and returning false', 2, function() { - // auto-confirm: - window.confirm = function(msg) { - ok(true, 'confirm dialog should be called'); - return true; - }; - - $('a[data-confirm]') - .bind('confirm:complete', function() { - App.assert_callback_invoked('confirm:complete'); - return false; - }) - .bind('ajax:beforeSend', function() { - App.assert_callback_not_invoked('ajax:beforeSend'); - }) - .trigger('click'); - - setTimeout(function() { - start(); - }, 50); -}); diff --git a/test/public/test/data-disable.js b/test/public/test/data-disable.js deleted file mode 100644 index 6c973dfd..00000000 --- a/test/public/test/data-disable.js +++ /dev/null @@ -1,247 +0,0 @@ -module('data-disable', { - setup: function() { - $('#qunit-fixture').append($('', { - action: '/echo', - 'data-remote': 'true', - method: 'post' - })) - .find('form') - .append($('')); - - $('#qunit-fixture').append($('', { - action: '/echo', - method: 'post' - })) - .find('form:last') - // WEEIRDD: the form won't submit to an iframe if the button is name="submit" (??!) - .append($('')); - - $('#qunit-fixture').append($('', { - text: 'Click me', - href: '/echo', - 'data-disable-with': 'clicking...' - })); - }, - teardown: function() { - $(document).unbind('iframe:loaded'); - } -}); - -function getVal(el) { - return el.is('input,textarea,select') ? el.val() : el.text(); -} - -function disabled(el) { - return el.is('input,textarea,select,button') ? el.is(':disabled') : el.data('ujs:enable-with'); -} - -function checkEnabledState(el, text) { - ok(!disabled(el), el.get(0).tagName + ' should not be disabled'); - equal(getVal(el), text, el.get(0).tagName + ' text should be original value'); -} - -function checkDisabledState(el, text) { - ok(disabled(el), el.get(0).tagName + ' should be disabled'); - equal(getVal(el), text, el.get(0).tagName + ' text should be disabled value'); -} - -asyncTest('form input field with "data-disable-with" attribute', 7, function() { - var form = $('form[data-remote]'), input = form.find('input[type=text]'); - - checkEnabledState(input, 'john'); - - form.bind('ajax:success', function(e, data) { - setTimeout(function() { - checkEnabledState(input, 'john'); - equal(data.params.user_name, 'john'); - start(); - }, 13) - }) - form.trigger('submit'); - - checkDisabledState(input, 'processing ...'); -}); - -asyncTest('form button with "data-disable-with" attribute', 6, function() { - var form = $('form[data-remote]'), button = $(''); - form.append(button); - - checkEnabledState(button, 'Submit'); - - form.bind('ajax:success', function(e, data) { - setTimeout(function() { - checkEnabledState(button, 'Submit'); - start(); - }, 13) - }) - form.trigger('submit'); - - checkDisabledState(button, 'submitting ...'); -}); - -asyncTest('form input[type=submit][data-disable-with] disables', 6, function(){ - var form = $('form:not([data-remote])'), input = form.find('input[type=submit]'); - - checkEnabledState(input, 'Submit'); - - // WEEIRDD: attaching this handler makes the test work in IE7 - $(document).bind('iframe:loading', function(e, form) {}); - - $(document).bind('iframe:loaded', function(e, data) { - setTimeout(function() { - checkDisabledState(input, 'submitting ...'); - start(); - }, 30); - }); - form.trigger('submit'); - - setTimeout(function() { - checkDisabledState(input, 'submitting ...'); - }, 30); -}); - -asyncTest('form[data-remote] input[type=submit][data-disable-with] is replaced in ajax callback', 2, function(){ - var form = $('form:not([data-remote])').attr('data-remote', 'true'), origFormContents = form.html(); - - form.bind('ajax:success', function(){ - form.html(origFormContents); - - setTimeout(function(){ - var input = form.find('input[type=submit]'); - checkEnabledState(input, 'Submit'); - start(); - }, 30); - }).trigger('submit'); -}); - -asyncTest('form[data-remote] input[data-disable-with] is replaced with disabled field in ajax callback', 2, function(){ - var form = $('form:not([data-remote])').attr('data-remote', 'true'), input = form.find('input[type=submit]'), - newDisabledInput = input.clone().attr('disabled', 'disabled'); - - form.bind('ajax:success', function(){ - input.replaceWith(newDisabledInput); - - setTimeout(function(){ - checkEnabledState(newDisabledInput, 'Submit'); - start(); - }, 30); - }).trigger('submit'); -}); - -asyncTest('form[data-remote] textarea[data-disable-with] attribute', 3, function() { - var form = $('form[data-remote]'), - textarea = $('').appendTo(form); - - form.bind('ajax:success', function(e, data) { - setTimeout(function() { - equal(data.params.user_bio, 'born, lived, died.'); - start(); - }, 13) - }) - form.trigger('submit'); - - checkDisabledState(textarea, 'processing ...'); -}); - -asyncTest('a[data-disable-with] disables', 4, function() { - var link = $('a[data-disable-with]'); - - checkEnabledState(link, 'Click me'); - - link.trigger('click'); - checkDisabledState(link, 'clicking...'); - start(); -}); - -asyncTest('a[data-remote][data-disable-with] disables and re-enables', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); - - checkEnabledState(link, 'Click me'); - - link - .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); - }) - .bind('ajax:complete', function() { - setTimeout( function() { - checkEnabledState(link, 'Click me'); - start(); - }, 15); - }) - .trigger('click'); -}); - -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:before` event is cancelled', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); - - checkEnabledState(link, 'Click me'); - - link - .bind('ajax:before', function() { - checkDisabledState(link, 'clicking...'); - return false; - }) - .trigger('click'); - - setTimeout(function() { - checkEnabledState(link, 'Click me'); - start(); - }, 30); -}); - -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:beforeSend` event is cancelled', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true); - - checkEnabledState(link, 'Click me'); - - link - .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); - return false; - }) - .trigger('click'); - - setTimeout(function() { - checkEnabledState(link, 'Click me'); - start(); - }, 30); -}); - -asyncTest('a[data-remote][data-disable-with] re-enables when `ajax:error` event is triggered', 6, function() { - var link = $('a[data-disable-with]').attr('data-remote', true).attr('href', '/error'); - - checkEnabledState(link, 'Click me'); - - link - .bind('ajax:beforeSend', function() { - checkDisabledState(link, 'clicking...'); - }) - .trigger('click'); - - setTimeout(function() { - checkEnabledState(link, 'Click me'); - start(); - }, 30); -}); - -asyncTest('form[data-remote] input|button|textarea[data-disable-with] does not disable when `ajax:beforeSend` event is cancelled', 8, function() { - var form = $('form[data-remote]'), - input = form.find('input:text'), - button = $('').appendTo(form), - textarea = $('').appendTo(form), - submit = $('').appendTo(form); - - form - .bind('ajax:beforeSend', function() { - return false; - }) - .trigger('submit'); - - checkEnabledState(input, 'john'); - checkEnabledState(button, 'Submit'); - checkEnabledState(textarea, 'born, lived, died.'); - checkEnabledState(submit, 'Submit'); - - start(); - -}); diff --git a/test/public/test/data-method.js b/test/public/test/data-method.js deleted file mode 100644 index c4426624..00000000 --- a/test/public/test/data-method.js +++ /dev/null @@ -1,49 +0,0 @@ -(function(){ - -module('data-method', { - setup: function() { - $('#qunit-fixture').append($('', { - href: '/echo', 'data-method': 'delete', text: 'destroy!' - })); - }, - teardown: function() { - $(document).unbind('iframe:loaded'); - } -}); - -function submit(fn, options) { - $(document).bind('iframe:loaded', function(e, data) { - fn(data); - start(); - }); - - $('#qunit-fixture').find('a') - .trigger('click'); -} - -asyncTest('link with "data-method" set to "delete"', 3, function() { - submit(function(data) { - equal(data.REQUEST_METHOD, 'DELETE'); - strictEqual(data.params.authenticity_token, undefined); - strictEqual(data.HTTP_X_CSRF_TOKEN, undefined); - }); -}); - -asyncTest('link with "data-method" and CSRF', 1, function() { - $('#qunit-fixture') - .append('') - .append(''); - - submit(function(data) { - equal(data.params.authenticity_token, 'cf50faa3fe97702ca1ae'); - }); -}); - -asyncTest('link "target" should be carried over to generated form', 1, function() { - $('a[data-method]').attr('target', 'super-special-frame'); - submit(function(data) { - equal(data.params._target, 'super-special-frame'); - }); -}); - -})(); diff --git a/test/public/test/data-remote.js b/test/public/test/data-remote.js deleted file mode 100644 index d9c2f6d7..00000000 --- a/test/public/test/data-remote.js +++ /dev/null @@ -1,169 +0,0 @@ -module('data-remote', { - setup: function() { - $('#qunit-fixture') - .append($('', { - href: '/echo', - 'data-remote': 'true', - 'data-params': 'data1=value1&data2=value2', - text: 'my address' - })) - .append($('', { - action: '/echo', - 'data-remote': 'true', - method: 'post' - })) - .find('form').append($('')); - - } -}); - -asyncTest('ctrl-clicking on a link does not fire ajaxyness', 0, function() { - var link = $('a[data-remote]'), e; - - // Ideally, we'd setup an iframe to intercept normal link clicks - // and add a test to make sure the iframe:loaded event is triggered. - // However, jquery doesn't actually cause a native `click` event and - // follow links using `trigger('click')`, it only fires bindings. - link - .removeAttr('data-params') - .bind('ajax:beforeSend', function() { - ok(false, 'ajax should not be triggered'); - }); - - e = $.Event('click'); - e.metaKey = true; - link.trigger(e); - - e = $.Event('click'); - e.ctrlKey = true; - link.trigger(e); - - setTimeout(function(){ start(); }, 13); -}); - -asyncTest('ctrl-clicking on a link still fires ajax for non-GET links and for links with "data-params"', 2, function() { - var link = $('a[data-remote]'), e; - e = $.Event('click'); - e.metaKey = true; - - link - .removeAttr('data-params') - .attr('data-method', 'POST') - .bind('ajax:beforeSend', function() { - ok(true, 'ajax should be triggered'); - }) - .trigger(e); - - e = $.Event('click'); - e.metaKey = true; - - link - .removeAttr('data-method') - .attr('data-params', 'name=steve') - .trigger(e); - - setTimeout(function(){ start(); }, 13); -}); - -asyncTest('clicking on a link with data-remote attribute', 5, function() { - $('a[data-remote]') - .bind('ajax:success', function(e, data, status, xhr) { - App.assert_callback_invoked('ajax:success'); - App.assert_request_path(data, '/echo'); - equal(data.params.data1, 'value1', 'ajax arguments should have key data1 with right value'); - equal(data.params.data2, 'value2', 'ajax arguments should have key data2 with right value'); - App.assert_get_request(data); - }) - .bind('ajax:complete', function() { start() }) - .trigger('click'); -}); - -asyncTest('changing a select option with data-remote attribute', 5, function() { - $('form') - .append( - $('')) - .bind('submit', function(event){ - ok(event.type == 'submit', 'submit event handlers are called with submit event'); - ok(true, 'binding handler is called'); - directBindingCalled = true; - }) - .bind('ajax:beforeSend', function(){ - ok(true, 'form being submitted via ajax'); - ok(directBindingCalled, 'binding handler already called'); - }) - .bind('ajax:complete', function(){ - start(); - }); - - if(!$.support.submitBubbles) { - // Must indrectly submit form via click to trigger jQuery's manual submit bubbling in IE - form.find('input[type=submit]') - .trigger('click'); - } else { - form.trigger('submit'); - } -}); - -asyncTest('returning false in form\'s submit bindings in non-submit-bubbling browsers', 1, function(){ - var form = $('form[data-remote]'); - - form - .append($('')) - .bind('submit', function(){ - ok(true, 'binding handler is called'); - return false; - }) - .bind('ajax:beforeSend', function(){ - ok(false, 'form should not be submitted'); - }); - - if (!$.support.submitBubbles) { - // Must indrectly submit form via click to trigger jQuery's manual submit bubbling in IE - form.find('input[type=submit]').trigger('click'); - } else { - form.trigger('submit'); - } - - setTimeout(function(){ start(); }, 13); -}); diff --git a/test/public/test/override.js b/test/public/test/override.js deleted file mode 100644 index ba84b6dc..00000000 --- a/test/public/test/override.js +++ /dev/null @@ -1,68 +0,0 @@ -(function(){ - -module('override', { - setup: function() { - window.realHref = $.rails.href; - $('#qunit-fixture') - .append($('', { - href: '/real/href', 'data-method': 'delete', 'data-href': '/data/href' - })) - .append($('', { - href: '/other/href', 'data-custom-remote-link': 'true' - })); - }, - teardown: function() { - $.rails.href = window.realHref; - } -}); - -asyncTest("the getter for an element's href is publicly accessible", 1, function() { - ok($.rails.href); - start(); -}); - -asyncTest("the getter for an element's href is overridable", 1, function() { - $.rails.href = function(element) { return element.data('href'); } - $.rails.ajax = function(options) { - equal('/data/href', options.url); - } - $.rails.handleRemote($('#qunit-fixture').find('a')); - start(); -}); - -asyncTest("the getter for an element's href works normally if not overridden", 1, function() { - $.rails.ajax = function(options) { - equal('/real/href', options.url); - } - $.rails.handleRemote($('#qunit-fixture').find('a')); - start(); -}); - -asyncTest("the event selector strings are overridable", 2, function() { - var documentClickBindings = $._data(document, 'events').click, - linkClickBinding = $.grep(documentClickBindings, function(a) { - return a.selector && a.selector.indexOf('a[data-remote]') != -1; - })[0]; - - ok($.rails.linkClickSelector.indexOf(', a[data-custom-remote-link]') != -1, 'linkClickSelector contains custom selector'); - - ok(linkClickBinding.selector.indexOf(', a[data-custom-remote-link]') != -1, 'actual document binding contains custom selector'); - - start(); -}); - -// Not sure why this test isn't working in jquery 1.7, -// or why the error message doesn't show in the console in 1.8 -// when the test is run. -// -//asyncTest("including jquery-ujs multiple times throws error", 1, function() { -// var script = document.createElement( 'script' ); -// script.type = 'text/javascript'; -// script.src = '/src/rails.js'; -// raises(function() { -// $("#qunit-fixture").append( script ); -// }, 'appending rails.js again throws error'); -// setTimeout(function() { start(); }, 50); -//}); - -})(); diff --git a/test/public/test/settings.js b/test/public/test/settings.js deleted file mode 100644 index e23bf7ed..00000000 --- a/test/public/test/settings.js +++ /dev/null @@ -1,37 +0,0 @@ -var App = App || {}; - -App.assert_callback_invoked = function(callback_name) { - ok(true, callback_name + ' callback should have been invoked'); -}; - -App.assert_callback_not_invoked = function(callback_name) { - ok(false, callback_name + ' callback should not have been invoked'); -}; - -App.assert_get_request = function(request_env){ - equal(request_env['REQUEST_METHOD'], 'GET', 'request type should be GET'); -}; - -App.assert_post_request = function(request_env){ - equal(request_env['REQUEST_METHOD'], 'POST', 'request type should be POST'); -}; - -App.assert_request_path = function(request_env, path) { - equal(request_env['PATH_INFO'], path, 'request should be sent to right url'); -}; - -// hijacks normal form submit; lets it submit to an iframe to prevent -// navigating away from the test suite -$(document).bind('submit', function(e) { - if (!e.isDefaultPrevented()) { - var form = $(e.target), action = form.attr('action'), - name = 'form-frame' + jQuery.guid++, - iframe = $('