api_resource 0.4.0 → 0.4.1
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.
- metadata +179 -123
- data/.document +0 -5
- data/.rspec +0 -5
- data/.travis.yml +0 -4
- data/Gemfile +0 -37
- data/Gemfile.lock +0 -190
- data/Guardfile +0 -27
- data/Rakefile +0 -49
- data/VERSION +0 -1
- data/api_resource.gemspec +0 -180
- data/lib/api_resource.rb +0 -130
- data/lib/api_resource/association_activation.rb +0 -19
- data/lib/api_resource/associations.rb +0 -218
- data/lib/api_resource/associations/association_proxy.rb +0 -116
- data/lib/api_resource/associations/belongs_to_remote_object_proxy.rb +0 -16
- data/lib/api_resource/associations/dynamic_resource_scope.rb +0 -23
- data/lib/api_resource/associations/generic_scope.rb +0 -68
- data/lib/api_resource/associations/has_many_remote_object_proxy.rb +0 -16
- data/lib/api_resource/associations/has_many_through_remote_object_proxy.rb +0 -13
- data/lib/api_resource/associations/has_one_remote_object_proxy.rb +0 -24
- data/lib/api_resource/associations/multi_argument_resource_scope.rb +0 -15
- data/lib/api_resource/associations/multi_object_proxy.rb +0 -84
- data/lib/api_resource/associations/related_object_hash.rb +0 -12
- data/lib/api_resource/associations/relation_scope.rb +0 -25
- data/lib/api_resource/associations/resource_scope.rb +0 -32
- data/lib/api_resource/associations/scope.rb +0 -132
- data/lib/api_resource/associations/single_object_proxy.rb +0 -82
- data/lib/api_resource/attributes.rb +0 -243
- data/lib/api_resource/base.rb +0 -717
- data/lib/api_resource/callbacks.rb +0 -45
- data/lib/api_resource/connection.rb +0 -195
- data/lib/api_resource/core_extensions.rb +0 -7
- data/lib/api_resource/custom_methods.rb +0 -117
- data/lib/api_resource/decorators.rb +0 -6
- data/lib/api_resource/decorators/caching_decorator.rb +0 -20
- data/lib/api_resource/exceptions.rb +0 -99
- data/lib/api_resource/formats.rb +0 -22
- data/lib/api_resource/formats/json_format.rb +0 -25
- data/lib/api_resource/formats/xml_format.rb +0 -36
- data/lib/api_resource/local.rb +0 -12
- data/lib/api_resource/log_subscriber.rb +0 -15
- data/lib/api_resource/mocks.rb +0 -277
- data/lib/api_resource/model_errors.rb +0 -82
- data/lib/api_resource/observing.rb +0 -27
- data/lib/api_resource/railtie.rb +0 -24
- data/lib/api_resource/scopes.rb +0 -48
- data/nohup.out +0 -63
- data/spec/lib/api_resource_spec.rb +0 -43
- data/spec/lib/associations_spec.rb +0 -751
- data/spec/lib/attributes_spec.rb +0 -191
- data/spec/lib/base_spec.rb +0 -655
- data/spec/lib/callbacks_spec.rb +0 -68
- data/spec/lib/connection_spec.rb +0 -137
- data/spec/lib/local_spec.rb +0 -20
- data/spec/lib/mocks_spec.rb +0 -45
- data/spec/lib/model_errors_spec.rb +0 -29
- data/spec/lib/prefixes_spec.rb +0 -107
- data/spec/spec_helper.rb +0 -82
- data/spec/support/mocks/association_mocks.rb +0 -63
- data/spec/support/mocks/error_resource_mocks.rb +0 -21
- data/spec/support/mocks/prefix_model_mocks.rb +0 -5
- data/spec/support/mocks/test_resource_mocks.rb +0 -44
- data/spec/support/requests/association_requests.rb +0 -31
- data/spec/support/requests/error_resource_requests.rb +0 -25
- data/spec/support/requests/prefix_model_requests.rb +0 -7
- data/spec/support/requests/test_resource_requests.rb +0 -38
- data/spec/support/test_resource.rb +0 -72
- data/spec/tmp/DIR +0 -0
@@ -1,27 +0,0 @@
|
|
1
|
-
module ApiResource
|
2
|
-
|
3
|
-
module Observing
|
4
|
-
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
include ActiveModel::Observing
|
7
|
-
|
8
|
-
# Redefine these methods to
|
9
|
-
included do
|
10
|
-
%w( create save update destroy ).each do |method|
|
11
|
-
alias_method_chain method, :observers
|
12
|
-
end
|
13
|
-
|
14
|
-
%w( create save update destroy ).each do |method|
|
15
|
-
module_eval <<-EOE, __FILE__, __LINE__ + 1
|
16
|
-
def #{method}_with_observers(*args)
|
17
|
-
notify_observers(:before_#method)
|
18
|
-
if result = #{method}_without_observers(*args)
|
19
|
-
notify_observers(:after_#{method})
|
20
|
-
end
|
21
|
-
return result
|
22
|
-
end
|
23
|
-
EOE
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
data/lib/api_resource/railtie.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'api_resource'
|
2
|
-
require 'rails'
|
3
|
-
|
4
|
-
module ApiResource
|
5
|
-
|
6
|
-
class Railtie < ::Rails::Railtie
|
7
|
-
|
8
|
-
config.api_resource = ActiveSupport::OrderedOptions.new
|
9
|
-
|
10
|
-
initializer "api_resource.set_configs" do |app|
|
11
|
-
app.config.api_resource.each do |k,v|
|
12
|
-
ApiResource::Base.send "#{k}=", v
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
initializer "api_resource.activate_associations" do
|
17
|
-
ActiveSupport.on_load(:active_record) do
|
18
|
-
ApiResource::Associations.activate_active_record
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
data/lib/api_resource/scopes.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
module ApiResource
|
2
|
-
module Scopes
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
|
6
|
-
module ClassMethods
|
7
|
-
def scopes
|
8
|
-
return self.related_objects[:scopes]
|
9
|
-
end
|
10
|
-
|
11
|
-
# Called by base.rb
|
12
|
-
# @param name is the name of the scope from the json
|
13
|
-
# @param hsh is always a hash with the arguments for the scope
|
14
|
-
def scope(name, hsh)
|
15
|
-
raise ArgumentError, "Expecting an attributes hash given #{hsh.inspect}" unless hsh.is_a?(Hash)
|
16
|
-
self.related_objects[:scopes][name.to_sym] = hsh
|
17
|
-
# we also need to define a class method for each scope
|
18
|
-
self.instance_eval <<-EOE, __FILE__, __LINE__ + 1
|
19
|
-
def #{name}(*args)
|
20
|
-
return #{ApiResource::Associations::ResourceScope.class_factory(hsh)}.new(self, :#{name}, *args)
|
21
|
-
end
|
22
|
-
EOE
|
23
|
-
end
|
24
|
-
|
25
|
-
def scope?(name)
|
26
|
-
self.related_objects[:scopes][name.to_sym].present?
|
27
|
-
end
|
28
|
-
|
29
|
-
def scope_attributes(name)
|
30
|
-
raise "No such scope #{name}" unless self.scope?(name)
|
31
|
-
self.related_objects[:scopes][name.to_sym]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def scopes
|
36
|
-
return self.class.scopes
|
37
|
-
end
|
38
|
-
|
39
|
-
def scope?(name)
|
40
|
-
return self.class.scope?(name)
|
41
|
-
end
|
42
|
-
|
43
|
-
def scope_attributes(name)
|
44
|
-
return self.class.scope_attributes(name)
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
data/nohup.out
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/choice-0.1.4/lib/choice/parser.rb:108: warning: Hash#index is deprecated; use Hash#key
|
2
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
3
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid 18804 exit 2> (RuntimeError)
|
4
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:96:in `project_path='
|
5
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
6
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:86:in `start'
|
7
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/bin/cijoe:50:in `<top (required)>'
|
8
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `load'
|
9
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `<main>'
|
10
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/choice-0.1.4/lib/choice/parser.rb:108: warning: Hash#index is deprecated; use Hash#key
|
11
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
12
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid 19377 exit 2> (RuntimeError)
|
13
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:96:in `project_path='
|
14
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
15
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:86:in `start'
|
16
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/bin/cijoe:50:in `<top (required)>'
|
17
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `load'
|
18
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `<main>'
|
19
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/choice-0.1.4/lib/choice/parser.rb:108: warning: Hash#index is deprecated; use Hash#key
|
20
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
21
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid 19463 exit 2> (RuntimeError)
|
22
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:96:in `project_path='
|
23
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
24
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:86:in `start'
|
25
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/bin/cijoe:50:in `<top (required)>'
|
26
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `load'
|
27
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `<main>'
|
28
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/choice-0.1.4/lib/choice/parser.rb:108: warning: Hash#index is deprecated; use Hash#key
|
29
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
30
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid 19730 exit 2> (RuntimeError)
|
31
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:96:in `project_path='
|
32
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
33
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:86:in `start'
|
34
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/bin/cijoe:50:in `<top (required)>'
|
35
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `load'
|
36
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `<main>'
|
37
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/choice-0.1.4/lib/choice/parser.rb:108: warning: Hash#index is deprecated; use Hash#key
|
38
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
39
|
-
/home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid 19738 exit 2> (RuntimeError)
|
40
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:96:in `project_path='
|
41
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
42
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/lib/cijoe/server.rb:86:in `start'
|
43
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/gems/cijoe-0.9.2/bin/cijoe:50:in `<top (required)>'
|
44
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `load'
|
45
|
-
from /home/bb/.rvm/gems/ruby-1.9.2-p290/bin/cijoe:19:in `<main>'
|
46
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
47
|
-
/usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid=19748,exited(2)> (RuntimeError)
|
48
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/server.rb:96:in `project_path='
|
49
|
-
from /usr/lib/ruby/gems/1.8/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `__send__'
|
50
|
-
from /usr/lib/ruby/gems/1.8/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
51
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/server.rb:86:in `start'
|
52
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/cijoe:50
|
53
|
-
from /usr/bin/cijoe:19:in `load'
|
54
|
-
from /usr/bin/cijoe:19
|
55
|
-
cd: 1: can't cd to /vol/www/releases/api_resource/api_resource
|
56
|
-
/usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/config.rb:25:in `to_s': Error calling git config, is a recent version of git installed? Command: "cd /vol/www/releases/api_resource/api_resource && git config cijoe.user", Error: "", Status: #<Process::Status: pid=19909,exited(2)> (RuntimeError)
|
57
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/server.rb:96:in `project_path='
|
58
|
-
from /usr/lib/ruby/gems/1.8/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `__send__'
|
59
|
-
from /usr/lib/ruby/gems/1.8/gems/sinatra-1.2.7/lib/sinatra/base.rb:964:in `set'
|
60
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/../lib/cijoe/server.rb:86:in `start'
|
61
|
-
from /usr/lib/ruby/gems/1.8/gems/cijoe-0.9.2/bin/cijoe:50
|
62
|
-
from /usr/bin/cijoe:19:in `load'
|
63
|
-
from /usr/bin/cijoe:19
|
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ApiResource do
|
4
|
-
|
5
|
-
context ".cache" do
|
6
|
-
|
7
|
-
around(:each) do |example|
|
8
|
-
begin
|
9
|
-
old_rails = Object.send(:remove_const, :Rails)
|
10
|
-
example.run
|
11
|
-
ensure
|
12
|
-
Rails = old_rails
|
13
|
-
ApiResource
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should be a Rails cache if it's initialized" do
|
18
|
-
cache_stub = stub()
|
19
|
-
Rails = mock(:cache => cache_stub)
|
20
|
-
ApiResource.cache(true).should be cache_stub
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should default to an instance of memory cache" do
|
24
|
-
defined?(Rails).should be_blank
|
25
|
-
ApiResource.cache(true).should be_a(
|
26
|
-
ActiveSupport::Cache::MemoryStore
|
27
|
-
)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context ".with_ttl" do
|
32
|
-
|
33
|
-
it "should temporarily set ttl for a block" do
|
34
|
-
old_ttl = ApiResource.ttl
|
35
|
-
ApiResource.with_ttl(10) do
|
36
|
-
ApiResource.ttl.should eql(10)
|
37
|
-
end
|
38
|
-
ApiResource.ttl.should eql(old_ttl)
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
@@ -1,751 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
include ApiResource
|
4
|
-
|
5
|
-
describe "Associations" do
|
6
|
-
|
7
|
-
after(:all) do
|
8
|
-
TestResource.reload_class_attributes
|
9
|
-
end
|
10
|
-
|
11
|
-
context "creating and testing for associations of various types" do
|
12
|
-
|
13
|
-
it "should be able to give a list of all associations" do
|
14
|
-
AllAssociations = Class.new(ApiResource::Base)
|
15
|
-
AllAssociations.class_eval do
|
16
|
-
has_many :has_many_objects
|
17
|
-
belongs_to :belongs_to_object
|
18
|
-
has_one :has_one_object
|
19
|
-
end
|
20
|
-
AllAssociations.association_names.sort.should eql [:has_many_objects, :belongs_to_object, :has_one_object].sort
|
21
|
-
AllAssociations.new.association_names.sort.should eql [:has_many_objects, :belongs_to_object, :has_one_object].sort
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should be be able to define an asociation using a method named after that association type" do
|
25
|
-
TestResource.has_many :has_many_objects
|
26
|
-
TestResource.has_many?(:has_many_objects).should be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should be able to define associations with different class names" do
|
30
|
-
TestResource.has_many :test_name, :class_name => :has_many_objects
|
31
|
-
TestResource.has_many?(:test_name).should be_true
|
32
|
-
TestResource.has_many_class_name(:test_name).should eql("HasManyObject")
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should be able to define multiple associations at the same time" do
|
36
|
-
TestResource.has_many :has_many_objects, :other_has_many_objects
|
37
|
-
TestResource.has_many?(:has_many_objects).should be_true
|
38
|
-
TestResource.has_many?(:other_has_many_objects).should be_true
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should be able to tell if something is an association via the association? method" do
|
42
|
-
TestResource.belongs_to :belongs_to_object
|
43
|
-
TestResource.association?(:belongs_to_object).should be_true
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be able to get the class name of an association via the association_class_name method" do
|
47
|
-
TestResource.belongs_to :belongs_to_object
|
48
|
-
TestResource.association_class_name(:belongs_to_object).should eql("BelongsToObject")
|
49
|
-
TestResource.belongs_to :strange_name, :class_name => :belongs_to_object
|
50
|
-
TestResource.association_class_name(:strange_name).should eql("BelongsToObject")
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should only define relationships for the given class - they should not cascade" do
|
54
|
-
TestResource.belongs_to :belongs_to_object
|
55
|
-
AnotherTestResource.association?(:belongs_to_object).should_not be_true
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should have its relationship cascade when sub-classed after the relationship is defined" do
|
59
|
-
TestResource.belongs_to :belongs_to_object
|
60
|
-
class ChildTestResource2 < TestResource; end
|
61
|
-
ChildTestResource2.association?(:belongs_to_object).should be true
|
62
|
-
end
|
63
|
-
|
64
|
-
context "Determining associated classes with a namespace" do
|
65
|
-
|
66
|
-
it "should be able to find classes for associations that exist in the same module without a namespace" do
|
67
|
-
TestMod::TestClass.belongs_to :test_association
|
68
|
-
TestMod::TestClass.association_class_name(:test_association).should eql("TestMod::TestAssociation")
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should be return a regular class name for a class defined at the root level" do
|
72
|
-
TestMod::TestClass.belongs_to :belongs_to_object
|
73
|
-
TestMod::TestClass.association_class_name(:belongs_to_object).should eql("BelongsToObject")
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should work for a class name specified with a namespace module" do
|
77
|
-
TestMod::TestClass.belongs_to :nonsense, :class_name => "TestMod::TestAssociation"
|
78
|
-
TestMod::TestClass.association_class_name(:nonsense).should eql("TestMod::TestAssociation")
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should work for nested module as well" do
|
82
|
-
TestMod::InnerMod::InnerClass.belongs_to :test_association
|
83
|
-
TestMod::InnerMod::InnerClass.association_class_name(:test_association).should eql("TestMod::TestAssociation")
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should prefer to find classes within similar modules to ones in the root namespace" do
|
87
|
-
TestMod::InnerMod::InnerClass.belongs_to :test_resource
|
88
|
-
TestMod::InnerMod::InnerClass.association_class_name(:test_resource).should eql("TestMod::TestResource")
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should be able to override into the root namespace by prefixing with ::" do
|
92
|
-
TestMod::InnerMod::InnerClass.belongs_to :test_resource, :class_name => "::TestResource"
|
93
|
-
TestMod::InnerMod::InnerClass.association_class_name(:test_resource).should eql("::TestResource")
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
context "Remote Definitions" do
|
102
|
-
|
103
|
-
before(:all) do
|
104
|
-
TestResource.reload_class_attributes
|
105
|
-
end
|
106
|
-
|
107
|
-
it "should be able define an association remotely" do
|
108
|
-
TestResource.belongs_to?(:belongs_to_object).should be true
|
109
|
-
TestResource.new.belongs_to_object.klass.should eql BelongsToObject
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should be able define an association remotely" do
|
113
|
-
TestResource.belongs_to?(:custom_name).should be true
|
114
|
-
TestResource.new.custom_name.klass.should eql BelongsToObject
|
115
|
-
end
|
116
|
-
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
context "creating and testing for scopes" do
|
121
|
-
|
122
|
-
it "should be able to define scopes which require class names" do
|
123
|
-
lambda {
|
124
|
-
TestResource.scope :test_scope
|
125
|
-
}.should raise_error
|
126
|
-
TestResource.scope :test_scope, {:has_many_objects => "test"}
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should be able to test if a scope exists" do
|
130
|
-
TestResource.scope :test_scope, {:item => "test"}
|
131
|
-
TestResource.scope?(:test_scope).should be_true
|
132
|
-
TestResource.scope_attributes(:test_scope).should eql({"item" => "test"})
|
133
|
-
end
|
134
|
-
|
135
|
-
it "should not propagate scopes from one class to another" do
|
136
|
-
|
137
|
-
Scope1Class = Class.new(ApiResource::Base) do
|
138
|
-
scope :one, {:item => "test"}
|
139
|
-
end
|
140
|
-
|
141
|
-
Scope2Class = Class.new(ApiResource::Base) do
|
142
|
-
scope :two, {:abc => "def"}
|
143
|
-
end
|
144
|
-
|
145
|
-
Scope1Class.scope?(:one).should be true
|
146
|
-
Scope1Class.scope?(:two).should be false
|
147
|
-
|
148
|
-
Scope2Class.scope?(:one).should be false
|
149
|
-
Scope2Class.scope?(:two).should be true
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
context "testing for scopes and associations on an instance" do
|
156
|
-
|
157
|
-
it "should be able to define associations on a class and test for them on an instance" do
|
158
|
-
TestResource.has_many :has_many_objects, :class_name => :other_has_many_objects
|
159
|
-
tst = TestResource.new
|
160
|
-
tst.has_many?(:has_many_objects).should be_true
|
161
|
-
tst.has_many_class_name(:has_many_objects).should eql("OtherHasManyObject")
|
162
|
-
end
|
163
|
-
|
164
|
-
it "should be able to define scopes on a class and test for them on an instance" do
|
165
|
-
TestResource.scope :has_many_objects, {:item => "test"}
|
166
|
-
tst = TestResource.new
|
167
|
-
tst.scope?(:has_many_objects).should be_true
|
168
|
-
tst.scope_attributes(:has_many_objects).should eql({"item" => "test"})
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
describe "Single Object Associations" do
|
174
|
-
|
175
|
-
before(:all) do
|
176
|
-
TestResource.reload_class_attributes
|
177
|
-
end
|
178
|
-
|
179
|
-
after(:all) do
|
180
|
-
TestResource.reload_class_attributes
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should return nil if its internal object is nil" do
|
184
|
-
ap = Associations::SingleObjectProxy.new("TestResource", {})
|
185
|
-
ap.instance_variable_set(:@internal_object, nil)
|
186
|
-
ap.blank?.should be_true
|
187
|
-
end
|
188
|
-
|
189
|
-
it "should not throw an error on serializable hash if its internal object is nil" do
|
190
|
-
ap = Associations::SingleObjectProxy.new("TestResource", {})
|
191
|
-
ap.instance_variable_set(:@internal_object, nil)
|
192
|
-
lambda {ap.serializable_hash}.should_not raise_error
|
193
|
-
end
|
194
|
-
|
195
|
-
it "should be able to create a SingleObjectProxy around a blank hash" do
|
196
|
-
ap = Associations::SingleObjectProxy.new("TestResource", {})
|
197
|
-
ap.remote_path.should be_blank
|
198
|
-
end
|
199
|
-
|
200
|
-
it "should be able to extract a service uri from the contents hash" do
|
201
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => "/path"})
|
202
|
-
ap.remote_path.should eql("/path")
|
203
|
-
end
|
204
|
-
|
205
|
-
it "should be able to recognize the attributes of an object and not make them scopes" do
|
206
|
-
TestResource.define_attributes :test
|
207
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => "/path", :test => "testval"})
|
208
|
-
ap.scope?("test").should be_false
|
209
|
-
ap.remote_path.should eql("/path")
|
210
|
-
end
|
211
|
-
|
212
|
-
it "should make all attributes except the service uri into scopes given the scopes_only option" do
|
213
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => "/path", :test_scope => {"testval" => true}, :scopes_only => true})
|
214
|
-
ap.scope?("test_scope").should be_true
|
215
|
-
ap.remote_path.should eql("/path")
|
216
|
-
end
|
217
|
-
|
218
|
-
it "should pass the attributes that are not scopes and make them attributes of the object" do
|
219
|
-
TestResource.define_attributes :test
|
220
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => "/path", :test => "testval"})
|
221
|
-
ap.internal_object.attributes.keys.should include("test")
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
describe "Multi Object Associations" do
|
226
|
-
|
227
|
-
before(:all) do
|
228
|
-
TestResource.related_objects[:scopes].clear
|
229
|
-
end
|
230
|
-
|
231
|
-
after(:each) do
|
232
|
-
Associations::MultiObjectProxy.remote_path_element = :service_uri
|
233
|
-
end
|
234
|
-
|
235
|
-
describe "Loading settings" do
|
236
|
-
|
237
|
-
context "Loading array contents" do
|
238
|
-
|
239
|
-
it "should be able to load a blank array" do
|
240
|
-
ap = Associations::MultiObjectProxy.new("TestResource",[])
|
241
|
-
ap.remote_path.should be_nil
|
242
|
-
ap.scopes.keys.should eql([])
|
243
|
-
end
|
244
|
-
|
245
|
-
it "should be able to recognize a settings hash if it has a service_uri" do
|
246
|
-
ap = Associations::MultiObjectProxy.new("TestResource",[{:service_uri => "/route"}])
|
247
|
-
ap.remote_path.should eql("/route")
|
248
|
-
end
|
249
|
-
|
250
|
-
it "should be able to recognize a settings hash if it has a 'service_uri' with another preset name" do
|
251
|
-
Associations::MultiObjectProxy.remote_path_element = :the_element
|
252
|
-
ap = Associations::MultiObjectProxy.new("TestResource",[{:the_element => "/route"}])
|
253
|
-
ap.remote_path.should eql("/route")
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
context "Loading hash contents" do
|
259
|
-
it "should not be able to load a hash without a 'service_uri'" do
|
260
|
-
lambda {
|
261
|
-
Associations::MultiObjectProxy.new("TestResource", {:hi => 3})
|
262
|
-
}.should raise_error
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should be able to recognize settings from a hash" do
|
266
|
-
ap = Associations::MultiObjectProxy.new("TestResource", {:service_uri => "/route"})
|
267
|
-
ap.remote_path.should eql("/route")
|
268
|
-
end
|
269
|
-
|
270
|
-
it "should recognize settings with differing 'service_uri' names" do
|
271
|
-
Associations::MultiObjectProxy.remote_path_element = :the_element
|
272
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:the_element => "/route"})
|
273
|
-
ap.remote_path.should eql("/route")
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
context "Defining scopes" do
|
278
|
-
|
279
|
-
it "should define scopes based on the other keys in a settings hash" do
|
280
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope1 => {"scope1" => true}, :scope2 => {"scope2" => true}}])
|
281
|
-
[:scope1, :scope2].each{|s| ap.scopes.include?(s).should be_true }
|
282
|
-
end
|
283
|
-
|
284
|
-
it "should identify known scopes based on the scopes defined on the object it is a proxy to" do
|
285
|
-
TestResource.scope :class_scope, "class_scope" => "true"
|
286
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope1 => {"scope1" => true}, :scope2 => {"scope2" => true}}])
|
287
|
-
[:scope1, :scope2, :class_scope].each{|s| ap.scopes.include?(s).should be_true}
|
288
|
-
end
|
289
|
-
|
290
|
-
it "scopes in the response should shadow class defined scopes" do
|
291
|
-
TestResource.scope :scope1, "scope1" => "true"
|
292
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope1 => {"scope1" => true}, :scope2 => {"scope2" => true}}])
|
293
|
-
ap.scopes[:scope1].should eql({"scope1" => true})
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
end
|
298
|
-
|
299
|
-
describe "Selecting scopes" do
|
300
|
-
|
301
|
-
before(:all) do
|
302
|
-
ScopeResource.class_eval do
|
303
|
-
scope :no_arg, {}
|
304
|
-
scope :one_arg, {:id => :req}
|
305
|
-
scope :one_array_arg, {:ids => :req}
|
306
|
-
scope :two_args, {:page => :req, :per_page => :req}
|
307
|
-
scope :opt_args, {:arg1 => :opt}
|
308
|
-
scope :var_args, {:ids => :rest}
|
309
|
-
scope :mix_args, {:id => :req, :vararg => :rest}
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
it "should be able to query scopes on the current model" do
|
314
|
-
ScopeResource.no_arg.to_query.should eql "no_arg=true"
|
315
|
-
# ScopeResource.one_arg(5).to_query.should eql "one_arg[id]=5"
|
316
|
-
# ScopeResource.one_array_arg([3, 5]).to_query.should eql "one_array_arg[ids][]=3&one_array_arg[ids][]=5"
|
317
|
-
# ScopeResource.two_args(1, 20).to_query.should eql "two_args[page]=1&two_args[per_page]=20"
|
318
|
-
# ScopeResource.opt_arg.to_query.should eql "opt_args=true"
|
319
|
-
# ScopeResource.opt_args(3).to_query.should eql "opt_args[arg1]=3"
|
320
|
-
# ScopeResource.var_args(1, 2).to_query.should eql "var_args[ids][]=1&var_args[ids][]=2"
|
321
|
-
# ScopeResource.mix_args("a", {:opt1 => 1}, {:opt2 => 2}).to_query.should eql "mix_args[arg1]=a&mix_args[vararg][][opt1]=1&mix_arg[vararg][][opt2]=2"
|
322
|
-
end
|
323
|
-
|
324
|
-
it "should be able to change scopes" do
|
325
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope1 => {"scope1" => true}, :scope2 => {"scope2" => true}}])
|
326
|
-
ap.scope1.should be_a(Associations::RelationScope)
|
327
|
-
ap.scope1.current_scope.scope1_scope?.should be_true
|
328
|
-
end
|
329
|
-
|
330
|
-
it "should be able to chain scope calls together" do
|
331
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope1 => {"scope1" => true}, :scope2 => {"scope2" => true}}])
|
332
|
-
ap.scope1.scope2.current_scope.scope1_and_scope2_scope?.should be_true
|
333
|
-
ap.scope1.scope2.to_query.should eql("scope1=true&scope2=true")
|
334
|
-
end
|
335
|
-
|
336
|
-
it "should support scopes that contain underscores" do
|
337
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope_1 => {"scope_1" => true}, :scope_2 => {"scope_2" => true}}])
|
338
|
-
ap.scope_1.scope_2.current_scope.scope_1_and_scope_2_scope?.should be_true
|
339
|
-
end
|
340
|
-
|
341
|
-
it "should be able to return the current query string" do
|
342
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope_1 => {"scope_1" => true}, :scope_2 => {"scope_2" => true}}])
|
343
|
-
ap.scope_1.scope_2.to_query.should eql("scope_1=true&scope_2=true")
|
344
|
-
end
|
345
|
-
|
346
|
-
it "should be able to substitute values into the scope query strings by passing a hash to the methods" do
|
347
|
-
ap = Associations::MultiObjectProxy.new("TestResource", [{:service_uri => "/route", :scope_1 => {"scope_1" => true, :test_sub => false}, :scope_2 => {"scope_2" => true}}])
|
348
|
-
obj = ap.scope_1(:test_sub => true).scope_2
|
349
|
-
obj.to_query.should eql("scope_1=true&scope_2=true&test_sub=true")
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
|
354
|
-
end
|
355
|
-
|
356
|
-
describe "Loading and Caching loaded data" do
|
357
|
-
|
358
|
-
context "Single Object" do
|
359
|
-
|
360
|
-
before(:all) do
|
361
|
-
TestResource.reload_class_attributes
|
362
|
-
end
|
363
|
-
|
364
|
-
it "should be able to force load an object" do
|
365
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :scopes_only => true})
|
366
|
-
ap.loaded.should be_blank
|
367
|
-
name = ap.name
|
368
|
-
name.should_not be_blank
|
369
|
-
ap.loaded.should_not be_blank
|
370
|
-
# Make sure it isn't reloaded
|
371
|
-
ap.name.should eql(name)
|
372
|
-
end
|
373
|
-
|
374
|
-
it "should be able to load a scope" do
|
375
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :scopes_only => true})
|
376
|
-
ap.internal_object.active.should be_false
|
377
|
-
ap.times_loaded.should eql(1)
|
378
|
-
ap.active.should be_a Associations::RelationScope
|
379
|
-
ap.active.name.should_not be_blank
|
380
|
-
ap.times_loaded.should eql(2)
|
381
|
-
ap.active.internal_object.active.should be_true
|
382
|
-
# another check that the resource wasn't reloaded
|
383
|
-
ap.times_loaded.should eql(2)
|
384
|
-
end
|
385
|
-
|
386
|
-
it "should be able to load a chain of scopes" do
|
387
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :with_birthday => {:birthday => true}, :scopes_only => true})
|
388
|
-
first = ap.active.with_birthday.id
|
389
|
-
ap.with_birthday.active.id.should eql(first)
|
390
|
-
ap.times_loaded.should eql(1)
|
391
|
-
ap.active.with_birthday.birthday.should_not be_blank
|
392
|
-
end
|
393
|
-
|
394
|
-
it "should proxy unknown methods to the object loading if it hasn't already" do
|
395
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => false}, :with_birthday => {:birthday => true}, :scopes_only => true})
|
396
|
-
ap.times_loaded.should eql(0)
|
397
|
-
ap.id.should_not be_blank
|
398
|
-
ap.times_loaded.should eql(1)
|
399
|
-
end
|
400
|
-
|
401
|
-
it "should load scopes with caching" do
|
402
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :scopes_only => true})
|
403
|
-
ap.times_loaded.should eql(0)
|
404
|
-
ap.active.expires_in(30).internal_object
|
405
|
-
ap.active.expires_in(30).internal_object
|
406
|
-
ap.times_loaded.should eql(1)
|
407
|
-
end
|
408
|
-
|
409
|
-
it "should check that ttl matches the expiration parameter" do
|
410
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :scopes_only => true})
|
411
|
-
ap.active.expires_in(10).ttl.should eql(10)
|
412
|
-
end
|
413
|
-
|
414
|
-
it "should cache scopes when caching enabled" do
|
415
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => false}, :with_birthday => {:birthday => true}, :scopes_only => true})
|
416
|
-
ApiResource.expects(:with_ttl).with(10)
|
417
|
-
ap.active(:active => true, :expires_in => 10).internal_object
|
418
|
-
end
|
419
|
-
|
420
|
-
it "should only load each distinct set of scopes once" do
|
421
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => false}, :with_birthday => {:birthday => true}, :scopes_only => true})
|
422
|
-
ap.times_loaded.should eql(0)
|
423
|
-
ap.active.with_birthday.internal_object
|
424
|
-
ap.active.with_birthday.internal_object
|
425
|
-
ap.with_birthday.active.internal_object
|
426
|
-
ap.times_loaded.should eql(1)
|
427
|
-
end
|
428
|
-
|
429
|
-
it "should be able to clear it's loading cache" do
|
430
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :with_birthday => {:birthday => true}, :scopes_only => true})
|
431
|
-
ap.active.internal_object
|
432
|
-
ap.times_loaded.should eql(1)
|
433
|
-
ap.reload
|
434
|
-
ap.active.internal_object
|
435
|
-
ap.times_loaded.should eql(1)
|
436
|
-
end
|
437
|
-
|
438
|
-
end
|
439
|
-
|
440
|
-
it "should be able to reload a single-object association" do
|
441
|
-
ap = Associations::SingleObjectProxy.new("TestResource",{:service_uri => '/single_object_association', :active => {:active => true}, :scopes_only => true})
|
442
|
-
|
443
|
-
old_name = ap.name
|
444
|
-
|
445
|
-
str = "krdflkjsd"
|
446
|
-
|
447
|
-
ap.name = str
|
448
|
-
ap.name.should eql str
|
449
|
-
ap.reload
|
450
|
-
|
451
|
-
ap.name.should eql old_name
|
452
|
-
end
|
453
|
-
|
454
|
-
it "should be able to reload a multi-object association" do
|
455
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => false}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
456
|
-
|
457
|
-
old_name = ap.first.name
|
458
|
-
|
459
|
-
str = "krdflkjsd"
|
460
|
-
|
461
|
-
ap.first.name = str
|
462
|
-
ap.first.name.should eql str
|
463
|
-
|
464
|
-
ap.reload
|
465
|
-
|
466
|
-
ap.first.name.should eql old_name
|
467
|
-
end
|
468
|
-
|
469
|
-
context "Multi Object" do
|
470
|
-
|
471
|
-
it "should be able to load 'all'" do
|
472
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => false}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
473
|
-
results = ap.all
|
474
|
-
results.size.should eql(5)
|
475
|
-
results.first.active.should be_false
|
476
|
-
end
|
477
|
-
|
478
|
-
it "should be able to load a scope" do
|
479
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => false}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
480
|
-
results = ap.active.internal_object
|
481
|
-
results.size.should eql(5)
|
482
|
-
results.first.active.should be_true
|
483
|
-
end
|
484
|
-
|
485
|
-
it "should be able to load a chain of scopes" do
|
486
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
487
|
-
results = ap.active.with_birthday.internal_object
|
488
|
-
results.first.active.should be_true
|
489
|
-
results.first.birthday.should_not be_blank
|
490
|
-
end
|
491
|
-
|
492
|
-
it "should be able to load a chain of scopes with substitution" do
|
493
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
494
|
-
results = ap.inactive(:active => true).with_birthday.internal_object
|
495
|
-
results.first.active.should be_true
|
496
|
-
results.first.birthday.should_not be_blank
|
497
|
-
end
|
498
|
-
|
499
|
-
it "should proxy unknown methods to the object array loading if it hasn't already" do
|
500
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
501
|
-
ap.first.should be_a TestResource
|
502
|
-
ap.active.first.should be_a TestResource
|
503
|
-
ap.times_loaded.should eql(2)
|
504
|
-
end
|
505
|
-
|
506
|
-
it "should only load each distinct set of scopes once" do
|
507
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
508
|
-
ap.first
|
509
|
-
ap.active.first
|
510
|
-
ap.times_loaded.should eql(2)
|
511
|
-
ap.active.first
|
512
|
-
ap.times_loaded.should eql(2)
|
513
|
-
ap.active.with_birthday.first
|
514
|
-
ap.with_birthday.active.first
|
515
|
-
ap.times_loaded.should eql(3)
|
516
|
-
end
|
517
|
-
|
518
|
-
it "should be able to clear it's loading cache" do
|
519
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
520
|
-
ap.active.first
|
521
|
-
ap.times_loaded.should eql(1)
|
522
|
-
ap.reload
|
523
|
-
ap.active.first
|
524
|
-
ap.times_loaded.should eql(1)
|
525
|
-
end
|
526
|
-
|
527
|
-
it "should be enumerable" do
|
528
|
-
ap = Associations::MultiObjectProxy.new("TestResource",{:service_uri => '/multi_object_association', :active => {:active => true}, :inactive => {:active => false}, :with_birthday => {:birthday => true}})
|
529
|
-
ap.each do |tr|
|
530
|
-
tr.name.should_not be_blank
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
end
|
535
|
-
|
536
|
-
context "Scopes" do
|
537
|
-
|
538
|
-
before(:all) do
|
539
|
-
TestResource.reload_class_attributes
|
540
|
-
end
|
541
|
-
|
542
|
-
it "should define class methods for the known scopes" do
|
543
|
-
TestResource.scopes.each do |key, _|
|
544
|
-
TestResource.should respond_to key
|
545
|
-
end
|
546
|
-
end
|
547
|
-
|
548
|
-
it "should return a ResourceScope when calling any scope on a class" do
|
549
|
-
TestResource.send(TestResource.scopes.first.first.to_sym).should be_a Associations::ResourceScope
|
550
|
-
end
|
551
|
-
|
552
|
-
it "should be able to chain scopes" do
|
553
|
-
scp = TestResource.active.paginate
|
554
|
-
scp.should be_a Associations::ResourceScope
|
555
|
-
scp.to_query.should eql("active=true&paginate=true")
|
556
|
-
end
|
557
|
-
|
558
|
-
it "should load when calling all" do
|
559
|
-
TestResource.active.should respond_to :all
|
560
|
-
TestResource.active.should respond_to :internal_object
|
561
|
-
results = TestResource.active.all
|
562
|
-
results.should be_a Array
|
563
|
-
results.size.should eql(5)
|
564
|
-
results.each do |res|
|
565
|
-
res.should be_a TestResource
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
it "should load when calling an enumerable method or an array method" do
|
570
|
-
TestResource.active.each do |result|
|
571
|
-
result.should be_a TestResource
|
572
|
-
end
|
573
|
-
end
|
574
|
-
end
|
575
|
-
|
576
|
-
context "Assigning Data" do
|
577
|
-
context "Single Object Association" do
|
578
|
-
before(:all) do
|
579
|
-
TestResource.has_one(:has_one_object)
|
580
|
-
TestResource.belongs_to(:belongs_to_object)
|
581
|
-
end
|
582
|
-
after(:all) do
|
583
|
-
TestResource.reload_class_attributes
|
584
|
-
end
|
585
|
-
|
586
|
-
it "should assign associations to the correct type on initialization" do
|
587
|
-
#binding.pry
|
588
|
-
tr = TestResource.new(:has_one_object => {:name => "Dan"}, :belongs_to_object => {:name => "Dan"})
|
589
|
-
|
590
|
-
tr.has_one_object.internal_object.should be_instance_of HasOneObject
|
591
|
-
tr.belongs_to_object.internal_object.should be_instance_of BelongsToObject
|
592
|
-
|
593
|
-
end
|
594
|
-
|
595
|
-
it "should assign associations to the correct type when setting attributes directly" do
|
596
|
-
tr = TestResource.new()
|
597
|
-
tr.has_one_object = {:name => "Dan"}
|
598
|
-
tr.belongs_to_object = {:name => "Dan"}
|
599
|
-
|
600
|
-
tr.has_one_object.internal_object.should be_instance_of HasOneObject
|
601
|
-
tr.belongs_to_object.internal_object.should be_instance_of BelongsToObject
|
602
|
-
end
|
603
|
-
|
604
|
-
it "should be able to reload a single-object association" do
|
605
|
-
ApiResource::Associations::SingleObjectProxy.any_instance.stubs(:remote_path => "/has_one_objects")
|
606
|
-
HasOneObject.connection.stubs(:get => nil)
|
607
|
-
|
608
|
-
tr = TestResource.new()
|
609
|
-
|
610
|
-
tr.has_one_object = {:color => "Blue"}
|
611
|
-
|
612
|
-
tr.has_one_object.reload
|
613
|
-
tr.has_one_object.instance_variable_get(:@internal_object).should be_blank
|
614
|
-
end
|
615
|
-
|
616
|
-
end
|
617
|
-
|
618
|
-
context "Multi Object Association" do
|
619
|
-
before(:all) do
|
620
|
-
TestResource.has_many(:has_many_objects)
|
621
|
-
end
|
622
|
-
after(:all) do
|
623
|
-
TestResource.reload_class_attributes
|
624
|
-
end
|
625
|
-
|
626
|
-
it "should assign associations to the correct type on initialization" do
|
627
|
-
tr = TestResource.new(:has_many_objects => [{:name => "Dan"}])
|
628
|
-
tr.has_many_objects.internal_object.first.should be_instance_of HasManyObject
|
629
|
-
|
630
|
-
end
|
631
|
-
|
632
|
-
it "should assign associations to the correct type when setting attributes directly" do
|
633
|
-
tr = TestResource.new()
|
634
|
-
tr.has_many_objects = [{:name => "Dan"}]
|
635
|
-
tr.has_many_objects.internal_object.first.should be_instance_of HasManyObject
|
636
|
-
end
|
637
|
-
|
638
|
-
it "should be able to reload a multi-object association" do
|
639
|
-
ApiResource::Associations::MultiObjectProxy.any_instance.stubs(:remote_path => "/has_many_objects")
|
640
|
-
ApiResource::Connection.any_instance.stubs(:get => [])
|
641
|
-
|
642
|
-
tr = TestResource.new(:has_many_objects => [{:color => "blue"}])
|
643
|
-
|
644
|
-
tr.has_many_objects.reload
|
645
|
-
|
646
|
-
tr.has_many_objects.should be_blank
|
647
|
-
end
|
648
|
-
|
649
|
-
end
|
650
|
-
|
651
|
-
context "ActiveModel" do
|
652
|
-
before(:all) do
|
653
|
-
require 'active_record'
|
654
|
-
db_path = File.expand_path(File.dirname(__FILE__) + "/../tmp/api_resource_test_db.sqlite")
|
655
|
-
ActiveRecord::Base.establish_connection({"adapter" => "sqlite3", "database" => db_path})
|
656
|
-
ActiveRecord::Base.connection.create_table(:test_ars, :force => true) do |t|
|
657
|
-
t.integer(:test_resource_id)
|
658
|
-
end
|
659
|
-
ApiResource::Associations.activate_active_record
|
660
|
-
TestAR = Class.new(ActiveRecord::Base)
|
661
|
-
TestAR.class_eval do
|
662
|
-
belongs_to_remote :my_favorite_thing, :class_name => "TestClassYay"
|
663
|
-
end
|
664
|
-
end
|
665
|
-
it "should define remote association types for AR" do
|
666
|
-
[:has_many_remote, :belongs_to_remote, :has_one_remote].each do |assoc|
|
667
|
-
ActiveRecord::Base.singleton_methods.should include assoc
|
668
|
-
end
|
669
|
-
end
|
670
|
-
it "should add remote associations to related objects" do
|
671
|
-
TestAR.related_objects.should eql({"has_many_remote"=>{}, "belongs_to_remote"=>{"my_favorite_thing"=>"TestClassYay"}, "has_one_remote"=>{}, "scopes"=>{}})
|
672
|
-
end
|
673
|
-
context "Not Overriding Scopes" do
|
674
|
-
it "should not override scopes, which would raise an error with lambda-style scopes" do
|
675
|
-
lambda {
|
676
|
-
TestAR.class_eval do
|
677
|
-
scope :my_favorite_scope, lambda {
|
678
|
-
joins(:my_test)
|
679
|
-
}
|
680
|
-
end
|
681
|
-
}.should_not raise_error
|
682
|
-
end
|
683
|
-
end
|
684
|
-
context "Belongs To" do
|
685
|
-
before(:all) do
|
686
|
-
TestAR.class_eval do
|
687
|
-
belongs_to_remote :test_resource
|
688
|
-
end
|
689
|
-
end
|
690
|
-
it "should attempt to load a single remote object for a belongs_to relationship" do
|
691
|
-
tar = TestAR.new
|
692
|
-
tar.stubs(:test_resource_id).returns(1)
|
693
|
-
TestResource.connection.expects(:get).with("/test_resources/1.json").once.returns({"name" => "testing"})
|
694
|
-
# load the test resource
|
695
|
-
tar.test_resource.name.should eql "testing"
|
696
|
-
end
|
697
|
-
end
|
698
|
-
context "Has One" do
|
699
|
-
before(:all) do
|
700
|
-
TestAR.class_eval do
|
701
|
-
has_one_remote :test_resource
|
702
|
-
end
|
703
|
-
end
|
704
|
-
it "should attempt to load a single remote object for a has_one relationship" do
|
705
|
-
tar = TestAR.new
|
706
|
-
tar.stubs(:id).returns(1)
|
707
|
-
TestResource.connection.expects(:get).with("/test_resources.json?test_ar_id=1").once.returns([{"name" => "testing"}])
|
708
|
-
# load the test resource
|
709
|
-
tar.test_resource.name.should eql "testing"
|
710
|
-
end
|
711
|
-
end
|
712
|
-
context "Has Many" do
|
713
|
-
before(:all) do
|
714
|
-
TestAR.class_eval do
|
715
|
-
has_many_remote :has_many_objects
|
716
|
-
end
|
717
|
-
end
|
718
|
-
it "should attempt to load a collection of remote objects for a has_many relationship" do
|
719
|
-
tar = TestAR.new
|
720
|
-
tar.stubs(:id).returns(1)
|
721
|
-
HasManyObject.connection.expects(:get).with("/has_many_objects.json?test_ar_id=1").once.returns([{"name" => "testing"}])
|
722
|
-
# load the test resource
|
723
|
-
tar.has_many_objects.first.name.should eql "testing"
|
724
|
-
end
|
725
|
-
end
|
726
|
-
context "Has Many Through" do
|
727
|
-
before(:all) do
|
728
|
-
TestAR.class_eval do
|
729
|
-
self.extend ApiResource::Associations::HasManyThroughRemoteObjectProxy
|
730
|
-
has_many :test_throughs
|
731
|
-
has_many_through_remote(:belongs_to_objects, :through => :test_throughs)
|
732
|
-
end
|
733
|
-
end
|
734
|
-
it "should attempt to load a collection of remote objects for a has_many_through relationship" do
|
735
|
-
tar = TestAR.new
|
736
|
-
through_test_resource_1 = TestThrough.new
|
737
|
-
through_test_resource_2 = TestThrough.new
|
738
|
-
belongs_to_object_1 = BelongsToObject.new
|
739
|
-
belongs_to_object_2 = BelongsToObject.new
|
740
|
-
tar.expects(:test_throughs).returns([through_test_resource_1, through_test_resource_2])
|
741
|
-
through_test_resource_1.expects(:belongs_to_object).returns([belongs_to_object_1])
|
742
|
-
through_test_resource_2.expects(:belongs_to_object).returns([belongs_to_object_2])
|
743
|
-
|
744
|
-
tar.belongs_to_objects.should eql [belongs_to_object_1, belongs_to_object_2]
|
745
|
-
end
|
746
|
-
|
747
|
-
end
|
748
|
-
end
|
749
|
-
end
|
750
|
-
end
|
751
|
-
end
|