checkr-official 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/History.txt +4 -0
- data/README.md +58 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/bin/checkr-console +7 -0
- data/checkr-official.gemspec +28 -0
- data/gemfiles/default-with-activesupport.gemfile +10 -0
- data/gemfiles/json.gemfile +12 -0
- data/gemfiles/yajl.gemfile +12 -0
- data/lib/checkr.rb +241 -0
- data/lib/checkr/api_class.rb +395 -0
- data/lib/checkr/api_list.rb +78 -0
- data/lib/checkr/api_resource.rb +18 -0
- data/lib/checkr/api_singleton.rb +5 -0
- data/lib/checkr/candidate.rb +35 -0
- data/lib/checkr/county_criminal_search.rb +19 -0
- data/lib/checkr/document.rb +13 -0
- data/lib/checkr/document_list.rb +25 -0
- data/lib/checkr/errors/api_connection_error.rb +4 -0
- data/lib/checkr/errors/api_error.rb +10 -0
- data/lib/checkr/errors/authentication_error.rb +4 -0
- data/lib/checkr/errors/checkr_error.rb +20 -0
- data/lib/checkr/errors/invalid_request_error.rb +10 -0
- data/lib/checkr/geo.rb +19 -0
- data/lib/checkr/motor_vehicle_report.rb +31 -0
- data/lib/checkr/national_criminal_search.rb +17 -0
- data/lib/checkr/report.rb +43 -0
- data/lib/checkr/report_list.rb +27 -0
- data/lib/checkr/sex_offender_search.rb +18 -0
- data/lib/checkr/ssn_trace.rb +18 -0
- data/lib/checkr/subscription.rb +27 -0
- data/lib/checkr/terrorist_watchlist_search.rb +17 -0
- data/lib/checkr/util.rb +91 -0
- data/lib/checkr/version.rb +3 -0
- data/mclovin.jpg +0 -0
- data/tasks/api_test.rb +192 -0
- data/test/checkr/api_class_test.rb +426 -0
- data/test/checkr/api_list_test.rb +27 -0
- data/test/checkr/api_resource_test.rb +28 -0
- data/test/checkr/api_singleton_test.rb +12 -0
- data/test/checkr/authentication_test.rb +50 -0
- data/test/checkr/candidate_test.rb +164 -0
- data/test/checkr/county_criminal_search_test.rb +82 -0
- data/test/checkr/document_test.rb +90 -0
- data/test/checkr/geo_test.rb +73 -0
- data/test/checkr/motor_vehicle_report_test.rb +130 -0
- data/test/checkr/national_criminal_search_test.rb +74 -0
- data/test/checkr/report_test.rb +124 -0
- data/test/checkr/sex_offender_search_test.rb +75 -0
- data/test/checkr/ssn_trace_test.rb +78 -0
- data/test/checkr/status_codes_test.rb +63 -0
- data/test/checkr/subscription_test.rb +96 -0
- data/test/checkr/terrorist_watchlist_search_test.rb +74 -0
- data/test/checkr/util_test.rb +50 -0
- data/test/mock_resource.rb +88 -0
- data/test/test_data.rb +413 -0
- data/test/test_helper.rb +43 -0
- metadata +230 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module Checkr
|
2
|
+
class TerroristWatchlistSearch < APIResource
|
3
|
+
|
4
|
+
attribute :status
|
5
|
+
attribute :completed_at
|
6
|
+
attribute :turnaround_time
|
7
|
+
attribute :records
|
8
|
+
|
9
|
+
api_class_method :retrieve, :get, ":path/:id", :arguments => [:id]
|
10
|
+
|
11
|
+
def self.path
|
12
|
+
"/v1/terrorist_watchlist_searches"
|
13
|
+
end
|
14
|
+
|
15
|
+
APIClass.register_subclass(self, "terrorist_watchlist_search")
|
16
|
+
end
|
17
|
+
end
|
data/lib/checkr/util.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module Checkr
|
2
|
+
module Util
|
3
|
+
|
4
|
+
def self.query_string(params)
|
5
|
+
if params && params.any?
|
6
|
+
return query_array(params).join('&')
|
7
|
+
else
|
8
|
+
return ""
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Three major use cases (and nesting of them needs to be supported):
|
13
|
+
# { :a => { :b => "bvalue" } } => ["a[b]=bvalue"]
|
14
|
+
# { :a => [1, 2] } => ["a[]=1", "a[]=2"]
|
15
|
+
# { :a => "value" } => ["a=value"]
|
16
|
+
def self.query_array(params, key_prefix=nil)
|
17
|
+
ret = []
|
18
|
+
params.each do |key, value|
|
19
|
+
if params.is_a?(Array)
|
20
|
+
value = key
|
21
|
+
key = ''
|
22
|
+
end
|
23
|
+
key_suffix = escape(key)
|
24
|
+
full_key = key_prefix ? "#{key_prefix}[#{key_suffix}]" : key_suffix
|
25
|
+
|
26
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
27
|
+
# Handles the following cases:
|
28
|
+
# { :a => { :b => "bvalue" } } => ["a[b]=bvalue"]
|
29
|
+
# { :a => [1, 2] } => ["a[]=1", "a[]=2"]
|
30
|
+
ret += query_array(value, full_key)
|
31
|
+
else
|
32
|
+
# Handles the base case with just key and value:
|
33
|
+
# { :a => "value" } => ["a=value"]
|
34
|
+
ret << "#{full_key}=#{escape(value)}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.escape(val)
|
41
|
+
URI.escape(val.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.symbolize_keys(obj)
|
45
|
+
if obj.is_a?(Hash)
|
46
|
+
ret = {}
|
47
|
+
obj.each do |key, value|
|
48
|
+
ret[(key.to_sym rescue key) || key] = symbolize_keys(value)
|
49
|
+
end
|
50
|
+
return ret
|
51
|
+
elsif obj.is_a?(Array)
|
52
|
+
return obj.map{ |value| symbolize_keys(value) }
|
53
|
+
else
|
54
|
+
return obj
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.sorta_deep_clone(json)
|
59
|
+
if json.is_a?(Hash)
|
60
|
+
ret = {}
|
61
|
+
json.each do |k, v|
|
62
|
+
ret[k] = sorta_deep_clone(v)
|
63
|
+
end
|
64
|
+
ret
|
65
|
+
elsif json.is_a?(Array)
|
66
|
+
json.map{ |j| sorta_deep_clone(j) }
|
67
|
+
else
|
68
|
+
begin
|
69
|
+
json.dup
|
70
|
+
rescue
|
71
|
+
json
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.constantize(str, prefix=false)
|
77
|
+
str = str.to_s
|
78
|
+
begin
|
79
|
+
str.split('::').reduce(Module, :const_get)
|
80
|
+
rescue NameError => e
|
81
|
+
if prefix
|
82
|
+
raise e
|
83
|
+
else
|
84
|
+
p = "#{self.name}".split("::").first
|
85
|
+
constantize("#{p}::#{str}", true)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/mclovin.jpg
ADDED
Binary file
|
data/tasks/api_test.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'checkr'
|
2
|
+
|
3
|
+
class APITest
|
4
|
+
def initialize(api_key)
|
5
|
+
Checkr.api_key = api_key
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
geos = run_geos_test
|
10
|
+
candidate = run_candidate_tests(geos)
|
11
|
+
document = run_document_tests(candidate)
|
12
|
+
consider, clear = run_report_tests(candidate)
|
13
|
+
run_ssn_trace_tests(consider, clear)
|
14
|
+
run_sex_offender_search_tests(consider, clear)
|
15
|
+
# TODO: Uncomment this when there isn't a forbidden bug with shared resources in test.
|
16
|
+
# run_terrorist_watchlist_search_tests(consider, clear)
|
17
|
+
run_national_criminal_search_tests(consider, clear)
|
18
|
+
run_county_criminal_search_tests(consider, clear)
|
19
|
+
run_motor_vehicle_report_tests(consider, clear)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_geos_test
|
23
|
+
puts "Looking up geos..."
|
24
|
+
geos = Checkr::Geo.all
|
25
|
+
puts "Found #{geos.length} geos."
|
26
|
+
|
27
|
+
scranton = geos.select{ |g| g.name == "Scranton" }.first
|
28
|
+
|
29
|
+
unless scranton
|
30
|
+
scranton = Checkr::Geo.create({
|
31
|
+
:name => "Scranton",
|
32
|
+
:state => "PA"
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "Deleting the geo for Scranton"
|
37
|
+
scranton.delete
|
38
|
+
|
39
|
+
puts "Create the Scranton geo..."
|
40
|
+
scranton = Checkr::Geo.create({
|
41
|
+
:name => "Scranton",
|
42
|
+
:state => "PA"
|
43
|
+
})
|
44
|
+
puts "Created: #{scranton.inspect}"
|
45
|
+
|
46
|
+
puts "Looking up a created geo."
|
47
|
+
geo = Checkr::Geo.retrieve(scranton.id)
|
48
|
+
puts "Found: #{geo.inspect}"
|
49
|
+
|
50
|
+
Checkr::Geo.all.select{ |g| g.state == "CA" }
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_candidate_tests(geos)
|
54
|
+
puts "Creating a candidate..."
|
55
|
+
candidate = Checkr::Candidate.create({
|
56
|
+
:first_name => "John",
|
57
|
+
:middle_name => "Alfred",
|
58
|
+
:last_name => "Smith",
|
59
|
+
:email => "John.Smith@gmail.com",
|
60
|
+
:phone => "5555555555",
|
61
|
+
:zipcode => "90401",
|
62
|
+
:dob => "1970-01-22",
|
63
|
+
:ssn => "543-43-4645",
|
64
|
+
:driver_license_number => "F211165",
|
65
|
+
:driver_license_state => "CA",
|
66
|
+
:geo_ids => geos.map(&:id)
|
67
|
+
})
|
68
|
+
puts "Created: #{candidate.inspect}"
|
69
|
+
|
70
|
+
puts "Looking up all candidates..."
|
71
|
+
candidates = Checkr::Candidate.all
|
72
|
+
puts "Found #{candidates.length} candidates."
|
73
|
+
|
74
|
+
puts "Retrieving the created candidate..."
|
75
|
+
candidate = Checkr::Candidate.retrieve(candidate.id)
|
76
|
+
puts "Retrieved the candidate with id=#{candidate.id}"
|
77
|
+
|
78
|
+
candidate
|
79
|
+
end
|
80
|
+
|
81
|
+
def run_document_tests(candidate)
|
82
|
+
puts "Creating a document..."
|
83
|
+
document = candidate.documents.create({
|
84
|
+
:type => "driver_license",
|
85
|
+
:file => File.open("#{File.dirname(__FILE__)}/../mclovin.jpg")
|
86
|
+
})
|
87
|
+
puts "Created: #{document.inspect}"
|
88
|
+
|
89
|
+
puts "Looking up all documents..."
|
90
|
+
documents = candidate.documents.all
|
91
|
+
puts "Found #{documents.length} documents."
|
92
|
+
|
93
|
+
document
|
94
|
+
end
|
95
|
+
|
96
|
+
def run_report_tests(candidate)
|
97
|
+
puts "Creating a report for Candidate##{candidate.id}..."
|
98
|
+
report = candidate.reports.create("tasker_plus")
|
99
|
+
puts "Created #{report.inspect}"
|
100
|
+
|
101
|
+
puts "Retrieving the created report..."
|
102
|
+
report = Checkr::Report.retrieve(report.id)
|
103
|
+
puts "Retrieved the report with id=#{report.id}"
|
104
|
+
|
105
|
+
puts "Updating the report..."
|
106
|
+
report.package = "driver_plus"
|
107
|
+
report.save
|
108
|
+
puts "New package is #{report.package}"
|
109
|
+
|
110
|
+
puts "Retrieving a consider report..."
|
111
|
+
consider = Checkr::Report.retrieve("59b650f567e1dd0f01422b92")
|
112
|
+
puts "Retrieving a clear report..."
|
113
|
+
clear = Checkr::Report.retrieve("31e894fc23e30953c26a2d26")
|
114
|
+
|
115
|
+
[consider, clear]
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_ssn_trace_tests(consider, clear)
|
119
|
+
puts "Retrieving SSN Trace using the consider report."
|
120
|
+
consider.ssn_trace.refresh
|
121
|
+
puts "Retrieved the SSN Trace: #{consider.ssn_trace.inspect}"
|
122
|
+
|
123
|
+
puts "Retrieving SSN Trace using the clear report."
|
124
|
+
ssn_trace = Checkr::SSNTrace.retrieve(clear.ssn_trace.id)
|
125
|
+
puts "Retrieved the SSN Trace: #{ssn_trace.inspect}"
|
126
|
+
|
127
|
+
ssn_trace
|
128
|
+
end
|
129
|
+
|
130
|
+
def run_sex_offender_search_tests(consider, clear)
|
131
|
+
puts "Retrieving Sex Offender Search using the consider report."
|
132
|
+
consider.sex_offender_search.refresh
|
133
|
+
puts "Retrieved the Sex Offender Search: #{consider.sex_offender_search.inspect}"
|
134
|
+
|
135
|
+
puts "Retrieving Sex Offender Search using the clear report."
|
136
|
+
sex_offender_search = Checkr::SexOffenderSearch.retrieve(clear.sex_offender_search.id)
|
137
|
+
puts "Retrieved the Sex Offender Search: #{sex_offender_search.inspect}"
|
138
|
+
|
139
|
+
sex_offender_search
|
140
|
+
end
|
141
|
+
|
142
|
+
def run_terrorist_watchlist_search_tests(consider, clear)
|
143
|
+
puts "Retrieving using consider..."
|
144
|
+
consider.terrorist_watchlist_search.refresh
|
145
|
+
puts "Retrieved the terrorist_watchlist_search: #{consider.terrorist_watchlist_search.inspect}"
|
146
|
+
|
147
|
+
puts "Retrieving using clear report..."
|
148
|
+
terrorist_watchlist_search = Checkr::TerroristWatchlistSearch.retrieve(clear.terrorist_watchlist_search.id)
|
149
|
+
puts "Retrieved the terrorist_watchlist_search: #{terrorist_watchlist_search.inspect}"
|
150
|
+
|
151
|
+
terrorist_watchlist_search
|
152
|
+
end
|
153
|
+
|
154
|
+
def run_national_criminal_search_tests(consider, clear)
|
155
|
+
puts "Retrieving using consider..."
|
156
|
+
consider.national_criminal_search.refresh
|
157
|
+
puts "Retrieved the national_criminal_search: #{consider.national_criminal_search.inspect}"
|
158
|
+
|
159
|
+
puts "Retrieving using clear report..."
|
160
|
+
national_criminal_search = Checkr::NationalCriminalSearch.retrieve(clear.national_criminal_search.id)
|
161
|
+
puts "Retrieved the national_criminal_search: #{national_criminal_search.inspect}"
|
162
|
+
|
163
|
+
national_criminal_search
|
164
|
+
end
|
165
|
+
|
166
|
+
def run_county_criminal_search_tests(consider, clear)
|
167
|
+
puts "Retrieving using consider..."
|
168
|
+
consider.county_criminal_searches.first.refresh
|
169
|
+
puts "Retrieved the county_criminal_search: #{consider.county_criminal_searches.first.inspect}"
|
170
|
+
|
171
|
+
puts "Retrieving using clear report..."
|
172
|
+
county_criminal_search = Checkr::CountyCriminalSearch.retrieve(clear.county_criminal_searches.first.id)
|
173
|
+
puts "Retrieved the county_criminal_search: #{county_criminal_search.inspect}"
|
174
|
+
|
175
|
+
county_criminal_search
|
176
|
+
end
|
177
|
+
|
178
|
+
def run_motor_vehicle_report_tests(consider, clear)
|
179
|
+
puts "Retrieving using consider..."
|
180
|
+
consider.motor_vehicle_report.refresh
|
181
|
+
puts "Retrieved the motor_vehicle_report: #{consider.motor_vehicle_report.inspect}"
|
182
|
+
|
183
|
+
puts "Retrieving using clear report..."
|
184
|
+
motor_vehicle_report = Checkr::MotorVehicleReport.retrieve(clear.motor_vehicle_report.id)
|
185
|
+
puts "Retrieved the motor_vehicle_report: #{motor_vehicle_report.inspect}"
|
186
|
+
|
187
|
+
motor_vehicle_report
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
end
|
@@ -0,0 +1,426 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.expand_path('../../test_helper', __FILE__)
|
3
|
+
|
4
|
+
module Checkr
|
5
|
+
class ApiClassTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context 'Non-network actions' do
|
8
|
+
setup do
|
9
|
+
@mock.expects(:get).never
|
10
|
+
@mock.expects(:post).never
|
11
|
+
@mock.expects(:put).never
|
12
|
+
@mock.expects(:delete).never
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'not fetch over the network when creating a new APIClass' do
|
16
|
+
MockResource.new('fake_id')
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'not fetch over the network when creating a new APIClass from a hash' do
|
20
|
+
MockResource.construct(test_mock_resource)
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'not fetch over the network when setting an attribute' do
|
24
|
+
c = MockResource.new('fake_id')
|
25
|
+
c.name = 'Another Name'
|
26
|
+
end
|
27
|
+
|
28
|
+
should 'not fetch over the network when accessing an attribute' do
|
29
|
+
c = MockResource.new('fake_id')
|
30
|
+
c.id
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# These GET, POST, etc should really be in a dif test, but this is easier.
|
35
|
+
context 'Making a GET request' do
|
36
|
+
should 'urlencode values in params and have no payload' do
|
37
|
+
response = test_response(test_mock_resource_list)
|
38
|
+
|
39
|
+
# The test is to basically make sure this expectation passes.
|
40
|
+
@mock.expects(:get).with do |url, headers, params|
|
41
|
+
(url == "#{Checkr.api_base}#{MockResource.path}?page=1&filter=test%20filter" ||
|
42
|
+
url == "#{Checkr.api_base}#{MockResource.path}?filter=test%20filter&page=1") &&
|
43
|
+
params == nil
|
44
|
+
end.returns(response)
|
45
|
+
|
46
|
+
list = MockResource.all({
|
47
|
+
:page => 1,
|
48
|
+
:filter => 'test filter',
|
49
|
+
})
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'Making a DELETE request' do
|
54
|
+
should 'urlencode values in params and have no payload' do
|
55
|
+
@mock.expects(:get).once.returns(test_response(test_mock_resource))
|
56
|
+
mock_resource = MockResource.retrieve("fake_id")
|
57
|
+
|
58
|
+
@mock.expects(:delete).once.with do |url, headers, payload|
|
59
|
+
url == "#{Checkr.api_base}#{mock_resource.path}?reason=delinquent%20payments" && payload.nil?
|
60
|
+
end.returns(test_response({}))
|
61
|
+
mock_resource.delete(:reason => "delinquent payments")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'Making a PUT request' do
|
66
|
+
should 'have a payload with no query string' do
|
67
|
+
@mock.expects(:get).once.returns(test_response(test_mock_resource))
|
68
|
+
mock_resource = MockResource.retrieve("fake_id")
|
69
|
+
mock_resource.name = "new name"
|
70
|
+
|
71
|
+
@mock.expects(:put).once.with do |url, header, payload|
|
72
|
+
payload == { :name => "new name" }
|
73
|
+
end.returns(test_response(test_mock_resource))
|
74
|
+
mock_resource.save
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'Making a POST request' do
|
79
|
+
should 'have a payload with no query string' do
|
80
|
+
params = { :name => "some name" }
|
81
|
+
@mock.expects(:post).once.with("#{Checkr.api_base}#{MockResource.path}", anything, params).returns(test_response(test_mock_resource))
|
82
|
+
|
83
|
+
MockResource.create(params)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'APIClass :default_params' do
|
88
|
+
context 'api_instance_method' do
|
89
|
+
setup do
|
90
|
+
@response = test_response(test_mock_resource_list)
|
91
|
+
@mr = MockResource.new(test_mock_resource)
|
92
|
+
end
|
93
|
+
|
94
|
+
should 'call any provided lambdas and set the result as params' do
|
95
|
+
@mock.expects(:put).once.with(anything, anything, { :name => "new name" }).returns(@response)
|
96
|
+
|
97
|
+
@mr.name = "new name"
|
98
|
+
@mr.with_lambda
|
99
|
+
end
|
100
|
+
|
101
|
+
should 'call any method defined by a symbol and set the results as params' do
|
102
|
+
@mock.expects(:put).once.with(anything, anything, { :name => "new name" }).returns(@response)
|
103
|
+
|
104
|
+
@mr.name = "new name"
|
105
|
+
@mr.with_symbol
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'order priority' do
|
109
|
+
# Intended order of priority:
|
110
|
+
# 1. Params. eg in mock_resource.save(params, opts), params should take
|
111
|
+
# priority with duplicate keys.
|
112
|
+
# 2. Arguments. These should take priority over default values from :params
|
113
|
+
# method.
|
114
|
+
# 3. Results from method defined by :default_params. This can be a symbol that is
|
115
|
+
# the name of a method to call, or a lambda (though a hash is preferred).
|
116
|
+
should 'prioritize params argument over args and default_params method' do
|
117
|
+
params = {
|
118
|
+
:name => "not arg name",
|
119
|
+
:tarray => ["not method tarray"],
|
120
|
+
:thash => { :val => "custom hash" }
|
121
|
+
}
|
122
|
+
@mock.expects(:put).once.with(anything, anything, params).returns(@response)
|
123
|
+
|
124
|
+
@mr.tarray = ["method array"]
|
125
|
+
@mr.with_symbol_and_args("arg name", params)
|
126
|
+
end
|
127
|
+
|
128
|
+
should 'prioritize arguments over :default_params' do
|
129
|
+
@mock.expects(:put).once.with(anything, anything, { :name => "arg name" }).returns(@response)
|
130
|
+
|
131
|
+
@mr.name = "changed name"
|
132
|
+
@mr.with_symbol_and_args("arg name")
|
133
|
+
end
|
134
|
+
|
135
|
+
should 'use :default_params method as even when args and params are present' do
|
136
|
+
@mock.expects(:put).once.with(anything, anything, {
|
137
|
+
:thash => { :val => "params hash" },
|
138
|
+
:name => "arg name",
|
139
|
+
:tarray => ["change array"],
|
140
|
+
}).returns(@response)
|
141
|
+
|
142
|
+
@mr.tarray = ["change array"]
|
143
|
+
@mr.with_symbol_and_args("arg name", { :thash => { :val => "params hash" } })
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'api_class_method' do
|
149
|
+
setup do
|
150
|
+
@response = test_response(test_mock_resource_list)
|
151
|
+
end
|
152
|
+
|
153
|
+
should 'call any provided lambdas and set the result as params' do
|
154
|
+
@mock.expects(:post).once.with(anything, anything, MockResource.default_values).returns(@response)
|
155
|
+
MockResource.with_lambda
|
156
|
+
end
|
157
|
+
|
158
|
+
should 'call any method defined by a symbol and set the results as params' do
|
159
|
+
@mock.expects(:post).once.with(anything, anything, MockResource.default_values).returns(@response)
|
160
|
+
MockResource.with_symbol
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'order priority' do
|
164
|
+
# Intended order of priority:
|
165
|
+
# 1. Params. eg in mock_resource.save(params, opts), params should take
|
166
|
+
# priority with duplicate keys.
|
167
|
+
# 2. Arguments. These should take priority over default values from :params
|
168
|
+
# method.
|
169
|
+
# 3. Results from method defined by :default_params. This can be a symbol that is
|
170
|
+
# the name of a method to call, or a lambda (though a hash is preferred).
|
171
|
+
should 'prioritize params argument over args and default_params method' do
|
172
|
+
params = {
|
173
|
+
:name => "not arg name",
|
174
|
+
:tarray => ["not method tarray"],
|
175
|
+
:thash => { :val => "custom hash" }
|
176
|
+
}
|
177
|
+
@mock.expects(:post).once.with(anything, anything, params).returns(@response)
|
178
|
+
MockResource.with_symbol_and_args("name arg", params)
|
179
|
+
end
|
180
|
+
|
181
|
+
should 'prioritize arguments over :default_params' do
|
182
|
+
params = Util.sorta_deep_clone(MockResource.default_values)
|
183
|
+
params[:name] = "name arg"
|
184
|
+
@mock.expects(:post).once.with(anything, anything, params).returns(@response)
|
185
|
+
MockResource.with_symbol_and_args("name arg", params)
|
186
|
+
end
|
187
|
+
|
188
|
+
should 'use :default_params method as even when args and params are present' do
|
189
|
+
params = {
|
190
|
+
:name => "name arg",
|
191
|
+
:tarray => MockResource.default_values[:tarray].dup,
|
192
|
+
:thash => { :val => "custom hash" }
|
193
|
+
}
|
194
|
+
@mock.expects(:post).once.with(anything, anything, params).returns(@response)
|
195
|
+
MockResource.with_symbol_and_args("name arg", { :thash => { :val => "custom hash" }})
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
context 'APIClass#attribute' do
|
203
|
+
should 'create a getter method' do
|
204
|
+
assert(MockResource.method_defined?(:name))
|
205
|
+
end
|
206
|
+
|
207
|
+
should 'create a setter method' do
|
208
|
+
assert(MockResource.method_defined?(:name=))
|
209
|
+
end
|
210
|
+
|
211
|
+
should 'have no changed attributes after init' do
|
212
|
+
mr = MockResource.new(test_mock_resource)
|
213
|
+
assert(mr.changed_attributes.empty?)
|
214
|
+
end
|
215
|
+
|
216
|
+
should 'keep track of changed attributes' do
|
217
|
+
mr = MockResource.new(test_mock_resource)
|
218
|
+
assert(mr.changed_attributes.empty?)
|
219
|
+
mr.name = "new name"
|
220
|
+
assert_equal({:name => "new name"}, mr.changed_attributes)
|
221
|
+
end
|
222
|
+
|
223
|
+
should 'keep track of changed arrays' do
|
224
|
+
mr = MockResource.new(test_mock_resource)
|
225
|
+
assert(mr.changed_attributes.empty?)
|
226
|
+
mr.tarray << "new"
|
227
|
+
assert_equal({:tarray => test_mock_resource[:tarray] + ["new"]}, mr.changed_attributes)
|
228
|
+
end
|
229
|
+
|
230
|
+
should 'keep track of changed hashes' do
|
231
|
+
mr = MockResource.new(test_mock_resource)
|
232
|
+
assert(mr.changed_attributes.empty?)
|
233
|
+
mr.thash[:some_key] = "new value"
|
234
|
+
assert_equal({:thash => { :some_key => "new value" }}, mr.changed_attributes)
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'constructors' do
|
238
|
+
should 'instantiate on #new' do
|
239
|
+
mr = MockResource.new(test_mock_resource)
|
240
|
+
assert(mr.nested.is_a?(NestedResource))
|
241
|
+
assert(mr.nested_alt.is_a?(NestedResource))
|
242
|
+
assert(mr.nested_with.is_a?(NestedWithParent))
|
243
|
+
assert_equal(mr.path + "/nested_path", mr.nested_with.path)
|
244
|
+
end
|
245
|
+
|
246
|
+
should 'instantiate on #construct' do
|
247
|
+
mr = MockResource.construct(test_mock_resource)
|
248
|
+
assert(mr.nested.is_a?(NestedResource))
|
249
|
+
assert(mr.nested_alt.is_a?(NestedResource))
|
250
|
+
assert(mr.nested_with.is_a?(NestedWithParent))
|
251
|
+
assert_equal(mr.path + "/nested_path", mr.nested_with.path)
|
252
|
+
end
|
253
|
+
|
254
|
+
should 'instantiate on #refresh_from' do
|
255
|
+
mr = MockResource.new('fake_id')
|
256
|
+
assert(mr.nested.nil?)
|
257
|
+
mr.refresh_from(test_mock_resource)
|
258
|
+
assert(mr.nested.is_a?(NestedResource))
|
259
|
+
assert(mr.nested_alt.is_a?(NestedResource))
|
260
|
+
assert(mr.nested_with.is_a?(NestedWithParent))
|
261
|
+
assert_equal(mr.path + "/nested_path", mr.nested_with.path)
|
262
|
+
end
|
263
|
+
|
264
|
+
should 'with default values' do
|
265
|
+
mr = MockResource.new('fake_id')
|
266
|
+
assert(mr.nested_with.is_a?(NestedWithParent))
|
267
|
+
assert_equal(mr.path + "/nested_path", mr.nested_with.path)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'APIClass :constructor' do
|
273
|
+
context 'for api_class_method' do
|
274
|
+
setup do
|
275
|
+
@mock.expects(:get).once.returns(test_response(test_mock_resource))
|
276
|
+
end
|
277
|
+
|
278
|
+
should 'create a new MockResource with :constructor => :self' do
|
279
|
+
mr = MockResource.with_con_self
|
280
|
+
assert(mr.is_a?(MockResource))
|
281
|
+
end
|
282
|
+
|
283
|
+
should 'create a new MockResource with :constructor => MockResource' do
|
284
|
+
mr = MockResource.with_con_class
|
285
|
+
assert(mr.is_a?(MockResource))
|
286
|
+
end
|
287
|
+
|
288
|
+
should 'use the lambda with :constructor => lambda{...}' do
|
289
|
+
mr = MockResource.with_con_lambda
|
290
|
+
assert_equal("lamdba result", mr)
|
291
|
+
end
|
292
|
+
|
293
|
+
should 'create a new MockResource with no constructor defined' do
|
294
|
+
mr = MockResource.with_con_default
|
295
|
+
assert(mr.is_a?(MockResource))
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context 'for api_instance_method' do
|
300
|
+
setup do
|
301
|
+
@mock.expects(:get).once.returns(test_response(test_mock_resource))
|
302
|
+
@mr = MockResource.new('fake_id')
|
303
|
+
end
|
304
|
+
|
305
|
+
should 'update this instance with :constructor => :self' do
|
306
|
+
@mr.with_con_self
|
307
|
+
assert(@mr.is_a?(MockResource))
|
308
|
+
assert_equal(test_mock_resource[:id], @mr.id)
|
309
|
+
end
|
310
|
+
|
311
|
+
should 'create a new instance with :constructor => MockResource' do
|
312
|
+
res = @mr.with_con_class
|
313
|
+
assert(res.is_a?(MockResource))
|
314
|
+
assert_not_equal(@mr.id, res.id)
|
315
|
+
end
|
316
|
+
|
317
|
+
should 'use the lambda with :constructor => lambda{...}' do
|
318
|
+
res = @mr.with_con_lambda
|
319
|
+
assert_equal("lamdba result", res)
|
320
|
+
end
|
321
|
+
|
322
|
+
should 'update this instance with no constructor defined' do
|
323
|
+
@mr.with_con_default
|
324
|
+
assert(@mr.is_a?(MockResource))
|
325
|
+
assert_equal(test_mock_resource[:id], @mr.id)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'APIClass api_*_method arguments' do
|
331
|
+
should 'throw an ArgumentError if too few arguments are provided' do
|
332
|
+
assert_raises(ArgumentError) { MockResource.retrieve }
|
333
|
+
end
|
334
|
+
|
335
|
+
should 'throw an ArgumentError with the name of missing arguments' do
|
336
|
+
begin
|
337
|
+
MockResource.retrieve
|
338
|
+
assert(false, "ArgumentError was expected.")
|
339
|
+
rescue ArgumentError => e
|
340
|
+
assert(e.message =~ /id/)
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
should 'throw an ArgumentError if too many arguments are provided' do
|
345
|
+
assert_raises(ArgumentError) { MockResource.retrieve(1, 2, {}, {}) }
|
346
|
+
end
|
347
|
+
|
348
|
+
should 'throw an ArgumentError if the param argument is invalid' do
|
349
|
+
assert_raises(ArgumentError) { MockResource.retrieve(1, 2) }
|
350
|
+
end
|
351
|
+
|
352
|
+
should 'throw an ArgumentError if the opts argument is invalid' do
|
353
|
+
assert_raises(ArgumentError) { MockResource.retrieve(1, {}, "abc") }
|
354
|
+
end
|
355
|
+
|
356
|
+
should 'not throw an ArgumentError if the opts or params are nil' do
|
357
|
+
@mock.expects(:get).times(2).returns(test_response(test_mock_resource))
|
358
|
+
MockResource.retrieve(1, nil, {})
|
359
|
+
MockResource.retrieve(1, {}, nil)
|
360
|
+
end
|
361
|
+
|
362
|
+
should 'urlencode unused arguments via GET' do
|
363
|
+
response = test_response(test_mock_resource)
|
364
|
+
@mock.expects(:get).with do |url, headers, params|
|
365
|
+
(url == "#{Checkr.api_base}#{MockResource.path}/bval/many?a=aval&c=cval" ||
|
366
|
+
url == "#{Checkr.api_base}#{MockResource.path}/bval/many?c=cval&a=aval") &&
|
367
|
+
params.nil?
|
368
|
+
end.returns(response)
|
369
|
+
|
370
|
+
MockResource.many_args_get("aval", "bval", "cval")
|
371
|
+
end
|
372
|
+
|
373
|
+
should 'assign unused arguments to the params payload via POST' do
|
374
|
+
response = test_response(test_mock_resource)
|
375
|
+
@mock.expects(:post).with("#{Checkr.api_base}#{MockResource.path}/bval/many", anything, { :a => "aval", :c => "cval" }).returns(response)
|
376
|
+
|
377
|
+
MockResource.many_args_post("aval", "bval", "cval")
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context 'APIClass api_instance_method paths' do
|
382
|
+
should 'use the provided argument if it is present' do
|
383
|
+
response = test_response(test_mock_resource)
|
384
|
+
@mock.expects(:get).with("#{Checkr.api_base}/custom_path", anything, anything).returns(response)
|
385
|
+
|
386
|
+
mr = MockResource.new(test_mock_resource)
|
387
|
+
mr.custom_path("/custom_path")
|
388
|
+
end
|
389
|
+
|
390
|
+
should 'use the instance method for path values' do
|
391
|
+
response = test_response(test_mock_resource)
|
392
|
+
name = "/mock_resource_name"
|
393
|
+
@mock.expects(:get).with("#{Checkr.api_base}#{name}", anything, anything).returns(response)
|
394
|
+
|
395
|
+
mr = MockResource.new(test_mock_resource)
|
396
|
+
mr.name = name
|
397
|
+
mr.name_path
|
398
|
+
end
|
399
|
+
|
400
|
+
should 'use the class method for path values' do
|
401
|
+
response = test_response(test_mock_resource)
|
402
|
+
@mock.expects(:get).with("#{Checkr.api_base}#{MockResource.crazy}", anything, anything).returns(response)
|
403
|
+
|
404
|
+
mr = MockResource.new(test_mock_resource)
|
405
|
+
mr.crazy_path
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
context 'APIClass api_class_method paths' do
|
410
|
+
should 'use the provided argument if it is present' do
|
411
|
+
response = test_response(test_mock_resource)
|
412
|
+
@mock.expects(:get).with("#{Checkr.api_base}#{MockResource.path}/fake_id", anything, anything).returns(response)
|
413
|
+
|
414
|
+
mr = MockResource.retrieve('fake_id')
|
415
|
+
end
|
416
|
+
|
417
|
+
should 'use the class method for path values' do
|
418
|
+
response = test_response(test_mock_resource)
|
419
|
+
@mock.expects(:get).with("#{Checkr.api_base}#{MockResource.crazy}", anything, anything).returns(response)
|
420
|
+
|
421
|
+
MockResource.crazy_path
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
end
|