activeresource 2.0.2 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activeresource might be problematic. Click here for more details.
- data/CHANGELOG +15 -0
- data/Rakefile +4 -3
- data/lib/active_resource.rb +1 -1
- data/lib/active_resource/base.rb +48 -25
- data/lib/active_resource/custom_methods.rb +58 -44
- data/lib/active_resource/http_mock.rb +6 -7
- data/lib/active_resource/version.rb +1 -1
- data/test/authorization_test.rb +3 -4
- data/test/base/load_test.rb +35 -0
- data/test/connection_test.rb +0 -1
- data/test/format_test.rb +41 -0
- metadata +5 -4
data/CHANGELOG
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
*2.0.4* (2nd September 2008)
|
2
|
+
|
3
|
+
* Fix small documentation typo. Closes #10670 [l.guidi]
|
4
|
+
|
5
|
+
* find_or_create_resource_for handles module nesting. #10646 [xavier]
|
6
|
+
|
7
|
+
* Allow setting ActiveResource::Base#format before #site. [rick]
|
8
|
+
|
9
|
+
* Support agnostic formats when calling custom methods. Closes #10635 [joerichsen]
|
10
|
+
|
11
|
+
* Document custom methods. #10589 [Cheah Chu Yeow]
|
12
|
+
|
13
|
+
* Ruby 1.9 compatibility. [Jeremy Kemper]
|
14
|
+
|
15
|
+
|
1
16
|
*2.0.2* (December 16th, 2007)
|
2
17
|
|
3
18
|
* Added more specific exceptions for 400, 401, and 403 (all descending from ClientError so existing rescues will work) #10326 [trek]
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ require 'rake/testtask'
|
|
4
4
|
require 'rake/rdoctask'
|
5
5
|
require 'rake/packagetask'
|
6
6
|
require 'rake/gempackagetask'
|
7
|
+
require 'rake/contrib/sshpublisher'
|
7
8
|
require 'rake/contrib/rubyforgepublisher'
|
8
9
|
require File.join(File.dirname(__FILE__), 'lib', 'active_resource', 'version')
|
9
10
|
|
@@ -63,7 +64,7 @@ spec = Gem::Specification.new do |s|
|
|
63
64
|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
64
65
|
end
|
65
66
|
|
66
|
-
s.add_dependency('activesupport', '= 2.0.
|
67
|
+
s.add_dependency('activesupport', '= 2.0.4' + PKG_BUILD)
|
67
68
|
|
68
69
|
s.require_path = 'lib'
|
69
70
|
s.autorequire = 'active_resource'
|
@@ -113,8 +114,8 @@ end
|
|
113
114
|
|
114
115
|
desc "Publish the beta gem"
|
115
116
|
task :pgem => [:package] do
|
116
|
-
Rake::SshFilePublisher.new("
|
117
|
-
`ssh
|
117
|
+
Rake::SshFilePublisher.new("david@greed.loudthinking.com", "/u/sites/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
118
|
+
`ssh david@greed.loudthinking.com '/u/sites/gems/gemupdate.sh'`
|
118
119
|
end
|
119
120
|
|
120
121
|
desc "Publish the API documentation"
|
data/lib/active_resource.rb
CHANGED
@@ -27,7 +27,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
27
27
|
unless defined?(ActiveSupport)
|
28
28
|
begin
|
29
29
|
$:.unshift(File.dirname(__FILE__) + "/../../activesupport/lib")
|
30
|
-
require 'active_support'
|
30
|
+
require 'active_support'
|
31
31
|
rescue LoadError
|
32
32
|
require 'rubygems'
|
33
33
|
gem 'activesupport'
|
data/lib/active_resource/base.rb
CHANGED
@@ -5,7 +5,7 @@ require 'set'
|
|
5
5
|
module ActiveResource
|
6
6
|
# ActiveResource::Base is the main class for mapping RESTful resources as models in a Rails application.
|
7
7
|
#
|
8
|
-
# For an outline of what Active Resource is capable of, see link:files/README.html.
|
8
|
+
# For an outline of what Active Resource is capable of, see link:files/vendor/rails/activeresource/README.html.
|
9
9
|
#
|
10
10
|
# == Automated mapping
|
11
11
|
#
|
@@ -33,7 +33,7 @@ module ActiveResource
|
|
33
33
|
# ryan.exists? #=> true
|
34
34
|
#
|
35
35
|
# ryan = Person.find(1)
|
36
|
-
# # => Resource holding our newly
|
36
|
+
# # => Resource holding our newly created Person object
|
37
37
|
#
|
38
38
|
# ryan.first = 'Rizzle'
|
39
39
|
# ryan.save #=> true
|
@@ -46,15 +46,26 @@ module ActiveResource
|
|
46
46
|
# === Custom REST methods
|
47
47
|
#
|
48
48
|
# Since simple CRUD/lifecycle methods can't accomplish every task, Active Resource also supports
|
49
|
-
# defining your own custom REST methods.
|
50
|
-
#
|
51
|
-
#
|
49
|
+
# defining your own custom REST methods. To invoke them, Active Resource provides the <tt>get</tt>,
|
50
|
+
# <tt>post</tt>, <tt>put</tt> and <tt>delete</tt> methods where you can specify a custom REST method
|
51
|
+
# name to invoke.
|
52
|
+
#
|
53
|
+
# # POST to the custom 'register' REST method, i.e. POST /people/new/register.xml.
|
54
|
+
# Person.new(:name => 'Ryan').post(:register)
|
52
55
|
# # => { :id => 1, :name => 'Ryan', :position => 'Clerk' }
|
53
56
|
#
|
57
|
+
# # PUT an update by invoking the 'promote' REST method, i.e. PUT /people/1/promote.xml?position=Manager.
|
54
58
|
# Person.find(1).put(:promote, :position => 'Manager')
|
55
59
|
# # => { :id => 1, :name => 'Ryan', :position => 'Manager' }
|
60
|
+
#
|
61
|
+
# # GET all the positions available, i.e. GET /people/positions.xml.
|
62
|
+
# Person.get(:positions)
|
63
|
+
# # => [{:name => 'Manager'}, {:name => 'Clerk'}]
|
64
|
+
#
|
65
|
+
# # DELETE to 'fire' a person, i.e. DELETE /people/1/fire.xml.
|
66
|
+
# Person.find(1).delete(:fire)
|
56
67
|
#
|
57
|
-
# For more information on
|
68
|
+
# For more information on using custom REST methods, see the
|
58
69
|
# ActiveResource::CustomMethods documentation.
|
59
70
|
#
|
60
71
|
# == Validations
|
@@ -87,12 +98,12 @@ module ActiveResource
|
|
87
98
|
# == Errors & Validation
|
88
99
|
#
|
89
100
|
# Error handling and validation is handled in much the same manner as you're used to seeing in
|
90
|
-
# Active Record. Both the response code in the
|
101
|
+
# Active Record. Both the response code in the HTTP response and the body of the response are used to
|
91
102
|
# indicate that an error occurred.
|
92
103
|
#
|
93
104
|
# === Resource errors
|
94
105
|
#
|
95
|
-
# When a
|
106
|
+
# When a GET is requested for a resource that does not exist, the HTTP <tt>404</tt> (Resource Not Found)
|
96
107
|
# response code will be returned from the server which will raise an ActiveResource::ResourceNotFound
|
97
108
|
# exception.
|
98
109
|
#
|
@@ -100,7 +111,7 @@ module ActiveResource
|
|
100
111
|
# ryan = Person.find(999) # => Raises ActiveResource::ResourceNotFound
|
101
112
|
# # => Response = 404
|
102
113
|
#
|
103
|
-
#
|
114
|
+
# <tt>404</tt> is just one of the HTTP error response codes that ActiveResource will handle with its own exception. The
|
104
115
|
# following HTTP response codes will also result in these exceptions:
|
105
116
|
#
|
106
117
|
# 200 - 399:: Valid response, no exception
|
@@ -125,8 +136,8 @@ module ActiveResource
|
|
125
136
|
#
|
126
137
|
# Active Resource supports validations on resources and will return errors if any these validations fail
|
127
138
|
# (e.g., "First name can not be blank" and so on). These types of errors are denoted in the response by
|
128
|
-
# a response code of
|
129
|
-
# then fail (with a
|
139
|
+
# a response code of <tt>422</tt> and an XML representation of the validation errors. The save operation will
|
140
|
+
# then fail (with a <tt>false</tt> return value) and the validation errors can be accessed on the resource in question.
|
130
141
|
#
|
131
142
|
# ryan = Person.find(1)
|
132
143
|
# ryan.first #=> ''
|
@@ -181,7 +192,7 @@ module ActiveResource
|
|
181
192
|
ActiveResource::Formats[mime_type_reference_or_format] : mime_type_reference_or_format
|
182
193
|
|
183
194
|
write_inheritable_attribute("format", format)
|
184
|
-
connection.format = format
|
195
|
+
connection.format = format if site
|
185
196
|
end
|
186
197
|
|
187
198
|
# Returns the current format, default is ActiveResource::Formats::XmlFormat
|
@@ -191,7 +202,7 @@ module ActiveResource
|
|
191
202
|
|
192
203
|
# An instance of ActiveResource::Connection that is the base connection to the remote service.
|
193
204
|
# The +refresh+ parameter toggles whether or not the connection is refreshed at every request
|
194
|
-
# or not (defaults to
|
205
|
+
# or not (defaults to <tt>false</tt>).
|
195
206
|
def connection(refresh = false)
|
196
207
|
if defined?(@connection) || superclass == Object
|
197
208
|
@connection = Connection.new(site, format) if refresh || @connection.nil?
|
@@ -372,6 +383,9 @@ module ActiveResource
|
|
372
383
|
# Person.find(:one, :from => :leader)
|
373
384
|
# # => GET /people/leader.xml
|
374
385
|
#
|
386
|
+
# Person.find(:all, :from => :developers, :params => { :language => 'ruby' })
|
387
|
+
# # => GET /people/developers.xml?language=ruby
|
388
|
+
#
|
375
389
|
# Person.find(:one, :from => "/companies/1/manager.xml")
|
376
390
|
# # => GET /companies/1/manager.xml
|
377
391
|
#
|
@@ -687,9 +701,9 @@ module ActiveResource
|
|
687
701
|
#
|
688
702
|
# indent:: Set the indent level for the XML output (default is +2+).
|
689
703
|
# dasherize:: Boolean option to determine whether or not element names should
|
690
|
-
# replace underscores with dashes (default is
|
704
|
+
# replace underscores with dashes (default is <tt>false</tt>).
|
691
705
|
# skip_instruct:: Toggle skipping the +instruct!+ call on the XML builder
|
692
|
-
# that generates the XML declaration (default is
|
706
|
+
# that generates the XML declaration (default is <tt>false</tt>).
|
693
707
|
#
|
694
708
|
# ==== Examples
|
695
709
|
# my_group = SubsidiaryGroup.find(:first)
|
@@ -769,8 +783,8 @@ module ActiveResource
|
|
769
783
|
alias_method :respond_to_without_attributes?, :respond_to?
|
770
784
|
|
771
785
|
# A method to determine if an object responds to a message (e.g., a method call). In Active Resource, a +Person+ object with a
|
772
|
-
# +name+ attribute can answer
|
773
|
-
#
|
786
|
+
# +name+ attribute can answer <tt>true</tt> to <tt>my_person.respond_to?("name")</tt>, <tt>my_person.respond_to?("name=")</tt>, and
|
787
|
+
# <tt>my_person.respond_to?("name?")</tt>.
|
774
788
|
def respond_to?(method, include_priv = false)
|
775
789
|
method_name = method.to_s
|
776
790
|
if attributes.nil?
|
@@ -831,17 +845,26 @@ module ActiveResource
|
|
831
845
|
find_or_create_resource_for(name.to_s.singularize)
|
832
846
|
end
|
833
847
|
|
848
|
+
# Tries to find a resource in a non empty list of nested modules
|
849
|
+
# Raises a NameError if it was not found in any of the given nested modules
|
850
|
+
def find_resource_in_modules(resource_name, module_names)
|
851
|
+
receiver = Object
|
852
|
+
namespaces = module_names[0, module_names.size-1].map do |module_name|
|
853
|
+
receiver = receiver.const_get(module_name)
|
854
|
+
end
|
855
|
+
if namespace = namespaces.reverse.detect { |ns| ns.const_defined?(resource_name) }
|
856
|
+
return namespace.const_get(resource_name)
|
857
|
+
else
|
858
|
+
raise NameError
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
834
862
|
# Tries to find a resource for a given name; if it fails, then the resource is created
|
835
863
|
def find_or_create_resource_for(name)
|
836
864
|
resource_name = name.to_s.camelize
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
begin
|
841
|
-
ancestors.first.constantize.const_get(resource_name)
|
842
|
-
rescue NameError
|
843
|
-
self.class.const_get(resource_name)
|
844
|
-
end
|
865
|
+
ancestors = self.class.name.split("::")
|
866
|
+
if ancestors.size > 1
|
867
|
+
find_resource_in_modules(resource_name, ancestors)
|
845
868
|
else
|
846
869
|
self.class.const_get(resource_name)
|
847
870
|
end
|
@@ -1,59 +1,73 @@
|
|
1
|
-
# A module to support custom REST methods and sub-resources, allowing you to break out
|
2
|
-
# of the "default" REST methods with your own custom resource requests. For example,
|
3
|
-
# say you use Rails to expose a REST service and configure your routes with:
|
4
|
-
#
|
5
|
-
# map.resources :people, :new => { :register => :post },
|
6
|
-
# :element => { :promote => :put, :deactivate => :delete }
|
7
|
-
# :collection => { :active => :get }
|
8
|
-
#
|
9
|
-
# This route set creates routes for the following http requests:
|
10
|
-
#
|
11
|
-
# POST /people/new/register.xml #=> PeopleController.register
|
12
|
-
# PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
|
13
|
-
# DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
|
14
|
-
# GET /people/active.xml #=> PeopleController.active
|
15
|
-
#
|
16
|
-
# Using this module, Active Resource can use these custom REST methods just like the
|
17
|
-
# standard methods.
|
18
|
-
#
|
19
|
-
# class Person < ActiveResource::Base
|
20
|
-
# self.site = "http://37s.sunrise.i:3000"
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
|
24
|
-
# # => { :id => 1, :name => 'Ryan' }
|
25
|
-
#
|
26
|
-
# Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
|
27
|
-
# Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
|
28
|
-
#
|
29
|
-
# Person.get(:active) # GET /people/active.xml
|
30
|
-
# # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
|
31
|
-
#
|
32
1
|
module ActiveResource
|
2
|
+
# A module to support custom REST methods and sub-resources, allowing you to break out
|
3
|
+
# of the "default" REST methods with your own custom resource requests. For example,
|
4
|
+
# say you use Rails to expose a REST service and configure your routes with:
|
5
|
+
#
|
6
|
+
# map.resources :people, :new => { :register => :post },
|
7
|
+
# :member => { :promote => :put, :deactivate => :delete }
|
8
|
+
# :collection => { :active => :get }
|
9
|
+
#
|
10
|
+
# This route set creates routes for the following http requests:
|
11
|
+
#
|
12
|
+
# POST /people/new/register.xml #=> PeopleController.register
|
13
|
+
# PUT /people/1/promote.xml #=> PeopleController.promote with :id => 1
|
14
|
+
# DELETE /people/1/deactivate.xml #=> PeopleController.deactivate with :id => 1
|
15
|
+
# GET /people/active.xml #=> PeopleController.active
|
16
|
+
#
|
17
|
+
# Using this module, Active Resource can use these custom REST methods just like the
|
18
|
+
# standard methods.
|
19
|
+
#
|
20
|
+
# class Person < ActiveResource::Base
|
21
|
+
# self.site = "http://37s.sunrise.i:3000"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Person.new(:name => 'Ryan).post(:register) # POST /people/new/register.xml
|
25
|
+
# # => { :id => 1, :name => 'Ryan' }
|
26
|
+
#
|
27
|
+
# Person.find(1).put(:promote, :position => 'Manager') # PUT /people/1/promote.xml
|
28
|
+
# Person.find(1).delete(:deactivate) # DELETE /people/1/deactivate.xml
|
29
|
+
#
|
30
|
+
# Person.get(:active) # GET /people/active.xml
|
31
|
+
# # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
|
32
|
+
#
|
33
33
|
module CustomMethods
|
34
|
-
def self.included(
|
35
|
-
|
34
|
+
def self.included(base)
|
35
|
+
base.class_eval do
|
36
36
|
extend ActiveResource::CustomMethods::ClassMethods
|
37
37
|
include ActiveResource::CustomMethods::InstanceMethods
|
38
38
|
|
39
39
|
class << self
|
40
40
|
alias :orig_delete :delete
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
# Invokes a GET to a given custom REST method. For example:
|
43
|
+
#
|
44
|
+
# Person.get(:active) # GET /people/active.xml
|
45
|
+
# # => [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}]
|
46
|
+
#
|
47
|
+
# Person.get(:active, :awesome => true) # GET /people/active.xml?awesome=true
|
48
|
+
# # => [{:id => 1, :name => 'Ryan'}]
|
49
|
+
#
|
50
|
+
# Note: the objects returned from this method are not automatically converted
|
51
|
+
# into ActiveResource instances - they are ordinary Hashes. If you are expecting
|
52
|
+
# ActiveResource instances, use the <tt>find</tt> class method with the
|
53
|
+
# <tt>:from</tt> option. For example:
|
54
|
+
#
|
55
|
+
# Person.find(:all, :from => :active)
|
56
|
+
def get(custom_method_name, options = {})
|
57
|
+
connection.get(custom_method_collection_url(custom_method_name, options), headers)
|
44
58
|
end
|
45
59
|
|
46
|
-
def post(
|
47
|
-
connection.post(custom_method_collection_url(
|
60
|
+
def post(custom_method_name, options = {}, body = '')
|
61
|
+
connection.post(custom_method_collection_url(custom_method_name, options), body, headers)
|
48
62
|
end
|
49
63
|
|
50
|
-
def put(
|
51
|
-
connection.put(custom_method_collection_url(
|
64
|
+
def put(custom_method_name, options = {}, body = '')
|
65
|
+
connection.put(custom_method_collection_url(custom_method_name, options), body, headers)
|
52
66
|
end
|
53
67
|
|
54
|
-
# Need to jump through some hoops to retain the original class 'delete' method
|
55
68
|
def delete(custom_method_name, options = {})
|
56
|
-
|
69
|
+
# Need to jump through some hoops to retain the original class 'delete' method
|
70
|
+
if custom_method_name.is_a?(Symbol)
|
57
71
|
connection.delete(custom_method_collection_url(custom_method_name, options), headers)
|
58
72
|
else
|
59
73
|
orig_delete(custom_method_name, options)
|
@@ -66,7 +80,7 @@ module ActiveResource
|
|
66
80
|
module ClassMethods
|
67
81
|
def custom_method_collection_url(method_name, options = {})
|
68
82
|
prefix_options, query_options = split_options(options)
|
69
|
-
"#{prefix(prefix_options)}#{collection_name}/#{method_name}.
|
83
|
+
"#{prefix(prefix_options)}#{collection_name}/#{method_name}.#{format.extension}#{query_string(query_options)}"
|
70
84
|
end
|
71
85
|
end
|
72
86
|
|
@@ -94,11 +108,11 @@ module ActiveResource
|
|
94
108
|
|
95
109
|
private
|
96
110
|
def custom_method_element_url(method_name, options = {})
|
97
|
-
"#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.
|
111
|
+
"#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
|
98
112
|
end
|
99
113
|
|
100
114
|
def custom_method_new_element_url(method_name, options = {})
|
101
|
-
"#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.
|
115
|
+
"#{self.class.prefix(prefix_options)}#{self.class.collection_name}/new/#{method_name}.#{self.class.format.extension}#{self.class.send!(:query_string, options)}"
|
102
116
|
end
|
103
117
|
end
|
104
118
|
end
|
@@ -10,7 +10,7 @@ module ActiveResource
|
|
10
10
|
end
|
11
11
|
|
12
12
|
for method in [ :post, :put, :get, :delete ]
|
13
|
-
module_eval <<-EOE
|
13
|
+
module_eval <<-EOE, __FILE__, __LINE__
|
14
14
|
def #{method}(path, request_headers = {}, body = nil, status = 200, response_headers = {})
|
15
15
|
@responses[Request.new(:#{method}, path, nil, request_headers)] = Response.new(body || "", status, response_headers)
|
16
16
|
end
|
@@ -47,21 +47,21 @@ module ActiveResource
|
|
47
47
|
end
|
48
48
|
|
49
49
|
for method in [ :post, :put ]
|
50
|
-
module_eval <<-EOE
|
50
|
+
module_eval <<-EOE, __FILE__, __LINE__
|
51
51
|
def #{method}(path, body, headers)
|
52
52
|
request = ActiveResource::Request.new(:#{method}, path, body, headers)
|
53
53
|
self.class.requests << request
|
54
|
-
self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for
|
54
|
+
self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for \#{request}"))
|
55
55
|
end
|
56
56
|
EOE
|
57
57
|
end
|
58
58
|
|
59
59
|
for method in [ :get, :delete ]
|
60
|
-
module_eval <<-EOE
|
60
|
+
module_eval <<-EOE, __FILE__, __LINE__
|
61
61
|
def #{method}(path, headers)
|
62
62
|
request = ActiveResource::Request.new(:#{method}, path, nil, headers)
|
63
63
|
self.class.requests << request
|
64
|
-
self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for
|
64
|
+
self.class.responses[request] || raise(InvalidRequestError.new("No response recorded for \#{request}"))
|
65
65
|
end
|
66
66
|
EOE
|
67
67
|
end
|
@@ -75,8 +75,7 @@ module ActiveResource
|
|
75
75
|
attr_accessor :path, :method, :body, :headers
|
76
76
|
|
77
77
|
def initialize(method, path, body = nil, headers = {})
|
78
|
-
@method, @path, @body, @headers = method, path, body, headers.
|
79
|
-
@headers.update('Content-Type' => 'application/xml')
|
78
|
+
@method, @path, @body, @headers = method, path, body, headers.reverse_merge('Content-Type' => 'application/xml')
|
80
79
|
end
|
81
80
|
|
82
81
|
def ==(other_request)
|
data/test/authorization_test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require "#{File.dirname(__FILE__)}/abstract_unit"
|
2
|
-
require 'base64'
|
3
2
|
|
4
3
|
class AuthorizationTest < Test::Unit::TestCase
|
5
4
|
Response = Struct.new(:code)
|
@@ -25,7 +24,7 @@ class AuthorizationTest < Test::Unit::TestCase
|
|
25
24
|
authorization = authorization_header["Authorization"].to_s.split
|
26
25
|
|
27
26
|
assert_equal "Basic", authorization[0]
|
28
|
-
assert_equal ["david", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
|
27
|
+
assert_equal ["david", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
29
28
|
end
|
30
29
|
|
31
30
|
def test_authorization_header_with_username_but_no_password
|
@@ -34,7 +33,7 @@ class AuthorizationTest < Test::Unit::TestCase
|
|
34
33
|
authorization = authorization_header["Authorization"].to_s.split
|
35
34
|
|
36
35
|
assert_equal "Basic", authorization[0]
|
37
|
-
assert_equal ["david"], Base64.decode64(authorization[1]).split(":")[0..1]
|
36
|
+
assert_equal ["david"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
38
37
|
end
|
39
38
|
|
40
39
|
def test_authorization_header_with_password_but_no_username
|
@@ -43,7 +42,7 @@ class AuthorizationTest < Test::Unit::TestCase
|
|
43
42
|
authorization = authorization_header["Authorization"].to_s.split
|
44
43
|
|
45
44
|
assert_equal "Basic", authorization[0]
|
46
|
-
assert_equal ["", "test123"], Base64.decode64(authorization[1]).split(":")[0..1]
|
45
|
+
assert_equal ["", "test123"], ActiveSupport::Base64.decode64(authorization[1]).split(":")[0..1]
|
47
46
|
end
|
48
47
|
|
49
48
|
def test_get
|
data/test/base/load_test.rb
CHANGED
@@ -10,6 +10,29 @@ module Highrise
|
|
10
10
|
class Comment < ActiveResource::Base
|
11
11
|
self.site = "http://37s.sunrise.i:3000"
|
12
12
|
end
|
13
|
+
|
14
|
+
module Deeply
|
15
|
+
module Nested
|
16
|
+
|
17
|
+
class Note < ActiveResource::Base
|
18
|
+
self.site = "http://37s.sunrise.i:3000"
|
19
|
+
end
|
20
|
+
|
21
|
+
class Comment < ActiveResource::Base
|
22
|
+
self.site = "http://37s.sunrise.i:3000"
|
23
|
+
end
|
24
|
+
|
25
|
+
module TestDifferentLevels
|
26
|
+
|
27
|
+
class Note < ActiveResource::Base
|
28
|
+
self.site = "http://37s.sunrise.i:3000"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
13
36
|
end
|
14
37
|
|
15
38
|
|
@@ -108,4 +131,16 @@ class BaseLoadTest < Test::Unit::TestCase
|
|
108
131
|
n = Highrise::Note.new(:comments => [{ :name => "1" }])
|
109
132
|
assert_kind_of Highrise::Comment, n.comments.first
|
110
133
|
end
|
134
|
+
|
135
|
+
def test_nested_collections_within_deeply_nested_namespace
|
136
|
+
n = Highrise::Deeply::Nested::Note.new(:comments => [{ :name => "1" }])
|
137
|
+
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_nested_collections_in_different_levels_of_namespaces
|
141
|
+
n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(:comments => [{ :name => "1" }])
|
142
|
+
assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
|
143
|
+
end
|
144
|
+
|
145
|
+
|
111
146
|
end
|
data/test/connection_test.rb
CHANGED
data/test/format_test.rb
CHANGED
@@ -29,6 +29,47 @@ class FormatTest < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_formats_on_custom_collection_method
|
33
|
+
for format in [ :json, :xml ]
|
34
|
+
using_format(Person, format) do
|
35
|
+
ActiveResource::HttpMock.respond_to.get "/people/retrieve.#{format}?name=David", {}, ActiveResource::Formats[format].encode([@david])
|
36
|
+
remote_programmers = Person.get(:retrieve, :name => 'David')
|
37
|
+
assert_equal 1, remote_programmers.size
|
38
|
+
assert_equal @david[:id], remote_programmers[0]['id']
|
39
|
+
assert_equal @david[:name], remote_programmers[0]['name']
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_formats_on_custom_element_method
|
45
|
+
for format in [ :json, :xml ]
|
46
|
+
using_format(Person, format) do
|
47
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
48
|
+
mock.get "/people/2.#{format}", {}, ActiveResource::Formats[format].encode(@david)
|
49
|
+
mock.get "/people/2/shallow.#{format}", {}, ActiveResource::Formats[format].encode(@david)
|
50
|
+
end
|
51
|
+
remote_programmer = Person.find(2).get(:shallow)
|
52
|
+
assert_equal @david[:id], remote_programmer['id']
|
53
|
+
assert_equal @david[:name], remote_programmer['name']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
for format in [ :json, :xml ]
|
58
|
+
ryan = ActiveResource::Formats[format].encode({ :name => 'Ryan' })
|
59
|
+
using_format(Person, format) do
|
60
|
+
ActiveResource::HttpMock.respond_to.post "/people/new/register.#{format}", {}, ryan, 201, 'Location' => "/people/5.#{format}"
|
61
|
+
remote_ryan = Person.new(:name => 'Ryan')
|
62
|
+
assert_equal ActiveResource::Response.new(ryan, 201, {'Location' => "/people/5.#{format}"}), remote_ryan.post(:register)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_setting_format_before_site
|
68
|
+
resource = Class.new(ActiveResource::Base)
|
69
|
+
resource.format = :json
|
70
|
+
resource.site = 'http://37s.sunrise.i:3000'
|
71
|
+
assert_equal ActiveResource::Formats[:json], resource.connection.format
|
72
|
+
end
|
32
73
|
|
33
74
|
private
|
34
75
|
def using_format(klass, mime_type_reference)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activeresource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -9,17 +9,18 @@ autorequire: active_resource
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-09-03 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - "="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 2.0.
|
23
|
+
version: 2.0.4
|
23
24
|
version:
|
24
25
|
description: Wraps web resources in model classes that can be manipulated through XML over REST.
|
25
26
|
email: david@loudthinking.com
|
@@ -84,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
85
|
requirements: []
|
85
86
|
|
86
87
|
rubyforge_project: activeresource
|
87
|
-
rubygems_version: 1.
|
88
|
+
rubygems_version: 1.2.0
|
88
89
|
signing_key:
|
89
90
|
specification_version: 2
|
90
91
|
summary: Think Active Record for web resources.
|