From d43392a50b4f7023b13747a67c4a6aa85e4036c4 Mon Sep 17 00:00:00 2001 From: Leon Breedt Date: Fri, 4 Mar 2005 10:07:53 +0000 Subject: 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 --- .../lib/action_web_service/test_invoke.rb | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 actionwebservice/lib/action_web_service/test_invoke.rb (limited to 'actionwebservice/lib/action_web_service/test_invoke.rb') 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 -- cgit v1.2.3