onfido 1.1.0 → 2.1.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.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/gem-push.yml +31 -0
  3. data/.github/workflows/ruby.yml +25 -0
  4. data/.rubocop.yml +5 -49
  5. data/.travis.yml +2 -8
  6. data/CHANGELOG.md +26 -1
  7. data/Gemfile +2 -0
  8. data/README.md +37 -148
  9. data/lib/onfido.rb +3 -3
  10. data/lib/onfido/api.rb +18 -12
  11. data/lib/onfido/errors/connection_error.rb +2 -0
  12. data/lib/onfido/errors/onfido_error.rb +2 -0
  13. data/lib/onfido/errors/request_error.rb +2 -0
  14. data/lib/onfido/errors/server_error.rb +2 -0
  15. data/lib/onfido/options.rb +38 -0
  16. data/lib/onfido/resource.rb +48 -59
  17. data/lib/onfido/resources/address.rb +3 -4
  18. data/lib/onfido/resources/applicant.rb +2 -0
  19. data/lib/onfido/resources/check.rb +6 -0
  20. data/lib/onfido/resources/document.rb +2 -0
  21. data/lib/onfido/resources/extraction.rb +2 -0
  22. data/lib/onfido/resources/live_photo.rb +2 -0
  23. data/lib/onfido/resources/live_video.rb +2 -0
  24. data/lib/onfido/resources/report.rb +2 -0
  25. data/lib/onfido/resources/sdk_token.rb +2 -0
  26. data/lib/onfido/resources/webhook.rb +4 -2
  27. data/lib/onfido/version.rb +3 -1
  28. data/onfido.gemspec +5 -6
  29. data/spec/integrations/address_spec.rb +4 -2
  30. data/spec/integrations/applicant_spec.rb +12 -7
  31. data/spec/integrations/check_spec.rb +17 -4
  32. data/spec/integrations/document_spec.rb +7 -3
  33. data/spec/integrations/extraction_spec.rb +6 -2
  34. data/spec/integrations/live_photo_spec.rb +7 -3
  35. data/spec/integrations/live_video_spec.rb +6 -1
  36. data/spec/integrations/report_spec.rb +6 -1
  37. data/spec/integrations/resource_spec.rb +106 -0
  38. data/spec/integrations/sdk_token_spec.rb +5 -1
  39. data/spec/integrations/webhook_spec.rb +28 -24
  40. data/spec/onfido/api_spec.rb +14 -25
  41. data/spec/onfido/connection_error_spec.rb +4 -2
  42. data/spec/onfido/options_spec.rb +39 -0
  43. data/spec/onfido/request_error_spec.rb +4 -2
  44. data/spec/spec_helper.rb +3 -5
  45. data/spec/support/fake_onfido_api.rb +63 -49
  46. data/spec/support/fixtures/applicant.json +1 -1
  47. data/spec/support/fixtures/check.json +1 -1
  48. data/spec/support/fixtures/checks.json +1 -1
  49. data/spec/support/fixtures/document.json +1 -1
  50. data/spec/support/fixtures/documents.json +2 -2
  51. data/spec/support/fixtures/live_photo.json +2 -2
  52. data/spec/support/fixtures/live_photos.json +4 -4
  53. data/spec/support/fixtures/live_video.json +2 -2
  54. data/spec/support/fixtures/live_videos.json +2 -2
  55. data/spec/support/fixtures/report.json +1 -1
  56. data/spec/support/fixtures/reports.json +2 -2
  57. data/spec/support/fixtures/webhook.json +1 -1
  58. data/spec/support/fixtures/webhooks.json +2 -2
  59. metadata +16 -33
  60. data/Rakefile +0 -1
  61. data/lib/onfido/configuration.rb +0 -47
  62. data/lib/onfido/null_logger.rb +0 -5
  63. data/spec/integrations/exceptions_spec.rb +0 -73
  64. data/spec/onfido/resource_spec.rb +0 -133
  65. data/spec/onfido_spec.rb +0 -83
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Address do
2
- subject(:api) { Onfido::API.new }
4
+ include_context 'fake onfido api'
3
5
 
4
6
  describe '#all' do
5
7
  it 'returns the addresses matching the postcode' do
6
- response = api.address.all('SW1 4NG')
8
+ response = onfido.address.all('SW1 4NG')
7
9
 
8
10
  expect(response['addresses'].count).to eq(2)
9
11
  end
@@ -1,5 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Applicant do
2
- subject(:applicant) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:applicant) { onfido.applicant }
7
+
3
8
  let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
4
9
  let(:params) do
5
10
  {
@@ -29,9 +34,9 @@ describe Onfido::Applicant do
29
34
 
30
35
  it 'serializes the payload correctly' do
31
36
  WebMock.after_request do |request_signature, _response|
32
- if request_signature.uri.path == 'v3/applicants'
33
- expect(Rack::Utils.parse_nested_query(request_signature.body)).
34
- to eq(params)
37
+ if request_signature.uri.path == 'v3.2/applicants'
38
+ expect(Rack::Utils.parse_nested_query(request_signature.body))
39
+ .to eq(params)
35
40
  end
36
41
  end
37
42
  end
@@ -93,13 +98,13 @@ describe Onfido::Applicant do
93
98
  it 'returns an error' do
94
99
  applicant_id = 'a2fb9c62-ab10-4898-a8ec-342c4b552ad5'
95
100
 
96
- expect { applicant.restore(applicant_id) }.to raise_error { |error|
101
+ expect { applicant.restore(applicant_id) }.to raise_error do |error|
97
102
  expect(error).to be_a(Onfido::RequestError)
98
103
  expect(error.message).to eq('There was a validation error on this request')
99
104
  expect(error.fields).to eq(
100
- "Applicant a2fb9c62-ab10-4898-a8ec-342c4b552ad5 is not scheduled for deletion"
105
+ 'Applicant a2fb9c62-ab10-4898-a8ec-342c4b552ad5 is not scheduled for deletion'
101
106
  )
102
- }
107
+ end
103
108
  end
104
109
  end
105
110
  end
@@ -1,5 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Check do
2
- subject(:check) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:check) { onfido.check }
7
+
3
8
  let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
4
9
  let(:check_id) { '8546921-123123-123123' }
5
10
 
@@ -20,7 +25,7 @@ describe Onfido::Check do
20
25
  expect(response['id']).to eq(check_id)
21
26
  end
22
27
 
23
- it "returns report_ids" do
28
+ it 'returns report_ids' do
24
29
  response = check.find(check_id)
25
30
 
26
31
  expect(response['report_ids'].first).to be_a(String)
@@ -36,16 +41,24 @@ describe Onfido::Check do
36
41
  end
37
42
  end
38
43
 
39
- it "returns report_ids" do
44
+ it 'returns report_ids' do
40
45
  response = check.all(applicant_id)
41
46
 
42
47
  expect(response['checks'].first['report_ids'].first).to be_a(String)
43
48
  end
44
49
  end
45
50
 
46
- describe "#resume" do
51
+ describe '#resume' do
47
52
  it 'returns success response' do
48
53
  expect { check.resume(check_id) }.not_to raise_error
49
54
  end
50
55
  end
56
+
57
+ describe '#download' do
58
+ it 'returns the file data' do
59
+ response = check.download(check_id)
60
+
61
+ expect(response).not_to be_nil
62
+ end
63
+ end
51
64
  end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tempfile'
2
4
 
3
5
  describe Onfido::Document do
4
- subject(:document) { described_class.new }
6
+ include_context 'fake onfido api'
7
+
8
+ subject(:document) { onfido.document }
5
9
 
6
10
  describe '#create' do
7
11
  let(:params) do
@@ -32,8 +36,8 @@ describe Onfido::Document do
32
36
  let(:file) { 'https://onfido.com/images/logo.png' }
33
37
 
34
38
  it 'raises an ArgumentError' do
35
- expect { document.create(**params) }.
36
- to raise_error(ArgumentError, /must be a `File`-like object/)
39
+ expect { document.create(**params) }
40
+ .to raise_error(ArgumentError, /must be a `File`-like object/)
37
41
  end
38
42
  end
39
43
  end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tempfile'
2
4
 
3
5
  describe Onfido::Extraction do
4
- subject(:extraction) { described_class.new }
6
+ include_context 'fake onfido api'
7
+
8
+ subject(:extraction) { onfido.extraction }
5
9
 
6
10
  describe '#create' do
7
11
  let(:params) do
@@ -11,7 +15,7 @@ describe Onfido::Extraction do
11
15
  end
12
16
 
13
17
  it 'creates a new extraction' do
14
- response = extraction.create(params)
18
+ response = extraction.create(**params)
15
19
 
16
20
  expect(response['document_id']).to eq('7568415-123123-123123')
17
21
  end
@@ -1,7 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tempfile'
2
4
 
3
5
  describe Onfido::LivePhoto do
4
- subject(:live_photo) { described_class.new }
6
+ include_context 'fake onfido api'
7
+
8
+ subject(:live_photo) { onfido.live_photo }
5
9
 
6
10
  describe '#create' do
7
11
  let(:params) { { applicant_id: '123456', file: file } }
@@ -25,8 +29,8 @@ describe Onfido::LivePhoto do
25
29
  let(:file) { 'https://onfido.com/images/photo.jpg' }
26
30
 
27
31
  it 'raises an ArgumentError' do
28
- expect { live_photo.create(**params) }.
29
- to raise_error(ArgumentError, /must be a `File`-like object/)
32
+ expect { live_photo.create(**params) }
33
+ .to raise_error(ArgumentError, /must be a `File`-like object/)
30
34
  end
31
35
  end
32
36
  end
@@ -1,7 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tempfile'
2
4
 
3
5
  describe Onfido::LiveVideo do
4
- subject(:live_video) { described_class.new }
6
+ include_context 'fake onfido api'
7
+
8
+ subject(:live_video) { onfido.live_video }
9
+
5
10
  let(:live_video_id) { 'c9701e9b-83aa-442f-995b-20320ee8fb01' }
6
11
 
7
12
  describe '#find' do
@@ -1,5 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Report do
2
- subject(:report) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:report) { onfido.report }
7
+
3
8
  describe '#find' do
4
9
  it 'returns a report for an existing check' do
5
10
  report_id = '6951786-123123-422221'
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TestResource < Onfido::Resource
4
+ def get(path:)
5
+ super(path: path)
6
+ end
7
+ end
8
+
9
+ describe Onfido::Resource do
10
+ include_context 'fake onfido api'
11
+
12
+ subject(:resource) { TestResource.new(Onfido::Options.new(api_key: 'test', region: :eu)) }
13
+
14
+ context '4xx response' do
15
+ it 'raises a custom error' do
16
+ path = '4xx_response'
17
+
18
+ expect { resource.get(path: path) }
19
+ .to raise_error(Onfido::RequestError, 'Something went wrong')
20
+ end
21
+ end
22
+
23
+ context 'unexpected error format' do
24
+ it 'raises a custom error' do
25
+ path = 'unexpected_error_format'
26
+
27
+ expect { resource.get(path: path) }
28
+ .to raise_error(Onfido::RequestError, /response code was 400/)
29
+ end
30
+ end
31
+
32
+ context 'unparseable JSON 5xx' do
33
+ it 'raises a server error' do
34
+ path = 'unparseable_response'
35
+
36
+ expect { resource.get(path: path) }
37
+ .to raise_error(Onfido::ServerError, /response code was 504/)
38
+ end
39
+ end
40
+
41
+ context 'timeout' do
42
+ before do
43
+ allow(RestClient::Request)
44
+ .to receive(:execute)
45
+ .and_raise(RestClient::RequestTimeout)
46
+ end
47
+
48
+ it 'raises a ConnectionError' do
49
+ expect { resource.get(path: '') }
50
+ .to raise_error(Onfido::ConnectionError, /Could not connect/)
51
+ end
52
+ end
53
+
54
+ context 'RestClient : BadGateway' do
55
+ before do
56
+ allow(RestClient::Request)
57
+ .to receive(:execute)
58
+ .and_raise(RestClient::BadGateway)
59
+ end
60
+
61
+ it 'raises a ConnectionError' do
62
+ expect { resource.get(path: '') }
63
+ .to raise_error(Onfido::ConnectionError, /Could not connect/)
64
+ end
65
+ end
66
+
67
+ context 'broken connection' do
68
+ before do
69
+ allow(RestClient::Request)
70
+ .to receive(:execute)
71
+ .and_raise(RestClient::ServerBrokeConnection)
72
+ end
73
+
74
+ it 'raises a ConnectionError' do
75
+ expect { resource.get(path: '') }
76
+ .to raise_error(Onfido::ConnectionError, /connection to the server/)
77
+ end
78
+ end
79
+
80
+ context 'bad SSL certificate' do
81
+ before do
82
+ allow(RestClient::Request)
83
+ .to receive(:execute)
84
+ .and_raise(RestClient::SSLCertificateNotVerified.new(nil))
85
+ end
86
+
87
+ it 'raises a ConnectionError' do
88
+ expect { resource.get(path: '') }
89
+ .to raise_error(Onfido::ConnectionError, /SSL certificate/)
90
+ end
91
+ end
92
+
93
+ context 'with a timeout error response' do
94
+ before do
95
+ allow_any_instance_of(RestClient::ExceptionWithResponse)
96
+ .to receive(:response).and_return(double(body: '', code: '408'))
97
+ expect(RestClient::Request).to receive(:execute)
98
+ .and_raise(RestClient::ExceptionWithResponse)
99
+ end
100
+
101
+ it 'raises a ConnectionError' do
102
+ expect { resource.get(path: '') }
103
+ .to raise_error(Onfido::ConnectionError)
104
+ end
105
+ end
106
+ end
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::SdkToken do
2
- subject(:sdk_token) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:sdk_token) { onfido.sdk_token }
3
7
 
4
8
  describe '#create' do
5
9
  it 'creates a new SDK token for the applicant' do
@@ -1,28 +1,32 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Webhook do
2
- subject(:webhook) { described_class.new }
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:webhook) { onfido.webhook }
3
7
 
4
- describe "#create" do
8
+ describe '#create' do
5
9
  let(:params) do
6
10
  {
7
- url: "https://webhookendpoint.url",
11
+ url: 'https://webhookendpoint.url',
8
12
  enabled: true,
9
13
  events: [
10
- "report.completed",
11
- "check.completed"
14
+ 'report.completed',
15
+ 'check.completed'
12
16
  ]
13
17
  }
14
18
  end
15
19
 
16
- it "creates the webhook" do
20
+ it 'creates the webhook' do
17
21
  response = webhook.create(**params)
18
22
 
19
23
  expect(response['id']).to_not be_nil
20
24
  end
21
25
 
22
- it "responds with the right url" do
26
+ it 'responds with the right url' do
23
27
  response = webhook.create(**params)
24
28
 
25
- expect(response["url"]).to eq params[:url]
29
+ expect(response['url']).to eq params[:url]
26
30
  end
27
31
  end
28
32
 
@@ -36,29 +40,29 @@ describe Onfido::Webhook do
36
40
  end
37
41
  end
38
42
 
39
- describe "#destroy" do
40
- it "removes the webhook" do
43
+ describe '#destroy' do
44
+ it 'removes the webhook' do
41
45
  webhook_id = 'fcb73186-0733-4f6f-9c57-d9d5ef979443'
42
46
  expect { webhook.destroy(webhook_id) }.not_to raise_error
43
47
  end
44
48
  end
45
49
 
46
- describe "#all" do
47
- it "returns all the registered webhooks" do
50
+ describe '#all' do
51
+ it 'returns all the registered webhooks' do
48
52
  response = webhook.all
49
53
 
50
- expect(response["webhooks"].count).to eq 2
54
+ expect(response['webhooks'].count).to eq 2
51
55
  end
52
56
 
53
- it "returns with id" do
57
+ it 'returns with id' do
54
58
  response = webhook.all
55
59
 
56
- expect(response["webhooks"][0]["id"]).to_not be_nil
57
- expect(response["webhooks"][1]["id"]).to_not be_nil
60
+ expect(response['webhooks'][0]['id']).to_not be_nil
61
+ expect(response['webhooks'][1]['id']).to_not be_nil
58
62
  end
59
63
  end
60
64
 
61
- describe ".valid?" do
65
+ describe '.valid?' do
62
66
  subject(:valid?) do
63
67
  described_class.valid?(request_body, request_signature, token)
64
68
  end
@@ -71,34 +75,34 @@ describe Onfido::Webhook do
71
75
 
72
76
  it { is_expected.to be(true) }
73
77
 
74
- context "with an invalid signature" do
78
+ context 'with an invalid signature' do
75
79
  let(:request_signature) do
76
80
  's21fd54ew2w1f5d15642132f3d7727ff9a32a7c87072ce514df1f6d3228bec'
77
81
  end
78
82
  it { is_expected.to be(false) }
79
83
  end
80
84
 
81
- context "with a nil request signature" do
85
+ context 'with a nil request signature' do
82
86
  let(:request_signature) { nil }
83
87
  specify { expect { valid? }.to raise_error(ArgumentError) }
84
88
  end
85
89
 
86
- context "with a token other than the one used to sign the request" do
87
- let(:token) { "quite_secret_token" }
90
+ context 'with a token other than the one used to sign the request' do
91
+ let(:token) { 'quite_secret_token' }
88
92
  it { is_expected.to be(false) }
89
93
  end
90
94
 
91
- context "with a nil token" do
95
+ context 'with a nil token' do
92
96
  let(:token) { nil }
93
97
  specify { expect { valid? }.to raise_error(ArgumentError) }
94
98
  end
95
99
 
96
- context "with a modified request body" do
100
+ context 'with a modified request body' do
97
101
  let(:request_body) { '{"bar":"baz"}' }
98
102
  it { is_expected.to be(false) }
99
103
  end
100
104
 
101
- context "with a nil request body" do
105
+ context 'with a nil request body' do
102
106
  let(:request_body) { nil }
103
107
  specify { expect { valid? }.to raise_error(ArgumentError) }
104
108
  end
@@ -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