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,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