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
@@ -1,7 +1,7 @@
1
1
  require 'hello_sign/middleware/raise_error'
2
+ require 'hello_sign/middleware/parse_json'
2
3
  require 'hello_sign/client'
3
4
  require 'hello_sign/version'
4
-
5
5
  require 'forwardable'
6
6
 
7
7
  module HelloSign
@@ -10,10 +10,19 @@ module HelloSign
10
10
 
11
11
  attr_accessor :email_address, :password
12
12
 
13
- delegate [:account, :signature_request, :reusable_form, :team, :unclaimed_draft] => :client
13
+ delegate [
14
+ :account,
15
+ :signature_request,
16
+ :reusable_form,
17
+ :team,
18
+ :unclaimed_draft
19
+ ] => :client
14
20
 
15
21
  def client
16
- @client = HelloSign::Client.new(email_address, password) unless credentials_match?
22
+ unless credentials_match?
23
+ @client = HelloSign::Client.new(email_address, password)
24
+ end
25
+
17
26
  @client
18
27
  end
19
28
 
@@ -24,10 +33,25 @@ module HelloSign
24
33
  private
25
34
 
26
35
  def credentials_match?
27
- @client && [@client.email_address, @client.password].hash == [email_address, password].hash
36
+ @client && client_credentials.hash == provided_credentials.hash
37
+ end
38
+
39
+ def client_credentials
40
+ [@client.email_address, @client.password]
41
+ end
42
+
43
+ def provided_credentials
44
+ [email_address, password]
28
45
  end
29
46
 
30
- Faraday.register_middleware :response, raise_error: HelloSign::Middleware::RaiseError
47
+ Faraday.register_middleware(
48
+ :response,
49
+ raise_error: HelloSign::Middleware::RaiseError
50
+ )
51
+ Faraday.register_middleware(
52
+ :response,
53
+ json: HelloSign::Middleware::ParseJson
54
+ )
31
55
 
32
56
  end
33
57
  end
@@ -1,57 +1,32 @@
1
1
  require 'hello_sign/proxy'
2
-
3
- require 'faraday'
4
- require 'faraday_middleware-multi_json'
2
+ require 'hello_sign/connection'
3
+ require 'forwardable'
5
4
 
6
5
  module HelloSign
7
6
  class Client
8
- include HelloSign::Proxy
7
+ extend Forwardable
9
8
 
10
- API_ENDPOINT = 'https://api.hellosign.com'
11
- API_VERSION = '/v3'
9
+ include HelloSign::Proxy
12
10
 
13
11
  attr_reader :email_address, :password
14
12
 
15
- def initialize(email_address_or_hash, password = nil)
16
- if email_address_or_hash.is_a? Hash
17
- @email_address = email_address_or_hash.fetch(:email_address) { raise ArgumentError }
18
- @password = email_address_or_hash.fetch(:password) { raise ArgumentError }
13
+ def initialize(email_or_hash, password = nil)
14
+ if email_or_hash.is_a?(Hash)
15
+ @email_address = email_or_hash.fetch(:email_address) { raise ArgumentError }
16
+ @password = email_or_hash.fetch(:password) { raise ArgumentError }
19
17
  else
20
- @email_address = email_address_or_hash
18
+ @email_address = email_or_hash
21
19
  @password = password
22
20
  end
23
21
  end
24
22
 
25
- def get(path, options = {})
26
- request(:get, path, options)
27
- end
28
-
29
- def post(path, options = {})
30
- request(:post, path, options)
31
- end
23
+ delegate [:get, :post] => :connection
32
24
 
33
25
  private
34
26
 
35
- def request(method, path, options)
36
- base_connection do |connection|
37
- connection.request :basic_auth, email_address, password unless options[:auth_not_required]
38
- end.send(method) do |request|
39
- request.url "#{API_VERSION}#{path}", options[:params]
40
- request.body = options[:body]
41
- end.body
42
- end
43
-
44
- def base_connection
45
- options = {url: API_ENDPOINT, headers: {user_agent: "hello_sign gem v#{HelloSign::VERSION}"}}
46
-
47
- Faraday.new(options) do |connection|
48
- yield connection
49
-
50
- connection.request :multipart
51
- connection.request :url_encoded
52
- connection.response :raise_error
53
- connection.response :multi_json, symbolize_keys: true
54
- connection.adapter :net_http
27
+ def connection
28
+ HelloSign::Connection.new do |connection|
29
+ connection.request :basic_auth, email_address, password
55
30
  end
56
31
  end
57
32
 
@@ -0,0 +1,53 @@
1
+ require 'faraday'
2
+
3
+ module HelloSign
4
+ class Connection
5
+ API_ENDPOINT = 'https://api.hellosign.com'
6
+ API_VERSION = '3'
7
+
8
+ attr_reader :auth_configuration
9
+
10
+ def initialize(&auth_configuration)
11
+ @auth_configuration = auth_configuration
12
+ end
13
+
14
+ def get(path, options = {})
15
+ request(:get, path, options)
16
+ end
17
+
18
+ def post(path, options = {})
19
+ request(:post, path, options)
20
+ end
21
+
22
+ private
23
+
24
+ def request(method, path, options)
25
+ base_connection do |connection|
26
+ auth_configuration.call(connection) unless options[:auth_not_required]
27
+ end.send(method) do |request|
28
+ request.url "/v#{API_VERSION}#{path}", options[:params]
29
+ request.body = options[:body]
30
+ end.body
31
+ end
32
+
33
+ def base_connection
34
+ Faraday.new(connection_options) do |connection|
35
+ yield connection
36
+
37
+ connection.request :multipart
38
+ connection.request :url_encoded
39
+ connection.response :raise_error
40
+ connection.response :json
41
+ connection.adapter :net_http
42
+ end
43
+ end
44
+
45
+ def connection_options
46
+ {
47
+ url: API_ENDPOINT,
48
+ headers: {user_agent: "hello_sign gem v#{HelloSign::VERSION}"}
49
+ }
50
+ end
51
+
52
+ end
53
+ end
@@ -16,14 +16,18 @@ module HelloSign
16
16
  "[Status code: #{status_code}] #{message}"
17
17
  end
18
18
 
19
- class BadRequest < HelloSign::Error; end
20
- class Unauthorized < HelloSign::Error; end
21
- class Forbidden < HelloSign::Error; end
22
- class NotFound < HelloSign::Error; end
23
- class Unknown < HelloSign::Error; end
24
- class TeamInviteFailed < HelloSign::Error; end
25
- class InvalidRecipient < HelloSign::Error; end
26
- class ConvertFailed < HelloSign::Error; end
27
- class SignatureRequestCancelFailed < HelloSign::Error; end
19
+ [
20
+ :BadRequest,
21
+ :Unauthorized,
22
+ :Forbidden,
23
+ :NotFound,
24
+ :Unknown,
25
+ :TeamInviteFailed,
26
+ :InvalidRecipient,
27
+ :ConvertFailed,
28
+ :SignatureRequestCancelFailed
29
+ ].each do |error_name|
30
+ const_set(error_name, Class.new(HelloSign::Error))
31
+ end
28
32
  end
29
33
  end
@@ -0,0 +1,22 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module HelloSign
5
+ module Middleware
6
+ class ParseJson < Faraday::Response::Middleware
7
+
8
+ def on_complete(env)
9
+ body = env[:body] or return
10
+
11
+ env[:body] = ::JSON.parse(body, symbolize_names: true) if json?(env)
12
+ end
13
+
14
+ private
15
+
16
+ def json?(env)
17
+ env[:response_headers]['Content-Type'] == 'application/json'
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -9,6 +9,8 @@ module HelloSign
9
9
  def on_complete(env)
10
10
  body = env[:body] or return
11
11
 
12
+ return unless body.is_a?(Hash)
13
+
12
14
  error = body[:error] and begin
13
15
  exception = begin
14
16
  case error[:error_name]
@@ -1,7 +1,8 @@
1
1
  module HelloSign
2
2
  module Parameters
3
3
  class ReusableFormSignatureRequest
4
- attr_writer :reusable_form_id, :title, :subject, :message, :ccs, :signers, :custom_fields
4
+ attr_writer :reusable_form_id, :title, :subject, :message, :ccs, :signers,
5
+ :custom_fields
5
6
 
6
7
  def formatted
7
8
  {
@@ -9,9 +10,9 @@ module HelloSign
9
10
  title: title,
10
11
  subject: subject,
11
12
  message: message,
12
- ccs: ccs,
13
- signers: signers,
14
- custom_fields: custom_fields
13
+ ccs: formatted_ccs,
14
+ signers: formatted_signers,
15
+ custom_fields: formatted_custom_fields
15
16
  }
16
17
  end
17
18
 
@@ -19,27 +20,39 @@ module HelloSign
19
20
 
20
21
  attr_reader :reusable_form_id, :title, :subject, :message
21
22
 
22
- def ccs
23
- @ccs.inject({}) do |parameter, cc|
23
+ def formatted_ccs
24
+ ccs.each_with_object({}) do |cc, parameter|
24
25
  parameter[cc[:role]] = {email_address: cc[:email_address]}
25
- parameter
26
26
  end
27
27
  end
28
28
 
29
- def signers
30
- @signers.inject({}) do |parameter, signer|
31
- parameter[signer[:role]] = {name: signer[:name], email_address: signer[:email_address]}
32
- parameter
29
+ def formatted_signers
30
+ signers.each_with_object({}) do |signer, parameter|
31
+ parameter[signer[:role]] = {
32
+ name: signer[:name],
33
+ email_address: signer[:email_address]
34
+ }
33
35
  end
34
36
  end
35
37
 
36
- def custom_fields
37
- @custom_fields.inject({}) do |parameter, custom_field|
38
+ def formatted_custom_fields
39
+ custom_fields.each_with_object({}) do |custom_field, parameter|
38
40
  parameter[custom_field[:name]] = custom_field[:value]
39
- parameter
40
41
  end
41
42
  end
42
43
 
44
+ def ccs
45
+ @ccs || {}
46
+ end
47
+
48
+ def signers
49
+ @signers || {}
50
+ end
51
+
52
+ def custom_fields
53
+ @custom_fields || {}
54
+ end
55
+
43
56
  end
44
57
  end
45
58
  end
@@ -3,37 +3,45 @@ require 'hello_sign/file'
3
3
  module HelloSign
4
4
  module Parameters
5
5
  class SignatureRequest
6
- attr_accessor :title, :subject, :message, :ccs
7
- attr_writer :signers, :files
6
+ attr_writer :title, :subject, :message, :ccs, :signers, :files
8
7
 
9
- def signers
10
- (@signers || {}).each_with_index.inject({}) do |parameter, (signer, index)|
11
- signer = {
8
+ def formatted
9
+ {
10
+ title: title,
11
+ subject: subject,
12
+ message: message,
13
+ cc_email_addresses: ccs,
14
+ signers: formatted_signers,
15
+ file: formatted_files
16
+ }
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :title, :subject, :message, :ccs
22
+
23
+ def formatted_signers
24
+ signers.each_with_index.each_with_object({}) do |(signer, i), parameter|
25
+ parameter[i] = {
12
26
  name: signer[:name],
13
27
  email_address: signer[:email_address],
14
- order: index
28
+ order: i
15
29
  }
16
- parameter[index] = signer
17
- parameter
18
30
  end
19
31
  end
20
32
 
21
- def files
22
- (@files || {}).each_with_index.inject({}) do |parameter, (file_data, index)|
23
- parameter[index + 1] = HelloSign::File.new(file_data).attachment
24
- parameter
33
+ def formatted_files
34
+ files.each_with_index.each_with_object({}) do |(file, i), parameter|
35
+ parameter[i + 1] = HelloSign::File.new(file).attachment
25
36
  end
26
37
  end
27
38
 
28
- def formatted
29
- {
30
- title: title,
31
- subject: subject,
32
- message: message,
33
- cc_email_addresses: ccs,
34
- signers: signers,
35
- file: files
36
- }
39
+ def signers
40
+ @signers || {}
41
+ end
42
+
43
+ def files
44
+ @files || {}
37
45
  end
38
46
 
39
47
  end
@@ -6,18 +6,21 @@ module HelloSign
6
6
  attr_writer :files
7
7
 
8
8
  def formatted
9
- {file: files}
9
+ {file: formatted_files}
10
10
  end
11
11
 
12
12
  private
13
13
 
14
- def files
15
- @files.each_with_index.inject({}) do |parameter, (file_data, index)|
16
- parameter[index] = HelloSign::File.new(file_data).attachment
17
- parameter
14
+ def formatted_files
15
+ files.each_with_index.each_with_object({}) do |(file, i), parameter|
16
+ parameter[i] = HelloSign::File.new(file).attachment
18
17
  end
19
18
  end
20
19
 
20
+ def files
21
+ @files || {}
22
+ end
23
+
21
24
  end
22
25
  end
23
26
  end
@@ -7,23 +7,15 @@ module HelloSign
7
7
  attr_reader :client, :request_id
8
8
 
9
9
  def initialize(client, request_id)
10
- @client = client
10
+ @client = client
11
11
  @request_id = request_id
12
12
  end
13
13
 
14
- def deliver(params = {})
14
+ def deliver(params = {}, &block)
15
15
  if form_id = params[:form]
16
- reusable_form_request_parameters.reusable_form_id = form_id
17
- yield reusable_form_request_parameters
18
-
19
- client.post(
20
- '/signature_request/send_with_reusable_form',
21
- body: reusable_form_request_parameters.formatted
22
- )
16
+ deliver_request_with_form(form_id, &block)
23
17
  else
24
- yield request_parameters
25
-
26
- client.post('/signature_request/send', body: request_parameters.formatted)
18
+ deliver_request(&block)
27
19
  end
28
20
  end
29
21
 
@@ -32,15 +24,15 @@ module HelloSign
32
24
  end
33
25
 
34
26
  def list(params = {})
35
- params = {page: 1}.merge(params)
27
+ client.get('/signature_request/list', params: {page: 1}.merge(params))
36
28
 
37
- client.get('/signature_request/list', params: params)
38
29
  end
39
30
 
40
31
  def remind(params = {})
41
- params = {email_address: params.delete(:email)}.merge(params)
42
-
43
- client.post("/signature_request/remind/#{request_id}", body: params)
32
+ client.post(
33
+ "/signature_request/remind/#{request_id}",
34
+ body: {email_address: params.delete(:email)}.merge(params)
35
+ )
44
36
  end
45
37
 
46
38
  def cancel
@@ -53,12 +45,32 @@ module HelloSign
53
45
 
54
46
  private
55
47
 
48
+ def deliver_request
49
+ yield request_parameters
50
+
51
+ client.post(
52
+ '/signature_request/send',
53
+ body: request_parameters.formatted
54
+ )
55
+ end
56
+
57
+ def deliver_request_with_form(form_id)
58
+ reusable_form_request_parameters.reusable_form_id = form_id
59
+ yield reusable_form_request_parameters
60
+
61
+ client.post(
62
+ '/signature_request/send_with_reusable_form',
63
+ body: reusable_form_request_parameters.formatted
64
+ )
65
+ end
66
+
56
67
  def request_parameters
57
68
  @request_parameters ||= Parameters::SignatureRequest.new
58
69
  end
59
70
 
60
71
  def reusable_form_request_parameters
61
- @reusable_form_request_parameters ||= Parameters::ReusableFormSignatureRequest.new
72
+ @reusable_form_request_parameters ||=
73
+ Parameters::ReusableFormSignatureRequest.new
62
74
  end
63
75
 
64
76
  end