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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2689b8821fe1f2cc878b2f2892add1b614eb0df59d70d210cd7d38c035518f1
4
- data.tar.gz: 94ec43eb585924cc3aeb51f0ad4a8aab0b301f8adca2fcfd9c2aec532328e52a
3
+ metadata.gz: a6703223e8cb869c369a0fb982517c22f3e157048df0369f126bce3b2f87e5bc
4
+ data.tar.gz: c8035625c31262714bd1a2dee7f63c97de510835046aed54aabe5590d37e04cd
5
5
  SHA512:
6
- metadata.gz: 9b26efbd2f9c6a9b688a68fdcac2eb06955b6676d0306752f5a3a9cd87ae4dba374c27e7298a088627df4d6b3ee1a16e0a60865bb353b919366d90de01e53dff
7
- data.tar.gz: 39965b3ca89a8cba176ef471aeff6c388e90f6ceeffb6a4494a575b784bbb2d1ef474b94ca59e50fce2b053f8b060025b08fffbb1f73b78a7c4c5a0f3e640372
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
@@ -0,0 +1,5 @@
1
+ FROM ruby:2.7.6
2
+
3
+ RUN apt-get update && apt-get install -y vim
4
+
5
+ WORKDIR /usr/src/app
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
3
+
4
+ gemspec
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
@@ -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
@@ -0,0 +1,5 @@
1
+ services:
2
+ web:
3
+ build: .
4
+ volumes:
5
+ - .:/usr/src/app
@@ -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
@@ -2,6 +2,5 @@
2
2
 
3
3
  require 'cns_brazil/cns'
4
4
  require 'cns_brazil/cns_validator'
5
- require 'cns_brazil/generator'
6
5
 
7
6
  require 'cns_brazil/validate_cns_matcher' if defined?(::Shoulda)
@@ -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,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserAllowBlank
4
+ include ActiveModel::Model
5
+
6
+ attr_accessor :cns, :name
7
+
8
+ validates :cns, '::CnsBrazil::Cns': true, allow_blank: true
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserCnsRequired
4
+ include ActiveModel::Model
5
+
6
+ attr_accessor :cns
7
+
8
+ validates :cns, '::CnsBrazil::Cns': true
9
+ 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
@@ -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.3
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-10 00:00:00.000000000 Z
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