validate_credit_card_fields 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +1 -0
- data/lib/validate_credit_card_fields.rb +158 -0
- data/lib/validate_credit_card_fields/version.rb +3 -0
- data/spec/dummy/user.rb +20 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/validate_credit_card_fields_spec.rb +301 -0
- data/validate_credit_card_fields.gemspec +27 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 08479b11ce7e965583a9682f6cc262917980bf05
|
4
|
+
data.tar.gz: 081101d249d8ae2061d5202652772e8bad8a98f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3644cc31ca0295440b0b355b556e04143d3ac1ebf7eac012df8a7d9fa478731a8d9b10857d233c19ac24f8d2e97fb97ccbd46b69d60e67cb8baf1ec0689ee7ac
|
7
|
+
data.tar.gz: 7190a8b5502317e99b2d42eeee7f4ddaf080c0714ba76dbc45939a70b2050c0602f045181e3d8120aa7e804435bb786b3ef8b54a3d62505d1f4d23c7e178605d
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 TODO: Write your name
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# validate_credit_card_fields
|
2
|
+
|
3
|
+
Simple gem helpful in validating standard credit card forms.
|
4
|
+
Consists of validation for credit card, its cvv, expiration date and owner. Also allows provider limitation.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'validate_credit_card_fields'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install validate_credit_card_fields
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Inside your model:
|
23
|
+
|
24
|
+
validate_credit_card_fields number: :your_cc_number_field,
|
25
|
+
cvv: :your_ccv_field,
|
26
|
+
month: :your_cc_month_field,
|
27
|
+
year: :your_cc_year_field,
|
28
|
+
owner: :your_cc_owner_field,
|
29
|
+
providers: [:amex, :visa]
|
30
|
+
|
31
|
+
In place of `:your_something_field` place keys representing desired value in your model.
|
32
|
+
|
33
|
+
`providers` are used to specify provider limitations. Supply it with a list of **supported** providers (those you want to be valid). Leaving it blank will allow any of the accepted providers below:
|
34
|
+
|
35
|
+
:visa, :master_card, :maestro, :diners_club, :amex, :discover, :jcb
|
36
|
+
|
37
|
+
When a field name isn't presented, validator will use default values:
|
38
|
+
|
39
|
+
:cc_number, :cc_cvv, :cc_month, :cc_year, :cc_owner
|
40
|
+
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it ( http://github.com/<my-github-username>/validate_credit_card_fields/fork )
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,158 @@
|
|
1
|
+
class CCTypeError < StandardError; end
|
2
|
+
|
3
|
+
require 'validate_credit_card_fields/version'
|
4
|
+
require 'date'
|
5
|
+
require 'active_support/core_ext/object/try'
|
6
|
+
|
7
|
+
module ActiveModel
|
8
|
+
module Validations
|
9
|
+
|
10
|
+
class CreditCardFieldsValidator < Validator
|
11
|
+
ERROR_TYPES = [:invalid, :blank, :not_supported]
|
12
|
+
|
13
|
+
PROVIDERS = {
|
14
|
+
visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
|
15
|
+
master_card: /^5[1-5][0-9]{14}$/,
|
16
|
+
maestro: /(^6759[0-9]{2}([0-9]{10})$)|(^6759[0-9]{2}([0-9]{12})$)|(^6759[0-9]{2}([0-9]{13})$)/,
|
17
|
+
diners_club: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
|
18
|
+
amex: /^3[47][0-9]{13}$/,
|
19
|
+
discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
|
20
|
+
jcb: /^(?:2131|1800|35\d{3})\d{11}$/
|
21
|
+
}
|
22
|
+
|
23
|
+
attr_accessor :options, :cc_number, :cc_cvv, :cc_month,
|
24
|
+
:cc_year, :cc_owner, :cc_providers, :cc_type, :custom_messages
|
25
|
+
|
26
|
+
def initialize(options={})
|
27
|
+
@options = options
|
28
|
+
@custom_messages = {}
|
29
|
+
@cc_number = init_option(:number, :cc_number)
|
30
|
+
@cc_cvv = init_option(:cvv, :cc_cvv)
|
31
|
+
@cc_month = init_option(:month, :cc_month)
|
32
|
+
@cc_year = init_option(:year, :cc_year)
|
33
|
+
@cc_owner = init_option(:owner, :cc_owner)
|
34
|
+
@cc_providers = options[:providers]
|
35
|
+
end
|
36
|
+
|
37
|
+
def init_option(key, default)
|
38
|
+
if options[key].is_a? Hash
|
39
|
+
init_option_from_hash options[key], default
|
40
|
+
else
|
41
|
+
options[key] || default
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def init_option_from_hash(hash, default)
|
46
|
+
field_name = hash[:field] || default
|
47
|
+
custom_messages[field_name] = hash.select{ |k,_| ERROR_TYPES.include? k }
|
48
|
+
field_name
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate(record)
|
52
|
+
@record = record
|
53
|
+
check_fields_format
|
54
|
+
@cc_type = get_cc_type
|
55
|
+
validate_fields_presence
|
56
|
+
validate_cc_number
|
57
|
+
validate_cc_cvv
|
58
|
+
validate_cc_month
|
59
|
+
validate_cc_year
|
60
|
+
validate_cc_expiry_date
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def validate_fields_presence
|
66
|
+
[cc_number, cc_cvv, cc_month, cc_year, cc_owner].each do |field|
|
67
|
+
add_error(field, :blank) if @record.public_send(field).blank?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate_cc_number
|
72
|
+
err = if @cc_type.nil? || !luhn_algorithm_valid?
|
73
|
+
:invalid
|
74
|
+
elsif !cc_providers.blank? && !cc_providers.include?(@cc_type)
|
75
|
+
:not_supported
|
76
|
+
end
|
77
|
+
add_error(cc_number, err) if err
|
78
|
+
end
|
79
|
+
|
80
|
+
def validate_cc_cvv
|
81
|
+
length = (@cc_type == :amex) ? 4 : 3
|
82
|
+
unless !@cc_type.nil? && (/\A\d{#{length}}\z/).match(@record.public_send(cc_cvv))
|
83
|
+
add_error(cc_cvv, :invalid)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def validate_cc_month
|
88
|
+
unless (/\A\d{2}\z/).match("%02d" % @record.public_send(cc_month).to_i) && @record.public_send(cc_month).to_i.between?(1, 12)
|
89
|
+
add_error(cc_month, :invalid)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def validate_cc_year
|
94
|
+
unless (/\A\d{2}\z/).match(@record.public_send(cc_year)) && (@record.public_send(cc_year).to_i >= Date.today.year-2000)
|
95
|
+
add_error(cc_year, :invalid)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def validate_cc_expiry_date
|
100
|
+
if (@record.errors.messages.keys & [cc_year, cc_month]).empty?
|
101
|
+
year = "20#{@record.public_send(cc_year)}".to_i
|
102
|
+
month = @record.public_send(cc_month).to_i
|
103
|
+
date = Date.new(year, month).next_month.prev_day
|
104
|
+
if date < Date.today
|
105
|
+
field = if date.year < Date.today.year
|
106
|
+
cc_year
|
107
|
+
else
|
108
|
+
cc_month
|
109
|
+
end
|
110
|
+
add_error(field, :invalid)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def luhn_algorithm_valid?
|
116
|
+
s1 = s2 = 0
|
117
|
+
@record.public_send(cc_number).to_s.reverse.chars.each_slice(2) do |odd, even|
|
118
|
+
s1 += odd.to_i
|
119
|
+
double = even.to_i * 2
|
120
|
+
double -= 9 if double >= 10
|
121
|
+
s2 += double
|
122
|
+
end
|
123
|
+
(s1 + s2) % 10 == 0
|
124
|
+
end
|
125
|
+
|
126
|
+
def add_error(field, message)
|
127
|
+
@record.errors.add(field, error_message(field, message)) if @record.errors[field].blank?
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_cc_type
|
131
|
+
PROVIDERS.find{ |_, regex| regex.match(@record.public_send(cc_number)) }.try(:first)
|
132
|
+
end
|
133
|
+
|
134
|
+
def error_message(field, message)
|
135
|
+
custom_messages[field].try(:[], message) || translate_error(message)
|
136
|
+
end
|
137
|
+
|
138
|
+
def translate_error error
|
139
|
+
::I18n.t("errors.messages.#{error}")
|
140
|
+
end
|
141
|
+
|
142
|
+
def check_fields_format
|
143
|
+
invalid_attr = [cc_number, cc_cvv, cc_month, cc_year, cc_owner].find do |attr|
|
144
|
+
!@record.public_send(attr).is_a?(NilClass) && !@record.public_send(attr).is_a?(String)
|
145
|
+
end
|
146
|
+
if invalid_attr
|
147
|
+
raise CCTypeError, "#{invalid_attr} is a #{@record.public_send(invalid_attr).class}, String expected."
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
module HelperMethods
|
153
|
+
def validate_credit_card_fields(options={})
|
154
|
+
validates_with CreditCardFieldsValidator, options
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/spec/dummy/user.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
class User
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :credit_card_number, :credit_card_cvv, :credit_card_month,
|
7
|
+
:credit_card_year, :credit_card_owner
|
8
|
+
|
9
|
+
validate_credit_card_fields number: :credit_card_number,
|
10
|
+
cvv: :credit_card_cvv,
|
11
|
+
month: { field: :credit_card_month },
|
12
|
+
year: :credit_card_year,
|
13
|
+
owner: :credit_card_owner,
|
14
|
+
providers: [:amex, :visa]
|
15
|
+
|
16
|
+
def [](key)
|
17
|
+
send(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def should_have_error field, message
|
4
|
+
dummy.valid?
|
5
|
+
expect(dummy.errors.messages[field]).to include message
|
6
|
+
end
|
7
|
+
|
8
|
+
def has_valid *fields
|
9
|
+
dummy.valid?
|
10
|
+
fields.to_a.each do |field|
|
11
|
+
expect(dummy.errors.messages[field]).not_to be
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
describe ValidateCreditCardFields do
|
17
|
+
|
18
|
+
context 'Implemented model\'s credit card' do
|
19
|
+
let(:dummy) { User.new }
|
20
|
+
|
21
|
+
context 'owner' do
|
22
|
+
|
23
|
+
it 'must be present' do
|
24
|
+
dummy.credit_card_owner = nil
|
25
|
+
should_have_error :credit_card_owner, 'can\'t be blank'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'raises an error if it\'s not a string' do
|
29
|
+
dummy.credit_card_owner = 1
|
30
|
+
expect{dummy.valid?}.to raise_error{CCTypeError}
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'not raising error if nil' do
|
34
|
+
dummy.credit_card_owner = nil
|
35
|
+
expect{dummy.valid?}.not_to raise_error{CCTypeError}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'number' do
|
40
|
+
|
41
|
+
it 'must be present' do
|
42
|
+
dummy.credit_card_number = nil
|
43
|
+
should_have_error :credit_card_number, 'can\'t be blank'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'must have a valid provider' do
|
47
|
+
dummy.credit_card_number = '0000'
|
48
|
+
should_have_error :credit_card_number, 'is invalid'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'must have a supported provider' do
|
52
|
+
dummy.credit_card_number = '36255264496934' # => diner's club
|
53
|
+
dummy.valid?
|
54
|
+
expect(dummy.errors[:credit_card_number].length).to eq(1)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises an error if it\'s not a string' do
|
58
|
+
dummy.credit_card_number = 1
|
59
|
+
expect{dummy.valid?}.to raise_error{CCTypeError}
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'not raising error if nil' do
|
63
|
+
dummy.credit_card_number = nil
|
64
|
+
expect{dummy.valid?}.not_to raise_error{CCTypeError}
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'Luhn algorithm' do
|
68
|
+
|
69
|
+
it 'is invalid with bad checksum' do
|
70
|
+
dummy.credit_card_number = '4111111111111110' # => visa
|
71
|
+
should_have_error :credit_card_number, 'is invalid'
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'has no errors with valid card number' do
|
75
|
+
valid_card_numbers = %w(4111111111111111 378282246310005 4012888888881881 371449635398431)
|
76
|
+
valid_card_numbers.each do |ccn|
|
77
|
+
dummy.credit_card_number = ccn
|
78
|
+
has_valid :credit_card_number
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'cvv' do
|
87
|
+
|
88
|
+
it 'must be present' do
|
89
|
+
dummy.credit_card_cvv = nil
|
90
|
+
should_have_error :credit_card_cvv, 'can\'t be blank'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'must be 4 digits long for an amex card' do
|
94
|
+
dummy.credit_card_cvv = '123'
|
95
|
+
dummy.credit_card_number = '377012652618992' # => amex
|
96
|
+
should_have_error :credit_card_cvv, 'is invalid'
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'must be 3 digits long for any other card' do
|
100
|
+
dummy.credit_card_cvv = '1234'
|
101
|
+
dummy.credit_card_number = '123'
|
102
|
+
should_have_error :credit_card_cvv, 'is invalid'
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'raises an error if it\'s not a string' do
|
106
|
+
dummy.credit_card_cvv = 1
|
107
|
+
expect{dummy.valid?}.to raise_error{CCTypeError}
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'not raising error if nil' do
|
111
|
+
dummy.credit_card_cvv = nil
|
112
|
+
expect{dummy.valid?}.not_to raise_error{CCTypeError}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'month' do
|
117
|
+
|
118
|
+
it 'must be present' do
|
119
|
+
dummy.credit_card_month = nil
|
120
|
+
should_have_error :credit_card_month, 'can\'t be blank'
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'must be positive' do
|
124
|
+
dummy.credit_card_month = '-1'
|
125
|
+
should_have_error :credit_card_month, 'is invalid'
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'must be an integer' do
|
129
|
+
dummy.credit_card_month = '.5'
|
130
|
+
should_have_error :credit_card_month, 'is invalid'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'accepts 2 digits' do
|
134
|
+
dummy.credit_card_month = '11'
|
135
|
+
has_valid :credit_card_month
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'accepts 1 digit' do
|
139
|
+
dummy.credit_card_month = '1'
|
140
|
+
has_valid :credit_card_month
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'accepts correct input' do
|
144
|
+
dummy.credit_card_month = '12'
|
145
|
+
has_valid :credit_card_month
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'must be smaller than 12' do
|
149
|
+
dummy.credit_card_month = '13'
|
150
|
+
should_have_error :credit_card_month, 'is invalid'
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'raises an error if it\'s not a string' do
|
154
|
+
dummy.credit_card_month = 1
|
155
|
+
expect{dummy.valid?}.to raise_error{CCTypeError}
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'not raising error if nil' do
|
159
|
+
dummy.credit_card_month = nil
|
160
|
+
expect{dummy.valid?}.not_to raise_error{CCTypeError}
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'year' do
|
166
|
+
|
167
|
+
it 'must be present' do
|
168
|
+
dummy.credit_card_year = nil
|
169
|
+
should_have_error :credit_card_year, 'can\'t be blank'
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'must be positive' do
|
173
|
+
dummy.credit_card_year = '-1'
|
174
|
+
should_have_error :credit_card_year, 'is invalid'
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'must be an integer' do
|
178
|
+
dummy.credit_card_year = '.5'
|
179
|
+
should_have_error :credit_card_year, 'is invalid'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'must have 2 digits' do
|
183
|
+
dummy.credit_card_year = '9'
|
184
|
+
should_have_error :credit_card_year, 'is invalid'
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'cannot be past' do
|
188
|
+
dummy.credit_card_year = (Date.today.year-1).to_s[2..-1]
|
189
|
+
should_have_error :credit_card_year, 'is invalid'
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'accepts without leading zeros' do
|
193
|
+
dummy.credit_card_month = "1"
|
194
|
+
dummy.credit_card_year = (Date.today.year+1).to_s[2..-1]
|
195
|
+
has_valid :credit_card_month, :credit_card_year
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'accepts correct input' do
|
199
|
+
dummy.credit_card_year = (Date.today.year+1).to_s[2..-1]
|
200
|
+
has_valid :credit_card_year
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'raises an error if it\'s not a string' do
|
204
|
+
dummy.credit_card_year = 1
|
205
|
+
expect{dummy.valid?}.to raise_error{CCTypeError}
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'not raising error if nil' do
|
209
|
+
dummy.credit_card_year = nil
|
210
|
+
expect{dummy.valid?}.not_to raise_error{CCTypeError}
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
context 'date' do
|
216
|
+
|
217
|
+
it 'sets past year as invalid' do
|
218
|
+
dummy.credit_card_month = '01'
|
219
|
+
dummy.credit_card_year = '10'
|
220
|
+
should_have_error :credit_card_year, 'is invalid'
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'sets past month as invalid' do
|
224
|
+
dummy.credit_card_month = '01'
|
225
|
+
dummy.credit_card_year = Date.today.year.to_s[2..-1]
|
226
|
+
should_have_error :credit_card_month, 'is invalid'
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'accepts future date' do
|
230
|
+
dummy.credit_card_month = '01'
|
231
|
+
dummy.credit_card_year = (Date.today.year+1).to_s[2..-1]
|
232
|
+
has_valid :credit_card_month, :credit_card_year
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'accepts current date' do
|
236
|
+
dummy.credit_card_month = "%02d" % Date.today.month
|
237
|
+
dummy.credit_card_year = (Date.today.year).to_s[2..-1]
|
238
|
+
has_valid :credit_card_month, :credit_card_year
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'validation options' do
|
245
|
+
let(:default_fields) { [:cc_number, :cc_cvv, :cc_month, :cc_year, :cc_owner] }
|
246
|
+
let(:default_options) { { providers: [:amex, :visa] } }
|
247
|
+
let(:fields) { default_fields }
|
248
|
+
let(:options) { default_options }
|
249
|
+
|
250
|
+
let(:klass) {
|
251
|
+
_fields = fields
|
252
|
+
_opt = options
|
253
|
+
Class.new do
|
254
|
+
include ActiveModel::Validations
|
255
|
+
attr_accessor *_fields
|
256
|
+
validate_credit_card_fields _opt
|
257
|
+
end
|
258
|
+
}
|
259
|
+
|
260
|
+
let(:dummy) { klass.new }
|
261
|
+
|
262
|
+
context 'without settings' do
|
263
|
+
it 'uses default field names' do
|
264
|
+
expect{dummy.valid?}.not_to raise_error
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'with custom field' do
|
269
|
+
let(:owner_field) { :custom_owner_field }
|
270
|
+
let(:fields) { default_fields + [owner_field] }
|
271
|
+
|
272
|
+
before {dummy.send("#{owner_field}=", 'John Test')}
|
273
|
+
|
274
|
+
context 'passed as symbol' do
|
275
|
+
let(:options) { default_options.merge({owner: owner_field}) }
|
276
|
+
it 'uses custom field name' do
|
277
|
+
has_valid owner_field
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
context 'passed in hash' do
|
282
|
+
let(:options) { default_options.merge({owner: {field: owner_field}}) }
|
283
|
+
it 'uses custom field name' do
|
284
|
+
has_valid owner_field
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context 'with custom error message' do
|
290
|
+
let(:error_msg) { 'custom error message' }
|
291
|
+
let(:options) { default_options.merge({owner: {blank: error_msg}}) }
|
292
|
+
it 'uses custom error message' do
|
293
|
+
dummy.cc_owner = nil
|
294
|
+
should_have_error :cc_owner, error_msg
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'validate_credit_card_fields/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "validate_credit_card_fields"
|
8
|
+
spec.version = ValidateCreditCardFields::VERSION
|
9
|
+
spec.authors = ["Piotr Kruczek", "Jacek Zachariasz", "Jan Grodowski", "Patryk Pastewski"]
|
10
|
+
spec.email = ["daftcode@daftcode.pl"]
|
11
|
+
spec.summary = %q{Credit card validation with all dependant fields}
|
12
|
+
spec.description = %q{Simple gem helpful in validating standard credit card forms}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activemodel"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "byebug"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: validate_credit_card_fields
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Piotr Kruczek
|
8
|
+
- Jacek Zachariasz
|
9
|
+
- Jan Grodowski
|
10
|
+
- Patryk Pastewski
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2015-06-08 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activemodel
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ~>
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '1.5'
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.5'
|
44
|
+
- !ruby/object:Gem::Dependency
|
45
|
+
name: rake
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: byebug
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
description: Simple gem helpful in validating standard credit card forms
|
87
|
+
email:
|
88
|
+
- daftcode@daftcode.pl
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- .gitignore
|
94
|
+
- .rspec
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- lib/validate_credit_card_fields.rb
|
100
|
+
- lib/validate_credit_card_fields/version.rb
|
101
|
+
- spec/dummy/user.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/validate_credit_card_fields_spec.rb
|
104
|
+
- validate_credit_card_fields.gemspec
|
105
|
+
homepage: ''
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata: {}
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
requirements: []
|
124
|
+
rubyforge_project:
|
125
|
+
rubygems_version: 2.2.0
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Credit card validation with all dependant fields
|
129
|
+
test_files:
|
130
|
+
- spec/dummy/user.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/validate_credit_card_fields_spec.rb
|