hello_sign 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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