savon 0.9.14 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/README.md +1 -1
- data/lib/savon.rb +2 -2
- data/lib/savon/core_ext/string.rb +18 -11
- data/lib/savon/hooks/group.rb +31 -9
- data/lib/savon/hooks/hook.rb +28 -3
- data/lib/savon/model.rb +1 -7
- data/lib/savon/soap/request.rb +1 -1
- data/lib/savon/version.rb +1 -1
- data/spec/savon/hooks/group_spec.rb +71 -0
- data/spec/savon/hooks/hook_spec.rb +16 -0
- data/spec/savon/logger_spec.rb +1 -1
- data/spec/savon/model_spec.rb +0 -26
- data/spec/savon/soap/request_spec.rb +42 -5
- data/spec/spec_helper.rb +1 -1
- metadata +7 -5
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 1.0.0 (2012-06-09)
|
2
|
+
|
3
|
+
* Fix: `Savon.client` didn't pass the optional block.
|
4
|
+
|
5
|
+
* Improvement: [#291](https://github.com/rubiii/savon/issues/291) changed the `:soap_request` hook to act
|
6
|
+
like an around filter. The hook now receives a callback block to execute the SOAP call and can return
|
7
|
+
the result of the callback to continue the request. It can also not call the callback block and return
|
8
|
+
some `HTTPI::Response` to mock the SOAP request.
|
9
|
+
|
10
|
+
As this change affects `savon_spec`, you need to update `savon_spec` to v1.3.0.
|
11
|
+
|
1
12
|
## 0.9.14 (2012-06-07)
|
2
13
|
|
3
14
|
* Fix: [#292](https://github.com/rubiii/savon/issues/292) again
|
data/README.md
CHANGED
data/lib/savon.rb
CHANGED
@@ -4,17 +4,24 @@ module Savon
|
|
4
4
|
module CoreExt
|
5
5
|
module String
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
def self.included(base)
|
8
|
+
unless "savon".respond_to?(:snakecase)
|
9
|
+
base.send(:include, Extension)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Extension
|
14
|
+
def snakecase
|
15
|
+
str = dup
|
16
|
+
str.gsub! /::/, '/'
|
17
|
+
str.gsub! /([A-Z]+)([A-Z][a-z])/, '\1_\2'
|
18
|
+
str.gsub! /([a-z\d])([A-Z])/, '\1_\2'
|
19
|
+
str.tr! ".", "_"
|
20
|
+
str.tr! "-", "_"
|
21
|
+
str.downcase!
|
22
|
+
str
|
23
|
+
end
|
24
|
+
end
|
18
25
|
|
19
26
|
end
|
20
27
|
end
|
data/lib/savon/hooks/group.rb
CHANGED
@@ -9,14 +9,18 @@ module Savon
|
|
9
9
|
class Group
|
10
10
|
|
11
11
|
# Accepts an Array of +hooks+ to start with.
|
12
|
-
def initialize(hooks =
|
13
|
-
|
12
|
+
def initialize(hooks = [])
|
13
|
+
@hooks = hooks
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
# Returns whether this group contains hooks.
|
17
|
+
def empty?
|
18
|
+
hooks.empty?
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
21
|
+
# Returns the number of hooks in this group.
|
22
|
+
def count
|
23
|
+
hooks.count
|
20
24
|
end
|
21
25
|
|
22
26
|
# Adds a new hook.
|
@@ -25,14 +29,21 @@ module Savon
|
|
25
29
|
end
|
26
30
|
|
27
31
|
# Removes hooks matching the given +ids+.
|
28
|
-
def reject
|
32
|
+
def reject(*ids)
|
29
33
|
ids = ids.flatten
|
30
34
|
hooks.reject! { |hook| ids.include? hook.id }
|
31
35
|
end
|
32
36
|
|
33
|
-
#
|
34
|
-
def
|
35
|
-
|
37
|
+
# Fire a given +hook+ with any given +args+.
|
38
|
+
def fire(hook, *args, &callback)
|
39
|
+
callable = select(hook)
|
40
|
+
|
41
|
+
if callable.empty?
|
42
|
+
callback.call
|
43
|
+
else
|
44
|
+
args.unshift(callback) if callback
|
45
|
+
callable.call(*args)
|
46
|
+
end
|
36
47
|
end
|
37
48
|
|
38
49
|
# Calls the hooks with the given +args+ and returns the
|
@@ -41,6 +52,17 @@ module Savon
|
|
41
52
|
hooks.inject(nil) { |memo, hook| hook.call(*args) }
|
42
53
|
end
|
43
54
|
|
55
|
+
private
|
56
|
+
|
57
|
+
def hooks
|
58
|
+
@hooks ||= []
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns a new group for a given +hook+.
|
62
|
+
def select(hook)
|
63
|
+
Group.new hooks.select { |h| h.hook == hook }
|
64
|
+
end
|
65
|
+
|
44
66
|
end
|
45
67
|
end
|
46
68
|
end
|
data/lib/savon/hooks/hook.rb
CHANGED
@@ -8,17 +8,42 @@ module Savon
|
|
8
8
|
|
9
9
|
HOOKS = [
|
10
10
|
|
11
|
-
#
|
11
|
+
# :soap_request
|
12
|
+
#
|
13
|
+
# Around filter wrapping the POST request executed to call a SOAP service.
|
12
14
|
# See: Savon::SOAP::Request#response
|
13
15
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
+
# Arguments
|
17
|
+
#
|
18
|
+
# [callback] A block to execute the SOAP request
|
19
|
+
# [request] The current <tt>Savon::SOAP::Request</tt>
|
20
|
+
#
|
21
|
+
# Examples
|
22
|
+
#
|
23
|
+
# Log the time before and after the SOAP call:
|
24
|
+
#
|
25
|
+
# Savon.config.hooks.define(:my_hook, :soap_request) do |callback, request|
|
26
|
+
# Timer.log(:start, Time.now)
|
27
|
+
# response = callback.call
|
28
|
+
# Timer.log(:end, Time.now)
|
29
|
+
# response
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Replace the SOAP call and return a custom response:
|
33
|
+
#
|
34
|
+
# Savon.config.hooks.define(:mock_hook, :soap_request) do |_, request|
|
35
|
+
# HTTPI::Response.new(200, {}, "")
|
36
|
+
# end
|
16
37
|
:soap_request
|
17
38
|
|
18
39
|
]
|
19
40
|
|
20
41
|
# Expects an +id+, the name of the +hook+ to use and a +block+ to be called.
|
21
42
|
def initialize(id, hook, &block)
|
43
|
+
unless HOOKS.include?(hook)
|
44
|
+
raise ArgumentError, "No such hook: #{hook}. Expected one of: #{HOOKS.join(', ')}"
|
45
|
+
end
|
46
|
+
|
22
47
|
self.id = id
|
23
48
|
self.hook = hook
|
24
49
|
self.block = block
|
data/lib/savon/model.rb
CHANGED
@@ -30,8 +30,7 @@ module Savon
|
|
30
30
|
def define_class_action(action)
|
31
31
|
class_action_module.module_eval %{
|
32
32
|
def #{action.to_s.snakecase}(body = nil, &block)
|
33
|
-
|
34
|
-
config.hooks.select(:model_soap_response).call(response) || response
|
33
|
+
client.request :wsdl, #{action.inspect}, :body => body, &block
|
35
34
|
end
|
36
35
|
}
|
37
36
|
end
|
@@ -49,11 +48,6 @@ module Savon
|
|
49
48
|
def class_action_module
|
50
49
|
@class_action_module ||= Module.new do
|
51
50
|
|
52
|
-
# Returns the memoized <tt>Savon::Config</tt>.
|
53
|
-
def config
|
54
|
-
@config ||= Savon.config.clone
|
55
|
-
end
|
56
|
-
|
57
51
|
# Returns the memoized <tt>Savon::Client</tt>.
|
58
52
|
def client(&block)
|
59
53
|
@client ||= Savon::Client.new(&block)
|
data/lib/savon/soap/request.rb
CHANGED
@@ -31,7 +31,7 @@ module Savon
|
|
31
31
|
# Executes the request and returns the response.
|
32
32
|
def response
|
33
33
|
@response ||= begin
|
34
|
-
response = config.hooks.
|
34
|
+
response = config.hooks.fire(:soap_request, self) { with_logging { HTTPI.post(http) } }
|
35
35
|
SOAP::Response.new(config, response)
|
36
36
|
end
|
37
37
|
end
|
data/lib/savon/version.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Savon::Hooks::Group do
|
4
|
+
|
5
|
+
let(:group) { subject }
|
6
|
+
|
7
|
+
describe "#empty?" do
|
8
|
+
it "returns true for an empty group" do
|
9
|
+
group.should be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns false if the group contains hooks" do
|
13
|
+
group = Savon::Hooks::Group.new [:some_hook]
|
14
|
+
group.should_not be_empty
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#define" do
|
19
|
+
it "lets you define a new hook" do
|
20
|
+
group.define(:test_hook, :soap_request)
|
21
|
+
group.should_not be_empty
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises if there is no such hook" do
|
25
|
+
expect { group.define(:supposed_to_fail, :no_such_hook) }.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#reject" do
|
30
|
+
it "rejects hooks matching any given id" do
|
31
|
+
group.define(:remove1, :soap_request)
|
32
|
+
group.define(:here_to_stay, :soap_request)
|
33
|
+
group.define(:remove2, :soap_request)
|
34
|
+
group.count.should == 3
|
35
|
+
|
36
|
+
group.reject(:remove1, :remove2)
|
37
|
+
group.count.should == 1
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#fire" do
|
42
|
+
let(:hook) { lambda {} }
|
43
|
+
let(:fallback) { lambda {} }
|
44
|
+
|
45
|
+
context "with hooks" do
|
46
|
+
before do
|
47
|
+
group.define(:some_hook, :soap_request, &hook)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "calls the hooks passing any arguments" do
|
51
|
+
hook.expects(:call).with(:arg1, :arg2)
|
52
|
+
group.fire(:soap_request, :arg1, :arg2)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "calls the hooks passing any arguments and the callback" do
|
56
|
+
hook.expects(:call).with(fallback, :arg)
|
57
|
+
group.fire(:soap_request, :arg, &fallback)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "without hooks" do
|
62
|
+
it "executes the callback" do
|
63
|
+
report = :call
|
64
|
+
fallback = lambda { report = :back }
|
65
|
+
group.fire(:soap_request, &fallback)
|
66
|
+
report.should == :back
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Savon::Hooks::Hook do
|
4
|
+
|
5
|
+
let(:hook) { lambda {} }
|
6
|
+
|
7
|
+
describe "#call" do
|
8
|
+
it "calls the hook" do
|
9
|
+
hook = Savon::Hooks::Hook.new(:my_hook, :soap_request, &hook)
|
10
|
+
hook.expects(:call).with(:arg1, :arg2)
|
11
|
+
|
12
|
+
hook.call(:arg1, :arg2)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
data/spec/savon/logger_spec.rb
CHANGED
@@ -26,7 +26,7 @@ describe Savon::Logger do
|
|
26
26
|
it "logs a given message (pretty and filtered)" do
|
27
27
|
logger.subject.expects(logger.level).with(filtered_message.to_xml(:indent => 2))
|
28
28
|
logger.filter << :hello
|
29
|
-
|
29
|
+
logger.log(message, :pretty => true, :filter => true)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "defaults to wrap the standard Logger" do
|
data/spec/savon/model_spec.rb
CHANGED
@@ -6,38 +6,12 @@ describe Savon::Model do
|
|
6
6
|
Class.new { extend Savon::Model }
|
7
7
|
end
|
8
8
|
|
9
|
-
describe ":model_soap_response hook" do
|
10
|
-
before(:all) do
|
11
|
-
model.actions :get_user, "GetAllUsers"
|
12
|
-
end
|
13
|
-
|
14
|
-
after do
|
15
|
-
Savon.config.hooks.reject! :test_hook
|
16
|
-
end
|
17
|
-
|
18
|
-
it "can be used for pre-processing SOAP responses" do
|
19
|
-
Savon.config.hooks.define(:test_hook, :model_soap_response) do |response|
|
20
|
-
"hello #{response}"
|
21
|
-
end
|
22
|
-
|
23
|
-
model.client.stubs(:request).returns("world") #
|
24
|
-
model.get_user.should == "hello world"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
9
|
describe ".client" do
|
29
10
|
it "memoizes the Savon::Client" do
|
30
11
|
model.client.should equal(model.client)
|
31
12
|
end
|
32
13
|
end
|
33
14
|
|
34
|
-
describe ".config" do
|
35
|
-
it "memoizes a clone of the global config" do
|
36
|
-
model.config.should be_a(Savon::Config)
|
37
|
-
model.config.should_not equal(Savon.config)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
15
|
describe ".endpoint" do
|
42
16
|
it "sets the SOAP endpoint" do
|
43
17
|
model.endpoint "http://example.com"
|
@@ -2,9 +2,15 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Savon::SOAP::Request do
|
4
4
|
|
5
|
-
let(:soap_request)
|
6
|
-
let(:http_request)
|
7
|
-
let(:
|
5
|
+
let(:soap_request) { Savon::SOAP::Request.new(config, http_request, soap_xml) }
|
6
|
+
let(:http_request) { HTTPI::Request.new }
|
7
|
+
let(:http_response) { HTTPI::Response.new 200, {}, Fixture.response(:authentication) }
|
8
|
+
|
9
|
+
let(:config) {
|
10
|
+
config = Savon::Config.default
|
11
|
+
config.log = false
|
12
|
+
config
|
13
|
+
}
|
8
14
|
|
9
15
|
def soap_xml(*args)
|
10
16
|
@soap_xml ||= soap_xml!(*args)
|
@@ -26,7 +32,7 @@ describe Savon::SOAP::Request do
|
|
26
32
|
|
27
33
|
describe ".execute" do
|
28
34
|
it "executes a SOAP request and returns the response" do
|
29
|
-
HTTPI.expects(:post).returns(
|
35
|
+
HTTPI.expects(:post).returns(http_response)
|
30
36
|
response = Savon::SOAP::Request.execute config, http_request, soap_xml
|
31
37
|
response.should be_a(Savon::SOAP::Response)
|
32
38
|
end
|
@@ -67,9 +73,40 @@ describe Savon::SOAP::Request do
|
|
67
73
|
|
68
74
|
describe "#response" do
|
69
75
|
it "executes an HTTP POST request and returns a Savon::SOAP::Response" do
|
70
|
-
HTTPI.expects(:post).returns(
|
76
|
+
HTTPI.expects(:post).returns(http_response)
|
71
77
|
soap_request.response.should be_a(Savon::SOAP::Response)
|
72
78
|
end
|
79
|
+
|
80
|
+
context "with a :soap_request hook" do
|
81
|
+
it "lets you replace the HTTP request and return your own response" do
|
82
|
+
config.hooks.define(:test, :soap_request) do |_, request|
|
83
|
+
request.should be_a(Savon::SOAP::Request)
|
84
|
+
http_response
|
85
|
+
end
|
86
|
+
|
87
|
+
response = soap_request.response
|
88
|
+
response.http.should equal(http_response)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "works as an around filter for the SOAP request" do
|
92
|
+
HTTPI.expects(:post).returns(http_response)
|
93
|
+
state = []
|
94
|
+
|
95
|
+
config.hooks.define(:test, :soap_request) do |callback, request|
|
96
|
+
state << :before
|
97
|
+
response = callback.call
|
98
|
+
state << response
|
99
|
+
state << :after
|
100
|
+
response
|
101
|
+
end
|
102
|
+
|
103
|
+
response = soap_request.response
|
104
|
+
|
105
|
+
state[0].should == :before
|
106
|
+
state[1].should be_a(HTTPI::Response)
|
107
|
+
state[2].should == :after
|
108
|
+
end
|
109
|
+
end
|
73
110
|
end
|
74
111
|
|
75
112
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: savon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 0.9.14
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Daniel Harrington
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-06-
|
18
|
+
date: 2012-06-09 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -242,6 +242,8 @@ files:
|
|
242
242
|
- spec/savon/client_spec.rb
|
243
243
|
- spec/savon/config_spec.rb
|
244
244
|
- spec/savon/core_ext/string_spec.rb
|
245
|
+
- spec/savon/hooks/group_spec.rb
|
246
|
+
- spec/savon/hooks/hook_spec.rb
|
245
247
|
- spec/savon/http/error_spec.rb
|
246
248
|
- spec/savon/logger_spec.rb
|
247
249
|
- spec/savon/model_spec.rb
|