credit_card_validations 2.0.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.hound.yml +2 -0
- data/Changelog.md +8 -2
- data/README.md +43 -34
- data/lib/credit_card_validations.rb +1 -0
- data/lib/credit_card_validations/detector.rb +1 -6
- data/lib/credit_card_validations/error.rb +4 -0
- data/lib/credit_card_validations/factory.rb +3 -5
- data/lib/credit_card_validations/plugins/diners_us.rb +6 -0
- data/lib/credit_card_validations/plugins/en_route.rb +5 -0
- data/lib/credit_card_validations/plugins/laser.rb +4 -0
- data/lib/credit_card_validations/version.rb +1 -1
- data/lib/data/brands.yaml +4 -21
- data/spec/active_model_spec.rb +14 -14
- data/spec/credit_card_validations_spec.rb +55 -48
- data/spec/factory_spec.rb +1 -4
- data/spec/fixtures/valid_cards.yml +3 -3
- data/spec/models/credit_card.rb +9 -9
- data/spec/string_spec.rb +7 -18
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a1e73d7b928f5b5ff394ff97d474efb2b3cf788
|
4
|
+
data.tar.gz: bc489307b73e6d13e6f4916b2858fe5683471079
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 257782b63a7f3f33c97909dde5f5aaed324c1aa0d22244431a0c06bc8cee9ad03dc8f65c29e9717bfb7e197819235b5b4dc617f12e14cfc4872eb19ea23c5bf0
|
7
|
+
data.tar.gz: cc6be70cf2d14199bca83b56af71ee18caea1c1e7b9cbb905d1b62f34be0752a070d3aea5485d3e1cf320f2ebf892dbdae35bb904da2cfcc4b04a513e035e2c3
|
data/.hound.yml
ADDED
data/Changelog.md
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
+
# 3.0.0
|
2
|
+
* Remove Laser brand because Laser cards were withdrawn from the market on February 28 2014
|
3
|
+
* Remove Diners US brand for similar reason
|
4
|
+
* Move Laser ranges to Maestro. Add 6390 range to Maestro
|
5
|
+
* Add plugins for removed brands
|
6
|
+
|
1
7
|
# 2.0.2
|
2
8
|
* fix using ActiveModel Validator's message option
|
3
9
|
|
4
10
|
# 2.0.1
|
5
|
-
* fix typo dankrot -> dankort
|
6
|
-
|
11
|
+
* fix typo dankrot -> dankort
|
12
|
+
|
7
13
|
# 2.0.0
|
8
14
|
|
9
15
|
* added support for full brand names
|
data/README.md
CHANGED
@@ -31,26 +31,34 @@ Or install it yourself as:
|
|
31
31
|
|
32
32
|
The following issuing institutes are accepted:
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
34
|
+
Name | Key |
|
35
|
+
--------------------- | ------------|
|
36
|
+
[American Express](http://en.wikipedia.org/wiki/American_Express) | :amex
|
37
|
+
[China UnionPay](http://en.wikipedia.org/wiki/China_UnionPay) | :unionpay
|
38
|
+
[Dankort](http://en.wikipedia.org/wiki/Dankort) | :dankort
|
39
|
+
[Diners Club](http://en.wikipedia.org/wiki/Diners_Club_International) | :diners
|
40
|
+
[Discover](http://en.wikipedia.org/wiki/Discover_Card) | :discover
|
41
|
+
[Hipercard](http://pt.wikipedia.org/wiki/Hipercard) | :hipercard
|
42
|
+
[JCB](http://en.wikipedia.org/wiki/Japan_Credit_Bureau) | :jcb
|
43
|
+
[Maestro](http://en.wikipedia.org/wiki/Maestro_%28debit_card%29) | :maestro
|
44
|
+
[MasterCard](http://en.wikipedia.org/wiki/MasterCard) | :mastercard
|
45
|
+
[Rupay](http://en.wikipedia.org/wiki/RuPay) | :rupay
|
46
|
+
[Solo](http://en.wikipedia.org/wiki/Solo_(debit_card)) | :solo
|
47
|
+
[Switch](http://en.wikipedia.org/wiki/Switch_(debit_card)) | :switch
|
48
|
+
[Visa](http://en.wikipedia.org/wiki/Visa_Inc.) | :visa
|
49
|
+
|
50
|
+
|
51
|
+
The following are supported with with plugins
|
52
|
+
|
53
|
+
Name | Key |
|
54
|
+
--------------------- | ------------|
|
55
|
+
[Diners Club US](http://en.wikipedia.org/wiki/Diners_Club_International#MasterCard_alliance) | :diners_us
|
56
|
+
[EnRoute](https://en.wikipedia.org/wiki/EnRoute_(credit_card)) | :en_route
|
57
|
+
[Laser](https://en.wikipedia.org/wiki/Laser_%28debit_card%29) | :laser
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
### Examples using string monkey patch
|
54
62
|
|
55
63
|
```ruby
|
56
64
|
require 'credit_card_validations/string'
|
@@ -61,7 +69,7 @@ Examples using string monkey patch
|
|
61
69
|
'5274 5763 9425 9961'.valid_credit_card_brand?('MasterCard') #=> true
|
62
70
|
```
|
63
71
|
|
64
|
-
ActiveModel support
|
72
|
+
### ActiveModel support
|
65
73
|
|
66
74
|
only for certain brads
|
67
75
|
|
@@ -79,7 +87,7 @@ for all known brands
|
|
79
87
|
validates :number, presence: true, credit_card_number: true
|
80
88
|
```
|
81
89
|
|
82
|
-
Examples using CreditCardValidations::Detector class
|
90
|
+
### Examples using CreditCardValidations::Detector class
|
83
91
|
|
84
92
|
```ruby
|
85
93
|
number = "4111111111111111"
|
@@ -91,32 +99,24 @@ Examples using CreditCardValidations::Detector class
|
|
91
99
|
detector.issuer_category #"Banking and financial"
|
92
100
|
```
|
93
101
|
|
94
|
-
Also You can add your own brand rules to detect other credit card brands/types
|
102
|
+
### Also You can add your own brand rules to detect other credit card brands/types
|
95
103
|
passing name,length(integer/array of integers) and prefix(string/array of strings)
|
96
104
|
Example
|
97
105
|
|
98
106
|
```ruby
|
99
107
|
CreditCardValidations.add_brand(:voyager, {length: 15, prefixes: '86'})
|
100
|
-
CreditCardValidations.add_brand(:en_route, {length: 15, prefixes: ['2014', '2149']}, {skip_luhn: true}) #skip luhn
|
101
|
-
|
102
108
|
voyager_test_card_number = '869926275400212'
|
103
109
|
CreditCardValidations::Detector.new(voyager_test_card_number).brand #:voyager
|
104
110
|
CreditCardValidations::Detector.new(voyager_test_card_number).voyager? #true
|
105
|
-
|
106
|
-
en_route_test_card_number = '2014-0000-0000-001'
|
107
|
-
CreditCardValidations::Detector.new(en_route_test_card_number).brand #:en_route
|
108
|
-
CreditCardValidations::Detector.new(en_route_test_card_number).en_route? #true
|
109
111
|
```
|
110
112
|
|
111
|
-
Remove brands also supported
|
113
|
+
### Remove brands also supported
|
112
114
|
|
113
115
|
```ruby
|
114
116
|
CreditCardValidations.delete_brand(:maestro)
|
115
117
|
```
|
116
118
|
|
117
|
-
|
118
|
-
|
119
|
-
Check luhn
|
119
|
+
### Check luhn
|
120
120
|
|
121
121
|
```ruby
|
122
122
|
CreditCardValidations::Detector.new(@credit_card_number).valid_luhn?
|
@@ -124,7 +124,7 @@ Check luhn
|
|
124
124
|
CreditCardValidations::Luhn.valid?(@credit_card_number)
|
125
125
|
```
|
126
126
|
|
127
|
-
Generate credit card numbers that pass validation
|
127
|
+
### Generate credit card numbers that pass validation
|
128
128
|
|
129
129
|
```ruby
|
130
130
|
CreditCardValidations::Factory.random(:amex)
|
@@ -133,6 +133,15 @@ Generate credit card numbers that pass validation
|
|
133
133
|
# => "6010430241237266856"
|
134
134
|
```
|
135
135
|
|
136
|
+
### Plugins
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
require 'credit_card_validations/plugins/en_route'
|
140
|
+
require 'credit_card_validations/plugins/laser'
|
141
|
+
require 'credit_card_validations/plugins/diners_us'
|
142
|
+
|
143
|
+
```
|
144
|
+
|
136
145
|
## Contributing
|
137
146
|
|
138
147
|
1. Fork it
|
@@ -101,7 +101,6 @@ module CreditCardValidations
|
|
101
101
|
else
|
102
102
|
nil
|
103
103
|
end
|
104
|
-
|
105
104
|
end
|
106
105
|
|
107
106
|
def brand_key(brand_name)
|
@@ -120,7 +119,7 @@ module CreditCardValidations
|
|
120
119
|
#create rule for detecting brand
|
121
120
|
def add_rule(key, length, prefixes)
|
122
121
|
unless brands.has_key?(key)
|
123
|
-
raise
|
122
|
+
raise Error.new("brand #{key} is undefined, please use #add_brand method")
|
124
123
|
end
|
125
124
|
length, prefixes = Array(length), Array(prefixes)
|
126
125
|
brands[key][:rules] << {length: length, regexp: compile_regexp(prefixes), prefixes: prefixes}
|
@@ -139,14 +138,10 @@ module CreditCardValidations
|
|
139
138
|
undef_method "#{key}?".to_sym if method_defined? "#{key}?".to_sym
|
140
139
|
end
|
141
140
|
|
142
|
-
|
143
141
|
#create regexp by array of prefixes
|
144
142
|
def compile_regexp(prefixes)
|
145
143
|
Regexp.new("^((#{prefixes.join(")|(")}))")
|
146
144
|
end
|
147
|
-
|
148
145
|
end
|
149
|
-
|
150
146
|
end
|
151
|
-
|
152
147
|
end
|
@@ -12,13 +12,11 @@ module CreditCardValidations
|
|
12
12
|
class Factory
|
13
13
|
class << self
|
14
14
|
def random(brand = nil)
|
15
|
-
if brand.nil?
|
16
|
-
|
17
|
-
|
18
|
-
raise RuntimeError.new("Unsupported brand") if Detector.brands[brand].nil?
|
15
|
+
brand = Detector.brands.keys.sample if brand.nil?
|
16
|
+
if Detector.brands[brand].nil?
|
17
|
+
raise Error.new('Unsupported brand')
|
19
18
|
end
|
20
19
|
generate(Detector.brands[brand][:rules].sample)
|
21
|
-
|
22
20
|
end
|
23
21
|
|
24
22
|
def generate(rule)
|
data/lib/data/brands.yaml
CHANGED
@@ -42,15 +42,6 @@
|
|
42
42
|
- '38'
|
43
43
|
:options:
|
44
44
|
:brand_name: Diners Club
|
45
|
-
:diners_us:
|
46
|
-
:rules:
|
47
|
-
- :length:
|
48
|
-
- 16
|
49
|
-
:prefixes:
|
50
|
-
- '54'
|
51
|
-
- '55'
|
52
|
-
:options:
|
53
|
-
:brand_name: Diners Club US
|
54
45
|
:discover:
|
55
46
|
:rules:
|
56
47
|
- :length:
|
@@ -89,17 +80,6 @@
|
|
89
80
|
- '357266'
|
90
81
|
:options:
|
91
82
|
:brand_name: JCB
|
92
|
-
:laser:
|
93
|
-
:rules:
|
94
|
-
- :length:
|
95
|
-
- 16
|
96
|
-
- 17
|
97
|
-
- 18
|
98
|
-
- 19
|
99
|
-
:prefixes:
|
100
|
-
- '6304'
|
101
|
-
- '6706'
|
102
|
-
- '6771'
|
103
83
|
:solo:
|
104
84
|
:rules:
|
105
85
|
- :length:
|
@@ -173,6 +153,8 @@
|
|
173
153
|
- '621'
|
174
154
|
- '627'
|
175
155
|
- '629'
|
156
|
+
- '6304'
|
157
|
+
- '6390'
|
176
158
|
- '670'
|
177
159
|
- '671'
|
178
160
|
- '672'
|
@@ -189,6 +171,7 @@
|
|
189
171
|
- '6766'
|
190
172
|
- '6768'
|
191
173
|
- '6769'
|
174
|
+
- '6771'
|
192
175
|
- '679'
|
193
176
|
:unionpay:
|
194
177
|
:rules:
|
@@ -235,4 +218,4 @@
|
|
235
218
|
- :length:
|
236
219
|
- 19
|
237
220
|
:prefixes:
|
238
|
-
- '384'
|
221
|
+
- '384'
|
data/spec/active_model_spec.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe 'ActiveModel Validator' do
|
4
4
|
|
5
5
|
let(:model) { CreditCard.new }
|
6
6
|
|
7
|
-
describe
|
8
|
-
it
|
7
|
+
describe 'Proc support' do
|
8
|
+
it 'should be valid if brands from proc valid' do
|
9
9
|
card = model.dup
|
10
|
-
card.card_type =
|
10
|
+
card.card_type = 'Master Card'
|
11
11
|
card.number6 = CreditCardValidations::Factory.random(:visa)
|
12
12
|
card.valid?.must_equal false
|
13
13
|
card.number6 = CreditCardValidations::Factory.random(:mastercard)
|
@@ -15,8 +15,8 @@ describe "ActiveModel Validator" do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
19
|
-
it
|
18
|
+
describe 'Any Brand' do
|
19
|
+
it 'should be valid for all prepared valid numbers' do
|
20
20
|
VALID_NUMBERS.each do |_, numbers|
|
21
21
|
numbers.each do |number|
|
22
22
|
card = model
|
@@ -28,8 +28,8 @@ describe "ActiveModel Validator" do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe
|
32
|
-
it
|
31
|
+
describe 'Except Amex and Maestro brand' do
|
32
|
+
it 'should reject all other valid numbers' do
|
33
33
|
VALID_NUMBERS.except(:amex, :maestro).each do |_, numbers|
|
34
34
|
card = model
|
35
35
|
card.number = numbers.first
|
@@ -38,7 +38,7 @@ describe "ActiveModel Validator" do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'should accept using except options' do
|
42
42
|
VALID_NUMBERS.except(:amex, :maestro).each do |_, numbers|
|
43
43
|
card = model
|
44
44
|
card.number3 = numbers.first
|
@@ -47,8 +47,8 @@ describe "ActiveModel Validator" do
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
describe
|
51
|
-
it
|
50
|
+
describe 'Only Amex and Mestro brands' do
|
51
|
+
it 'should accept amex and maestro brand if valid' do
|
52
52
|
VALID_NUMBERS.slice(:amex, :maestro).each do |_, numbers|
|
53
53
|
card = model
|
54
54
|
card.number = numbers.first
|
@@ -58,12 +58,12 @@ describe "ActiveModel Validator" do
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
describe
|
62
|
-
it
|
61
|
+
describe 'Custom error message' do
|
62
|
+
it 'should allow custom message' do
|
63
63
|
card = model
|
64
64
|
card.number7 = 'wrong'
|
65
65
|
card.valid?.must_equal false
|
66
|
-
card.errors[:number7].must_equal [
|
66
|
+
card.errors[:number7].must_equal ['Custom message']
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -7,29 +7,28 @@ describe CreditCardValidations do
|
|
7
7
|
CreditCardValidations.reload!
|
8
8
|
end
|
9
9
|
|
10
|
-
describe
|
11
|
-
it
|
10
|
+
describe 'MMI' do
|
11
|
+
it 'should detect issuer category' do
|
12
12
|
d = detector(VALID_NUMBERS[:visa].first)
|
13
13
|
d.issuer_category.must_equal CreditCardValidations::Mmi::ISSUER_CATEGORIES[d.number[0]]
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe
|
17
|
+
describe 'Luhn#valid?' do
|
18
18
|
let(:card_detector) {
|
19
19
|
detector(VALID_NUMBERS[:unionpay].first)
|
20
20
|
}
|
21
|
-
it
|
21
|
+
it 'should call Luhn.valid? once' do
|
22
22
|
CreditCardValidations::Luhn.expects(:valid?).with(card_detector.number).once
|
23
23
|
card_detector.valid?(:visa, :unionpay).must_equal true
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it 'should call Luhn.valid? twice' do
|
27
27
|
CreditCardValidations::Luhn.expects(:valid?).with(card_detector.number).twice
|
28
28
|
card_detector.valid?(:visa, :mastercard).must_equal false
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
32
|
-
|
31
|
+
it 'should not call Luhn.valid?' do
|
33
32
|
CreditCardValidations::Luhn.expects(:valid?).never
|
34
33
|
card_detector.valid?(:unionpay).must_equal true
|
35
34
|
end
|
@@ -37,7 +36,7 @@ describe CreditCardValidations do
|
|
37
36
|
end
|
38
37
|
|
39
38
|
|
40
|
-
it
|
39
|
+
it 'should check luhn' do
|
41
40
|
VALID_NUMBERS.each do |brand, card_numbers|
|
42
41
|
if has_luhn_check_rule?(brand)
|
43
42
|
card_numbers.each do |number|
|
@@ -47,7 +46,7 @@ describe CreditCardValidations do
|
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
50
|
-
it
|
49
|
+
it 'should check valid brand' do
|
51
50
|
VALID_NUMBERS.each do |brand, card_numbers|
|
52
51
|
card_numbers.each do |card_number|
|
53
52
|
detector(card_number).send("#{brand}?").must_equal true
|
@@ -56,7 +55,7 @@ describe CreditCardValidations do
|
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
59
|
-
it
|
58
|
+
it 'should check if card invalid' do
|
60
59
|
INVALID_NUMBERS.each do |card_number|
|
61
60
|
detector(card_number).valid?.must_equal false
|
62
61
|
detector(card_number).brand.must_be_nil
|
@@ -66,14 +65,14 @@ describe CreditCardValidations do
|
|
66
65
|
end
|
67
66
|
end
|
68
67
|
|
69
|
-
it
|
70
|
-
amex =
|
68
|
+
it 'should detect by full brand name' do
|
69
|
+
amex = CreditCardValidations::Factory.random(:amex)
|
71
70
|
detector(amex).valid?('American Express').must_equal true
|
72
|
-
visa =
|
71
|
+
visa = CreditCardValidations::Factory.random(:visa)
|
73
72
|
detector(visa).valid?('American Express').must_equal false
|
74
73
|
end
|
75
74
|
|
76
|
-
it
|
75
|
+
it 'should support multiple brands for single check' do
|
77
76
|
VALID_NUMBERS.slice(:visa, :mastercard).each do |key, value|
|
78
77
|
detector(value.first).brand(:visa, :mastercard).must_equal key
|
79
78
|
end
|
@@ -83,7 +82,7 @@ describe CreditCardValidations do
|
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
86
|
-
it
|
85
|
+
it 'should check if valid brand without arguments' do
|
87
86
|
VALID_NUMBERS.each do |key, value|
|
88
87
|
value.each do |card_number|
|
89
88
|
detector(card_number).valid?(key).must_equal true
|
@@ -92,66 +91,75 @@ describe CreditCardValidations do
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
95
|
-
it
|
94
|
+
it 'should not be valid? if wrong brand' do
|
96
95
|
detector(VALID_NUMBERS[:visa].first).valid?(:mastercard).must_equal false
|
97
96
|
detector(VALID_NUMBERS[:mastercard].first).valid?(:visa).must_equal false
|
98
97
|
end
|
99
98
|
|
100
|
-
it
|
99
|
+
it 'should be valid? if right brand' do
|
101
100
|
detector(VALID_NUMBERS[:visa].first).valid?(:mastercard, :visa).must_equal true
|
102
101
|
detector(VALID_NUMBERS[:visa].first).valid?(:mastercard, :amex).must_equal false
|
103
102
|
end
|
104
103
|
|
105
104
|
|
106
|
-
describe
|
107
|
-
|
108
|
-
|
109
|
-
let(:voyager_number) {
|
110
|
-
'869926275400212'
|
111
|
-
}
|
112
|
-
|
113
|
-
it "should validate number as voyager" do
|
114
|
-
CreditCardValidations::Detector.add_brand(:voyager, {length: 15, prefixes: '86'})
|
115
|
-
detector(voyager_number).valid?(:voyager).must_equal true
|
116
|
-
detector(voyager_number).voyager?.must_equal true
|
117
|
-
detector(voyager_number).brand.must_equal :voyager
|
118
|
-
end
|
119
|
-
|
105
|
+
describe 'adding/removing brand' do
|
120
106
|
|
121
|
-
describe
|
122
|
-
before do
|
123
|
-
CreditCardValidations::Detector.add_brand(:voyager, {length: 15, prefixes: '86'})
|
124
|
-
end
|
107
|
+
describe 'adding rules' do
|
125
108
|
|
126
|
-
|
109
|
+
let(:voyager_number) { '869926275400212' }
|
127
110
|
|
111
|
+
it 'should validate number as voyager' do
|
112
|
+
CreditCardValidations::Detector.add_brand(:voyager, length: 15, prefixes: '86')
|
128
113
|
detector(voyager_number).valid?(:voyager).must_equal true
|
129
114
|
detector(voyager_number).voyager?.must_equal true
|
130
115
|
detector(voyager_number).brand.must_equal :voyager
|
131
|
-
|
132
116
|
end
|
133
117
|
|
134
|
-
describe
|
118
|
+
describe 'Add voyager rule' do
|
135
119
|
before do
|
136
|
-
CreditCardValidations::Detector.
|
120
|
+
CreditCardValidations::Detector.add_brand(:voyager, length: 15, prefixes: '86')
|
137
121
|
end
|
138
122
|
|
139
|
-
it
|
140
|
-
detector(voyager_number).
|
141
|
-
detector(voyager_number).
|
123
|
+
it 'should validate number as voyager' do
|
124
|
+
detector(voyager_number).valid?(:voyager).must_equal true
|
125
|
+
detector(voyager_number).voyager?.must_equal true
|
126
|
+
detector(voyager_number).brand.must_equal :voyager
|
142
127
|
end
|
143
|
-
end
|
144
128
|
|
145
|
-
|
129
|
+
describe 'Remove voyager rule' do
|
130
|
+
before do
|
131
|
+
CreditCardValidations::Detector.delete_brand(:voyager)
|
132
|
+
end
|
146
133
|
|
134
|
+
it 'should not validate number as voyager' do
|
135
|
+
detector(voyager_number).respond_to?(:voyager?).must_equal false
|
136
|
+
detector(voyager_number).brand.must_be_nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
147
141
|
|
148
|
-
|
149
|
-
|
142
|
+
describe 'plugins' do
|
143
|
+
[:diners_us, :en_route, :laser].each do |brand|
|
144
|
+
it "should support #{brand}" do
|
145
|
+
-> { CreditCardValidations::Factory.random(brand) }.
|
146
|
+
must_raise(CreditCardValidations::Error)
|
147
|
+
custom_number = 'some_number'
|
148
|
+
detector(custom_number).respond_to?("#{brand}?").must_equal false
|
149
|
+
require "credit_card_validations/plugins/#{brand}"
|
150
|
+
number = CreditCardValidations::Factory.random(brand)
|
151
|
+
detector(number).valid?("#{brand}".to_sym).must_equal true
|
152
|
+
detector(custom_number).respond_to?("#{brand}?").must_equal true
|
153
|
+
end
|
154
|
+
end
|
150
155
|
end
|
151
156
|
|
157
|
+
it 'should raise Error if no brand added before' do
|
158
|
+
-> { CreditCardValidations::Detector::add_rule(:undefined_brand, 20, [20]) }.
|
159
|
+
must_raise(CreditCardValidations::Error)
|
160
|
+
end
|
152
161
|
end
|
153
162
|
|
154
|
-
|
155
163
|
def luhn_valid?(number)
|
156
164
|
CreditCardValidations::Luhn.valid?(number)
|
157
165
|
end
|
@@ -160,7 +168,6 @@ describe CreditCardValidations do
|
|
160
168
|
CreditCardValidations::Detector.new(number)
|
161
169
|
end
|
162
170
|
|
163
|
-
|
164
171
|
def has_luhn_check_rule?(key)
|
165
172
|
CreditCardValidations::Detector.has_luhn_check_rule?(key)
|
166
173
|
end
|
data/spec/factory_spec.rb
CHANGED
@@ -2,20 +2,17 @@ require_relative 'test_helper'
|
|
2
2
|
|
3
3
|
describe CreditCardValidations::Factory do
|
4
4
|
|
5
|
-
it
|
5
|
+
it 'should generate random brand' do
|
6
6
|
number = CreditCardValidations::Factory.random
|
7
7
|
CreditCardValidations::Detector.new(number).valid?.must_equal true
|
8
8
|
end
|
9
9
|
|
10
10
|
CreditCardValidations::Detector.brands.keys.sort.each do |key|
|
11
11
|
describe "#{key}" do
|
12
|
-
|
13
12
|
it "should generate valid #{key}" do
|
14
13
|
number = CreditCardValidations::Factory.random(key)
|
15
14
|
CreditCardValidations::Detector.new(number).valid?(key).must_equal true
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
20
|
-
|
21
18
|
end
|
@@ -49,6 +49,9 @@
|
|
49
49
|
- 5033 9619 8909 17
|
50
50
|
- 5868 2416 0825 5333 38
|
51
51
|
- 6799 9901 0000 0000 019
|
52
|
+
- 6390 0200 0000 000003
|
53
|
+
- 6304 9506 0000 0000 00
|
54
|
+
- 6304 9000 1774 0292 441
|
52
55
|
:jcb:
|
53
56
|
- 3575 7591 5225 4876
|
54
57
|
- 3566 0020 2036 0505
|
@@ -70,9 +73,6 @@
|
|
70
73
|
- 5019 7170 1010 3742
|
71
74
|
:switch:
|
72
75
|
- 6331 1019 9999 0016
|
73
|
-
:laser:
|
74
|
-
- 6304 9506 0000 0000 00
|
75
|
-
- 6304 9000 1774 0292 441
|
76
76
|
:rupay:
|
77
77
|
- 6076 6000 0619 9992
|
78
78
|
- 6070 5500 5000 0047
|
data/spec/models/credit_card.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
class CreditCard
|
2
2
|
attr_accessor :number, :number2, :number3, :number4, :number5, :number6, :number7, :card_type
|
3
3
|
include ActiveModel::Validations
|
4
|
-
validates :number, credit_card_number: {brands: [:amex, :maestro]}
|
5
|
-
validates :number2, credit_card_number: {only: [:amex, :maestro]},
|
6
|
-
validates :number3, credit_card_number: {except: [:amex, :maestro]}
|
7
|
-
validates :number4, credit_card_number: {brands: :any}
|
8
|
-
validates :number5, credit_card_number: true
|
9
|
-
validates :number6, credit_card_number: { brands: ->(record){ record.supported_brand } }
|
10
|
-
validates :number7, credit_card_number: { message:
|
4
|
+
validates :number, credit_card_number: { brands: [:amex, :maestro] }, allow_blank: true
|
5
|
+
validates :number2, credit_card_number: { only: [:amex, :maestro] }, allow_blank: true
|
6
|
+
validates :number3, credit_card_number: { except: [:amex, :maestro] }, allow_blank: true
|
7
|
+
validates :number4, credit_card_number: { brands: :any }, allow_blank: true
|
8
|
+
validates :number5, credit_card_number: true, allow_blank: true
|
9
|
+
validates :number6, credit_card_number: { brands: ->(record) { record.supported_brand } }, allow_blank: true
|
10
|
+
validates :number7, credit_card_number: { message: 'Custom message' }, allow_blank: true
|
11
11
|
|
12
12
|
def supported_brand
|
13
13
|
{
|
14
|
-
|
15
|
-
|
14
|
+
'Master Card' => :mastercard,
|
15
|
+
'Visa' => :visa
|
16
16
|
}[self.card_type]
|
17
17
|
end
|
18
18
|
|
data/spec/string_spec.rb
CHANGED
@@ -1,22 +1,13 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
require 'credit_card_validations/string'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe 'String ext' do
|
5
5
|
|
6
|
-
let(:mastercard) {
|
7
|
-
|
8
|
-
}
|
9
|
-
|
10
|
-
let(:visa) {
|
11
|
-
CreditCardValidations::Factory.random(:visa)
|
12
|
-
}
|
13
|
-
|
14
|
-
let(:invalid) {
|
15
|
-
INVALID_NUMBERS.sample
|
16
|
-
}
|
17
|
-
|
18
|
-
it "should allow detect brand for mastercard" do
|
6
|
+
let(:mastercard) { CreditCardValidations::Factory.random(:mastercard) }
|
7
|
+
let(:visa) { CreditCardValidations::Factory.random(:visa) }
|
8
|
+
let(:invalid) { INVALID_NUMBERS.sample }
|
19
9
|
|
10
|
+
it 'should allow detect brand for mastercard' do
|
20
11
|
mastercard.credit_card_brand.must_equal :mastercard
|
21
12
|
mastercard.credit_card_brand_name.must_equal 'MasterCard'
|
22
13
|
mastercard.valid_credit_card_brand?(:mastercard).must_equal true
|
@@ -24,16 +15,14 @@ describe "String ext" do
|
|
24
15
|
mastercard.valid_credit_card_brand?(:visa, :amex).must_equal false
|
25
16
|
end
|
26
17
|
|
27
|
-
it
|
28
|
-
|
18
|
+
it 'should allow detect brand for visa' do
|
29
19
|
visa.credit_card_brand.must_equal :visa
|
30
20
|
visa.credit_card_brand_name.must_equal 'Visa'
|
31
21
|
visa.valid_credit_card_brand?(:mastercard).must_equal false
|
32
22
|
visa.valid_credit_card_brand?(:visa, :amex).must_equal true
|
33
23
|
end
|
34
24
|
|
35
|
-
it
|
36
|
-
|
25
|
+
it 'should not allow detect brand for invalid card' do
|
37
26
|
invalid.credit_card_brand.must_be_nil
|
38
27
|
invalid.credit_card_brand_name.must_be_nil
|
39
28
|
invalid.valid_credit_card_brand?(:mastercard).must_equal false
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: credit_card_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -85,6 +85,7 @@ executables: []
|
|
85
85
|
extensions: []
|
86
86
|
extra_rdoc_files: []
|
87
87
|
files:
|
88
|
+
- ".hound.yml"
|
88
89
|
- ".travis.yml"
|
89
90
|
- Changelog.md
|
90
91
|
- Gemfile
|
@@ -95,9 +96,13 @@ files:
|
|
95
96
|
- lib/active_model/credit_card_number_validator.rb
|
96
97
|
- lib/credit_card_validations.rb
|
97
98
|
- lib/credit_card_validations/detector.rb
|
99
|
+
- lib/credit_card_validations/error.rb
|
98
100
|
- lib/credit_card_validations/factory.rb
|
99
101
|
- lib/credit_card_validations/luhn.rb
|
100
102
|
- lib/credit_card_validations/mmi.rb
|
103
|
+
- lib/credit_card_validations/plugins/diners_us.rb
|
104
|
+
- lib/credit_card_validations/plugins/en_route.rb
|
105
|
+
- lib/credit_card_validations/plugins/laser.rb
|
101
106
|
- lib/credit_card_validations/string.rb
|
102
107
|
- lib/credit_card_validations/version.rb
|
103
108
|
- lib/data/brands.yaml
|
@@ -129,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
134
|
version: '0'
|
130
135
|
requirements: []
|
131
136
|
rubyforge_project:
|
132
|
-
rubygems_version: 2.
|
137
|
+
rubygems_version: 2.4.6
|
133
138
|
signing_key:
|
134
139
|
specification_version: 4
|
135
140
|
summary: gem should be used for credit card numbers validation, card brands detections,
|