kevintyll-ssn_validator 0.1.1
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.
- data/History.txt +4 -0
- data/Manifest.txt +17 -0
- data/PostInstall.txt +8 -0
- data/README.rdoc +66 -0
- data/Rakefile +25 -0
- data/generators/ssn_validator_migration/ssn_validator_migration_generator.rb +12 -0
- data/generators/ssn_validator_migration/templates/migration.rb +18 -0
- data/lib/ssn_validator/models/ssn_high_group_code.rb +96 -0
- data/lib/ssn_validator/models/ssn_validator.rb +79 -0
- data/lib/ssn_validator.rb +13 -0
- data/lib/tasks/ssn_validator.rake +8 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/test/test_helper.rb +26 -0
- data/test/test_ssn_high_group_code.rb +22 -0
- data/test/test_ssn_validator.rb +65 -0
- metadata +80 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
PostInstall.txt
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
generators/ssn_validator_migration/templates/migration.rb
|
7
|
+
generators/ssn_validator_migration/ssn_validator_migration_generator.rb
|
8
|
+
lib/ssn_validator/models/ssn_high_group_code.rb
|
9
|
+
lib/ssn_validator/models/ssn_validator.rb
|
10
|
+
lib/ssn_validator.rb
|
11
|
+
lib/tasks/ssn_validator.rake
|
12
|
+
script/console
|
13
|
+
script/destroy
|
14
|
+
script/generate
|
15
|
+
test/test_helper.rb
|
16
|
+
test/test_ssn_validator.rb
|
17
|
+
test/test_ssn_high_group_code.rb
|
data/PostInstall.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
For more information on ssn_validator, see http://kevintyll.github.com/ssn_validator/
|
3
|
+
|
4
|
+
* To create the necessary db migration, from the command line, run: script/generate ssn_validator_migration
|
5
|
+
* To load your table with the current SSN data, from the command line, run: rake ssn_validator:update_data
|
6
|
+
* The SSN data is updated monthly, so you'll want to run this rake task monthly to keep your validations accurate.
|
7
|
+
|
8
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
= ssn_validator
|
2
|
+
|
3
|
+
* http://kevintyll.github.com/ssn_validator/
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
A ruby gem that validates whether an SSN has likely been issued or not.
|
8
|
+
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
* Validates the likelyhood that an SSN has been issued to someone.
|
13
|
+
|
14
|
+
* What it cannot do:
|
15
|
+
Validate that an SSN actually belongs to a particular person.
|
16
|
+
|
17
|
+
* What it's planned to do if I can find the data:
|
18
|
+
Determine when an SSN was issued. This can be used to further validate an SSN by comparing it to a Date of Birth.
|
19
|
+
Check the Death Master File if the SSN belongs to a dead person.
|
20
|
+
|
21
|
+
== SYNOPSIS:
|
22
|
+
|
23
|
+
Just instantiate the object with an SSN.
|
24
|
+
ssn = SsnValidator::Ssn.new('123-45-6789')
|
25
|
+
|
26
|
+
Then check if it's valid
|
27
|
+
ssn.valid?
|
28
|
+
|
29
|
+
You can check the errors array to see why it's not valid.
|
30
|
+
ssn.errors
|
31
|
+
|
32
|
+
== REQUIREMENTS:
|
33
|
+
|
34
|
+
* Rails 2.0.0 or greater
|
35
|
+
|
36
|
+
== INSTALL:
|
37
|
+
|
38
|
+
* sudo gem install kevintyll-ssn_validator
|
39
|
+
* To create the necessary db migration, from the command line, run: script/generate ssn_validator_migration
|
40
|
+
* To load your table with the current SSN data, from the command line, run: rake ssn_validator:update_data
|
41
|
+
* The SSN data is updated monthly, so you'll want to run this rake task monthly to keep your validations accurate.
|
42
|
+
|
43
|
+
== LICENSE:
|
44
|
+
|
45
|
+
(The MIT License)
|
46
|
+
|
47
|
+
Copyright (c) 2009 Kevin Tyll
|
48
|
+
|
49
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
50
|
+
a copy of this software and associated documentation files (the
|
51
|
+
'Software'), to deal in the Software without restriction, including
|
52
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
53
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
54
|
+
permit persons to whom the Software is furnished to do so, subject to
|
55
|
+
the following conditions:
|
56
|
+
|
57
|
+
The above copyright notice and this permission notice shall be
|
58
|
+
included in all copies or substantial portions of the Software.
|
59
|
+
|
60
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
61
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
62
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
63
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
64
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
65
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
66
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/ssn_validator'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.new('ssn_validator', SsnValidator::VERSION) do |p|
|
7
|
+
p.developer('Kevin Tyll', 'kevintyll@gmail.com')
|
8
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
+
p.post_install_message = 'PostInstall.txt'
|
10
|
+
p.extra_deps = [
|
11
|
+
['activerecord','>= 2.0.0'],
|
12
|
+
]
|
13
|
+
p.extra_dev_deps = [
|
14
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
15
|
+
]
|
16
|
+
|
17
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
18
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
19
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
20
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
24
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
25
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateSsnValidatorTables < ActiveRecord::Migration
|
2
|
+
|
3
|
+
def self.up
|
4
|
+
create_table :ssn_high_group_codes do |t|
|
5
|
+
t.date :as_of
|
6
|
+
t.string :area
|
7
|
+
t.string :group
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :ssn_high_group_codes, [:area]
|
12
|
+
add_index :ssn_high_group_codes, [:area, :as_of]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :ssn_high_group_codes
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'activerecord'
|
2
|
+
require 'net/http'
|
3
|
+
class SsnHighGroupCode < ActiveRecord::Base
|
4
|
+
|
5
|
+
###############
|
6
|
+
#class mehtods#
|
7
|
+
###############
|
8
|
+
|
9
|
+
def self.load_historical_high_group_codes_file
|
10
|
+
['Jan','Feb','Mar','Apr','May','June','July','Aug','Sept','Oct','Nov','Dec'].each do |month|
|
11
|
+
(1..10).each do |day|
|
12
|
+
string_day = day.to_s
|
13
|
+
string_day.insert(0,'0') if day < 10
|
14
|
+
current_year = Date.today.year
|
15
|
+
#(1932..current_year).each do |year|
|
16
|
+
[2003].each do |year|
|
17
|
+
string_year = year.to_s.last(2)
|
18
|
+
['','corrected'].each do |mod|
|
19
|
+
['ssns','ssnvs'].each do |url_mod|
|
20
|
+
file_name = "HG#{month}#{string_day}#{string_year}#{mod}.txt"
|
21
|
+
text = Net::HTTP.get(URI.parse("http://www.socialsecurity.gov/employer/#{url_mod}/#{file_name}"))
|
22
|
+
puts file_name.inspect
|
23
|
+
puts '@@@@@@@@@ found file_name = ' + file_name.inspect unless text.include? 'File Not Found'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
#Loads the most recent file from http://www.socialsecurity.gov/employer/ssns/highgroup.txt
|
34
|
+
def self.load_current_high_group_codes_file
|
35
|
+
text = Net::HTTP.get(URI.parse('http://www.socialsecurity.gov/employer/ssns/highgroup.txt'))
|
36
|
+
create_records(parse_text(text),extract_as_of_date(text))
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.already_loaded?(file_as_of_date)
|
40
|
+
self.find_by_as_of(file_as_of_date)
|
41
|
+
end
|
42
|
+
###################
|
43
|
+
#end class mehtods#
|
44
|
+
###################
|
45
|
+
|
46
|
+
##################
|
47
|
+
#instance mehtods#
|
48
|
+
##################
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
######################
|
53
|
+
#end instance mehtods#
|
54
|
+
######################
|
55
|
+
private
|
56
|
+
|
57
|
+
def self.create_records(area_groups,file_as_of)
|
58
|
+
if already_loaded?(file_as_of)
|
59
|
+
"File as of #{file_as_of} has already been loaded."
|
60
|
+
else
|
61
|
+
area_groups.each do |area_group|
|
62
|
+
self.create(area_group.merge!(:as_of => file_as_of.to_s(:db)))
|
63
|
+
end
|
64
|
+
"File as of #{file_as_of} loaded."
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#extract the date from the file in the format mm/dd/yy
|
69
|
+
def self.extract_as_of_date(text)
|
70
|
+
as_of_start_index = text =~ /\d\d\/\d\d\/\d\d/
|
71
|
+
::Date.new(*::Date._parse($&,true).values_at(:year, :mon, :mday)) unless as_of_start_index.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
#The formatting of the file is a little bit messy. Sometimes tabs are
|
75
|
+
#used as delimiters and sometimes spaces are used as delimiters. Also, the asterisks indicating recent changes are not
|
76
|
+
#necessary for our purposes
|
77
|
+
#Returns an array of hashes.
|
78
|
+
def self.parse_text(text)
|
79
|
+
text.gsub!('*',' ')
|
80
|
+
text.gsub!(/\t/, ' ')
|
81
|
+
text_array = text.split(/\n/).compact
|
82
|
+
area_groups = []
|
83
|
+
text_array.each do |t|
|
84
|
+
t.gsub!(/\s+/,' ')
|
85
|
+
next if t =~ /[[:alpha:]]/ #skip over the header lines
|
86
|
+
|
87
|
+
if t =~ /\d\d\d \d\d/ #we want the lines with area group pairs
|
88
|
+
t.gsub(/\d\d\d \d\d/) do |s|
|
89
|
+
area_group = s.split(' ')
|
90
|
+
area_groups << {:area => area_group.first, :group => area_group.last}
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
return area_groups
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module SsnValidator
|
2
|
+
class Ssn
|
3
|
+
|
4
|
+
attr_reader :ssn,:area,:group,:serial_number
|
5
|
+
attr_reader :errors
|
6
|
+
|
7
|
+
|
8
|
+
def initialize(ssn)
|
9
|
+
@errors = []
|
10
|
+
ssn = ssn.to_s
|
11
|
+
if ssn =~ /-/ && ssn !~ /\d\d\d-\d\d-\d\d\d\d/
|
12
|
+
@errors << 'Hyphen misplaced.'
|
13
|
+
end
|
14
|
+
|
15
|
+
ssn.gsub!('-','')
|
16
|
+
if ssn.to_s.size != 9
|
17
|
+
@errors << 'SSN not 9 digits long.'
|
18
|
+
end
|
19
|
+
|
20
|
+
if ssn =~ /\D/
|
21
|
+
@errors << 'Non-digit found.'
|
22
|
+
end
|
23
|
+
|
24
|
+
#known dummy numbers
|
25
|
+
if ["078051120","111111111","123456789","219099999","999999999"].include? ssn || (ssn >= "987654320" and ssn <= "987654329")
|
26
|
+
@errors << "Known dummy SSN."
|
27
|
+
end
|
28
|
+
#known invalid area, group and serial numbers
|
29
|
+
if ssn =~ /\d{3}00\d{4}|0000\Z/
|
30
|
+
@errors << "Invalid group or serial number."
|
31
|
+
end
|
32
|
+
|
33
|
+
@ssn = ssn
|
34
|
+
@area = ssn.first(3)
|
35
|
+
@group = ssn[3,2]
|
36
|
+
@serial_number = ssn.last(4)
|
37
|
+
|
38
|
+
if @errors.empty?
|
39
|
+
@ssn_high_group_code = SsnHighGroupCode.find_by_area(@area, :order => 'as_of desc')
|
40
|
+
if @ssn_high_group_code.nil?
|
41
|
+
@errors << "Area '#{@area}' has not been assigned."
|
42
|
+
else
|
43
|
+
|
44
|
+
define_group_ranks
|
45
|
+
|
46
|
+
if @group_ranks[@group] > @group_ranks[@ssn_high_group_code.group]
|
47
|
+
@errors << "Group '#{@group}' has not been assigned yet for area '#{@area}'"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
def valid?
|
56
|
+
@errors.empty?
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def define_group_ranks
|
63
|
+
@group_ranks = {}
|
64
|
+
rank = 0
|
65
|
+
(1..9).step(2) do |group|
|
66
|
+
@group_ranks.merge!("0#{group.to_s}" => rank += 1)
|
67
|
+
end
|
68
|
+
(10..98).step(2) do |group|
|
69
|
+
@group_ranks.merge!(group.to_s => rank += 1)
|
70
|
+
end
|
71
|
+
(2..8).step(2) do |group|
|
72
|
+
@group_ranks.merge!("0#{group.to_s}" => rank += 1)
|
73
|
+
end
|
74
|
+
(11..99).step(2) do |group|
|
75
|
+
@group_ranks.merge!(group.to_s => rank += 1)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'ssn_validator/models/ssn_high_group_code'
|
5
|
+
require 'ssn_validator/models/ssn_validator'
|
6
|
+
require 'rake'
|
7
|
+
|
8
|
+
# Load rake file
|
9
|
+
import "#{File.dirname(__FILE__)}/tasks/ssn_validator.rake"
|
10
|
+
|
11
|
+
module SsnValidator
|
12
|
+
VERSION = '0.1.1'
|
13
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
namespace :ssn_validator do
|
3
|
+
desc "Loads the current file from http://www.socialsecurity.gov/employer/ssns/highgroup.txt if it hasn't already been loaded."
|
4
|
+
task :update_data => :environment do
|
5
|
+
puts SsnHighGroupCode.load_current_high_group_codes_file
|
6
|
+
end
|
7
|
+
|
8
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/ssn_validator.rb'}"
|
9
|
+
puts "Loading ssn_validator gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'test/unit'
|
3
|
+
require File.dirname(__FILE__) + '/../lib/ssn_validator'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
|
6
|
+
|
7
|
+
def create_ssn_high_group_codes_table
|
8
|
+
silence_stream(STDOUT) do
|
9
|
+
ActiveRecord::Schema.define(:version => 1) do
|
10
|
+
create_table :ssn_high_group_codes do |t|
|
11
|
+
t.date :as_of
|
12
|
+
t.string :area
|
13
|
+
t.string :group
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
|
17
|
+
add_index :ssn_high_group_codes, [:area]
|
18
|
+
add_index :ssn_high_group_codes, [:area, :as_of]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_high_group_codes_table
|
24
|
+
ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
|
25
|
+
create_ssn_high_group_codes_table
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestSsnHighGroupCode < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
setup_high_group_codes_table
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_should_load_table_with_current_file
|
10
|
+
assert_equal(0,SsnHighGroupCode.count)
|
11
|
+
SsnHighGroupCode.load_current_high_group_codes_file
|
12
|
+
assert SsnHighGroupCode.count > 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_should_not_load_table_if_as_of_already_in_table
|
16
|
+
SsnHighGroupCode.load_current_high_group_codes_file
|
17
|
+
assert SsnHighGroupCode.count > 0
|
18
|
+
record_count = SsnHighGroupCode.count
|
19
|
+
SsnHighGroupCode.load_current_high_group_codes_file
|
20
|
+
assert_equal(record_count, SsnHighGroupCode.count)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestSsnValidator < Test::Unit::TestCase
|
4
|
+
|
5
|
+
KNOWN_DUMMY_SSNS = %w(078051120 111111111 123456789 219099999 999999999)
|
6
|
+
MISSPLACED_HYPHEN_SSNS = %w(1-2-3456789 12-345678-9 123-4-56789 123-456789 1234567-89 12-345-6789 12345-6789 1234-5-6789)
|
7
|
+
INVALID_LENGTH_SSNS = %w(1 12 123 1234 12345 123456 1234567 13245678 1234567890)
|
8
|
+
NONDIGIT_SSNS = %w(078051a20 078F51120 78051#20 051,20 078051m20)
|
9
|
+
INVALID_ZEROS_SSNS = %w(166-00-1234 073-96-0000)
|
10
|
+
GROUPS_NOT_ASSIGNED_TO_AREA_SSNS = %w(752991234 755971234 762991254)
|
11
|
+
|
12
|
+
VALID_SSNS = %w(001021234 161-84-9876 223981111)
|
13
|
+
VALID_INTEGER_SSNS = [115941234, 161849876, 223981111]
|
14
|
+
|
15
|
+
def setup
|
16
|
+
setup_high_group_codes_table
|
17
|
+
SsnHighGroupCode.load_current_high_group_codes_file
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_ssn_validations
|
21
|
+
KNOWN_DUMMY_SSNS.each do |ssn|
|
22
|
+
validator = SsnValidator::Ssn.new(ssn)
|
23
|
+
assert !validator.valid?
|
24
|
+
assert validator.errors.include?('Known dummy SSN.'), "Errors: #{validator.errors}"
|
25
|
+
end
|
26
|
+
|
27
|
+
MISSPLACED_HYPHEN_SSNS.each do |ssn|
|
28
|
+
validator = SsnValidator::Ssn.new(ssn)
|
29
|
+
assert !validator.valid?
|
30
|
+
assert validator.errors.include?('Hyphen misplaced.'), "Errors: #{validator.errors}"
|
31
|
+
end
|
32
|
+
|
33
|
+
INVALID_LENGTH_SSNS.each do |ssn|
|
34
|
+
validator = SsnValidator::Ssn.new(ssn)
|
35
|
+
assert !validator.valid?
|
36
|
+
assert validator.errors.include?('SSN not 9 digits long.'), "Errors: #{validator.errors}"
|
37
|
+
end
|
38
|
+
|
39
|
+
NONDIGIT_SSNS.each do |ssn|
|
40
|
+
validator = SsnValidator::Ssn.new(ssn)
|
41
|
+
assert !validator.valid?
|
42
|
+
assert validator.errors.include?('Non-digit found.'), "Errors: #{validator.errors}"
|
43
|
+
end
|
44
|
+
|
45
|
+
INVALID_ZEROS_SSNS.each do |ssn|
|
46
|
+
validator = SsnValidator::Ssn.new(ssn)
|
47
|
+
assert !validator.valid?
|
48
|
+
assert validator.errors.include?('Invalid group or serial number.'), "Errors: #{validator.errors}"
|
49
|
+
end
|
50
|
+
|
51
|
+
GROUPS_NOT_ASSIGNED_TO_AREA_SSNS.each do |ssn|
|
52
|
+
validator = SsnValidator::Ssn.new(ssn)
|
53
|
+
assert !validator.valid?
|
54
|
+
assert validator.errors.include?("Group '#{validator.group}' has not been assigned yet for area '#{validator.area}'"), "Errors: #{validator.errors}"
|
55
|
+
end
|
56
|
+
|
57
|
+
(VALID_SSNS + VALID_INTEGER_SSNS).each do |ssn|
|
58
|
+
validator = SsnValidator::Ssn.new(ssn)
|
59
|
+
assert validator.valid?, "Errors: #{validator.errors}"
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kevintyll-ssn_validator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin Tyll
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-13 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.0.0
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: kevintyll@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- History.txt
|
35
|
+
- Manifest.txt
|
36
|
+
- PostInstall.txt
|
37
|
+
- README.rdoc
|
38
|
+
- Rakefile
|
39
|
+
- generators/ssn_validator_migration/templates/migration.rb
|
40
|
+
- generators/ssn_validator_migration/ssn_validator_migration_generator.rb
|
41
|
+
- lib/ssn_validator/models/ssn_high_group_code.rb
|
42
|
+
- lib/ssn_validator/models/ssn_validator.rb
|
43
|
+
- lib/ssn_validator.rb
|
44
|
+
- lib/tasks/ssn_validator.rake
|
45
|
+
- script/console
|
46
|
+
- script/destroy
|
47
|
+
- script/generate
|
48
|
+
- test/test_helper.rb
|
49
|
+
- test/test_ssn_validator.rb
|
50
|
+
- test/test_ssn_high_group_code.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage:
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
|
56
|
+
require_paths:
|
57
|
+
- .
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.2.0
|
74
|
+
signing_key:
|
75
|
+
specification_version: 2
|
76
|
+
summary: Validates whether an SSN has likely been issued or not.
|
77
|
+
test_files:
|
78
|
+
- test/test_helper.rb
|
79
|
+
- test/test_ssn_validator.rb
|
80
|
+
- test/test_ssn_high_group_code.rb
|