docusign_rest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ module DocusignRest
2
+ module Configuration
3
+ VALID_CONNECTION_KEYS = [:endpoint, :api_version, :user_agent, :method].freeze
4
+ VALID_OPTIONS_KEYS = [:username, :password, :integrator_key, :account_id, :format].freeze
5
+ VALID_CONFIG_KEYS = VALID_CONNECTION_KEYS + VALID_OPTIONS_KEYS
6
+
7
+ DEFAULT_ENDPOINT = 'https://demo.docusign.net/restapi'
8
+ DEFAULT_API_VERSION = 'v1'
9
+ DEFAULT_USER_AGENT = "DocusignRest API Ruby Gem #{DocusignRest::VERSION}".freeze
10
+ DEFAULT_METHOD = :get
11
+
12
+ DEFAULT_USERNAME = nil
13
+ DEFAULT_PASSWORD = nil
14
+ DEFAULT_INTEGRATOR_KEY = nil
15
+ DEFAULT_ACCOUNT_ID = nil
16
+ DEFAULT_FORMAT = :json
17
+
18
+ # Build accessor methods for every config options so we can do this, for example:
19
+ # DocusignRest.format = :xml
20
+ attr_accessor *VALID_CONFIG_KEYS
21
+
22
+ # Make sure we have the default values set when we get 'extended'
23
+ def self.extended(base)
24
+ base.reset
25
+ end
26
+
27
+ def reset
28
+ self.endpoint = DEFAULT_ENDPOINT
29
+ self.api_version = DEFAULT_API_VERSION
30
+ self.user_agent = DEFAULT_USER_AGENT
31
+ self.method = DEFAULT_METHOD
32
+
33
+ self.username = DEFAULT_USERNAME
34
+ self.password = DEFAULT_PASSWORD
35
+ self.integrator_key = DEFAULT_INTEGRATOR_KEY
36
+ self.account_id = DEFAULT_ACCOUNT_ID
37
+ self.format = DEFAULT_FORMAT
38
+ end
39
+
40
+ # Allow configuration via a block
41
+ def configure
42
+ yield self
43
+ end
44
+
45
+ def options
46
+ Hash[ * VALID_CONFIG_KEYS.map { |key| [key, send(key)] }.flatten ]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ require 'docusign_rest'
2
+ require 'rails'
3
+ module DocusignRest
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :docusign_rest
6
+
7
+ rake_tasks do
8
+ load 'tasks/docusign_task.rake'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module DocusignRest
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'multipart_post'
2
+ require 'parts'
3
+
4
+ Parts::ParamPart.class_eval do
5
+ def build_part(boundary, name, value)
6
+ part = "\r\n" #Add a leading carriage return line feed (not sure why DocuSign requires this)
7
+ part << "--#{boundary}\r\n"
8
+ part << "Content-Type: application/json\r\n" #Add the content type which isn't present in the multipart-post gem, but DocuSign requires
9
+ part << "Content-Disposition: form-data; name=\"#{name.to_s}\"\r\n"
10
+ part << "\r\n"
11
+ part << "#{value}\r\n"
12
+ end
13
+ end
@@ -0,0 +1,76 @@
1
+ require 'docusign_rest'
2
+
3
+ namespace :docusign_rest do
4
+ desc "Retrive account_id from the API"
5
+ task :generate_config do
6
+ def ask(message)
7
+ STDOUT.print message
8
+ STDIN.gets.chomp
9
+ end
10
+
11
+ STDOUT.puts %Q{
12
+ Please do the following:
13
+ ------------------------
14
+ 1) Login or register for an account at demo.docusign.net
15
+ ...or their production url if applicable
16
+ 2) Click 'Preferences' in the upper right corner of the page
17
+ 3) Click 'API' in far lower left corner of the menu
18
+ 4) Request a new 'Integrator Key' via the web interface
19
+ * You will use this key in one of the next steps to retrieve your 'accountId'\n\n}
20
+
21
+ username = ask('Please enter your DocuSign username: ')
22
+ password = ask('Please enter your DocuSign password: ')
23
+ integrator_key = ask('Please enter your DocuSign integrator key: ')
24
+
25
+ DocusignRest.configure do |config|
26
+ config.username = username
27
+ config.password = password
28
+ config.integrator_key = integrator_key
29
+ end
30
+
31
+ # initialize a client and request the accountId
32
+ client = DocusignRest::Client.new
33
+ acct_id = client.get_account_id
34
+
35
+ puts ""
36
+
37
+ # construct the configure block for the user with his or her credentials and accountId
38
+ config = %Q{# This file was generated by the docusign_rest:generate_config rake task.
39
+ # You can run 'rake docusign_rest:generate_config' as many times as you need
40
+ # to replace the content of this file with a new config.
41
+
42
+ require 'docusign_rest'
43
+
44
+ DocusignRest.configure do |config|
45
+ config.username = '#{username}'
46
+ config.password = '#{password}'
47
+ config.integrator_key = '#{integrator_key}'
48
+ config.account_id = '#{acct_id}'
49
+ end\n\n}
50
+
51
+ # write the initializer for the user
52
+ if defined?(Rails)
53
+ docusign_initializer_path = Rails.root.join("config/initializers/docusign_rest.rb")
54
+ else
55
+ docusign_initializer_path = "test/docusign_login_config.rb"
56
+ end
57
+
58
+ File.open(docusign_initializer_path, 'w') { |f| f.write(config) }
59
+ # read the initializer file into a var for comparison to the config block above
60
+ docusign_initializer_content = File.open(docusign_initializer_path) { |io| io.read }
61
+
62
+ # if they match tell the user we wrote the file, otherwise tell them to do it themselves
63
+ if docusign_initializer_content.include?(config)
64
+ if defined?(Rails)
65
+ puts "The following block of code was added to config/initializers/docusign_rest.rb\n\n"
66
+ else
67
+ puts "The following block of code was added to test/docusign_login_config.rb\n\n"
68
+ end
69
+ puts config
70
+ else
71
+ puts %Q{The config file was not able to be automatically created for you.
72
+ Please create it at config/initializers/docusign_rest.rb and add the following content:\n\n}
73
+ puts config
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,5 @@
1
+ require 'rake'
2
+ require 'json'
3
+
4
+ Rake.application.rake_require '../lib/tasks/docusign_task'
5
+ Rake.application['docusign_rest:generate_config'].invoke
Binary file
@@ -0,0 +1,191 @@
1
+ require 'helper'
2
+
3
+ describe DocusignRest::Client do
4
+
5
+ before do
6
+ @keys = DocusignRest::Configuration::VALID_CONFIG_KEYS
7
+ end
8
+
9
+ describe 'with module configuration' do
10
+ before do
11
+ DocusignRest.configure do |config|
12
+ @keys.each do |key|
13
+ config.send("#{key}=", key)
14
+ end
15
+ end
16
+ end
17
+
18
+ after do
19
+ DocusignRest.reset
20
+ end
21
+
22
+ it "should inherit module configuration" do
23
+ api = DocusignRest::Client.new
24
+ @keys.each do |key|
25
+ api.send(key).must_equal key
26
+ end
27
+ end
28
+
29
+ describe 'with class configuration' do
30
+ before do
31
+ @config = {
32
+ :username => 'un',
33
+ :password => 'pd',
34
+ :integrator_key => 'ik',
35
+ :account_id => 'ai',
36
+ :format => 'fm',
37
+ :endpoint => 'ep',
38
+ :api_version => 'av',
39
+ :user_agent => 'ua',
40
+ :method => 'md',
41
+ }
42
+ end
43
+
44
+ it 'should override module configuration' do
45
+ api = DocusignRest::Client.new(@config)
46
+ @keys.each do |key|
47
+ api.send(key).must_equal @config[key]
48
+ end
49
+ end
50
+
51
+ it 'should override module configuration after' do
52
+ api = DocusignRest::Client.new
53
+
54
+ @config.each do |key, value|
55
+ api.send("#{key}=", value)
56
+ end
57
+
58
+ @keys.each do |key|
59
+ api.send("#{key}").must_equal @config[key]
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'client' do
66
+ before do
67
+ # Note: to configure the client please run the docusign_task.rb file:
68
+ #
69
+ # $ ruby lib/tasks/docusign_task.rb
70
+ #
71
+ # which will populate the test/docusign_login_config.rb file
72
+ @client = DocusignRest::Client.new
73
+ end
74
+
75
+ it "should allow access to the auth headers after initialization" do
76
+ @client.must_respond_to :docusign_authentication_headers
77
+ end
78
+
79
+ it "should allow access to the acct_id after initialization" do
80
+ @client.must_respond_to :acct_id
81
+ end
82
+
83
+ it "should allow creating an envelope from a document" do
84
+ VCR.use_cassette("create_envelope/from_document", record: :once) do
85
+ response = @client.create_envelope_from_document(
86
+ email: {
87
+ subject: "test email subject",
88
+ body: "this is the email body and it's large!"
89
+ },
90
+ # If embedded is set to true in the signers array below, emails
91
+ # don't go out and you can embed the signature page in an iFrame
92
+ # by using the get_recipient_view method. You can choose 'false' or
93
+ # simply omit the option as I show in the second signer hash.
94
+ signers: [
95
+ {
96
+ embedded: true,
97
+ name: 'Test Guy',
98
+ email: 'someone@gmail.com'
99
+ },
100
+ {
101
+ #embedded: true,
102
+ name: 'Test Girl',
103
+ email: 'someone+else@gmail.com'
104
+ }
105
+ ],
106
+ files: [
107
+ {path: 'test.pdf', name: 'test.pdf'},
108
+ {path: 'test2.pdf', name: 'test2.pdf'}
109
+ ],
110
+ status: 'sent'
111
+ )
112
+ response = JSON.parse(response.body)
113
+ response["status"].must_equal "sent"
114
+ end
115
+ end
116
+
117
+ describe "embedded signing" do
118
+ before do
119
+ # create the template dynamically
120
+ VCR.use_cassette("create_template", record: :once) do
121
+ response = @client.create_template(
122
+ description: 'Cool Description',
123
+ name: "Cool Template Name",
124
+ signers: [
125
+ {
126
+ embedded: true,
127
+ name: 'jon',
128
+ email: 'someone@gmail.com',
129
+ role_name: 'Issuer',
130
+ anchor_string: 'sign here',
131
+ sign_here_tab_text: 'Issuer, Please Sign Here',
132
+ template_locked: true, #doesn't seem to do anything
133
+ template_required: true, #doesn't seem to do anything
134
+ email_notification: false #FIXME if signer is setup as 'embedded' initial email notifications don't go out, but even when I set up a signer as non-embedded this setting didn't seem to make the email notifications actually stop...
135
+ }
136
+ ],
137
+ files: [
138
+ {path: 'test.pdf', name: 'test.pdf'}
139
+ ]
140
+ )
141
+ @template_response = JSON.parse(response.body)
142
+ end
143
+
144
+ # use the templateId to get the envelopeId
145
+ VCR.use_cassette("create_envelope/from_template", record: :once) do
146
+ response = @client.create_envelope_from_template(
147
+ status: 'sent',
148
+ email: {
149
+ subject: "The test email subject envelope",
150
+ body: "Envelope body content here"
151
+ },
152
+ template_id: @template_response["templateId"],
153
+ signers: [
154
+ {
155
+ embedded: true,
156
+ name: 'jon',
157
+ email: 'someone@gmail.com',
158
+ role_name: 'Issuer'
159
+ }
160
+ ]
161
+ )
162
+ @envelope_response = JSON.parse(response.body)
163
+ end
164
+ end
165
+
166
+ it "should return a URL for embedded signing" do
167
+ #ensure template was created
168
+ @template_response["templateId"].wont_be_nil
169
+ @template_response["name"].must_equal "Cool Template Name"
170
+
171
+ #ensure creating an envelope from a dynamic template did not error
172
+ @envelope_response["errorCode"].must_be_nil
173
+
174
+ #return the URL for embedded signing
175
+ VCR.use_cassette("get_recipient_view", record: :once) do
176
+ response = @client.get_recipient_view(
177
+ envelope_id: @envelope_response["envelopeId"],
178
+ name: 'jon',
179
+ email: 'someone@gmail.com',
180
+ return_url: 'http://google.com'
181
+ )
182
+ @view_recipient_response = JSON.parse(response.body)
183
+ puts @view_recipient_response["url"]
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ end
190
+
191
+ end
@@ -0,0 +1,24 @@
1
+ require 'helper'
2
+
3
+ describe 'configuration' do
4
+ after do
5
+ DocusignRest.reset
6
+ end
7
+
8
+ describe '.configure' do
9
+ DocusignRest::Configuration::VALID_CONFIG_KEYS.each do |key|
10
+ it "should set the #{key}" do
11
+ DocusignRest.configure do |config|
12
+ config.send("#{key}=", key)
13
+ DocusignRest.send(key).must_equal key
14
+ end
15
+ end
16
+
17
+ describe '.key' do
18
+ it "should return default value for #{key}" do
19
+ DocusignRest.send(key).must_equal DocusignRest::Configuration.const_get("DEFAULT_#{key.upcase}")
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ describe DocusignRest do
4
+ it "should have a version" do
5
+ DocusignRest::VERSION.wont_be_nil
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ require 'docusign_rest'
2
+ require 'minitest/spec'
3
+ require 'minitest/autorun'
4
+ require 'turn'
5
+ require 'json'
6
+ require 'vcr'
7
+ require 'docusign_login_config'
8
+
9
+ VCR.configure do |c|
10
+ c.cassette_library_dir = "test/fixtures/vcr"
11
+ c.hook_into :fakeweb
12
+ end
Binary file
metadata ADDED
@@ -0,0 +1,200 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: docusign_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Kinney
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: multipart-post
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.5
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: turn
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: pry
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: vcr
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: fakeweb
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: Hooks a Rails app up to the DocuSign service through the DocuSign REST
143
+ API
144
+ email:
145
+ - jonkinney@gmail.com
146
+ executables: []
147
+ extensions: []
148
+ extra_rdoc_files: []
149
+ files:
150
+ - .gitignore
151
+ - Gemfile
152
+ - LICENSE
153
+ - README.md
154
+ - Rakefile
155
+ - docusign_rest.gemspec
156
+ - example.rb
157
+ - lib/docusign_rest.rb
158
+ - lib/docusign_rest/client.rb
159
+ - lib/docusign_rest/configuration.rb
160
+ - lib/docusign_rest/railtie.rb
161
+ - lib/docusign_rest/version.rb
162
+ - lib/multipart_post/parts.rb
163
+ - lib/tasks/docusign_task.rake
164
+ - lib/tasks/docusign_task.rb
165
+ - test.pdf
166
+ - test/docusign_rest/client_test.rb
167
+ - test/docusign_rest/configuration_test.rb
168
+ - test/docusign_rest/docusign_rest_test.rb
169
+ - test/helper.rb
170
+ - test2.pdf
171
+ homepage: https://github.com/j2fly/docusign_rest
172
+ licenses: []
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ none: false
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ required_rubygems_version: !ruby/object:Gem::Requirement
184
+ none: false
185
+ requirements:
186
+ - - ! '>='
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubyforge_project:
191
+ rubygems_version: 1.8.24
192
+ signing_key:
193
+ specification_version: 3
194
+ summary: Use this gem to embed signing of documents in a Rails app through the DocuSign
195
+ REST API
196
+ test_files:
197
+ - test/docusign_rest/client_test.rb
198
+ - test/docusign_rest/configuration_test.rb
199
+ - test/docusign_rest/docusign_rest_test.rb
200
+ - test/helper.rb