active_remote 3.3.3 → 5.0.0.pre

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +28 -0
  3. data/CHANGES.md +13 -0
  4. data/Gemfile +1 -1
  5. data/Rakefile +7 -3
  6. data/active_remote.gemspec +8 -6
  7. data/lib/active_remote.rb +9 -8
  8. data/lib/active_remote/association.rb +12 -14
  9. data/lib/active_remote/attribute_definition.rb +14 -12
  10. data/lib/active_remote/attributes.rb +6 -6
  11. data/lib/active_remote/base.rb +20 -27
  12. data/lib/active_remote/config.rb +1 -1
  13. data/lib/active_remote/dirty.rb +3 -3
  14. data/lib/active_remote/dsl.rb +3 -4
  15. data/lib/active_remote/errors.rb +1 -11
  16. data/lib/active_remote/persistence.rb +11 -12
  17. data/lib/active_remote/primary_key.rb +0 -1
  18. data/lib/active_remote/query_attributes.rb +13 -13
  19. data/lib/active_remote/rpc.rb +8 -14
  20. data/lib/active_remote/rpc_adapters/protobuf_adapter.rb +18 -17
  21. data/lib/active_remote/scope_keys.rb +1 -2
  22. data/lib/active_remote/search.rb +8 -6
  23. data/lib/active_remote/serializers/protobuf.rb +15 -25
  24. data/lib/active_remote/validations.rb +1 -1
  25. data/lib/active_remote/version.rb +1 -1
  26. data/spec/lib/active_remote/association_spec.rb +23 -23
  27. data/spec/lib/active_remote/attributes_spec.rb +49 -3
  28. data/spec/lib/active_remote/base_spec.rb +1 -1
  29. data/spec/lib/active_remote/dirty_spec.rb +12 -12
  30. data/spec/lib/active_remote/dsl_spec.rb +4 -4
  31. data/spec/lib/active_remote/integration_spec.rb +2 -2
  32. data/spec/lib/active_remote/persistence_spec.rb +26 -33
  33. data/spec/lib/active_remote/primary_key_spec.rb +3 -3
  34. data/spec/lib/active_remote/query_attribute_spec.rb +0 -120
  35. data/spec/lib/active_remote/rpc_adapters/protobuf_adapter_spec.rb +1 -1
  36. data/spec/lib/active_remote/rpc_spec.rb +1 -1
  37. data/spec/lib/active_remote/scope_keys_spec.rb +7 -7
  38. data/spec/lib/active_remote/search_spec.rb +8 -8
  39. data/spec/lib/active_remote/serialization_spec.rb +4 -4
  40. data/spec/lib/active_remote/serializers/protobuf_spec.rb +23 -23
  41. data/spec/lib/active_remote/validations_spec.rb +17 -17
  42. data/spec/spec_helper.rb +9 -9
  43. data/spec/support/helpers.rb +6 -6
  44. data/spec/support/models.rb +8 -8
  45. data/spec/support/models/author.rb +1 -1
  46. data/spec/support/models/category.rb +1 -2
  47. data/spec/support/models/default_author.rb +1 -1
  48. data/spec/support/models/post.rb +4 -4
  49. data/spec/support/models/tag.rb +1 -1
  50. data/spec/support/models/typecasted_author.rb +4 -5
  51. data/spec/support/protobuf.rb +5 -5
  52. metadata +24 -26
  53. data/lib/active_remote/attribute_assignment.rb +0 -53
  54. data/lib/active_remote/type.rb +0 -36
  55. data/lib/active_remote/type/registry.rb +0 -45
  56. data/lib/active_remote/typecasting.rb +0 -51
  57. data/lib/active_remote/typecasting/big_decimal_typecaster.rb +0 -21
  58. data/lib/active_remote/typecasting/boolean.rb +0 -7
  59. data/lib/active_remote/typecasting/boolean_typecaster.rb +0 -18
  60. data/lib/active_remote/typecasting/date_time_typecaster.rb +0 -10
  61. data/lib/active_remote/typecasting/date_typecaster.rb +0 -10
  62. data/lib/active_remote/typecasting/float_typecaster.rb +0 -9
  63. data/lib/active_remote/typecasting/integer_typecaster.rb +0 -10
  64. data/lib/active_remote/typecasting/object_typecaster.rb +0 -9
  65. data/lib/active_remote/typecasting/string_typecaster.rb +0 -9
  66. data/spec/lib/active_remote/errors_spec.rb +0 -31
  67. data/spec/lib/active_remote/typecasting_spec.rb +0 -53
@@ -1,11 +1,10 @@
1
- require 'active_support/inflector'
1
+ require "active_support/inflector"
2
2
 
3
3
  module ActiveRemote
4
4
  module DSL
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module ClassMethods
8
-
9
8
  # Whitelist enable attributes for serialization purposes.
10
9
  #
11
10
  # ====Examples
@@ -121,10 +120,10 @@ module ActiveRemote
121
120
  # the class constant.
122
121
  #
123
122
  def _determine_service_class
124
- class_name = [ namespace, service_name ].join("/")
123
+ class_name = [namespace, service_name].join("/")
125
124
  const_name = class_name.camelize
126
125
 
127
- return const_name.present? ? const_name.constantize : const_name
126
+ const_name.present? ? const_name.constantize : const_name
128
127
  end
129
128
 
130
129
  def _determine_service_name
@@ -18,7 +18,7 @@ module ActiveRemote
18
18
 
19
19
  def initialize(record)
20
20
  @record = record
21
- errors = @record.errors.full_messages.join(', ')
21
+ errors = @record.errors.full_messages.join(", ")
22
22
  super(errors)
23
23
  end
24
24
  end
@@ -43,16 +43,6 @@ module ActiveRemote
43
43
  # Raised by ActiveRemove::Base.save! and ActiveRemote::Base.create! methods
44
44
  # when remote record cannot be saved because it is invalid.
45
45
  class RemoteRecordNotSaved < ActiveRemoteError
46
- attr_reader :record
47
-
48
- def initialize(message_or_record = nil)
49
- message = message_or_record
50
- if message_or_record.is_a?(::ActiveRemote::Base)
51
- @record = message_or_record
52
- message = @record.errors.full_messages.join(", ")
53
- end
54
- super(message)
55
- end
56
46
  end
57
47
 
58
48
  class UnknownAttributeError < ActiveRemoteError
@@ -1,4 +1,4 @@
1
- require 'active_remote/rpc'
1
+ require "active_remote/rpc"
2
2
 
3
3
  module ActiveRemote
4
4
  module Persistence
@@ -20,7 +20,6 @@ module ActiveRemote
20
20
  end
21
21
 
22
22
  module ClassMethods
23
-
24
23
  # Creates a remote record through the service.
25
24
  #
26
25
  # The service will run any validations and if any of them fail, will return
@@ -81,7 +80,7 @@ module ActiveRemote
81
80
 
82
81
  add_errors(response.errors) if response.respond_to?(:errors)
83
82
 
84
- return success? ? freeze : false
83
+ success? ? freeze : false
85
84
  end
86
85
 
87
86
  # Deletes the record from the service (the service determines if the
@@ -92,7 +91,7 @@ module ActiveRemote
92
91
  #
93
92
  def delete!
94
93
  delete
95
- raise ActiveRemoteError.new(errors.to_s) if has_errors?
94
+ raise ActiveRemoteError, errors.to_s if has_errors?
96
95
  end
97
96
 
98
97
  # Destroys (hard deletes) the record from the service and freezes this
@@ -106,7 +105,7 @@ module ActiveRemote
106
105
 
107
106
  add_errors(response.errors) if response.respond_to?(:errors)
108
107
 
109
- return success? ? freeze : false
108
+ success? ? freeze : false
110
109
  end
111
110
 
112
111
  # Destroys (hard deletes) the record from the service and freezes this
@@ -116,13 +115,13 @@ module ActiveRemote
116
115
  #
117
116
  def destroy!
118
117
  destroy
119
- raise ActiveRemoteError.new(errors.to_s) if has_errors?
118
+ raise ActiveRemoteError, errors.to_s if has_errors?
120
119
  end
121
120
 
122
121
  # Returns true if the record has errors; otherwise, returns false.
123
122
  #
124
123
  def has_errors?
125
- return respond_to?(:errors) && errors.present?
124
+ respond_to?(:errors) && errors.present?
126
125
  end
127
126
 
128
127
  # Instantiate a record with the given remote attributes. Generally used
@@ -143,7 +142,7 @@ module ActiveRemote
143
142
  # Returns true if the remote record has been saved; otherwise, returns false.
144
143
  #
145
144
  def persisted?
146
- return ! new_record?
145
+ !new_record?
147
146
  end
148
147
 
149
148
  # Sets the instance to be a readonly object
@@ -184,13 +183,13 @@ module ActiveRemote
184
183
  # Also runs any before/after save callbacks that are defined.
185
184
  #
186
185
  def save!(*args)
187
- save(*args) || fail(RemoteRecordNotSaved, self)
186
+ save(*args) || raise(RemoteRecordNotSaved)
188
187
  end
189
188
 
190
189
  # Returns true if the record doesn't have errors; otherwise, returns false.
191
190
  #
192
191
  def success?
193
- return ! has_errors?
192
+ !has_errors?
194
193
  end
195
194
 
196
195
  # Updates a single attribute and saves the record.
@@ -241,7 +240,7 @@ module ActiveRemote
241
240
 
242
241
  response = remote_call(:create, new_attributes)
243
242
 
244
- assign_attributes(response.to_hash)
243
+ instantiate(response.to_hash)
245
244
  add_errors(response.errors) if response.respond_to?(:errors)
246
245
 
247
246
  @new_record = has_errors?
@@ -271,7 +270,7 @@ module ActiveRemote
271
270
 
272
271
  response = remote_call(:update, updated_attributes)
273
272
 
274
- assign_attributes(response.to_hash)
273
+ instantiate(response.to_hash)
275
274
  add_errors(response.errors) if response.respond_to?(:errors)
276
275
 
277
276
  success?
@@ -3,7 +3,6 @@ module ActiveRemote
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
-
7
6
  ##
8
7
  # The default_primary_key is used to define what attribute is used
9
8
  # as a primary key for your global code base. If you use a primary
@@ -21,25 +21,25 @@ module ActiveRemote
21
21
  attribute_method_suffix "?"
22
22
  end
23
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}?")
24
+ def query_attribute(attr_name)
25
+ value = self[attr_name]
26
+
27
+ case value
28
+ when true then true
29
+ when false, nil then false
34
30
  else
35
- raise ::ActiveRemote::UnknownAttributeError, "unknown attribute: #{name}"
31
+ if value.respond_to?(:zero?)
32
+ !value.zero?
33
+ else
34
+ value.present?
35
+ end
36
36
  end
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- def attribute?(name)
42
- ::ActiveRemote::Typecasting::BooleanTypecaster.call(read_attribute(name))
41
+ def attribute?(attribute_name)
42
+ query_attribute(attribute_name)
43
43
  end
44
44
  end
45
45
  end
@@ -1,5 +1,5 @@
1
- require 'active_remote/rpc_adapters/protobuf_adapter'
2
- require 'active_remote/serializers/protobuf'
1
+ require "active_remote/rpc_adapters/protobuf_adapter"
2
+ require "active_remote/serializers/protobuf"
3
3
 
4
4
  module ActiveRemote
5
5
  module RPC
@@ -12,19 +12,13 @@ module ActiveRemote
12
12
  module ClassMethods
13
13
  # Builds an attribute hash that be assigned directly
14
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]
25
- end
15
+ def build_from_rpc(values)
16
+ values = values.stringify_keys
17
+
18
+ attributes.inject({}) do |attributes, (name, definition)|
19
+ attributes[name] = definition.from_rpc(values[name])
20
+ attributes
26
21
  end
27
- constructed_attributes
28
22
  end
29
23
 
30
24
  # Execute an RPC call to the remote service and return the raw response.
@@ -1,11 +1,11 @@
1
- require 'active_remote/serializers/protobuf'
1
+ require "active_remote/serializers/protobuf"
2
2
 
3
3
  module ActiveRemote
4
4
  module RPCAdapters
5
5
  class ProtobufAdapter
6
6
  include Serializers::Protobuf
7
7
 
8
- attr_reader :last_request, :last_response, :service_class
8
+ attr_reader :service_class
9
9
  attr_accessor :endpoints
10
10
 
11
11
  delegate :client, :to => :service_class
@@ -22,9 +22,10 @@ module ActiveRemote
22
22
  #
23
23
  def execute(endpoint, request_args)
24
24
  rpc_method = endpoints.fetch(endpoint) { endpoint }
25
- @last_request = request(rpc_method, request_args)
25
+ request = build_request(rpc_method, request_args)
26
+ response = nil
26
27
 
27
- client.__send__(rpc_method, @last_request) do |c|
28
+ client.send(rpc_method, request) do |c|
28
29
  # In the event of service failure, raise the error.
29
30
  c.on_failure do |error|
30
31
  protobuf_error = protobuf_error_class(error)
@@ -32,16 +33,26 @@ module ActiveRemote
32
33
  end
33
34
 
34
35
  # In the event of service success, assign the response.
35
- c.on_success do |response|
36
- @last_response = response
36
+ c.on_success do |rpc_response|
37
+ response = rpc_response
37
38
  end
38
39
  end
39
40
 
40
- @last_response
41
+ response
41
42
  end
42
43
 
43
44
  private
44
45
 
46
+ # Return a protobuf request object for the given rpc request.
47
+ #
48
+ def build_request(rpc_method, request_args)
49
+ return request_args unless request_args.is_a?(Hash)
50
+
51
+ message_class = request_type(rpc_method)
52
+ fields = fields_from_attributes(message_class, request_args)
53
+ message_class.new(fields)
54
+ end
55
+
45
56
  def protobuf_error_class(error)
46
57
  return ::ActiveRemote::ActiveRemoteError unless error.respond_to?(:error_type)
47
58
 
@@ -71,16 +82,6 @@ module ActiveRemote
71
82
  end
72
83
  end
73
84
 
74
- # Return a protobuf request object for the given rpc request.
75
- #
76
- def request(rpc_method, request_args)
77
- return request_args unless request_args.is_a?(Hash)
78
-
79
- message_class = request_type(rpc_method)
80
- fields = fields_from_attributes(message_class, request_args)
81
- message_class.new(fields)
82
- end
83
-
84
85
  # Return the class applicable to the request for the given rpc method.
85
86
  #
86
87
  def request_type(rpc_method)
@@ -10,7 +10,6 @@ module ActiveRemote
10
10
  end
11
11
 
12
12
  module ClassMethods
13
-
14
13
  ##
15
14
  # Allows you to define, at a class level, what keys should be
16
15
  # used as identifiers when making remote calls. For instance,
@@ -31,7 +30,7 @@ module ActiveRemote
31
30
  # persistence or refresh calls.
32
31
  #
33
32
  def scope_keys
34
- [ primary_key.to_s ] + _scope_keys
33
+ [primary_key.to_s] + _scope_keys
35
34
  end
36
35
  end
37
36
 
@@ -1,5 +1,5 @@
1
- require 'active_remote/persistence'
2
- require 'active_remote/rpc'
1
+ require "active_remote/persistence"
2
+ require "active_remote/rpc"
3
3
 
4
4
  module ActiveRemote
5
5
  module Search
@@ -26,9 +26,9 @@ module ActiveRemote
26
26
  #
27
27
  def find(args)
28
28
  remote = self.search(args).first
29
- raise RemoteRecordNotFound.new(self) if remote.nil?
29
+ raise RemoteRecordNotFound, self if remote.nil?
30
30
 
31
- return remote
31
+ remote
32
32
  end
33
33
 
34
34
  # Tries to load the first record; if it fails, then create is called
@@ -91,7 +91,9 @@ module ActiveRemote
91
91
  response = remote_call(:search, args)
92
92
 
93
93
  if response.respond_to?(:records)
94
- records = serialize_records(response.records)
94
+ serialize_records(response.records)
95
+ else
96
+ response
95
97
  end
96
98
  end
97
99
 
@@ -115,7 +117,7 @@ module ActiveRemote
115
117
  #
116
118
  def reload
117
119
  fresh_object = self.class.find(scope_key_hash)
118
- @attributes.update(fresh_object.instance_variable_get('@attributes'))
120
+ @attributes.update(fresh_object.instance_variable_get("@attributes"))
119
121
  end
120
122
  end
121
123
  end
@@ -1,5 +1,3 @@
1
- require "active_remote/type"
2
-
3
1
  module ActiveRemote
4
2
  module Serializers
5
3
  module Protobuf
@@ -99,14 +97,22 @@ module ActiveRemote
99
97
  when field.message? then
100
98
  message_value
101
99
  when field.repeated? then
102
- repeated_value.map { |value| typecast(value) }
100
+ repeated_value.map { |value| cast(value) }
103
101
  else
104
- typecasted_value
102
+ cast_value
105
103
  end
106
104
  end
107
105
 
108
106
  private
109
107
 
108
+ def cast(value)
109
+ type.cast(value)
110
+ end
111
+
112
+ def cast_value
113
+ cast(value)
114
+ end
115
+
110
116
  def message_value(attributes = nil)
111
117
  attributes ||= value
112
118
  attributes.is_a?(Hash) ? Fields.from_attributes(field.type_class, attributes) : attributes
@@ -119,31 +125,15 @@ module ActiveRemote
119
125
  end
120
126
 
121
127
  def repeated_value
122
- value.is_a?(Array) ? value : [ value ]
128
+ value.is_a?(Array) ? value : [value]
123
129
  end
124
130
 
125
- def type_name
126
- Serializers::Protobuf.type_name_for_field(field)
131
+ def type
132
+ @type ||= ::ActiveModel::Type.lookup(type_name)
127
133
  end
128
134
 
129
- def typecast(value)
130
- return value if value.nil?
131
-
132
- typecaster? ? typecaster.call(value) : value
133
- end
134
-
135
- def typecasted_value
136
- typecast(value)
137
- end
138
-
139
- def typecaster
140
- return nil if type_name.nil?
141
-
142
- @typecaster ||= Type.lookup(type_name)
143
- end
144
-
145
- def typecaster?
146
- typecaster.present?
135
+ def type_name
136
+ Serializers::Protobuf.type_name_for_field(field) || :value
147
137
  end
148
138
  end
149
139
  end
@@ -54,7 +54,7 @@ module ActiveRemote
54
54
  protected
55
55
 
56
56
  def raise_validation_error
57
- fail(::ActiveRemote::RemoteRecordInvalid.new(self))
57
+ fail ActiveRemote::RemoteRecordInvalid, self
58
58
  end
59
59
 
60
60
  def perform_validations(options = {})
@@ -1,3 +1,3 @@
1
1
  module ActiveRemote
2
- VERSION = "3.3.3"
2
+ VERSION = "5.0.0.pre"
3
3
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe ActiveRemote::Association do
4
4
  let(:record) { double(:record) }
5
- let(:records) { [ record ] }
5
+ let(:records) { [record] }
6
6
 
7
7
  describe ".belongs_to" do
8
8
  context "simple association" do
@@ -39,7 +39,7 @@ describe ActiveRemote::Association do
39
39
  end
40
40
  end
41
41
 
42
- context 'scoped field' do
42
+ context "scoped field" do
43
43
  it { is_expected.to respond_to(:user) }
44
44
 
45
45
  it "searches the associated model for multiple records" do
@@ -47,19 +47,19 @@ describe ActiveRemote::Association do
47
47
  expect(subject.user).to eq(record)
48
48
  end
49
49
 
50
- context 'when user_guid doesnt exist on model 'do
50
+ context "when user_guid doesnt exist on model " do
51
51
  before { allow(subject.class).to receive_message_chain(:public_instance_methods, :include?).with(:user_guid).and_return(false) }
52
52
 
53
- it 'raises an error' do
54
- expect {subject.user}.to raise_error(::RuntimeError, /Could not find attribute/)
53
+ it "raises an error" do
54
+ expect { subject.user }.to raise_error(::RuntimeError, /Could not find attribute/)
55
55
  end
56
56
  end
57
57
 
58
- context 'when user_guid doesnt exist on associated model 'do
58
+ context "when user_guid doesnt exist on associated model " do
59
59
  before { allow(Author).to receive_message_chain(:public_instance_methods, :include?).with(:user_guid).and_return(false) }
60
60
 
61
- it 'raises an error' do
62
- expect {subject.user}.to raise_error(::RuntimeError, /Could not find attribute/)
61
+ it "raises an error" do
62
+ expect { subject.user }.to raise_error(::RuntimeError, /Could not find attribute/)
63
63
  end
64
64
  end
65
65
  end
@@ -95,7 +95,7 @@ describe ActiveRemote::Association do
95
95
  end
96
96
 
97
97
  describe ".has_many" do
98
- let(:records) { [ record, record, record ] }
98
+ let(:records) { [record, record, record] }
99
99
  let(:guid) { "AUT-123" }
100
100
  let(:user_guid) { "USR-123" }
101
101
 
@@ -147,7 +147,7 @@ describe ActiveRemote::Association do
147
147
  end
148
148
  end
149
149
 
150
- context 'scoped field' do
150
+ context "scoped field" do
151
151
  it { is_expected.to respond_to(:user_posts) }
152
152
 
153
153
  it "searches the associated model for multiple records" do
@@ -155,19 +155,19 @@ describe ActiveRemote::Association do
155
155
  expect(subject.user_posts).to eq(records)
156
156
  end
157
157
 
158
- context 'when user_guid doesnt exist on model 'do
158
+ context "when user_guid doesnt exist on model " do
159
159
  before { allow(subject).to receive(:respond_to?).with("user_guid").and_return(false) }
160
160
 
161
- it 'raises an error' do
162
- expect {subject.user_posts}.to raise_error(::ActiveRemote::UnknownAttributeError)
161
+ it "raises an error" do
162
+ expect { subject.user_posts }.to raise_error(::ActiveRemote::UnknownAttributeError)
163
163
  end
164
164
  end
165
165
 
166
- context 'when user_guid doesnt exist on associated model 'do
166
+ context "when user_guid doesnt exist on associated model " do
167
167
  before { allow(Post).to receive_message_chain(:public_instance_methods, :include?).with(:user_guid).and_return(false) }
168
168
 
169
- it 'raises an error' do
170
- expect {subject.user_posts}.to raise_error(::RuntimeError, /Could not find attribute/)
169
+ it "raises an error" do
170
+ expect { subject.user_posts }.to raise_error(::RuntimeError, /Could not find attribute/)
171
171
  end
172
172
  end
173
173
  end
@@ -243,7 +243,7 @@ describe ActiveRemote::Association do
243
243
  end
244
244
  end
245
245
 
246
- context 'scoped field' do
246
+ context "scoped field" do
247
247
  it { is_expected.to respond_to(:chief_editor) }
248
248
 
249
249
  it "searches the associated model for multiple records" do
@@ -251,19 +251,19 @@ describe ActiveRemote::Association do
251
251
  expect(subject.chief_editor).to eq(record)
252
252
  end
253
253
 
254
- context 'when user_guid doesnt exist on model 'do
254
+ context "when user_guid doesnt exist on model " do
255
255
  before { allow(subject).to receive(:respond_to?).with("user_guid").and_return(false) }
256
256
 
257
- it 'raises an error' do
258
- expect {subject.chief_editor}.to raise_error(::ActiveRemote::UnknownAttributeError)
257
+ it "raises an error" do
258
+ expect { subject.chief_editor }.to raise_error(::ActiveRemote::UnknownAttributeError)
259
259
  end
260
260
  end
261
261
 
262
- context 'when user_guid doesnt exist on associated model 'do
262
+ context "when user_guid doesnt exist on associated model " do
263
263
  before { allow(Author).to receive_message_chain(:public_instance_methods, :include?).with(:user_guid).and_return(false) }
264
264
 
265
- it 'raises an error' do
266
- expect {subject.chief_editor}.to raise_error(::RuntimeError, /Could not find attribute/)
265
+ it "raises an error" do
266
+ expect { subject.chief_editor }.to raise_error(::RuntimeError, /Could not find attribute/)
267
267
  end
268
268
  end
269
269
  end