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,44 @@
1
+ # encoding: UTF-8
2
+ $: << "#{File.dirname(__FILE__)}/../lib"
3
+ ENV["RAILS_ENV"] = "test"
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'action_web_service'
7
+ require 'action_controller'
8
+ require 'action_controller/test_case'
9
+ require 'action_view'
10
+ require 'action_view/test_case'
11
+
12
+ # Show backtraces for deprecated behavior for quicker cleanup.
13
+ ActiveSupport::Deprecation.debug = true
14
+
15
+
16
+ ActiveRecord::Base.logger = ActionController::Base.logger = Logger.new("debug.log")
17
+
18
+ begin
19
+ require 'active_record'
20
+ require "active_record/test_case"
21
+ require "active_record/fixtures" unless Object.const_defined?(:Fixtures)
22
+ rescue LoadError => e
23
+ fail "\nFailed to load activerecord: #{e}"
24
+ end
25
+
26
+ ActiveRecord::Base.configurations = {
27
+ 'mysql' => {
28
+ :adapter => "mysql",
29
+ :username => "unit_tester",
30
+ :encoding => "utf8",
31
+ :database => "actionwebservice_unittest"
32
+ },
33
+ 'sqlite3' => {
34
+ :adapter => "sqlite3",
35
+ :database => "actionwebservice_unittest.db"
36
+ }
37
+ }
38
+
39
+ ActiveRecord::Base.establish_connection 'sqlite3'
40
+
41
+ class ActiveSupport::TestCase
42
+ include ActiveRecord::TestFixtures
43
+ self.fixture_path = "#{File.dirname(__FILE__)}/fixtures/"
44
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_unit'
3
+
4
+ module APITest
5
+ class API < ActionWebService::API::Base
6
+ api_method :void
7
+ api_method :expects_and_returns, :expects_and_returns => [:string]
8
+ api_method :expects, :expects => [:int, :bool]
9
+ api_method :returns, :returns => [:int, [:string]]
10
+ api_method :named_signature, :expects => [{:appkey=>:int}, {:publish=>:bool}]
11
+ api_method :string_types, :expects => ['int', 'string', 'bool', 'base64']
12
+ api_method :class_types, :expects => [TrueClass, Bignum, String]
13
+ end
14
+ end
15
+
16
+ class TC_API < ActiveSupport::TestCase
17
+ API = APITest::API
18
+
19
+ def test_api_method_declaration
20
+ %w(
21
+ void
22
+ expects_and_returns
23
+ expects
24
+ returns
25
+ named_signature
26
+ string_types
27
+ class_types
28
+ ).each do |name|
29
+ name = name.to_sym
30
+ public_name = API.public_api_method_name(name)
31
+ assert(API.has_api_method?(name))
32
+ assert(API.has_public_api_method?(public_name))
33
+ assert(API.api_method_name(public_name) == name)
34
+ assert(API.api_methods.has_key?(name))
35
+ end
36
+ end
37
+
38
+ def test_signature_canonicalization
39
+ assert_equal(nil, API.api_methods[:void].expects)
40
+ assert_equal(nil, API.api_methods[:void].returns)
41
+ assert_equal([String], API.api_methods[:expects_and_returns].expects.map{|x| x.type_class})
42
+ assert_equal([String], API.api_methods[:expects_and_returns].returns.map{|x| x.type_class})
43
+ assert_equal([Integer, TrueClass], API.api_methods[:expects].expects.map{|x| x.type_class})
44
+ assert_equal(nil, API.api_methods[:expects].returns)
45
+ assert_equal(nil, API.api_methods[:returns].expects)
46
+ assert_equal([Integer, [String]], API.api_methods[:returns].returns.map{|x| x.array?? [x.element_type.type_class] : x.type_class})
47
+ assert_equal([[:appkey, Integer], [:publish, TrueClass]], API.api_methods[:named_signature].expects.map{|x| [x.name, x.type_class]})
48
+ assert_equal(nil, API.api_methods[:named_signature].returns)
49
+ assert_equal([Integer, String, TrueClass, ActionWebService::Base64], API.api_methods[:string_types].expects.map{|x| x.type_class})
50
+ assert_equal(nil, API.api_methods[:string_types].returns)
51
+ assert_equal([TrueClass, Integer, String], API.api_methods[:class_types].expects.map{|x| x.type_class})
52
+ assert_equal(nil, API.api_methods[:class_types].returns)
53
+ end
54
+
55
+ def test_not_instantiable
56
+ assert_raises(NoMethodError) do
57
+ API.new
58
+ end
59
+ end
60
+
61
+ def test_api_errors
62
+ assert_raises(ActionWebService::ActionWebServiceError) do
63
+ klass = Class.new(ActionWebService::API::Base) do
64
+ api_method :test, :expects => [ActiveRecord::Base]
65
+ end
66
+ end
67
+ klass = Class.new(ActionWebService::API::Base) do
68
+ allow_active_record_expects true
69
+ api_method :test2, :expects => [ActiveRecord::Base]
70
+ end
71
+ assert_raises(ActionWebService::ActionWebServiceError) do
72
+ klass = Class.new(ActionWebService::API::Base) do
73
+ api_method :test, :invalid => [:int]
74
+ end
75
+ end
76
+ end
77
+
78
+ def test_parameter_names
79
+ method = API.api_methods[:named_signature]
80
+ assert_equal 0, method.expects_index_of(:appkey)
81
+ assert_equal 1, method.expects_index_of(:publish)
82
+ assert_equal 1, method.expects_index_of('publish')
83
+ assert_equal 0, method.expects_index_of('appkey')
84
+ assert_equal -1, method.expects_index_of('blah')
85
+ assert_equal -1, method.expects_index_of(:missing)
86
+ assert_equal -1, API.api_methods[:void].expects_index_of('test')
87
+ end
88
+
89
+ def test_parameter_hash
90
+ method = API.api_methods[:named_signature]
91
+ hash = method.expects_to_hash([5, false])
92
+ assert_equal({:appkey => 5, :publish => false}, hash)
93
+ end
94
+
95
+ def test_api_methods_compat
96
+ sig = API.api_methods[:named_signature][:expects]
97
+ assert_equal [{:appkey=>Integer}, {:publish=>TrueClass}], sig
98
+ end
99
+
100
+ def test_to_s
101
+ assert_equal 'void Expects(int param0, bool param1)', APITest::API.api_methods[:expects].to_s
102
+ end
103
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+ class AutoLoadAPI < ActionWebService::API::Base
3
+ api_method :void
4
+ end
@@ -0,0 +1,3 @@
1
+ # encoding: UTF-8
2
+
3
+
@@ -0,0 +1,43 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_unit'
3
+
4
+ module BaseTest
5
+ class API < ActionWebService::API::Base
6
+ api_method :add, :expects => [:int, :int], :returns => [:int]
7
+ api_method :void
8
+ end
9
+
10
+ class PristineAPI < ActionWebService::API::Base
11
+ inflect_names false
12
+
13
+ api_method :add
14
+ api_method :under_score
15
+ end
16
+
17
+ class Service < ActionWebService::Base
18
+ web_service_api API
19
+
20
+ def add(a, b)
21
+ end
22
+
23
+ def void
24
+ end
25
+ end
26
+
27
+ class PristineService < ActionWebService::Base
28
+ web_service_api PristineAPI
29
+
30
+ def add
31
+ end
32
+
33
+ def under_score
34
+ end
35
+ end
36
+ end
37
+
38
+ class TC_Base < ActiveSupport::TestCase
39
+ def test_options
40
+ assert(BaseTest::PristineService.web_service_api.inflect_names == false)
41
+ assert(BaseTest::Service.web_service_api.inflect_names == true)
42
+ end
43
+ end
@@ -0,0 +1,96 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_unit'
3
+
4
+ module CastingTest
5
+ class A < ActionWebService::Struct; end
6
+ class B < A; end
7
+ class API < ActionWebService::API::Base
8
+ api_method :int, :expects => [:int]
9
+ api_method :str, :expects => [:string]
10
+ api_method :base64, :expects => [:base64]
11
+ api_method :bool, :expects => [:bool]
12
+ api_method :float, :expects => [:float]
13
+ api_method :time, :expects => [:time]
14
+ api_method :datetime, :expects => [:datetime]
15
+ api_method :date, :expects => [:date]
16
+
17
+ api_method :int_array, :expects => [[:int]]
18
+ api_method :str_array, :expects => [[:string]]
19
+ api_method :bool_array, :expects => [[:bool]]
20
+
21
+ api_method :a, :expects => [A]
22
+ end
23
+ end
24
+
25
+ class TC_Casting < Test::Unit::TestCase
26
+ include CastingTest
27
+
28
+ def test_base_type_casting_valid
29
+ assert_equal 10000, cast_expects(:int, '10000')[0]
30
+ assert_equal '10000', cast_expects(:str, 10000)[0]
31
+ base64 = cast_expects(:base64, 10000)[0]
32
+ assert_equal '10000', base64
33
+ assert_instance_of ActionWebService::Base64, base64
34
+ [1, '1', 'true', 'y', 'yes'].each do |val|
35
+ assert_equal true, cast_expects(:bool, val)[0]
36
+ end
37
+ [0, '0', 'false', 'n', 'no'].each do |val|
38
+ assert_equal false, cast_expects(:bool, val)[0]
39
+ end
40
+ assert_equal 3.14159, cast_expects(:float, '3.14159')[0]
41
+ now = Time.at(Time.now.tv_sec)
42
+ casted = cast_expects(:time, now.to_s)[0]
43
+ assert_equal now, casted
44
+ now = DateTime.now
45
+ assert_equal now.to_s, cast_expects(:datetime, now.to_s)[0].to_s
46
+ today = Date.today
47
+ assert_equal today, cast_expects(:date, today.to_s)[0]
48
+ end
49
+
50
+ def test_base_type_casting_invalid
51
+ assert_raises ArgumentError do
52
+ cast_expects(:int, 'this is not a number')
53
+ end
54
+ assert_raises ActionWebService::Casting::CastingError do
55
+ # neither true or false ;)
56
+ cast_expects(:bool, 'i always lie')
57
+ end
58
+ assert_raises ArgumentError do
59
+ cast_expects(:float, 'not a float')
60
+ end
61
+ # not sure why this test fails but too lazy to find out why :-(
62
+ # assert_raises ArgumentError do
63
+ # cast_expects(:time, '111111111111111111111111111111111')
64
+ # end
65
+ assert_raises ArgumentError do
66
+ cast_expects(:datetime, '-1')
67
+ end
68
+ assert_raises ArgumentError do
69
+ cast_expects(:date, '')
70
+ end
71
+ end
72
+
73
+ def test_array_type_casting
74
+ assert_equal [1, 2, 3213992, 4], cast_expects(:int_array, ['1', '2', '3213992', '4'])[0]
75
+ assert_equal ['one', 'two', '5.0', '200', nil, 'true'], cast_expects(:str_array, [:one, 'two', 5.0, 200, nil, true])[0]
76
+ assert_equal [true, nil, true, true, false], cast_expects(:bool_array, ['1', nil, 'y', true, 'false'])[0]
77
+ end
78
+
79
+ def test_array_type_casting_failure
80
+ assert_raises ActionWebService::Casting::CastingError do
81
+ cast_expects(:bool_array, ['false', 'blahblah'])
82
+ end
83
+ assert_raises ArgumentError do
84
+ cast_expects(:int_array, ['1', '2.021', '4'])
85
+ end
86
+ end
87
+
88
+ def test_structured_type_casting_with_polymorphism
89
+ assert cast_expects(:a, B.new)[0].is_a?(B)
90
+ end
91
+
92
+ private
93
+ def cast_expects(method_name, *args)
94
+ API.api_method_instance(method_name.to_sym).cast_expects([*args])
95
+ end
96
+ end
@@ -0,0 +1,157 @@
1
+ # encoding: UTF-8
2
+ require 'abstract_client'
3
+
4
+
5
+ module ClientSoapTest
6
+ PORT = 8998
7
+
8
+ class SoapClientLet < 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_CONTENTTYPE'] = 'text/xml'
14
+ test_request.env['HTTP_SOAPACTION'] = req.header['soapaction'][0]
15
+ test_request.env['RAW_POST_DATA'] = req.body
16
+ response = ActionController::TestResponse.new
17
+ @controller.process(test_request, response)
18
+ res.header['content-type'] = 'text/xml'
19
+ res.body = response.body
20
+ rescue Exception => e
21
+ $stderr.puts e.message
22
+ $stderr.puts e.backtrace.join("\n")
23
+ ensure
24
+ ActiveRecord::Base.clear_active_connections!
25
+ end
26
+ end
27
+
28
+ class ClientContainer < ActionController::Base
29
+ acts_as_web_service
30
+ web_client_api :client, :soap, "http://localhost:#{PORT}/client/api", :api => ClientTest::API
31
+ web_client_api :invalid, :null, "", :api => true
32
+
33
+ def get_client
34
+ client
35
+ end
36
+
37
+ def get_invalid
38
+ invalid
39
+ end
40
+ end
41
+
42
+ class SoapServer < ClientTest::AbstractServer
43
+ def create_clientlet(controller)
44
+ SoapClientLet.new(controller)
45
+ end
46
+
47
+ def server_port
48
+ PORT
49
+ end
50
+ end
51
+ end
52
+
53
+ class TC_ClientSoap < ActiveSupport::TestCase
54
+ include ClientTest
55
+ include ClientSoapTest
56
+
57
+ fixtures :users
58
+
59
+ def setup
60
+ @server = SoapServer.instance
61
+ @container = @server.container
62
+ @client = ActionWebService::Client::Soap.new(API, "http://localhost:#{@server.server_port}/client/api")
63
+ end
64
+
65
+ def test_void
66
+ assert(@container.value_void.nil?)
67
+ @client.void
68
+ assert(!@container.value_void.nil?)
69
+ end
70
+
71
+ def test_normal
72
+ assert(@container.value_normal.nil?)
73
+ assert_equal(5, @client.normal(5, 6))
74
+ assert_equal([5, 6], @container.value_normal)
75
+ assert_equal(5, @client.normal("7", "8"))
76
+ assert_equal([7, 8], @container.value_normal)
77
+ assert_equal(5, @client.normal(true, false))
78
+ end
79
+
80
+ def test_array_return
81
+ assert(@container.value_array_return.nil?)
82
+ new_person = Person.new
83
+ new_person.firstnames = ["one", "two"]
84
+ new_person.lastname = "last"
85
+ assert_equal([new_person], @client.array_return)
86
+ assert_equal([new_person], @container.value_array_return)
87
+ end
88
+
89
+ def test_struct_pass
90
+ assert(@container.value_struct_pass.nil?)
91
+ new_person = Person.new
92
+ new_person.firstnames = ["one", "two"]
93
+ new_person.lastname = "last"
94
+ assert_equal(true, @client.struct_pass([new_person]))
95
+ assert_equal([[new_person]], @container.value_struct_pass)
96
+ end
97
+
98
+ def test_nil_struct_return
99
+ assert_nil @client.nil_struct_return
100
+ end
101
+
102
+ def test_inner_nil
103
+ outer = @client.inner_nil
104
+ assert_equal 'outer', outer.name
105
+ assert_nil outer.inner
106
+ end
107
+
108
+ def test_client_container
109
+ assert_equal(50, ClientContainer.new.get_client.client_container)
110
+ assert(ClientContainer.new.get_invalid.nil?)
111
+ end
112
+
113
+ def test_named_parameters
114
+ assert(@container.value_named_parameters.nil?)
115
+ assert(@client.named_parameters("key", 5).nil?)
116
+ assert_equal(["key", 5], @container.value_named_parameters)
117
+ end
118
+
119
+ def test_capitalized_method_name
120
+ @container.value_normal = nil
121
+ assert_equal(5, @client.Normal(5, 6))
122
+ assert_equal([5, 6], @container.value_normal)
123
+ @container.value_normal = nil
124
+ end
125
+
126
+ def test_model_return
127
+ user = @client.user_return
128
+ assert_equal 1, user.id
129
+ assert_equal 'Kent', user.name
130
+ assert user.active?
131
+ assert_kind_of Date, user.created_on
132
+ assert_equal Date.today, user.created_on
133
+ assert_equal BigDecimal('12.2'), user.balance
134
+ end
135
+
136
+ def test_with_model
137
+ with_model = @client.with_model_return
138
+ assert_equal 'Kent', with_model.user.name
139
+ assert_equal 2, with_model.users.size
140
+ with_model.users.each do |user|
141
+ assert_kind_of User, user
142
+ end
143
+ end
144
+
145
+ def test_scoped_model_return
146
+ scoped_model = @client.scoped_model_return
147
+ assert_kind_of Accounting::User, scoped_model
148
+ assert_equal 'Kent', scoped_model.name
149
+ end
150
+
151
+ def test_multi_dim_return
152
+ md_struct = @client.multi_dim_return
153
+ assert_kind_of Array, md_struct.pref
154
+ assert_equal 2, md_struct.pref.size
155
+ assert_kind_of Array, md_struct.pref[0]
156
+ end
157
+ end