Ticket #6979: active_resource_custom_methods_patch_unblocked_fixed_tests.diff
| File active_resource_custom_methods_patch_unblocked_fixed_tests.diff, 10.5 kB (added by rwdaigle, 2 years ago) |
|---|
-
test/base/custom_methods_test.rb
old new 1 require "#{File.dirname(__FILE__)}/../abstract_unit" 2 require "#{File.dirname(__FILE__)}/../fixtures/person" 3 require "#{File.dirname(__FILE__)}/../fixtures/street_address" 4 5 class CustomMethodsTest < Test::Unit::TestCase 6 def setup 7 @matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person') 8 @matz_deep = { :id => 1, :name => 'Matz', :other => 'other' }.to_xml(:root => 'person') 9 @ryan = { :name => 'Ryan' }.to_xml(:root => 'person') 10 @addy = { :id => 1, :street => '12345 Street' }.to_xml(:root => 'address') 11 @addy_deep = { :id => 1, :street => '12345 Street', :zip => "27519" }.to_xml(:root => 'address') 12 @default_request_headers = { 'Content-Type' => 'application/xml' } 13 14 ActiveResource::HttpMock.respond_to do |mock| 15 mock.get "/people/1.xml", {}, @matz 16 mock.get "/people/1.xml;shallow", {}, @matz 17 mock.get "/people/1.xml;deep", {}, @matz_deep 18 mock.get "/people.xml;retrieve?name=Matz", {}, "<people>#{@matz}</people>" 19 mock.put "/people/1.xml;promote?position=Manager", {}, nil, 204 20 mock.put "/people.xml;promote?name=Matz", {}, nil, 204, {} 21 mock.put "/people.xml;sort?by=name", {}, nil, 204 22 mock.delete "/people.xml;deactivate?name=Matz", {}, nil, 200 23 mock.delete "/people/1.xml;deactivate", {}, nil, 200 24 mock.post "/people.xml/new;register", {}, @ryan, 201, 'Location' => '/people/5.xml' 25 mock.get "/people/1/addresses/1.xml", {}, @addy 26 mock.get "/people/1/addresses/1.xml;deep", {}, @addy_deep 27 mock.put "/people/1/addresses/1.xml;normalize_phone?locale=US", {}, nil, 204 28 mock.put "/people/1/addresses.xml;sort?by=name", {}, nil, 204 29 mock.post "/people/1/addresses.xml/new;link", {}, { :street => '12345 Street' }.to_xml(:root => 'address'), 201, 'Location' => '/people/1/addresses/2.xml' 30 end 31 end 32 33 def test_custom_collection_method 34 35 # GET 36 assert_equal([{ "id" => 1, "name" => 'Matz' }], Person.get(:retrieve, :name => 'Matz')) 37 38 # PUT 39 assert_equal ActiveResource::Response.new({}, 204, {}), 40 Person.put(:promote, {:name => 'Matz'}, 'atestbody') 41 assert_equal ActiveResource::Response.new({}, 204, {}), Person.put(:sort, :by => 'name') 42 43 # DELETE 44 Person.delete :deactivate, :name => 'Matz' 45 46 # Nested resource 47 assert_equal ActiveResource::Response.new({}, 204, {}), StreetAddress.put(:sort, :person_id => 1, :by => 'name') 48 end 49 50 def test_custom_element_method 51 52 # Test GET against an element URL 53 assert_equal Person.find(1).get(:shallow), {"id" => 1, "name" => 'Matz'} 54 assert_equal Person.find(1).get(:deep), {"id" => 1, "name" => 'Matz', "other" => 'other'} 55 56 # Test PUT against an element URL 57 assert_equal ActiveResource::Response.new({}, 204, {}), Person.find(1).put(:promote, {:position => 'Manager'}, 'body') 58 59 # Test DELETE against an element URL 60 assert_equal ActiveResource::Response.new({}, 200, {}), Person.find(1).delete(:deactivate) 61 62 # With nested resources 63 assert_equal StreetAddress.find(1, :person_id => 1).get(:deep), 64 { "id" => 1, "street" => '12345 Street', "zip" => "27519" } 65 assert_equal ActiveResource::Response.new({}, 204, {}), 66 StreetAddress.find(1, :person_id => 1).put(:normalize_phone, :locale => 'US') 67 end 68 69 def test_custom_new_element_method 70 71 # Test POST against a new element URL 72 ryan = Person.new(:name => 'Ryan') 73 assert_equal ActiveResource::Response.new(@ryan, 201, {'Location' => '/people/5.xml'}), ryan.post(:register) 74 75 # Test POST against a nested collection URL 76 addy = StreetAddress.new({:street => '123 Test Dr.'}, {:person_id => 1}) 77 assert_equal ActiveResource::Response.new({ :street => '12345 Street' }.to_xml(:root => 'address'), 78 201, {'Location' => '/people/1/addresses/2.xml'}), 79 addy.post(:link) 80 end 81 82 def teardown 83 ActiveResource::HttpMock.reset! 84 end 85 end -
test/base_test.rb
old new 95 95 assert_equal '/people.xml?gender=', Person.collection_path(:gender => nil) 96 96 97 97 assert_equal '/people.xml?gender=male', Person.collection_path('gender' => 'male') 98 assert_equal '/people.xml?gender=male&student=true', Person.collection_path(:gender => 'male', :student => true) 98 99 # Use includes? because ordering of param hash is not guaranteed 100 assert Person.collection_path(:gender => 'male', :student => true).include?('/people.xml?') 101 assert Person.collection_path(:gender => 'male', :student => true).include?('gender=male') 102 assert Person.collection_path(:gender => 'male', :student => true).include?('student=true') 99 103 100 104 assert_equal '/people.xml?name[]=bob&name[]=your+uncle%2Bme&name[]=&name[]=false', Person.collection_path(:name => ['bob', 'your uncle+me', nil, false]) 101 105 end -
lib/active_resource/custom_methods.rb
old new 1 # Support custom REST methods, in synch with the Simply RESTful 2 # plugin. 3 # 4 # I.e. on the server routes config you would have: 5 # 6 # map.resources :people, :new => { :register => :post }, 7 # :element => { :promote => :put, :deactivate => :delete } 8 # :collection => { :active => :get } 9 # 10 # Which creates routes for the following http requests 11 # 12 # POST: /people/new;register #=> PeopleController.register 13 # PUT: /people/1;promote #=> PeopleController.promote(:id => 1) 14 # DELETE: /people/1;deactivate #=> PeopleController.deactivate(:id => 1) 15 # GET: /people;active #=> PeopleController.active 16 # 17 # This module provides the ability for ActiveResource to call these 18 # custom REST methods and get the response back. 19 # 20 # class Person < ActiveResource::Base 21 # self.site = "http://37s.sunrise.i:3000" 22 # end 23 # 24 # Person.new(:name => 'Ryan).post(:register) #=> {:id => 1, :name => 'Ryan'} 25 # 26 # Person.find(1).put(:promote, :position => 'Manager') #=> <Response::XXXX> 27 # Person.find(1).delete(:deactivate) #=> <Response::XXXX> 28 # 29 # Person.get(:active) #=> [{:id => 1, :name => 'Ryan'}, {:id => 2, :name => 'Joe'}] 30 # 31 module ActiveResource 32 module CustomMethods 33 34 def self.included(within) 35 within.class_eval do 36 class << self 37 38 include ActiveResource::CustomMethods::ClassMethods 39 40 alias :orig_delete :delete 41 42 # Define the class level Http request methods - which are tied 43 # to a call on the collection url. 44 45 def get(method_name, options = {}) 46 connection.get(custom_method_collection_url(method_name, options)) 47 end 48 49 def post(method_name, options = {}, body = nil) 50 connection.post(custom_method_collection_url(method_name, options), body) 51 end 52 53 def put(method_name, options = {}, body = nil) 54 connection.put(custom_method_collection_url(method_name, options), body) 55 end 56 57 # Need to jump through some hoops to retain the original class 'delete' method 58 def delete(custom_method_name, options = {}) 59 if(custom_method_name.is_a?(Symbol)) 60 connection.delete(custom_method_collection_url(custom_method_name, options)) 61 else 62 orig_delete(custom_method_name) 63 end 64 end 65 end 66 67 end 68 69 within.send(:include, ActiveResource::CustomMethods::InstanceMethods) 70 end 71 72 module ClassMethods 73 def custom_method_collection_url(method_name, options = {}) 74 "#{prefix(options)}#{collection_name}.xml;#{method_name}#{query_string(options)}" 75 end 76 end 77 78 module InstanceMethods 79 80 def get(method_name, options = {}) 81 connection.get(custom_method_element_url(method_name, options)) 82 end 83 84 def post(method_name, options = {}, body = nil) 85 if(new?) 86 connection.post(custom_method_new_element_url(method_name, options), 87 (body.nil? ? to_xml : body)) 88 else 89 connection.post(custom_method_element_url(method_name, options), body) 90 end 91 end 92 93 def put(method_name, options = {}, body = nil) 94 connection.put(custom_method_element_url(method_name, options), body) 95 end 96 97 def delete(method_name, options = {}) 98 connection.delete(custom_method_element_url(method_name, options)) 99 end 100 101 private 102 103 def custom_method_element_url(method_name, options = {}) 104 "#{self.class.prefix(prefix_options)}#{self.class.collection_name}/#{id}.xml;#{method_name}#{self.class.send(:query_string, options)}" 105 end 106 107 def custom_method_new_element_url(method_name, options = {}) 108 "#{self.class.prefix(prefix_options)}#{self.class.collection_name}.xml/new;#{method_name}#{self.class.send(:query_string, options)}" 109 end 110 end 111 end 112 113 end -
lib/active_resource/http_mock.rb
old new 110 110 def []=(key, value) 111 111 headers[key] = value 112 112 end 113 114 def ==(other) 115 if(other.is_a?(Response)) 116 other.body == body && other.message == message && other.headers == headers 117 else 118 false 119 end 120 end 113 121 end 114 122 115 123 class Connection -
lib/active_resource.rb
old new 37 37 require 'active_resource/base' 38 38 require 'active_resource/struct' 39 39 require 'active_resource/validations' 40 require 'active_resource/custom_methods' 40 41 41 42 module ActiveResource 42 43 Base.class_eval do 43 44 include Validations 45 include CustomMethods 44 46 end 45 47 end