hello_sign 1.1.0 → 1.1.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 (32) hide show
  1. data/lib/hello_sign.rb +29 -5
  2. data/lib/hello_sign/client.rb +13 -38
  3. data/lib/hello_sign/connection.rb +53 -0
  4. data/lib/hello_sign/error.rb +13 -9
  5. data/lib/hello_sign/middleware/parse_json.rb +22 -0
  6. data/lib/hello_sign/middleware/raise_error.rb +2 -0
  7. data/lib/hello_sign/parameters/reusable_form_signature_request.rb +27 -14
  8. data/lib/hello_sign/parameters/signature_request.rb +29 -21
  9. data/lib/hello_sign/parameters/unclaimed_draft.rb +8 -5
  10. data/lib/hello_sign/proxy/signature_request.rb +30 -18
  11. data/lib/hello_sign/version.rb +1 -1
  12. data/spec/helper.rb +0 -6
  13. data/spec/integration/hello_sign_spec.rb +7 -1
  14. data/spec/integration/helper.rb +17 -4
  15. data/spec/shared_examples/proxy.rb +58 -15
  16. data/spec/unit/client_spec.rb +42 -27
  17. data/spec/unit/connection_spec.rb +38 -0
  18. data/spec/unit/error_spec.rb +65 -13
  19. data/spec/unit/hello_sign_spec.rb +66 -23
  20. data/spec/unit/middleware/parse_json_spec.rb +38 -0
  21. data/spec/unit/middleware/raise_error_spec.rb +36 -23
  22. data/spec/unit/parameters/reusable_form_signature_request_spec.rb +74 -37
  23. data/spec/unit/parameters/signature_request_spec.rb +11 -5
  24. data/spec/unit/parameters/unclaimed_draft_spec.rb +14 -6
  25. data/spec/unit/proxy/account_spec.rb +17 -9
  26. data/spec/unit/proxy/reusable_form_spec.rb +31 -14
  27. data/spec/unit/proxy/settings_spec.rb +11 -4
  28. data/spec/unit/proxy/signature_request_spec.rb +74 -38
  29. data/spec/unit/proxy/team_spec.rb +39 -20
  30. data/spec/unit/proxy/unclaimed_draft_spec.rb +25 -6
  31. data/spec/unit/upload_io_spec.rb +69 -27
  32. metadata +20 -40
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+ require 'hello_sign/middleware/parse_json'
3
+ require 'json'
4
+
5
+ describe HelloSign::Middleware::ParseJson do
6
+ let(:middleware) do
7
+ HelloSign::Middleware::ParseJson.new(->(env) { Faraday::Response.new(env) })
8
+ end
9
+
10
+ it "does not blow up if there is not a body" do
11
+ expect { middleware.call({}) }.not_to raise_error
12
+ end
13
+
14
+ context "when the content type is application/json" do
15
+ let(:env) { {response_headers: {'Content-Type' => 'application/json'}} }
16
+
17
+ it "does not change a nil body" do
18
+ expect(middleware.call(env.merge(body: nil)).env[:body]).to eq nil
19
+ end
20
+
21
+ context "and the body is valid JSON" do
22
+ let(:body) { {first: 1, second: 2}.to_json }
23
+
24
+ it "parses the body into a hash with symbols as keys" do
25
+ expect(middleware.call(env.merge(body: body)).env[:body])
26
+ .to eq({first: 1, second: 2})
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when the content type is not application/json" do
32
+ let(:env) { {response_headers: {'Content-Type' => 'application/pdf'}} }
33
+
34
+ it "does not parse the body" do
35
+ expect(middleware.call(env.merge(body: 'dave')).env[:body]).to eq 'dave'
36
+ end
37
+ end
38
+ end
@@ -8,34 +8,46 @@ describe HelloSign::Middleware::RaiseError do
8
8
  specify { expect { call_with_error(error) }.to raise_error exception }
9
9
  end
10
10
 
11
- {
12
- 'unauthorized' => HelloSign::Error::Unauthorized,
13
- 'forbidden' => HelloSign::Error::Forbidden,
14
- 'not_found' => HelloSign::Error::NotFound,
15
- 'unknown' => HelloSign::Error::Unknown,
16
- 'team_invite_failed' => HelloSign::Error::TeamInviteFailed,
17
- 'invalid_recipient' => HelloSign::Error::InvalidRecipient,
18
- 'convert_failed' => HelloSign::Error::ConvertFailed,
19
- 'signature_request_cancel_failed' => HelloSign::Error::SignatureRequestCancelFailed,
20
- 'unidentified_error' => HelloSign::Error
21
- }.each { |error_pair| it_raises_the_proper_exception(*error_pair) }
22
-
23
- it "does not blow up if there is not a body" do
24
- expect { middleware.call({}) }.to_not raise_error
25
- end
26
-
27
- context "when raising an exception" do
28
- let(:expected_message) { "[Status code: 418] I'm a teapot." }
11
+ context "when the content type is application/json" do
12
+ {
13
+ 'unauthorized' => HelloSign::Error::Unauthorized,
14
+ 'forbidden' => HelloSign::Error::Forbidden,
15
+ 'not_found' => HelloSign::Error::NotFound,
16
+ 'unknown' => HelloSign::Error::Unknown,
17
+ 'team_invite_failed' => HelloSign::Error::TeamInviteFailed,
18
+ 'invalid_recipient' => HelloSign::Error::InvalidRecipient,
19
+ 'convert_failed' => HelloSign::Error::ConvertFailed,
20
+ 'signature_request_cancel_failed' => HelloSign::Error::SignatureRequestCancelFailed,
21
+ 'unidentified_error' => HelloSign::Error
22
+ }.each { |error_pair| it_raises_the_proper_exception(*error_pair) }
23
+
24
+ it "does not blow up if there is not a body" do
25
+ expect { middleware.call({}) }.not_to raise_error
26
+ end
29
27
 
30
- it "returns the proper message" do
31
- begin
32
- call_with_error('bad_request', message: "I'm a teapot.", status_code: 418)
33
- rescue HelloSign::Error::BadRequest => e
34
- expect("#{e}").to match /#{Regexp.escape(expected_message)}/
28
+ context "and an exception is raised" do
29
+ it "returns the proper message" do
30
+ begin
31
+ middleware.call(
32
+ call_with_error(
33
+ 'bad_request',
34
+ message: "I'm a teapot.",
35
+ status_code: 418
36
+ ).merge(response_headers)
37
+ )
38
+ rescue HelloSign::Error::BadRequest => e
39
+ expect("#{e}").to match /#{Regexp.escape("[Status code: 418] I'm a teapot")}/
40
+ end
35
41
  end
36
42
  end
37
43
  end
38
44
 
45
+ context "when the body is not a hash" do
46
+ it "does not blow up" do
47
+ expect { middleware.call(body: 'hal') }.not_to raise_error
48
+ end
49
+ end
50
+
39
51
  private
40
52
 
41
53
  def call_with_error(error, options = {})
@@ -43,6 +55,7 @@ describe HelloSign::Middleware::RaiseError do
43
55
  body: {error: {error_name: error, error_msg: options[:message]}},
44
56
  response: {status: options[:status_code]}
45
57
  }
58
+
46
59
  middleware.call(env)
47
60
  end
48
61
 
@@ -5,46 +5,83 @@ describe HelloSign::Parameters::ReusableFormSignatureRequest do
5
5
  describe "#formatted" do
6
6
  let(:request_parameters) { HelloSign::Parameters::ReusableFormSignatureRequest.new }
7
7
 
8
- before do
9
- request_parameters.reusable_form_id = 'form_id'
10
- request_parameters.title = 'Lease'
11
- request_parameters.subject = 'Sign this'
12
- request_parameters.message = 'You must sign this.'
13
- request_parameters.ccs = [
14
- {email_address: 'lawyer@lawfirm.com', role: 'lawyer'},
15
- {email_address: 'accountant@llc.com', role: 'accountant'}
16
- ]
17
- request_parameters.signers = [
18
- {name: 'Jack', email_address: 'jack@hill.com', role: 'consultant'},
19
- {name: 'Jill', email_address: 'jill@hill.com', role: 'client'}
20
- ]
21
- request_parameters.custom_fields = [
22
- {name: 'cost', value: '$20,000'},
23
- {name: 'time', value: 'two weeks'}
24
- ]
8
+ context "when all parameters are provided" do
9
+ let(:expected) do
10
+ {
11
+ reusable_form_id: 'form_id',
12
+ title: 'Lease',
13
+ subject: 'Sign this',
14
+ message: 'You must sign this.',
15
+ ccs: {
16
+ 'lawyer' => {email_address: 'lawyer@lawfirm.com'},
17
+ 'accountant' => {email_address: 'accountant@llc.com'}
18
+ },
19
+ signers: {
20
+ 'consultant' => {name: 'Jack', email_address: 'jack@hill.com'},
21
+ 'client' => {name: 'Jill', email_address: 'jill@hill.com'}
22
+ },
23
+ custom_fields: {
24
+ 'cost' => '$20,000',
25
+ 'time' => 'two weeks'
26
+ }
27
+ }
28
+ end
29
+
30
+ before do
31
+ request_parameters.reusable_form_id = 'form_id'
32
+ request_parameters.title = 'Lease'
33
+ request_parameters.subject = 'Sign this'
34
+ request_parameters.message = 'You must sign this.'
35
+ request_parameters.ccs = [
36
+ {email_address: 'lawyer@lawfirm.com', role: 'lawyer'},
37
+ {email_address: 'accountant@llc.com', role: 'accountant'}
38
+ ]
39
+ request_parameters.signers = [
40
+ {name: 'Jack', email_address: 'jack@hill.com', role: 'consultant'},
41
+ {name: 'Jill', email_address: 'jill@hill.com', role: 'client'}
42
+ ]
43
+ request_parameters.custom_fields = [
44
+ {name: 'cost', value: '$20,000'},
45
+ {name: 'time', value: 'two weeks'}
46
+ ]
47
+ end
48
+
49
+ it "returns formatted parameters" do
50
+ expect(request_parameters.formatted).to eq expected
51
+ end
25
52
  end
26
53
 
27
- it "returns formatted parameters" do
28
- expected = {
29
- reusable_form_id: 'form_id',
30
- title: 'Lease',
31
- subject: 'Sign this',
32
- message: 'You must sign this.',
33
- ccs: {
34
- 'lawyer' => {email_address: 'lawyer@lawfirm.com'},
35
- 'accountant' => {email_address: 'accountant@llc.com'}
36
- },
37
- signers: {
38
- 'consultant' => {name: 'Jack', email_address: 'jack@hill.com'},
39
- 'client' => {name: 'Jill', email_address: 'jill@hill.com'}
40
- },
41
- custom_fields: {
42
- 'cost' => '$20,000',
43
- 'time' => 'two weeks'
44
- }
45
- }
54
+ context "when the ccs parameter is not provided" do
55
+ before do
56
+ request_parameters.signers = []
57
+ request_parameters.custom_fields = []
58
+ end
59
+
60
+ it "defaults to an empty hash" do
61
+ expect(request_parameters.formatted[:ccs]).to eq({})
62
+ end
63
+ end
64
+
65
+ context "when the signers parameter is not provided" do
66
+ before do
67
+ request_parameters.ccs = []
68
+ request_parameters.custom_fields = []
69
+ end
70
+
71
+ it "defaults to an empty hash" do
72
+ expect(request_parameters.formatted[:custom_fields]).to eq({})
73
+ end
74
+ end
75
+
76
+ context "when the custom_fields parameter is not provided" do
77
+ before do
78
+ request_parameters.ccs = []
79
+ request_parameters.signers = []
80
+ end
46
81
 
47
- expect(request_parameters.formatted).to eq expected
82
+ it "defaults to an empty hash" do
83
+ expect(request_parameters.formatted[:custom_fields]).to eq({})
84
+ end
48
85
  end
49
86
  end
50
87
  end
@@ -15,7 +15,7 @@ describe HelloSign::Parameters::SignatureRequest do
15
15
  message: 'You must sign this.',
16
16
  cc_email_addresses: ['lawyer@lawfirm.com', 'spouse@family.com'],
17
17
  signers: {
18
- 0 => {name: 'Jack', email_address: 'jack@hill.com', order: 0},
18
+ 0 => {name: 'Jack', email_address: 'jack@hill.com', order: 0},
19
19
  1 => {name: 'Jill', email_address: 'jill@hill.com', order: 1}
20
20
  },
21
21
  file: {1 => text_file, 2 => image_file}
@@ -35,13 +35,19 @@ describe HelloSign::Parameters::SignatureRequest do
35
35
  @file_data_1 = {filename: 'test.txt', io: 'text file IO object', mime: 'text/plain'},
36
36
  @file_data_2 = {filename: 'test.jpg', io: 'image file IO object', mime: 'image/jpeg'}
37
37
  ]
38
+
39
+ allow(HelloSign::File).to(
40
+ receive(:new).with(@file_data_1).and_return(text_file)
41
+ )
42
+ allow(HelloSign::File).to(
43
+ receive(:new).with(@file_data_2).and_return(image_file)
44
+ )
45
+ [text_file, image_file].each do |file|
46
+ allow(file).to receive(:attachment).and_return(file)
47
+ end
38
48
  end
39
49
 
40
50
  it "returns formatted parameters" do
41
- HelloSign::File.should_receive(:new).with(@file_data_1).and_return(text_file)
42
- HelloSign::File.should_receive(:new).with(@file_data_2).and_return(image_file)
43
- [text_file, image_file].each { |file| file.should_receive(:attachment).and_return(file) }
44
-
45
51
  expect(request_parameters.formatted).to eq expected
46
52
  end
47
53
  end
@@ -12,17 +12,25 @@ describe HelloSign::Parameters::UnclaimedDraft do
12
12
 
13
13
  before do
14
14
  draft_parameters.files = [
15
- @file_data_1 = {filename: 'test.txt', io: text_file, mime: 'text/plain'},
15
+ @file_data_1 = {filename: 'test.txt', io: text_file, mime: 'text/html'},
16
16
  @file_data_2 = {filename: 'test.jpg', io: image, mime: 'image/jpeg'}
17
17
  ]
18
+
19
+ allow(HelloSign::File).to(
20
+ receive(:new).with(@file_data_1).and_return(text_file)
21
+ )
22
+ allow(HelloSign::File).to(
23
+ receive(:new).with(@file_data_2).and_return(image)
24
+ )
25
+ [text_file, image].each do |file|
26
+ allow(file).to receive(:attachment).and_return(file)
27
+ end
18
28
  end
19
29
 
20
30
  it "returns formatted parameters" do
21
- HelloSign::File.should_receive(:new).with(@file_data_1).and_return(text_file)
22
- HelloSign::File.should_receive(:new).with(@file_data_2).and_return(image)
23
- [text_file, image].each { |file| file.should_receive(:attachment).and_return(file) }
24
-
25
- expect(draft_parameters.formatted).to eq({file: {0 => text_file, 1 => image}})
31
+ expect(draft_parameters.formatted).to(
32
+ eq({file: {0 => text_file, 1 => image}})
33
+ )
26
34
  end
27
35
  end
28
36
  end
@@ -10,18 +10,21 @@ describe HelloSign::Proxy::Account do
10
10
  let(:email_address) { 'david@bowman.com' }
11
11
  let(:password) { 'password' }
12
12
 
13
- before { client.stub(:post).and_return(api_response) }
13
+ before do
14
+ allow(client).to receive(:post).and_return(api_response)
15
+
16
+ account_proxy.create(
17
+ email_address: 'david@bowman.com',
18
+ password: 'space'
19
+ )
20
+ end
14
21
 
15
22
  it "sends a request to create an account" do
16
- client.should_receive(:post).with(
23
+ expect(client).to have_received(:post).with(
17
24
  '/account/create',
18
25
  body: {email_address: 'david@bowman.com', password: 'space'},
19
26
  auth_not_required: true
20
27
  )
21
- account_proxy.create(
22
- email_address: 'david@bowman.com',
23
- password: 'space'
24
- )
25
28
  end
26
29
 
27
30
  it "returns the API response" do
@@ -30,15 +33,20 @@ describe HelloSign::Proxy::Account do
30
33
  email_address: 'david@bowman.com',
31
34
  password: 'space'
32
35
  )
33
- ). to eq api_response
36
+ ).to eq api_response
34
37
  end
35
38
  end
36
39
 
37
40
  describe "#settings" do
38
- let(:settings_proxy) { double('settings proxy') }
41
+ let(:settings_proxy) { double('settings proxy') }
42
+
43
+ before do
44
+ allow(HelloSign::Proxy::Settings).to(
45
+ receive(:new).with(client).and_return(settings_proxy)
46
+ )
47
+ end
39
48
 
40
49
  it "returns a signature request proxy" do
41
- HelloSign::Proxy::Settings.should_receive(:new).with(client).and_return(settings_proxy)
42
50
  expect(account_proxy.settings).to be settings_proxy
43
51
  end
44
52
  end
@@ -6,54 +6,71 @@ describe HelloSign::Proxy::ReusableForm do
6
6
  let(:api_response) { double('API response') }
7
7
  let(:form_id) { 'form_id' }
8
8
  let(:email_address) { 'bob@example.com' }
9
+
9
10
  subject(:rf_proxy) { HelloSign::Proxy::ReusableForm.new(client, form_id) }
10
11
 
11
12
  before do
12
- client.stub(:get).and_return(api_response)
13
- client.stub(:post).and_return(api_response)
13
+ allow(client).to receive(:get).and_return(api_response)
14
+ allow(client).to receive(:post).and_return(api_response)
14
15
  end
15
16
 
16
17
  describe "#list" do
18
+ before { @response = rf_proxy.list(page: 10) }
19
+
17
20
  it "sends a request to fetch the list of reusable forms" do
18
- client.should_receive(:get).with('/reusable_form/list', params: {page: 10})
19
- rf_proxy.list(page: 10)
21
+ expect(client).to(
22
+ have_received(:get).with('/reusable_form/list', params: {page: 10})
23
+ )
20
24
  end
21
25
 
22
26
  it "returns the API response" do
23
- expect(rf_proxy.list).to eq api_response
27
+ expect(@response).to eq api_response
24
28
  end
25
29
  end
26
30
 
27
31
  describe "#show" do
32
+ before { @response = rf_proxy.show }
33
+
28
34
  it "sends a request to fetch the details of a reusable form" do
29
- client.should_receive(:get).with("/reusable_form/#{form_id}")
30
- rf_proxy.show
35
+ expect(client).to have_received(:get).with("/reusable_form/#{form_id}")
31
36
  end
32
37
 
33
38
  it "returns the API response" do
34
- expect(rf_proxy.show).to eq api_response
39
+ expect(@response).to eq api_response
35
40
  end
36
41
  end
37
42
 
38
43
  describe "#grant_access" do
44
+ before { @response = rf_proxy.grant_access(email_address: email_address) }
45
+
39
46
  it "sends a request to grant access" do
40
- client.should_receive(:post).with("/reusable_form/add_user/#{form_id}", body: {email_address: email_address})
41
- rf_proxy.grant_access(email_address: email_address)
47
+ expect(client).to(
48
+ have_received(:post).with(
49
+ "/reusable_form/add_user/#{form_id}",
50
+ body: {email_address: email_address}
51
+ )
52
+ )
42
53
  end
43
54
 
44
55
  it "returns the API response" do
45
- expect(rf_proxy.grant_access(:email => email_address)).to eq api_response
56
+ expect(@response).to eq api_response
46
57
  end
47
58
  end
48
59
 
49
60
  describe "#revoke_access" do
61
+ before { @response = rf_proxy.revoke_access(email_address: email_address) }
62
+
50
63
  it "sends a request to revoke access" do
51
- client.should_receive(:post).with("/reusable_form/remove_user/#{form_id}", body: {email_address: email_address})
52
- rf_proxy.revoke_access(email_address: email_address)
64
+ expect(client).to(
65
+ have_received(:post).with(
66
+ "/reusable_form/remove_user/#{form_id}",
67
+ body: {email_address: email_address}
68
+ )
69
+ )
53
70
  end
54
71
 
55
72
  it "returns the API response" do
56
- expect(rf_proxy.revoke_access(email_address: email_address)).to eq api_response
73
+ expect(@response).to eq api_response
57
74
  end
58
75
  end
59
76
  end
@@ -3,6 +3,7 @@ require 'hello_sign/proxy/settings'
3
3
 
4
4
  describe HelloSign::Proxy::Settings do
5
5
  let(:client) { double('client') }
6
+
6
7
  subject(:settings) { HelloSign::Proxy::Settings.new(client) }
7
8
 
8
9
  describe "#client" do
@@ -15,15 +16,21 @@ describe HelloSign::Proxy::Settings do
15
16
  let(:callback_url) { 'http://www.callmemaybe.com' }
16
17
  let(:api_response) { double('API response') }
17
18
 
18
- before { client.stub(:post).and_return(api_response) }
19
+ before do
20
+ allow(client).to receive(:post).and_return(api_response)
21
+
22
+ @response = settings.update(callback_url: callback_url)
23
+ end
19
24
 
20
25
  it "sends a request to update the account's settings" do
21
- client.should_receive(:post).with('/account', body: {callback_url: callback_url})
22
- settings.update(callback_url: callback_url)
26
+ expect(client).to have_received(:post).with(
27
+ '/account',
28
+ body: {callback_url: callback_url}
29
+ )
23
30
  end
24
31
 
25
32
  it "returns the API response" do
26
- expect(settings.update(callback_url: callback_url)).to be api_response
33
+ expect(@response).to be api_response
27
34
  end
28
35
  end
29
36
  end