aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md9
-rw-r--r--actionview/app/assets/javascripts/rails-ujs/utils/form.coffee1
-rw-r--r--actionview/lib/action_view/base.rb1
-rw-r--r--actionview/lib/action_view/digestor.rb9
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb3
-rw-r--r--actionview/lib/action_view/helpers/asset_url_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb7
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb105
-rw-r--r--actionview/lib/action_view/layouts.rb2
-rw-r--r--actionview/lib/action_view/lookup_context.rb1
-rw-r--r--actionview/lib/action_view/template.rb2
-rw-r--r--actionview/lib/action_view/template/error.rb20
-rw-r--r--actionview/lib/action_view/template/handlers.rb2
-rw-r--r--actionview/lib/action_view/template/html.rb2
-rw-r--r--actionview/lib/action_view/testing/resolvers.rb38
-rw-r--r--actionview/lib/action_view/unbound_template.rb6
-rw-r--r--actionview/test/template/template_error_test.rb16
-rw-r--r--actionview/test/template/testing/fixture_resolver_test.rb22
-rw-r--r--actionview/test/template/url_helper_test.rb128
-rw-r--r--actionview/test/ujs/public/test/data-remote.js18
20 files changed, 342 insertions, 52 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index f2f57e6a36..ca3ce1476a 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,12 @@
+* Added `phone_to` helper method to create a link from mobile numbers
+
+ *Pietro Moro*
+
+* annotated_source_code returns an empty array so TemplateErrors without a
+ template in the backtrace are surfaced properly by DebugExceptions.
+
+ *Guilherme Mansur*, *Kasper Timm Hansen*
+
* Add autoload for SyntaxErrorInTemplate so syntax errors are correctly raised by DebugExceptions.
*Guilherme Mansur*, *Gannon McGibbon*
diff --git a/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee b/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee
index 736cab08db..9e11bfa7ed 100644
--- a/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee
+++ b/actionview/app/assets/javascripts/rails-ujs/utils/form.coffee
@@ -11,6 +11,7 @@ Rails.serializeElement = (element, additionalParam) ->
inputs.forEach (input) ->
return if !input.name || input.disabled
+ return if input.closest('fieldset[disabled]')
if matches(input, 'select')
toArray(input.options).forEach (option) ->
params.push(name: input.name, value: option.value) if option.selected
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index 5253ef7b0c..40d5ed36a1 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -3,7 +3,6 @@
require "active_support/core_ext/module/attr_internal"
require "active_support/core_ext/module/attribute_accessors"
require "active_support/ordered_options"
-require "active_support/deprecation"
require "action_view/log_subscriber"
require "action_view/helpers"
require "action_view/context"
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb
index 97a6da3634..cdf436ccae 100644
--- a/actionview/lib/action_view/digestor.rb
+++ b/actionview/lib/action_view/digestor.rb
@@ -9,10 +9,11 @@ module ActionView
class << self
# Supported options:
#
- # * <tt>name</tt> - Template name
- # * <tt>finder</tt> - An instance of <tt>ActionView::LookupContext</tt>
- # * <tt>dependencies</tt> - An array of dependent views
- def digest(name:, format:, finder:, dependencies: nil)
+ # * <tt>name</tt> - Template name
+ # * <tt>format</tt> - Template format
+ # * <tt>finder</tt> - An instance of <tt>ActionView::LookupContext</tt>
+ # * <tt>dependencies</tt> - An array of dependent views
+ def digest(name:, format: nil, finder:, dependencies: nil)
if dependencies.nil? || dependencies.empty?
cache_key = "#{name}.#{format}"
else
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 59d70a1dc4..1e1d97fe75 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -3,7 +3,6 @@
require "active_support/core_ext/array/extract_options"
require "active_support/core_ext/hash/keys"
require "active_support/core_ext/object/inclusion"
-require "active_support/core_ext/object/try"
require "action_view/helpers/asset_url_helper"
require "action_view/helpers/tag_helper"
@@ -268,7 +267,7 @@ module ActionView
def preload_link_tag(source, options = {})
href = asset_path(source, skip_pipeline: options.delete(:skip_pipeline))
extname = File.extname(source).downcase.delete(".")
- mime_type = options.delete(:type) || Template::Types[extname].try(:to_s)
+ mime_type = options.delete(:type) || Template::Types[extname]&.to_s
as_type = options.delete(:as) || resolve_link_as(extname, mime_type)
crossorigin = options.delete(:crossorigin)
crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font")
diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb
index cc62783d60..295f945325 100644
--- a/actionview/lib/action_view/helpers/asset_url_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_url_helper.rb
@@ -133,6 +133,8 @@ module ActionView
# which is implemented by sprockets-rails.
#
# asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
+ # asset_path('application.js', host: 'example.com') # => "//example.com/assets/application.js"
+ # asset_path("application.js", host: 'example.com', protocol: 'https') # => "https://example.com/assets/application.js"
#
# === Without the asset pipeline (<tt>skip_pipeline: true</tt>)
#
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index a7747456a4..ad19426fff 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -566,9 +566,10 @@ module ActionView
# an ActiveSupport::TimeZone.
#
# By default, +model+ is the ActiveSupport::TimeZone constant (which can
- # be obtained in Active Record as a value object). The only requirement
- # is that the +model+ parameter be an object that responds to +all+, and
- # returns an array of objects that represent time zones.
+ # be obtained in Active Record as a value object). The +model+ parameter
+ # must respond to +all+ and return an array of objects that represent time
+ # zones; each object must respond to +name+. If a Regexp is given it will
+ # attempt to match the zones using the <code>=~<code> operator.
#
# NOTE: Only the option tags are returned, you have to wrap this call in
# a regular HTML select tag.
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb
index 4b3a258287..ea2a97f458 100644
--- a/actionview/lib/action_view/helpers/url_helper.rb
+++ b/actionview/lib/action_view/helpers/url_helper.rb
@@ -60,8 +60,8 @@ module ActionView
# Creates an anchor element of the given +name+ using a URL created by the set of +options+.
# See the valid options in the documentation for +url_for+. It's also possible to
- # pass a String instead of an options hash, which generates an anchor element that uses the
- # value of the String as the href for the link. Using a <tt>:back</tt> Symbol instead
+ # pass a \String instead of an options hash, which generates an anchor element that uses the
+ # value of the \String as the href for the link. Using a <tt>:back</tt> \Symbol instead
# of an options hash will generate a link to the referrer (a JavaScript back link
# will be used in place of a referrer if none exists). If +nil+ is passed as the name
# the value of the link itself will become the name.
@@ -226,7 +226,7 @@ module ActionView
# The +options+ hash accepts the same options as +url_for+.
#
# There are a few special +html_options+:
- # * <tt>:method</tt> - Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
+ # * <tt>:method</tt> - \Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
# <tt>:delete</tt>, <tt>:patch</tt>, and <tt>:put</tt>. By default it will be <tt>:post</tt>.
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
# * <tt>:data</tt> - This option can be used to add custom data attributes.
@@ -235,7 +235,7 @@ module ActionView
# * <tt>:form</tt> - This hash will be form attributes
# * <tt>:form_class</tt> - This controls the class of the form within which the submit button will
# be placed
- # * <tt>:params</tt> - Hash of parameters to be rendered as hidden fields within the form.
+ # * <tt>:params</tt> - \Hash of parameters to be rendered as hidden fields within the form.
#
# ==== Data attributes
#
@@ -571,6 +571,101 @@ module ActionView
end
end
+ # Creates an SMS anchor link tag to the specified +phone_number+, which is
+ # also used as the name of the link unless +name+ is specified. Additional
+ # HTML attributes for the link can be passed in +html_options+.
+ #
+ # When clicked, an SMS message is prepopulated with the passed phone number
+ # and optional +body+ value.
+ #
+ # +sms_to+ has a +body+ option for customizing the SMS message itself by
+ # passing special keys to +html_options+.
+ #
+ # ==== Options
+ # * <tt>:body</tt> - Preset the body of the message.
+ #
+ # ==== Examples
+ # sms_to "5155555785"
+ # # => <a href="sms:5155555785;">5155555785</a>
+ #
+ # sms_to "5155555785", "Text me"
+ # # => <a href="sms:5155555785;">Text me</a>
+ #
+ # sms_to "5155555785", "Text me",
+ # body: "Hello Jim I have a question about your product."
+ # # => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
+ #
+ # You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
+ #
+ # <%= sms_to "5155555785" do %>
+ # <strong>Text me:</strong>
+ # <% end %>
+ # # => <a href="sms:5155555785;">
+ # <strong>Text me:</strong>
+ # </a>
+ def sms_to(phone_number, name = nil, html_options = {}, &block)
+ html_options, name = name, nil if block_given?
+ html_options = (html_options || {}).stringify_keys
+
+ extras = %w{ body }.map! { |item|
+ option = html_options.delete(item).presence || next
+ "#{item.dasherize}=#{ERB::Util.url_encode(option)}"
+ }.compact
+ extras = extras.empty? ? "" : "?&" + extras.join("&")
+
+ encoded_phone_number = ERB::Util.url_encode(phone_number)
+ html_options["href"] = "sms:#{encoded_phone_number};#{extras}"
+
+ content_tag("a", name || phone_number, html_options, &block)
+ end
+
+ # Creates a TEL anchor link tag to the specified +phone_number+, which is
+ # also used as the name of the link unless +name+ is specified. Additional
+ # HTML attributes for the link can be passed in +html_options+.
+ #
+ # When clicked, the default app to make calls is opened, and it
+ # is prepopulated with the passed phone number and optional
+ # +country_code+ value.
+ #
+ # +phone_to+ has a optional +country_code+ option which automatically adds the country
+ # code as well as the + sign in the phone numer that gets prepopulated,
+ # for example if +country_code: "01"+ +\+01+ will be prepended to the
+ # phone numer, by passing special keys to +html_options+.
+ #
+ # ==== Options
+ # * <tt>:country_code</tt> - Prepends the country code to the number
+ #
+ # ==== Examples
+ # phone_to "1234567890"
+ # # => <a href="tel:1234567890">1234567890</a>
+ #
+ # phone_to "1234567890", "Phone me"
+ # # => <a href="tel:134567890">Phone me</a>
+ #
+ # phone_to "1234567890", "Phone me", country_code: "01"
+ # # => <a href="tel:+015155555785">Phone me</a>
+ #
+ # You can use a block as well if your link target is hard to fit into the name parameter. \ERB example:
+ #
+ # <%= phone_to "1234567890" do %>
+ # <strong>Phone me:</strong>
+ # <% end %>
+ # # => <a href="tel:1234567890">
+ # <strong>Phone me:</strong>
+ # </a>
+ def phone_to(phone_number, name = nil, html_options = {}, &block)
+ html_options, name = name, nil if block_given?
+ html_options = (html_options || {}).stringify_keys
+
+ country_code = html_options.delete("country_code").presence
+ country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"
+
+ encoded_phone_number = ERB::Util.url_encode(phone_number)
+ html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"
+
+ content_tag("a", name || phone_number, html_options, &block)
+ end
+
private
def convert_options_to_data_attributes(options, html_options)
if html_options
@@ -594,7 +689,7 @@ module ActionView
end
def add_method_to_attributes!(html_options, method)
- if method_not_get_method?(method) && html_options["rel"] !~ /nofollow/
+ if method_not_get_method?(method) && !html_options["rel"]&.match?(/nofollow/)
if html_options["rel"].blank?
html_options["rel"] = "nofollow"
else
diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb
index be21ff0e5d..74e8e80e07 100644
--- a/actionview/lib/action_view/layouts.rb
+++ b/actionview/lib/action_view/layouts.rb
@@ -395,7 +395,7 @@ module ActionView
end
def _normalize_layout(value)
- value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value
+ value.is_a?(String) && !value.match?(/\blayouts/) ? "layouts/#{value}" : value
end
# Returns the default layout for this controller.
diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb
index 138ffa515b..211fbc8e6c 100644
--- a/actionview/lib/action_view/lookup_context.rb
+++ b/actionview/lib/action_view/lookup_context.rb
@@ -3,7 +3,6 @@
require "concurrent/map"
require "active_support/core_ext/module/remove_method"
require "active_support/core_ext/module/attribute_accessors"
-require "active_support/deprecation"
require "action_view/template/resolver"
module ActionView
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index 88320dcd0d..3877108fef 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
-require "active_support/core_ext/object/try"
require "active_support/core_ext/kernel/singleton_class"
-require "active_support/deprecation"
require "thread"
require "delegate"
diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb
index feceef15f9..7fc74a5502 100644
--- a/actionview/lib/action_view/template/error.rb
+++ b/actionview/lib/action_view/template/error.rb
@@ -81,8 +81,8 @@ module ActionView
end
end
- def source_extract(indentation = 0, output = :console)
- return unless num = line_number
+ def source_extract(indentation = 0)
+ return [] unless num = line_number
num = num.to_i
source_code = @template.source.split("\n")
@@ -91,9 +91,9 @@ module ActionView
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
indent = end_on_line.to_s.size + indentation
- return unless source_code = source_code[start_on_line..end_on_line]
+ return [] unless source_code = source_code[start_on_line..end_on_line]
- formatted_code_for(source_code, start_on_line, indent, output)
+ formatted_code_for(source_code, start_on_line, indent)
end
def sub_template_of(template_path)
@@ -122,15 +122,11 @@ module ActionView
end + file_name
end
- def formatted_code_for(source_code, line_counter, indent, output)
- start_value = (output == :html) ? {} : []
- source_code.inject(start_value) do |result, line|
+ def formatted_code_for(source_code, line_counter, indent)
+ indent_template = "%#{indent}s: %s"
+ source_code.map do |line|
line_counter += 1
- if output == :html
- result.update(line_counter.to_s => "%#{indent}s %s\n" % ["", line])
- else
- result << "%#{indent}s: %s" % [line_counter, line]
- end
+ indent_template % [line_counter, line]
end
end
end
diff --git a/actionview/lib/action_view/template/handlers.rb b/actionview/lib/action_view/template/handlers.rb
index 6450513003..c7ef456125 100644
--- a/actionview/lib/action_view/template/handlers.rb
+++ b/actionview/lib/action_view/template/handlers.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "active_support/deprecation"
-
module ActionView #:nodoc:
# = Action View Template Handlers
class Template #:nodoc:
diff --git a/actionview/lib/action_view/template/html.rb b/actionview/lib/action_view/template/html.rb
index ecd1c31e79..563bffd333 100644
--- a/actionview/lib/action_view/template/html.rb
+++ b/actionview/lib/action_view/template/html.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true
-require "active_support/deprecation"
-
module ActionView #:nodoc:
# = Action View HTML Template
class Template #:nodoc:
diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb
index 539bedcdf0..03eac29bb4 100644
--- a/actionview/lib/action_view/testing/resolvers.rb
+++ b/actionview/lib/action_view/testing/resolvers.rb
@@ -7,10 +7,15 @@ module ActionView #:nodoc:
# file system. This is used internally by Rails' own test suite, and is
# useful for testing extensions that have no way of knowing what the file
# system will look like at runtime.
- class FixtureResolver < PathResolver
+ class FixtureResolver < OptimizedFileSystemResolver
def initialize(hash = {}, pattern = nil)
- super(pattern)
+ super("")
+ if pattern
+ ActiveSupport::Deprecation.warn "Specifying a custom path for #{self.class} is deprecated. Implement a custom Resolver subclass instead."
+ @pattern = pattern
+ end
@hash = hash
+ @path = ""
end
def data
@@ -23,25 +28,32 @@ module ActionView #:nodoc:
private
def query(path, exts, _, locals, cache:)
- query = +""
- EXTENSIONS.each do |ext, prefix|
- query << "(" << exts[ext].map { |e| e && Regexp.escape("#{prefix}#{e}") }.join("|") << "|)"
- end
- query = /^(#{Regexp.escape(path)})#{query}$/
+ regex = build_regex(path, exts)
- templates = []
- @hash.each do |_path, source|
- next unless query.match?(_path)
+ @hash.select do |_path, _|
+ ("/" + _path).match?(regex)
+ end.map do |_path, source|
handler, format, variant = extract_handler_and_format_and_variant(_path)
- templates << Template.new(source, _path, handler,
+
+ Template.new(source, _path, handler,
virtual_path: path.virtual,
format: format,
variant: variant,
locals: locals
)
+ end.sort_by do |t|
+ match = ("/" + t.identifier).match(regex)
+ EXTENSIONS.keys.reverse.map do |ext|
+ if ext == :variants && exts[ext] == :any
+ match[ext].nil? ? 0 : 1
+ elsif match[ext].nil?
+ exts[ext].length
+ else
+ found = match[ext].to_sym
+ exts[ext].index(found)
+ end
+ end
end
-
- templates.sort_by { |t| -t.identifier.match(/^#{query}$/).captures.reject(&:blank?).size }
end
end
diff --git a/actionview/lib/action_view/unbound_template.rb b/actionview/lib/action_view/unbound_template.rb
index d28bab91b6..3d4434b2e9 100644
--- a/actionview/lib/action_view/unbound_template.rb
+++ b/actionview/lib/action_view/unbound_template.rb
@@ -4,9 +4,9 @@ require "concurrent/map"
module ActionView
class UnboundTemplate
- def initialize(source, identifer, handler, options)
+ def initialize(source, identifier, handler, options)
@source = source
- @identifer = identifer
+ @identifier = identifier
@handler = handler
@options = options
@@ -22,7 +22,7 @@ module ActionView
options = @options.merge(locals: locals)
Template.new(
@source,
- @identifer,
+ @identifier,
@handler,
options
)
diff --git a/actionview/test/template/template_error_test.rb b/actionview/test/template/template_error_test.rb
index c4dc88e4aa..643c29602b 100644
--- a/actionview/test/template/template_error_test.rb
+++ b/actionview/test/template/template_error_test.rb
@@ -34,4 +34,20 @@ class TemplateErrorTest < ActiveSupport::TestCase
assert_equal "#<ActionView::Template::Error: original>", error.inspect
end
+
+ def test_annotated_source_code_returns_empty_array_if_source_cant_be_found
+ template = Class.new do
+ def identifier
+ "something"
+ end
+ end.new
+
+ error = begin
+ raise
+ rescue
+ raise ActionView::Template::Error.new(template) rescue $!
+ end
+
+ assert_equal [], error.annotated_source_code
+ end
end
diff --git a/actionview/test/template/testing/fixture_resolver_test.rb b/actionview/test/template/testing/fixture_resolver_test.rb
index 6d0317e0c9..a6066e94c6 100644
--- a/actionview/test/template/testing/fixture_resolver_test.rb
+++ b/actionview/test/template/testing/fixture_resolver_test.rb
@@ -27,4 +27,26 @@ class FixtureResolverTest < ActiveSupport::TestCase
assert_equal :html, templates.first.format
assert_equal "variant", templates.first.variant
end
+
+ def test_should_match_locales
+ resolver = ActionView::FixtureResolver.new("arbitrary/path.erb" => "this text", "arbitrary/path.fr.erb" => "ce texte")
+ en = resolver.find_all("path", "arbitrary", false, locale: [:en], formats: [:html], variants: [], handlers: [:erb])
+ fr = resolver.find_all("path", "arbitrary", false, locale: [:fr], formats: [:html], variants: [], handlers: [:erb])
+
+ assert_equal 1, en.size
+ assert_equal 2, fr.size
+
+ assert_equal "this text", en[0].source
+ assert_equal "ce texte", fr[0].source
+ assert_equal "this text", fr[1].source
+ end
+
+ def test_should_return_all_variants_for_any
+ resolver = ActionView::FixtureResolver.new("arbitrary/path.html.erb" => "this html", "arbitrary/path.html+varient.erb" => "this text")
+ templates = resolver.find_all("path", "arbitrary", false, locale: [], formats: [:html], variants: [], handlers: [:erb])
+ assert_equal 1, templates.size, "expected one template"
+ assert_equal "this html", templates.first.source
+ templates = resolver.find_all("path", "arbitrary", false, locale: [], formats: [:html], variants: :any, handlers: [:erb])
+ assert_equal 2, templates.size, "expected all templates"
+ end
end
diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb
index 632b32f09f..ba5ae837f1 100644
--- a/actionview/test/template/url_helper_test.rb
+++ b/actionview/test/template/url_helper_test.rb
@@ -657,7 +657,7 @@ class UrlHelperTest < ActiveSupport::TestCase
)
end
- def test_mail_with_options
+ def test_mail_to_with_options
assert_dom_equal(
%{<a href="mailto:me@example.com?cc=ccaddress%40example.com&amp;bcc=bccaddress%40example.com&amp;body=This%20is%20the%20body%20of%20the%20message.&amp;subject=This%20is%20an%20example%20email&amp;reply-to=foo%40bar.com">My email</a>},
mail_to("me@example.com", "My email", cc: "ccaddress@example.com", bcc: "bccaddress@example.com", subject: "This is an example email", body: "This is the body of the message.", reply_to: "foo@bar.com")
@@ -708,6 +708,132 @@ class UrlHelperTest < ActiveSupport::TestCase
assert_equal({ class: "special" }, options)
end
+ def test_sms_to
+ assert_dom_equal %{<a href="sms:15155555785;">15155555785</a>}, sms_to("15155555785")
+ assert_dom_equal %{<a href="sms:15155555785;">Jim Jones</a>}, sms_to("15155555785", "Jim Jones")
+ assert_dom_equal(
+ %{<a class="admin" href="sms:15155555785;">Jim Jones</a>},
+ sms_to("15155555785", "Jim Jones", "class" => "admin")
+ )
+ assert_equal sms_to("15155555785", "Jim Jones", "class" => "admin"),
+ sms_to("15155555785", "Jim Jones", class: "admin")
+ end
+
+ def test_sms_to_with_options
+ assert_dom_equal(
+ %{<a class="simple-class" href="sms:15155555785;?&body=Hello%20from%20Jim">Text me</a>},
+ sms_to("15155555785", "Text me", class: "simple-class", body: "Hello from Jim")
+ )
+
+ assert_dom_equal(
+ %{<a href="sms:15155555785;?&body=This%20is%20the%20body%20of%20the%20message.">Text me</a>},
+ sms_to("15155555785", "Text me", body: "This is the body of the message.")
+ )
+ end
+
+ def test_sms_to_with_img
+ assert_dom_equal %{<a href="sms:15155555785;"><img src="/feedback.png" /></a>},
+ sms_to("15155555785", raw('<img src="/feedback.png" />'))
+ end
+
+ def test_sms_to_with_html_safe_string
+ assert_dom_equal(
+ %{<a href="sms:1%2B5155555785;">1+5155555785</a>},
+ sms_to(raw("1+5155555785"))
+ )
+ end
+
+ def test_sms_to_with_nil
+ assert_dom_equal(
+ %{<a href="sms:;"></a>},
+ sms_to(nil)
+ )
+ end
+
+ def test_sms_to_returns_html_safe_string
+ assert_predicate sms_to("15155555785"), :html_safe?
+ end
+
+ def test_sms_to_with_block
+ assert_dom_equal %{<a href="sms:15155555785;"><span>Text me</span></a>},
+ sms_to("15155555785") { content_tag(:span, "Text me") }
+ end
+
+ def test_sms_to_with_block_and_options
+ assert_dom_equal %{<a class="special" href="sms:15155555785;?&body=Hello%20from%20Jim"><span>Text me</span></a>},
+ sms_to("15155555785", body: "Hello from Jim", class: "special") { content_tag(:span, "Text me") }
+ end
+
+ def test_sms_to_does_not_modify_html_options_hash
+ options = { class: "special" }
+ sms_to "15155555785", "ME!", options
+ assert_equal({ class: "special" }, options)
+ end
+
+ def test_phone_to
+ assert_dom_equal %{<a href="tel:1234567890">1234567890</a>},
+ phone_to("1234567890")
+ assert_dom_equal %{<a href="tel:1234567890">Bob</a>},
+ phone_to("1234567890", "Bob")
+ assert_dom_equal(
+ %{<a class="phoner" href="tel:1234567890">Bob</a>},
+ phone_to("1234567890", "Bob", "class" => "phoner")
+ )
+ assert_equal phone_to("1234567890", "Bob", "class" => "admin"),
+ phone_to("1234567890", "Bob", class: "admin")
+ end
+
+ def test_phone_to_with_options
+ assert_dom_equal(
+ %{<a class="example-class" href="tel:+011234567890">Phone</a>},
+ phone_to("1234567890", "Phone", class: "example-class", country_code: "01")
+ )
+
+ assert_dom_equal(
+ %{<a href="tel:+011234567890">Phone</a>},
+ phone_to("1234567890", "Phone", country_code: "01")
+ )
+ end
+
+ def test_phone_to_with_img
+ assert_dom_equal %{<a href="tel:1234567890"><img src="/feedback.png" /></a>},
+ phone_to("1234567890", raw('<img src="/feedback.png" />'))
+ end
+
+ def test_phone_to_with_html_safe_string
+ assert_dom_equal(
+ %{<a href="tel:1%2B234567890">1+234567890</a>},
+ phone_to(raw("1+234567890"))
+ )
+ end
+
+ def test_phone_to_with_nil
+ assert_dom_equal(
+ %{<a href="tel:"></a>},
+ phone_to(nil)
+ )
+ end
+
+ def test_phone_to_returns_html_safe_string
+ assert_predicate phone_to("1234567890"), :html_safe?
+ end
+
+ def test_phone_to_with_block
+ assert_dom_equal %{<a href="tel:1234567890"><span>Phone</span></a>},
+ phone_to("1234567890") { content_tag(:span, "Phone") }
+ end
+
+ def test_phone_to_with_block_and_options
+ assert_dom_equal %{<a class="special" href="tel:+011234567890"><span>Phone</span></a>},
+ phone_to("1234567890", country_code: "01", class: "special") { content_tag(:span, "Phone") }
+ end
+
+ def test_phone_to_does_not_modify_html_options_hash
+ options = { class: "special" }
+ phone_to "1234567890", "ME!", options
+ assert_equal({ class: "special" }, options)
+ end
+
def protect_against_forgery?
request_forgery
end
diff --git a/actionview/test/ujs/public/test/data-remote.js b/actionview/test/ujs/public/test/data-remote.js
index 16ea114f3b..dbbb383995 100644
--- a/actionview/test/ujs/public/test/data-remote.js
+++ b/actionview/test/ujs/public/test/data-remote.js
@@ -490,4 +490,22 @@ asyncTest('changing a select option without "data-url" attribute still fires aja
setTimeout(function() { start() }, 20)
})
+asyncTest('inputs inside disabled fieldset are not submited on remote forms', 3, function() {
+ $('form')
+ .append('<fieldset>\
+ <input name="description" value="A wise man" />\
+ </fieldset>')
+ .append('<fieldset disabled="disabled">\
+ <input name="age" />\
+ </fieldset>')
+ .bindNative('ajax:success', function(e, data, status, xhr) {
+ equal(data.params.user_name, 'john')
+ equal(data.params.description, 'A wise man')
+ equal(data.params.age, undefined)
+
+ start()
+ })
+ .triggerNative('submit')
+})
+
})()