active_remote 5.0.0.pre → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/active_remote.gemspec +1 -1
- data/lib/active_remote/attribute_definition.rb +2 -0
- data/lib/active_remote/attributes.rb +1 -0
- data/lib/active_remote/dirty.rb +8 -0
- data/lib/active_remote/dsl.rb +4 -4
- data/lib/active_remote/integration.rb +1 -1
- data/lib/active_remote/persistence.rb +19 -13
- data/lib/active_remote/query_attributes.rb +1 -5
- data/lib/active_remote/rpc.rb +6 -0
- data/lib/active_remote/version.rb +1 -1
- data/spec/lib/active_remote/dirty_spec.rb +9 -0
- data/spec/lib/active_remote/persistence_spec.rb +70 -15
- data/spec/lib/active_remote/query_attribute_spec.rb +3 -2
- data/spec/lib/active_remote/rpc_spec.rb +31 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24ecc4009b9bb7ab623c2f80961e2e15263a249ac412be97c39f86cde123fdaa
|
4
|
+
data.tar.gz: ac0215aad0dce875952b9e2583e8c3fe8ce114d33de15978a7393482e7fa65dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8cd4c36b5dc8840206dc32bbe4ccc3e591f631691e156d1ebcf537877442bf5be00c70506f8d2e890f2340f34b805e6cde7e1f80103c07bd1fcc4799b1829d7
|
7
|
+
data.tar.gz: ff8a9f380a3eba79fcd0cb41e4856e02c20ede68044bab07fe80b3996f88962e49e95f6db59308e4cdd7ff51468ff0b280f36307c21fdd5bf5f0cdd8c4bc393e
|
data/.travis.yml
CHANGED
data/active_remote.gemspec
CHANGED
@@ -28,6 +28,7 @@ module ActiveRemote
|
|
28
28
|
def <=>(other)
|
29
29
|
return nil unless other.instance_of? self.class
|
30
30
|
return nil if name == other.name && options != other.options
|
31
|
+
|
31
32
|
self.name.to_s <=> other.name.to_s
|
32
33
|
end
|
33
34
|
|
@@ -57,6 +58,7 @@ module ActiveRemote
|
|
57
58
|
# @since 0.2.0
|
58
59
|
def initialize(name, type = :value, **options)
|
59
60
|
raise TypeError, "can't convert #{name.class} into Symbol" unless name.respond_to? :to_sym
|
61
|
+
|
60
62
|
@name = name.to_sym
|
61
63
|
@type = ::ActiveModel::Type.lookup(type)
|
62
64
|
@options = options
|
data/lib/active_remote/dirty.rb
CHANGED
@@ -29,6 +29,14 @@ module ActiveRemote
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
# Override #remote to provide dirty tracking.
|
33
|
+
#
|
34
|
+
def remote(*)
|
35
|
+
super.tap do
|
36
|
+
clear_changes_information
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
32
40
|
# Override #save to store changes as previous changes then clear them.
|
33
41
|
#
|
34
42
|
def save(*)
|
data/lib/active_remote/dsl.rb
CHANGED
@@ -41,11 +41,11 @@ module ActiveRemote
|
|
41
41
|
|
42
42
|
def endpoints(endpoints_hash = nil)
|
43
43
|
@endpoints ||= {
|
44
|
-
:create
|
45
|
-
:delete
|
44
|
+
:create => :create,
|
45
|
+
:delete => :delete,
|
46
46
|
:destroy => :destroy,
|
47
|
-
:search
|
48
|
-
:update
|
47
|
+
:search => :search,
|
48
|
+
:update => :update
|
49
49
|
}
|
50
50
|
@endpoints.merge!(endpoints_hash) if endpoints_hash.present?
|
51
51
|
@endpoints
|
@@ -76,6 +76,7 @@ module ActiveRemote
|
|
76
76
|
#
|
77
77
|
def delete
|
78
78
|
raise ReadOnlyRemoteRecord if readonly?
|
79
|
+
|
79
80
|
response = remote_call(:delete, scope_key_hash)
|
80
81
|
|
81
82
|
add_errors(response.errors) if response.respond_to?(:errors)
|
@@ -101,6 +102,7 @@ module ActiveRemote
|
|
101
102
|
#
|
102
103
|
def destroy
|
103
104
|
raise ReadOnlyRemoteRecord if readonly?
|
105
|
+
|
104
106
|
response = remote_call(:destroy, scope_key_hash)
|
105
107
|
|
106
108
|
add_errors(response.errors) if response.respond_to?(:errors)
|
@@ -156,6 +158,19 @@ module ActiveRemote
|
|
156
158
|
self.class.readonly? || @readonly
|
157
159
|
end
|
158
160
|
|
161
|
+
# Executes a remote call on the current object and serializes it's attributes and
|
162
|
+
# errors from the response.
|
163
|
+
#
|
164
|
+
# Defaults request args to the scope key hash (e.g., { guid: 'ABC-123' }) when none are given.
|
165
|
+
# Returns false if the response contained errors; otherwise, returns true.
|
166
|
+
#
|
167
|
+
def remote(endpoint, request_args = scope_key_hash)
|
168
|
+
response = remote_call(endpoint, request_args)
|
169
|
+
assign_attributes_from_rpc(response)
|
170
|
+
|
171
|
+
success?
|
172
|
+
end
|
173
|
+
|
159
174
|
# Saves the remote record.
|
160
175
|
#
|
161
176
|
# If it is a new record, it will be created through the service, otherwise
|
@@ -203,6 +218,7 @@ module ActiveRemote
|
|
203
218
|
# attribute is marked as readonly.
|
204
219
|
def update_attribute(name, value)
|
205
220
|
raise ReadOnlyRemoteRecord if readonly?
|
221
|
+
|
206
222
|
name = name.to_s
|
207
223
|
send("#{name}=", value)
|
208
224
|
save(:validate => false)
|
@@ -235,13 +251,7 @@ module ActiveRemote
|
|
235
251
|
#
|
236
252
|
def remote_create
|
237
253
|
run_callbacks :create do
|
238
|
-
|
239
|
-
new_attributes = attributes
|
240
|
-
|
241
|
-
response = remote_call(:create, new_attributes)
|
242
|
-
|
243
|
-
instantiate(response.to_hash)
|
244
|
-
add_errors(response.errors) if response.respond_to?(:errors)
|
254
|
+
remote(:create, attributes)
|
245
255
|
|
246
256
|
@new_record = has_errors?
|
247
257
|
success?
|
@@ -254,6 +264,7 @@ module ActiveRemote
|
|
254
264
|
#
|
255
265
|
def create_or_update(*args)
|
256
266
|
raise ReadOnlyRemoteRecord if readonly?
|
267
|
+
|
257
268
|
new_record? ? remote_create : remote_update(*args)
|
258
269
|
end
|
259
270
|
|
@@ -268,12 +279,7 @@ module ActiveRemote
|
|
268
279
|
updated_attributes.slice!(*attribute_names)
|
269
280
|
updated_attributes.merge!(scope_key_hash)
|
270
281
|
|
271
|
-
|
272
|
-
|
273
|
-
instantiate(response.to_hash)
|
274
|
-
add_errors(response.errors) if response.respond_to?(:errors)
|
275
|
-
|
276
|
-
success?
|
282
|
+
remote(:update, updated_attributes)
|
277
283
|
end
|
278
284
|
end
|
279
285
|
end
|
data/lib/active_remote/rpc.rb
CHANGED
@@ -52,6 +52,12 @@ module ActiveRemote
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
def assign_attributes_from_rpc(response)
|
56
|
+
new_attributes = self.class.build_from_rpc(response.to_hash)
|
57
|
+
@attributes.update(new_attributes)
|
58
|
+
add_errors(response.errors) if response.respond_to?(:errors)
|
59
|
+
end
|
60
|
+
|
55
61
|
def remote_call(rpc_method, request_args)
|
56
62
|
self.class.remote_call(rpc_method, request_args)
|
57
63
|
end
|
@@ -54,6 +54,15 @@ describe ActiveRemote::Dirty do
|
|
54
54
|
its(:changes) { should be_empty }
|
55
55
|
end
|
56
56
|
|
57
|
+
describe "#remote" do
|
58
|
+
let(:post) { Post.new(:name => "foo") }
|
59
|
+
|
60
|
+
it "clears changes information" do
|
61
|
+
allow(post).to receive(:remote_call).and_return(::Generic::Remote::Post.new(:name => "foo"))
|
62
|
+
expect { post.remote(:reload) }.to change { post.changed? }.to(false)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
57
66
|
describe "#save" do
|
58
67
|
let!(:changes) { subject.changes }
|
59
68
|
|
@@ -140,15 +140,6 @@ describe ::ActiveRemote::Persistence do
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
|
143
|
-
describe "#readonly?" do
|
144
|
-
context "when the record is created through instantiate with options[:readonly]" do
|
145
|
-
subject { Tag.instantiate({ :guid => "foo" }, :readonly => true) }
|
146
|
-
|
147
|
-
its(:new_record?) { should be_falsey }
|
148
|
-
its(:readonly?) { should be_truthy }
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
143
|
describe "#has_errors?" do
|
153
144
|
context "when errors are not present" do
|
154
145
|
before { subject.errors.clear }
|
@@ -197,6 +188,70 @@ describe ::ActiveRemote::Persistence do
|
|
197
188
|
end
|
198
189
|
end
|
199
190
|
|
191
|
+
describe "#readonly?" do
|
192
|
+
context "when the record is created through instantiate with options[:readonly]" do
|
193
|
+
subject { Tag.instantiate({ :guid => "foo" }, :readonly => true) }
|
194
|
+
|
195
|
+
its(:new_record?) { should be_falsey }
|
196
|
+
its(:readonly?) { should be_truthy }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
describe "#remote" do
|
201
|
+
let(:response) { ::Generic::Remote::Tag.new(:guid => tag.guid, :name => "bar") }
|
202
|
+
let(:rpc) { ::ActiveRemote::RPCAdapters::ProtobufAdapter.new(::Tag.service_class, ::Tag.endpoints) }
|
203
|
+
let(:tag) { ::Tag.new(:guid => SecureRandom.uuid) }
|
204
|
+
|
205
|
+
subject { tag }
|
206
|
+
|
207
|
+
before do
|
208
|
+
allow(::Tag).to receive(:rpc).and_return(rpc)
|
209
|
+
allow(rpc).to receive(:execute).and_return(response)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "calls the given RPC method with default args" do
|
213
|
+
expect(::Tag.rpc).to receive(:execute).with(:remote_method, tag.scope_key_hash)
|
214
|
+
tag.remote(:remote_method)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "updates the attributes from the response" do
|
218
|
+
expect { tag.remote(:remote_method) }.to change { tag.name }.to(response.name)
|
219
|
+
end
|
220
|
+
|
221
|
+
it "returns true" do
|
222
|
+
expect(tag.remote(:remote_method)).to be(true)
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when request args are given" do
|
226
|
+
it "calls the given RPC method with default args" do
|
227
|
+
attributes = { :guid => tag.guid, :name => "foo" }
|
228
|
+
expect(::Tag.rpc).to receive(:execute).with(:remote_method, attributes)
|
229
|
+
tag.remote(:remote_method, attributes)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context "when response does not respond to errors" do
|
234
|
+
it "returns true" do
|
235
|
+
allow(rpc).to receive(:execute).and_return(double(:response, :to_hash => ::Hash.new))
|
236
|
+
expect(tag.remote(:remote_method)).to be(true)
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when errors are returned" do
|
241
|
+
let(:response) {
|
242
|
+
::Generic::Remote::Tag.new(:guid => tag.guid, :name => "bar", :errors => [{ :field => "name", :message => "message" }])
|
243
|
+
}
|
244
|
+
|
245
|
+
it "adds errors from the response" do
|
246
|
+
expect { tag.remote(:remote_method) }.to change { tag.has_errors? }.to(true)
|
247
|
+
end
|
248
|
+
|
249
|
+
it "returns false" do
|
250
|
+
expect(tag.remote(:remote_method)).to be(false)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
200
255
|
describe "#save" do
|
201
256
|
it "runs save callbacks" do
|
202
257
|
allow(subject).to receive(:run_callbacks).with(:validation).and_return(true)
|
@@ -313,12 +368,12 @@ describe ::ActiveRemote::Persistence do
|
|
313
368
|
|
314
369
|
it "runs update callbacks" do
|
315
370
|
expect(tag).to receive(:after_update_callback)
|
316
|
-
tag.
|
371
|
+
tag.update({})
|
317
372
|
end
|
318
373
|
|
319
374
|
it "updates a remote record" do
|
320
375
|
expect(rpc).to receive(:execute).with(:update, tag.scope_key_hash)
|
321
|
-
tag.
|
376
|
+
tag.update({})
|
322
377
|
end
|
323
378
|
|
324
379
|
before { allow(subject).to receive(:save) }
|
@@ -326,12 +381,12 @@ describe ::ActiveRemote::Persistence do
|
|
326
381
|
|
327
382
|
it "assigns new attributes" do
|
328
383
|
expect(subject).to receive(:assign_attributes).with(attributes)
|
329
|
-
subject.
|
384
|
+
subject.update(attributes)
|
330
385
|
end
|
331
386
|
|
332
387
|
it "saves the record" do
|
333
388
|
expect(subject).to receive(:save)
|
334
|
-
subject.
|
389
|
+
subject.update(attributes)
|
335
390
|
end
|
336
391
|
end
|
337
392
|
|
@@ -343,12 +398,12 @@ describe ::ActiveRemote::Persistence do
|
|
343
398
|
|
344
399
|
it "assigns new attributes" do
|
345
400
|
expect(subject).to receive(:assign_attributes).with(attributes)
|
346
|
-
subject.
|
401
|
+
subject.update!(attributes)
|
347
402
|
end
|
348
403
|
|
349
404
|
it "saves! the record" do
|
350
405
|
expect(subject).to receive(:save!)
|
351
|
-
subject.
|
406
|
+
subject.update!(attributes)
|
352
407
|
end
|
353
408
|
end
|
354
409
|
end
|
@@ -38,9 +38,10 @@ describe ::ActiveRemote::QueryAttributes do
|
|
38
38
|
expect(subject.name?).to eq true
|
39
39
|
end
|
40
40
|
|
41
|
-
|
41
|
+
# This behavior varies from ActiveRecord, so we test it explicitly
|
42
|
+
it "is true when the attribute is 0" do
|
42
43
|
subject.name = 0
|
43
|
-
expect(subject.name?).to eq
|
44
|
+
expect(subject.name?).to eq true
|
44
45
|
end
|
45
46
|
|
46
47
|
it "is true when the attribute is 1" do
|
@@ -50,4 +50,35 @@ describe ::ActiveRemote::RPC do
|
|
50
50
|
expect(::Tag.remote_call(:remote_method, args)).to eq response
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
describe "#assign_attributes_from_rpc" do
|
55
|
+
let(:response) { ::Generic::Remote::Tag.new(:guid => tag.guid, :name => "bar") }
|
56
|
+
let(:tag) { ::Tag.new(:guid => SecureRandom.uuid) }
|
57
|
+
|
58
|
+
it "updates the attributes from the response" do
|
59
|
+
expect { tag.assign_attributes_from_rpc(response) }.to change { tag.name }.to(response.name)
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when response does not respond to errors" do
|
63
|
+
let(:response) { double(:response, :to_hash => ::Hash.new) }
|
64
|
+
|
65
|
+
it "does not add errors from the response" do
|
66
|
+
expect { tag.assign_attributes_from_rpc(response) }.to_not change { tag.has_errors? }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when errors are returned" do
|
71
|
+
let(:response) {
|
72
|
+
::Generic::Remote::Tag.new(
|
73
|
+
:guid => tag.guid,
|
74
|
+
:name => "bar",
|
75
|
+
:errors => [{ :field => "name", :message => "message" }]
|
76
|
+
)
|
77
|
+
}
|
78
|
+
|
79
|
+
it "adds errors from the response" do
|
80
|
+
expect { tag.assign_attributes_from_rpc(response) }.to change { tag.has_errors? }.to(true)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
53
84
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_remote
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0.
|
4
|
+
version: 5.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Hutchison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|