cns_brazil 1.0.3 → 1.0.4
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/.gitignore +1 -0
- data/.rubocop.yml +21 -0
- data/.ruby-version +1 -0
- data/Dockerfile +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +72 -0
- data/LICENSE.md +20 -0
- data/README.md +87 -0
- data/cns_brazil.gemspec +22 -0
- data/docker-compose.yml +5 -0
- data/lib/cns_brazil/cns.rb +55 -0
- data/lib/cns_brazil/cns_validator.rb +14 -0
- data/lib/cns_brazil/generator.rb +60 -0
- data/lib/cns_brazil/validate_cns_matcher.rb +54 -0
- data/lib/cns_brazil.rb +0 -1
- data/spec/cns_brazil/cns_spec.rb +189 -0
- data/spec/cns_brazil/cns_validator_spec.rb +284 -0
- data/spec/cns_brazil/generator_spec.rb +32 -0
- data/spec/faker/user_allow_blank.rb +9 -0
- data/spec/faker/user_cns_required.rb +9 -0
- data/spec/shoulda/matchers/active_model/validate_cns_matcher_spec.rb +20 -0
- data/spec/spec_helper.rb +12 -0
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6703223e8cb869c369a0fb982517c22f3e157048df0369f126bce3b2f87e5bc
|
4
|
+
data.tar.gz: c8035625c31262714bd1a2dee7f63c97de510835046aed54aabe5590d37e04cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b2b448cbe111b04dcb7db6de39ed227baaf127b4e9a1bc15242c9f8f7db846029e282ef7e8f77ef896a8ef6e0ca8dabee3830ed1ec4a2411152e35baae74512
|
7
|
+
data.tar.gz: 29f0c8ea12d0f4d2b52b7b30ea55741f8f4b57255449e3b344df04d1097d220c9850d16dbde913f15a17cfc0573507e8cd5039175ef9948ea0d283ac8ade68c0
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
TargetRubyVersion: 2.7.6
|
4
|
+
Exclude:
|
5
|
+
- 'cns_brazil.gemspec'
|
6
|
+
- 'Gemfile'
|
7
|
+
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Max: 17
|
10
|
+
|
11
|
+
Metrics/BlockLength:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Metrics/LineLength:
|
15
|
+
Max: 150
|
16
|
+
|
17
|
+
Metrics/MethodLength:
|
18
|
+
Max: 25
|
19
|
+
|
20
|
+
Style/Documentation:
|
21
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.6
|
data/Dockerfile
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cns_brazil (1.0.4)
|
5
|
+
activemodel (= 7.0.4)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (7.0.4)
|
11
|
+
activesupport (= 7.0.4)
|
12
|
+
activesupport (7.0.4)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 1.6, < 2)
|
15
|
+
minitest (>= 5.1)
|
16
|
+
tzinfo (~> 2.0)
|
17
|
+
ast (2.4.2)
|
18
|
+
concurrent-ruby (1.1.10)
|
19
|
+
diff-lcs (1.5.0)
|
20
|
+
i18n (1.12.0)
|
21
|
+
concurrent-ruby (~> 1.0)
|
22
|
+
json (2.6.2)
|
23
|
+
minitest (5.16.3)
|
24
|
+
parallel (1.22.1)
|
25
|
+
parser (3.1.2.1)
|
26
|
+
ast (~> 2.4.1)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
regexp_parser (2.6.0)
|
29
|
+
rexml (3.2.5)
|
30
|
+
rspec (3.12.0)
|
31
|
+
rspec-core (~> 3.12.0)
|
32
|
+
rspec-expectations (~> 3.12.0)
|
33
|
+
rspec-mocks (~> 3.12.0)
|
34
|
+
rspec-core (3.12.0)
|
35
|
+
rspec-support (~> 3.12.0)
|
36
|
+
rspec-expectations (3.12.0)
|
37
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
+
rspec-support (~> 3.12.0)
|
39
|
+
rspec-mocks (3.12.0)
|
40
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
41
|
+
rspec-support (~> 3.12.0)
|
42
|
+
rspec-support (3.12.0)
|
43
|
+
rubocop (1.38.0)
|
44
|
+
json (~> 2.3)
|
45
|
+
parallel (~> 1.10)
|
46
|
+
parser (>= 3.1.2.1)
|
47
|
+
rainbow (>= 2.2.2, < 4.0)
|
48
|
+
regexp_parser (>= 1.8, < 3.0)
|
49
|
+
rexml (>= 3.2.5, < 4.0)
|
50
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
51
|
+
ruby-progressbar (~> 1.7)
|
52
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
53
|
+
rubocop-ast (1.23.0)
|
54
|
+
parser (>= 3.1.1.0)
|
55
|
+
ruby-progressbar (1.11.0)
|
56
|
+
shoulda-matchers (5.2.0)
|
57
|
+
activesupport (>= 5.2.0)
|
58
|
+
tzinfo (2.0.5)
|
59
|
+
concurrent-ruby (~> 1.0)
|
60
|
+
unicode-display_width (2.3.0)
|
61
|
+
|
62
|
+
PLATFORMS
|
63
|
+
ruby
|
64
|
+
|
65
|
+
DEPENDENCIES
|
66
|
+
cns_brazil!
|
67
|
+
rspec (= 3.12.0)
|
68
|
+
rubocop (= 1.38.0)
|
69
|
+
shoulda-matchers (= 5.2.0)
|
70
|
+
|
71
|
+
BUNDLED WITH
|
72
|
+
2.1.4
|
data/LICENSE.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
'Software'), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# CNS Brazil
|
2
|
+
- Is a validator and generator based in algorithm from https://integracao.esusab.ufsc.br/v211/docs/algoritmo_CNS.html
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
### Installing
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
gem 'cns_brazil'
|
9
|
+
|
10
|
+
And then execute:
|
11
|
+
|
12
|
+
$ bundle
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install cns_brazil
|
17
|
+
|
18
|
+
### Validator
|
19
|
+
#### ActiveRecord
|
20
|
+
|
21
|
+
- Just use as any other validator:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
validates :cns, '::CnsBrazil::Cns': true
|
26
|
+
end
|
27
|
+
```
|
28
|
+
- Use with anny column name
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
class User < ActiveRecord::Base
|
32
|
+
validates :my_cns, '::CnsBrazil::Cns': true
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
- Allow blank value
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
class User < ActiveRecord::Base
|
40
|
+
validates :cns, '::CnsBrazil::Cns': true, allow_blank: true
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
#### Elsewhere
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
require "cns_brazil"
|
48
|
+
|
49
|
+
cns_validator = CnsBrazil::Cns.new(value: '1234567891234516')
|
50
|
+
|
51
|
+
cns_validator.valid? # true || false
|
52
|
+
```
|
53
|
+
|
54
|
+
### Generator
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require "cns_brazil"
|
58
|
+
|
59
|
+
CnsBrazil::Cns.generate # returns a valida CNS
|
60
|
+
```
|
61
|
+
|
62
|
+
### Test
|
63
|
+
|
64
|
+
Use in your tests:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
specify { is_expected.to validate_cns } # It will test the attribute :cns by default
|
68
|
+
specify { is_expected.to validate_cns(:my_cns) }
|
69
|
+
```
|
70
|
+
With blank value
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
specify { is_expected.to validate_cns.allow_blank }
|
74
|
+
specify { is_expected.to validate_cns(:my_cns).allow_blank }
|
75
|
+
```
|
76
|
+
|
77
|
+
## Contributing
|
78
|
+
|
79
|
+
- Run using Docker: `docker-compose run web bash`
|
80
|
+
- In bash Run: `bundle install`
|
81
|
+
- Run spec: `spec`
|
82
|
+
|
83
|
+
1. Fork it
|
84
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
85
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
86
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
87
|
+
5. Create new Pull Request
|
data/cns_brazil.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'cns_brazil'
|
3
|
+
s.version = '1.0.4'
|
4
|
+
s.summary = 'Validate CNS (Cartão Nacional de Saúde)'
|
5
|
+
s.description = 'CNS is a national health card from Brazil'
|
6
|
+
s.authors = ['Horecio Araujo Dias']
|
7
|
+
s.email = 'horecio@gmail.com'
|
8
|
+
|
9
|
+
s.files = `git ls-files`.split("\n")
|
10
|
+
s.test_files = `git ls-files -- {test,spec,features,examples,gemfiles}/*`.split("\n")
|
11
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
12
|
+
s.require_paths = %w[lib]
|
13
|
+
|
14
|
+
s.homepage = 'https://github.com/HDias/CnsBrazil'
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.add_development_dependency 'rspec', '3.12.0'
|
18
|
+
s.add_development_dependency 'rubocop', '1.38.0'
|
19
|
+
s.add_development_dependency 'shoulda-matchers', '5.2.0'
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'activemodel', '7.0.4'
|
22
|
+
end
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CnsBrazil
|
4
|
+
class Cns
|
5
|
+
def initialize(value:)
|
6
|
+
@value = value.to_s.gsub(/[^\d]/, '')
|
7
|
+
end
|
8
|
+
|
9
|
+
def valid?
|
10
|
+
return false if @value.length != 15
|
11
|
+
|
12
|
+
return start_with_1_or_2? if %w[1 2].include?(@value[0])
|
13
|
+
return start_with_7_8_or_9? if %w[7 8 9].include?(@value[0])
|
14
|
+
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.generate
|
19
|
+
generator = CnsBrazil::Generator.new
|
20
|
+
|
21
|
+
generator.call
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def start_with_1_or_2?
|
27
|
+
pis = @value[0, 11]
|
28
|
+
|
29
|
+
sum_result = sum_result(pis)
|
30
|
+
|
31
|
+
rest = sum_result % 11
|
32
|
+
verificator_digit = rest.zero? ? 0 : 11 - rest
|
33
|
+
result = verificator_digit == 10 ? "#{pis}001#{11 - ((sum_result + 2) % 11)}" : "#{pis}000#{verificator_digit}"
|
34
|
+
|
35
|
+
result == @value
|
36
|
+
end
|
37
|
+
|
38
|
+
def start_with_7_8_or_9?
|
39
|
+
sum_result = sum_result(@value)
|
40
|
+
|
41
|
+
rest = sum_result % 11
|
42
|
+
|
43
|
+
rest.zero?
|
44
|
+
end
|
45
|
+
|
46
|
+
def sum_result(value)
|
47
|
+
cns_to_array = value.chars.map(&:to_i)
|
48
|
+
|
49
|
+
cns_to_array.each_with_index.reduce(0) do |sum, (element, index)|
|
50
|
+
sum += element * (15 - index)
|
51
|
+
sum
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_model'
|
3
|
+
|
4
|
+
module CnsBrazil
|
5
|
+
class CnsValidator < ::ActiveModel::EachValidator
|
6
|
+
def validate_each(record, attribute, value)
|
7
|
+
return true if options[:allow_blank] && value.blank?
|
8
|
+
|
9
|
+
cns = CnsBrazil::Cns.new(value: value)
|
10
|
+
|
11
|
+
record.errors.add(attribute, (options[:message] || 'is not an cns')) unless cns.valid?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CnsBrazil
|
4
|
+
class Generator
|
5
|
+
def call
|
6
|
+
result = generate
|
7
|
+
|
8
|
+
result = generate while result.to_s.length != 15
|
9
|
+
|
10
|
+
result
|
11
|
+
end
|
12
|
+
|
13
|
+
def block
|
14
|
+
first_number.to_s + block_number + block_number
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# first number should be 1,2,7,8 or 9
|
20
|
+
def first_number
|
21
|
+
range_value = []
|
22
|
+
range_value << rand(1..2)
|
23
|
+
range_value << rand(7..9)
|
24
|
+
|
25
|
+
range_value.sample
|
26
|
+
end
|
27
|
+
|
28
|
+
def block_number
|
29
|
+
"0#{rand(11_111..99_999).to_s.chop}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate
|
33
|
+
cns = block
|
34
|
+
rest = sum_result(cns) % 11
|
35
|
+
verificator_digit = rest.zero? ? 0 : 11 - rest
|
36
|
+
|
37
|
+
if verificator_digit == 10
|
38
|
+
sum_result = sum_result(cns)
|
39
|
+
sum_result += 2
|
40
|
+
|
41
|
+
resto = sum_result % 11
|
42
|
+
verificator_digit = 11 - resto
|
43
|
+
cns += "001#{verificator_digit}"
|
44
|
+
else
|
45
|
+
cns += "000#{verificator_digit}"
|
46
|
+
end
|
47
|
+
|
48
|
+
cns
|
49
|
+
end
|
50
|
+
|
51
|
+
def sum_result(cns)
|
52
|
+
cns_to_array = cns.chars.map(&:to_i)
|
53
|
+
|
54
|
+
cns_to_array.each_with_index.reduce(0) do |sum, (element, index)|
|
55
|
+
sum += element * (15 - index)
|
56
|
+
sum
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'shoulda-matchers'
|
4
|
+
|
5
|
+
module Shoulda
|
6
|
+
module Matchers
|
7
|
+
module ActiveModel
|
8
|
+
def validate_cns(attr = :cns)
|
9
|
+
ValidateCnsMatcher.new(attr)
|
10
|
+
end
|
11
|
+
|
12
|
+
class ValidateCnsMatcher < ValidationMatcher
|
13
|
+
ALLOW_VALUES = [
|
14
|
+
'166947669770008',
|
15
|
+
222_491_445_220_008,
|
16
|
+
'736 3347 8546 0000',
|
17
|
+
'807769250350009',
|
18
|
+
954_180_214_890_002
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
DISALLOW_VALUES = %w[12345678912314 1234567891234516].freeze
|
22
|
+
|
23
|
+
def initialize(attribute)
|
24
|
+
super(attribute)
|
25
|
+
@options = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def description
|
29
|
+
message = 'requires a valid CNS'
|
30
|
+
|
31
|
+
message += ' included blank' if expects_to_allow_blank?
|
32
|
+
|
33
|
+
message
|
34
|
+
end
|
35
|
+
|
36
|
+
def failure_message
|
37
|
+
'does not require a valid CNS'
|
38
|
+
end
|
39
|
+
|
40
|
+
def matches?(subject)
|
41
|
+
super(subject)
|
42
|
+
|
43
|
+
ALLOW_VALUES.each { |value| allows_value_of(value) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def does_not_match?(subject)
|
47
|
+
super(subject)
|
48
|
+
|
49
|
+
DISALLOW_VALUES.each { |value| disallows_value_of(value) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/cns_brazil.rb
CHANGED
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CnsBrazil::Cns do
|
6
|
+
describe '.generate' do
|
7
|
+
it 'be valid 15 times' do
|
8
|
+
15.times do
|
9
|
+
cns = described_class.generate
|
10
|
+
validator = described_class.new(value: cns)
|
11
|
+
|
12
|
+
expect(validator).to be_valid
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.valid?' do
|
18
|
+
context 'When value has length 14' do
|
19
|
+
specify do
|
20
|
+
value = '12345678912314'
|
21
|
+
cns_obj = described_class.new(value: value)
|
22
|
+
|
23
|
+
expect(value.length).to eq(14)
|
24
|
+
expect(cns_obj).to_not be_valid
|
25
|
+
end
|
26
|
+
|
27
|
+
specify do
|
28
|
+
value = 12_345_678_912_314
|
29
|
+
cns_obj = described_class.new(value: value)
|
30
|
+
|
31
|
+
expect(value.to_s.length).to eq(14)
|
32
|
+
expect(cns_obj).to_not be_valid
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'When value has length 16' do
|
37
|
+
specify do
|
38
|
+
value = '1234567891234516'
|
39
|
+
cns_obj = described_class.new(value: value)
|
40
|
+
|
41
|
+
expect(value.length).to eq(16)
|
42
|
+
expect(cns_obj).to_not be_valid
|
43
|
+
end
|
44
|
+
|
45
|
+
specify do
|
46
|
+
value = 1_234_567_891_234_516
|
47
|
+
cns_obj = described_class.new(value: value)
|
48
|
+
|
49
|
+
expect(value.to_s.length).to eq(16)
|
50
|
+
expect(cns_obj).to_not be_valid
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'When value begin with 1' do
|
55
|
+
context 'value has length 15' do
|
56
|
+
specify do
|
57
|
+
value = '166947669770008'
|
58
|
+
cns_obj = described_class.new(value: value)
|
59
|
+
|
60
|
+
expect(cns_obj).to be_valid
|
61
|
+
end
|
62
|
+
|
63
|
+
specify do
|
64
|
+
value = 166_947_669_770_008
|
65
|
+
cns_obj = described_class.new(value: value)
|
66
|
+
|
67
|
+
expect(cns_obj).to be_valid
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'value have cns mask' do
|
71
|
+
specify do
|
72
|
+
value = '166 9476 6977 0008'
|
73
|
+
cns_obj = described_class.new(value: value)
|
74
|
+
|
75
|
+
expect(cns_obj).to be_valid
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'When value begin with 2' do
|
82
|
+
context 'value has length 15' do
|
83
|
+
specify do
|
84
|
+
value = '222491445220008'
|
85
|
+
cns_obj = described_class.new(value: value)
|
86
|
+
|
87
|
+
expect(cns_obj).to be_valid
|
88
|
+
end
|
89
|
+
|
90
|
+
specify do
|
91
|
+
value = 222_491_445_220_008
|
92
|
+
cns_obj = described_class.new(value: value)
|
93
|
+
|
94
|
+
expect(cns_obj).to be_valid
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'value have cns mask' do
|
98
|
+
specify do
|
99
|
+
value = '222 4914 4522 0008'
|
100
|
+
cns_obj = described_class.new(value: value)
|
101
|
+
|
102
|
+
expect(cns_obj).to be_valid
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'When value begin with 7' do
|
109
|
+
context 'value has length 15' do
|
110
|
+
specify do
|
111
|
+
value = '736334785460000'
|
112
|
+
cns_obj = described_class.new(value: value)
|
113
|
+
|
114
|
+
expect(cns_obj).to be_valid
|
115
|
+
end
|
116
|
+
|
117
|
+
specify do
|
118
|
+
value = 736_334_785_460_000
|
119
|
+
cns_obj = described_class.new(value: value)
|
120
|
+
|
121
|
+
expect(cns_obj).to be_valid
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'value have cns mask' do
|
125
|
+
specify do
|
126
|
+
value = '736 3347 8546 0000'
|
127
|
+
cns_obj = described_class.new(value: value)
|
128
|
+
|
129
|
+
expect(cns_obj).to be_valid
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'When value begin with 8' do
|
136
|
+
context 'value has length 15' do
|
137
|
+
specify do
|
138
|
+
value = '807769250350009'
|
139
|
+
cns_obj = described_class.new(value: value)
|
140
|
+
|
141
|
+
expect(cns_obj).to be_valid
|
142
|
+
end
|
143
|
+
|
144
|
+
specify do
|
145
|
+
value = 807_769_250_350_009
|
146
|
+
cns_obj = described_class.new(value: value)
|
147
|
+
|
148
|
+
expect(cns_obj).to be_valid
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'value have cns mask' do
|
152
|
+
specify do
|
153
|
+
value = '807 7692 5035 0009'
|
154
|
+
cns_obj = described_class.new(value: value)
|
155
|
+
|
156
|
+
expect(cns_obj).to be_valid
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'When value begin with 9' do
|
163
|
+
context 'value has length 15' do
|
164
|
+
specify do
|
165
|
+
value = '954180214890002'
|
166
|
+
cns_obj = described_class.new(value: value)
|
167
|
+
|
168
|
+
expect(cns_obj).to be_valid
|
169
|
+
end
|
170
|
+
|
171
|
+
specify do
|
172
|
+
value = 954_180_214_890_002
|
173
|
+
cns_obj = described_class.new(value: value)
|
174
|
+
|
175
|
+
expect(cns_obj).to be_valid
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'value have cns mask' do
|
179
|
+
specify do
|
180
|
+
value = '954 1802 1489 0002'
|
181
|
+
cns_obj = described_class.new(value: value)
|
182
|
+
|
183
|
+
expect(cns_obj).to be_valid
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CnsBrazil::CnsValidator do
|
6
|
+
describe '#cns disallow blank' do
|
7
|
+
context 'When value is nil' do
|
8
|
+
specify do
|
9
|
+
value = nil
|
10
|
+
|
11
|
+
user_cns_required = UserCnsRequired.new
|
12
|
+
user_cns_required.cns = value
|
13
|
+
|
14
|
+
expect(user_cns_required).to_not be_valid
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'When value a empty string' do
|
19
|
+
specify do
|
20
|
+
value = ' '
|
21
|
+
|
22
|
+
user_cns_required = UserCnsRequired.new
|
23
|
+
user_cns_required.cns = value
|
24
|
+
|
25
|
+
expect(user_cns_required).to_not be_valid
|
26
|
+
end
|
27
|
+
|
28
|
+
specify do
|
29
|
+
value = ''
|
30
|
+
|
31
|
+
user_cns_required = UserCnsRequired.new
|
32
|
+
user_cns_required.cns = value
|
33
|
+
|
34
|
+
expect(user_cns_required).to_not be_valid
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#cns allow blank' do
|
40
|
+
context 'When value is nil' do
|
41
|
+
specify do
|
42
|
+
value = nil
|
43
|
+
|
44
|
+
user = UserAllowBlank.new
|
45
|
+
user.cns = value
|
46
|
+
|
47
|
+
expect(user).to be_valid
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'When value a empty string' do
|
52
|
+
specify do
|
53
|
+
value = ' '
|
54
|
+
|
55
|
+
user = UserAllowBlank.new
|
56
|
+
user.cns = value
|
57
|
+
|
58
|
+
expect(user).to be_valid
|
59
|
+
end
|
60
|
+
|
61
|
+
specify do
|
62
|
+
value = ''
|
63
|
+
|
64
|
+
user = UserAllowBlank.new
|
65
|
+
user.cns = value
|
66
|
+
|
67
|
+
expect(user).to be_valid
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'When value has length 14' do
|
72
|
+
it 'record is not valid and adds error to attribute' do
|
73
|
+
value = '12345678912314'
|
74
|
+
user = UserAllowBlank.new
|
75
|
+
user.cns = value
|
76
|
+
|
77
|
+
user.valid?
|
78
|
+
|
79
|
+
expect(value.length).to eq(14)
|
80
|
+
expect(user.errors[:cns]).not_to be_empty
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'record is not valid and adds error to attribute' do
|
84
|
+
value = 12_345_678_912_314
|
85
|
+
user = UserAllowBlank.new
|
86
|
+
user.cns = value
|
87
|
+
|
88
|
+
user.valid?
|
89
|
+
|
90
|
+
expect(value.to_s.length).to eq(14)
|
91
|
+
expect(user.errors[:cns]).not_to be_empty
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'When value has length 16' do
|
96
|
+
it 'record is not valid and adds error to attribute' do
|
97
|
+
value = '1234567891234516'
|
98
|
+
user = UserAllowBlank.new
|
99
|
+
user.cns = value
|
100
|
+
|
101
|
+
user.valid?
|
102
|
+
|
103
|
+
expect(value.length).to eq(16)
|
104
|
+
expect(user.errors[:cns]).not_to be_empty
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'record is not valid and adds error to attribute' do
|
108
|
+
value = 1_234_567_891_234_516
|
109
|
+
user = UserAllowBlank.new
|
110
|
+
user.cns = value
|
111
|
+
|
112
|
+
user.valid?
|
113
|
+
|
114
|
+
expect(value.to_s.length).to eq(16)
|
115
|
+
expect(user.errors[:cns]).not_to be_empty
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'When value begin with 1' do
|
120
|
+
context 'value has length 15' do
|
121
|
+
specify do
|
122
|
+
value = '166947669770008'
|
123
|
+
|
124
|
+
user = UserAllowBlank.new
|
125
|
+
user.cns = value
|
126
|
+
|
127
|
+
expect(user).to be_valid
|
128
|
+
end
|
129
|
+
|
130
|
+
specify do
|
131
|
+
value = 166_947_669_770_008
|
132
|
+
|
133
|
+
user = UserAllowBlank.new
|
134
|
+
user.cns = value
|
135
|
+
|
136
|
+
expect(user).to be_valid
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'value have cns mask' do
|
140
|
+
specify do
|
141
|
+
value = '166 9476 6977 0008'
|
142
|
+
|
143
|
+
user = UserAllowBlank.new
|
144
|
+
user.cns = value
|
145
|
+
|
146
|
+
expect(user).to be_valid
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'When value begin with 2' do
|
153
|
+
context 'value has length 15' do
|
154
|
+
specify do
|
155
|
+
value = '222491445220008'
|
156
|
+
|
157
|
+
user = UserAllowBlank.new
|
158
|
+
user.cns = value
|
159
|
+
|
160
|
+
expect(user).to be_valid
|
161
|
+
end
|
162
|
+
|
163
|
+
specify do
|
164
|
+
value = 222_491_445_220_008
|
165
|
+
|
166
|
+
user = UserAllowBlank.new
|
167
|
+
user.cns = value
|
168
|
+
|
169
|
+
expect(user).to be_valid
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'value have cns mask' do
|
173
|
+
specify do
|
174
|
+
value = '222 4914 4522 0008'
|
175
|
+
|
176
|
+
user = UserAllowBlank.new
|
177
|
+
user.cns = value
|
178
|
+
|
179
|
+
expect(user).to be_valid
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'When value begin with 7' do
|
186
|
+
context 'value has length 15' do
|
187
|
+
specify do
|
188
|
+
value = '736334785460000'
|
189
|
+
|
190
|
+
user = UserAllowBlank.new
|
191
|
+
user.cns = value
|
192
|
+
|
193
|
+
expect(user).to be_valid
|
194
|
+
end
|
195
|
+
|
196
|
+
specify do
|
197
|
+
value = 736_334_785_460_000
|
198
|
+
|
199
|
+
user = UserAllowBlank.new
|
200
|
+
user.cns = value
|
201
|
+
|
202
|
+
expect(user).to be_valid
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'value have cns mask' do
|
206
|
+
specify do
|
207
|
+
value = '736 3347 8546 0000'
|
208
|
+
|
209
|
+
user = UserAllowBlank.new
|
210
|
+
user.cns = value
|
211
|
+
|
212
|
+
expect(user).to be_valid
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'When value begin with 8' do
|
219
|
+
context 'value has length 15' do
|
220
|
+
specify do
|
221
|
+
value = '807769250350009'
|
222
|
+
|
223
|
+
user = UserAllowBlank.new
|
224
|
+
user.cns = value
|
225
|
+
|
226
|
+
expect(user).to be_valid
|
227
|
+
end
|
228
|
+
|
229
|
+
specify do
|
230
|
+
value = 807_769_250_350_009
|
231
|
+
|
232
|
+
user = UserAllowBlank.new
|
233
|
+
user.cns = value
|
234
|
+
|
235
|
+
expect(user).to be_valid
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'value have cns mask' do
|
239
|
+
specify do
|
240
|
+
value = '807 7692 5035 0009'
|
241
|
+
|
242
|
+
user = UserAllowBlank.new
|
243
|
+
user.cns = value
|
244
|
+
|
245
|
+
expect(user).to be_valid
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'When value begin with 9' do
|
252
|
+
context 'value has length 15' do
|
253
|
+
specify do
|
254
|
+
value = '954180214890002'
|
255
|
+
|
256
|
+
user = UserAllowBlank.new
|
257
|
+
user.cns = value
|
258
|
+
|
259
|
+
expect(user).to be_valid
|
260
|
+
end
|
261
|
+
|
262
|
+
specify do
|
263
|
+
value = 954_180_214_890_002
|
264
|
+
|
265
|
+
user = UserAllowBlank.new
|
266
|
+
user.cns = value
|
267
|
+
|
268
|
+
expect(user).to be_valid
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'value have cns mask' do
|
272
|
+
specify do
|
273
|
+
value = '954 1802 1489 0002'
|
274
|
+
|
275
|
+
user = UserAllowBlank.new
|
276
|
+
user.cns = value
|
277
|
+
|
278
|
+
expect(user).to be_valid
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CnsBrazil::Generator do
|
6
|
+
describe '.block_number' do
|
7
|
+
it 'expect legth be 11' do
|
8
|
+
generator = described_class.new
|
9
|
+
|
10
|
+
expect(generator.block.length).to eq(11)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.get' do
|
15
|
+
it 'expect legth be 11 15 times' do
|
16
|
+
generator = described_class.new
|
17
|
+
|
18
|
+
15.times { expect(generator.call.length).to eq(15) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.call' do
|
23
|
+
it 'be valid 15 times' do
|
24
|
+
15.times do
|
25
|
+
generator = described_class.new
|
26
|
+
validator = CnsBrazil::Cns.new(value: generator.call)
|
27
|
+
|
28
|
+
expect(validator).to be_valid
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Shoulda::Matchers::ActiveModel::ValidateCnsMatcher do
|
6
|
+
context 'Allow blank' do
|
7
|
+
subject { UserAllowBlank.new }
|
8
|
+
|
9
|
+
specify { is_expected.to validate_cns(:cns).allow_blank }
|
10
|
+
specify { is_expected.to validate_cns.allow_blank }
|
11
|
+
specify { is_expected.not_to validate_cns(:name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'Not allow blank' do
|
15
|
+
subject { UserCnsRequired.new }
|
16
|
+
|
17
|
+
specify { is_expected.to validate_cns(:cns) }
|
18
|
+
specify { is_expected.to validate_cns }
|
19
|
+
end
|
20
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'active_model'
|
5
|
+
require 'shoulda-matchers'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.include Shoulda::Matchers::ActiveModel
|
9
|
+
end
|
10
|
+
|
11
|
+
Dir[File.expand_path('lib/**/*.rb')].sort.each { |f| require f }
|
12
|
+
Dir[File.expand_path('spec/faker/**/*.rb')].sort.each { |f| require f }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cns_brazil
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Horecio Araujo Dias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-11-
|
11
|
+
date: 2022-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -72,7 +72,28 @@ executables: []
|
|
72
72
|
extensions: []
|
73
73
|
extra_rdoc_files: []
|
74
74
|
files:
|
75
|
+
- ".gitignore"
|
76
|
+
- ".rubocop.yml"
|
77
|
+
- ".ruby-version"
|
78
|
+
- Dockerfile
|
79
|
+
- Gemfile
|
80
|
+
- Gemfile.lock
|
81
|
+
- LICENSE.md
|
82
|
+
- README.md
|
83
|
+
- cns_brazil.gemspec
|
84
|
+
- docker-compose.yml
|
75
85
|
- lib/cns_brazil.rb
|
86
|
+
- lib/cns_brazil/cns.rb
|
87
|
+
- lib/cns_brazil/cns_validator.rb
|
88
|
+
- lib/cns_brazil/generator.rb
|
89
|
+
- lib/cns_brazil/validate_cns_matcher.rb
|
90
|
+
- spec/cns_brazil/cns_spec.rb
|
91
|
+
- spec/cns_brazil/cns_validator_spec.rb
|
92
|
+
- spec/cns_brazil/generator_spec.rb
|
93
|
+
- spec/faker/user_allow_blank.rb
|
94
|
+
- spec/faker/user_cns_required.rb
|
95
|
+
- spec/shoulda/matchers/active_model/validate_cns_matcher_spec.rb
|
96
|
+
- spec/spec_helper.rb
|
76
97
|
homepage: https://github.com/HDias/CnsBrazil
|
77
98
|
licenses:
|
78
99
|
- MIT
|