actionwebservice 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,8 +1,34 @@
1
+ *1.1.0* (March 27th, 2005)
2
+
3
+ * Make ActiveWebService::Struct type reloadable
4
+
5
+ * Fix scaffolding action when one of the members of a structural type has date or time type
6
+
7
+ * Remove extra index hash when generating scaffold html for parameters of structural type #4374 [joe@mjg2.com]
8
+
9
+ * Fix Scaffold Fails with Struct as a Parameter #4363 [joe@mjg2.com]
10
+
11
+ * Fix soap type registration of multidimensional arrays (#4232)
12
+
13
+ * Fix that marshaler couldn't handle ActiveRecord models defined in a different namespace (#2392).
14
+
15
+ * Fix that marshaler couldn't handle structs with members of ActiveRecord type (#1889).
16
+
17
+ * Fix that marshaler couldn't handle nil values for inner structs (#3576).
18
+
19
+ * Fix that changes to ActiveWebService::API::Base required restarting of the server (#2390).
20
+
21
+ * Fix scaffolding for signatures with :date, :time and :base64 types (#3321, #2769, #2078).
22
+
23
+ * Fix for incorrect casting of TrueClass/FalseClass instances (#2633, #3421).
24
+
25
+ * Fix for incompatibility problems with SOAP4R 1.5.5 (#2553) [Kent Sibilev]
26
+
27
+
1
28
  *1.0.0* (December 13th, 2005)
2
29
 
3
30
  * Become part of Rails 1.0
4
31
 
5
-
6
32
  *0.9.4* (December 7th, 2005)
7
33
 
8
34
  * Update from LGPL to MIT license as per Minero Aoki's permission. [Marcel Molina Jr.]
@@ -11,7 +37,6 @@
11
37
 
12
38
  * Fix that XML-RPC date/time values did not have well-defined behaviour (#2516, #2534). This fix has one caveat, in that we can't support pre-1970 dates from XML-RPC clients.
13
39
 
14
-
15
40
  *0.9.3* (November 7th, 2005)
16
41
 
17
42
  * Upgraded to Action Pack 1.11.0 and Active Record 1.13.0
data/Rakefile CHANGED
@@ -30,12 +30,20 @@ Rake::TestTask.new { |t|
30
30
  t.verbose = true
31
31
  }
32
32
 
33
+ SCHEMA_PATH = File.join(File.dirname(__FILE__), *%w(test fixtures db_definitions))
34
+
35
+ desc 'Build the MySQL test database'
36
+ task :build_database do
37
+ %x( mysqladmin create activewebservice_unittest )
38
+ %x( mysql activewebservice_unittest < #{File.join(SCHEMA_PATH, 'mysql.sql')} )
39
+ end
40
+
33
41
 
34
42
  # Generate the RDoc documentation
35
43
  Rake::RDocTask.new { |rdoc|
36
44
  rdoc.rdoc_dir = 'doc'
37
45
  rdoc.title = "Action Web Service -- Web services for Action Pack"
38
- rdoc.options << '--line-numbers --inline-source --main README --accessor class_inheritable_option=RW'
46
+ rdoc.options << '--line-numbers' << '--inline-source'
39
47
  rdoc.template = "#{ENV['template']}.rb" if ENV['template']
40
48
  rdoc.rdoc_files.include('README')
41
49
  rdoc.rdoc_files.include('CHANGELOG')
@@ -63,8 +71,8 @@ spec = Gem::Specification.new do |s|
63
71
  s.rubyforge_project = "aws"
64
72
  s.homepage = "http://www.rubyonrails.org"
65
73
 
66
- s.add_dependency('actionpack', '= 1.11.2' + PKG_BUILD)
67
- s.add_dependency('activerecord', '= 1.13.2' + PKG_BUILD)
74
+ s.add_dependency('actionpack', '= 1.12.0' + PKG_BUILD)
75
+ s.add_dependency('activerecord', '= 1.14.0' + PKG_BUILD)
68
76
 
69
77
  s.has_rdoc = true
70
78
  s.requirements << 'none'
@@ -14,6 +14,10 @@ module ActionWebService # :nodoc:
14
14
  # See ActionWebService::Container::Direct::ClassMethods for an example
15
15
  # of use.
16
16
  class Base
17
+ # Action WebService API subclasses should be reloaded by the dispatcher in Rails
18
+ # when Dependencies.mechanism = :load.
19
+ include Reloadable::Subclasses
20
+
17
21
  # Whether to transform the public API method names into camel-cased names
18
22
  class_inheritable_option :inflect_names, true
19
23
 
@@ -25,12 +25,16 @@ module ActionWebService # :nodoc:
25
25
  # api_method :delete_person, :expects => [:int]
26
26
  # end
27
27
  #
28
- # class SearchCriteria < ActionStruct::Base
28
+ # class SearchCriteria < ActionWebService::Struct
29
29
  # member :firstname, :string
30
30
  # member :lastname, :string
31
31
  # member :email, :string
32
32
  # end
33
33
  class Base
34
+ # Action WebService subclasses should be reloaded by the dispatcher in Rails
35
+ # when Dependencies.mechanism = :load.
36
+ include Reloadable::Subclasses
37
+
34
38
  # Whether to report exceptions back to the caller in the protocol's exception
35
39
  # format
36
40
  class_inheritable_option :web_service_exception_reporting, true
@@ -41,6 +41,11 @@ module ActionWebService # :nodoc:
41
41
  def cast(value, signature_type) # :nodoc:
42
42
  return value if signature_type.nil? # signature.length != params.length
43
43
  return nil if value.nil?
44
+ # XMLRPC protocol doesn't support nil values. It uses false instead.
45
+ # It should never happen for SOAP.
46
+ if signature_type.structured? && value.equal?(false)
47
+ return nil
48
+ end
44
49
  unless signature_type.array? || signature_type.structured?
45
50
  return value if canonical_type(value.class) == signature_type.type
46
51
  end
@@ -91,10 +96,13 @@ module ActionWebService # :nodoc:
91
96
  when :float
92
97
  Float(value)
93
98
  when :time
99
+ value = "#{value['2']}/#{value['3']}/#{value['1']} #{value['4']}:#{value['5']}:#{value['6']}" if value.kind_of?(Hash)
94
100
  Time.parse(value.to_s)
95
101
  when :date
102
+ value = "#{value['2']}/#{value['3']}/#{value['1']}" if value.kind_of?(Hash)
96
103
  Date.parse(value.to_s)
97
104
  when :datetime
105
+ value = "#{value['2']}/#{value['3']}/#{value['1']} #{value['4']}:#{value['5']}:#{value['6']}" if value.kind_of?(Hash)
98
106
  DateTime.parse(value.to_s)
99
107
  end
100
108
  end
@@ -108,6 +116,8 @@ module ActionWebService # :nodoc:
108
116
  value.each_pair do |name, val|
109
117
  type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil
110
118
  val = cast(val, type) if type
119
+ # See http://dev.rubyonrails.com/ticket/3567
120
+ val = val.to_time if val.is_a?(XMLRPC::DateTime)
111
121
  obj.__send__("#{name}=", val) if obj.respond_to?(name)
112
122
  end
113
123
  elsif value.respond_to?(:attributes)
@@ -80,12 +80,20 @@ module ActionWebService # :nodoc:
80
80
  if expects
81
81
  expects.each do |type|
82
82
  type_binding = @protocol.marshaler.lookup_type(type)
83
- param_def << ['in', type.name, type_binding.mapping]
83
+ if SOAP::Version >= "1.5.5"
84
+ param_def << ['in', type.name.to_s, [type_binding.type.type_class.to_s]]
85
+ else
86
+ param_def << ['in', type.name, type_binding.mapping]
87
+ end
84
88
  end
85
89
  end
86
90
  if returns
87
91
  type_binding = @protocol.marshaler.lookup_type(returns[0])
88
- param_def << ['retval', 'return', type_binding.mapping]
92
+ if SOAP::Version >= "1.5.5"
93
+ param_def << ['retval', 'return', [type_binding.type.type_class.to_s]]
94
+ else
95
+ param_def << ['retval', 'return', type_binding.mapping]
96
+ end
89
97
  end
90
98
  driver.add_method(qname, action, method.name.to_s, param_def)
91
99
  end
@@ -32,43 +32,47 @@ module ActionWebService
32
32
  end
33
33
 
34
34
  def ruby_to_soap(obj)
35
- SOAP::Mapping.obj2soap(obj, @registry)
35
+ soap = SOAP::Mapping.obj2soap(obj, @registry)
36
+ soap.elename = XSD::QName.new if SOAP::Version >= "1.5.5" && soap.elename == XSD::QName::EMPTY
37
+ soap
36
38
  end
37
39
 
38
40
  def register_type(type)
39
41
  return @type2binding[type] if @type2binding.has_key?(type)
40
42
 
41
- type_class = type.array?? type.element_type.type_class : type.type_class
42
- type_type = type.array?? type.element_type : type
43
- type_binding = nil
44
- if (mapping = @registry.find_mapped_soap_class(type_class) rescue nil)
45
- qname = mapping[2] ? mapping[2][:type] : nil
46
- qname ||= soap_base_type_name(mapping[0])
47
- type_binding = SoapBinding.new(self, qname, type_type, mapping)
48
- else
49
- qname = XSD::QName.new(@namespace, soap_type_name(type_class.name))
50
- @registry.add(type_class,
51
- SOAP::SOAPStruct,
52
- typed_struct_factory(type_class),
53
- { :type => qname })
54
- mapping = @registry.find_mapped_soap_class(type_class)
55
- type_binding = SoapBinding.new(self, qname, type_type, mapping)
56
- end
57
-
58
- array_binding = nil
59
43
  if type.array?
60
44
  array_mapping = @registry.find_mapped_soap_class(Array)
61
45
  qname = XSD::QName.new(@namespace, soap_type_name(type.element_type.type_class.name) + 'Array')
62
- array_binding = SoapBinding.new(self, qname, type, array_mapping, type_binding)
46
+ element_type_binding = register_type(type.element_type)
47
+ @type2binding[type] = SoapBinding.new(self, qname, type, array_mapping, element_type_binding)
48
+ elsif (mapping = @registry.find_mapped_soap_class(type.type_class) rescue nil)
49
+ qname = mapping[2] ? mapping[2][:type] : nil
50
+ qname ||= soap_base_type_name(mapping[0])
51
+ @type2binding[type] = SoapBinding.new(self, qname, type, mapping)
52
+ else
53
+ qname = XSD::QName.new(@namespace, soap_type_name(type.type_class.name))
54
+ @registry.add(type.type_class,
55
+ SOAP::SOAPStruct,
56
+ typed_struct_factory(type.type_class),
57
+ { :type => qname })
58
+ mapping = @registry.find_mapped_soap_class(type.type_class)
59
+ @type2binding[type] = SoapBinding.new(self, qname, type, mapping)
60
+ end
61
+
62
+ if type.structured?
63
+ type.each_member do |m_name, m_type|
64
+ register_type(m_type)
65
+ end
63
66
  end
64
-
65
- @type2binding[type] = array_binding ? array_binding : type_binding
67
+
66
68
  @type2binding[type]
67
69
  end
68
70
  alias :lookup_type :register_type
69
71
 
70
72
  def annotate_arrays(binding, value)
71
- if binding.type.array?
73
+ if value.nil?
74
+ return
75
+ elsif binding.type.array?
72
76
  mark_typed_array(value, binding.element_binding.qname)
73
77
  if binding.element_binding.type.custom?
74
78
  value.each do |element|
@@ -50,10 +50,10 @@ module ActionWebService # :nodoc:
50
50
  end
51
51
 
52
52
  def encode_response(method_name, return_value, return_type, protocol_options={})
53
- return_value = true if return_value.nil?
54
- if return_type
53
+ if return_value && return_type
55
54
  return_value = value_to_xmlrpc_wire_format(return_value, return_type)
56
55
  end
56
+ return_value = false if return_value.nil?
57
57
  raw_response = XMLRPC::Marshal.dump_response(return_value)
58
58
  Response.new(raw_response, 'text/xml', return_value)
59
59
  end
@@ -65,16 +65,13 @@ module ActionWebService
65
65
  when :xmlrpc
66
66
  @protocol = Protocol::XmlRpc::XmlRpcProtocol.create(self)
67
67
  end
68
- @invocation_cgi = request.respond_to?(:cgi) ? request.cgi : nil
69
68
  bm = Benchmark.measure do
70
69
  @protocol.register_api(@scaffold_service.api)
71
70
  post_params = params['method_params'] ? params['method_params'].dup : nil
72
71
  params = []
73
- if @scaffold_method.expects
74
- @scaffold_method.expects.length.times do |i|
75
- params << post_params[i.to_s]
76
- end
77
- end
72
+ @scaffold_method.expects.each_with_index do |spec, i|
73
+ params << post_params[i.to_s]
74
+ end if @scaffold_method.expects
78
75
  params = @scaffold_method.cast_expects(params)
79
76
  method_name = public_method_name(@scaffold_service.name, @scaffold_method.public_name)
80
77
  @method_request_xml = @protocol.encode_request(method_name, params, @scaffold_method.expects)
@@ -130,14 +127,8 @@ module ActionWebService
130
127
  end
131
128
 
132
129
  def reset_invocation_response
133
- template = response.template
134
- if @invocation_cgi
135
- @response = ::ActionController::CgiResponse.new(@invocation_cgi)
136
- else
137
- @response = ::ActionController::TestResponse.new
138
- end
139
- response.template = template
140
- @performed_render = false
130
+ erase_render_results
131
+ @response.headers = ::ActionController::AbstractResponse::DEFAULT_HEADERS.merge("cookie" => [])
141
132
  end
142
133
 
143
134
  def public_method_name(service_name, method_name)
@@ -173,18 +164,21 @@ module ActionWebService
173
164
  end
174
165
 
175
166
  module Helpers # :nodoc:
176
- def method_parameter_input_fields(method, type, field_name_base)
167
+ def method_parameter_input_fields(method, type, field_name_base, idx, was_structured=false)
177
168
  if type.array?
178
169
  return content_tag('em', "Typed array input fields not supported yet (#{type.name})")
179
170
  end
180
171
  if type.structured?
172
+ return content_tag('em', "Nested structural types not supported yet (#{type.name})") if was_structured
181
173
  parameters = ""
182
174
  type.each_member do |member_name, member_type|
183
175
  label = method_parameter_label(member_name, member_type)
184
176
  nested_content = method_parameter_input_fields(
185
177
  method,
186
178
  member_type,
187
- field_name_base + '[' + member_name.to_s + ']')
179
+ "#{field_name_base}[#{idx}][#{member_name}]",
180
+ idx,
181
+ true)
188
182
  if member_type.custom?
189
183
  parameters << content_tag('li', label)
190
184
  parameters << content_tag('ul', nested_content)
@@ -194,20 +188,35 @@ module ActionWebService
194
188
  end
195
189
  content_tag('ul', parameters)
196
190
  else
191
+ # If the data source was structured previously we already have the index set
192
+ field_name_base = "#{field_name_base}[#{idx}]" unless was_structured
193
+
197
194
  case type.type
198
195
  when :int
199
- text_field_tag field_name_base
196
+ text_field_tag "#{field_name_base}"
200
197
  when :string
201
- text_field_tag field_name_base
198
+ text_field_tag "#{field_name_base}"
199
+ when :base64
200
+ text_area_tag "#{field_name_base}", nil, :size => "40x5"
202
201
  when :bool
203
- radio_button_tag(field_name_base, "true") + " True" +
204
- radio_button_tag(field_name_base, "false") + "False"
202
+ radio_button_tag("#{field_name_base}", "true") + " True" +
203
+ radio_button_tag("#{field_name_base}", "false") + "False"
205
204
  when :float
206
- text_field_tag field_name_base
207
- when :time
208
- select_datetime Time.now, 'name' => field_name_base
205
+ text_field_tag "#{field_name_base}"
206
+ when :time, :datetime
207
+ time = Time.now
208
+ i = 0
209
+ %w|year month day hour minute second|.map do |name|
210
+ i += 1
211
+ send("select_#{name}", time, :prefix => "#{field_name_base}[#{i}]", :discard_type => true)
212
+ end.join
209
213
  when :date
210
- select_date Date.today, 'name' => field_name_base
214
+ date = Date.today
215
+ i = 0
216
+ %w|year month day|.map do |name|
217
+ i += 1
218
+ send("select_#{name}", date, :prefix => "#{field_name_base}[#{i}]", :discard_type => true)
219
+ end.join
211
220
  end
212
221
  end
213
222
  end
@@ -19,6 +19,9 @@ module ActionWebService
19
19
  # Active Record model classes are already implicitly supported in method
20
20
  # signatures.
21
21
  class Struct
22
+ # Action WebService Struct subclasses should be reloaded by the dispatcher in Rails
23
+ # when Dependencies.mechanism = :load.
24
+ include Reloadable::Subclasses
22
25
 
23
26
  # If a Hash is given as argument to an ActionWebService::Struct constructor,
24
27
  # it can contain initial values for the structure member.
@@ -53,9 +53,9 @@ module ActionWebService # :nodoc:
53
53
  case name
54
54
  when :int, :integer, :fixnum, :bignum
55
55
  :int
56
- when :string
56
+ when :string, :text
57
57
  :string
58
- when :base64
58
+ when :base64, :binary
59
59
  :base64
60
60
  when :bool, :boolean
61
61
  :bool
@@ -203,7 +203,7 @@ module ActionWebService # :nodoc:
203
203
  elsif @type_class.respond_to?(:columns)
204
204
  i = -1
205
205
  @type_class.columns.each do |column|
206
- yield column.name, canonical_signature_entry(column.klass, i += 1)
206
+ yield column.name, canonical_signature_entry(column.type, i += 1)
207
207
  end
208
208
  end
209
209
  end
@@ -26,7 +26,7 @@
26
26
  display: table;
27
27
  }
28
28
 
29
- #ErrorExplanation {
29
+ #errorExplanation {
30
30
  width: 400px;
31
31
  border: 2px solid red;
32
32
  padding: 7px;
@@ -35,7 +35,7 @@
35
35
  background-color: #f0f0f0;
36
36
  }
37
37
 
38
- #ErrorExplanation h2 {
38
+ #errorExplanation h2 {
39
39
  text-align: left;
40
40
  font-weight: bold;
41
41
  padding: 5px 5px 5px 15px;
@@ -45,13 +45,13 @@
45
45
  color: #fff;
46
46
  }
47
47
 
48
- #ErrorExplanation p {
48
+ #errorExplanation p {
49
49
  color: #333;
50
50
  margin-bottom: 0;
51
51
  padding: 5px;
52
52
  }
53
53
 
54
- #ErrorExplanation ul li {
54
+ #errorExplanation ul li {
55
55
  font-size: 12px;
56
56
  list-style: square;
57
57
  }
@@ -10,20 +10,19 @@
10
10
  </p>
11
11
 
12
12
  <% if @scaffold_method.expects %>
13
- <% i = 0 %>
14
13
 
15
14
  <strong>Method Parameters:</strong><br />
16
- <% @scaffold_method.expects.each do |type| %>
15
+ <% @scaffold_method.expects.each_with_index do |type, i| %>
17
16
  <p>
18
17
  <label for="method_params[<%= i %>]"><%= method_parameter_label(type.name, type) %> </label><br />
19
- <%= method_parameter_input_fields(@scaffold_method, type, "method_params[#{i}]") %>
18
+ <%= method_parameter_input_fields(@scaffold_method, type, "method_params", i) %>
20
19
  </p>
21
- <% i += 1 %>
22
20
  <% end %>
23
21
 
24
22
  <% end %>
25
23
 
26
24
  <%= submit_tag "Invoke" %>
25
+ <%= end_form_tag %>
27
26
 
28
27
  <p>
29
28
  <%= link_to "Back", :action => @scaffold_action_name %>
@@ -1,7 +1,7 @@
1
1
  module ActionWebService
2
- module VERSION
2
+ module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 0
4
+ MINOR = 1
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -12,17 +12,49 @@ module ClientTest
12
12
  firstnames == other.firstnames && lastname == other.lastname
13
13
  end
14
14
  end
15
+
16
+ class Inner < ActionWebService::Struct
17
+ member :name, :string
18
+ end
19
+
20
+ class Outer < ActionWebService::Struct
21
+ member :name, :string
22
+ member :inner, Inner
23
+ end
24
+
25
+ class User < ActiveRecord::Base
26
+ end
27
+
28
+ module Accounting
29
+ class User < ActiveRecord::Base
30
+ end
31
+ end
32
+
33
+ class WithModel < ActionWebService::Struct
34
+ member :user, User
35
+ member :users, [User]
36
+ end
37
+
38
+ class WithMultiDimArray < ActionWebService::Struct
39
+ member :pref, [[:string]]
40
+ end
15
41
 
16
42
  class API < ActionWebService::API::Base
17
43
  api_method :void
18
- api_method :normal, :expects => [:int, :int], :returns => [:int]
19
- api_method :array_return, :returns => [[Person]]
20
- api_method :struct_pass, :expects => [[Person]], :returns => [:bool]
21
- api_method :client_container, :returns => [:int]
22
- api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}]
44
+ api_method :normal, :expects => [:int, :int], :returns => [:int]
45
+ api_method :array_return, :returns => [[Person]]
46
+ api_method :struct_pass, :expects => [[Person]], :returns => [:bool]
47
+ api_method :nil_struct_return, :returns => [Person]
48
+ api_method :inner_nil, :returns => [Outer]
49
+ api_method :client_container, :returns => [:int]
50
+ api_method :named_parameters, :expects => [{:key=>:string}, {:id=>:int}]
23
51
  api_method :thrower
52
+ api_method :user_return, :returns => [User]
53
+ api_method :with_model_return, :returns => [WithModel]
54
+ api_method :scoped_model_return, :returns => [Accounting::User]
55
+ api_method :multi_dim_return, :returns => [WithMultiDimArray]
24
56
  end
25
-
57
+
26
58
  class NullLogOut
27
59
  def <<(*args); end
28
60
  end
@@ -65,6 +97,14 @@ module ClientTest
65
97
  @value_struct_pass = @method_params
66
98
  true
67
99
  end
100
+
101
+ def nil_struct_return
102
+ nil
103
+ end
104
+
105
+ def inner_nil
106
+ Outer.new :name => 'outer', :inner => nil
107
+ end
68
108
 
69
109
  def client_container
70
110
  50
@@ -77,6 +117,22 @@ module ClientTest
77
117
  def thrower
78
118
  raise "Hi"
79
119
  end
120
+
121
+ def user_return
122
+ User.find(1)
123
+ end
124
+
125
+ def with_model_return
126
+ WithModel.new :user => User.find(1), :users => User.find(:all)
127
+ end
128
+
129
+ def scoped_model_return
130
+ Accounting::User.find(1)
131
+ end
132
+
133
+ def multi_dim_return
134
+ WithMultiDimArray.new :pref => [%w{pref1 value1}, %w{pref2 value2}]
135
+ end
80
136
  end
81
137
 
82
138
  class AbstractClientLet < WEBrick::HTTPServlet::AbstractServlet
@@ -5,10 +5,34 @@ $:.unshift(File.dirname(__FILE__) + '/../../actionpack/lib')
5
5
  $:.unshift(File.dirname(__FILE__) + '/../../activerecord/lib')
6
6
 
7
7
  require 'test/unit'
8
- require 'active_record'
9
8
  require 'action_web_service'
10
9
  require 'action_controller'
11
10
  require 'action_controller/test_process'
12
11
 
13
12
  ActionController::Base.logger = nil
14
13
  ActionController::Base.ignore_missing_templates = true
14
+
15
+ begin
16
+ PATH_TO_AR = File.dirname(__FILE__) + '/../../activerecord'
17
+ require "#{PATH_TO_AR}/lib/active_record" unless Object.const_defined?(:ActiveRecord)
18
+ require "#{PATH_TO_AR}/lib/active_record/fixtures" unless Object.const_defined?(:Fixtures)
19
+ rescue Object => e
20
+ fail "\nFailed to load activerecord: #{e}"
21
+ end
22
+
23
+ ActiveRecord::Base.establish_connection(
24
+ :adapter => "mysql",
25
+ :username => "rails",
26
+ :encoding => "utf8",
27
+ :database => "activewebservice_unittest"
28
+ )
29
+ ActiveRecord::Base.connection
30
+
31
+ Test::Unit::TestCase.fixture_path = "#{File.dirname(__FILE__)}/fixtures/"
32
+
33
+ # restore default raw_post functionality
34
+ class ActionController::TestRequest
35
+ def raw_post
36
+ super
37
+ end
38
+ end
@@ -49,6 +49,8 @@ end
49
49
  class TC_ClientSoap < Test::Unit::TestCase
50
50
  include ClientTest
51
51
  include ClientSoapTest
52
+
53
+ fixtures :users
52
54
 
53
55
  def setup
54
56
  @server = SoapServer.instance
@@ -88,6 +90,16 @@ class TC_ClientSoap < Test::Unit::TestCase
88
90
  assert_equal(true, @client.struct_pass([new_person]))
89
91
  assert_equal([[new_person]], @container.value_struct_pass)
90
92
  end
93
+
94
+ def test_nil_struct_return
95
+ assert_nil @client.nil_struct_return
96
+ end
97
+
98
+ def test_inner_nil
99
+ outer = @client.inner_nil
100
+ assert_equal 'outer', outer.name
101
+ assert_nil outer.inner
102
+ end
91
103
 
92
104
  def test_client_container
93
105
  assert_equal(50, ClientContainer.new.get_client.client_container)
@@ -106,4 +118,35 @@ class TC_ClientSoap < Test::Unit::TestCase
106
118
  assert_equal([5, 6], @container.value_normal)
107
119
  @container.value_normal = nil
108
120
  end
121
+
122
+ def test_model_return
123
+ user = @client.user_return
124
+ assert_equal 1, user.id
125
+ assert_equal 'Kent', user.name
126
+ assert user.active?
127
+ assert_kind_of Date, user.created_on
128
+ assert_equal Date.today, user.created_on
129
+ end
130
+
131
+ def test_with_model
132
+ with_model = @client.with_model_return
133
+ assert_equal 'Kent', with_model.user.name
134
+ assert_equal 2, with_model.users.size
135
+ with_model.users.each do |user|
136
+ assert_kind_of User, user
137
+ end
138
+ end
139
+
140
+ def test_scoped_model_return
141
+ scoped_model = @client.scoped_model_return
142
+ assert_kind_of Accounting::User, scoped_model
143
+ assert_equal 'Kent', scoped_model.name
144
+ end
145
+
146
+ def test_multi_dim_return
147
+ md_struct = @client.multi_dim_return
148
+ assert_kind_of Array, md_struct.pref
149
+ assert_equal 2, md_struct.pref.size
150
+ assert_kind_of Array, md_struct.pref[0]
151
+ end
109
152
  end
@@ -12,7 +12,7 @@ module ClientXmlRpcTest
12
12
  test_request.env['HTTP_CONTENT_TYPE'] = 'text/xml'
13
13
  test_request.env['RAW_POST_DATA'] = req.body
14
14
  response = ActionController::TestResponse.new
15
- @controller.process(test_request, response)
15
+ @controller.process(test_request, response)
16
16
  res.header['content-type'] = 'text/xml'
17
17
  res.body = response.body
18
18
  # puts res.body
@@ -44,6 +44,8 @@ end
44
44
  class TC_ClientXmlRpc < Test::Unit::TestCase
45
45
  include ClientTest
46
46
  include ClientXmlRpcTest
47
+
48
+ fixtures :users
47
49
 
48
50
  def setup
49
51
  @server = XmlRpcServer.instance
@@ -83,6 +85,16 @@ class TC_ClientXmlRpc < Test::Unit::TestCase
83
85
  assert_equal(true, @client.struct_pass([new_person]))
84
86
  assert_equal([[new_person]], @container.value_struct_pass)
85
87
  end
88
+
89
+ def test_nil_struct_return
90
+ assert_equal false, @client.nil_struct_return
91
+ end
92
+
93
+ def test_inner_nil
94
+ outer = @client.inner_nil
95
+ assert_equal 'outer', outer.name
96
+ assert_nil outer.inner
97
+ end
86
98
 
87
99
  def test_client_container
88
100
  assert_equal(50, ClientContainer.new.get_client.client_container)
@@ -90,7 +102,7 @@ class TC_ClientXmlRpc < Test::Unit::TestCase
90
102
 
91
103
  def test_named_parameters
92
104
  assert(@container.value_named_parameters.nil?)
93
- assert_equal(true, @client.named_parameters("xxx", 7))
105
+ assert_equal(false, @client.named_parameters("xxx", 7))
94
106
  assert_equal(["xxx", 7], @container.value_named_parameters)
95
107
  end
96
108
 
@@ -105,4 +117,35 @@ class TC_ClientXmlRpc < Test::Unit::TestCase
105
117
  @client.normal
106
118
  end
107
119
  end
120
+
121
+ def test_model_return
122
+ user = @client.user_return
123
+ assert_equal 1, user.id
124
+ assert_equal 'Kent', user.name
125
+ assert user.active?
126
+ assert_kind_of Time, user.created_on
127
+ assert_equal Time.utc(Time.now.year, Time.now.month, Time.now.day), user.created_on
128
+ end
129
+
130
+ def test_with_model
131
+ with_model = @client.with_model_return
132
+ assert_equal 'Kent', with_model.user.name
133
+ assert_equal 2, with_model.users.size
134
+ with_model.users.each do |user|
135
+ assert_kind_of User, user
136
+ end
137
+ end
138
+
139
+ def test_scoped_model_return
140
+ scoped_model = @client.scoped_model_return
141
+ assert_kind_of Accounting::User, scoped_model
142
+ assert_equal 'Kent', scoped_model.name
143
+ end
144
+
145
+ def test_multi_dim_return
146
+ md_struct = @client.multi_dim_return
147
+ assert_kind_of Array, md_struct.pref
148
+ assert_equal 2, md_struct.pref.size
149
+ assert_kind_of Array, md_struct.pref[0]
150
+ end
108
151
  end
@@ -0,0 +1,7 @@
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
+ `created_on` date default NULL,
6
+ PRIMARY KEY (`id`)
7
+ ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
@@ -0,0 +1,10 @@
1
+ user1:
2
+ id: 1
3
+ name: Kent
4
+ active: 1
5
+ created_on: <%= Date.today %>
6
+ user2:
7
+ id: 2
8
+ name: David
9
+ active: 1
10
+ created_on: <%= Date.today %>
@@ -2,11 +2,15 @@ require File.dirname(__FILE__) + '/abstract_unit'
2
2
 
3
3
  ActionController::Routing::Routes.draw do |map|
4
4
  map.connect '', :controller => 'scaffolded'
5
+ map.connect ':controller/:action/:id'
5
6
  end
6
7
 
8
+ ActionController::Base.template_root = '.'
9
+
7
10
  class ScaffoldPerson < ActionWebService::Struct
8
- member :id, :int
9
- member :name, :string
11
+ member :id, :int
12
+ member :name, :string
13
+ member :birth, :date
10
14
 
11
15
  def ==(other)
12
16
  self.id == other.id && self.name == other.name
@@ -15,7 +19,12 @@ end
15
19
 
16
20
  class ScaffoldedControllerTestAPI < ActionWebService::API::Base
17
21
  api_method :hello, :expects => [{:integer=>:int}, :string], :returns => [:bool]
22
+ api_method :hello_struct_param, :expects => [{:person => ScaffoldPerson}], :returns => [:bool]
23
+ api_method :date_of_birth, :expects => [ScaffoldPerson], :returns => [:string]
18
24
  api_method :bye, :returns => [[ScaffoldPerson]]
25
+ api_method :date_diff, :expects => [{:start_date => :date}, {:end_date => :date}], :returns => [:int]
26
+ api_method :time_diff, :expects => [{:start_time => :time}, {:end_time => :time}], :returns => [:int]
27
+ api_method :base64_upcase, :expects => [:base64], :returns => [:base64]
19
28
  end
20
29
 
21
30
  class ScaffoldedController < ActionController::Base
@@ -25,6 +34,14 @@ class ScaffoldedController < ActionController::Base
25
34
  def hello(int, string)
26
35
  0
27
36
  end
37
+
38
+ def hello_struct_param(person)
39
+ 0
40
+ end
41
+
42
+ def date_of_birth(person)
43
+ person.birth.to_s
44
+ end
28
45
 
29
46
  def bye
30
47
  [ScaffoldPerson.new(:id => 1, :name => "leon"), ScaffoldPerson.new(:id => 2, :name => "paul")]
@@ -33,6 +50,18 @@ class ScaffoldedController < ActionController::Base
33
50
  def rescue_action(e)
34
51
  raise e
35
52
  end
53
+
54
+ def date_diff(start_date, end_date)
55
+ end_date - start_date
56
+ end
57
+
58
+ def time_diff(start_time, end_time)
59
+ end_time - start_time
60
+ end
61
+
62
+ def base64_upcase(data)
63
+ data.upcase
64
+ end
36
65
  end
37
66
 
38
67
  class ScaffoldedControllerTest < Test::Unit::TestCase
@@ -51,6 +80,12 @@ class ScaffoldedControllerTest < Test::Unit::TestCase
51
80
  get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'Hello'
52
81
  assert_rendered_file 'parameters.rhtml'
53
82
  end
83
+
84
+ def test_scaffold_invoke_method_params_with_struct
85
+ get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'HelloStructParam'
86
+ assert_rendered_file 'parameters.rhtml'
87
+ assert_tag :tag => 'input', :attributes => {:name => "method_params[0][name]"}
88
+ end
54
89
 
55
90
  def test_scaffold_invoke_submit_hello
56
91
  post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Hello', :method_params => {'0' => '5', '1' => 'hello world'}
@@ -64,4 +99,47 @@ class ScaffoldedControllerTest < Test::Unit::TestCase
64
99
  persons = [ScaffoldPerson.new(:id => 1, :name => "leon"), ScaffoldPerson.new(:id => 2, :name => "paul")]
65
100
  assert_equal persons, @controller.instance_eval{ @method_return_value }
66
101
  end
102
+
103
+ def test_scaffold_date_params
104
+ get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'DateDiff'
105
+ (0..1).each do |param|
106
+ (1..3).each do |date_part|
107
+ assert_tag :tag => 'select', :attributes => {:name => "method_params[#{param}][#{date_part}]"},
108
+ :children => {:greater_than => 1, :only => {:tag => 'option'}}
109
+ end
110
+ end
111
+
112
+ post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'DateDiff',
113
+ :method_params => {'0' => {'1' => '2006', '2' => '2', '3' => '1'}, '1' => {'1' => '2006', '2' => '2', '3' => '2'}}
114
+ assert_equal 1, @controller.instance_eval{ @method_return_value }
115
+ end
116
+
117
+ def test_scaffold_struct_date_params
118
+ post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'DateOfBirth',
119
+ :method_params => {'0' => {'birth' => {'1' => '2006', '2' => '2', '3' => '1'}, 'id' => '1', 'name' => 'person'}}
120
+ assert_equal '2006-02-01', @controller.instance_eval{ @method_return_value }
121
+ end
122
+
123
+ def test_scaffold_time_params
124
+ get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'TimeDiff'
125
+ (0..1).each do |param|
126
+ (1..6).each do |date_part|
127
+ assert_tag :tag => 'select', :attributes => {:name => "method_params[#{param}][#{date_part}]"},
128
+ :children => {:greater_than => 1, :only => {:tag => 'option'}}
129
+ end
130
+ end
131
+
132
+ post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'TimeDiff',
133
+ :method_params => {'0' => {'1' => '2006', '2' => '2', '3' => '1', '4' => '1', '5' => '1', '6' => '1'},
134
+ '1' => {'1' => '2006', '2' => '2', '3' => '2', '4' => '1', '5' => '1', '6' => '1'}}
135
+ assert_equal 86400, @controller.instance_eval{ @method_return_value }
136
+ end
137
+
138
+ def test_scaffold_base64
139
+ get :scaffold_invoke_method_params, :service => 'scaffolded', :method => 'Base64Upcase'
140
+ assert_tag :tag => 'textarea', :attributes => {:name => 'method_params[0]'}
141
+
142
+ post :scaffold_invoke_submit, :service => 'scaffolded', :method => 'Base64Upcase', :method_params => {'0' => 'scaffold'}
143
+ assert_equal 'SCAFFOLD', @controller.instance_eval{ @method_return_value }
144
+ end
67
145
  end
metadata CHANGED
@@ -3,11 +3,11 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: actionwebservice
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2005-12-13 00:00:00 -06:00
6
+ version: 1.1.0
7
+ date: 2006-03-27 00:00:00 -06:00
8
8
  summary: Web service support for Action Pack.
9
9
  require_paths:
10
- - lib
10
+ - lib
11
11
  email: bitserf@gmail.com
12
12
  homepage: http://www.rubyonrails.org
13
13
  rubyforge_project: aws
@@ -18,129 +18,135 @@ bindir: bin
18
18
  has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
- -
22
- - ">"
23
- - !ruby/object:Gem::Version
24
- version: 0.0.0
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
25
24
  version:
26
25
  platform: ruby
27
26
  signing_key:
28
27
  cert_chain:
29
28
  authors:
30
- - Leon Breedt
29
+ - Leon Breedt
31
30
  files:
32
- - Rakefile
33
- - setup.rb
34
- - README
35
- - TODO
36
- - CHANGELOG
37
- - MIT-LICENSE
38
- - examples/googlesearch
39
- - examples/metaWeblog
40
- - examples/googlesearch/autoloading
41
- - examples/googlesearch/delegated
42
- - examples/googlesearch/direct
43
- - examples/googlesearch/README
44
- - examples/googlesearch/autoloading/google_search_api.rb
45
- - examples/googlesearch/autoloading/google_search_controller.rb
46
- - examples/googlesearch/delegated/google_search_service.rb
47
- - examples/googlesearch/delegated/search_controller.rb
48
- - examples/googlesearch/direct/google_search_api.rb
49
- - examples/googlesearch/direct/search_controller.rb
50
- - examples/metaWeblog/apis
51
- - examples/metaWeblog/controllers
52
- - examples/metaWeblog/README
53
- - examples/metaWeblog/apis/blogger_api.rb
54
- - examples/metaWeblog/apis/blogger_service.rb
55
- - examples/metaWeblog/apis/meta_weblog_api.rb
56
- - examples/metaWeblog/apis/meta_weblog_service.rb
57
- - examples/metaWeblog/controllers/xmlrpc_controller.rb
58
- - lib/action_web_service
59
- - lib/action_web_service.rb
60
- - lib/action_web_service/api.rb
61
- - lib/action_web_service/base.rb
62
- - lib/action_web_service/casting.rb
63
- - lib/action_web_service/client
64
- - lib/action_web_service/client.rb
65
- - lib/action_web_service/container
66
- - lib/action_web_service/container.rb
67
- - lib/action_web_service/dispatcher
68
- - lib/action_web_service/dispatcher.rb
69
- - lib/action_web_service/invocation.rb
70
- - lib/action_web_service/protocol
71
- - lib/action_web_service/protocol.rb
72
- - lib/action_web_service/scaffolding.rb
73
- - lib/action_web_service/struct.rb
74
- - lib/action_web_service/support
75
- - lib/action_web_service/templates
76
- - lib/action_web_service/test_invoke.rb
77
- - lib/action_web_service/version.rb
78
- - lib/action_web_service/client/base.rb
79
- - lib/action_web_service/client/soap_client.rb
80
- - lib/action_web_service/client/xmlrpc_client.rb
81
- - lib/action_web_service/container/action_controller_container.rb
82
- - lib/action_web_service/container/delegated_container.rb
83
- - lib/action_web_service/container/direct_container.rb
84
- - lib/action_web_service/dispatcher/abstract.rb
85
- - lib/action_web_service/dispatcher/action_controller_dispatcher.rb
86
- - lib/action_web_service/protocol/abstract.rb
87
- - lib/action_web_service/protocol/discovery.rb
88
- - lib/action_web_service/protocol/soap_protocol
89
- - lib/action_web_service/protocol/soap_protocol.rb
90
- - lib/action_web_service/protocol/xmlrpc_protocol.rb
91
- - lib/action_web_service/protocol/soap_protocol/marshaler.rb
92
- - lib/action_web_service/support/class_inheritable_options.rb
93
- - lib/action_web_service/support/signature_types.rb
94
- - lib/action_web_service/templates/scaffolds
95
- - lib/action_web_service/templates/scaffolds/layout.rhtml
96
- - lib/action_web_service/templates/scaffolds/methods.rhtml
97
- - lib/action_web_service/templates/scaffolds/parameters.rhtml
98
- - lib/action_web_service/templates/scaffolds/result.rhtml
99
- - test/abstract_client.rb
100
- - test/abstract_dispatcher.rb
101
- - test/abstract_unit.rb
102
- - test/api_test.rb
103
- - test/apis
104
- - test/base_test.rb
105
- - test/casting_test.rb
106
- - test/client_soap_test.rb
107
- - test/client_xmlrpc_test.rb
108
- - test/container_test.rb
109
- - test/dispatcher_action_controller_soap_test.rb
110
- - test/dispatcher_action_controller_xmlrpc_test.rb
111
- - test/gencov
112
- - test/invocation_test.rb
113
- - test/run
114
- - test/scaffolded_controller_test.rb
115
- - test/struct_test.rb
116
- - test/test_invoke_test.rb
117
- - test/apis/auto_load_api.rb
118
- - test/apis/broken_auto_load_api.rb
31
+ - Rakefile
32
+ - setup.rb
33
+ - README
34
+ - TODO
35
+ - CHANGELOG
36
+ - MIT-LICENSE
37
+ - examples/googlesearch
38
+ - examples/metaWeblog
39
+ - examples/googlesearch/autoloading
40
+ - examples/googlesearch/delegated
41
+ - examples/googlesearch/direct
42
+ - examples/googlesearch/README
43
+ - examples/googlesearch/autoloading/google_search_api.rb
44
+ - examples/googlesearch/autoloading/google_search_controller.rb
45
+ - examples/googlesearch/delegated/google_search_service.rb
46
+ - examples/googlesearch/delegated/search_controller.rb
47
+ - examples/googlesearch/direct/google_search_api.rb
48
+ - examples/googlesearch/direct/search_controller.rb
49
+ - examples/metaWeblog/apis
50
+ - examples/metaWeblog/controllers
51
+ - examples/metaWeblog/README
52
+ - examples/metaWeblog/apis/blogger_api.rb
53
+ - examples/metaWeblog/apis/blogger_service.rb
54
+ - examples/metaWeblog/apis/meta_weblog_api.rb
55
+ - examples/metaWeblog/apis/meta_weblog_service.rb
56
+ - examples/metaWeblog/controllers/xmlrpc_controller.rb
57
+ - lib/action_web_service
58
+ - lib/action_web_service.rb
59
+ - lib/action_web_service/api.rb
60
+ - lib/action_web_service/base.rb
61
+ - lib/action_web_service/casting.rb
62
+ - lib/action_web_service/client
63
+ - lib/action_web_service/client.rb
64
+ - lib/action_web_service/container
65
+ - lib/action_web_service/container.rb
66
+ - lib/action_web_service/dispatcher
67
+ - lib/action_web_service/dispatcher.rb
68
+ - lib/action_web_service/invocation.rb
69
+ - lib/action_web_service/protocol
70
+ - lib/action_web_service/protocol.rb
71
+ - lib/action_web_service/scaffolding.rb
72
+ - lib/action_web_service/struct.rb
73
+ - lib/action_web_service/support
74
+ - lib/action_web_service/templates
75
+ - lib/action_web_service/test_invoke.rb
76
+ - lib/action_web_service/version.rb
77
+ - lib/action_web_service/client/base.rb
78
+ - lib/action_web_service/client/soap_client.rb
79
+ - lib/action_web_service/client/xmlrpc_client.rb
80
+ - lib/action_web_service/container/action_controller_container.rb
81
+ - lib/action_web_service/container/delegated_container.rb
82
+ - lib/action_web_service/container/direct_container.rb
83
+ - lib/action_web_service/dispatcher/abstract.rb
84
+ - lib/action_web_service/dispatcher/action_controller_dispatcher.rb
85
+ - lib/action_web_service/protocol/abstract.rb
86
+ - lib/action_web_service/protocol/discovery.rb
87
+ - lib/action_web_service/protocol/soap_protocol
88
+ - lib/action_web_service/protocol/soap_protocol.rb
89
+ - lib/action_web_service/protocol/xmlrpc_protocol.rb
90
+ - lib/action_web_service/protocol/soap_protocol/marshaler.rb
91
+ - lib/action_web_service/support/class_inheritable_options.rb
92
+ - lib/action_web_service/support/signature_types.rb
93
+ - lib/action_web_service/templates/scaffolds
94
+ - lib/action_web_service/templates/scaffolds/layout.rhtml
95
+ - lib/action_web_service/templates/scaffolds/methods.rhtml
96
+ - lib/action_web_service/templates/scaffolds/parameters.rhtml
97
+ - lib/action_web_service/templates/scaffolds/result.rhtml
98
+ - test/abstract_client.rb
99
+ - test/abstract_dispatcher.rb
100
+ - test/abstract_unit.rb
101
+ - test/api_test.rb
102
+ - test/apis
103
+ - test/base_test.rb
104
+ - test/casting_test.rb
105
+ - test/client_soap_test.rb
106
+ - test/client_xmlrpc_test.rb
107
+ - test/container_test.rb
108
+ - test/dispatcher_action_controller_soap_test.rb
109
+ - test/dispatcher_action_controller_xmlrpc_test.rb
110
+ - test/fixtures
111
+ - test/gencov
112
+ - test/invocation_test.rb
113
+ - test/run
114
+ - test/scaffolded_controller_test.rb
115
+ - test/struct_test.rb
116
+ - test/test_invoke_test.rb
117
+ - test/apis/auto_load_api.rb
118
+ - test/apis/broken_auto_load_api.rb
119
+ - test/fixtures/db_definitions
120
+ - test/fixtures/users.yml
121
+ - test/fixtures/db_definitions/mysql.sql
119
122
  test_files: []
123
+
120
124
  rdoc_options: []
125
+
121
126
  extra_rdoc_files: []
127
+
122
128
  executables: []
129
+
123
130
  extensions: []
131
+
124
132
  requirements:
125
- - none
133
+ - none
126
134
  dependencies:
127
- - !ruby/object:Gem::Dependency
128
- name: actionpack
129
- version_requirement:
130
- version_requirements: !ruby/object:Gem::Version::Requirement
131
- requirements:
132
- -
133
- - "="
134
- - !ruby/object:Gem::Version
135
- version: 1.11.2
136
- version:
137
- - !ruby/object:Gem::Dependency
138
- name: activerecord
139
- version_requirement:
140
- version_requirements: !ruby/object:Gem::Version::Requirement
141
- requirements:
142
- -
143
- - "="
144
- - !ruby/object:Gem::Version
145
- version: 1.13.2
146
- version:
135
+ - !ruby/object:Gem::Dependency
136
+ name: actionpack
137
+ version_requirement:
138
+ version_requirements: !ruby/object:Gem::Version::Requirement
139
+ requirements:
140
+ - - "="
141
+ - !ruby/object:Gem::Version
142
+ version: 1.12.0
143
+ version:
144
+ - !ruby/object:Gem::Dependency
145
+ name: activerecord
146
+ version_requirement:
147
+ version_requirements: !ruby/object:Gem::Version::Requirement
148
+ requirements:
149
+ - - "="
150
+ - !ruby/object:Gem::Version
151
+ version: 1.14.0
152
+ version: