credit_card_validations 2.0.2 → 3.0.0
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 +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,
|