active_remote 2.4.0 → 3.0.0.pre1
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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/CHANGES.md +22 -0
- data/README.md +2 -0
- data/active_remote.gemspec +2 -2
- data/bin/console +10 -0
- data/lib/active_remote/association.rb +4 -0
- data/lib/active_remote/attribute_assignment.rb +53 -0
- data/lib/active_remote/attribute_definition.rb +106 -0
- data/lib/active_remote/attributes.rb +165 -8
- data/lib/active_remote/base.rb +41 -36
- data/lib/active_remote/dirty.rb +0 -9
- data/lib/active_remote/errors.rb +6 -0
- data/lib/active_remote/persistence.rb +10 -19
- data/lib/active_remote/query_attributes.rb +45 -0
- data/lib/active_remote/rpc.rb +17 -67
- data/lib/active_remote/search.rb +0 -20
- data/lib/active_remote/serialization.rb +1 -32
- data/lib/active_remote/typecasting.rb +3 -12
- data/lib/active_remote/version.rb +1 -1
- data/lib/active_remote.rb +0 -2
- data/spec/lib/active_remote/association_spec.rb +11 -2
- data/spec/lib/active_remote/attributes_spec.rb +177 -0
- data/spec/lib/active_remote/persistence_spec.rb +7 -16
- data/spec/lib/active_remote/query_attribute_spec.rb +171 -0
- data/spec/lib/active_remote/rpc_spec.rb +33 -75
- data/spec/lib/active_remote/search_spec.rb +0 -21
- data/spec/lib/active_remote/serialization_spec.rb +0 -23
- data/spec/support/models/no_attributes.rb +2 -0
- data/spec/support/models.rb +1 -0
- metadata +21 -66
- data/lib/active_remote/attribute_defaults.rb +0 -100
- data/lib/active_remote/bulk.rb +0 -168
- data/lib/active_remote/core_ext/date.rb +0 -7
- data/lib/active_remote/core_ext/date_time.rb +0 -7
- data/lib/active_remote/core_ext/integer.rb +0 -19
- data/lib/active_remote/core_ext.rb +0 -3
- data/lib/active_remote/publication.rb +0 -54
- data/lib/active_remote/serializers/json.rb +0 -16
- data/spec/core_ext/date_time_spec.rb +0 -9
- data/spec/lib/active_remote/attribute_defaults_spec.rb +0 -26
- data/spec/lib/active_remote/bulk_spec.rb +0 -83
- data/spec/lib/active_remote/publication_spec.rb +0 -18
- data/spec/lib/active_remote/serializers/json_spec.rb +0 -78
@@ -0,0 +1,45 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
|
4
|
+
module ActiveRemote
|
5
|
+
# QueryAttributes provides instance methods for querying attributes.
|
6
|
+
#
|
7
|
+
# @example Usage
|
8
|
+
# class Person < ::ActiveRemote::Base
|
9
|
+
# attribute :name
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# person = Person.new
|
13
|
+
# person.name? #=> false
|
14
|
+
# person.name = "Chris Griego"
|
15
|
+
# person.name? #=> true
|
16
|
+
#
|
17
|
+
module QueryAttributes
|
18
|
+
extend ::ActiveSupport::Concern
|
19
|
+
|
20
|
+
included do
|
21
|
+
attribute_method_suffix "?"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Test the presence of an attribute
|
25
|
+
#
|
26
|
+
# See {Typecasting::BooleanTypecaster.call} for more details.
|
27
|
+
#
|
28
|
+
# @example Query an attribute
|
29
|
+
# person.query_attribute(:name)
|
30
|
+
#
|
31
|
+
def query_attribute(name)
|
32
|
+
if respond_to?("#{name}?")
|
33
|
+
send("#{name}?")
|
34
|
+
else
|
35
|
+
raise ::ActiveRemote::UnknownAttributeError, "unknown attribute: #{name}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def attribute?(name)
|
42
|
+
::ActiveRemote::Typecasting::BooleanTypecaster.call(read_attribute(name))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/active_remote/rpc.rb
CHANGED
@@ -3,80 +3,30 @@ require 'active_remote/serializers/protobuf'
|
|
3
3
|
|
4
4
|
module ActiveRemote
|
5
5
|
module RPC
|
6
|
-
extend ActiveSupport::Concern
|
6
|
+
extend ::ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
include
|
9
|
+
include ::ActiveRemote::Serializers::Protobuf
|
10
10
|
end
|
11
11
|
|
12
|
-
module
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
message_class = request_type(rpc_method)
|
27
|
-
fields = fields_from_attributes(message_class, request_args)
|
28
|
-
message_class.new(fields)
|
29
|
-
end
|
30
|
-
|
31
|
-
# :noapi:
|
32
|
-
def request_type(rpc_method)
|
33
|
-
warn "DEPRECATED Model.request_type is deprecated and will be removed in Active Remote 3.0. This is handled by the Protobuf RPC adpater now"
|
34
|
-
|
35
|
-
service_class.rpcs[rpc_method].request_type
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# :noapi:
|
40
|
-
def execute(rpc_method, request_args)
|
41
|
-
warn "DEPRECATED Model#execute is deprecated and will be removed in Active Remote 3.0. Use Model#rpc.execute instead"
|
42
|
-
|
43
|
-
@last_request = request(rpc_method, request_args)
|
44
|
-
|
45
|
-
_service_class.client.__send__(rpc_method, @last_request) do |c|
|
46
|
-
|
47
|
-
# In the event of service failure, raise the error.
|
48
|
-
c.on_failure do |error|
|
49
|
-
raise ActiveRemoteError, error.message
|
50
|
-
end
|
51
|
-
|
52
|
-
# In the event of service success, assign the response.
|
53
|
-
c.on_success do |response|
|
54
|
-
@last_response = response
|
12
|
+
module ClassMethods
|
13
|
+
# Builds an attribute hash that be assigned directly
|
14
|
+
# to an object from an rpc response
|
15
|
+
def build_from_rpc(new_attributes)
|
16
|
+
new_attributes = new_attributes.stringify_keys
|
17
|
+
constructed_attributes = {}
|
18
|
+
attributes.each do |name, definition|
|
19
|
+
if new_attributes[name].nil?
|
20
|
+
constructed_attributes[name] = nil
|
21
|
+
elsif definition[:typecaster]
|
22
|
+
constructed_attributes[name] = definition[:typecaster].call(new_attributes[name])
|
23
|
+
else
|
24
|
+
constructed_attributes[name] = new_attributes[name]
|
55
25
|
end
|
56
26
|
end
|
57
|
-
|
58
|
-
@last_response
|
59
|
-
end
|
60
|
-
|
61
|
-
# :noapi:
|
62
|
-
def remote_call(rpc_method, request_args)
|
63
|
-
warn "DEPRECATED Model#remote_call is deprecated and will be removed in Active Remote 3.0. Use Model#rpc.execute instead"
|
64
|
-
|
65
|
-
rpc.execute(rpc_method, request_args)
|
27
|
+
constructed_attributes
|
66
28
|
end
|
67
29
|
|
68
|
-
private
|
69
|
-
|
70
|
-
# :noapi:
|
71
|
-
def request(rpc_method, attributes)
|
72
|
-
warn "DEPRECATED Model#request is deprecated and will be removed in Active Remote 3.0. This is handled by the Protobuf RPC adpater now"
|
73
|
-
|
74
|
-
self.class.request(rpc_method, attributes)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
module ClassMethods
|
79
|
-
|
80
30
|
# Execute an RPC call to the remote service and return the raw response.
|
81
31
|
#
|
82
32
|
def remote_call(rpc_method, request_args)
|
@@ -104,7 +54,7 @@ module ActiveRemote
|
|
104
54
|
#
|
105
55
|
# path_to_adapter.classify.constantize
|
106
56
|
|
107
|
-
RPCAdapters::ProtobufAdapter
|
57
|
+
::ActiveRemote::RPCAdapters::ProtobufAdapter
|
108
58
|
end
|
109
59
|
end
|
110
60
|
|
data/lib/active_remote/search.rb
CHANGED
@@ -8,19 +8,9 @@ module ActiveRemote
|
|
8
8
|
included do
|
9
9
|
include Persistence
|
10
10
|
include RPC
|
11
|
-
|
12
|
-
define_model_callbacks :search
|
13
11
|
end
|
14
12
|
|
15
13
|
module ClassMethods
|
16
|
-
|
17
|
-
# :noapi:
|
18
|
-
def _active_remote_search_args(args)
|
19
|
-
warn "DEPRECATED Model._active_remote_search_args is depracted and will be remoted in Active Remote 3.0."
|
20
|
-
|
21
|
-
validate_search_args!(args)
|
22
|
-
end
|
23
|
-
|
24
14
|
# Tries to load the first record; if it fails, an exception is raised.
|
25
15
|
#
|
26
16
|
# ====Examples
|
@@ -102,7 +92,6 @@ module ActiveRemote
|
|
102
92
|
|
103
93
|
if response.respond_to?(:records)
|
104
94
|
records = serialize_records(response.records)
|
105
|
-
records.each { |record| record.run_callbacks :search }
|
106
95
|
end
|
107
96
|
end
|
108
97
|
|
@@ -122,15 +111,6 @@ module ActiveRemote
|
|
122
111
|
end
|
123
112
|
end
|
124
113
|
|
125
|
-
# :noapi:
|
126
|
-
def _active_remote_search(args)
|
127
|
-
warn "DEPRECATED Model#_active_remote_search is depracted and will be remoted in Active Remote 3.0."
|
128
|
-
|
129
|
-
run_callbacks :search do
|
130
|
-
rpc.execute(:search, args)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
114
|
# Reload this record from the remote service.
|
135
115
|
#
|
136
116
|
def reload
|
@@ -1,11 +1,9 @@
|
|
1
|
-
require 'active_remote/serializers/json'
|
2
|
-
|
3
1
|
module ActiveRemote
|
4
2
|
module Serialization
|
5
3
|
extend ActiveSupport::Concern
|
6
4
|
|
7
5
|
included do
|
8
|
-
include Serializers::JSON
|
6
|
+
include ::ActiveModel::Serializers::JSON
|
9
7
|
end
|
10
8
|
|
11
9
|
module ClassMethods
|
@@ -45,34 +43,5 @@ module ActiveRemote
|
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
48
|
-
|
49
|
-
# Examine the given response and add any errors to our internal errors
|
50
|
-
# list.
|
51
|
-
#
|
52
|
-
# ====Examples
|
53
|
-
#
|
54
|
-
# response = remote_call(:action_that_returns_errors, { :stuff => 'foo' })
|
55
|
-
#
|
56
|
-
# add_errors_from_response(response)
|
57
|
-
#
|
58
|
-
def add_errors_from_response(response = nil)
|
59
|
-
unless response
|
60
|
-
warn 'DEPRECATED calling Model#add_errors_from_response without args is deprecated and will be removed in Active Remote 3.0.'
|
61
|
-
response = last_response
|
62
|
-
end
|
63
|
-
|
64
|
-
add_errors(response.errors) if response.respond_to?(:errors)
|
65
|
-
end
|
66
|
-
|
67
|
-
# DEPRECATED – Use the class-level :serialize_errors instead
|
68
|
-
#
|
69
|
-
def serialize_records(records = nil)
|
70
|
-
warn 'DEPRECATED Calling Model#serialize_records is deprecated and will be removed in Active Remote 3.0. Use Model.serialize_records instead'
|
71
|
-
|
72
|
-
records ||= last_response.records if last_response.respond_to?(:records)
|
73
|
-
return if records.nil?
|
74
|
-
|
75
|
-
self.class.serialize_records(records)
|
76
|
-
end
|
77
46
|
end
|
78
47
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "active_support/core_ext/string/conversions"
|
2
|
+
|
1
3
|
require "active_remote/typecasting/big_decimal_typecaster"
|
2
4
|
require "active_remote/typecasting/boolean"
|
3
5
|
require "active_remote/typecasting/boolean_typecaster"
|
@@ -28,23 +30,12 @@ module ActiveRemote
|
|
28
30
|
def attribute=(name, value)
|
29
31
|
return super if value.nil?
|
30
32
|
|
31
|
-
typecaster =
|
33
|
+
typecaster = self.class.attributes[name][:typecaster]
|
32
34
|
return super unless typecaster
|
33
35
|
|
34
36
|
super(name, typecaster.call(value))
|
35
37
|
end
|
36
38
|
|
37
|
-
def _attribute_typecaster(attribute_name)
|
38
|
-
self.class.attributes[attribute_name][:typecaster] || _typecaster_for(attribute_name)
|
39
|
-
end
|
40
|
-
|
41
|
-
def _typecaster_for(attribute_name)
|
42
|
-
type = self.class.attributes[attribute_name][:type]
|
43
|
-
return nil unless type
|
44
|
-
|
45
|
-
TYPECASTER_MAP[type]
|
46
|
-
end
|
47
|
-
|
48
39
|
module ClassMethods
|
49
40
|
def inspect
|
50
41
|
inspected_attributes = attribute_names.sort.map { |name| "#{name}: #{_attribute_type(name)}" }
|
data/lib/active_remote.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
require 'active_attr'
|
2
1
|
require 'active_model'
|
3
2
|
require 'active_support'
|
4
3
|
require 'protobuf'
|
5
4
|
|
6
5
|
require 'active_remote/base'
|
7
6
|
require 'active_remote/config'
|
8
|
-
require 'active_remote/core_ext'
|
9
7
|
require 'active_remote/errors'
|
10
8
|
require 'active_remote/version'
|
11
9
|
|
@@ -102,6 +102,7 @@ describe ActiveRemote::Association do
|
|
102
102
|
subject { Author.new(:guid => guid, :user_guid => user_guid) }
|
103
103
|
|
104
104
|
it { is_expected.to respond_to(:posts) }
|
105
|
+
it { is_expected.to respond_to(:posts=) }
|
105
106
|
|
106
107
|
it "searches the associated model for all associated records" do
|
107
108
|
expect(Post).to receive(:search).with(:author_guid => subject.guid).and_return(records)
|
@@ -158,7 +159,7 @@ describe ActiveRemote::Association do
|
|
158
159
|
before { allow(subject).to receive(:respond_to?).with("user_guid").and_return(false) }
|
159
160
|
|
160
161
|
it 'raises an error' do
|
161
|
-
expect {subject.user_posts}.to raise_error(::
|
162
|
+
expect {subject.user_posts}.to raise_error(::ActiveRemote::UnknownAttributeError)
|
162
163
|
end
|
163
164
|
end
|
164
165
|
|
@@ -170,6 +171,14 @@ describe ActiveRemote::Association do
|
|
170
171
|
end
|
171
172
|
end
|
172
173
|
end
|
174
|
+
|
175
|
+
context "writer method" do
|
176
|
+
context "when new value is not an array" do
|
177
|
+
it "should raise error" do
|
178
|
+
expect { subject.posts = Post.new }.to raise_error(::RuntimeError, /New value must be an array/)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
173
182
|
end
|
174
183
|
|
175
184
|
describe ".has_one" do
|
@@ -246,7 +255,7 @@ describe ActiveRemote::Association do
|
|
246
255
|
before { allow(subject).to receive(:respond_to?).with("user_guid").and_return(false) }
|
247
256
|
|
248
257
|
it 'raises an error' do
|
249
|
-
expect {subject.chief_editor}.to raise_error(::
|
258
|
+
expect {subject.chief_editor}.to raise_error(::ActiveRemote::UnknownAttributeError)
|
250
259
|
end
|
251
260
|
end
|
252
261
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ::ActiveRemote::Attributes do
|
4
|
+
let(:model_class) do
|
5
|
+
::Class.new do
|
6
|
+
include ::ActiveRemote::Attributes
|
7
|
+
|
8
|
+
attribute :name
|
9
|
+
attribute :address
|
10
|
+
|
11
|
+
def self.name
|
12
|
+
"TestClass"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
subject { ::Author.new }
|
17
|
+
|
18
|
+
describe ".attribute" do
|
19
|
+
context "a dangerous attribute" do
|
20
|
+
it "raises an error" do
|
21
|
+
expect { model_class.attribute(:timeout) }.to raise_error(::ActiveRemote::DangerousAttributeError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "a harmless attribute" do
|
26
|
+
it "creates an attribute with no options" do
|
27
|
+
expect(model_class.attributes.values).to include(::ActiveRemote::AttributeDefinition.new(:name))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the attribute definition" do
|
31
|
+
expect(model_class.attribute(:name)).to eq(::ActiveRemote::AttributeDefinition.new(:name))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "defines an attribute reader that calls #attribute" do
|
35
|
+
expect(subject).to receive(:attribute).with("name")
|
36
|
+
subject.name
|
37
|
+
end
|
38
|
+
|
39
|
+
it "defines an attribute writer that calls #attribute=" do
|
40
|
+
expect(subject).to receive(:attribute=).with("name", "test")
|
41
|
+
subject.name = "test"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe ".attribute!" do
|
47
|
+
it "can create an attribute with no options" do
|
48
|
+
model_class.attribute!(:first_name)
|
49
|
+
expect(model_class.attributes.values).to include(::ActiveRemote::AttributeDefinition.new(:first_name))
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns the attribute definition" do
|
53
|
+
expect(model_class.attribute!(:address)).to eq(::ActiveRemote::AttributeDefinition.new(:address))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".attributes" do
|
58
|
+
it "can access AttributeDefinition with a Symbol" do
|
59
|
+
expect(::Author.attributes[:name]).to eq(::ActiveRemote::AttributeDefinition.new(:name))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "can access AttributeDefinition with a String" do
|
63
|
+
expect(::Author.attributes["name"]).to eq(::ActiveRemote::AttributeDefinition.new(:name))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe ".inspect" do
|
68
|
+
it "renders the class name" do
|
69
|
+
expect(model_class.inspect).to match(/^TestClass\(.*\)$/)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "renders the attribute names in alphabetical order" do
|
73
|
+
expect(model_class.inspect).to match("(address, name)")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "#==" do
|
78
|
+
it "returns true when all attributes are equal" do
|
79
|
+
expect(::Author.new(:guid => "test")).to eq(::Author.new(:guid => "test"))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns false when compared to another type" do
|
83
|
+
expect(::Category.new(:guid => "test")).to_not eq(::Author.new(:name => "test"))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#attributes" do
|
88
|
+
context "when no attributes are defined" do
|
89
|
+
it "returns an empty Hash" do
|
90
|
+
expect(::NoAttributes.new.attributes).to eq({})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when an attribute is defined" do
|
95
|
+
it "returns the key value pairs" do
|
96
|
+
subject.name = "test"
|
97
|
+
expect(subject.attributes).to include("name" => "test")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns a new Hash " do
|
101
|
+
subject.attributes.merge!("foobar" => "foobar")
|
102
|
+
expect(subject.attributes).to_not include("foobar" => "foobar")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns all attributes" do
|
106
|
+
expect(subject.attributes.keys).to eq(["guid", "name", "user_guid", "chief_editor_guid", "editor_guid", "category_guid"])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#inspect" do
|
112
|
+
before { subject.name = "test" }
|
113
|
+
|
114
|
+
it "includes the class name and all attribute values in alphabetical order by attribute name" do
|
115
|
+
expect(subject.inspect).to eq(%{#<Author category_guid: nil, chief_editor_guid: nil, editor_guid: nil, guid: nil, name: "test", user_guid: nil>})
|
116
|
+
end
|
117
|
+
|
118
|
+
it "doesn't format the inspection string for attributes if the model does not have any" do
|
119
|
+
expect(::NoAttributes.new.inspect).to eq(%{#<NoAttributes>})
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
[:[], :read_attribute].each do |method|
|
124
|
+
describe "##{method}" do
|
125
|
+
context "when an attribute is not set" do
|
126
|
+
it "returns nil" do
|
127
|
+
expect(subject.send(method, :name)).to be_nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when an attribute is set" do
|
132
|
+
before { subject.write_attribute(:name, "test") }
|
133
|
+
|
134
|
+
it "returns the attribute using a Symbol" do
|
135
|
+
expect(subject.send(method, :name)).to eq("test")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns the attribute using a String" do
|
139
|
+
expect(subject.send(method, "name")).to eq("test")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it "raises when getting an undefined attribute" do
|
144
|
+
expect { subject.send(method, :foobar) }.to raise_error(::ActiveRemote::UnknownAttributeError)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
[:[]=, :write_attribute].each do |method|
|
150
|
+
describe "##{method}" do
|
151
|
+
it "raises ArgumentError with one argument" do
|
152
|
+
expect { subject.send(method, :name) }.to raise_error(::ArgumentError)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "raises ArgumentError with no arguments" do
|
156
|
+
expect { subject.send(method) }.to raise_error(::ArgumentError)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "sets an attribute using a Symbol and value" do
|
160
|
+
expect { subject.send(method, :name, "test") }.to change { subject.attributes["name"] }.from(nil).to("test")
|
161
|
+
end
|
162
|
+
|
163
|
+
it "sets an attribute using a String and value" do
|
164
|
+
expect { subject.send(method, "name", "test") }.to change { subject.attributes["name"] }.from(nil).to("test")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "is able to set an attribute to nil" do
|
168
|
+
subject.name = "test"
|
169
|
+
expect { subject.send(method, :name, nil) }.to change { subject.attributes["name"] }.from("test").to(nil)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "raises when setting an undefined attribute" do
|
173
|
+
expect { subject.send(method, :foobar, "test") }.to raise_error(::ActiveRemote::UnknownAttributeError)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -1,16 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ActiveRemote::Persistence do
|
4
|
-
let(:
|
5
|
-
let(:
|
3
|
+
describe ::ActiveRemote::Persistence do
|
4
|
+
let(:response_without_errors) { ::HashWithIndifferentAccess.new(:errors => []) }
|
5
|
+
let(:rpc) { ::ActiveRemote::RPCAdapters::ProtobufAdapter.new(::Tag.service_class) }
|
6
6
|
|
7
|
-
subject { Tag.new }
|
7
|
+
subject { ::Tag.new }
|
8
8
|
|
9
9
|
before {
|
10
10
|
allow(rpc).to receive(:execute).and_return(response_without_errors)
|
11
11
|
allow(Tag).to receive(:rpc).and_return(rpc)
|
12
12
|
}
|
13
|
-
after { allow(Tag).to receive(:rpc).and_call_original }
|
13
|
+
after { allow(::Tag).to receive(:rpc).and_call_original }
|
14
14
|
|
15
15
|
describe ".create" do
|
16
16
|
it "runs create callbacks" do
|
@@ -251,9 +251,6 @@ describe ActiveRemote::Persistence do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
describe "#save!" do
|
254
|
-
before { allow(subject).to receive(:execute) }
|
255
|
-
after { allow(subject).to receive(:execute).and_call_original }
|
256
|
-
|
257
254
|
context "when the record is saved" do
|
258
255
|
it "returns true" do
|
259
256
|
allow(subject).to receive(:save).and_return(true)
|
@@ -286,16 +283,13 @@ describe ActiveRemote::Persistence do
|
|
286
283
|
describe "#update_attribute" do
|
287
284
|
let(:tag) { Tag.allocate.instantiate({:guid => "123"}) }
|
288
285
|
|
289
|
-
before { allow(Tag.rpc).to receive(:execute).and_return(HashWithIndifferentAccess.new) }
|
290
|
-
after { allow(Tag.rpc).to receive(:execute).and_call_original }
|
291
|
-
|
292
286
|
it "runs update callbacks" do
|
293
287
|
expect(tag).to receive(:after_update_callback)
|
294
288
|
tag.update_attribute(:name, "foo")
|
295
289
|
end
|
296
290
|
|
297
291
|
it "updates a remote record" do
|
298
|
-
expect(
|
292
|
+
expect(rpc).to receive(:execute).with(:update, {"name" => "foo", "guid" => "123"})
|
299
293
|
tag.update_attribute(:name, "foo")
|
300
294
|
end
|
301
295
|
|
@@ -317,16 +311,13 @@ describe ActiveRemote::Persistence do
|
|
317
311
|
let(:attributes) { HashWithIndifferentAccess.new(:name => 'bar') }
|
318
312
|
let(:tag) { Tag.allocate.instantiate({:guid => "123"}) }
|
319
313
|
|
320
|
-
before { allow(Tag.rpc).to receive(:execute).and_return(HashWithIndifferentAccess.new) }
|
321
|
-
after { allow(Tag.rpc).to receive(:execute).and_call_original }
|
322
|
-
|
323
314
|
it "runs update callbacks" do
|
324
315
|
expect(tag).to receive(:after_update_callback)
|
325
316
|
tag.update_attributes({})
|
326
317
|
end
|
327
318
|
|
328
319
|
it "updates a remote record" do
|
329
|
-
expect(
|
320
|
+
expect(rpc).to receive(:execute).with(:update, tag.scope_key_hash)
|
330
321
|
tag.update_attributes({})
|
331
322
|
end
|
332
323
|
|