onfido 1.0.0 → 2.0.2
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 +4 -4
- data/.github/workflows/gem-push.yml +31 -0
- data/.github/workflows/ruby.yml +25 -0
- data/.rubocop.yml +5 -49
- data/.travis.yml +3 -10
- data/CHANGELOG.md +27 -0
- data/Gemfile +2 -0
- data/README.md +44 -156
- data/lib/onfido.rb +4 -3
- data/lib/onfido/api.rb +21 -11
- data/lib/onfido/errors/connection_error.rb +2 -0
- data/lib/onfido/errors/onfido_error.rb +2 -0
- data/lib/onfido/errors/request_error.rb +2 -0
- data/lib/onfido/errors/server_error.rb +2 -0
- data/lib/onfido/options.rb +38 -0
- data/lib/onfido/resource.rb +48 -58
- data/lib/onfido/resources/address.rb +3 -4
- data/lib/onfido/resources/applicant.rb +2 -0
- data/lib/onfido/resources/check.rb +6 -0
- data/lib/onfido/resources/document.rb +2 -0
- data/lib/onfido/resources/extraction.rb +11 -0
- data/lib/onfido/resources/live_photo.rb +2 -0
- data/lib/onfido/resources/live_video.rb +2 -0
- data/lib/onfido/resources/report.rb +2 -0
- data/lib/onfido/resources/sdk_token.rb +2 -0
- data/lib/onfido/resources/webhook.rb +8 -2
- data/lib/onfido/version.rb +3 -1
- data/onfido.gemspec +5 -7
- data/spec/integrations/address_spec.rb +4 -2
- data/spec/integrations/applicant_spec.rb +12 -7
- data/spec/integrations/check_spec.rb +17 -4
- data/spec/integrations/document_spec.rb +8 -4
- data/spec/integrations/extraction_spec.rb +23 -0
- data/spec/integrations/live_photo_spec.rb +8 -4
- data/spec/integrations/live_video_spec.rb +6 -1
- data/spec/integrations/report_spec.rb +6 -1
- data/spec/integrations/resource_spec.rb +106 -0
- data/spec/integrations/sdk_token_spec.rb +5 -1
- data/spec/integrations/webhook_spec.rb +35 -24
- data/spec/onfido/api_spec.rb +14 -25
- data/spec/onfido/connection_error_spec.rb +4 -2
- data/spec/onfido/options_spec.rb +39 -0
- data/spec/onfido/request_error_spec.rb +4 -2
- data/spec/spec_helper.rb +3 -5
- data/spec/support/fake_onfido_api.rb +69 -46
- data/spec/support/fixtures/applicant.json +1 -1
- data/spec/support/fixtures/check.json +1 -1
- data/spec/support/fixtures/checks.json +1 -1
- data/spec/support/fixtures/document.json +1 -1
- data/spec/support/fixtures/documents.json +2 -2
- data/spec/support/fixtures/extraction.json +23 -0
- data/spec/support/fixtures/live_photo.json +2 -2
- data/spec/support/fixtures/live_photos.json +4 -4
- data/spec/support/fixtures/live_video.json +2 -2
- data/spec/support/fixtures/live_videos.json +2 -2
- data/spec/support/fixtures/report.json +1 -1
- data/spec/support/fixtures/reports.json +2 -2
- data/spec/support/fixtures/webhook.json +1 -1
- data/spec/support/fixtures/webhooks.json +2 -2
- metadata +18 -43
- data/Rakefile +0 -1
- data/lib/onfido/configuration.rb +0 -46
- data/lib/onfido/null_logger.rb +0 -5
- data/spec/integrations/exceptions_spec.rb +0 -73
- data/spec/onfido/resource_spec.rb +0 -131
- data/spec/onfido_spec.rb +0 -76
data/lib/onfido/version.rb
CHANGED
data/onfido.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = 'A wrapper for Onfido API'
|
13
13
|
spec.description = "A thin wrapper for Onfido's API. This gem only supports "\
|
14
14
|
"v3 of the Onfido API. Refer to Onfido's "\
|
15
|
-
|
16
|
-
|
15
|
+
'API documentation for details of the expected '\
|
16
|
+
'requests and responses.'
|
17
17
|
spec.homepage = 'http://github.com/onfido/onfido-ruby'
|
18
18
|
spec.license = 'MIT'
|
19
19
|
|
@@ -21,13 +21,11 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
23
|
spec.require_paths = ['lib']
|
24
|
-
spec.required_ruby_version =
|
24
|
+
spec.required_ruby_version = '>= 2.4.0'
|
25
25
|
|
26
|
-
spec.add_development_dependency 'bundler', '~> 2.0'
|
27
|
-
spec.add_development_dependency 'rake', '~> 12.0'
|
28
26
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
29
27
|
spec.add_development_dependency 'rspec-its', '~> 1.2'
|
30
|
-
spec.add_development_dependency 'rubocop', '~>
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 1.11'
|
31
29
|
spec.add_development_dependency 'sinatra', '~> 1.4'
|
32
30
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
33
31
|
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
describe Onfido::Address do
|
2
|
-
|
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 =
|
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
|
-
|
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.1/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
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
-
|
6
|
+
include_context 'fake onfido api'
|
7
|
+
|
8
|
+
subject(:document) { onfido.document }
|
5
9
|
|
6
10
|
describe '#create' do
|
7
11
|
let(:params) do
|
@@ -22,7 +26,7 @@ describe Onfido::Document do
|
|
22
26
|
end
|
23
27
|
|
24
28
|
it 'creates a new document' do
|
25
|
-
response = document.create(params)
|
29
|
+
response = document.create(**params)
|
26
30
|
|
27
31
|
expect(response['id']).not_to be_nil
|
28
32
|
end
|
@@ -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
|
@@ -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,7 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'tempfile'
|
2
4
|
|
3
5
|
describe Onfido::LivePhoto do
|
4
|
-
|
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 } }
|
@@ -15,7 +19,7 @@ describe Onfido::LivePhoto do
|
|
15
19
|
end
|
16
20
|
|
17
21
|
it 'creates a new photo' do
|
18
|
-
response = live_photo.create(params)
|
22
|
+
response = live_photo.create(**params)
|
19
23
|
|
20
24
|
expect(response['id']).not_to be_nil
|
21
25
|
end
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
4
|
+
include_context 'fake onfido api'
|
5
|
+
|
6
|
+
subject(:webhook) { onfido.webhook }
|
3
7
|
|
4
|
-
describe
|
8
|
+
describe '#create' do
|
5
9
|
let(:params) do
|
6
10
|
{
|
7
|
-
url:
|
11
|
+
url: 'https://webhookendpoint.url',
|
8
12
|
enabled: true,
|
9
13
|
events: [
|
10
|
-
|
11
|
-
|
14
|
+
'report.completed',
|
15
|
+
'check.completed'
|
12
16
|
]
|
13
17
|
}
|
14
18
|
end
|
15
19
|
|
16
|
-
it
|
17
|
-
response = webhook.create(params)
|
20
|
+
it 'creates the webhook' do
|
21
|
+
response = webhook.create(**params)
|
18
22
|
|
19
23
|
expect(response['id']).to_not be_nil
|
20
24
|
end
|
21
25
|
|
22
|
-
it
|
23
|
-
response = webhook.create(params)
|
26
|
+
it 'responds with the right url' do
|
27
|
+
response = webhook.create(**params)
|
24
28
|
|
25
|
-
expect(response[
|
29
|
+
expect(response['url']).to eq params[:url]
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -36,22 +40,29 @@ describe Onfido::Webhook do
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
|
-
describe
|
40
|
-
it
|
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
|
41
52
|
response = webhook.all
|
42
53
|
|
43
|
-
expect(response[
|
54
|
+
expect(response['webhooks'].count).to eq 2
|
44
55
|
end
|
45
56
|
|
46
|
-
it
|
57
|
+
it 'returns with id' do
|
47
58
|
response = webhook.all
|
48
59
|
|
49
|
-
expect(response[
|
50
|
-
expect(response[
|
60
|
+
expect(response['webhooks'][0]['id']).to_not be_nil
|
61
|
+
expect(response['webhooks'][1]['id']).to_not be_nil
|
51
62
|
end
|
52
63
|
end
|
53
64
|
|
54
|
-
describe
|
65
|
+
describe '.valid?' do
|
55
66
|
subject(:valid?) do
|
56
67
|
described_class.valid?(request_body, request_signature, token)
|
57
68
|
end
|
@@ -64,34 +75,34 @@ describe Onfido::Webhook do
|
|
64
75
|
|
65
76
|
it { is_expected.to be(true) }
|
66
77
|
|
67
|
-
context
|
78
|
+
context 'with an invalid signature' do
|
68
79
|
let(:request_signature) do
|
69
80
|
's21fd54ew2w1f5d15642132f3d7727ff9a32a7c87072ce514df1f6d3228bec'
|
70
81
|
end
|
71
82
|
it { is_expected.to be(false) }
|
72
83
|
end
|
73
84
|
|
74
|
-
context
|
85
|
+
context 'with a nil request signature' do
|
75
86
|
let(:request_signature) { nil }
|
76
87
|
specify { expect { valid? }.to raise_error(ArgumentError) }
|
77
88
|
end
|
78
89
|
|
79
|
-
context
|
80
|
-
let(:token) {
|
90
|
+
context 'with a token other than the one used to sign the request' do
|
91
|
+
let(:token) { 'quite_secret_token' }
|
81
92
|
it { is_expected.to be(false) }
|
82
93
|
end
|
83
94
|
|
84
|
-
context
|
95
|
+
context 'with a nil token' do
|
85
96
|
let(:token) { nil }
|
86
97
|
specify { expect { valid? }.to raise_error(ArgumentError) }
|
87
98
|
end
|
88
99
|
|
89
|
-
context
|
100
|
+
context 'with a modified request body' do
|
90
101
|
let(:request_body) { '{"bar":"baz"}' }
|
91
102
|
it { is_expected.to be(false) }
|
92
103
|
end
|
93
104
|
|
94
|
-
context
|
105
|
+
context 'with a nil request body' do
|
95
106
|
let(:request_body) { nil }
|
96
107
|
specify { expect { valid? }.to raise_error(ArgumentError) }
|
97
108
|
end
|