cw_credit_card_validations 3.4.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.
@@ -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