diff options
Diffstat (limited to 'actionwebservice/test/abstract_dispatcher.rb')
-rw-r--r-- | actionwebservice/test/abstract_dispatcher.rb | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/actionwebservice/test/abstract_dispatcher.rb b/actionwebservice/test/abstract_dispatcher.rb new file mode 100644 index 0000000000..b743afce4c --- /dev/null +++ b/actionwebservice/test/abstract_dispatcher.rb @@ -0,0 +1,294 @@ +require File.dirname(__FILE__) + '/abstract_unit' + +module DispatcherTest + class Node < ActiveRecord::Base + def initialize(*args) + super(*args) + @new_record = false + end + + class << self + def name + "Node" + end + + def columns(*args) + [ + ActiveRecord::ConnectionAdapters::Column.new('id', 0, 'int'), + ActiveRecord::ConnectionAdapters::Column.new('name', nil, 'string'), + ActiveRecord::ConnectionAdapters::Column.new('description', nil, 'string'), + ] + end + + def connection + self + end + end + end + + class API < ActionWebService::API::Base + api_method :add, :expects => [:int, :int], :returns => [:int] + api_method :interceptee + api_method :struct_return, :returns => [[Node]] + api_method :void + end + + class DirectAPI < ActionWebService::API::Base + api_method :add, :expects => [{:a=>:int}, {:b=>:int}], :returns => [:int] + api_method :before_filtered + api_method :after_filtered, :returns => [[:int]] + api_method :struct_return, :returns => [[Node]] + api_method :thrower + api_method :void + end + + class Service < ActionWebService::Base + web_service_api API + + before_invocation :do_intercept, :only => [:interceptee] + + attr :added + attr :intercepted + attr :void_called + + def initialize + @void_called = false + end + + def add(a, b) + @added = a + b + end + + def interceptee + @intercepted = false + end + + def struct_return + n1 = Node.new('id' => 1, 'name' => 'node1', 'description' => 'Node 1') + n2 = Node.new('id' => 2, 'name' => 'node2', 'description' => 'Node 2') + [n1, n2] + end + + def void(*args) + @void_called = args + end + + def do_intercept(name, args) + [false, "permission denied"] + end + end + + class AbstractController < ActionController::Base + def generate_wsdl + to_wsdl + end + end + + class DelegatedController < AbstractController + web_service_dispatching_mode :delegated + + web_service(:test_service) { @service ||= Service.new; @service } + end + + class DirectController < AbstractController + web_service_api DirectAPI + web_service_dispatching_mode :direct + + before_filter :alwaysfail, :only => [:before_filtered] + after_filter :alwaysok, :only => [:after_filtered] + + attr :added + attr :before_filter_called + attr :before_filter_target_called + attr :after_filter_called + attr :after_filter_target_called + attr :void_called + + def initialize + @before_filter_called = false + @before_filter_target_called = false + @after_filter_called = false + @after_filter_target_called = false + @void_called = false + end + + def add + @added = @params['a'] + @params['b'] + end + + def before_filtered + @before_filter_target_called = true + end + + def after_filtered + @after_filter_target_called = true + [5, 6, 7] + end + + def thrower + raise "Hi, I'm an exception" + end + + def struct_return + n1 = Node.new('id' => 1, 'name' => 'node1', 'description' => 'Node 1') + n2 = Node.new('id' => 2, 'name' => 'node2', 'description' => 'Node 2') + [n1, n2] + end + + def void + @void_called = @method_params + end + + protected + def alwaysfail + @before_filter_called = true + false + end + + def alwaysok + @after_filter_called = true + end + end +end + +module DispatcherCommonTests + def test_direct_dispatching + assert_equal(70, do_method_call(@direct_controller, 'Add', 20, 50)) + assert_equal(70, @direct_controller.added) + assert(@direct_controller.void_called == false) + case @encoder + when WS::Encoding::SoapRpcEncoding + assert(do_method_call(@direct_controller, 'Void', 3, 4, 5).nil?) + when WS::Encoding::XmlRpcEncoding + assert(do_method_call(@direct_controller, 'Void', 3, 4, 5) == true) + end + assert(@direct_controller.void_called == []) + end + + def test_direct_entrypoint + assert(@direct_controller.respond_to?(:api)) + end + + def test_direct_filtering + assert_equal(false, @direct_controller.before_filter_called) + assert_equal(false, @direct_controller.before_filter_target_called) + do_method_call(@direct_controller, 'BeforeFiltered') + assert_equal(true, @direct_controller.before_filter_called) + assert_equal(false, @direct_controller.before_filter_target_called) + assert_equal(false, @direct_controller.after_filter_called) + assert_equal(false, @direct_controller.after_filter_target_called) + assert_equal([5, 6, 7], do_method_call(@direct_controller, 'AfterFiltered')) + assert_equal(true, @direct_controller.after_filter_called) + assert_equal(true, @direct_controller.after_filter_target_called) + end + + def test_delegated_dispatching + assert_equal(130, do_method_call(@delegated_controller, 'Add', 50, 80)) + service = @delegated_controller.web_service_object(:test_service) + assert_equal(130, service.added) + @delegated_controller.web_service_exception_reporting = true + assert(service.intercepted.nil?) + result = do_method_call(@delegated_controller, 'Interceptee') + assert(service.intercepted.nil?) + assert(is_exception?(result)) + assert_match(/permission denied/, exception_message(result)) + result = do_method_call(@delegated_controller, 'NonExistentMethod') + assert(is_exception?(result)) + assert_match(/NonExistentMethod/, exception_message(result)) + assert(service.void_called == false) + case @encoder + when WS::Encoding::SoapRpcEncoding + assert(do_method_call(@delegated_controller, 'Void', 3, 4, 5).nil?) + when WS::Encoding::XmlRpcEncoding + assert(do_method_call(@delegated_controller, 'Void', 3, 4, 5) == true) + end + assert(service.void_called == []) + end + + def test_garbage_request + [@direct_controller, @delegated_controller].each do |controller| + controller.class.web_service_exception_reporting = true + send_garbage_request = lambda do + request = create_ap_request(controller, 'invalid request body', 'xxx') + response = ActionController::TestResponse.new + controller.process(request, response) + # puts response.body + assert(response.headers['Status'] =~ /^500/) + end + send_garbage_request.call + controller.class.web_service_exception_reporting = false + send_garbage_request.call + end + end + + def test_exception_marshaling + @direct_controller.web_service_exception_reporting = true + result = do_method_call(@direct_controller, 'Thrower') + assert(is_exception?(result)) + assert_equal("Hi, I'm an exception", exception_message(result)) + @direct_controller.web_service_exception_reporting = false + result = do_method_call(@direct_controller, 'Thrower') + assert(exception_message(result) != "Hi, I'm an exception") + end + + def test_ar_struct_return + [@direct_controller, @delegated_controller].each do |controller| + result = do_method_call(controller, 'StructReturn') + case @encoder + when WS::Encoding::SoapRpcEncoding + assert(result[0].is_a?(DispatcherTest::Node)) + assert(result[1].is_a?(DispatcherTest::Node)) + assert_equal('node1', result[0].name) + assert_equal('node2', result[1].name) + when WS::Encoding::XmlRpcEncoding + assert(result[0].is_a?(Hash)) + assert(result[1].is_a?(Hash)) + assert_equal('node1', result[0]['name']) + assert_equal('node2', result[1]['name']) + end + end + end + + protected + def service_name(container) + raise NotImplementedError + end + + def exception_message(obj) + raise NotImplementedError + end + + def is_exception?(obj) + raise NotImplementedError + end + + def do_method_call(container, public_method_name, *params) + mode = container.web_service_dispatching_mode + case mode + when :direct + api = container.class.web_service_api + when :delegated + api = container.web_service_object(service_name(container)).class.web_service_api + end + method_name = api.api_method_name(public_method_name) + info = api.api_methods[method_name] || {} + params = params.dup + ((info[:expects] || []) + (info[:returns] || [])).each do |spec| + @marshaler.register_type(spec) + end + expects = info[:expects] + (0..(params.length-1)).each do |i| + type_binding = @marshaler.register_type(expects ? expects[i] : params[i].class) + info = WS::ParamInfo.create(expects ? expects[i] : params[i].class, i, type_binding) + params[i] = @marshaler.marshal(WS::Param.new(params[i], info)) + end + body = @encoder.encode_rpc_call(public_method_name, params) + # puts body + ap_request = create_ap_request(container, body, public_method_name, *params) + ap_response = ActionController::TestResponse.new + container.process(ap_request, ap_response) + # puts ap_response.body + public_method_name, return_value = @encoder.decode_rpc_response(ap_response.body) + @marshaler.unmarshal(return_value).value + end +end |