rightsignature-railstyle 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/CONTRIBUTING.md +26 -0
- data/Gemfile +2 -0
- data/README.md +443 -0
- data/Rakefile +2 -0
- data/lib/rightsignature.rb +15 -0
- data/lib/rightsignature/account.rb +37 -0
- data/lib/rightsignature/connection.rb +207 -0
- data/lib/rightsignature/connection/oauth_connection.rb +109 -0
- data/lib/rightsignature/connection/token_connection.rb +36 -0
- data/lib/rightsignature/document.rb +333 -0
- data/lib/rightsignature/errors.rb +51 -0
- data/lib/rightsignature/helpers/normalizing.rb +137 -0
- data/lib/rightsignature/helpers/refine_hash_to_indifferent_access.rb +23 -0
- data/lib/rightsignature/rails_style.rb +89 -0
- data/lib/rightsignature/template.rb +299 -0
- data/lib/rightsignature/version.rb +3 -0
- data/rightsignature-api.gemspec +26 -0
- data/spec/account_spec.rb +54 -0
- data/spec/api_token_connection_spec.rb +27 -0
- data/spec/configuration_spec.rb +98 -0
- data/spec/connection_spec.rb +224 -0
- data/spec/document_spec.rb +301 -0
- data/spec/errors_spec.rb +153 -0
- data/spec/normalizing_spec.rb +85 -0
- data/spec/oauth_connnection_spec.rb +143 -0
- data/spec/rails_style_spec.rb +331 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/template_spec.rb +408 -0
- metadata +143 -0
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe RightSignature::ResponseError do
|
4
|
+
describe "For OAuth response" do
|
5
|
+
before do
|
6
|
+
@net_http_response = Net::HTTPSuccess.new('1.1', '200', 'OK')
|
7
|
+
@error = RightSignature::ResponseError.new(@net_http_response)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "response should return Net::HTTP response" do
|
11
|
+
@error.response.should == @net_http_response
|
12
|
+
end
|
13
|
+
|
14
|
+
it "code should return response code" do
|
15
|
+
@error.code.should == '200'
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "message" do
|
19
|
+
it "should return response message" do
|
20
|
+
@error.message.should == 'OK'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should return specified message" do
|
24
|
+
error = RightSignature::ResponseError.new(@net_http_response, "No Way")
|
25
|
+
error.message.should == 'No Way'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "detailed_message" do
|
30
|
+
it "should return error message from xml" do
|
31
|
+
response = Net::HTTPNotAcceptable.new('1.1', 406, 'Not Acceptable')
|
32
|
+
response.stub(:body).and_return('<error><message>Invalid GUID</message></error>')
|
33
|
+
error = RightSignature::ResponseError.new(response)
|
34
|
+
error.detailed_message.should == 'Invalid GUID'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return nothing if response does not have error message node" do
|
38
|
+
response = Net::HTTPNotFound.new('1.1', 404, 'Not Found')
|
39
|
+
response.stub(:body).and_return('<html><body>Not Found</body></html>')
|
40
|
+
error = RightSignature::ResponseError.new(response)
|
41
|
+
error.detailed_message.should be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "common_solutions" do
|
46
|
+
describe "on 406" do
|
47
|
+
it "should suggest to check Content-Type header, url, or Accept header" do
|
48
|
+
net_http_response = Net::HTTPNotAcceptable.new('1.1', '406', 'Not Acceptable')
|
49
|
+
error = RightSignature::ResponseError.new(net_http_response)
|
50
|
+
error.common_solutions.should match /Check the Content-Type/i
|
51
|
+
error.common_solutions.should match /ensure url has \.xml or \.json/i
|
52
|
+
error.common_solutions.should match /check 'Accept' header/i
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "on 401" do
|
57
|
+
it "should suggest to check credentials" do
|
58
|
+
net_http_response = Net::HTTPUnauthorized.new('1.1', '401', 'Unauthorized Access')
|
59
|
+
error = RightSignature::ResponseError.new(net_http_response)
|
60
|
+
error.common_solutions.should match /Check your credentials/i
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "on 500s" do
|
65
|
+
it "should suggest to check xml or json format" do
|
66
|
+
net_http_response = Net::HTTPInternalServerError.new('1.1', '500', 'Internal Server Error')
|
67
|
+
error = RightSignature::ResponseError.new(net_http_response)
|
68
|
+
error.common_solutions.should match /Check the format of your xml or json/i
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "For HTTParty response" do
|
75
|
+
before do
|
76
|
+
@net_http_response = Net::HTTPOK.new('1.1', 200, 'OK')
|
77
|
+
@net_http_response.stub(:body =>"{}")
|
78
|
+
|
79
|
+
@response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), @net_http_response, lambda { {} })
|
80
|
+
@error = RightSignature::ResponseError.new(@response)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "response should return HTTParty response" do
|
84
|
+
@error.response.should == @response
|
85
|
+
end
|
86
|
+
|
87
|
+
it "code should return response code" do
|
88
|
+
@error.code.should == 200
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "message" do
|
92
|
+
it "should return response message" do
|
93
|
+
@error.message.should == 'OK'
|
94
|
+
end
|
95
|
+
it "should return specified message" do
|
96
|
+
error = RightSignature::ResponseError.new(@response, "No Way")
|
97
|
+
error.message.should == 'No Way'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "detailed_message" do
|
102
|
+
it "should return error message from xml" do
|
103
|
+
net_http_response = Net::HTTPNotAcceptable.new('1.1', 406, 'Not Acceptable')
|
104
|
+
net_http_response.stub(:body).and_return('<error><message>Invalid GUID</message></error>')
|
105
|
+
response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), net_http_response, lambda{{"error" => {"message" => "Invalid GUID"}}})
|
106
|
+
error = RightSignature::ResponseError.new(response)
|
107
|
+
error.detailed_message.should == 'Invalid GUID'
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should return nothing if response does not have error message node" do
|
111
|
+
net_http_response = Net::HTTPNotFound.new('1.1', 404, 'Not Found')
|
112
|
+
net_http_response.stub(:body).and_return('<html><body>Not Found</body></html>')
|
113
|
+
response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), net_http_response, lambda{ {}})
|
114
|
+
error = RightSignature::ResponseError.new(response)
|
115
|
+
error.detailed_message.should be_nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "common_solutions" do
|
120
|
+
describe "on 406" do
|
121
|
+
it "should suggest to check Content-Type header, url, or Accept header" do
|
122
|
+
net_http_response = Net::HTTPNotAcceptable.new('1.1', '406', 'Not Acceptable')
|
123
|
+
net_http_response.stub(:body =>"{}")
|
124
|
+
response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), net_http_response, lambda { {} })
|
125
|
+
error = RightSignature::ResponseError.new(response)
|
126
|
+
error.common_solutions.should match /Check the Content-Type/i
|
127
|
+
error.common_solutions.should match /ensure url has \.xml or \.json/i
|
128
|
+
error.common_solutions.should match /check 'Accept' header/i
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "on 401" do
|
133
|
+
it "should suggest to check credentials" do
|
134
|
+
net_http_response = Net::HTTPUnauthorized.new('1.1', '401', 'Unauthorized Access')
|
135
|
+
net_http_response.stub(:body =>"{}")
|
136
|
+
response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), net_http_response, lambda { {} })
|
137
|
+
error = RightSignature::ResponseError.new(response)
|
138
|
+
error.common_solutions.should match /Check your credentials/i
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "on 500s" do
|
143
|
+
it "should suggest to check xml or json format" do
|
144
|
+
net_http_response = Net::HTTPInternalServerError.new('1.1', '500', 'Internal Server Error')
|
145
|
+
net_http_response.stub(:body =>"{}")
|
146
|
+
response = HTTParty::Response.new(HTTParty::Request.new(Net::HTTP::Get, '/'), net_http_response, lambda { {} })
|
147
|
+
error = RightSignature::ResponseError.new(response)
|
148
|
+
error.common_solutions.should match /Check the format of your xml or json/i
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe RightSignature::Helpers::TagsHelper do
|
4
|
+
describe "mixed_array_to_string_array" do
|
5
|
+
it "should convert array of strings and hashes to string" do
|
6
|
+
RightSignature::Helpers::TagsHelper.mixed_array_to_string_array(["a", {'good' => "yea"}, '123']).should == "a,good:yea,123"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should raise error if array contains something other than hash or string" do
|
10
|
+
lambda {RightSignature::Helpers::TagsHelper.mixed_array_to_string_array(["a", ['bad'], {'good' => "yea"}])}.should raise_error
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "array_to_xml_hash" do
|
15
|
+
it "should convert array of string and hash of {name => value} into array of :tag => {:name => name, :value => value}" do
|
16
|
+
RightSignature::Helpers::TagsHelper.array_to_xml_hash(['abc', {"taggy" => "tvalue"}]).should == [{:tag => {:name => 'abc'}}, {:tag => {:name => 'taggy', :value => 'tvalue'}}]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should convert a symbol to a string for names and values" do
|
20
|
+
RightSignature::Helpers::TagsHelper.array_to_xml_hash([:abc, {:taggy => :tvalue}]).should == [
|
21
|
+
{:tag => {:name => 'abc'}},
|
22
|
+
{:tag => {:name => 'taggy', :value => 'tvalue'}}
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe RightSignature::Helpers::RolesHelper do
|
29
|
+
describe "array_to_xml_hash" do
|
30
|
+
it "should convert array of {\"Role name\" => {:name => name, :email => email}} to array of {:role => {:name => name, :email => email, \"@role_id\" => \"Role name\"}} " do
|
31
|
+
results = RightSignature::Helpers::RolesHelper.array_to_xml_hash([
|
32
|
+
{"Leaser" => {:name => "John Bellingham", :email => "j@example.com"}},
|
33
|
+
{"Leasee" => {:name => "Timmy S", :email => "t@example.com"}}
|
34
|
+
])
|
35
|
+
results.size.should == 2
|
36
|
+
results.include?({:role => {:name => "John Bellingham", :email => "j@example.com", "@role_name" => "Leaser"}})
|
37
|
+
results.include?({:role => {:name => "Timmy S", :email => "t@example.com", "@role_name" => "Leasee"}})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should convert array of {\"signer_A\" => {:name => name, :email => email}} or {\"cc_A\" => {:name => name, :email => email}} to array of {:role => {:name => name, :email => email, \"@role_id\" => \"signer_a\"}} " do
|
41
|
+
results = RightSignature::Helpers::RolesHelper.array_to_xml_hash([
|
42
|
+
{"signer_A" => {:name => "John Bellingham", :email => "j@example.com"}},
|
43
|
+
{"cc_A" => {:name => "Timmy S", :email => "t@example.com"}}
|
44
|
+
])
|
45
|
+
results.size.should == 2
|
46
|
+
results.include?({:role => {:name => "John Bellingham", :email => "j@example.com", "@role_id" => "signer_A"}})
|
47
|
+
results.include?({:role => {:name => "Timmy S", :email => "t@example.com", "@role_id" => "cc_A"}})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe RightSignature::Helpers::MergeFieldsHelper do
|
53
|
+
describe "array_to_xml_hash" do
|
54
|
+
it "should convert array of {\"Merge field name\" => \"Merge Field Value\"} to array of {:merge_field => {:value => \"Merge Field Value\", \"@merge_field_name\" => \"Merge Field Name\"}} " do
|
55
|
+
results = RightSignature::Helpers::MergeFieldsHelper.array_to_xml_hash([
|
56
|
+
{"City" => "Santa Barbara"},
|
57
|
+
{"Section" => "House"}
|
58
|
+
])
|
59
|
+
results.size.should == 2
|
60
|
+
results.include?({:merge_field => {:value => "Santa Barbara", "@merge_field_name" => "City"}})
|
61
|
+
results.include?({:merge_field => {:value => "House", "@merge_field_name" => "Section"}})
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should convert array of {\"Merge field name\" => \"Merge Field Value\"} to array of {:merge_field => {:value => \"Merge Field Value\", \"@merge_field_id\" => \"Merge Field Name\"}} " do
|
65
|
+
results = RightSignature::Helpers::MergeFieldsHelper.array_to_xml_hash([
|
66
|
+
{"1_abc_defg" => "Santa Barbara"},
|
67
|
+
{"2_345_789" => "House"}
|
68
|
+
], true)
|
69
|
+
results.size.should == 2
|
70
|
+
results.include?({:merge_field => {:value => "Santa Barbara", "@merge_field_id" => "1_abc_defg"}})
|
71
|
+
results.include?({:merge_field => {:value => "House", "@merge_field_id" => "2_345_789"}})
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should convert a symbol to a string for names and values" do
|
75
|
+
results = RightSignature::Helpers::MergeFieldsHelper.array_to_xml_hash([
|
76
|
+
{:abc_defg => :SomeValue},
|
77
|
+
{:higjk => "House"}
|
78
|
+
], true)
|
79
|
+
results.size.should == 2
|
80
|
+
results.include?({:merge_field => {:value => "SomeValue", "@merge_field_id" => "abc_defg"}})
|
81
|
+
results.include?({:merge_field => {:value => "House", "@merge_field_id" => "higjk"}})
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe RightSignature::OauthConnection do
|
4
|
+
before do
|
5
|
+
@consumer_mock = double(OAuth::Consumer)
|
6
|
+
@access_token_mock = double(OAuth::AccessToken, :token => "token", :secret => "secret")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "oauth_consumer" do
|
10
|
+
after do
|
11
|
+
# Reset caching of oauth_consumer
|
12
|
+
@oauth_connection.instance_variable_set("@oauth_consumer", nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise error if no configuration is set" do
|
16
|
+
@oauth_connection = RightSignature::OauthConnection.new()
|
17
|
+
lambda{@oauth_connection.oauth_consumer}.should raise_error(Exception, "Please set consumer_key, consumer_secret, access_token, access_secret")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should return consumer if consumer_key and consumer_secret is set" do
|
21
|
+
@oauth_connection = RightSignature::OauthConnection.new(:consumer_key => "Consumer123", :consumer_secret => "Secret098")
|
22
|
+
OAuth::Consumer.should_receive(:new).with(
|
23
|
+
"Consumer123",
|
24
|
+
"Secret098",
|
25
|
+
{
|
26
|
+
:site => "https://rightsignature.com",
|
27
|
+
:scheme => :header,
|
28
|
+
:http_method => :post,
|
29
|
+
:authorize_path =>'/oauth/authorize',
|
30
|
+
:access_token_path =>'/oauth/access_token',
|
31
|
+
:request_token_path=>'/oauth/request_token'
|
32
|
+
}).and_return(@consumer_mock)
|
33
|
+
@oauth_connection.oauth_consumer.should == @consumer_mock
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "access_token" do
|
38
|
+
it "should raise error if access_token is not set" do
|
39
|
+
oauth_connection = RightSignature::OauthConnection.new(:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_secret => "Secret098")
|
40
|
+
lambda{oauth_connection.access_token}.should raise_error(Exception, "Please set consumer_key, consumer_secret, access_token, access_secret")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should raise error if access_secret is not set" do
|
44
|
+
oauth_connection = RightSignature::OauthConnection.new(:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098")
|
45
|
+
lambda{oauth_connection.access_token}.should raise_error(Exception, "Please set consumer_key, consumer_secret, access_token, access_secret")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should create OAuth access token with credentials" do
|
49
|
+
oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123"})
|
50
|
+
OAuth::Consumer.should_receive(:new).and_return(@consumer_mock)
|
51
|
+
OAuth::AccessToken.should_receive(:new).with(@consumer_mock, 'AccessToken098', 'AccessSecret123')
|
52
|
+
|
53
|
+
oauth_connection.access_token
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "set_access_token" do
|
57
|
+
it "should create new access_token with given token and secret" do
|
58
|
+
OAuth::Consumer.stub(:new).and_return(@consumer_mock)
|
59
|
+
OAuth::AccessToken.should_receive(:new).with(@consumer_mock, "newAToken", "newASecret").and_return(@access_token_mock)
|
60
|
+
|
61
|
+
oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123"})
|
62
|
+
oauth_connection.set_access_token("newAToken","newASecret")
|
63
|
+
oauth_connection.access_token.should == @access_token_mock
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "new_request_token" do
|
69
|
+
it "should generate new RequestToken from consumer" do
|
70
|
+
request_mock = double(OAuth::RequestToken)
|
71
|
+
OAuth::Consumer.stub(:new).and_return(@consumer_mock)
|
72
|
+
@consumer_mock.should_receive(:get_request_token).and_return(request_mock)
|
73
|
+
|
74
|
+
oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123"})
|
75
|
+
oauth_connection.new_request_token
|
76
|
+
oauth_connection.request_token.should == request_mock
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should pass in options" do
|
80
|
+
request_mock = double(OAuth::RequestToken)
|
81
|
+
OAuth::Consumer.stub(:new).and_return(@consumer_mock)
|
82
|
+
@consumer_mock.should_receive(:get_request_token).with({:oauth_callback => "http://example.com/callback"}).and_return(request_mock)
|
83
|
+
|
84
|
+
oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123"})
|
85
|
+
oauth_connection.new_request_token({:oauth_callback => "http://example.com/callback"})
|
86
|
+
oauth_connection.request_token.should == request_mock
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "set_request_token" do
|
91
|
+
it "should create RequestToken with given token and secret" do
|
92
|
+
oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098"})
|
93
|
+
oauth_connection.set_request_token('request1', 'secret2')
|
94
|
+
oauth_connection.request_token.token.should == 'request1'
|
95
|
+
oauth_connection.request_token.secret.should == 'secret2'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "generate_access_token" do
|
100
|
+
before do
|
101
|
+
@oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098"})
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should raise error if there is no request_token" do
|
105
|
+
# Reset request_token cache"
|
106
|
+
@oauth_connection.instance_variable_set("@request_token", nil)
|
107
|
+
lambda{@oauth_connection.generate_access_token("verifi123")}.should raise_error(Exception, "Please set request token with new_request_token")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should get access token from request token with given verifier" do
|
111
|
+
request_token_mock = double(OAuth::RequestToken)
|
112
|
+
request_token_mock.should_receive(:get_access_token).with({:oauth_verifier => "verifi123"}).and_return(@access_token_mock)
|
113
|
+
@oauth_connection.instance_variable_set("@request_token", request_token_mock)
|
114
|
+
|
115
|
+
@oauth_connection.generate_access_token("verifi123")
|
116
|
+
@oauth_connection.access_token.should == @access_token_mock
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "request" do
|
121
|
+
before do
|
122
|
+
@oauth_connection = RightSignature::OauthConnection.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098"})
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should raise error if no configuration is set" do
|
126
|
+
oauth_connection = RightSignature::OauthConnection.new()
|
127
|
+
lambda{oauth_connection.request(:get, "path", {"User-Agent" => 'My own'})}.should raise_error(Exception, "Please set consumer_key, consumer_secret, access_token, access_secret")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should create GET request with access token and path with custom headers as 3rd argument" do
|
131
|
+
@access_token_mock.should_receive(:get).with('path', {"User-Agent" => 'My own', "Accept"=>"*/*", "content-type"=>"application/xml"})
|
132
|
+
@oauth_connection.stub(:access_token).and_return(@access_token_mock)
|
133
|
+
@oauth_connection.request(:get, "path", {"User-Agent" => 'My own'})
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should create POST request with access token and path with body as 3rd argument and custom headers as 4th argument" do
|
137
|
+
@access_token_mock.should_receive(:post).with('path', "<template></template>", {"User-Agent" => 'My own', "Accept"=>"*/*", "content-type"=>"application/xml"})
|
138
|
+
@oauth_connection.stub(:access_token).and_return(@access_token_mock)
|
139
|
+
@oauth_connection.request(:post, "path", "<template></template>", {"User-Agent" => 'My own'})
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
@@ -0,0 +1,331 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe RightSignature::RailsStyle do
|
4
|
+
describe "send_document" do
|
5
|
+
before do
|
6
|
+
@time = Time.now
|
7
|
+
@document_details = {
|
8
|
+
document: {
|
9
|
+
guid: "MYGUID",
|
10
|
+
created_at: (@time+0).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
11
|
+
completed_at: (@time+1).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
12
|
+
last_activity_at: (@time+2).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
13
|
+
expires_on: (@time+3).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
14
|
+
is_trashed: "false",
|
15
|
+
size: "4096",
|
16
|
+
content_type: "pdf",
|
17
|
+
original_filename: "MyFilename.pdf",
|
18
|
+
signed_pdf_checksum: "SOME123CHECKSUM",
|
19
|
+
subject: "some subject",
|
20
|
+
message: "some message",
|
21
|
+
processing_state: "done-processing",
|
22
|
+
merge_state: "done-processing",
|
23
|
+
state: "signed",
|
24
|
+
callback_location: "https://example.com/callback",
|
25
|
+
tags: "hel%2Clo,the%22re,abc:de%3Af",
|
26
|
+
recipients: {
|
27
|
+
recipient: [
|
28
|
+
{ name: "Jack Employee",
|
29
|
+
email: "jack@company.com",
|
30
|
+
must_sign: "true",
|
31
|
+
document_role_id: "signer_A",
|
32
|
+
role_id: "signer_A",
|
33
|
+
state: "signed",
|
34
|
+
is_sender: "false",
|
35
|
+
viewed_at: (@time+0).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
36
|
+
completed_at: (@time+1).strftime("%Y-%m-%dT%H:%M:%S%:z")
|
37
|
+
},
|
38
|
+
{ name: "Jill Employee",
|
39
|
+
email: "jill@company.com",
|
40
|
+
must_sign: "false",
|
41
|
+
document_role_id: "cc_A",
|
42
|
+
role_id: "cc_A",
|
43
|
+
state: "pending",
|
44
|
+
is_sender: "true",
|
45
|
+
viewed_at: nil,
|
46
|
+
completed_at: nil
|
47
|
+
}
|
48
|
+
]},
|
49
|
+
audit_trails: {
|
50
|
+
audit_trail: [
|
51
|
+
{ timestamp: (@time+0).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
52
|
+
keyword: "created",
|
53
|
+
message: "Document created via the RightSignature API by Jill Employee (jill@company.com)."
|
54
|
+
},
|
55
|
+
{ timestamp: (@time+1).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
56
|
+
keyword: "viewed",
|
57
|
+
message: "Document viewed by Jack Employee (jack@company.com)."
|
58
|
+
},
|
59
|
+
{ timestamp: (@time+2).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
60
|
+
keyword: "signed",
|
61
|
+
message: "Document signed by Jack Employee (jack@company.com) with drawn signature."
|
62
|
+
},
|
63
|
+
{ timestamp: (@time+3).strftime("%Y-%m-%dT%H:%M:%S%:z"),
|
64
|
+
keyword: "complete",
|
65
|
+
message: "All parties have signed document. Signed copies sent to: Jack Employee and Jill Employee."
|
66
|
+
}
|
67
|
+
]},
|
68
|
+
pages: {
|
69
|
+
page:
|
70
|
+
{ page_number: "1",
|
71
|
+
original_template_guid: "a_Template_GUID",
|
72
|
+
original_template_filename: "MyFilename.pdf"}
|
73
|
+
},
|
74
|
+
form_fields: {
|
75
|
+
form_field: [
|
76
|
+
{ id: "a_22177095_3d68450d37e04db69218abc886ebda0f_528356597",
|
77
|
+
name: "Form Field A",
|
78
|
+
role_id: "signer_A",
|
79
|
+
value: "Some Value A",
|
80
|
+
page: "1"
|
81
|
+
},
|
82
|
+
{ id: "a_22177095_3d68450d37e04db69218abc886ebda0f_528356595",
|
83
|
+
name: "Form Field B",
|
84
|
+
role_id: "signer_A",
|
85
|
+
value: "Some Value B",
|
86
|
+
page: "1"
|
87
|
+
},
|
88
|
+
]},
|
89
|
+
original_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22177095%2FMyFilename.pdf%3FAWSAccessKeyId%3DKEY%26Expires%3D#{@time.to_i}%26Signature%3DSOMESIG",
|
90
|
+
pdf_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22177095%2FMyFilename.pdf%3FAWSAccessKeyId%3DKEY%26Expires%3D#{@time.to_i}%26Signature%3DSOMESIG",
|
91
|
+
thumbnail_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22177095%2Fa_Some_Id_s_p1_t.png%3FAWSAccessKeyId%3DKEY%26Expires%3D#{@time.to_i}%26Signature%3DSOMESIG",
|
92
|
+
large_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22177095%2Fa_Some_id_s_p1.png%3FAWSAccessKeyId%3DKEY%26Expires%3D#{@time.to_i}%26Signature%3DSOMESIG",
|
93
|
+
signed_pdf_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22177095%2FMyFilename-signed.pdf%3FAWSAccessKeyId%3DKEY%26Expires%3D#{@time.to_i}%26Signature%3DSOMESIG",
|
94
|
+
}}
|
95
|
+
|
96
|
+
@template_details = {
|
97
|
+
template: {
|
98
|
+
type: "Document",
|
99
|
+
guid: "MYGUID",
|
100
|
+
created_at: "2017-03-03T09:24:18-08:00",
|
101
|
+
filename: "fw8ben.pdf",
|
102
|
+
size: "69211",
|
103
|
+
content_type: "pdf",
|
104
|
+
page_count: "1",
|
105
|
+
subject: "W-8BEN Tax Form",
|
106
|
+
message: "Please sign this document.",
|
107
|
+
tags: "hel%2Clo,the%22re,abc:de%3Af",
|
108
|
+
processing_state: "done-processing",
|
109
|
+
roles: {
|
110
|
+
role: [
|
111
|
+
{ role: "Document Sender",
|
112
|
+
name: "Document Sender",
|
113
|
+
must_sign: "false",
|
114
|
+
document_role_id: "cc_A",
|
115
|
+
is_sender: "true"
|
116
|
+
},
|
117
|
+
{ role: "Non-US Person",
|
118
|
+
name: "Non-US Person",
|
119
|
+
must_sign: "true",
|
120
|
+
document_role_id: "signer_A",
|
121
|
+
is_sender: "false"
|
122
|
+
}
|
123
|
+
]
|
124
|
+
},
|
125
|
+
merge_fields: {
|
126
|
+
merge_field: [
|
127
|
+
{id: "a_21470713_efe491a03af24760b457ea0c12061d55_512294075",
|
128
|
+
name: "Effective Date",
|
129
|
+
page: "1",
|
130
|
+
value: nil
|
131
|
+
},
|
132
|
+
{id: "a_21470713_efe491a03af24760b457ea0c12061d55_512294076",
|
133
|
+
name: "Content URL",
|
134
|
+
page: "1",
|
135
|
+
value: nil
|
136
|
+
},
|
137
|
+
]},
|
138
|
+
pages: {
|
139
|
+
page: {
|
140
|
+
page_number: "1",
|
141
|
+
original_template_guid: "a_22168482_df3f2b8fc9894d779d1f07c2d398ce70",
|
142
|
+
original_template_filename: "fw8ben.pdf"
|
143
|
+
}},
|
144
|
+
thumbnail_url: "https%3A%2F%2Fs3.amazonaws.com%2Fdocs.rightsignature.com%2Fassets%2F22168482%2Fa_Some_Id_p1_t.png%3FAWSAccessKeyId%3DKey%26Expires%3D#{@time.to_i}%26Signature%3DSomeSig",
|
145
|
+
}}
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'can accept strings or symbols for options' do
|
150
|
+
|
151
|
+
@rs.should_receive(:post).with('/api/templates/GUID123/prepackage.xml',
|
152
|
+
{}
|
153
|
+
).and_return({"template" => {
|
154
|
+
"guid" => "a_123985_1z9v8pd654",
|
155
|
+
"subject" => "subject template",
|
156
|
+
"message" => "Default message here",
|
157
|
+
}})
|
158
|
+
|
159
|
+
@rs.should_receive(:post).with('/api/templates.xml', {:template => {
|
160
|
+
:guid => "a_123985_1z9v8pd654",
|
161
|
+
:action => "send",
|
162
|
+
:subject => "sign me",
|
163
|
+
:roles => []
|
164
|
+
}})
|
165
|
+
|
166
|
+
@rs.prepackage_and_send("GUID123", [], {"subject" => "sign me"})
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'escapes tags' do
|
170
|
+
@rs.should_receive(:get).with('/api/templates.xml', {tags: "hel%2Clo,the%22re,key:val%3Aue"})
|
171
|
+
@rs.templates_list(tags: ["hel,lo", "the\"re",{key: "val:ue"}])
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'can accept metadata and tags' do
|
175
|
+
@rs.should_receive(:get).with('/api/templates.xml', {tags: "hello,there,abc:def"})
|
176
|
+
@rs.templates_list(
|
177
|
+
tags: ["hello", "there"],
|
178
|
+
metadata: {"abc" => "def"},
|
179
|
+
)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'escapes metadata and tags' do
|
183
|
+
@rs.should_receive(:get).with('/api/templates.xml', {tags: "hel%2Clo,the%22re,abc:de%3Af"})
|
184
|
+
@rs.templates_list(
|
185
|
+
tags: ["hel,lo", "the\"re"],
|
186
|
+
metadata: {"abc" => "de:f"},
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'can accept hash-based data' do
|
191
|
+
@rs = RightSignature::RailsStyle.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123", :api_token => "APITOKEN"})
|
192
|
+
|
193
|
+
@rs.should_receive(:post).with('/api/templates/GUID123/prepackage.xml',
|
194
|
+
{}
|
195
|
+
).and_return({"template" => {
|
196
|
+
"guid" => "a_123985_1z9v8pd654",
|
197
|
+
"subject" => "subject template",
|
198
|
+
"message" => "Default message here",
|
199
|
+
:merge_fields => [
|
200
|
+
{:merge_field => {
|
201
|
+
:value => "123456",
|
202
|
+
"@merge_field_id" => "123_abc_78"
|
203
|
+
}},
|
204
|
+
{merge_field: {
|
205
|
+
value: "654321",
|
206
|
+
"@merge_field_id": "321_cba_87"
|
207
|
+
}}
|
208
|
+
]
|
209
|
+
}})
|
210
|
+
|
211
|
+
@rs.should_receive(:post).with('/api/templates.xml', {:template => {
|
212
|
+
:guid => "a_123985_1z9v8pd654",
|
213
|
+
:action => "send",
|
214
|
+
:subject=>"subject template",
|
215
|
+
:tags=>[
|
216
|
+
{:tag=>{:name=>"a"}},
|
217
|
+
{:tag=>{:name=>"tag"}},
|
218
|
+
{:tag=>{:name=>"some", :value=>"data"}}
|
219
|
+
],
|
220
|
+
:merge_fields=>[
|
221
|
+
{:merge_field=>{:value=>"123456", "@merge_field_id"=>"123_abc_78"}},
|
222
|
+
{:merge_field=>{:value=>"654321", "@merge_field_id"=>"321_cba_87"}}
|
223
|
+
],
|
224
|
+
:roles => [
|
225
|
+
{:role => {
|
226
|
+
:name => "John Employee",
|
227
|
+
:email => "john@employee.com",
|
228
|
+
"@role_id" => "signer_A"
|
229
|
+
}},
|
230
|
+
{role: {
|
231
|
+
name: "Jill Employee",
|
232
|
+
email: "jill@employee.com",
|
233
|
+
"@role_id" => "signer_B",
|
234
|
+
}},
|
235
|
+
],
|
236
|
+
}})
|
237
|
+
|
238
|
+
@rs.prepackage_and_send(
|
239
|
+
"GUID123",
|
240
|
+
{ signer_A: {
|
241
|
+
:name => "John Employee",
|
242
|
+
:email => "john@employee.com"
|
243
|
+
},
|
244
|
+
signer_B: {
|
245
|
+
name: "Jill Employee",
|
246
|
+
email: "jill@employee.com",
|
247
|
+
}
|
248
|
+
},
|
249
|
+
{:merge_fields => {
|
250
|
+
"123_abc_78" => "123456",
|
251
|
+
"321_cba_87": "654321",
|
252
|
+
},
|
253
|
+
:use_merge_field_ids => true,
|
254
|
+
tags: ["a","tag"],
|
255
|
+
metadata: {
|
256
|
+
some: :data,
|
257
|
+
other: nil
|
258
|
+
}
|
259
|
+
})
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should format template details' do
|
263
|
+
@rs = RightSignature::RailsStyle.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123", :api_token => "APITOKEN"})
|
264
|
+
|
265
|
+
@rs.should_receive(:get).with('/api/templates/MYGUID.xml', {}).and_return(@template_details)
|
266
|
+
|
267
|
+
@doc = @rs.template_details('MYGUID')
|
268
|
+
|
269
|
+
expect(@doc).to include(
|
270
|
+
metadata: {"abc" => "de:f"},
|
271
|
+
tags: ["hel,lo", "the\"re"],
|
272
|
+
roles: include(
|
273
|
+
"cc_A" => include(document_role_id: "cc_A"),
|
274
|
+
"signer_A" => include(document_role_id: "signer_A"),
|
275
|
+
),
|
276
|
+
merge_fields: include(
|
277
|
+
"Effective Date" => include(name: "Effective Date"),
|
278
|
+
"Content URL" => include(name: "Content URL")
|
279
|
+
),
|
280
|
+
original_template_guid: "a_22168482_df3f2b8fc9894d779d1f07c2d398ce70",
|
281
|
+
original_template_filename: "fw8ben.pdf",
|
282
|
+
)
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'should format document details' do
|
286
|
+
@rs = RightSignature::RailsStyle.new({:consumer_key => "Consumer123", :consumer_secret => "Secret098", :access_token => "AccessToken098", :access_secret => "AccessSecret123", :api_token => "APITOKEN"})
|
287
|
+
|
288
|
+
@rs.should_receive(:get).with('/api/documents/MYGUID.xml').and_return(@document_details)
|
289
|
+
@doc = @rs.document_details('MYGUID')
|
290
|
+
|
291
|
+
# Only measuring the things that are different from normal document_details
|
292
|
+
expect(@doc).to include(
|
293
|
+
metadata: {"abc" => "de:f"},
|
294
|
+
tags: ["hel,lo", "the\"re"],
|
295
|
+
original_url: "https://s3.amazonaws.com/docs.rightsignature.com/assets/22177095/MyFilename.pdf?AWSAccessKeyId=KEY&Expires=#{@time.to_i}&Signature=SOMESIG",
|
296
|
+
original_template_guid: "a_Template_GUID",
|
297
|
+
original_template_filename: "MyFilename.pdf",
|
298
|
+
recipients: include(
|
299
|
+
"signer_A" => include(
|
300
|
+
name: "Jack Employee",
|
301
|
+
),
|
302
|
+
"cc_A" => include(
|
303
|
+
name: "Jill Employee",
|
304
|
+
),
|
305
|
+
),
|
306
|
+
audit_trails: include(
|
307
|
+
(@time+0).strftime("%Y-%m-%dT%H:%M:%S%:z") => include(
|
308
|
+
keyword: "created",
|
309
|
+
),
|
310
|
+
(@time+1).strftime("%Y-%m-%dT%H:%M:%S%:z") => include(
|
311
|
+
keyword: "viewed",
|
312
|
+
),
|
313
|
+
(@time+2).strftime("%Y-%m-%dT%H:%M:%S%:z") => include(
|
314
|
+
keyword: "signed",
|
315
|
+
),
|
316
|
+
(@time+3).strftime("%Y-%m-%dT%H:%M:%S%:z") => include(
|
317
|
+
keyword: "complete",
|
318
|
+
),
|
319
|
+
),
|
320
|
+
form_fields: include(
|
321
|
+
"Form Field A" => include(
|
322
|
+
value: "Some Value A",
|
323
|
+
),
|
324
|
+
"Form Field B" => include(
|
325
|
+
value: "Some Value B"
|
326
|
+
),
|
327
|
+
),
|
328
|
+
)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|