active_utils 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +14 -0
- data/Rakefile +13 -0
- data/active_utils.gemspec +26 -0
- data/lib/active_utils/common/connection.rb +158 -0
- data/lib/active_utils/common/country.rb +328 -0
- data/lib/active_utils/common/error.rb +26 -0
- data/lib/active_utils/common/post_data.rb +24 -0
- data/lib/active_utils/common/posts_data.rb +63 -0
- data/lib/active_utils/common/requires_parameters.rb +16 -0
- data/lib/active_utils/common/utils.rb +22 -0
- data/lib/active_utils/common/validateable.rb +81 -0
- data/lib/active_utils/version.rb +3 -0
- data/lib/active_utils.rb +19 -0
- data/test/test_helper.rb +12 -0
- data/test/unit/connection_test.rb +131 -0
- data/test/unit/country_code_test.rb +31 -0
- data/test/unit/country_test.rb +68 -0
- data/test/unit/post_data_test.rb +50 -0
- data/test/unit/utils_test.rb +7 -0
- data/test/unit/validateable_test.rb +59 -0
- metadata +153 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module PostsData #:nodoc:
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.superclass_delegating_accessor :ssl_strict
|
6
|
+
base.ssl_strict = true
|
7
|
+
|
8
|
+
base.class_attribute :retry_safe
|
9
|
+
base.retry_safe = false
|
10
|
+
|
11
|
+
base.superclass_delegating_accessor :open_timeout
|
12
|
+
base.open_timeout = 60
|
13
|
+
|
14
|
+
base.superclass_delegating_accessor :read_timeout
|
15
|
+
base.read_timeout = 60
|
16
|
+
|
17
|
+
base.superclass_delegating_accessor :logger
|
18
|
+
base.superclass_delegating_accessor :wiredump_device
|
19
|
+
end
|
20
|
+
|
21
|
+
def ssl_get(endpoint, headers={})
|
22
|
+
ssl_request(:get, endpoint, nil, headers)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ssl_post(endpoint, data, headers = {})
|
26
|
+
ssl_request(:post, endpoint, data, headers)
|
27
|
+
end
|
28
|
+
|
29
|
+
def ssl_request(method, endpoint, data, headers)
|
30
|
+
handle_response(raw_ssl_request(method, endpoint, data, headers))
|
31
|
+
end
|
32
|
+
|
33
|
+
def raw_ssl_request(method, endpoint, data, headers = {})
|
34
|
+
connection = Connection.new(endpoint)
|
35
|
+
connection.open_timeout = open_timeout
|
36
|
+
connection.read_timeout = read_timeout
|
37
|
+
connection.retry_safe = retry_safe
|
38
|
+
connection.verify_peer = ssl_strict
|
39
|
+
connection.logger = logger
|
40
|
+
connection.tag = self.class.name
|
41
|
+
connection.wiredump_device = wiredump_device
|
42
|
+
|
43
|
+
connection.pem = @options[:pem] if @options
|
44
|
+
connection.pem_password = @options[:pem_password] if @options
|
45
|
+
|
46
|
+
connection.ignore_http_status = @options[:ignore_http_status] if @options
|
47
|
+
|
48
|
+
connection.request(method, data, headers)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def handle_response(response)
|
54
|
+
case response.code.to_i
|
55
|
+
when 200...300
|
56
|
+
response.body
|
57
|
+
else
|
58
|
+
raise ResponseError.new(response)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module RequiresParameters #:nodoc:
|
3
|
+
def requires!(hash, *params)
|
4
|
+
params.each do |param|
|
5
|
+
if param.is_a?(Array)
|
6
|
+
raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first)
|
7
|
+
|
8
|
+
valid_options = param[1..-1]
|
9
|
+
raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(:words_connector => 'or')}") unless valid_options.include?(hash[param.first])
|
10
|
+
else
|
11
|
+
raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Utils #:nodoc:
|
5
|
+
def generate_unique_id
|
6
|
+
md5 = Digest::MD5.new
|
7
|
+
now = Time.now
|
8
|
+
md5 << now.to_s
|
9
|
+
md5 << String(now.usec)
|
10
|
+
md5 << String(rand(0))
|
11
|
+
md5 << String($$)
|
12
|
+
md5 << self.class.name
|
13
|
+
md5.hexdigest
|
14
|
+
end
|
15
|
+
|
16
|
+
module_function :generate_unique_id
|
17
|
+
|
18
|
+
def deprecated(message)
|
19
|
+
warn(Kernel.caller[1] + message)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Validateable #:nodoc:
|
3
|
+
def valid?
|
4
|
+
errors.clear
|
5
|
+
|
6
|
+
before_validate if respond_to?(:before_validate, true)
|
7
|
+
validate if respond_to?(:validate, true)
|
8
|
+
|
9
|
+
errors.empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(attributes = {})
|
13
|
+
self.attributes = attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
def errors
|
17
|
+
@errors ||= Errors.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def attributes=(attributes)
|
23
|
+
unless attributes.nil?
|
24
|
+
for key, value in attributes
|
25
|
+
send("#{key}=", value )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# This hash keeps the errors of the object
|
31
|
+
class Errors < HashWithIndifferentAccess
|
32
|
+
|
33
|
+
def initialize(base)
|
34
|
+
super() { |h, k| h[k] = [] ; h[k] }
|
35
|
+
@base = base
|
36
|
+
end
|
37
|
+
|
38
|
+
def count
|
39
|
+
size
|
40
|
+
end
|
41
|
+
|
42
|
+
def empty?
|
43
|
+
all? { |k, v| v && v.empty? }
|
44
|
+
end
|
45
|
+
|
46
|
+
# returns a specific fields error message.
|
47
|
+
# if more than one error is available we will only return the first. If no error is available
|
48
|
+
# we return an empty string
|
49
|
+
def on(field)
|
50
|
+
self[field].to_a.first
|
51
|
+
end
|
52
|
+
|
53
|
+
def add(field, error)
|
54
|
+
self[field] << error
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_to_base(error)
|
58
|
+
add(:base, error)
|
59
|
+
end
|
60
|
+
|
61
|
+
def each_full
|
62
|
+
full_messages.each { |msg| yield msg }
|
63
|
+
end
|
64
|
+
|
65
|
+
def full_messages
|
66
|
+
result = []
|
67
|
+
|
68
|
+
self.each do |key, messages|
|
69
|
+
next if messages.blank?
|
70
|
+
if key == 'base'
|
71
|
+
result << "#{messages.first}"
|
72
|
+
else
|
73
|
+
result << "#{key.to_s.humanize} #{messages.first}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
result
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/active_utils.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
2
|
+
require 'active_support/core_ext/hash/conversions'
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
4
|
+
|
5
|
+
module ActiveMerchant
|
6
|
+
autoload :Connection, 'active_utils/common/connection'
|
7
|
+
autoload :Country, 'active_utils/common/country'
|
8
|
+
autoload :CountryCode, 'active_utils/common/country'
|
9
|
+
autoload :ActiveMerchantError, 'active_utils/common/error'
|
10
|
+
autoload :ConnectionError, 'active_utils/common/error'
|
11
|
+
autoload :RetriableConnectionError, 'active_utils/common/error'
|
12
|
+
autoload :ResponseError, 'active_utils/common/error'
|
13
|
+
autoload :ClientCertificateError, 'active_utils/common/error'
|
14
|
+
autoload :PostData, 'active_utils/common/post_data'
|
15
|
+
autoload :PostsData, 'active_utils/common/posts_data'
|
16
|
+
autoload :RequiresParameters, 'active_utils/common/requires_parameters'
|
17
|
+
autoload :Utils, 'active_utils/common/utils'
|
18
|
+
autoload :Validateable, 'active_utils/common/validateable'
|
19
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ConnectionTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@ok = stub(:code => 200, :message => 'OK', :body => 'success')
|
7
|
+
|
8
|
+
@endpoint = 'https://example.com/tx.php'
|
9
|
+
@connection = ActiveMerchant::Connection.new(@endpoint)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_connection_endpoint_parses_string_to_uri
|
13
|
+
assert_equal URI.parse(@endpoint), @connection.endpoint
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_connection_endpoint_accepts_uri
|
17
|
+
endpoint = URI.parse(@endpoint)
|
18
|
+
connection = ActiveMerchant::Connection.new(endpoint)
|
19
|
+
assert_equal endpoint, connection.endpoint
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_connection_endpoint_raises_uri_error
|
23
|
+
assert_raises URI::InvalidURIError do
|
24
|
+
ActiveMerchant::Connection.new("not a URI")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_successful_get_request
|
29
|
+
Net::HTTP.any_instance.expects(:get).with('/tx.php', {}).returns(@ok)
|
30
|
+
response = @connection.request(:get, nil, {})
|
31
|
+
assert_equal 'success', response.body
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_successful_post_request
|
35
|
+
Net::HTTP.any_instance.expects(:post).with('/tx.php', 'data', ActiveMerchant::Connection::RUBY_184_POST_HEADERS).returns(@ok)
|
36
|
+
response = @connection.request(:post, 'data', {})
|
37
|
+
assert_equal 'success', response.body
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_get_raises_argument_error_if_passed_data
|
41
|
+
assert_raise(ArgumentError) do
|
42
|
+
@connection.request(:get, 'data', {})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_request_raises_when_request_method_not_supported
|
47
|
+
assert_raise(ArgumentError) do
|
48
|
+
@connection.request(:delete, nil, {})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
def test_default_read_timeout
|
55
|
+
assert_equal ActiveMerchant::Connection::READ_TIMEOUT, @connection.read_timeout
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_override_read_timeout
|
59
|
+
@connection.read_timeout = 20
|
60
|
+
assert_equal 20, @connection.read_timeout
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_default_open_timeout
|
64
|
+
@connection.open_timeout = 20
|
65
|
+
assert_equal 20, @connection.open_timeout
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_default_verify_peer
|
69
|
+
assert_equal ActiveMerchant::Connection::VERIFY_PEER, @connection.verify_peer
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_override_verify_peer
|
73
|
+
@connection.verify_peer = false
|
74
|
+
assert_equal false, @connection.verify_peer
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_unrecoverable_exception
|
78
|
+
Net::HTTP.any_instance.expects(:post).raises(EOFError)
|
79
|
+
|
80
|
+
assert_raises(ActiveMerchant::ConnectionError) do
|
81
|
+
@connection.request(:post, '')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_failure_then_success_with_recoverable_exception
|
86
|
+
Net::HTTP.any_instance.expects(:post).times(2).raises(Errno::ECONNREFUSED).then.returns(@ok)
|
87
|
+
|
88
|
+
assert_nothing_raised do
|
89
|
+
@connection.request(:post, '')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_failure_limit_reached
|
94
|
+
Net::HTTP.any_instance.expects(:post).times(ActiveMerchant::Connection::MAX_RETRIES).raises(Errno::ECONNREFUSED)
|
95
|
+
|
96
|
+
assert_raises(ActiveMerchant::ConnectionError) do
|
97
|
+
@connection.request(:post, '')
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_failure_then_success_with_retry_safe_enabled
|
102
|
+
Net::HTTP.any_instance.expects(:post).times(2).raises(EOFError).then.returns(@ok)
|
103
|
+
|
104
|
+
@connection.retry_safe = true
|
105
|
+
|
106
|
+
assert_nothing_raised do
|
107
|
+
@connection.request(:post, '')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_mixture_of_failures_with_retry_safe_enabled
|
112
|
+
Net::HTTP.any_instance.expects(:post).times(3).raises(Errno::ECONNRESET).
|
113
|
+
raises(Errno::ECONNREFUSED).
|
114
|
+
raises(EOFError)
|
115
|
+
|
116
|
+
@connection.retry_safe = true
|
117
|
+
|
118
|
+
assert_raises(ActiveMerchant::ConnectionError) do
|
119
|
+
@connection.request(:post, '')
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_failure_with_ssl_certificate
|
124
|
+
Net::HTTP.any_instance.expects(:post).raises(OpenSSL::X509::CertificateError)
|
125
|
+
|
126
|
+
assert_raises(ActiveMerchant::ClientCertificateError) do
|
127
|
+
@connection.request(:post, '')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CountryCodeTest < Test::Unit::TestCase
|
4
|
+
def test_alpha2_country_code
|
5
|
+
code = CountryCode.new('CA')
|
6
|
+
assert_equal 'CA', code.value
|
7
|
+
assert_equal 'CA', code.to_s
|
8
|
+
assert_equal :alpha2, code.format
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_lower_alpha2_country_code
|
12
|
+
code = CountryCode.new('ca')
|
13
|
+
assert_equal 'CA', code.value
|
14
|
+
assert_equal 'CA', code.to_s
|
15
|
+
assert_equal :alpha2, code.format
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_alpha2_country_code
|
19
|
+
code = CountryCode.new('CAN')
|
20
|
+
assert_equal :alpha3, code.format
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_numeric_code
|
24
|
+
code = CountryCode.new('004')
|
25
|
+
assert_equal :numeric, code.format
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_invalid_code_format
|
29
|
+
assert_raise(CountryCodeFormatError){ CountryCode.new('Canada') }
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CountryTest < Test::Unit::TestCase
|
4
|
+
def test_country_from_hash
|
5
|
+
country = Country.new(:name => 'Canada', :alpha2 => 'CA', :alpha3 => 'CAN', :numeric => '124')
|
6
|
+
assert_equal 'CA', country.code(:alpha2).value
|
7
|
+
assert_equal 'CAN', country.code(:alpha3).value
|
8
|
+
assert_equal '124', country.code(:numeric).value
|
9
|
+
assert_equal 'Canada', country.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_country_for_alpha2_code
|
13
|
+
country = Country.find('CA')
|
14
|
+
assert_equal 'CA', country.code(:alpha2).value
|
15
|
+
assert_equal 'CAN', country.code(:alpha3).value
|
16
|
+
assert_equal '124', country.code(:numeric).value
|
17
|
+
assert_equal 'Canada', country.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_country_for_alpha3_code
|
21
|
+
country = Country.find('CAN')
|
22
|
+
assert_equal 'Canada', country.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_country_for_numeric_code
|
26
|
+
country = Country.find('124')
|
27
|
+
assert_equal 'Canada', country.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_find_country_by_name
|
31
|
+
country = Country.find('Canada')
|
32
|
+
assert_equal 'Canada', country.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_find_unknown_country_name
|
36
|
+
assert_raise(InvalidCountryCodeError) do
|
37
|
+
Country.find('Asskickistan')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_find_australia
|
42
|
+
country = Country.find('AU')
|
43
|
+
assert_equal 'AU', country.code(:alpha2).value
|
44
|
+
|
45
|
+
country = Country.find('Australia')
|
46
|
+
assert_equal 'AU', country.code(:alpha2).value
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_find_united_kingdom
|
50
|
+
country = Country.find('GB')
|
51
|
+
assert_equal 'GB', country.code(:alpha2).value
|
52
|
+
|
53
|
+
country = Country.find('United Kingdom')
|
54
|
+
assert_equal 'GB', country.code(:alpha2).value
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_raise_on_nil_name
|
58
|
+
assert_raise(InvalidCountryCodeError) do
|
59
|
+
Country.find(nil)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_country_names_are_alphabetized
|
64
|
+
country_names = Country::COUNTRIES.map { | each | each[:name] }
|
65
|
+
assert_equal(country_names.sort, country_names)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MyPost < ActiveMerchant::PostData
|
4
|
+
self.required_fields = [ :ccnumber, :ccexp, :firstname, :lastname, :username, :password, :order_id, :key, :time ]
|
5
|
+
end
|
6
|
+
|
7
|
+
class PostDataTest < Test::Unit::TestCase
|
8
|
+
def teardown
|
9
|
+
ActiveMerchant::PostData.required_fields = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_element_assignment
|
13
|
+
name = 'Cody Fauser'
|
14
|
+
post = ActiveMerchant::PostData.new
|
15
|
+
|
16
|
+
post[:name] = name
|
17
|
+
assert_equal name, post[:name]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_ignore_blank_fields
|
21
|
+
post = ActiveMerchant::PostData.new
|
22
|
+
assert_equal 0, post.keys.size
|
23
|
+
|
24
|
+
post[:name] = ''
|
25
|
+
assert_equal 0, post.keys.size
|
26
|
+
|
27
|
+
post[:name] = nil
|
28
|
+
assert_equal 0, post.keys.size
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_dont_ignore_required_blank_fields
|
32
|
+
ActiveMerchant::PostData.required_fields = [ :name ]
|
33
|
+
post = ActiveMerchant::PostData.new
|
34
|
+
|
35
|
+
assert_equal 0, post.keys.size
|
36
|
+
|
37
|
+
post[:name] = ''
|
38
|
+
assert_equal 1, post.keys.size
|
39
|
+
assert_equal '', post[:name]
|
40
|
+
|
41
|
+
post[:name] = nil
|
42
|
+
assert_equal 1, post.keys.size
|
43
|
+
assert_nil post[:name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_subclass
|
47
|
+
post = MyPost.new
|
48
|
+
assert_equal [ :ccnumber, :ccexp, :firstname, :lastname, :username, :password, :order_id, :key, :time ], post.required_fields
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class Dood
|
4
|
+
include ActiveMerchant::Validateable
|
5
|
+
|
6
|
+
attr_accessor :name, :email, :country
|
7
|
+
|
8
|
+
def validate
|
9
|
+
errors.add "name", "cannot be empty" if name.blank?
|
10
|
+
errors.add "email", "cannot be empty" if email.blank?
|
11
|
+
errors.add_to_base "The country cannot be blank" if country.blank?
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class ValidateableTest < Test::Unit::TestCase
|
17
|
+
|
18
|
+
def setup
|
19
|
+
@dood = Dood.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_validation
|
23
|
+
assert ! @dood.valid?
|
24
|
+
assert ! @dood.errors.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_assigns
|
28
|
+
@dood = Dood.new(:name => "tobi", :email => "tobi@neech.de", :country => 'DE')
|
29
|
+
|
30
|
+
assert_equal "tobi", @dood.name
|
31
|
+
assert_equal "tobi@neech.de", @dood.email
|
32
|
+
assert @dood.valid?
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_multiple_calls
|
36
|
+
@dood.name = "tobi"
|
37
|
+
assert !@dood.valid?
|
38
|
+
|
39
|
+
@dood.email = "tobi@neech.de"
|
40
|
+
assert !@dood.valid?
|
41
|
+
|
42
|
+
@dood.country = 'DE'
|
43
|
+
assert @dood.valid?
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_messages
|
47
|
+
@dood.valid?
|
48
|
+
assert_equal "cannot be empty", @dood.errors.on('name')
|
49
|
+
assert_equal "cannot be empty", @dood.errors.on('email')
|
50
|
+
assert_equal nil, @dood.errors.on('doesnt_exist')
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_full_messages
|
55
|
+
@dood.valid?
|
56
|
+
assert_equal ["Email cannot be empty", "Name cannot be empty", "The country cannot be blank"], @dood.errors.full_messages.sort
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|