active_remote-cached 1.0.0 → 1.2.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.
@@ -1,63 +1,94 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  class SearchMethodClass
4
6
  include ::ActiveRemote::Cached
5
7
 
6
- def self.derp; nil; end
7
- def self.find; nil; end
8
- def self.search; nil; end
8
+ def self.derp
9
+ nil
10
+ end
11
+
12
+ def self.find
13
+ nil
14
+ end
15
+
16
+ def self.search
17
+ nil
18
+ end
9
19
 
10
20
  cached_finders_for :foo, :expires_in => 500
11
21
  cached_finders_for :guid
12
22
  cached_finders_for :guid, :user_guid
13
- cached_finders_for [:user_guid, :client_guid]
14
- cached_finders_for [:derp, :user_guid, :client_guid]
23
+ cached_finders_for %i[user_guid client_guid]
24
+ cached_finders_for %i[derp user_guid client_guid]
25
+ cached_finders_for %i[zippy123 alpha]
15
26
  end
16
27
 
17
28
  describe SearchMethodClass do
18
- describe "API" do
29
+ let(:versioned_prefix) { ::ActiveRemote::Cached::RUBY_AND_ACTIVE_SUPPORT_VERSION }
30
+
31
+ describe 'API' do
19
32
  it "creates 'cached_search_by_foo'" do
20
- SearchMethodClass.must_respond_to("cached_search_by_foo")
33
+ expect(SearchMethodClass).to respond_to(:cached_search_by_foo)
21
34
  end
22
35
 
23
36
  it "creates 'cached_search_by_foo!'" do
24
- SearchMethodClass.must_respond_to("cached_search_by_foo!")
37
+ expect(SearchMethodClass).to respond_to(:cached_search_by_foo!)
25
38
  end
26
39
 
27
40
  it "creates 'cached_search_by_guid'" do
28
- SearchMethodClass.must_respond_to("cached_search_by_guid")
41
+ expect(SearchMethodClass).to respond_to(:cached_search_by_guid)
29
42
  end
30
43
 
31
44
  it "creates 'cached_search_by_user_guid'" do
32
- SearchMethodClass.must_respond_to("cached_search_by_user_guid")
45
+ expect(SearchMethodClass).to respond_to(:cached_search_by_user_guid)
33
46
  end
34
47
 
35
48
  it "creates 'cached_search_by_user_guid_and_client_guid'" do
36
- SearchMethodClass.must_respond_to("cached_search_by_user_guid_and_client_guid")
49
+ expect(SearchMethodClass).to respond_to(:cached_search_by_user_guid_and_client_guid)
37
50
  end
38
51
 
39
52
  it "creates 'cached_search_by_client_guid_and_user_guid'" do
40
- SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid")
53
+ expect(SearchMethodClass).to respond_to(:cached_search_by_client_guid_and_user_guid)
41
54
  end
42
55
 
43
56
  it "creates 'cached_search_by_derp_and_user_guid_and_client_guid'" do
44
- SearchMethodClass.must_respond_to("cached_search_by_derp_and_user_guid_and_client_guid")
57
+ expect(SearchMethodClass).to respond_to(:cached_search_by_derp_and_user_guid_and_client_guid)
45
58
  end
46
59
 
47
60
  it "creates 'cached_search_by_client_guid_and_derp_and_user_guid'" do
48
- SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_derp_and_user_guid")
61
+ expect(SearchMethodClass).to respond_to(:cached_search_by_client_guid_and_derp_and_user_guid)
49
62
  end
50
63
 
51
64
  it "creates 'cached_search_by_client_guid_and_user_guid_and_derp'" do
52
- SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp")
65
+ expect(SearchMethodClass).to respond_to(:cached_search_by_client_guid_and_user_guid_and_derp)
53
66
  end
54
67
 
55
68
  it "creates 'cached_search_by_client_guid_and_user_guid_and_derp!'" do
56
- SearchMethodClass.must_respond_to("cached_search_by_client_guid_and_user_guid_and_derp!")
69
+ expect(SearchMethodClass).to respond_to(:cached_search_by_client_guid_and_user_guid_and_derp!)
70
+ end
71
+
72
+ # Ensure it works with numbers in method name
73
+ it "creates 'cached_search_by_alpha_and_zippy123'" do
74
+ expect(SearchMethodClass).to respond_to(:cached_search_by_alpha_and_zippy123)
75
+ end
76
+
77
+ # Ensure it responds to methods where params are not sorted
78
+ # i.e. the method missing override is used.
79
+ it "responds to 'cached_search_by_zippy123_and_alpha'" do
80
+ expect(SearchMethodClass).to respond_to(:cached_search_by_zippy123_and_alpha)
81
+ end
82
+
83
+ # Ensure the right method actually gets called when
84
+ # method_missing override is used.
85
+ it "can call 'cached_search_by_zippy123_and_alpha' when not defined" do
86
+ expect(SearchMethodClass).to receive(:search)
87
+ SearchMethodClass.cached_search_by_zippy123_and_alpha('abc', '123')
57
88
  end
58
89
  end
59
90
 
60
- describe "#cached_search_by_guid" do
91
+ describe '#cached_search_by_guid' do
61
92
  before do
62
93
  ::ActiveRemote::Cached.cache(HashCache.new)
63
94
  ::ActiveRemote::Cached.default_options(:expires_in => 100)
@@ -67,108 +98,105 @@ describe SearchMethodClass do
67
98
  ::ActiveRemote::Cached.default_options({})
68
99
  end
69
100
 
70
- it "executes the search block when a block is passed" do
71
- SearchMethodClass.stub(:derp, :derp) do
72
- SearchMethodClass.cached_search(:guid => :guid) do
73
- SearchMethodClass.derp
74
- end.must_equal(:derp)
75
- end
101
+ it 'executes the search block when a block is passed' do
102
+ expect(SearchMethodClass).to receive(:derp).and_return(:derp)
103
+ expect(SearchMethodClass.cached_search(:guid => :guid) do
104
+ SearchMethodClass.derp
105
+ end).to eq(:derp)
76
106
  end
77
107
 
78
- it "does not persist empty values by default" do
79
- SearchMethodClass.stub(:derp, []) do
80
- SearchMethodClass.cached_search(:guid => :guid) do
81
- SearchMethodClass.derp
82
- end
108
+ it 'does not persist empty values by default' do
109
+ expect(SearchMethodClass).to receive(:derp).and_return([])
83
110
 
84
- SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(false)
111
+ SearchMethodClass.cached_search(:guid => :guid) do
112
+ SearchMethodClass.derp
85
113
  end
86
- end
87
114
 
88
- it "persists empty values when allow_empty sent" do
89
- SearchMethodClass.stub(:derp, []) do
90
- SearchMethodClass.cached_search({:guid => :guid}, :allow_empty => true) do
91
- SearchMethodClass.derp
92
- end
115
+ expect(SearchMethodClass.cached_exist_search_by_guid?(:guid)).to eq(false)
116
+ end
93
117
 
94
- SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true)
118
+ it 'persists empty values when allow_empty sent' do
119
+ expect(SearchMethodClass).to receive(:derp).and_return([])
120
+ SearchMethodClass.cached_search({ :guid => :guid }, :allow_empty => true) do
121
+ SearchMethodClass.derp
95
122
  end
96
- end
97
123
 
98
- it "does not persist nil values by default" do
99
- SearchMethodClass.stub(:derp, nil) do
100
- SearchMethodClass.cached_search(:guid => :guid) do
101
- SearchMethodClass.derp
102
- end
124
+ expect(SearchMethodClass.cached_exist_search_by_guid?(:guid)).to eq(true)
125
+ end
103
126
 
104
- SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(false)
127
+ it 'does not persist nil values by default' do
128
+ expect(SearchMethodClass).to receive(:derp).and_return(nil)
129
+ SearchMethodClass.cached_search(:guid => :guid) do
130
+ SearchMethodClass.derp
105
131
  end
106
- end
107
132
 
108
- it "persists nil values when allow_nil sent" do
109
- SearchMethodClass.stub(:derp, nil) do
110
- SearchMethodClass.cached_search({:guid => :guid}, :allow_nil => true) do
111
- SearchMethodClass.derp
112
- end
133
+ expect(SearchMethodClass.cached_exist_search_by_guid?(:guid)).to eq(false)
134
+ end
113
135
 
114
- SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true)
136
+ it 'persists nil values when allow_nil sent' do
137
+ expect(SearchMethodClass).to receive(:derp).and_return(nil)
138
+ SearchMethodClass.cached_search({ :guid => :guid }, :allow_nil => true) do
139
+ SearchMethodClass.derp
115
140
  end
116
- end
117
141
 
118
- it "does persist non nil values" do
119
- SearchMethodClass.stub(:derp, :derp) do
120
- SearchMethodClass.cached_search(:guid => :guid) do
121
- SearchMethodClass.derp
122
- end
142
+ expect(SearchMethodClass.cached_exist_search_by_guid?(:guid)).to eq(true)
143
+ end
123
144
 
124
- SearchMethodClass.cached_exist_search_by_guid?(:guid).must_equal(true)
145
+ it 'does persist non nil values' do
146
+ expect(SearchMethodClass).to receive(:derp).and_return(:derp)
147
+ SearchMethodClass.cached_search(:guid => :guid) do
148
+ SearchMethodClass.derp
125
149
  end
150
+
151
+ expect(SearchMethodClass.cached_exist_search_by_guid?(:guid)).to eq(true)
126
152
  end
127
153
 
128
- it "executes search_by_guid when cached_search with guid called" do
129
- FindMethodClass.stub(:search, :hello) do
130
- FindMethodClass.cached_search(:guid => :guid).must_equal(:hello)
131
- end
154
+ it 'executes search_by_guid when cached_search with guid called' do
155
+ expect(SearchMethodClass).to receive(:search).and_return(:hello)
156
+
157
+ expect(SearchMethodClass.cached_search(:guid => :guid)).to eq(:hello)
132
158
  end
133
159
 
134
- it "executes the fetch block if not present in cache" do
135
- SearchMethodClass.stub(:search, :hello) do
136
- SearchMethodClass.cached_search_by_guid(:guid).must_equal(:hello)
137
- end
160
+ it 'executes the fetch block if not present in cache' do
161
+ expect(SearchMethodClass).to receive(:search).and_return(:hello)
162
+ expect(SearchMethodClass.cached_search_by_guid(:guid)).to eq(:hello)
138
163
  end
139
164
 
140
- it "merges the default options in for the fetch call" do
141
- ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "guid"], :expires_in => 100).returns(:hello)
165
+ it 'merges the default options in for the fetch call' do
166
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
167
+ [versioned_prefix, SearchMethodClass.name, '#search', 'guid.guid'], { :expires_in => 100 }
168
+ ).and_return(:hello)
142
169
 
143
- SearchMethodClass.stub(:search, :hello) do
144
- SearchMethodClass.cached_search_by_guid(:guid).must_equal(:hello)
145
- end
170
+ expect(SearchMethodClass).not_to receive(:search)
171
+ expect(SearchMethodClass.cached_search_by_guid(:guid)).to eq(:hello)
146
172
  end
147
173
 
148
- it "overrides the default options with local options for the fetch call" do
149
- ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "guid"], :expires_in => 200).returns(:hello)
174
+ it 'overrides the default options with local options for the fetch call' do
175
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
176
+ [versioned_prefix, SearchMethodClass.name, '#search', 'guid.guid'], { :expires_in => 200 }
177
+ ).and_return(:hello)
150
178
 
151
- SearchMethodClass.stub(:search, :hello) do
152
- SearchMethodClass.cached_search_by_guid(:guid, :expires_in => 200).must_equal(:hello)
153
- end
179
+ expect(SearchMethodClass).not_to receive(:search)
180
+ expect(SearchMethodClass.cached_search_by_guid(:guid, { :expires_in => 200 })).to eq(:hello)
154
181
  end
155
182
 
156
- describe "namespaced cache" do
183
+ describe 'namespaced cache' do
157
184
  before do
158
- ::ActiveRemote::Cached.default_options(:expires_in => 100, :namespace => "MyApp")
185
+ ::ActiveRemote::Cached.default_options(:expires_in => 100, :namespace => 'MyApp')
159
186
  end
160
187
 
161
- it "uses the namespace as a prefix to the cache key" do
162
- ::ActiveRemote::Cached.cache.expects(:fetch).with(["MyApp", SearchMethodClass.name, "#search", "guid"], :expires_in => 100).returns(:hello)
188
+ it 'uses the namespace as a prefix to the cache key' do
189
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
190
+ [versioned_prefix, 'MyApp', SearchMethodClass.name, '#search', 'guid.guid'], { :expires_in => 100 }
191
+ ).and_return(:hello)
163
192
 
164
- SearchMethodClass.stub(:search, :hello) do
165
- SearchMethodClass.cached_search_by_guid(:guid)
166
- end
193
+ expect(SearchMethodClass).not_to receive(:search)
194
+ SearchMethodClass.cached_search_by_guid(:guid)
167
195
  end
168
196
  end
169
197
  end
170
198
 
171
- describe "#cached_search_by_foo" do
199
+ describe '#cached_search_by_foo' do
172
200
  before do
173
201
  ::ActiveRemote::Cached.cache(HashCache.new)
174
202
  ::ActiveRemote::Cached.default_options(:expires_in => 100)
@@ -178,24 +206,26 @@ describe SearchMethodClass do
178
206
  ::ActiveRemote::Cached.default_options({})
179
207
  end
180
208
 
181
- it "overrides the default options with cached_finder options for the fetch call" do
182
- ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "foo"], :expires_in => 500).returns(:hello)
209
+ it 'overrides the default options with cached_finder options for the fetch call' do
210
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
211
+ [versioned_prefix, SearchMethodClass.name, '#search', 'foo.foo'], { :expires_in => 500 }
212
+ ).and_return(:hello)
183
213
 
184
- SearchMethodClass.stub(:find, :hello) do
185
- SearchMethodClass.cached_search_by_foo(:foo).must_equal(:hello)
186
- end
214
+ expect(SearchMethodClass).not_to receive(:find)
215
+ expect(SearchMethodClass.cached_search_by_foo(:foo)).to eq(:hello)
187
216
  end
188
217
 
189
- it "overrides the cached_finder options with local options for the fetch call" do
190
- ::ActiveRemote::Cached.cache.expects(:fetch).with([SearchMethodClass.name, "#search", "foo"], :expires_in => 200).returns(:hello)
218
+ it 'overrides the cached_finder options with local options for the fetch call' do
219
+ expect(::ActiveRemote::Cached.cache).to receive(:fetch).with(
220
+ [versioned_prefix, SearchMethodClass.name, '#search', 'foo.foo'], { :expires_in => 200 }
221
+ ).and_return(:hello)
191
222
 
192
- SearchMethodClass.stub(:find, :hello) do
193
- SearchMethodClass.cached_search_by_foo(:foo, :expires_in => 200).must_equal(:hello)
194
- end
223
+ expect(SearchMethodClass).not_to receive(:find)
224
+ expect(SearchMethodClass.cached_search_by_foo(:foo, :expires_in => 200)).to eq(:hello)
195
225
  end
196
226
  end
197
227
 
198
- describe "#cached_search_by_foo!" do
228
+ describe '#cached_search_by_foo!' do
199
229
  before do
200
230
  ::ActiveRemote::Cached.cache(HashCache.new)
201
231
  ::ActiveRemote::Cached.default_options(:expires_in => 100)
@@ -205,16 +235,86 @@ describe SearchMethodClass do
205
235
  ::ActiveRemote::Cached.default_options({})
206
236
  end
207
237
 
208
- it "returns results when present" do
209
- SearchMethodClass.stub(:search, [:hello]) do
210
- SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200).must_equal([:hello])
211
- end
238
+ it 'and_return results when present' do
239
+ expect(SearchMethodClass).to receive(:search).and_return([:hello])
240
+ expect(SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200)).to eq([:hello])
212
241
  end
213
242
 
214
- it "raises ActiveRemote::RemoteRecordNotFound when not found" do
215
- SearchMethodClass.stub(:search, []) do
216
- -> { SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200) }.must_raise ::ActiveRemote::RemoteRecordNotFound
217
- end
243
+ it 'raises ActiveRemote::RemoteRecordNotFound when not found' do
244
+ expect(SearchMethodClass).to receive(:search).and_return([])
245
+ expect do
246
+ SearchMethodClass.cached_search_by_foo!(:foo, :expires_in => 200)
247
+ end.to raise_error ::ActiveRemote::RemoteRecordNotFound
248
+ end
249
+
250
+ it 'raises ActiveRemote::RemoteRecordNotFound when the block returns no results' do
251
+ expect(SearchMethodClass).not_to receive(:search)
252
+ expect do
253
+ SearchMethodClass.cached_search_by_foo!(:foo) { [] }
254
+ end.to raise_error ::ActiveRemote::RemoteRecordNotFound
255
+ end
256
+
257
+ it 'raises ActiveRemote::RemoteRecordNotFound when the first result is nil' do
258
+ expect(SearchMethodClass).not_to receive(:search)
259
+ expect do
260
+ SearchMethodClass.cached_search_by_foo!(:foo) { [nil] }
261
+ end.to raise_error ::ActiveRemote::RemoteRecordNotFound
262
+ end
263
+
264
+ it 'raises ActiveRemote::RemoteRecordNotFound when the results are nil' do
265
+ expect(SearchMethodClass).to receive(:search).and_return(nil)
266
+ expect do
267
+ SearchMethodClass.cached_search_by_foo!(:foo)
268
+ end.to raise_error ::ActiveRemote::RemoteRecordNotFound
269
+ end
270
+
271
+ it 'names the model class in the error' do
272
+ expect(SearchMethodClass).to receive(:search).and_return([])
273
+ expect do
274
+ SearchMethodClass.cached_search_by_foo!(:foo)
275
+ end.to raise_error(::ActiveRemote::RemoteRecordNotFound, /SearchMethodClass/)
276
+ end
277
+
278
+ it 'reports the model class on the error' do
279
+ expect(SearchMethodClass).to receive(:search).and_return([])
280
+
281
+ SearchMethodClass.cached_search_by_foo!(:foo)
282
+ rescue ::ActiveRemote::RemoteRecordNotFound => e
283
+ expect(e.remote_record_class).to eq(SearchMethodClass)
284
+ end
285
+
286
+ it 'does not cache the results when it raises' do
287
+ expect do
288
+ SearchMethodClass.cached_search_by_foo!(:foo) { [] }
289
+ end.to raise_error ::ActiveRemote::RemoteRecordNotFound
290
+
291
+ expect(SearchMethodClass.cached_exist_search_by_foo?(:foo)).to eq(false)
292
+ end
293
+
294
+ it 'caches the results when they are present' do
295
+ expect(SearchMethodClass).to receive(:search).once.and_return([:hello])
296
+
297
+ expect(SearchMethodClass.cached_search_by_foo!(:foo)).to eq([:hello])
298
+ expect(SearchMethodClass.cached_search_by_foo!(:foo)).to eq([:hello])
299
+ end
300
+ end
301
+
302
+ # This tests the method_missing override
303
+ describe '#cached_search_by_zippy123_and_alpha' do
304
+ before do
305
+ ::ActiveRemote::Cached.cache(HashCache.new)
306
+ ::ActiveRemote::Cached.default_options(:expires_in => 100)
307
+ end
308
+
309
+ after do
310
+ ::ActiveRemote::Cached.default_options({})
311
+ end
312
+
313
+ it 'calls the underlying method with params in correct order' do
314
+ expect(SearchMethodClass).to receive(:cached_search_by_alpha_and_zippy123).with('123', 'abc').and_return(:hello)
315
+
316
+ # Calls method that does not exist (different param order)
317
+ expect(SearchMethodClass.cached_search_by_zippy123_and_alpha('abc', '123')).to eq(:hello)
218
318
  end
219
319
  end
220
320
  end