onfido 0.15.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -49
  3. data/.travis.yml +3 -10
  4. data/CHANGELOG.md +24 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +2 -1
  7. data/README.md +46 -172
  8. data/lib/onfido.rb +4 -3
  9. data/lib/onfido/api.rb +21 -15
  10. data/lib/onfido/errors/connection_error.rb +2 -0
  11. data/lib/onfido/errors/onfido_error.rb +2 -0
  12. data/lib/onfido/errors/request_error.rb +2 -0
  13. data/lib/onfido/errors/server_error.rb +2 -0
  14. data/lib/onfido/options.rb +38 -0
  15. data/lib/onfido/resource.rb +44 -61
  16. data/lib/onfido/resources/address.rb +3 -4
  17. data/lib/onfido/resources/applicant.rb +8 -6
  18. data/lib/onfido/resources/check.rb +15 -19
  19. data/lib/onfido/resources/document.rb +13 -11
  20. data/lib/onfido/resources/extraction.rb +11 -0
  21. data/lib/onfido/resources/live_photo.rb +11 -14
  22. data/lib/onfido/resources/live_video.rb +7 -8
  23. data/lib/onfido/resources/report.rb +10 -9
  24. data/lib/onfido/resources/sdk_token.rb +5 -5
  25. data/lib/onfido/resources/webhook.rb +15 -11
  26. data/lib/onfido/version.rb +3 -1
  27. data/onfido.gemspec +10 -12
  28. data/spec/integrations/address_spec.rb +5 -2
  29. data/spec/integrations/applicant_spec.rb +29 -42
  30. data/spec/integrations/check_spec.rb +28 -69
  31. data/spec/integrations/document_spec.rb +22 -19
  32. data/spec/integrations/extraction_spec.rb +23 -0
  33. data/spec/integrations/live_photo_spec.rb +18 -15
  34. data/spec/integrations/live_video_spec.rb +13 -11
  35. data/spec/integrations/report_spec.rb +16 -13
  36. data/spec/integrations/resource_spec.rb +93 -0
  37. data/spec/integrations/sdk_token_spec.rb +10 -6
  38. data/spec/integrations/webhook_spec.rb +56 -37
  39. data/spec/onfido/api_spec.rb +14 -25
  40. data/spec/onfido/connection_error_spec.rb +4 -2
  41. data/spec/onfido/options_spec.rb +39 -0
  42. data/spec/onfido/request_error_spec.rb +4 -2
  43. data/spec/spec_helper.rb +3 -5
  44. data/spec/support/fake_onfido_api.rb +77 -88
  45. data/spec/support/fixtures/applicant.json +21 -42
  46. data/spec/support/fixtures/check.json +4 -4
  47. data/spec/support/fixtures/checks.json +4 -4
  48. data/spec/support/fixtures/document.json +2 -2
  49. data/spec/support/fixtures/documents.json +8 -8
  50. data/spec/support/fixtures/extraction.json +23 -0
  51. data/spec/support/fixtures/live_photo.json +3 -3
  52. data/spec/support/fixtures/live_photos.json +6 -6
  53. data/spec/support/fixtures/live_video.json +3 -3
  54. data/spec/support/fixtures/live_videos.json +4 -4
  55. data/spec/support/fixtures/report.json +4 -4
  56. data/spec/support/fixtures/reports.json +8 -8
  57. data/spec/support/fixtures/webhook.json +6 -5
  58. data/spec/support/fixtures/webhooks.json +17 -12
  59. metadata +25 -65
  60. data/Rakefile +0 -1
  61. data/lib/onfido/configuration.rb +0 -47
  62. data/lib/onfido/null_logger.rb +0 -5
  63. data/lib/onfido/resources/report_type_group.rb +0 -11
  64. data/spec/integrations/exceptions_spec.rb +0 -74
  65. data/spec/integrations/report_type_group_spec.rb +0 -19
  66. data/spec/onfido/resource_spec.rb +0 -137
  67. data/spec/onfido_spec.rb +0 -84
  68. data/spec/support/fixtures/check_with_expanded_reports.json +0 -30
  69. data/spec/support/fixtures/checks_with_expanded_reports.json +0 -34
  70. data/spec/support/fixtures/report_type_group.json +0 -25
  71. data/spec/support/fixtures/report_type_groups.json +0 -30
@@ -1,33 +1,22 @@
1
- describe Onfido::API do
2
- subject(:api) { described_class.new }
3
-
4
- describe 'given a single-word resource' do
5
- specify { expect(api.address).to be_a(Onfido::Address) }
6
- end
1
+ # frozen_string_literal: true
7
2
 
8
- describe 'given a multi-word resource' do
9
- specify { expect(api.live_photo).to be_a(Onfido::LivePhoto) }
10
- end
11
-
12
- describe 'given an unknown resource' do
13
- specify { expect { api.blood_test }.to raise_error(NameError) }
3
+ describe Onfido::API do
4
+ before do
5
+ allow(Onfido::Options).to receive(:new).and_call_original
14
6
  end
15
7
 
16
- describe 'given no API key' do
17
- it 'uses nil for the resource API key' do
18
- expect(Onfido::Address).to receive(:new).with(nil)
19
- api.address
20
- end
8
+ let(:options) do
9
+ {
10
+ api_key: 'test',
11
+ region: :eu,
12
+ open_timeout: 1,
13
+ read_timeout: 2
14
+ }
21
15
  end
22
16
 
23
- describe 'given an API key' do
24
- let(:api_key) { 'some_key' }
25
-
26
- subject(:api) { described_class.new(api_key: api_key) }
17
+ it 'passes through options' do
18
+ described_class.new(**options)
27
19
 
28
- it 'uses that key to create the resource' do
29
- expect(Onfido::Address).to receive(:new).with(api_key)
30
- api.address
31
- end
20
+ expect(Onfido::Options).to have_received(:new).with(**options)
32
21
  end
33
22
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::ConnectionError do
2
4
  subject(:error) do
3
5
  described_class.new(
4
- "Invalid response object from API",
6
+ 'Invalid response object from API',
5
7
  response_code: response_code,
6
8
  response_body: response_body
7
9
  )
@@ -10,7 +12,7 @@ describe Onfido::ConnectionError do
10
12
  let(:response_code) { nil }
11
13
  let(:response_body) { nil }
12
14
 
13
- context "without a response_body" do
15
+ context 'without a response_body' do
14
16
  its(:json_body) { is_expected.to be_nil }
15
17
  its(:type) { is_expected.to be_nil }
16
18
  its(:fields) { is_expected.to be_nil }
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Onfido::Options do
4
+ subject(:options) do
5
+ described_class.new(
6
+ api_key: 'test',
7
+ region: :us,
8
+ open_timeout: 1,
9
+ read_timeout: 2
10
+ )
11
+ end
12
+
13
+ it 'checks region is valid' do
14
+ expect { described_class.new(api_key: 'test', region: :aa) }.to raise_error 'Unknown region aa'
15
+ end
16
+
17
+ context 'when creating rest client resource' do
18
+ let(:rest_client) { options.rest_client }
19
+
20
+ it 'configures with headers' do
21
+ expect(rest_client.options[:headers]).to eq(
22
+ 'Accept' => 'application/json',
23
+ 'Authorization' => 'Token token=test',
24
+ 'User-Agent' => "onfido-ruby/#{Onfido::VERSION}"
25
+ )
26
+ end
27
+
28
+ it 'configures with region' do
29
+ expect(rest_client.url).to eq 'https://api.us.onfido.com/v3.1/'
30
+ end
31
+
32
+ it 'configures with timeouts' do
33
+ expect(rest_client.options).to include(
34
+ open_timeout: 1,
35
+ read_timeout: 2
36
+ )
37
+ end
38
+ end
39
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::RequestError do
2
4
  subject(:error) do
3
5
  described_class.new(
@@ -20,8 +22,8 @@ describe Onfido::RequestError do
20
22
  end
21
23
 
22
24
  it 'returns the right message' do
23
- expect { raise error }.
24
- to raise_error('Authorization error: please re-check your credentials')
25
+ expect { raise error }
26
+ .to raise_error('Authorization error: please re-check your credentials')
25
27
  end
26
28
 
27
29
  its(:type) { is_expected.to eq('authorization_error') }
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
- Dir[File.dirname(__FILE__).concat("/support/**/*.rb")].each { |f| require f }
5
+ Dir[File.dirname(__FILE__).concat('/support/**/*.rb')].sort.each { |f| require f }
4
6
 
5
7
  require 'onfido'
6
8
  require 'webmock/rspec'
@@ -40,8 +42,4 @@ RSpec.configure do |config|
40
42
  # test failures related to randomization by passing the same `--seed` value
41
43
  # as the one that triggered the failure.
42
44
  Kernel.srand config.seed
43
-
44
- config.before(:each) do
45
- stub_request(:any, /onfido.com/).to_rack(FakeOnfidoAPI)
46
- end
47
45
  end
@@ -1,188 +1,177 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sinatra/base'
2
4
 
3
- class FakeOnfidoAPI < Sinatra::Base
4
- get '/v2/addresses/pick' do
5
+ RSpec.shared_context 'fake onfido api' do
6
+ let(:onfido) { Onfido::API.new(api_key: 'test', region: :eu) }
7
+
8
+ before { stub_request(:any, /api.eu.onfido.com/).to_rack(FakeOnfidoAPI) }
9
+ end
10
+
11
+ class FakeOnfidoAPI < Sinatra::Base # rubocop:disable Metrics/ClassLength
12
+ get '/v3.1/addresses/pick' do
5
13
  json_response(200, 'addresses.json')
6
14
  end
7
15
 
8
- post '/v2/applicants' do
16
+ post '/v3.1/applicants' do
9
17
  json_response(201, 'applicant.json')
10
18
  end
11
19
 
12
- put '/v2/applicants/:id' do
20
+ put '/v3.1/applicants/:id' do
13
21
  json_response(200, 'applicant.json')
14
22
  end
15
23
 
16
- get '/v2/applicants/:id' do
24
+ get '/v3.1/applicants/:id' do
17
25
  json_response(200, 'applicant.json')
18
26
  end
19
27
 
20
- get '/v2/applicants' do
28
+ get '/v3.1/applicants' do
21
29
  response = json_response(200, 'applicants.json')
22
30
  { applicants: JSON.parse(response)['applicants'][pagination_range] }.to_json
23
31
  end
24
32
 
25
- delete '/v2/applicants/:id' do
33
+ delete '/v3.1/applicants/:id' do
26
34
  status 204
27
35
  end
28
36
 
29
- post '/v2/applicants/:id/restore' do
30
- if params["id"] == "a2fb9c62-ab10-4898-a8ec-342c4b552ad5"
37
+ post '/v3.1/applicants/:id/restore' do
38
+ if params['id'] == 'a2fb9c62-ab10-4898-a8ec-342c4b552ad5'
31
39
  json_response(422, 'not_scheduled_for_deletion_error.json')
32
40
  else
33
41
  status 204
34
42
  end
35
43
  end
36
44
 
37
- post '/v2/applicants/:id/documents' do
45
+ post '/v3.1/documents' do
38
46
  json_response(201, 'document.json')
39
47
  end
40
48
 
41
- get '/v2/applicants/:id/documents/:id' do
49
+ post '/v3.1/extractions' do
50
+ json_response(201, 'extraction.json')
51
+ end
52
+
53
+ get '/v3.1/documents/:id' do
42
54
  json_response(200, 'document.json')
43
55
  end
44
56
 
45
- get '/v2/applicants/:id/documents' do
57
+ get '/v3.1/documents' do
46
58
  json_response(200, 'documents.json')
47
59
  end
48
60
 
49
- get '/v2/applicants/:id/documents/:id/download' do
61
+ get '/v3.1/documents/:id/download' do
50
62
  status 200
51
63
  content_type 'application/octet-stream'
52
64
  "\x01\x02\x03" # acts as binary file data
53
65
  end
54
66
 
55
- post '/v2/live_photos' do
67
+ post '/v3.1/live_photos' do
56
68
  json_response(201, 'live_photo.json')
57
69
  end
58
70
 
59
- get '/v2/live_photos/:id' do
60
- if params["applicant_id"] != "1030303-123123-123123"
61
- status 404
62
- else
63
- json_response(200, 'live_photo.json')
64
- end
71
+ get '/v3.1/live_photos/:id' do
72
+ json_response(200, 'live_photo.json')
65
73
  end
66
74
 
67
- get '/v2/live_photos' do
68
- if params["applicant_id"] != "1030303-123123-123123"
69
- status 404
70
- else
75
+ get '/v3.1/live_photos' do
76
+ if params['applicant_id'] == '1030303-123123-123123'
71
77
  json_response(200, 'live_photos.json')
72
- end
73
- end
74
-
75
- get '/v2/live_photos/:id/download' do
76
- if params["applicant_id"] != "1030303-123123-123123"
77
- status 404
78
78
  else
79
- status 200
80
- content_type 'image/jpeg'
81
- "\x01\x02\x03" # acts as binary file data
79
+ status 404
82
80
  end
83
81
  end
84
82
 
85
- get '/v2/live_videos/:id' do
86
- if params["applicant_id"] != "1030303-123123-123123"
87
- status 404
88
- else
89
- json_response(200, 'live_video.json')
90
- end
83
+ get '/v3.1/live_photos/:id/download' do
84
+ status 200
85
+ content_type 'image/jpeg'
86
+ "\x01\x02\x03" # acts as binary file data
91
87
  end
92
88
 
93
- get '/v2/live_videos' do
94
- if params["applicant_id"] != "1030303-123123-123123"
95
- status 404
96
- else
97
- json_response(200, 'live_videos.json')
98
- end
89
+ get '/v3.1/live_videos/:id' do
90
+ json_response(200, 'live_video.json')
99
91
  end
100
92
 
101
- get '/v2/live_videos/:id/download' do
102
- if params["applicant_id"] != "1030303-123123-123123"
103
- status 404
93
+ get '/v3.1/live_videos' do
94
+ if params['applicant_id'] == '1030303-123123-123123'
95
+ json_response(200, 'live_videos.json')
104
96
  else
105
- status 200
106
- content_type 'video/quicktime'
107
- "\x01\x02\x03" # acts as binary file data
97
+ status 404
108
98
  end
109
99
  end
110
100
 
111
- post '/v2/applicants/:id/checks' do
112
- json_response(201, 'check.json')
101
+ get '/v3.1/live_videos/:id/download' do
102
+ status 200
103
+ content_type 'video/quicktime'
104
+ "\x01\x02\x03" # acts as binary file data
113
105
  end
114
106
 
115
- get '/v2/applicants/:id/checks/:id' do
116
- if params["expand"] == "reports"
117
- json_response(200, "check_with_expanded_reports.json")
118
- else
119
- json_response(200, "check.json")
120
- end
107
+ post '/v3.1/checks' do
108
+ params['applicant_id'].nil? ? status(422) : json_response(201, 'check.json')
121
109
  end
122
110
 
123
- get '/v2/applicants/:id/checks' do
124
- response = if params["expand"] == "reports"
125
- json_response(200, "checks_with_expanded_reports.json")
126
- else
127
- json_response(200, "checks.json")
128
- end
111
+ get '/v3.1/checks/:id' do
112
+ json_response(200, 'check.json')
113
+ end
129
114
 
130
- { checks: JSON.parse(response)['checks'][pagination_range] }.to_json
115
+ get '/v3.1/checks' do
116
+ json_response(200, 'checks.json')
131
117
  end
132
118
 
133
- post '/v2/checks/:id/resume' do
119
+ post '/v3.1/checks/:id/resume' do
134
120
  status 204 # no_content
135
121
  end
136
122
 
137
- get '/v2/checks/:id/reports' do
123
+ get '/v3.1/checks/:id/download' do
124
+ status 200
125
+ content_type 'application/pdf'
126
+ "\x01\x02\x03" # acts as binary file data
127
+ end
128
+
129
+ get '/v3.1/reports' do
138
130
  json_response(200, 'reports.json')
139
131
  end
140
132
 
141
- get '/v2/checks/:id/reports/:id' do
133
+ get '/v3.1/reports/:id' do
142
134
  json_response(200, 'report.json')
143
135
  end
144
136
 
145
- post '/v2/checks/:id/reports/:id/resume' do
137
+ post '/v3.1/reports/:id/resume' do
146
138
  status 204
147
139
  end
148
140
 
149
- post '/v2/checks/:id/reports/:id/cancel' do
141
+ post '/v3.1/reports/:id/cancel' do
150
142
  status 204
151
143
  end
152
144
 
153
- get '/v2/report_type_groups/:id' do
154
- json_response(200, 'report_type_group.json')
155
- end
156
-
157
- get '/v2/report_type_groups' do
158
- json_response(200, 'report_type_groups.json')
159
- end
160
-
161
- post '/v2/sdk_token' do
145
+ post '/v3.1/sdk_token' do
162
146
  json_response(201, 'sdk_token.json')
163
147
  end
164
148
 
165
- post '/v2/webhooks' do
149
+ post '/v3.1/webhooks' do
166
150
  json_response(201, 'webhook.json')
167
151
  end
168
152
 
169
- get '/v2/webhooks/:id' do
153
+ get '/v3.1/webhooks/:id' do
170
154
  json_response(200, 'webhook.json')
171
155
  end
172
156
 
173
- get '/v2/webhooks' do
157
+ delete '/v3.1/webhooks/:id' do
158
+ content_type 'application/json; charset=utf-8'
159
+ status 204
160
+ end
161
+
162
+ get '/v3.1/webhooks' do
174
163
  json_response(200, 'webhooks.json')
175
164
  end
176
165
 
177
- get '/v2/4xx_response' do
166
+ get '/v3.1/4xx_response' do
178
167
  json_response(422, '4xx_response.json')
179
168
  end
180
169
 
181
- get '/v2/unexpected_error_format' do
170
+ get '/v3.1/unexpected_error_format' do
182
171
  json_response(400, 'unexpected_error_format.json')
183
172
  end
184
173
 
185
- get '/v2/unparseable_response' do
174
+ get '/v3.1/unparseable_response' do
186
175
  content_type :json
187
176
  status 504
188
177
  ''
@@ -191,9 +180,9 @@ class FakeOnfidoAPI < Sinatra::Base
191
180
  private
192
181
 
193
182
  def json_response(response_code, file_name)
194
- content_type "application/json; charset=utf-8"
183
+ content_type 'application/json; charset=utf-8'
195
184
  status response_code
196
- File.open(File.dirname(__FILE__) + '/fixtures/' + file_name, 'rb').read
185
+ File.open("#{File.dirname(__FILE__)}/fixtures/#{file_name}", 'rb').read
197
186
  end
198
187
 
199
188
  def pagination_range
@@ -1,44 +1,23 @@
1
1
  {
2
- "id":"61f659cb-c90b-4067-808a-6136b5c01351",
3
- "created_at":"2015-04-10T13:16:01Z",
4
- "title":"Mr",
5
- "first_name":"Chandler",
6
- "middle_name":"Muriel",
7
- "last_name":"Bing",
8
- "email":"chandler_bing_6@friends.com",
9
- "gender":"Male",
10
- "dob":"1968-04-08",
11
- "telephone":"555555555",
12
- "mobile":"77777777",
13
- "country":"gbr",
14
- "href":"/v2/applicants/61f659cb-c90b-4067-808a-6136b5c01351",
15
- "id_numbers":[],
16
- "addresses": [
17
- {
18
- "flat_number":"4",
19
- "building_number":"100",
20
- "building_name":"Awesome Building",
21
- "street":"Main Street",
22
- "sub_street":"A sub street",
23
- "town":"London",
24
- "state":"",
25
- "postcode":"SW4 6EH",
26
- "country":"GBR",
27
- "start_date":"",
28
- "end_date":""
29
- },
30
- {
31
- "flat_number":"1",
32
- "building_number":"10",
33
- "building_name":"Great Building",
34
- "street":"Old Street",
35
- "sub_street":"Sub Street",
36
- "town":"London",
37
- "state":"",
38
- "postcode":"SW1 4NG",
39
- "country":"GBR",
40
- "start_date":"",
41
- "end_date":""
42
- }
43
- ]
2
+ "id":"61f659cb-c90b-4067-808a-6136b5c01351",
3
+ "created_at":"2015-04-10T13:16:01Z",
4
+ "title":"Mr",
5
+ "first_name":"Chandler",
6
+ "middle_name":"Muriel",
7
+ "last_name":"Bing",
8
+ "email":"chandler_bing_6@friends.com",
9
+ "dob":"1968-04-08",
10
+ "href":"/v3.1/applicants/61f659cb-c90b-4067-808a-6136b5c01351",
11
+ "id_numbers":[],
12
+ "address": {
13
+ "flat_number":"4",
14
+ "building_number":"100",
15
+ "building_name":"Awesome Building",
16
+ "street":"Main Street",
17
+ "sub_street":"A sub street",
18
+ "town":"London",
19
+ "state":"",
20
+ "postcode":"SW4 6EH",
21
+ "country":"GBR"
22
+ }
44
23
  }