actionwebservice 0.5.0

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 (54) hide show
  1. data/ChangeLog +47 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +238 -0
  4. data/Rakefile +144 -0
  5. data/TODO +13 -0
  6. data/examples/googlesearch/README +143 -0
  7. data/examples/googlesearch/autoloading/google_search_api.rb +50 -0
  8. data/examples/googlesearch/autoloading/google_search_controller.rb +57 -0
  9. data/examples/googlesearch/delegated/google_search_service.rb +108 -0
  10. data/examples/googlesearch/delegated/search_controller.rb +7 -0
  11. data/examples/googlesearch/direct/google_search_api.rb +50 -0
  12. data/examples/googlesearch/direct/search_controller.rb +58 -0
  13. data/examples/metaWeblog/README +16 -0
  14. data/examples/metaWeblog/blog_controller.rb +127 -0
  15. data/lib/action_web_service.rb +60 -0
  16. data/lib/action_web_service/api.rb +2 -0
  17. data/lib/action_web_service/api/abstract.rb +192 -0
  18. data/lib/action_web_service/api/action_controller.rb +92 -0
  19. data/lib/action_web_service/base.rb +41 -0
  20. data/lib/action_web_service/client.rb +3 -0
  21. data/lib/action_web_service/client/base.rb +39 -0
  22. data/lib/action_web_service/client/soap_client.rb +88 -0
  23. data/lib/action_web_service/client/xmlrpc_client.rb +77 -0
  24. data/lib/action_web_service/container.rb +85 -0
  25. data/lib/action_web_service/dispatcher.rb +2 -0
  26. data/lib/action_web_service/dispatcher/abstract.rb +150 -0
  27. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +299 -0
  28. data/lib/action_web_service/invocation.rb +205 -0
  29. data/lib/action_web_service/protocol.rb +4 -0
  30. data/lib/action_web_service/protocol/abstract.rb +128 -0
  31. data/lib/action_web_service/protocol/registry.rb +55 -0
  32. data/lib/action_web_service/protocol/soap_protocol.rb +484 -0
  33. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +168 -0
  34. data/lib/action_web_service/struct.rb +55 -0
  35. data/lib/action_web_service/support/class_inheritable_options.rb +26 -0
  36. data/lib/action_web_service/support/signature.rb +100 -0
  37. data/setup.rb +1360 -0
  38. data/test/abstract_client.rb +131 -0
  39. data/test/abstract_soap.rb +58 -0
  40. data/test/abstract_unit.rb +9 -0
  41. data/test/api_test.rb +52 -0
  42. data/test/base_test.rb +42 -0
  43. data/test/client_soap_test.rb +93 -0
  44. data/test/client_xmlrpc_test.rb +92 -0
  45. data/test/container_test.rb +53 -0
  46. data/test/dispatcher_action_controller_test.rb +186 -0
  47. data/test/gencov +3 -0
  48. data/test/invocation_test.rb +149 -0
  49. data/test/protocol_registry_test.rb +53 -0
  50. data/test/protocol_soap_test.rb +252 -0
  51. data/test/protocol_xmlrpc_test.rb +147 -0
  52. data/test/run +5 -0
  53. data/test/struct_test.rb +40 -0
  54. metadata +131 -0
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/abstract_unit'
2
+
3
+ module ContainerTest
4
+
5
+ $immediate_service = Object.new
6
+ $deferred_service = Object.new
7
+
8
+ class DelegateContainer < ActionController::Base
9
+ web_service_dispatching_mode :delegated
10
+
11
+ attr :flag
12
+ attr :previous_flag
13
+
14
+ def initialize
15
+ @previous_flag = nil
16
+ @flag = true
17
+ end
18
+
19
+ web_service :immediate_service, $immediate_service
20
+ web_service(:deferred_service) { @previous_flag = @flag; @flag = false; $deferred_service }
21
+ end
22
+
23
+ class DirectContainer < ActionController::Base
24
+ web_service_dispatching_mode :direct
25
+ end
26
+ end
27
+
28
+ class TC_Container < Test::Unit::TestCase
29
+ def setup
30
+ @delegate_container = ContainerTest::DelegateContainer.new
31
+ @direct_container = ContainerTest::DirectContainer.new
32
+ end
33
+
34
+ def test_registration
35
+ assert(ContainerTest::DelegateContainer.has_web_service?(:immediate_service))
36
+ assert(ContainerTest::DelegateContainer.has_web_service?(:deferred_service))
37
+ assert(!ContainerTest::DelegateContainer.has_web_service?(:fake_service))
38
+ end
39
+
40
+ def test_service_object
41
+ assert(@delegate_container.flag == true)
42
+ assert(@delegate_container.web_service_object(:immediate_service) == $immediate_service)
43
+ assert(@delegate_container.previous_flag.nil?)
44
+ assert(@delegate_container.flag == true)
45
+ assert(@delegate_container.web_service_object(:deferred_service) == $deferred_service)
46
+ assert(@delegate_container.previous_flag == true)
47
+ assert(@delegate_container.flag == false)
48
+ end
49
+
50
+ def test_direct_container
51
+ assert(ContainerTest::DirectContainer.web_service_dispatching_mode == :direct)
52
+ end
53
+ end
@@ -0,0 +1,186 @@
1
+ require File.dirname(__FILE__) + '/abstract_soap'
2
+ require 'wsdl/parser'
3
+
4
+ module DispatcherActionControllerTest
5
+ class API < ActionWebService::API::Base
6
+ api_method :add, :expects => [:int, :int], :returns => [:int]
7
+ end
8
+
9
+ class DirectAPI < ActionWebService::API::Base
10
+ api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int]
11
+ api_method :before_filtered
12
+ api_method :after_filtered, :returns => [:int]
13
+ api_method :thrower
14
+ end
15
+
16
+ class Service < ActionWebService::Base
17
+ web_service_api API
18
+
19
+ attr :added
20
+
21
+ def add(a, b)
22
+ @added = a + b
23
+ end
24
+ end
25
+
26
+ class AbstractController < ActionController::Base
27
+ def generate_wsdl(container, uri, soap_action_base)
28
+ to_wsdl(container, uri, soap_action_base)
29
+ end
30
+ end
31
+
32
+ class DelegatedController < AbstractController
33
+ web_service_dispatching_mode :delegated
34
+
35
+ web_service(:test_service) { @service ||= Service.new; @service }
36
+ end
37
+
38
+ class DirectController < AbstractController
39
+ web_service_api DirectAPI
40
+ web_service_dispatching_mode :direct
41
+
42
+ before_filter :alwaysfail, :only => [:before_filtered]
43
+ after_filter :alwaysok, :only => [:after_filtered]
44
+
45
+ attr :added
46
+ attr :before_filter_called
47
+ attr :before_filter_target_called
48
+ attr :after_filter_called
49
+ attr :after_filter_target_called
50
+
51
+ def initialize
52
+ @before_filter_called = false
53
+ @before_filter_target_called = false
54
+ @after_filter_called = false
55
+ @after_filter_target_called = false
56
+ end
57
+
58
+ def add
59
+ @added = @params['a'] + @params['b']
60
+ end
61
+
62
+ def before_filtered
63
+ @before_filter_target_called = true
64
+ end
65
+
66
+ def after_filtered
67
+ @after_filter_target_called = true
68
+ 5
69
+ end
70
+
71
+ def thrower
72
+ raise "Hi, I'm a SOAP exception"
73
+ end
74
+
75
+ protected
76
+ def alwaysfail
77
+ @before_filter_called = true
78
+ false
79
+ end
80
+
81
+ def alwaysok
82
+ @after_filter_called = true
83
+ end
84
+ end
85
+ end
86
+
87
+ class TC_DispatcherActionController < AbstractSoapTest
88
+ include DispatcherActionControllerTest
89
+
90
+ def test_direct_dispatching
91
+ @container = DirectController.new
92
+ assert(do_soap_call('Add', 20, 50) == 70)
93
+ assert(@container.added == 70)
94
+ end
95
+
96
+ def test_direct_entrypoint
97
+ @container = DirectController.new
98
+ assert(@container.respond_to?(:api))
99
+ end
100
+
101
+ def test_direct_filtering
102
+ @container = DirectController.new
103
+ assert(@container.before_filter_called == false)
104
+ assert(@container.before_filter_target_called == false)
105
+ assert(do_soap_call('BeforeFiltered').nil?)
106
+ assert(@container.before_filter_called == true)
107
+ assert(@container.before_filter_target_called == false)
108
+ assert(@container.after_filter_called == false)
109
+ assert(@container.after_filter_target_called == false)
110
+ assert(do_soap_call('AfterFiltered') == 5)
111
+ assert(@container.after_filter_called == true)
112
+ assert(@container.after_filter_target_called == true)
113
+ end
114
+
115
+ def test_delegated_dispatching
116
+ @container = DelegatedController.new
117
+ assert(do_soap_call('Add', 50, 80) == 130)
118
+ assert(service.added == 130)
119
+ end
120
+
121
+ def test_exception_marshaling
122
+ @container = DirectController.new
123
+ result = do_soap_call('Thrower')
124
+ exception = result.detail
125
+ assert(exception.cause.is_a?(RuntimeError))
126
+ assert_equal("Hi, I'm a SOAP exception", exception.cause.message)
127
+ @container.web_service_exception_reporting = false
128
+ assert_raises(SoapTestError) do
129
+ do_soap_call('Thrower')
130
+ end
131
+ end
132
+
133
+ def test_wsdl_generation
134
+ ensure_valid_wsdl_generation DelegatedController.new
135
+ ensure_valid_wsdl_generation DirectController.new
136
+ end
137
+
138
+ def
139
+
140
+ def test_wsdl_action
141
+ ensure_valid_wsdl_action DelegatedController.new
142
+ ensure_valid_wsdl_action DirectController.new
143
+ end
144
+
145
+ protected
146
+ def service_name
147
+ @container.is_a?(DelegatedController) ? 'test_service' : 'api'
148
+ end
149
+
150
+ def service
151
+ @container.web_service_object(:test_service)
152
+ end
153
+
154
+ def do_soap_call(public_method_name, *args)
155
+ super(public_method_name, *args) do |test_request, test_response|
156
+ response = @container.process(test_request, test_response)
157
+ end
158
+ end
159
+
160
+ def ensure_valid_wsdl_generation(controller)
161
+ wsdl = controller.generate_wsdl(controller, 'http://localhost:3000/test/', '/test')
162
+ ensure_valid_wsdl(wsdl)
163
+ end
164
+
165
+ def ensure_valid_wsdl(wsdl)
166
+ definitions = WSDL::Parser.new.parse(wsdl)
167
+ assert(definitions.is_a?(WSDL::Definitions))
168
+ definitions.bindings.each do |binding|
169
+ assert(binding.name.name.index(':').nil?)
170
+ end
171
+ definitions.services.each do |service|
172
+ service.ports.each do |port|
173
+ assert(port.name.name.index(':').nil?)
174
+ end
175
+ end
176
+ end
177
+
178
+ def ensure_valid_wsdl_action(controller)
179
+ test_request = ActionController::TestRequest.new({ 'action' => 'wsdl' })
180
+ test_request.env['REQUEST_METHOD'] = 'GET'
181
+ test_request.env['HTTP_HOST'] = 'localhost:3000'
182
+ test_response = ActionController::TestResponse.new
183
+ wsdl = controller.process(test_request, test_response).body
184
+ ensure_valid_wsdl(wsdl)
185
+ end
186
+ end
data/test/gencov ADDED
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ rcov -x '.*_test\.rb,rubygems,abstract_,/run' ./run
@@ -0,0 +1,149 @@
1
+ require File.dirname(__FILE__) + '/abstract_unit'
2
+
3
+ module InvocationTest
4
+ class API < ActionWebService::API::Base
5
+ api_method :add, :expects => [:int, :int], :returns => [:int]
6
+ api_method :transmogrify, :expects_and_returns => [:string]
7
+ api_method :fail_with_reason
8
+ api_method :fail_generic
9
+ api_method :no_before
10
+ api_method :no_after
11
+ api_method :only_one
12
+ api_method :only_two
13
+ end
14
+
15
+ class Service < ActionWebService::Base
16
+ web_service_api API
17
+
18
+ before_invocation :intercept_before, :except => [:no_before]
19
+ after_invocation :intercept_after, :except => [:no_after]
20
+ before_invocation :intercept_only, :only => [:only_one, :only_two]
21
+
22
+ attr_accessor :before_invoked
23
+ attr_accessor :after_invoked
24
+ attr_accessor :only_invoked
25
+ attr_accessor :invocation_result
26
+
27
+ def initialize
28
+ @before_invoked = nil
29
+ @after_invoked = nil
30
+ @only_invoked = nil
31
+ @invocation_result = nil
32
+ end
33
+
34
+ def add(a, b)
35
+ a + b
36
+ end
37
+
38
+ def transmogrify(str)
39
+ str.upcase
40
+ end
41
+
42
+ def fail_with_reason
43
+ end
44
+
45
+ def fail_generic
46
+ end
47
+
48
+ def no_before
49
+ 5
50
+ end
51
+
52
+ def no_after
53
+ end
54
+
55
+ def only_one
56
+ end
57
+
58
+ def only_two
59
+ end
60
+
61
+ protected
62
+ def intercept_before(name, args)
63
+ @before_invoked = name
64
+ return [false, "permission denied"] if name == :fail_with_reason
65
+ return false if name == :fail_generic
66
+ end
67
+
68
+ def intercept_after(name, args, result)
69
+ @after_invoked = name
70
+ @invocation_result = result
71
+ end
72
+
73
+ def intercept_only(name, args)
74
+ raise "Interception error" unless name == :only_one || name == :only_two
75
+ @only_invoked = name
76
+ end
77
+ end
78
+ end
79
+
80
+ class TC_Invocation < Test::Unit::TestCase
81
+ include ActionWebService::Invocation
82
+
83
+ def setup
84
+ @service = InvocationTest::Service.new
85
+ end
86
+
87
+ def test_invocation
88
+ assert(perform_invocation(:add, 5, 10) == 15)
89
+ assert(perform_invocation(:transmogrify, "hello") == "HELLO")
90
+ assert_raises(NoMethodError) do
91
+ perform_invocation(:nonexistent_method_xyzzy)
92
+ end
93
+ end
94
+
95
+ def test_interceptor_registration
96
+ assert(InvocationTest::Service.before_invocation_interceptors.length == 2)
97
+ assert(InvocationTest::Service.after_invocation_interceptors.length == 1)
98
+ end
99
+
100
+ def test_interception
101
+ assert(@service.before_invoked.nil? && @service.after_invoked.nil? && @service.only_invoked.nil? && @service.invocation_result.nil?)
102
+ perform_invocation(:add, 20, 50)
103
+ assert(@service.before_invoked == :add)
104
+ assert(@service.after_invoked == :add)
105
+ assert(@service.invocation_result == 70)
106
+ end
107
+
108
+ def test_interception_canceling
109
+ reason = nil
110
+ perform_invocation(:fail_with_reason){|r| reason = r}
111
+ assert(@service.before_invoked == :fail_with_reason)
112
+ assert(@service.after_invoked.nil?)
113
+ assert(@service.invocation_result.nil?)
114
+ assert(reason == "permission denied")
115
+ reason = true
116
+ @service.before_invoked = @service.after_invoked = @service.invocation_result = nil
117
+ perform_invocation(:fail_generic){|r| reason = r}
118
+ assert(@service.before_invoked == :fail_generic)
119
+ assert(@service.after_invoked.nil?)
120
+ assert(@service.invocation_result.nil?)
121
+ assert(reason == true)
122
+ end
123
+
124
+ def test_interception_except_conditions
125
+ perform_invocation(:no_before)
126
+ assert(@service.before_invoked.nil?)
127
+ assert(@service.after_invoked == :no_before)
128
+ assert(@service.invocation_result == 5)
129
+ @service.before_invoked = @service.after_invoked = @service.invocation_result = nil
130
+ perform_invocation(:no_after)
131
+ assert(@service.before_invoked == :no_after)
132
+ assert(@service.after_invoked.nil?)
133
+ assert(@service.invocation_result.nil?)
134
+ end
135
+
136
+ def test_interception_only_conditions
137
+ assert(@service.only_invoked.nil?)
138
+ perform_invocation(:only_one)
139
+ assert(@service.only_invoked == :only_one)
140
+ @service.only_invoked = nil
141
+ perform_invocation(:only_two)
142
+ assert(@service.only_invoked == :only_two)
143
+ end
144
+
145
+ private
146
+ def perform_invocation(method_name, *args, &block)
147
+ @service.perform_invocation(method_name, args, &block)
148
+ end
149
+ end
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__) + '/abstract_unit'
2
+
3
+
4
+ module Foo
5
+ include ActionWebService::Protocol
6
+
7
+ def self.append_features(base)
8
+ super
9
+ base.register_protocol(BodyOnly, FooMinimalProtocol)
10
+ base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo)
11
+ base.register_protocol(HeaderAndBody, FooMinimalProtocolTwo)
12
+ base.register_protocol(HeaderAndBody, FooFullProtocol)
13
+ end
14
+
15
+ class FooFullProtocol < AbstractProtocol
16
+ def self.create_protocol_request(klass, request)
17
+ protocol = FooFullProtocol.new klass
18
+ ActionWebService::Protocol::ProtocolRequest.new(protocol, '', '', '', '')
19
+ end
20
+ end
21
+
22
+ class FooMinimalProtocol < AbstractProtocol
23
+ def self.create_protocol_request(klass, request)
24
+ protocol = FooMinimalProtocol.new klass
25
+ ActionWebService::Protocol::ProtocolRequest.new(protocol, '', '', '', '')
26
+ end
27
+ end
28
+
29
+ class FooMinimalProtocolTwo < AbstractProtocol
30
+ end
31
+ end
32
+
33
+ class ProtocolRegistry
34
+ include ActionWebService::Protocol::Registry
35
+ include Foo
36
+
37
+ def all_protocols
38
+ header_and_body_protocols + body_only_protocols
39
+ end
40
+
41
+ def protocol_request
42
+ probe_request_protocol(nil)
43
+ end
44
+ end
45
+
46
+
47
+ class TC_ProtocolRegistry < Test::Unit::TestCase
48
+ def test_registration
49
+ registry = ProtocolRegistry.new
50
+ assert(registry.all_protocols.length == 4)
51
+ assert(registry.protocol_request.protocol.is_a?(Foo::FooFullProtocol))
52
+ end
53
+ end