draper 3.0.0.pre1 → 3.0.0
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/.codeclimate.yml +16 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +24 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +3 -2
- data/CHANGELOG.md +20 -0
- data/Guardfile +5 -5
- data/README.md +27 -5
- data/Rakefile +1 -2
- data/draper.gemspec +1 -0
- data/lib/draper.rb +7 -2
- data/lib/draper/automatic_delegation.rb +5 -3
- data/lib/draper/collection_decorator.rb +1 -11
- data/lib/draper/compatibility/api_only.rb +23 -0
- data/lib/draper/configuration.rb +15 -0
- data/lib/draper/decoratable.rb +2 -2
- data/lib/draper/decorator.rb +4 -12
- data/lib/draper/finders.rb +0 -0
- data/lib/draper/helper_proxy.rb +1 -8
- data/lib/draper/railtie.rb +12 -13
- data/lib/draper/tasks/test.rake +1 -1
- data/lib/draper/test/devise_helper.rb +1 -8
- data/lib/draper/test/minitest_integration.rb +0 -0
- data/lib/draper/test/rspec_integration.rb +0 -0
- data/lib/draper/undecorate.rb +8 -0
- data/lib/draper/version.rb +1 -1
- data/lib/draper/view_context.rb +3 -19
- data/lib/draper/view_context/build_strategy.rb +11 -2
- data/lib/generators/controller_override.rb +2 -2
- data/lib/generators/draper/install_generator.rb +14 -0
- data/lib/generators/draper/templates/application_decorator.rb +8 -0
- data/lib/generators/mini_test/decorator_generator.rb +1 -1
- data/lib/generators/rails/decorator_generator.rb +1 -8
- data/lib/generators/rspec/templates/decorator_spec.rb +1 -1
- data/spec/draper/collection_decorator_spec.rb +11 -26
- data/spec/draper/configuration_spec.rb +25 -0
- data/spec/draper/decoratable_spec.rb +28 -13
- data/spec/draper/decorated_association_spec.rb +9 -9
- data/spec/draper/decorates_assigned_spec.rb +6 -6
- data/spec/draper/decorator_spec.rb +104 -89
- data/spec/draper/draper_spec.rb +24 -0
- data/spec/draper/factory_spec.rb +24 -24
- data/spec/draper/finders_spec.rb +21 -21
- data/spec/draper/helper_proxy_spec.rb +2 -2
- data/spec/draper/lazy_helpers_spec.rb +2 -2
- data/spec/draper/undecorate_chain_spec.rb +20 -0
- data/spec/draper/view_context/build_strategy_spec.rb +26 -10
- data/spec/draper/view_context_spec.rb +49 -21
- data/spec/dummy/app/controllers/base_controller.rb +4 -0
- data/spec/dummy/app/controllers/posts_controller.rb +2 -2
- data/spec/dummy/app/decorators/post_decorator.rb +0 -0
- data/spec/dummy/config/boot.rb +1 -1
- data/spec/dummy/config/initializers/draper.rb +3 -0
- data/spec/dummy/db/schema.rb +4 -4
- data/spec/dummy/fast_spec/post_decorator_spec.rb +1 -1
- data/spec/dummy/lib/tasks/test.rake +1 -1
- data/spec/dummy/spec/decorators/devise_spec.rb +0 -9
- data/spec/dummy/spec/decorators/post_decorator_spec.rb +2 -2
- data/spec/dummy/test/decorators/minitest/devise_test.rb +0 -9
- data/spec/dummy/test/decorators/minitest/view_context_test.rb +3 -3
- data/spec/dummy/test/decorators/test_unit/devise_test.rb +0 -9
- data/spec/generators/controller/controller_generator_spec.rb +3 -3
- data/spec/generators/decorator/decorator_generator_spec.rb +11 -10
- data/spec/generators/install/install_generator_spec.rb +19 -0
- data/spec/spec_helper.rb +4 -3
- data/spec/support/shared_examples/view_helpers.rb +8 -8
- metadata +38 -7
- data/spec/dummy/app/controllers/application_controller.rb +0 -4
data/lib/draper/tasks/test.rake
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
module Draper
|
2
2
|
module DeviseHelper
|
3
3
|
def sign_in(resource_or_scope, resource = nil)
|
4
|
-
scope =
|
5
|
-
Devise::Mapping.find_scope!(resource_or_scope)
|
6
|
-
rescue RuntimeError => e
|
7
|
-
# Draper 1.0 didn't require the mapping to exist
|
8
|
-
ActiveSupport::Deprecation.warn("#{e.message}.\nUse `sign_in :user, mock_user` instead.", caller)
|
9
|
-
:user
|
10
|
-
end
|
11
|
-
|
4
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
12
5
|
_stub_current_scope scope, resource || resource_or_scope
|
13
6
|
end
|
14
7
|
|
File without changes
|
File without changes
|
data/lib/draper/undecorate.rb
CHANGED
data/lib/draper/version.rb
CHANGED
data/lib/draper/view_context.rb
CHANGED
@@ -20,8 +20,10 @@ module Draper
|
|
20
20
|
RequestStore.store[:current_controller]
|
21
21
|
end
|
22
22
|
|
23
|
-
# Sets the current controller.
|
23
|
+
# Sets the current controller. Clears view context when we are setting
|
24
|
+
# different controller.
|
24
25
|
def self.controller=(controller)
|
26
|
+
clear! if RequestStore.store[:current_controller] != controller
|
25
27
|
RequestStore.store[:current_controller] = controller
|
26
28
|
end
|
27
29
|
|
@@ -82,23 +84,5 @@ module Draper
|
|
82
84
|
def self.build_strategy
|
83
85
|
@build_strategy ||= Draper::ViewContext::BuildStrategy.new(:full)
|
84
86
|
end
|
85
|
-
|
86
|
-
# @deprecated Use {controller} instead.
|
87
|
-
def self.current_controller
|
88
|
-
ActiveSupport::Deprecation.warn("Draper::ViewContext.current_controller is deprecated (use controller instead)", caller)
|
89
|
-
self.controller || ApplicationController.new
|
90
|
-
end
|
91
|
-
|
92
|
-
# @deprecated Use {controller=} instead.
|
93
|
-
def self.current_controller=(controller)
|
94
|
-
ActiveSupport::Deprecation.warn("Draper::ViewContext.current_controller= is deprecated (use controller instead)", caller)
|
95
|
-
self.controller = controller
|
96
|
-
end
|
97
|
-
|
98
|
-
# @deprecated Use {build} instead.
|
99
|
-
def self.build_view_context
|
100
|
-
ActiveSupport::Deprecation.warn("Draper::ViewContext.build_view_context is deprecated (use build instead)", caller)
|
101
|
-
build
|
102
|
-
end
|
103
87
|
end
|
104
88
|
end
|
@@ -37,10 +37,19 @@ module Draper
|
|
37
37
|
attr_reader :block
|
38
38
|
|
39
39
|
def controller
|
40
|
-
|
41
|
-
|
40
|
+
Draper::ViewContext.controller ||= Draper.default_controller.new
|
41
|
+
Draper::ViewContext.controller.tap do |controller|
|
42
|
+
controller.request ||= new_test_request controller if defined?(ActionController::TestRequest)
|
42
43
|
end
|
43
44
|
end
|
45
|
+
|
46
|
+
def new_test_request(controller)
|
47
|
+
is_above_rails_5_1 ? ActionController::TestRequest.create(controller) : ActionController::TestRequest.create
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_above_rails_5_1
|
51
|
+
ActionController::TestRequest.method(:create).parameters.first == [:req, :controller_class]
|
52
|
+
end
|
44
53
|
end
|
45
54
|
|
46
55
|
end
|
@@ -5,13 +5,13 @@ require "rails/generators/rails/scaffold_controller/scaffold_controller_generato
|
|
5
5
|
module Rails
|
6
6
|
module Generators
|
7
7
|
class ControllerGenerator
|
8
|
-
hook_for :decorator, default: true do |generator|
|
8
|
+
hook_for :decorator, type: :boolean, default: true do |generator|
|
9
9
|
invoke generator, [name.singularize]
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
13
|
class ScaffoldControllerGenerator
|
14
|
-
hook_for :decorator, default: true
|
14
|
+
hook_for :decorator, type: :boolean, default: true
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Draper
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
|
6
|
+
desc 'Creates an ApplicationDecorator, if none exists.'
|
7
|
+
|
8
|
+
def create_application_decorator
|
9
|
+
file = 'application_decorator.rb'
|
10
|
+
copy_file file, "app/decorators/#{file}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -7,7 +7,7 @@ module MiniTest
|
|
7
7
|
File.expand_path('../templates', __FILE__)
|
8
8
|
end
|
9
9
|
|
10
|
-
class_option :spec, :
|
10
|
+
class_option :spec, type: :boolean, default: false, desc: "Use MiniTest::Spec DSL"
|
11
11
|
|
12
12
|
check_class_collision suffix: "DecoratorTest"
|
13
13
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Rails
|
2
2
|
module Generators
|
3
|
-
|
3
|
+
class DecoratorGenerator < NamedBase
|
4
4
|
source_root File.expand_path("../templates", __FILE__)
|
5
5
|
check_class_collision suffix: "Decorator"
|
6
6
|
|
@@ -24,13 +24,6 @@ module Rails
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
28
|
-
# Rails 3.0.X compatibility, stolen from https://github.com/jnunemaker/mongomapper/pull/385/files#L1R32
|
29
|
-
unless methods.include?(:module_namespacing)
|
30
|
-
def module_namespacing
|
31
|
-
yield if block_given?
|
32
|
-
end
|
33
|
-
end
|
34
27
|
end
|
35
28
|
end
|
36
29
|
end
|
@@ -63,7 +63,7 @@ module Draper
|
|
63
63
|
it "does not trigger decoration" do
|
64
64
|
decorator = CollectionDecorator.new([])
|
65
65
|
|
66
|
-
decorator.
|
66
|
+
expect(decorator).not_to receive(:decorated_collection)
|
67
67
|
decorator.context = {other: "context"}
|
68
68
|
end
|
69
69
|
|
@@ -110,37 +110,22 @@ module Draper
|
|
110
110
|
protect_class ProductsDecorator
|
111
111
|
|
112
112
|
it "defaults the :to option to :object" do
|
113
|
-
Object.
|
113
|
+
expect(Object).to receive(:delegate).with(:foo, :bar, to: :object)
|
114
114
|
ProductsDecorator.delegate :foo, :bar
|
115
115
|
end
|
116
116
|
|
117
117
|
it "does not overwrite the :to option if supplied" do
|
118
|
-
Object.
|
118
|
+
expect(Object).to receive(:delegate).with(:foo, :bar, to: :baz)
|
119
119
|
ProductsDecorator.delegate :foo, :bar, to: :baz
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
describe "#find" do
|
124
|
-
|
125
|
-
|
126
|
-
decorator = CollectionDecorator.new([])
|
127
|
-
|
128
|
-
decorator.decorated_collection.should_receive(:find).and_return(:delegated)
|
129
|
-
expect(decorator.find{|p| p.title == "title"}).to be :delegated
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
context "without a block" do
|
134
|
-
it "decorates object.find" do
|
135
|
-
object = []
|
136
|
-
found = double(decorate: :decorated)
|
137
|
-
decorator = CollectionDecorator.new(object)
|
124
|
+
it "decorates Enumerable#find" do
|
125
|
+
decorator = CollectionDecorator.new([])
|
138
126
|
|
139
|
-
|
140
|
-
|
141
|
-
expect(decorator.find(1)).to be :decorated
|
142
|
-
end
|
143
|
-
end
|
127
|
+
expect(decorator.decorated_collection).to receive(:find).and_return(:delegated)
|
128
|
+
expect(decorator.find{|p| p.title == "title"}).to be :delegated
|
144
129
|
end
|
145
130
|
end
|
146
131
|
|
@@ -149,7 +134,7 @@ module Draper
|
|
149
134
|
it "delegates to the decorated collection" do
|
150
135
|
decorator = CollectionDecorator.new([])
|
151
136
|
|
152
|
-
decorator.decorated_collection.
|
137
|
+
expect(decorator.decorated_collection).to receive(:to_ary).and_return(:delegated)
|
153
138
|
expect(decorator.to_ary).to be :delegated
|
154
139
|
end
|
155
140
|
end
|
@@ -157,7 +142,7 @@ module Draper
|
|
157
142
|
it "delegates array methods to the decorated collection" do
|
158
143
|
decorator = CollectionDecorator.new([])
|
159
144
|
|
160
|
-
decorator.
|
145
|
+
allow(decorator).to receive_message_chain(:decorated_collection, :[]).with(42).and_return(:delegated)
|
161
146
|
expect(decorator[42]).to be :delegated
|
162
147
|
end
|
163
148
|
|
@@ -267,14 +252,14 @@ module Draper
|
|
267
252
|
describe '#kind_of?' do
|
268
253
|
it 'asks the kind of its decorated collection' do
|
269
254
|
decorator = ProductsDecorator.new([])
|
270
|
-
decorator.decorated_collection.
|
255
|
+
expect(decorator.decorated_collection).to receive(:kind_of?).with(Array).and_return("true")
|
271
256
|
expect(decorator.kind_of?(Array)).to eq "true"
|
272
257
|
end
|
273
258
|
|
274
259
|
context 'when asking the underlying collection returns false' do
|
275
260
|
it 'asks the CollectionDecorator instance itself' do
|
276
261
|
decorator = ProductsDecorator.new([])
|
277
|
-
decorator.decorated_collection.
|
262
|
+
allow(decorator.decorated_collection).to receive(:kind_of?).with(::Draper::CollectionDecorator).and_return(false)
|
278
263
|
expect(decorator.kind_of?(::Draper::CollectionDecorator)).to be true
|
279
264
|
end
|
280
265
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Draper
|
4
|
+
RSpec.describe Configuration do
|
5
|
+
it 'yields Draper on configure' do
|
6
|
+
Draper.configure { |config| expect(config).to be Draper }
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'defaults default_controller to ApplicationController' do
|
10
|
+
expect(Draper.default_controller).to be ApplicationController
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'allows customizing default_controller through configure' do
|
14
|
+
default = Draper.default_controller
|
15
|
+
|
16
|
+
Draper.configure do |config|
|
17
|
+
config.default_controller = CustomController
|
18
|
+
end
|
19
|
+
|
20
|
+
expect(Draper.default_controller).to be CustomController
|
21
|
+
|
22
|
+
Draper.default_controller = default
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -22,7 +22,7 @@ module Draper
|
|
22
22
|
|
23
23
|
it "uses the #decorator_class" do
|
24
24
|
product = Product.new
|
25
|
-
product.
|
25
|
+
allow(product).to receive_messages decorator_class: OtherDecorator
|
26
26
|
|
27
27
|
expect(product.decorate).to be_an_instance_of OtherDecorator
|
28
28
|
end
|
@@ -70,7 +70,7 @@ module Draper
|
|
70
70
|
it "delegates to .decorator_class" do
|
71
71
|
product = Product.new
|
72
72
|
|
73
|
-
Product.
|
73
|
+
expect(Product).to receive(:decorator_class).and_return(:some_decorator)
|
74
74
|
expect(product.decorator_class).to be :some_decorator
|
75
75
|
end
|
76
76
|
end
|
@@ -83,14 +83,14 @@ module Draper
|
|
83
83
|
it "is true when #== is true" do
|
84
84
|
product = Product.new
|
85
85
|
|
86
|
-
product.
|
86
|
+
expect(product).to receive(:==).and_return(true)
|
87
87
|
expect(product === :anything).to be_truthy
|
88
88
|
end
|
89
89
|
|
90
90
|
it "is false when #== is false" do
|
91
91
|
product = Product.new
|
92
92
|
|
93
|
-
product.
|
93
|
+
expect(product).to receive(:==).and_return(false)
|
94
94
|
expect(product === :anything).to be_falsey
|
95
95
|
end
|
96
96
|
end
|
@@ -109,19 +109,25 @@ module Draper
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it "is true for a decorated instance" do
|
112
|
-
decorator =
|
112
|
+
decorator = Product.new.decorate
|
113
113
|
|
114
114
|
expect(Product === decorator).to be_truthy
|
115
115
|
end
|
116
116
|
|
117
117
|
it "is true for a decorated derived instance" do
|
118
|
-
decorator =
|
118
|
+
decorator = Class.new(Product).new.decorate
|
119
119
|
|
120
120
|
expect(Product === decorator).to be_truthy
|
121
121
|
end
|
122
122
|
|
123
123
|
it "is false for a decorated unrelated instance" do
|
124
|
-
decorator =
|
124
|
+
decorator = Other.new.decorate
|
125
|
+
|
126
|
+
expect(Product === decorator).to be_falsey
|
127
|
+
end
|
128
|
+
|
129
|
+
it "is false for a non-decorator which happens to respond to object" do
|
130
|
+
decorator = double(object: Product.new)
|
125
131
|
|
126
132
|
expect(Product === decorator).to be_falsey
|
127
133
|
end
|
@@ -130,17 +136,17 @@ module Draper
|
|
130
136
|
describe ".decorate" do
|
131
137
|
it "calls #decorate_collection on .decorator_class" do
|
132
138
|
scoped = [Product.new]
|
133
|
-
Product.
|
139
|
+
allow(Product).to receive(:all).and_return(scoped)
|
134
140
|
|
135
|
-
Product.decorator_class.
|
141
|
+
expect(Product.decorator_class).to receive(:decorate_collection).with(scoped, with: nil).and_return(:decorated_collection)
|
136
142
|
expect(Product.decorate).to be :decorated_collection
|
137
143
|
end
|
138
144
|
|
139
145
|
it "accepts options" do
|
140
146
|
options = {with: ProductDecorator, context: {some: "context"}}
|
141
|
-
Product.
|
147
|
+
allow(Product).to receive(:all).and_return([])
|
142
148
|
|
143
|
-
Product.decorator_class.
|
149
|
+
expect(Product.decorator_class).to receive(:decorate_collection).with([], options)
|
144
150
|
Product.decorate(options)
|
145
151
|
end
|
146
152
|
end
|
@@ -175,13 +181,22 @@ module Draper
|
|
175
181
|
|
176
182
|
context "for ActiveModel classes" do
|
177
183
|
it "infers the decorator from the model name" do
|
178
|
-
Namespaced::Product.
|
184
|
+
allow(Namespaced::Product).to receive(:model_name).and_return("Namespaced::Other")
|
179
185
|
|
180
186
|
expect(Namespaced::Product.decorator_class).to be Namespaced::OtherDecorator
|
181
187
|
end
|
182
188
|
end
|
183
189
|
end
|
184
190
|
|
191
|
+
context "when the decorator contains name error" do
|
192
|
+
it "throws an NameError" do
|
193
|
+
# We imitate ActiveSupport::Autoload behavior here in order to cause lazy NameError exception raising
|
194
|
+
allow_any_instance_of(Module).to receive(:const_missing) { Class.new { any_nonexisting_method_name } }
|
195
|
+
|
196
|
+
expect{Model.decorator_class}.to raise_error { |error| expect(error).to be_an_instance_of(NameError) }
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
185
200
|
context "when the decorator can't be inferred" do
|
186
201
|
it "throws an UninferrableDecoratorError" do
|
187
202
|
expect{Model.decorator_class}.to raise_error UninferrableDecoratorError
|
@@ -190,7 +205,7 @@ module Draper
|
|
190
205
|
|
191
206
|
context "when an unrelated NameError is thrown" do
|
192
207
|
it "re-raises that error" do
|
193
|
-
String.
|
208
|
+
allow_any_instance_of(String).to receive(:constantize) { Draper::Base }
|
194
209
|
expect{Product.decorator_class}.to raise_error NameError, /Draper::Base/
|
195
210
|
end
|
196
211
|
end
|
@@ -16,20 +16,20 @@ module Draper
|
|
16
16
|
it "creates a factory" do
|
17
17
|
options = {with: Decorator, context: {foo: "bar"}}
|
18
18
|
|
19
|
-
Factory.
|
19
|
+
expect(Factory).to receive(:new).with(options)
|
20
20
|
DecoratedAssociation.new(double, :association, options)
|
21
21
|
end
|
22
22
|
|
23
23
|
describe ":with option" do
|
24
24
|
it "defaults to nil" do
|
25
|
-
Factory.
|
25
|
+
expect(Factory).to receive(:new).with(with: nil, context: anything())
|
26
26
|
DecoratedAssociation.new(double, :association, {})
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
describe ":context option" do
|
31
31
|
it "defaults to the identity function" do
|
32
|
-
Factory.
|
32
|
+
expect(Factory).to receive(:new) do |options|
|
33
33
|
options[:context].call(:anything) == :anything
|
34
34
|
end
|
35
35
|
DecoratedAssociation.new(double, :association, {})
|
@@ -40,7 +40,7 @@ module Draper
|
|
40
40
|
describe "#call" do
|
41
41
|
it "calls the factory" do
|
42
42
|
factory = double
|
43
|
-
Factory.
|
43
|
+
allow(Factory).to receive_messages(new: factory)
|
44
44
|
associated = double
|
45
45
|
owner_context = {foo: "bar"}
|
46
46
|
object = double(association: associated)
|
@@ -48,18 +48,18 @@ module Draper
|
|
48
48
|
decorated_association = DecoratedAssociation.new(owner, :association, {})
|
49
49
|
decorated = double
|
50
50
|
|
51
|
-
factory.
|
51
|
+
expect(factory).to receive(:decorate).with(associated, context_args: owner_context).and_return(decorated)
|
52
52
|
expect(decorated_association.call).to be decorated
|
53
53
|
end
|
54
54
|
|
55
55
|
it "memoizes" do
|
56
56
|
factory = double
|
57
|
-
Factory.
|
57
|
+
allow(Factory).to receive_messages(new: factory)
|
58
58
|
owner = double(object: double(association: double), context: {})
|
59
59
|
decorated_association = DecoratedAssociation.new(owner, :association, {})
|
60
60
|
decorated = double
|
61
61
|
|
62
|
-
factory.
|
62
|
+
expect(factory).to receive(:decorate).once.and_return(decorated)
|
63
63
|
expect(decorated_association.call).to be decorated
|
64
64
|
expect(decorated_association.call).to be decorated
|
65
65
|
end
|
@@ -67,14 +67,14 @@ module Draper
|
|
67
67
|
context "when the :scope option was given" do
|
68
68
|
it "applies the scope before decoration" do
|
69
69
|
factory = double
|
70
|
-
Factory.
|
70
|
+
allow(Factory).to receive_messages(new: factory)
|
71
71
|
scoped = double
|
72
72
|
object = double(association: double(applied_scope: scoped))
|
73
73
|
owner = double(object: object, context: {})
|
74
74
|
decorated_association = DecoratedAssociation.new(owner, :association, scope: :applied_scope)
|
75
75
|
decorated = double
|
76
76
|
|
77
|
-
factory.
|
77
|
+
expect(factory).to receive(:decorate).with(scoped, anything()).and_return(decorated)
|
78
78
|
expect(decorated_association.call).to be decorated
|
79
79
|
end
|
80
80
|
end
|