aboutsummaryrefslogtreecommitdiffstats
path: root/actionwebservice/lib/action_web_service/test_invoke.rb
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-03-04 10:07:53 +0000
committerLeon Breedt <bitserf@gmail.com>2005-03-04 10:07:53 +0000
commitd43392a50b4f7023b13747a67c4a6aa85e4036c4 (patch)
tree66203f6fceae6c4d7489a10664fddc9afd9d53be /actionwebservice/lib/action_web_service/test_invoke.rb
parentb78283b3fcae6752e7f1698cc063eff6214d2104 (diff)
downloadrails-d43392a50b4f7023b13747a67c4a6aa85e4036c4.tar.gz
rails-d43392a50b4f7023b13747a67c4a6aa85e4036c4.tar.bz2
rails-d43392a50b4f7023b13747a67c4a6aa85e4036c4.zip
add action_web_service/test_invoke, will be used by for testing APIs in
a Rails project instance. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@830 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionwebservice/lib/action_web_service/test_invoke.rb')
-rw-r--r--actionwebservice/lib/action_web_service/test_invoke.rb130
1 files changed, 130 insertions, 0 deletions
diff --git a/actionwebservice/lib/action_web_service/test_invoke.rb b/actionwebservice/lib/action_web_service/test_invoke.rb
new file mode 100644
index 0000000000..44601c1c11
--- /dev/null
+++ b/actionwebservice/lib/action_web_service/test_invoke.rb
@@ -0,0 +1,130 @@
+require 'test/unit'
+
+module Test
+ module Unit
+ class TestCase # :nodoc:
+ private
+ # invoke the specified API method
+ def invoke_direct(method_name, *args)
+ prepare_request('api', 'api', method_name, *args)
+ @controller.process(@request, @response)
+ decode_rpc_response
+ end
+ alias_method :invoke, :invoke_direct
+
+ # invoke the specified API method on the specified service
+ def invoke_delegated(service_name, method_name, *args)
+ prepare_request(service_name.to_s, service_name, method_name, *args)
+ @controller.process(@request, @response)
+ decode_rpc_response
+ end
+
+ # invoke the specified layered API method on the correct service
+ def invoke_layered(service_name, method_name, *args)
+ if protocol == :soap
+ raise "SOAP protocol support for :layered dispatching mode is not available"
+ end
+ prepare_request('api', service_name, method_name, *args)
+ @controller.process(@request, @response)
+ decode_rpc_response
+ end
+
+ # ---------------------- internal ---------------------------
+
+ def prepare_request(action, service_name, api_method_name, *args)
+ @request.request_parameters['action'] = action
+ @request.env['REQUEST_METHOD'] = 'POST'
+ @request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
+ @request.env['RAW_POST_DATA'] = encode_rpc_call(service_name, api_method_name, *args)
+ case protocol
+ when :soap
+ soap_action = "/#{@controller.controller_name}/#{service_name}/#{public_method_name(service_name, api_method_name)}"
+ @request.env['HTTP_SOAPACTION'] = soap_action
+ when :xmlrpc
+ @request.env.delete('HTTP_SOAPACTION')
+ end
+ end
+
+ def encode_rpc_call(service_name, api_method_name, *args)
+ case @controller.web_service_dispatching_mode
+ when :direct
+ api = @controller.class.web_service_api
+ when :delegated, :layered
+ api = @controller.web_service_object(service_name.to_sym).class.web_service_api
+ end
+ info = api.api_methods[api_method_name.to_sym]
+ ((info[:expects] || []) + (info[:returns] || [])).each do |spec|
+ marshaler.register_type spec
+ end
+ expects = info[:expects]
+ args = args.dup
+ (0..(args.length-1)).each do |i|
+ type_binding = marshaler.register_type(expects ? expects[i] : args[i].class)
+ info = WS::ParamInfo.create(expects ? expects[i] : args[i].class, type_binding, i)
+ args[i] = marshaler.marshal(WS::Param.new(args[i], info))
+ end
+ encoder.encode_rpc_call(public_method_name(service_name, api_method_name), args)
+ end
+
+ def decode_rpc_response
+ public_method_name, return_value = encoder.decode_rpc_response(@response.body)
+ result = marshaler.unmarshal(return_value).value
+ unless @return_exceptions
+ exception = is_exception?(result)
+ raise exception if exception
+ end
+ result
+ end
+
+ def public_method_name(service_name, api_method_name)
+ public_name = service_api(service_name).public_api_method_name(api_method_name)
+ if @controller.web_service_dispatching_mode == :layered
+ '%s.%s' % [service_name.to_s, public_name]
+ else
+ public_name
+ end
+ end
+
+ def service_api(service_name)
+ case @controller.web_service_dispatching_mode
+ when :direct
+ @controller.class.web_service_api
+ when :delegated, :layered
+ @controller.web_service_object(service_name.to_sym).class.web_service_api
+ end
+ end
+
+ def protocol
+ @protocol ||= :soap
+ end
+
+ def marshaler
+ case protocol
+ when :soap
+ @soap_marshaler ||= WS::Marshaling::SoapMarshaler.new 'urn:ActionWebService'
+ when :xmlrpc
+ @xmlrpc_marshaler ||= WS::Marshaling::XmlRpcMarshaler.new
+ end
+ end
+
+ def encoder
+ case protocol
+ when :soap
+ @soap_encoder ||= WS::Encoding::SoapRpcEncoding.new 'urn:ActionWebService'
+ when :xmlrpc
+ @xmlrpc_encoder ||= WS::Encoding::XmlRpcEncoding.new
+ end
+ end
+
+ def is_exception?(obj)
+ case protocol
+ when :soap
+ (obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \
+ obj.detail.cause.is_a?(Exception)) ? obj.detail.cause : nil
+ when :xmlrpc
+ obj.is_a?(XMLRPC::FaultException) ? obj : nil
+ end
+ end
+ end
+ end
+end