codebrulee-attr_remote 0.0.5 → 0.0.6
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.
- data/attr_remote.gemspec +1 -1
- data/lib/attr_remote.rb +32 -11
- data/test/db/test.db +0 -0
- data/test/factories.rb +5 -0
- data/test/helper.rb +10 -21
- data/test/test_attr_remote.rb +44 -11
- metadata +1 -1
data/attr_remote.gemspec
CHANGED
data/lib/attr_remote.rb
CHANGED
@@ -4,14 +4,11 @@ require 'active_resource'
|
|
4
4
|
|
5
5
|
module AttrRemote
|
6
6
|
module ClassMethods
|
7
|
+
|
7
8
|
def remote_attributes
|
8
9
|
@remote_attributes ||= []
|
9
10
|
end
|
10
11
|
|
11
|
-
def remote_changed?
|
12
|
-
@remote_changed == true
|
13
|
-
end
|
14
|
-
|
15
12
|
def attr_remote(*remote_attrs)
|
16
13
|
remote_class = "Remote#{self.to_s}"
|
17
14
|
remote_instance_meth = remote_class.underscore
|
@@ -19,7 +16,7 @@ module AttrRemote
|
|
19
16
|
|
20
17
|
remote_attributes.concat(remote_attrs).uniq!
|
21
18
|
|
22
|
-
class_eval <<-remote_access
|
19
|
+
class_eval <<-remote_access, __FILE__, __LINE__+1
|
23
20
|
# def remote_user
|
24
21
|
# @remote_user ||= RemoteUser.find(self.remote_user_id) rescue nil
|
25
22
|
# end
|
@@ -79,7 +76,7 @@ module AttrRemote
|
|
79
76
|
before_update :update_#{remote_instance_meth}
|
80
77
|
|
81
78
|
# def update_remote_user
|
82
|
-
# if self.remote_user_id and self.
|
79
|
+
# if self.remote_user_id and self.remote_attributes_changed?
|
83
80
|
# remote_hash = {}
|
84
81
|
# self.class.remote_attributes.each do |attr|
|
85
82
|
# remote_hash[attr.to_sym] = self.send(attr.to_sym)
|
@@ -93,13 +90,13 @@ module AttrRemote
|
|
93
90
|
# end
|
94
91
|
# return false
|
95
92
|
# else
|
96
|
-
# @
|
93
|
+
# @remote_attributes_changed = false
|
97
94
|
# return true
|
98
95
|
# end
|
99
96
|
# end
|
100
97
|
# end
|
101
98
|
def update_#{remote_instance_meth}
|
102
|
-
if self.#{remote_instance_id} and self.
|
99
|
+
if self.#{remote_instance_id} and self.remote_attributes_changed?
|
103
100
|
remote_hash = {}
|
104
101
|
self.class.remote_attributes.each do |attr|
|
105
102
|
remote_hash[attr.to_sym] = self.send(attr.to_sym)
|
@@ -113,7 +110,7 @@ module AttrRemote
|
|
113
110
|
end
|
114
111
|
return false
|
115
112
|
else
|
116
|
-
@
|
113
|
+
@remote_attributes_changed = false
|
117
114
|
return true
|
118
115
|
end
|
119
116
|
end
|
@@ -128,7 +125,7 @@ module AttrRemote
|
|
128
125
|
remote_access
|
129
126
|
|
130
127
|
remote_attributes.each do |attr|
|
131
|
-
class_eval <<-remote_attribute
|
128
|
+
class_eval <<-remote_attribute, __FILE__, __LINE__+1
|
132
129
|
def #{attr} # def username
|
133
130
|
remote_#{attr} || '' # remote_username || ''
|
134
131
|
end # end
|
@@ -147,12 +144,36 @@ remote_access
|
|
147
144
|
|
148
145
|
def #{attr}=(attr_value) # def username=(attr_value)
|
149
146
|
@#{attr} = attr_value # @username = attr_value
|
150
|
-
@
|
147
|
+
@remote_attributes_changed = true # @remote_attributes_changed = true
|
151
148
|
end # end
|
152
149
|
remote_attribute
|
153
150
|
end
|
154
151
|
end
|
155
152
|
end
|
153
|
+
|
154
|
+
module InstanceMethods
|
155
|
+
def self.included(base)
|
156
|
+
base.alias_method_chain :save, :dirty_remote
|
157
|
+
base.alias_method_chain :save!, :dirty_remote
|
158
|
+
end
|
159
|
+
|
160
|
+
def remote_attributes_changed?
|
161
|
+
@remote_attributes_changed == true
|
162
|
+
end
|
163
|
+
|
164
|
+
def save_with_dirty_remote(*args) #:nodoc:
|
165
|
+
if status = save_without_dirty_remote(*args)
|
166
|
+
@remote_attributes_changed = false
|
167
|
+
end
|
168
|
+
status
|
169
|
+
end
|
170
|
+
def save_with_dirty_remote!(*args) #:nodoc:
|
171
|
+
status = save_without_dirty_remote!(*args)
|
172
|
+
@remote_attributes_changed = false
|
173
|
+
status
|
174
|
+
end
|
175
|
+
end
|
156
176
|
end
|
157
177
|
|
158
178
|
ActiveRecord::Base.extend AttrRemote::ClassMethods
|
179
|
+
ActiveRecord::Base.send(:include, AttrRemote::InstanceMethods)
|
data/test/db/test.db
CHANGED
Binary file
|
data/test/factories.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -17,29 +17,18 @@ ActiveRecord::Base.establish_connection({
|
|
17
17
|
:dbfile => File.dirname(__FILE__) + '/db/test.db'
|
18
18
|
})
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
}
|
20
|
+
class Test::Unit::TestCase
|
21
|
+
def mock_user(user)
|
22
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
23
|
+
mock.get "/users/#{user.remote_user_id}.xml", {}, {
|
24
|
+
:id => user.remote_user_id,
|
25
|
+
:name => user.name
|
26
|
+
}.to_xml(:root => "user")
|
27
|
+
mock.put "/users/#{user.remote_user_id}.xml", {}, '', 200, {}
|
28
|
+
end
|
29
|
+
end
|
31
30
|
|
32
|
-
mock.put "/users/1.xml", {}, '', 200, {}
|
33
31
|
|
34
|
-
# bob is not so lucky
|
35
|
-
mock.post "/bobs.xml",
|
36
|
-
{},
|
37
|
-
returning(ActiveRecord::Errors.new(Bob.new)) { |errors|
|
38
|
-
errors.add(:email, "can't be blank")
|
39
|
-
}.to_xml, 422
|
40
|
-
end
|
41
|
-
|
42
|
-
class Test::Unit::TestCase
|
43
32
|
def teardown
|
44
33
|
# cleanup all our test data
|
45
34
|
User.delete_all
|
data/test/test_attr_remote.rb
CHANGED
@@ -9,7 +9,7 @@ class TestAttrRemote < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
context "remote object access" do
|
11
11
|
before do
|
12
|
-
@user = Factory(:user)
|
12
|
+
mock_user(@user = Factory(:user, :name => "Kevin"))
|
13
13
|
end
|
14
14
|
test "that an instance should have a method for the remote object" do
|
15
15
|
assert @user.respond_to?(:remote_user)
|
@@ -31,7 +31,10 @@ class TestAttrRemote < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
|
33
33
|
test "that after first read, an instance variable contains the value" do
|
34
|
-
user = Factory
|
34
|
+
mock_user(user = Factory(:user))
|
35
|
+
expected_name = user.name
|
36
|
+
|
37
|
+
user = User.find(user.id)
|
35
38
|
assert_nil user.instance_variable_get('@name')
|
36
39
|
user.name
|
37
40
|
assert_equal "Kevin", user.instance_variable_get('@name')
|
@@ -59,8 +62,16 @@ class TestAttrRemote < Test::Unit::TestCase
|
|
59
62
|
assert_equal "test", user.name
|
60
63
|
end
|
61
64
|
test "that the remote object id is set after creation" do
|
62
|
-
user = Factory(:user, :
|
63
|
-
|
65
|
+
user = Factory.build(:user, :remote_user_id => nil)
|
66
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
67
|
+
mock.post "/users.xml", {}, {
|
68
|
+
:name => user.name
|
69
|
+
}.to_xml(:root => "user"), 200, {
|
70
|
+
'Location' => 'http://0.0.0.0:3000/users/1'
|
71
|
+
}
|
72
|
+
end
|
73
|
+
assert user.save
|
74
|
+
assert_not_nil user.remote_user_id
|
64
75
|
end
|
65
76
|
|
66
77
|
test "that remote errors halt save process" do
|
@@ -70,33 +81,55 @@ class TestAttrRemote < Test::Unit::TestCase
|
|
70
81
|
end
|
71
82
|
|
72
83
|
test "that failure of local validations halts remote creation and therefore remote errors do not show up" do
|
84
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
85
|
+
mock.post "/bobs.xml",
|
86
|
+
{},
|
87
|
+
returning(ActiveRecord::Errors.new(Bob.new)) { |errors|
|
88
|
+
errors.add(:email, "can't be blank")
|
89
|
+
}.to_xml, 422
|
90
|
+
end
|
73
91
|
bob = Bob.create(:title => nil)
|
74
92
|
assert !bob.save
|
75
93
|
assert_not_nil bob.errors.on(:title)
|
76
94
|
assert_nil bob.errors.on(:email)
|
77
95
|
end
|
96
|
+
|
97
|
+
test "that after a successful creation an instance is marked as not having any remote changes" do
|
98
|
+
user = Factory(:user, :remote_user_id => 2)
|
99
|
+
assert !user.remote_attributes_changed?
|
100
|
+
end
|
78
101
|
end
|
79
102
|
|
80
103
|
context "updates" do
|
81
104
|
test "that a remote attribute change is propogated" do
|
82
|
-
user = Factory(:user)
|
105
|
+
mock_user(user = Factory(:user))
|
83
106
|
user.name = "boo"
|
84
107
|
assert user.save
|
85
|
-
|
86
|
-
mock.get "/users/1.xml", {}, {
|
87
|
-
:name => "boo"
|
88
|
-
}.to_xml(:root => "user")
|
89
|
-
end
|
108
|
+
mock_user(user)
|
90
109
|
user = User.find(user.id)
|
91
110
|
assert_equal "boo", user.name
|
92
111
|
end
|
93
112
|
|
113
|
+
test "that after a successful update an instance is marked as not having any remote changes" do
|
114
|
+
user = Factory(:user)
|
115
|
+
mock_user(user)
|
116
|
+
user.name = "new name"
|
117
|
+
assert user.save
|
118
|
+
assert !user.remote_attributes_changed?
|
119
|
+
end
|
120
|
+
|
94
121
|
test "that save doesn't cause a remote hit if a remote attribute has not been changed" do
|
95
122
|
user = Factory(:user, :remote_user_id => 2)
|
96
123
|
# purposely not mocking the ARes call to "prove"
|
97
|
-
# that it isn't invoked
|
124
|
+
# that it isn't invoked on save
|
98
125
|
assert user.save
|
99
126
|
end
|
127
|
+
|
128
|
+
test "that changing a local attribute does not trigger a remote save" do
|
129
|
+
bob = Bob.new(:remote_bob_id => 3)
|
130
|
+
bob.title = "test"
|
131
|
+
assert bob.save
|
132
|
+
end
|
100
133
|
end
|
101
134
|
|
102
135
|
context "deletes" do
|