onfido 0.15.1 → 2.0.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  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 +3 -10
  6. data/CHANGELOG.md +28 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE +2 -1
  9. data/README.md +46 -172
  10. data/lib/onfido.rb +4 -4
  11. data/lib/onfido/api.rb +21 -15
  12. data/lib/onfido/errors/connection_error.rb +2 -0
  13. data/lib/onfido/errors/onfido_error.rb +2 -0
  14. data/lib/onfido/errors/request_error.rb +2 -0
  15. data/lib/onfido/errors/server_error.rb +2 -0
  16. data/lib/onfido/options.rb +38 -0
  17. data/lib/onfido/resource.rb +44 -61
  18. data/lib/onfido/resources/address.rb +3 -2
  19. data/lib/onfido/resources/applicant.rb +8 -6
  20. data/lib/onfido/resources/check.rb +15 -19
  21. data/lib/onfido/resources/document.rb +13 -11
  22. data/lib/onfido/resources/extraction.rb +11 -0
  23. data/lib/onfido/resources/live_photo.rb +11 -14
  24. data/lib/onfido/resources/live_video.rb +7 -8
  25. data/lib/onfido/resources/report.rb +10 -9
  26. data/lib/onfido/resources/sdk_token.rb +5 -5
  27. data/lib/onfido/resources/webhook.rb +15 -11
  28. data/lib/onfido/version.rb +3 -1
  29. data/onfido.gemspec +10 -12
  30. data/spec/integrations/address_spec.rb +5 -2
  31. data/spec/integrations/applicant_spec.rb +29 -42
  32. data/spec/integrations/check_spec.rb +28 -69
  33. data/spec/integrations/document_spec.rb +22 -19
  34. data/spec/integrations/extraction_spec.rb +23 -0
  35. data/spec/integrations/live_photo_spec.rb +18 -15
  36. data/spec/integrations/live_video_spec.rb +13 -11
  37. data/spec/integrations/report_spec.rb +16 -13
  38. data/spec/integrations/resource_spec.rb +93 -0
  39. data/spec/integrations/sdk_token_spec.rb +10 -6
  40. data/spec/integrations/webhook_spec.rb +56 -37
  41. data/spec/onfido/api_spec.rb +14 -25
  42. data/spec/onfido/connection_error_spec.rb +4 -2
  43. data/spec/onfido/options_spec.rb +39 -0
  44. data/spec/onfido/request_error_spec.rb +4 -2
  45. data/spec/spec_helper.rb +3 -5
  46. data/spec/support/fake_onfido_api.rb +77 -88
  47. data/spec/support/fixtures/applicant.json +21 -42
  48. data/spec/support/fixtures/check.json +4 -4
  49. data/spec/support/fixtures/checks.json +4 -4
  50. data/spec/support/fixtures/document.json +2 -2
  51. data/spec/support/fixtures/documents.json +8 -8
  52. data/spec/support/fixtures/extraction.json +23 -0
  53. data/spec/support/fixtures/live_photo.json +3 -3
  54. data/spec/support/fixtures/live_photos.json +6 -6
  55. data/spec/support/fixtures/live_video.json +3 -3
  56. data/spec/support/fixtures/live_videos.json +4 -4
  57. data/spec/support/fixtures/report.json +4 -4
  58. data/spec/support/fixtures/reports.json +8 -8
  59. data/spec/support/fixtures/webhook.json +6 -5
  60. data/spec/support/fixtures/webhooks.json +17 -12
  61. metadata +27 -65
  62. data/Rakefile +0 -1
  63. data/lib/onfido/configuration.rb +0 -47
  64. data/lib/onfido/null_logger.rb +0 -5
  65. data/lib/onfido/resources/report_type_group.rb +0 -11
  66. data/spec/integrations/exceptions_spec.rb +0 -74
  67. data/spec/integrations/report_type_group_spec.rb +0 -19
  68. data/spec/onfido/resource_spec.rb +0 -137
  69. data/spec/onfido_spec.rb +0 -84
  70. data/spec/support/fixtures/check_with_expanded_reports.json +0 -30
  71. data/spec/support/fixtures/checks_with_expanded_reports.json +0 -34
  72. data/spec/support/fixtures/report_type_group.json +0 -25
  73. data/spec/support/fixtures/report_type_groups.json +0 -30
@@ -1,20 +1,24 @@
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
8
12
  {
9
- type: 'passport',
10
- side: 'back',
11
- file: file
13
+ applicant_id: '1030303-123123-123123',
14
+ type: 'driving_licence',
15
+ file: file,
16
+ side: 'front'
12
17
  }
13
18
  end
14
- let(:applicant_id) { '1030303-123123-123123' }
15
19
 
16
20
  context 'with a File-like object to upload' do
17
- let(:file) { Tempfile.new(['passport', '.jpg']) }
21
+ let(:file) { Tempfile.new(['driving_licence', '.jpg']) }
18
22
 
19
23
  after do
20
24
  file.close
@@ -22,7 +26,8 @@ describe Onfido::Document do
22
26
  end
23
27
 
24
28
  it 'creates a new document' do
25
- response = document.create('foobar', params)
29
+ response = document.create(**params)
30
+
26
31
  expect(response['id']).not_to be_nil
27
32
  end
28
33
  end
@@ -31,37 +36,35 @@ describe Onfido::Document do
31
36
  let(:file) { 'https://onfido.com/images/logo.png' }
32
37
 
33
38
  it 'raises an ArgumentError' do
34
- expect { document.create('foobar', params) }.
35
- 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/)
36
41
  end
37
42
  end
38
43
  end
39
44
 
40
45
  describe '#find' do
41
- let(:applicant_id) { '1030303-123123-123123' }
42
- let(:document_id) { '7568415-123123-123123' }
43
-
44
46
  it 'returns the expected document' do
45
- response = document.find(applicant_id, document_id)
47
+ document_id = '7568415-123123-123123'
48
+ response = document.find(document_id)
49
+
46
50
  expect(response['id']).to eq(document_id)
47
51
  end
48
52
  end
49
53
 
50
54
  describe '#all' do
51
- let(:applicant_id) { '1030303-123123-123123' }
52
-
53
55
  it 'returns list of documents' do
56
+ applicant_id = '1030303-123123-123123'
54
57
  response = document.all(applicant_id)
58
+
55
59
  expect(response['documents']).not_to be_empty
56
60
  end
57
61
  end
58
62
 
59
63
  describe '#download' do
60
- let(:applicant_id) { '1030303-123123-123123' }
61
- let(:document_id) { '1212121-123123-123123' }
62
-
63
64
  it 'returns the file data' do
64
- response = document.download(applicant_id, document_id)
65
+ document_id = '1212121-123123-123123'
66
+ response = document.download(document_id)
67
+
65
68
  expect(response).not_to be_nil
66
69
  end
67
70
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+
5
+ describe Onfido::Extraction do
6
+ include_context 'fake onfido api'
7
+
8
+ subject(:extraction) { onfido.extraction }
9
+
10
+ describe '#create' do
11
+ let(:params) do
12
+ {
13
+ document_id: '7568415-123123-123123'
14
+ }
15
+ end
16
+
17
+ it 'creates a new extraction' do
18
+ response = extraction.create(**params)
19
+
20
+ expect(response['document_id']).to eq('7568415-123123-123123')
21
+ end
22
+ end
23
+ end
@@ -1,10 +1,14 @@
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
- let(:params) { { file: file } }
11
+ let(:params) { { applicant_id: '123456', file: file } }
8
12
 
9
13
  context 'with a File-like object to upload' do
10
14
  let(:file) { Tempfile.new(['passport', '.jpg']) }
@@ -15,7 +19,8 @@ describe Onfido::LivePhoto do
15
19
  end
16
20
 
17
21
  it 'creates a new photo' do
18
- response = live_photo.create('foobar', params)
22
+ response = live_photo.create(**params)
23
+
19
24
  expect(response['id']).not_to be_nil
20
25
  end
21
26
  end
@@ -24,37 +29,35 @@ describe Onfido::LivePhoto do
24
29
  let(:file) { 'https://onfido.com/images/photo.jpg' }
25
30
 
26
31
  it 'raises an ArgumentError' do
27
- expect { live_photo.create('foobar', params) }.
28
- 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/)
29
34
  end
30
35
  end
31
36
  end
32
37
 
33
38
  describe '#find' do
34
- let(:applicant_id) { '1030303-123123-123123' }
35
- let(:live_photo_id) { '3538c8f6-fdce-4745-9d34-fc246bc05aa1' }
36
-
37
39
  it 'returns the expected live photo' do
38
- response = live_photo.find(applicant_id, live_photo_id)
40
+ live_photo_id = '3538c8f6-fdce-4745-9d34-fc246bc05aa1'
41
+ response = live_photo.find(live_photo_id)
42
+
39
43
  expect(response['id']).to eq(live_photo_id)
40
44
  end
41
45
  end
42
46
 
43
47
  describe '#all' do
44
- let(:applicant_id) { '1030303-123123-123123' }
45
-
46
48
  it 'returns list of documents' do
49
+ applicant_id = '1030303-123123-123123'
47
50
  response = live_photo.all(applicant_id)
51
+
48
52
  expect(response['live_photos']).not_to be_empty
49
53
  end
50
54
  end
51
55
 
52
56
  describe '#download' do
53
- let(:applicant_id) { '1030303-123123-123123' }
54
- let(:live_photo_id) { '3538c8f6-fdce-4745-9d34-fc246bc05aa1' }
55
-
56
57
  it 'returns the file data' do
57
- response = live_photo.download(applicant_id, live_photo_id)
58
+ live_photo_id = '3538c8f6-fdce-4745-9d34-fc246bc05aa1'
59
+ response = live_photo.download(live_photo_id)
60
+
58
61
  expect(response).not_to be_nil
59
62
  end
60
63
  end
@@ -1,33 +1,35 @@
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'
5
7
 
6
- describe '#find' do
7
- let(:applicant_id) { '1030303-123123-123123' }
8
- let(:live_video_id) { 'c9701e9b-83aa-442f-995b-20320ee8fb01' }
8
+ subject(:live_video) { onfido.live_video }
9
+
10
+ let(:live_video_id) { 'c9701e9b-83aa-442f-995b-20320ee8fb01' }
9
11
 
12
+ describe '#find' do
10
13
  it 'returns the expected live photo' do
11
- response = live_video.find(applicant_id, live_video_id)
14
+ response = live_video.find(live_video_id)
15
+
12
16
  expect(response['id']).to eq(live_video_id)
13
17
  end
14
18
  end
15
19
 
16
20
  describe '#all' do
17
- let(:applicant_id) { '1030303-123123-123123' }
18
-
19
21
  it 'returns list of documents' do
22
+ applicant_id = '1030303-123123-123123'
20
23
  response = live_video.all(applicant_id)
24
+
21
25
  expect(response['live_videos']).not_to be_empty
22
26
  end
23
27
  end
24
28
 
25
29
  describe '#download' do
26
- let(:applicant_id) { '1030303-123123-123123' }
27
- let(:live_video_id) { 'c9701e9b-83aa-442f-995b-20320ee8fb01' }
28
-
29
30
  it 'returns the file data' do
30
- response = live_video.download(applicant_id, live_video_id)
31
+ response = live_video.download(live_video_id)
32
+
31
33
  expect(response).not_to be_nil
32
34
  end
33
35
  end
@@ -1,38 +1,41 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Report do
2
- subject(:report) { described_class.new }
3
- let(:check_id) { '8546921-123123-123123' }
4
+ include_context 'fake onfido api'
4
5
 
5
- describe '#find' do
6
- let(:report_id) { '6951786-123123-422221' }
6
+ subject(:report) { onfido.report }
7
7
 
8
+ describe '#find' do
8
9
  it 'returns a report for an existing check' do
9
- response = report.find(check_id, report_id)
10
+ report_id = '6951786-123123-422221'
11
+ response = report.find(report_id)
12
+
10
13
  expect(response['id']).to eq(report_id)
11
14
  end
12
15
  end
13
16
 
14
17
  describe '#all' do
15
18
  it 'lists all reports for an existing check' do
19
+ check_id = '8546921-123123-123123'
16
20
  response = report.all(check_id)
21
+
17
22
  expect(response['reports'].count).to eq(2)
18
23
  end
19
24
  end
20
25
 
21
26
  describe '#resume' do
22
- let(:report_id) { '6951786-123123-422221' }
23
- let(:check_id) { '1212121-123123-422221' }
24
-
25
27
  it 'returns a success response' do
26
- expect { report.resume(check_id, report_id) }.not_to raise_error
28
+ report_id = '6951786-123123-422221'
29
+
30
+ expect { report.resume(report_id) }.not_to raise_error
27
31
  end
28
32
  end
29
33
 
30
34
  describe '#cancel' do
31
- let(:report_id) { '6951786-123123-422221' }
32
- let(:check_id) { '1212121-123123-422221' }
33
-
34
35
  it 'returns a success response' do
35
- expect { report.cancel(check_id, report_id) }.not_to raise_error
36
+ report_id = '6951786-123123-422221'
37
+
38
+ expect { report.cancel(report_id) }.not_to raise_error
36
39
  end
37
40
  end
38
41
  end
@@ -0,0 +1,93 @@
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 'broken connection' do
55
+ before do
56
+ allow(RestClient::Request)
57
+ .to receive(:execute)
58
+ .and_raise(RestClient::ServerBrokeConnection)
59
+ end
60
+
61
+ it 'raises a ConnectionError' do
62
+ expect { resource.get(path: '') }
63
+ .to raise_error(Onfido::ConnectionError, /connection to the server/)
64
+ end
65
+ end
66
+
67
+ context 'bad SSL certificate' do
68
+ before do
69
+ allow(RestClient::Request)
70
+ .to receive(:execute)
71
+ .and_raise(RestClient::SSLCertificateNotVerified.new(nil))
72
+ end
73
+
74
+ it 'raises a ConnectionError' do
75
+ expect { resource.get(path: '') }
76
+ .to raise_error(Onfido::ConnectionError, /SSL certificate/)
77
+ end
78
+ end
79
+
80
+ context 'with a timeout error response' do
81
+ before do
82
+ allow_any_instance_of(RestClient::ExceptionWithResponse)
83
+ .to receive(:response).and_return(double(body: '', code: '408'))
84
+ expect(RestClient::Request).to receive(:execute)
85
+ .and_raise(RestClient::ExceptionWithResponse)
86
+ end
87
+
88
+ it 'raises a ConnectionError' do
89
+ expect { resource.get(path: '') }
90
+ .to raise_error(Onfido::ConnectionError)
91
+ end
92
+ end
93
+ end
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::SdkToken do
2
- subject(:sdk_token) { described_class.new }
3
- let(:applicant_id) { '61f659cb-c90b-4067-808a-6136b5c01351' }
4
- let(:referrer) { 'http://*.mywebsite.com/*' }
4
+ include_context 'fake onfido api'
5
5
 
6
- describe '#create' do
7
- let(:params) { { applicant_id: applicant_id, referrer: referrer } }
6
+ subject(:sdk_token) { onfido.sdk_token }
8
7
 
8
+ describe '#create' do
9
9
  it 'creates a new SDK token for the applicant' do
10
- response = sdk_token.create(params)
10
+ applicant_id = '61f659cb-c90b-4067-808a-6136b5c01351'
11
+ referrer = 'http://*.mywebsite.com/*'
12
+
13
+ response = sdk_token.create(applicant_id: applicant_id, referrer: referrer)
14
+
11
15
  expect(response['token']).not_to be_nil
12
16
  end
13
17
  end
@@ -1,89 +1,108 @@
1
+ # frozen_string_literal: true
2
+
1
3
  describe Onfido::Webhook do
2
- subject(:webhook) { described_class.new }
3
- let(:params) do
4
- {
5
- "url" => "https://webhookendpoint.url",
6
- "enabled" => true,
7
- "events" => [
8
- "report completion",
9
- "report withdrawal",
10
- "check completion",
11
- "check in progress"
12
- ]
13
- }
14
- end
4
+ include_context 'fake onfido api'
5
+
6
+ subject(:webhook) { onfido.webhook }
7
+
8
+ describe '#create' do
9
+ let(:params) do
10
+ {
11
+ url: 'https://webhookendpoint.url',
12
+ enabled: true,
13
+ events: [
14
+ 'report.completed',
15
+ 'check.completed'
16
+ ]
17
+ }
18
+ end
19
+
20
+ it 'creates the webhook' do
21
+ response = webhook.create(**params)
15
22
 
16
- describe "#create" do
17
- it "cretes the webhook" do
18
- response = webhook.create(params)
19
23
  expect(response['id']).to_not be_nil
20
24
  end
21
25
 
22
- it "responds with the right url" do
23
- response = webhook.create(params)
24
- expect(response["url"]).to eq params["url"]
26
+ it 'responds with the right url' do
27
+ response = webhook.create(**params)
28
+
29
+ expect(response['url']).to eq params[:url]
25
30
  end
26
31
  end
27
32
 
28
33
  describe '#find' do
29
- let(:webhook_id) { 'fcb73186-0733-4f6f-9c57-d9d5ef979443' }
30
-
31
34
  it 'returns the webhook' do
35
+ webhook_id = 'fcb73186-0733-4f6f-9c57-d9d5ef979443'
36
+
32
37
  response = webhook.find(webhook_id)
38
+
33
39
  expect(response['id']).to eq(webhook_id)
34
40
  end
35
41
  end
36
42
 
37
- describe "#all" do
38
- it "returns all the registered webhooks" do
43
+ describe '#destroy' do
44
+ it 'removes the webhook' do
45
+ webhook_id = 'fcb73186-0733-4f6f-9c57-d9d5ef979443'
46
+ expect { webhook.destroy(webhook_id) }.not_to raise_error
47
+ end
48
+ end
49
+
50
+ describe '#all' do
51
+ it 'returns all the registered webhooks' do
39
52
  response = webhook.all
40
- expect(response["webhooks"].count).to eq 2
53
+
54
+ expect(response['webhooks'].count).to eq 2
41
55
  end
42
56
 
43
- it "returns with id" do
57
+ it 'returns with id' do
44
58
  response = webhook.all
45
- expect(response["webhooks"][0]["id"]).to_not be_nil
46
- expect(response["webhooks"][1]["id"]).to_not be_nil
59
+
60
+ expect(response['webhooks'][0]['id']).to_not be_nil
61
+ expect(response['webhooks'][1]['id']).to_not be_nil
47
62
  end
48
63
  end
49
64
 
50
- describe ".valid?" do
65
+ describe '.valid?' do
51
66
  subject(:valid?) do
52
67
  described_class.valid?(request_body, request_signature, token)
53
68
  end
54
69
 
55
70
  let(:request_body) { '{"foo":"bar"}' }
56
- let(:request_signature) { 'fdab9db604d33297741b43b9fc9536028d09dca3' }
71
+ let(:request_signature) do
72
+ '89e60408fec20bfb26bb0f993d5e88307818982f50f23b361a00d679bae8b1dc'
73
+ end
57
74
  let(:token) { 'very_secret_token' }
58
75
 
59
76
  it { is_expected.to be(true) }
60
77
 
61
- context "with an invalid signature" do
62
- let(:request_signature) { '2f3d7727ff9a32a7c87072ce514df1f6d3228bec' }
78
+ context 'with an invalid signature' do
79
+ let(:request_signature) do
80
+ 's21fd54ew2w1f5d15642132f3d7727ff9a32a7c87072ce514df1f6d3228bec'
81
+ end
63
82
  it { is_expected.to be(false) }
64
83
  end
65
84
 
66
- context "with a nil request signature" do
85
+ context 'with a nil request signature' do
67
86
  let(:request_signature) { nil }
68
87
  specify { expect { valid? }.to raise_error(ArgumentError) }
69
88
  end
70
89
 
71
- context "with a token other than the one used to sign the request" do
72
- 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' }
73
92
  it { is_expected.to be(false) }
74
93
  end
75
94
 
76
- context "with a nil token" do
95
+ context 'with a nil token' do
77
96
  let(:token) { nil }
78
97
  specify { expect { valid? }.to raise_error(ArgumentError) }
79
98
  end
80
99
 
81
- context "with a modified request body" do
100
+ context 'with a modified request body' do
82
101
  let(:request_body) { '{"bar":"baz"}' }
83
102
  it { is_expected.to be(false) }
84
103
  end
85
104
 
86
- context "with a nil request body" do
105
+ context 'with a nil request body' do
87
106
  let(:request_body) { nil }
88
107
  specify { expect { valid? }.to raise_error(ArgumentError) }
89
108
  end