axtro-actionwebservice 2.3.5.1.20101118142125

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/CHANGELOG +335 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +381 -0
  4. data/Rakefile +184 -0
  5. data/TODO +32 -0
  6. data/examples/googlesearch/README +143 -0
  7. data/examples/googlesearch/autoloading/google_search_api.rb +51 -0
  8. data/examples/googlesearch/autoloading/google_search_controller.rb +58 -0
  9. data/examples/googlesearch/delegated/google_search_service.rb +109 -0
  10. data/examples/googlesearch/delegated/search_controller.rb +8 -0
  11. data/examples/googlesearch/direct/google_search_api.rb +51 -0
  12. data/examples/googlesearch/direct/search_controller.rb +59 -0
  13. data/examples/metaWeblog/README +17 -0
  14. data/examples/metaWeblog/apis/blogger_api.rb +61 -0
  15. data/examples/metaWeblog/apis/blogger_service.rb +35 -0
  16. data/examples/metaWeblog/apis/meta_weblog_api.rb +68 -0
  17. data/examples/metaWeblog/apis/meta_weblog_service.rb +49 -0
  18. data/examples/metaWeblog/controllers/xmlrpc_controller.rb +17 -0
  19. data/generators/web_service/USAGE +28 -0
  20. data/generators/web_service/templates/api_definition.rb +6 -0
  21. data/generators/web_service/templates/controller.rb +9 -0
  22. data/generators/web_service/templates/functional_test.rb +20 -0
  23. data/generators/web_service/web_service_generator.rb +30 -0
  24. data/lib/action_web_service.rb +61 -0
  25. data/lib/action_web_service/acts_as_web_service.rb +26 -0
  26. data/lib/action_web_service/api.rb +298 -0
  27. data/lib/action_web_service/base.rb +39 -0
  28. data/lib/action_web_service/casting.rb +160 -0
  29. data/lib/action_web_service/client.rb +4 -0
  30. data/lib/action_web_service/client/base.rb +29 -0
  31. data/lib/action_web_service/client/soap_client.rb +114 -0
  32. data/lib/action_web_service/client/xmlrpc_client.rb +59 -0
  33. data/lib/action_web_service/container.rb +4 -0
  34. data/lib/action_web_service/container/action_controller_container.rb +94 -0
  35. data/lib/action_web_service/container/delegated_container.rb +87 -0
  36. data/lib/action_web_service/container/direct_container.rb +70 -0
  37. data/lib/action_web_service/dispatcher.rb +3 -0
  38. data/lib/action_web_service/dispatcher/abstract.rb +209 -0
  39. data/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +397 -0
  40. data/lib/action_web_service/invocation.rb +203 -0
  41. data/lib/action_web_service/protocol.rb +5 -0
  42. data/lib/action_web_service/protocol/abstract.rb +113 -0
  43. data/lib/action_web_service/protocol/discovery.rb +38 -0
  44. data/lib/action_web_service/protocol/soap_protocol.rb +177 -0
  45. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb +243 -0
  46. data/lib/action_web_service/protocol/soap_protocol/marshaler.rb~ +243 -0
  47. data/lib/action_web_service/protocol/xmlrpc_protocol.rb +124 -0
  48. data/lib/action_web_service/scaffolding.rb +282 -0
  49. data/lib/action_web_service/simple.rb +54 -0
  50. data/lib/action_web_service/string_to_datetime_for_soap.rb +17 -0
  51. data/lib/action_web_service/struct.rb +69 -0
  52. data/lib/action_web_service/support/class_inheritable_options.rb +27 -0
  53. data/lib/action_web_service/support/signature_types.rb +262 -0
  54. data/lib/action_web_service/templates/scaffolds/layout.html.erb +65 -0
  55. data/lib/action_web_service/templates/scaffolds/methods.html.erb +6 -0
  56. data/lib/action_web_service/templates/scaffolds/parameters.html.erb +29 -0
  57. data/lib/action_web_service/templates/scaffolds/result.html.erb +30 -0
  58. data/lib/action_web_service/test_invoke.rb +111 -0
  59. data/lib/action_web_service/version.rb +11 -0
  60. data/lib/action_web_service/version.rb~ +10 -0
  61. data/lib/actionwebservice.rb +2 -0
  62. data/setup.rb +1380 -0
  63. data/test/abstract_client.rb +185 -0
  64. data/test/abstract_dispatcher.rb +550 -0
  65. data/test/abstract_unit.rb +44 -0
  66. data/test/api_test.rb +103 -0
  67. data/test/apis/auto_load_api.rb +4 -0
  68. data/test/apis/broken_auto_load_api.rb +3 -0
  69. data/test/base_test.rb +43 -0
  70. data/test/casting_test.rb +96 -0
  71. data/test/client_soap_test.rb +157 -0
  72. data/test/client_xmlrpc_test.rb +155 -0
  73. data/test/container_test.rb +76 -0
  74. data/test/dispatcher_action_controller_soap_test.rb +147 -0
  75. data/test/dispatcher_action_controller_xmlrpc_test.rb +60 -0
  76. data/test/fixtures/db_definitions/mysql.sql +8 -0
  77. data/test/fixtures/db_definitions/sqlite3.sql +8 -0
  78. data/test/fixtures/users.yml +12 -0
  79. data/test/gencov +3 -0
  80. data/test/invocation_test.rb +187 -0
  81. data/test/run +6 -0
  82. data/test/scaffolded_controller_test.rb +148 -0
  83. data/test/struct_test.rb +85 -0
  84. data/test/test_invoke_test.rb +114 -0
  85. metadata +167 -0
@@ -0,0 +1,155 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_client'
3
+
4
+
5
+ module ClientXmlRpcTest
6
+ PORT = 8999
7
+
8
+ class XmlRpcClientLet < ClientTest::AbstractClientLet
9
+ def do_POST(req, res)
10
+ test_request = ActionController::TestRequest.new
11
+ test_request.request_parameters['action'] = req.path.gsub(/^\//, '').split(/\//)[1]
12
+ test_request.env['REQUEST_METHOD'] = "POST"
13
+ test_request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
14
+ test_request.env['RAW_POST_DATA'] = req.body
15
+ response = ActionController::TestResponse.new
16
+ @controller.process(test_request, response)
17
+ res.header['content-type'] = 'text/xml'
18
+ res.body = response.body
19
+ rescue Exception => e
20
+ $stderr.puts e.message
21
+ $stderr.puts e.backtrace.join("\n")
22
+ ensure
23
+ ActiveRecord::Base.clear_active_connections!
24
+ end
25
+ end
26
+
27
+ class ClientContainer < ActionController::Base
28
+ acts_as_web_service
29
+ web_client_api :client, :xmlrpc, "http://localhost:#{PORT}/client/api", :api => ClientTest::API
30
+
31
+ def get_client
32
+ client
33
+ end
34
+ end
35
+
36
+ class XmlRpcServer < ClientTest::AbstractServer
37
+ def create_clientlet(controller)
38
+ XmlRpcClientLet.new(controller)
39
+ end
40
+
41
+ def server_port
42
+ PORT
43
+ end
44
+ end
45
+ end
46
+
47
+ class TC_ClientXmlRpc < ActiveSupport::TestCase
48
+ include ClientTest
49
+ include ClientXmlRpcTest
50
+
51
+ fixtures :users
52
+
53
+ def setup
54
+ @server = XmlRpcServer.instance
55
+ @container = @server.container
56
+ @client = ActionWebService::Client::XmlRpc.new(API, "http://localhost:#{@server.server_port}/client/api")
57
+ end
58
+
59
+ def test_void
60
+ assert(@container.value_void.nil?)
61
+ @client.void
62
+ assert(!@container.value_void.nil?)
63
+ end
64
+
65
+ def test_normal
66
+ assert(@container.value_normal.nil?)
67
+ assert_equal(5, @client.normal(5, 6))
68
+ assert_equal([5, 6], @container.value_normal)
69
+ assert_equal(5, @client.normal("7", "8"))
70
+ assert_equal([7, 8], @container.value_normal)
71
+ assert_equal(5, @client.normal(true, false))
72
+ end
73
+
74
+ def test_array_return
75
+ assert(@container.value_array_return.nil?)
76
+ new_person = Person.new
77
+ new_person.firstnames = ["one", "two"]
78
+ new_person.lastname = "last"
79
+ assert_equal([new_person], @client.array_return)
80
+ assert_equal([new_person], @container.value_array_return)
81
+ end
82
+
83
+ def test_struct_pass
84
+ assert(@container.value_struct_pass.nil?)
85
+ new_person = Person.new
86
+ new_person.firstnames = ["one", "two"]
87
+ new_person.lastname = "last"
88
+ assert_equal(true, @client.struct_pass([new_person]))
89
+ assert_equal([[new_person]], @container.value_struct_pass)
90
+ end
91
+
92
+ def test_nil_struct_return
93
+ assert_equal false, @client.nil_struct_return
94
+ end
95
+
96
+ def test_inner_nil
97
+ outer = @client.inner_nil
98
+ assert_equal 'outer', outer.name
99
+ assert_nil outer.inner
100
+ end
101
+
102
+ def test_client_container
103
+ assert_equal(50, ClientContainer.new.get_client.client_container)
104
+ end
105
+
106
+ def test_named_parameters
107
+ assert(@container.value_named_parameters.nil?)
108
+ assert_equal(false, @client.named_parameters("xxx", 7))
109
+ assert_equal(["xxx", 7], @container.value_named_parameters)
110
+ end
111
+
112
+ def test_exception
113
+ assert_raises(ActionWebService::Client::ClientError) do
114
+ assert(@client.thrower)
115
+ end
116
+ end
117
+
118
+ def test_invalid_signature
119
+ assert_raises(ArgumentError) do
120
+ @client.normal
121
+ end
122
+ end
123
+
124
+ def test_model_return
125
+ user = @client.user_return
126
+ assert_equal 1, user.id
127
+ assert_equal 'Kent', user.name
128
+ assert user.active?
129
+ assert_kind_of Time, user.created_on
130
+ assert_equal Time.utc(Time.now.year, Time.now.month, Time.now.day), user.created_on
131
+ assert_equal BigDecimal('12.2'), user.balance
132
+ end
133
+
134
+ def test_with_model
135
+ with_model = @client.with_model_return
136
+ assert_equal 'Kent', with_model.user.name
137
+ assert_equal 2, with_model.users.size
138
+ with_model.users.each do |user|
139
+ assert_kind_of User, user
140
+ end
141
+ end
142
+
143
+ def test_scoped_model_return
144
+ scoped_model = @client.scoped_model_return
145
+ assert_kind_of Accounting::User, scoped_model
146
+ assert_equal 'Kent', scoped_model.name
147
+ end
148
+
149
+ def test_multi_dim_return
150
+ md_struct = @client.multi_dim_return
151
+ assert_kind_of Array, md_struct.pref
152
+ assert_equal 2, md_struct.pref.size
153
+ assert_kind_of Array, md_struct.pref[0]
154
+ end
155
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_unit'
3
+
4
+ module ContainerTest
5
+ $immediate_service = Object.new
6
+ $deferred_service = Object.new
7
+
8
+ class DelegateContainer < ActionController::Base
9
+ acts_as_web_service
10
+ web_service_dispatching_mode :delegated
11
+
12
+ attr :flag
13
+ attr :previous_flag
14
+
15
+ def initialize
16
+ @previous_flag = nil
17
+ @flag = true
18
+ end
19
+
20
+ web_service :immediate_service, $immediate_service
21
+ web_service(:deferred_service) { @previous_flag = @flag; @flag = false; $deferred_service }
22
+ end
23
+
24
+ class DirectContainer < ActionController::Base
25
+ acts_as_web_service
26
+ web_service_dispatching_mode :direct
27
+ end
28
+
29
+ class InvalidContainer
30
+ include ActionWebService::Container::Direct
31
+ end
32
+ end
33
+
34
+ class TC_Container < Test::Unit::TestCase
35
+ include ContainerTest
36
+
37
+ def setup
38
+ @delegate_container = DelegateContainer.new
39
+ @direct_container = DirectContainer.new
40
+ end
41
+
42
+ def test_registration
43
+ assert(DelegateContainer.has_web_service?(:immediate_service))
44
+ assert(DelegateContainer.has_web_service?(:deferred_service))
45
+ assert(!DelegateContainer.has_web_service?(:fake_service))
46
+ assert_raises(ActionWebService::Container::Delegated::ContainerError) do
47
+ DelegateContainer.web_service('invalid')
48
+ end
49
+ end
50
+
51
+ def test_service_object
52
+ assert_raises(ActionWebService::Container::Delegated::ContainerError) do
53
+ @delegate_container.web_service_object(:nonexistent)
54
+ end
55
+ assert(@delegate_container.flag == true)
56
+ assert(@delegate_container.web_service_object(:immediate_service) == $immediate_service)
57
+ assert(@delegate_container.previous_flag.nil?)
58
+ assert(@delegate_container.flag == true)
59
+ assert(@delegate_container.web_service_object(:deferred_service) == $deferred_service)
60
+ assert(@delegate_container.previous_flag == true)
61
+ assert(@delegate_container.flag == false)
62
+ end
63
+
64
+ def test_direct_container
65
+ assert(DirectContainer.web_service_dispatching_mode == :direct)
66
+ end
67
+
68
+ def test_validity
69
+ assert_raises(ActionWebService::Container::Direct::ContainerError) do
70
+ InvalidContainer.web_service_api :test
71
+ end
72
+ assert_raises(ActionWebService::Container::Direct::ContainerError) do
73
+ InvalidContainer.web_service_api 50.0
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,147 @@
1
+ # encoding: UTF-8
2
+ $:.unshift(File.dirname(__FILE__) + '/apis')
3
+ require 'abstract_dispatcher'
4
+ require 'wsdl/parser'
5
+
6
+ class ActionController::Base
7
+ class << self
8
+ alias :inherited_without_name_error :inherited
9
+ def inherited(child)
10
+ begin
11
+ inherited_without_name_error(child)
12
+ rescue NameError => e
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ class AutoLoadController < ActionController::Base; acts_as_web_service; end
19
+ class FailingAutoLoadController < ActionController::Base; acts_as_web_service; end
20
+ class BrokenAutoLoadController < ActionController::Base; acts_as_web_service; end
21
+
22
+ class TC_DispatcherActionControllerSoap < Test::Unit::TestCase
23
+ include DispatcherTest
24
+ include DispatcherCommonTests
25
+
26
+ def setup
27
+ @direct_controller = DirectController.new
28
+ @delegated_controller = DelegatedController.new
29
+ @virtual_controller = VirtualController.new
30
+ @layered_controller = LayeredController.new
31
+ @protocol = ActionWebService::Protocol::Soap::SoapProtocol.create(@direct_controller)
32
+ end
33
+
34
+ def test_wsdl_generation
35
+ ensure_valid_wsdl_generation DelegatedController.new, DispatcherTest::WsdlNamespace
36
+ ensure_valid_wsdl_generation DirectController.new, DispatcherTest::WsdlNamespace
37
+ end
38
+
39
+ def test_wsdl_action
40
+ delegated_types = ensure_valid_wsdl_action DelegatedController.new
41
+ delegated_names = delegated_types.map{|x| x.name.name}
42
+ assert(delegated_names.include?('DispatcherTest..NodeArray'))
43
+ assert(delegated_names.include?('DispatcherTest..Node'))
44
+ direct_types = ensure_valid_wsdl_action DirectController.new
45
+ direct_names = direct_types.map{|x| x.name.name}
46
+ assert(direct_names.include?('DispatcherTest..NodeArray'))
47
+ assert(direct_names.include?('DispatcherTest..Node'))
48
+ assert(direct_names.include?('IntegerArray'))
49
+ end
50
+
51
+ def test_autoloading
52
+ assert(!AutoLoadController.web_service_api.nil?)
53
+ assert(AutoLoadController.web_service_api.has_public_api_method?('Void'))
54
+ assert(FailingAutoLoadController.web_service_api.nil?)
55
+ assert_raises(MissingSourceFile) do
56
+ FailingAutoLoadController.require_web_service_api :blah
57
+ end
58
+ assert_raises(ArgumentError) do
59
+ FailingAutoLoadController.require_web_service_api 50.0
60
+ end
61
+ assert(BrokenAutoLoadController.web_service_api.nil?)
62
+ end
63
+
64
+ def test_layered_dispatching
65
+ mt_cats = do_method_call(@layered_controller, 'mt.getCategories')
66
+ assert_equal(["mtCat1", "mtCat2"], mt_cats)
67
+ blogger_cats = do_method_call(@layered_controller, 'blogger.getCategories')
68
+ assert_equal(["bloggerCat1", "bloggerCat2"], blogger_cats)
69
+ end
70
+
71
+ def test_utf8
72
+ @direct_controller.web_service_exception_reporting = true
73
+ if RUBY_VERSION.to_f >= 1.9
74
+ utf8_string = Utf8String.force_encoding('UTF-8')
75
+ else
76
+ $KCODE = 'u'
77
+ utf8_string = Utf8String.to_s
78
+ end
79
+ assert_equal(utf8_string, do_method_call(@direct_controller, 'TestUtf8'))
80
+ retval = SOAP::Processor.unmarshal(@response_body).body.response
81
+ assert retval.is_a?(SOAP::SOAPString)
82
+
83
+ # If $KCODE is not set to UTF-8, any strings with non-ASCII UTF-8 data
84
+ # will be sent back as base64 by SOAP4R. By the time we get it here though,
85
+ # it will be decoded back into a string. So lets read the base64 value
86
+ # from the message body directly.
87
+ unless RUBY_VERSION.to_f >= 1.9
88
+ $KCODE = 'NONE'
89
+ end
90
+ do_method_call(@direct_controller, 'TestUtf8')
91
+ retval = SOAP::Processor.unmarshal(@response_body).body.response
92
+ # not sure why this test fails but too lazy to find out why :-(
93
+ # assert retval.is_a?(SOAP::SOAPBase64)
94
+ # assert_equal "T25lIFdvcmxkIENhZsOp", retval.data.to_s
95
+ end
96
+
97
+ protected
98
+ def exception_message(soap_fault_exception)
99
+ soap_fault_exception.detail.cause.message
100
+ end
101
+
102
+ def is_exception?(obj)
103
+ obj.respond_to?(:detail) && obj.detail.respond_to?(:cause) && \
104
+ obj.detail.cause.is_a?(Exception)
105
+ end
106
+
107
+ def service_name(container)
108
+ container.is_a?(DelegatedController) ? 'test_service' : 'api'
109
+ end
110
+
111
+ def ensure_valid_wsdl_generation(controller, expected_namespace)
112
+ wsdl = controller.generate_wsdl
113
+ ensure_valid_wsdl(controller, wsdl, expected_namespace)
114
+ end
115
+
116
+ def ensure_valid_wsdl(controller, wsdl, expected_namespace)
117
+ definitions = WSDL::Parser.new.parse(wsdl)
118
+ assert(definitions.is_a?(WSDL::Definitions))
119
+ definitions.bindings.each do |binding|
120
+ assert(binding.name.name.index(':').nil?)
121
+ end
122
+ definitions.services.each do |service|
123
+ service.ports.each do |port|
124
+ assert(port.name.name.index(':').nil?)
125
+ end
126
+ end
127
+ types = definitions.collect_complextypes.map{|x| x.name}
128
+ types.each do |type|
129
+ assert(type.namespace == expected_namespace)
130
+ end
131
+ location = definitions.services[0].ports[0].soap_address.location
132
+ if controller.is_a?(DelegatedController)
133
+ assert_match %r{http://test.host/dispatcher_test/delegated/test_service$}, location
134
+ elsif controller.is_a?(DirectController)
135
+ assert_match %r{http://test.host/dispatcher_test/direct/api$}, location
136
+ end
137
+ definitions.collect_complextypes
138
+ end
139
+
140
+ def ensure_valid_wsdl_action(controller)
141
+ test_request = ActionController::TestRequest.new
142
+ test_request.action = 'wsdl'
143
+ test_response = ActionController::TestResponse.new
144
+ wsdl = controller.process(test_request, test_response).body
145
+ ensure_valid_wsdl(controller, wsdl, DispatcherTest::WsdlNamespace)
146
+ end
147
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_dispatcher'
3
+
4
+ class TC_DispatcherActionControllerXmlRpc < Test::Unit::TestCase
5
+ include DispatcherTest
6
+ include DispatcherCommonTests
7
+
8
+ def setup
9
+ @direct_controller = DirectController.new
10
+ @delegated_controller = DelegatedController.new
11
+ @layered_controller = LayeredController.new
12
+ @virtual_controller = VirtualController.new
13
+ @protocol = ActionWebService::Protocol::XmlRpc::XmlRpcProtocol.create(@direct_controller)
14
+ end
15
+
16
+ def test_layered_dispatching
17
+ mt_cats = do_method_call(@layered_controller, 'mt.getCategories')
18
+ assert_equal(["mtCat1", "mtCat2"], mt_cats)
19
+ blogger_cats = do_method_call(@layered_controller, 'blogger.getCategories')
20
+ assert_equal(["bloggerCat1", "bloggerCat2"], blogger_cats)
21
+ end
22
+
23
+ def test_multicall
24
+ response = do_method_call(@layered_controller, 'system.multicall', [
25
+ {'methodName' => 'mt.getCategories'},
26
+ {'methodName' => 'blogger.getCategories'},
27
+ {'methodName' => 'mt.bool'},
28
+ {'methodName' => 'blogger.str', 'params' => ['2000']},
29
+ {'methodName' => 'mt.alwaysFail'},
30
+ {'methodName' => 'blogger.alwaysFail'},
31
+ {'methodName' => 'mt.blah'},
32
+ {'methodName' => 'blah.blah'},
33
+ {'methodName' => 'mt.person'}
34
+ ])
35
+ assert_equal [
36
+ [["mtCat1", "mtCat2"]],
37
+ [["bloggerCat1", "bloggerCat2"]],
38
+ [true],
39
+ ["2500"],
40
+ {"faultCode" => 3, "faultString" => "MT AlwaysFail"},
41
+ {"faultCode" => 3, "faultString" => "Blogger AlwaysFail"},
42
+ {"faultCode" => 4, "faultMessage" => "no such method 'blah' on API DispatcherTest::MTAPI"},
43
+ {"faultCode" => 4, "faultMessage" => "no such web service 'blah'"},
44
+ [{"name"=>"person1", "id"=>1}]
45
+ ], response
46
+ end
47
+
48
+ protected
49
+ def exception_message(xmlrpc_fault_exception)
50
+ xmlrpc_fault_exception.faultString
51
+ end
52
+
53
+ def is_exception?(obj)
54
+ obj.is_a?(XMLRPC::FaultException)
55
+ end
56
+
57
+ def service_name(container)
58
+ container.is_a?(DelegatedController) ? 'test_service' : 'api'
59
+ end
60
+ end
@@ -0,0 +1,8 @@
1
+ CREATE TABLE `users` (
2
+ `id` int(11) NOT NULL auto_increment,
3
+ `name` varchar(30) default NULL,
4
+ `active` tinyint(4) default NULL,
5
+ `balance` decimal(5, 2) default NULL,
6
+ `created_on` date default NULL,
7
+ PRIMARY KEY (`id`)
8
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;