cw_credit_card_validations 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'ActiveModel Validator' do
4
+
5
+ let(:model) { CreditCard.new }
6
+
7
+ describe 'Proc support' do
8
+ it 'should be valid if brands from proc valid' do
9
+ card = model.dup
10
+ card.card_type = 'Master Card'
11
+ card.number6 = CreditCardValidations::Factory.random(:visa)
12
+ card.valid?.must_equal false
13
+ card.number6 = CreditCardValidations::Factory.random(:mastercard)
14
+ card.valid?.must_equal true
15
+ end
16
+ end
17
+
18
+ describe 'Any Brand' do
19
+ it 'should be valid for all prepared valid numbers' do
20
+ VALID_NUMBERS.each do |_, numbers|
21
+ numbers.each do |number|
22
+ card = model
23
+ card.number4 = number
24
+ card.number5 = number
25
+ card.valid?.must_equal true
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'Except Amex and Maestro brand' do
32
+ it 'should reject all other valid numbers' do
33
+ VALID_NUMBERS.except(:amex, :maestro).each do |_, numbers|
34
+ card = model
35
+ card.number = numbers.first
36
+ card.valid?.must_equal false
37
+ card.errors[:number].include?(card.errors.generate_message(:number, :invalid)).must_equal true
38
+ end
39
+ end
40
+
41
+ it 'should accept using except options' do
42
+ VALID_NUMBERS.except(:amex, :maestro).each do |_, numbers|
43
+ card = model
44
+ card.number3 = numbers.first
45
+ card.valid?.must_equal true
46
+ end
47
+ end
48
+ end
49
+
50
+ describe 'Only Amex and Mestro brands' do
51
+ it 'should accept amex and maestro brand if valid' do
52
+ VALID_NUMBERS.slice(:amex, :maestro).each do |_, numbers|
53
+ card = model
54
+ card.number = numbers.first
55
+ card.number2 = numbers.first
56
+ card.valid?.must_equal true
57
+ end
58
+ end
59
+ end
60
+
61
+ describe 'Custom error message' do
62
+ it 'should allow custom message' do
63
+ card = model
64
+ card.number7 = 'wrong'
65
+ card.valid?.must_equal false
66
+ card.errors[:number7].must_equal ['Custom message']
67
+ end
68
+ end
69
+
70
+ end
@@ -0,0 +1,175 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe CreditCardValidations do
4
+
5
+
6
+ before do
7
+ CreditCardValidations.reload!
8
+ end
9
+
10
+ describe 'MMI' do
11
+ it 'should detect issuer category' do
12
+ d = detector(VALID_NUMBERS[:visa].first)
13
+ d.issuer_category.must_equal CreditCardValidations::Mmi::ISSUER_CATEGORIES[d.number[0]]
14
+ end
15
+ end
16
+
17
+ describe 'Luhn#valid?' do
18
+ let(:card_detector) {
19
+ detector(VALID_NUMBERS[:unionpay].first)
20
+ }
21
+ it 'should call Luhn.valid? once' do
22
+ CreditCardValidations::Luhn.expects(:valid?).with(card_detector.number).once
23
+ card_detector.valid?(:visa, :unionpay).must_equal true
24
+ end
25
+
26
+ it 'should call Luhn.valid? twice' do
27
+ CreditCardValidations::Luhn.expects(:valid?).with(card_detector.number).twice
28
+ card_detector.valid?(:visa, :mastercard).must_equal false
29
+ end
30
+
31
+ it 'should not call Luhn.valid?' do
32
+ CreditCardValidations::Luhn.expects(:valid?).never
33
+ card_detector.valid?(:unionpay).must_equal true
34
+ end
35
+
36
+ end
37
+
38
+
39
+ it 'should check luhn' do
40
+ VALID_NUMBERS.each do |brand, card_numbers|
41
+ if has_luhn_check_rule?(brand)
42
+ card_numbers.each do |number|
43
+ luhn_valid?(detector(number).number).must_equal true
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ it 'should check valid brand' do
50
+ VALID_NUMBERS.each do |brand, card_numbers|
51
+ card_numbers.each do |card_number|
52
+ detector(card_number).send("#{brand}?").must_equal true
53
+ detector(card_number).brand.must_equal brand
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'should check if card invalid' do
59
+ INVALID_NUMBERS.each do |card_number|
60
+ detector(card_number).valid?.must_equal false
61
+ detector(card_number).brand.must_be_nil
62
+ VALID_NUMBERS.keys.each do |brand|
63
+ detector(card_number).send("#{brand}?").must_equal false
64
+ end
65
+ end
66
+ end
67
+
68
+ it 'should detect by full brand name' do
69
+ amex = CreditCardValidations::Factory.random(:amex)
70
+ detector(amex).valid?('American Express').must_equal true
71
+ visa = CreditCardValidations::Factory.random(:visa)
72
+ detector(visa).valid?('American Express').must_equal false
73
+ end
74
+
75
+ it 'should support multiple brands for single check' do
76
+ VALID_NUMBERS.slice(:visa, :mastercard).each do |key, value|
77
+ detector(value.first).brand(:visa, :mastercard).must_equal key
78
+ end
79
+
80
+ VALID_NUMBERS.except(:visa, :mastercard).each do |_, value|
81
+ detector(value.first).brand(:visa, :mastercard).must_be_nil
82
+ end
83
+ end
84
+
85
+ it 'should check if valid brand without arguments' do
86
+ VALID_NUMBERS.each do |key, value|
87
+ value.each do |card_number|
88
+ detector(card_number).valid?(key).must_equal true
89
+ assert detector(card_number).valid?.must_equal true
90
+ end
91
+ end
92
+ end
93
+
94
+ it 'should not be valid? if wrong brand' do
95
+ detector(VALID_NUMBERS[:visa].first).valid?(:mastercard).must_equal false
96
+ detector(VALID_NUMBERS[:mastercard].first).valid?(:visa).must_equal false
97
+ end
98
+
99
+ it 'should be valid? if right brand' do
100
+ detector(VALID_NUMBERS[:visa].first).valid?(:mastercard, :visa).must_equal true
101
+ detector(VALID_NUMBERS[:visa].first).valid?(:mastercard, :amex).must_equal false
102
+ end
103
+
104
+
105
+ describe 'adding/removing brand' do
106
+
107
+ describe 'adding rules' do
108
+
109
+ let(:voyager_number) { '869926275400212' }
110
+
111
+ it 'should validate number as voyager' do
112
+ CreditCardValidations::Detector.add_brand(:voyager, length: 15, prefixes: '86')
113
+ detector(voyager_number).valid?(:voyager).must_equal true
114
+ detector(voyager_number).voyager?.must_equal true
115
+ detector(voyager_number).brand.must_equal :voyager
116
+ end
117
+
118
+ describe 'Add voyager rule' do
119
+ before do
120
+ CreditCardValidations::Detector.add_brand(:voyager, length: 15, prefixes: '86')
121
+ end
122
+
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
127
+ end
128
+
129
+ describe 'Remove voyager rule' do
130
+ before do
131
+ CreditCardValidations::Detector.delete_brand(:voyager)
132
+ end
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
141
+
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
155
+ end
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
161
+ end
162
+
163
+ def luhn_valid?(number)
164
+ CreditCardValidations::Luhn.valid?(number)
165
+ end
166
+
167
+ def detector(number)
168
+ CreditCardValidations::Detector.new(number)
169
+ end
170
+
171
+ def has_luhn_check_rule?(key)
172
+ CreditCardValidations::Detector.has_luhn_check_rule?(key)
173
+ end
174
+
175
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe CreditCardValidations::Factory do
4
+
5
+ it 'should generate random brand' do
6
+ number = CreditCardValidations::Factory.random
7
+ CreditCardValidations::Detector.new(number).valid?.must_equal true
8
+ end
9
+
10
+ CreditCardValidations::Detector.brands.keys.sort.each do |key|
11
+ describe "#{key}" do
12
+ it "should generate valid #{key}" do
13
+ number = CreditCardValidations::Factory.random(key)
14
+ CreditCardValidations::Detector.new(number).valid?(key).must_equal true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ ---
2
+ - '1111111111111111'
3
+ - '00000000000000'
4
+ - fakenumber
5
+ - c4111111111111111
6
+ - 4111111111111111i
@@ -0,0 +1,119 @@
1
+ ---
2
+ :visa:
3
+ - 4012 8888 8888 1881
4
+ - 4111 1111 1111 1111
5
+ - 4222 2222 2222 2
6
+ - 4917 6100 0000 0000
7
+ :mastercard:
8
+ - 5274 5763 9425 9961
9
+ - 5555 5555 5555 4444
10
+ - 5105 1051 0510 5100
11
+ - 2720 1700 0000 0006
12
+ - 2223 4800 0000 0001
13
+ - 2223 0400 0000 0003
14
+ - 2223 0700 0000 0000
15
+ - 2223 2700 0000 0006
16
+ - 2720 3500 0000 0004
17
+ - 2223 1000 0000 0005
18
+ - 2720 0500 0000 0000
19
+ :diners:
20
+ - 3020 4169 3226 43
21
+ - 3021 8047 1965 57
22
+ - 3022 1511 5632 52
23
+ - 3600 0000 0000 08
24
+ - 3614 8900 6479 13
25
+ - 3670 0102 0000 00
26
+ - 3852 0000 0232 37
27
+ - 3056 9309 0259 04
28
+ - 3020 4169 3226 43
29
+ :amex:
30
+ - 3714 4963 5398 431
31
+ - 3787 3449 3671 000
32
+ - 3400 0000 0000 009
33
+ - 3411 1111 1111 111
34
+ - 3434 3434 3434 343
35
+ - 3468 2763 0435 344
36
+ - 3700 0000 0000 002
37
+ - 3700 0020 0000 000
38
+ - 3704 0726 9909 809
39
+ - 3705 5601 9309 221
40
+ - 3714 4963 5398 431
41
+ - 3742 0000 0000 004
42
+ - 3764 6228 0921 451
43
+ - 3777 5274 9896 404
44
+ - 3782 8224 6310 005
45
+ :discover:
46
+ - 6011 1111 1111 1117
47
+ - 6011 0009 9013 9424
48
+ - 6011 0000 0000 0004
49
+ - 6011 0004 0000 0000
50
+ - 6011 1532 1637 1980
51
+ - 6011 6011 6011 6611
52
+ - 6011 6874 8256 4166
53
+ - 6011 8148 3690 5651
54
+ :maestro:
55
+ - 6759 6498 2643 8453
56
+ - 5641 8200 0000 0005
57
+ - 5033 9619 8909 17
58
+ - 5868 2416 0825 5333 38
59
+ - 6799 9901 0000 0000 019
60
+ - 6390 0200 0000 000003
61
+ - 6304 9506 0000 0000 00
62
+ - 6304 9000 1774 0292 441
63
+ :jcb:
64
+ - 3575 7591 5225 4876
65
+ - 3566 0020 2036 0505
66
+ - 1800 0163 8277 392
67
+ - 3569 9900 0000 0009
68
+ - 3530 1113 3330 0000
69
+ - 3572 6600 0000 0000 006
70
+ :solo:
71
+ - 6767 6222 2222 2222 222
72
+ - 6334 5805 0000 0000
73
+ - 6334 9000 0000 0005
74
+ - 6334 7306 0000 0000 00
75
+ - 6767 6767 6767 6767 671
76
+ :unionpay:
77
+ - 6264 1852 1292 2132 067
78
+ - 6288 9977 1545 2584
79
+ - 6269 9920 5813 4322
80
+ :dankort:
81
+ - 5019 7170 1010 3742
82
+ :switch:
83
+ - 6331 1019 9999 0016
84
+ :rupay:
85
+ - 6076 6000 0619 9992
86
+ - 6070 5500 5000 0047
87
+ :hipercard:
88
+ - 3841 0058 9908 8180 330
89
+ :elo:
90
+ - '4011 7841 3850 9070'
91
+ - '4389 3555 4728 7502'
92
+ - '4573 9320 5642 0699'
93
+ - '4576 3198 7564 9522'
94
+ - '5041 7572 2687 1008'
95
+ - '5066 9917 1703 9876'
96
+ - '5067 5391 6526 0388'
97
+ - '5090 4071 4078 7707'
98
+ - '5090 4270 1119 7080'
99
+ - '5090 4344 4788 5021'
100
+ - '5090 4514 6675 8555'
101
+ - '5090 4673 1437 9707'
102
+ - '5090 4791 2220 0924'
103
+ - '5090 4854 1570 5059'
104
+ - '5090 4968 1280 8652'
105
+ - '5090 5097 0678 9193'
106
+ - '5090 5157 9762 1083'
107
+ - '5090 5225 6947 6964'
108
+ - '5090 6473 8030 4070'
109
+ - '5090 6644 0324 2820'
110
+ - '5090 6724 8089 9317'
111
+ - '5090 6888 2173 4488'
112
+ - '5090 6948 3784 4758'
113
+ - '5090 7463 8779 6948'
114
+ - '6362 9745 2190 7765'
115
+ - '6363 6850 2897 2643'
116
+ - '6504 9799 9991 0279'
117
+ - '6516 5299 9991 0328'
118
+ :mir:
119
+ - 2202 1234 1234 1234
@@ -0,0 +1,19 @@
1
+ class CreditCard
2
+ attr_accessor :number, :number2, :number3, :number4, :number5, :number6, :number7, :card_type
3
+ include ActiveModel::Validations
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
+
12
+ def supported_brand
13
+ {
14
+ 'Master Card' => :mastercard,
15
+ 'Visa' => :visa
16
+ }[self.card_type]
17
+ end
18
+
19
+ end
@@ -0,0 +1,32 @@
1
+ require_relative 'test_helper'
2
+ require 'credit_card_validations/string'
3
+
4
+ describe 'String ext' do
5
+
6
+ let(:mastercard) { CreditCardValidations::Factory.random(:mastercard) }
7
+ let(:visa) { CreditCardValidations::Factory.random(:visa) }
8
+ let(:invalid) { INVALID_NUMBERS.sample }
9
+
10
+ it 'should allow detect brand for mastercard' do
11
+ mastercard.credit_card_brand.must_equal :mastercard
12
+ mastercard.credit_card_brand_name.must_equal 'MasterCard'
13
+ mastercard.valid_credit_card_brand?(:mastercard).must_equal true
14
+ mastercard.valid_credit_card_brand?('MasterCard').must_equal true
15
+ mastercard.valid_credit_card_brand?(:visa, :amex).must_equal false
16
+ end
17
+
18
+ it 'should allow detect brand for visa' do
19
+ visa.credit_card_brand.must_equal :visa
20
+ visa.credit_card_brand_name.must_equal 'Visa'
21
+ visa.valid_credit_card_brand?(:mastercard).must_equal false
22
+ visa.valid_credit_card_brand?(:visa, :amex).must_equal true
23
+ end
24
+
25
+ it 'should not allow detect brand for invalid card' do
26
+ invalid.credit_card_brand.must_be_nil
27
+ invalid.credit_card_brand_name.must_be_nil
28
+ invalid.valid_credit_card_brand?(:mastercard).must_equal false
29
+ invalid.valid_credit_card_brand?(:visa, :amex).must_equal false
30
+ end
31
+
32
+ end