Permalink
Browse files

first pass of web service scaffolding. add ability to quickly generat…

…e an

action pack request for a protocol, add missing log_error when we fail to parse
protocol messages. add RDoc for scaffolding and functional testing.


git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1037 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
1 parent 715715a commit b94bd32f3116b469b48400382dbc964bf17994d1 @bitserf bitserf committed Mar 29, 2005
@@ -1,7 +1,11 @@
*0.7.0* (Unreleased)
+* Add scaffolding via ActionController::Base.web_service_scaffold for quick testing using a web browser
+
* Generalize casting code to be used by both SOAP and XML-RPC (previously, it was only XML-RPC)
+* Include backtraces in 500 error responses for failed request parsing, and remove "rescue nil" statements obscuring real errors for XML-RPC
+
*0.6.2* (27th March, 2005)
@@ -197,6 +197,51 @@ For this example, a remote call for a method with a name like
method on the <tt>:mt</tt> service.
+== Testing your APIs
+
+
+=== Functional testing
+
+You can perform testing of your APIs by creating a functional test for the
+controller dispatching the API, and calling #invoke in the test case to
+perform the invocation.
+
+Example:
+
+ class PersonApiControllerTest < Test::Unit::TestCase
+ def setup
+ @controller = PersonController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ end
+
+ def test_add
+ result = invoke :remove, 1
+ assert_equal true, result
+ end
+ end
+
+This example invokes the API method <tt>test</tt>, defined on
+the PersonController, and returns the result.
+
+
+=== Scaffolding
+
+You can also test your APIs with a web browser by attaching scaffolding
+to the controller.
+
+Example:
+
+ class PersonController
+ web_service_scaffold :invocation
+ end
+
+This creates an action named <tt>invocation</tt> on the PersonController.
+
+Navigating to this action lets you select the method to invoke, supply the parameters,
+and view the result of the invocation.
+
+
== Using the client support
Action Web Service includes client classes that can use the same API
@@ -1,6 +1,10 @@
= 0.7.0
- WS Dynamic Scaffolding
- - WS Scaffolding Generators
+ * add protocol selection ability
+ * test with XML-RPC (namespaced method name support)
+ * support structured types as input parameters with the input field helper
+
+ - update manual for scaffolding and functional testing
= 0.8.0
- Consumption of WSDL services
@@ -46,6 +46,7 @@
require 'action_web_service/protocol'
require 'action_web_service/struct'
require 'action_web_service/dispatcher'
+require 'action_web_service/scaffolding'
ActionWebService::Base.class_eval do
include ActionWebService::Container::Direct
@@ -61,4 +62,5 @@
include ActionWebService::Container::ActionController
include ActionWebService::Dispatcher
include ActionWebService::Dispatcher::ActionController
+ include ActionWebService::Scaffolding
end
@@ -284,10 +284,31 @@ def cast_returns(marshaler, return_value)
marshaler.cast_inbound_recursive(return_value, @returns[0])
end
+ # String representation of this method
+ def to_s
+ fqn = ""
+ fqn << (@returns ? (friendly_param(@returns[0], nil) + " ") : "void ")
+ fqn << "#{@public_name}("
+ if @expects
+ i = 0
+ fqn << @expects.map{ |p| friendly_param(p, i+= 1) }.join(", ")
+ end
+ fqn << ")"
+ fqn
+ end
+
private
def response_name(encoder)
encoder.is_a?(WS::Encoding::SoapRpcEncoding) ? (@public_name + "Response") : @public_name
end
+
+ def friendly_param(spec, i)
+ name = param_name(spec, i)
+ type = param_type(spec)
+ spec = spec.values.first if spec.is_a?(Hash)
+ type = spec.is_a?(Array) ? (type.to_s + "[]") : type.to_s
+ i ? (type + " " + name) : type
+ end
end
end
end
@@ -63,6 +63,7 @@ def dispatch_web_service_request
end
else
exception ||= DispatcherError.new("Malformed SOAP or XML-RPC protocol message")
+ log_error(exception) unless logger.nil?
send_web_service_error_response(request, exception)
end
rescue Exception => e
@@ -7,10 +7,64 @@ class AbstractProtocol
attr :marshaler
attr :encoder
+ def unmarshal_request(ap_request)
+ end
+
def marshal_response(method, return_value)
body = method.encode_rpc_response(marshaler, encoder, return_value)
Response.new(body, 'text/xml')
end
+
+ def protocol_client(api, protocol_name, endpoint_uri, options)
+ end
+
+ def create_action_pack_request(service_name, public_method_name, raw_body, options={})
+ klass = options[:request_class] || SimpleActionPackRequest
+ request = klass.new
+ request.request_parameters['action'] = service_name.to_s
+ request.env['RAW_POST_DATA'] = raw_body
+ request.env['REQUEST_METHOD'] = 'POST'
+ request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
+ request
+ end
+ end
+
+ class SimpleActionPackRequest < ActionController::AbstractRequest
+ def initialize
+ @env = {}
+ @qparams = {}
+ @rparams = {}
+ @cookies = {}
+ reset_session
+ end
+
+ def query_parameters
+ @qparams
+ end
+
+ def request_parameters
+ @rparams
+ end
+
+ def env
+ @env
+ end
+
+ def host
+ ''
+ end
+
+ def cookies
+ @cookies
+ end
+
+ def session
+ @session
+ end
+
+ def reset_session
+ @session = {}
+ end
end
class Request # :nodoc:
@@ -20,11 +20,17 @@ def unmarshal_request(ap_request)
Request.new(self, method_name, params, service_name)
end
- def protocol_client(api, protocol_name, endpoint_uri, options)
+ def protocol_client(api, protocol_name, endpoint_uri, options={})
return nil unless protocol_name == :soap
ActionWebService::Client::Soap.new(api, endpoint_uri, options)
end
+ def create_action_pack_request(service_name, public_method_name, raw_body, options={})
+ request = super
+ request.env['HTTP_SOAPACTION'] = '/soap/%s/%s' % [service_name, public_method_name]
+ request
+ end
+
private
def has_valid_soap_action?(request)
return nil unless request.method == :post
@@ -18,7 +18,7 @@ def unmarshal_request(ap_request)
Request.new(self, method_name, params, service_name)
end
- def protocol_client(api, protocol_name, endpoint_uri, options)
+ def protocol_client(api, protocol_name, endpoint_uri, options={})
return nil unless protocol_name == :xmlrpc
ActionWebService::Client::XmlRpc.new(api, endpoint_uri, options)
end
Oops, something went wrong. Retry.

0 comments on commit b94bd32

Please sign in to comment.