Merge remote-tracking branch 'upstream/pull/2044'
This commit is contained in:
commit
a39c645602
26 changed files with 187 additions and 35 deletions
|
@ -28,7 +28,7 @@ class ChangesetComment < ActiveRecord::Base
|
|||
validates :changeset, :presence => true, :associated => true
|
||||
validates :author, :presence => true, :associated => true
|
||||
validates :visible, :inclusion => [true, false]
|
||||
validates :body, :format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/
|
||||
validates :body, :characters => true
|
||||
|
||||
# Return the comment text
|
||||
def body
|
||||
|
|
|
@ -21,6 +21,6 @@ class ChangesetTag < ActiveRecord::Base
|
|||
belongs_to :changeset
|
||||
|
||||
validates :changeset, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => :changeset_id }
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ class DiaryComment < ActiveRecord::Base
|
|||
|
||||
scope :visible, -> { where(:visible => true) }
|
||||
|
||||
validates :body, :presence => true
|
||||
validates :body, :presence => true, :characters => true
|
||||
validates :diary_entry, :user, :associated => true
|
||||
|
||||
after_save :spam_check
|
||||
|
|
|
@ -37,8 +37,8 @@ class DiaryEntry < ActiveRecord::Base
|
|||
|
||||
scope :visible, -> { where(:visible => true) }
|
||||
|
||||
validates :title, :body, :presence => true
|
||||
validates :title, :length => 1..255
|
||||
validates :title, :presence => true, :length => 1..255, :characters => true
|
||||
validates :body, :presence => true, :characters => true
|
||||
validates :latitude, :allow_nil => true,
|
||||
:numericality => { :greater_than_or_equal_to => -90,
|
||||
:less_than_or_equal_to => 90 }
|
||||
|
|
|
@ -24,7 +24,7 @@ class IssueComment < ActiveRecord::Base
|
|||
belongs_to :issue
|
||||
belongs_to :user
|
||||
|
||||
validates :body, :presence => true
|
||||
validates :body, :presence => true, :characters => true
|
||||
validates :user, :presence => true
|
||||
validates :issue, :presence => true
|
||||
end
|
||||
|
|
|
@ -32,6 +32,7 @@ class Message < ActiveRecord::Base
|
|||
|
||||
validates :title, :presence => true, :utf8 => true, :length => 1..255
|
||||
validates :body, :sent_on, :sender, :recipient, :presence => true
|
||||
validates :title, :body, :characters => true
|
||||
|
||||
def self.from_mail(mail, from, to)
|
||||
if mail.multipart?
|
||||
|
|
|
@ -18,6 +18,6 @@ class NodeTag < ActiveRecord::Base
|
|||
belongs_to :node
|
||||
|
||||
validates :node, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => :node_id }
|
||||
end
|
||||
|
|
|
@ -33,8 +33,7 @@ class NoteComment < ActiveRecord::Base
|
|||
validates :visible, :inclusion => [true, false]
|
||||
validates :author, :associated => true
|
||||
validates :event, :inclusion => %w[opened closed reopened commented hidden]
|
||||
validates :body, :length => { :maximum => 2000 },
|
||||
:format => /\A[^\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff]*\z/
|
||||
validates :body, :length => { :maximum => 2000 }, :characters => true
|
||||
|
||||
# Return the comment text
|
||||
def body
|
||||
|
|
|
@ -19,6 +19,6 @@ class OldNodeTag < ActiveRecord::Base
|
|||
belongs_to :old_node, :foreign_key => [:node_id, :version]
|
||||
|
||||
validates :old_node, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => [:node_id, :version] }
|
||||
end
|
||||
|
|
|
@ -19,6 +19,6 @@ class OldRelationTag < ActiveRecord::Base
|
|||
belongs_to :old_relation, :foreign_key => [:relation_id, :version]
|
||||
|
||||
validates :old_relation, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => [:relation_id, :version] }
|
||||
end
|
||||
|
|
|
@ -19,6 +19,6 @@ class OldWayTag < ActiveRecord::Base
|
|||
belongs_to :old_way, :foreign_key => [:way_id, :version]
|
||||
|
||||
validates :old_way, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => [:way_id, :version] }
|
||||
end
|
||||
|
|
|
@ -31,7 +31,8 @@ class Redaction < ActiveRecord::Base
|
|||
has_many :old_ways
|
||||
has_many :old_relations
|
||||
|
||||
validates :description, :presence => true
|
||||
validates :title, :presence => true, :characters => true
|
||||
validates :description, :presence => true, :characters => true
|
||||
validates :description_format, :inclusion => { :in => %w[text html markdown] }
|
||||
|
||||
# this method overrides the AR default to provide the rich
|
||||
|
|
|
@ -18,6 +18,6 @@ class RelationTag < ActiveRecord::Base
|
|||
belongs_to :relation
|
||||
|
||||
validates :relation, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => :relation_id }
|
||||
end
|
||||
|
|
|
@ -27,7 +27,7 @@ class Report < ActiveRecord::Base
|
|||
|
||||
validates :issue, :presence => true
|
||||
validates :user, :presence => true
|
||||
validates :details, :presence => true
|
||||
validates :details, :presence => true, :characters => true
|
||||
validates :category, :presence => true
|
||||
|
||||
def self.categories_for(reportable)
|
||||
|
|
|
@ -38,8 +38,8 @@ class Trace < ActiveRecord::Base
|
|||
scope :tagged, ->(t) { joins(:tags).where(:gpx_file_tags => { :tag => t }) }
|
||||
|
||||
validates :user, :presence => true, :associated => true
|
||||
validates :name, :presence => true, :length => 1..255
|
||||
validates :description, :presence => { :on => :create }, :length => 1..255
|
||||
validates :name, :presence => true, :length => 1..255, :characters => true
|
||||
validates :description, :presence => { :on => :create }, :length => 1..255, :characters => true
|
||||
validates :timestamp, :presence => true
|
||||
validates :visibility, :inclusion => %w[private public trackable identifiable]
|
||||
|
||||
|
|
|
@ -22,5 +22,5 @@ class Tracetag < ActiveRecord::Base
|
|||
belongs_to :trace, :foreign_key => "gpx_id"
|
||||
|
||||
validates :trace, :associated => true
|
||||
validates :tag, :length => 1..255, :format => %r{\A[^/;.,?]*\z}
|
||||
validates :tag, :length => 1..255, :characters => { :url_safe => true }
|
||||
end
|
||||
|
|
|
@ -88,17 +88,14 @@ class User < ActiveRecord::Base
|
|||
:default_url => "/assets/:class/:attachment/:style.png",
|
||||
:styles => { :large => "100x100>", :small => "50x50>" }
|
||||
|
||||
validates :display_name, :presence => true, :allow_nil => true, :length => 3..255,
|
||||
validates :display_name, :presence => true, :length => 3..255,
|
||||
:exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended]
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
:uniqueness => { :case_sensitive => false }
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
:format => { :with => %r{\A[^\x00-\x1f\x7f\ufffe\uffff/;.,?%#]*\z} }
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
:format => { :with => /\A\S/, :message => "has leading whitespace" }
|
||||
validates :display_name, :if => proc { |u| u.display_name_changed? },
|
||||
:format => { :with => /\S\z/, :message => "has trailing whitespace" }
|
||||
validates :email, :presence => true, :confirmation => true
|
||||
:characters => { :url_safe => true },
|
||||
:whitespace => { :leading => false, :trailing => false }
|
||||
validates :email, :presence => true, :confirmation => true, :characters => true
|
||||
validates :email, :if => proc { |u| u.email_changed? },
|
||||
:uniqueness => { :case_sensitive => false }
|
||||
validates :pass_crypt, :confirmation => true, :length => 8..255
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
class UserBlock < ActiveRecord::Base
|
||||
validate :moderator_permissions
|
||||
validates :reason, :characters => true
|
||||
|
||||
belongs_to :user, :class_name => "User", :foreign_key => :user_id
|
||||
belongs_to :creator, :class_name => "User", :foreign_key => :creator_id
|
||||
|
|
|
@ -17,7 +17,7 @@ class UserPreference < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
|
||||
validates :user, :presence => true, :associated => true
|
||||
validates :k, :v, :length => 1..255
|
||||
validates :k, :v, :length => 1..255, :characters => true
|
||||
|
||||
# Turn this Node in to an XML Node without the <osm> wrapper.
|
||||
def to_xml_node
|
||||
|
|
|
@ -18,6 +18,6 @@ class WayTag < ActiveRecord::Base
|
|||
belongs_to :way
|
||||
|
||||
validates :way, :presence => true, :associated => true
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }
|
||||
validates :k, :v, :allow_blank => true, :length => { :maximum => 255 }, :characters => true
|
||||
validates :k, :uniqueness => { :scope => :way_id }
|
||||
end
|
||||
|
|
12
app/validators/characters_validator.rb
Normal file
12
app/validators/characters_validator.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
class CharactersValidator < ActiveModel::EachValidator
|
||||
INVALID_CHARS = "\x00-\x08\x0b-\x0c\x0e-\x1f\x7f\ufffe\uffff".freeze
|
||||
INVALID_URL_CHARS = "/;.,?%#".freeze
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
record.errors[attribute] << (options[:message] || I18n.t("validations.invalid_characters")) if value =~ /[#{INVALID_CHARS}]/
|
||||
|
||||
if options[:url_safe]
|
||||
record.errors[attribute] << (options[:message] || I18n.t("validations.url_characters", :characters => INVALID_URL_CHARS)) if value =~ /[#{INVALID_URL_CHARS}]/
|
||||
end
|
||||
end
|
||||
end
|
11
app/validators/whitespace_validator.rb
Normal file
11
app/validators/whitespace_validator.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
class WhitespaceValidator < ActiveModel::EachValidator
|
||||
def validate_each(record, attribute, value)
|
||||
unless options.fetch(:leading, true)
|
||||
record.errors[attribute] << (options[:message] || I18n.t("validations.leading_whitespace")) if value =~ /\A\s/
|
||||
end
|
||||
|
||||
unless options.fetch(:trailing, true)
|
||||
record.errors[attribute] << (options[:message] || I18n.t("validations.trailing_whitespace")) if value =~ /\s\z/
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2562,3 +2562,8 @@ en:
|
|||
not_empty: "Redaction is not empty. Please un-redact all versions belonging to this redaction before destroying it."
|
||||
flash: "Redaction destroyed."
|
||||
error: "There was an error destroying this redaction."
|
||||
validations:
|
||||
leading_whitespace: "has leading whitespace"
|
||||
trailing_whitespace: "has trailing whitespace"
|
||||
invalid_characters: "contains invalid characters"
|
||||
url_characters: "contains special URL characters (%{characters})"
|
||||
|
|
|
@ -65,16 +65,13 @@ class UserTest < ActiveSupport::TestCase
|
|||
def test_display_name_length
|
||||
user = build(:user)
|
||||
user.display_name = "123"
|
||||
assert user.valid?, " should allow nil display name"
|
||||
assert user.valid?, "should allow 3 char name name"
|
||||
user.display_name = "12"
|
||||
assert_not user.valid?, "should not allow 2 char name"
|
||||
user.display_name = ""
|
||||
assert_not user.valid?
|
||||
assert_not user.valid?, "should not allow blank/0 char name"
|
||||
user.display_name = nil
|
||||
# Don't understand why it isn't allowing a nil value,
|
||||
# when the validates statements specifically allow it
|
||||
# It appears the database does not allow null values
|
||||
assert_not user.valid?
|
||||
assert_not user.valid?, "should not allow nil value"
|
||||
end
|
||||
|
||||
def test_display_name_valid
|
||||
|
@ -82,14 +79,15 @@ class UserTest < ActiveSupport::TestCase
|
|||
# expact are allowed
|
||||
# However, would they affect the xml planet dumps?
|
||||
ok = ["Name", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
|
||||
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲"]
|
||||
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲", "space space"]
|
||||
# These need to be 3 chars in length, otherwise the length test above
|
||||
# should be used.
|
||||
bad = ["<hr/>", "test@example.com", "s/f", "aa/", "aa;", "aa.",
|
||||
"aa,", "aa?", "/;.,?", "も対応します/", "#ping",
|
||||
"foo\x1fbar", "foo\x7fbar", "foo\ufffebar", "foo\uffffbar",
|
||||
"new", "terms", "save", "confirm", "confirm-email",
|
||||
"go_public", "reset-password", "forgot-password", "suspended"]
|
||||
"go_public", "reset-password", "forgot-password", "suspended",
|
||||
"trailing whitespace ", " leading whitespace"]
|
||||
ok.each do |display_name|
|
||||
user = build(:user)
|
||||
user.display_name = display_name
|
||||
|
|
66
test/validators/characters_validator_test.rb
Normal file
66
test/validators/characters_validator_test.rb
Normal file
|
@ -0,0 +1,66 @@
|
|||
require "test_helper"
|
||||
|
||||
class InvalidCharsValidatable
|
||||
include ActiveModel::Validations
|
||||
validates :chars, :characters => true
|
||||
attr_accessor :chars
|
||||
end
|
||||
|
||||
class InvalidUrlCharsValidatable
|
||||
include ActiveModel::Validations
|
||||
validates :chars, :characters => { :url_safe => true }
|
||||
attr_accessor :chars
|
||||
end
|
||||
|
||||
class CharactersValidatorTest < ActiveSupport::TestCase
|
||||
include Rails::Dom::Testing::Assertions::SelectorAssertions
|
||||
|
||||
def test_with_valid_chars
|
||||
c = InvalidCharsValidatable.new
|
||||
|
||||
valid = ["Name.", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
|
||||
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲", "/;.,?%#"]
|
||||
|
||||
valid.each do |v|
|
||||
c.chars = v
|
||||
assert c.valid?, "'#{v}' should be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_with_invalid_chars
|
||||
c = InvalidCharsValidatable.new
|
||||
|
||||
invalid = ["\x7f<hr/>", "test@example.com\x0e-", "s/\x1ff", "aa/\ufffe",
|
||||
"aa\x0b-,", "aa?\x08", "/;\uffff.,?", "\x00-も対応します/", "\x0c#ping",
|
||||
"foo\x1fbar", "foo\x7fbar", "foo\ufffebar", "foo\uffffbar"]
|
||||
|
||||
invalid.each do |v|
|
||||
c.chars = v
|
||||
assert_not c.valid?, "'#{v}' should not be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_with_valid_url_chars
|
||||
c = InvalidUrlCharsValidatable.new
|
||||
|
||||
valid = ["Name", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
|
||||
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲"]
|
||||
|
||||
valid.each do |v|
|
||||
c.chars = v
|
||||
assert c.valid?, "'#{v}' should be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_with_invalid_url_chars
|
||||
c = InvalidUrlCharsValidatable.new
|
||||
|
||||
invalid = ["Name.", "you;me", "he\"#", "<hr/>", "50%", "good?",
|
||||
"vergrößern,deutsche", "ルシステムに;.も対応します", "輕觸搖/晃的遊戲", "/;.,?%#"]
|
||||
|
||||
invalid.each do |v|
|
||||
c.chars = v
|
||||
assert_not c.valid?, "'#{v}' should not be valid"
|
||||
end
|
||||
end
|
||||
end
|
61
test/validators/whitespace_validator_test.rb
Normal file
61
test/validators/whitespace_validator_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require "test_helper"
|
||||
|
||||
class LeadingWhitespaceValidatable
|
||||
include ActiveModel::Validations
|
||||
validates :string, :whitespace => { :leading => false }
|
||||
attr_accessor :string
|
||||
end
|
||||
|
||||
class TrailingWhitespaceValidatable
|
||||
include ActiveModel::Validations
|
||||
validates :string, :whitespace => { :trailing => false }
|
||||
attr_accessor :string
|
||||
end
|
||||
|
||||
class WhitespaceValidatorTest < ActiveSupport::TestCase
|
||||
include Rails::Dom::Testing::Assertions::SelectorAssertions
|
||||
|
||||
def test_with_leading_whitespace
|
||||
validator = LeadingWhitespaceValidatable.new
|
||||
|
||||
strings = [" ", " test", " ", "\ttest"]
|
||||
|
||||
strings.each do |v|
|
||||
validator.string = v
|
||||
assert_not validator.valid?, "'#{v}' should not be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_without_leading_whitespace
|
||||
validator = LeadingWhitespaceValidatable.new
|
||||
|
||||
strings = ["test", "test ", "t est", "test\t", ".test", "_test"]
|
||||
|
||||
strings.each do |v|
|
||||
validator.string = v
|
||||
assert validator.valid?, "'#{v}' should be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_with_trailing_whitespace
|
||||
validator = TrailingWhitespaceValidatable.new
|
||||
|
||||
strings = [" ", "test ", " ", "test\t", "_test_ "]
|
||||
|
||||
strings.each do |v|
|
||||
validator.string = v
|
||||
assert_not validator.valid?, "'#{v}' should not be valid"
|
||||
end
|
||||
end
|
||||
|
||||
def test_without_trailing_whitespace
|
||||
validator = TrailingWhitespaceValidatable.new
|
||||
|
||||
strings = ["test", " test", "tes t", "\ttest", "test.", "test_"]
|
||||
|
||||
strings.each do |v|
|
||||
validator.string = v
|
||||
assert validator.valid?, "'#{v}' should be valid"
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue