actionwebservice 0.5.0

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