active_rest_client 0.9.58

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.simplecov +4 -0
  5. data/Gemfile +4 -0
  6. data/Guardfile +9 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +585 -0
  9. data/Rakefile +3 -0
  10. data/active_rest_client.gemspec +34 -0
  11. data/lib/active_rest_client.rb +23 -0
  12. data/lib/active_rest_client/base.rb +128 -0
  13. data/lib/active_rest_client/caching.rb +84 -0
  14. data/lib/active_rest_client/configuration.rb +69 -0
  15. data/lib/active_rest_client/connection.rb +76 -0
  16. data/lib/active_rest_client/connection_manager.rb +21 -0
  17. data/lib/active_rest_client/headers_list.rb +47 -0
  18. data/lib/active_rest_client/instrumentation.rb +62 -0
  19. data/lib/active_rest_client/lazy_association_loader.rb +95 -0
  20. data/lib/active_rest_client/lazy_loader.rb +23 -0
  21. data/lib/active_rest_client/logger.rb +67 -0
  22. data/lib/active_rest_client/mapping.rb +65 -0
  23. data/lib/active_rest_client/proxy_base.rb +143 -0
  24. data/lib/active_rest_client/recording.rb +24 -0
  25. data/lib/active_rest_client/request.rb +412 -0
  26. data/lib/active_rest_client/request_filtering.rb +52 -0
  27. data/lib/active_rest_client/result_iterator.rb +66 -0
  28. data/lib/active_rest_client/validation.rb +60 -0
  29. data/lib/active_rest_client/version.rb +3 -0
  30. data/spec/lib/base_spec.rb +245 -0
  31. data/spec/lib/caching_spec.rb +179 -0
  32. data/spec/lib/configuration_spec.rb +105 -0
  33. data/spec/lib/connection_manager_spec.rb +36 -0
  34. data/spec/lib/connection_spec.rb +73 -0
  35. data/spec/lib/headers_list_spec.rb +61 -0
  36. data/spec/lib/instrumentation_spec.rb +59 -0
  37. data/spec/lib/lazy_association_loader_spec.rb +118 -0
  38. data/spec/lib/lazy_loader_spec.rb +25 -0
  39. data/spec/lib/logger_spec.rb +63 -0
  40. data/spec/lib/mapping_spec.rb +48 -0
  41. data/spec/lib/proxy_spec.rb +154 -0
  42. data/spec/lib/recording_spec.rb +34 -0
  43. data/spec/lib/request_filtering_spec.rb +72 -0
  44. data/spec/lib/request_spec.rb +471 -0
  45. data/spec/lib/result_iterator_spec.rb +104 -0
  46. data/spec/lib/validation_spec.rb +113 -0
  47. data/spec/spec_helper.rb +22 -0
  48. metadata +265 -0
@@ -0,0 +1,66 @@
1
+ module ActiveRestClient
2
+ class ResultIterator
3
+ include Enumerable
4
+
5
+ attr_accessor :_status
6
+ attr_reader :items
7
+
8
+ def initialize(status = nil)
9
+ @_status = status
10
+ @items = []
11
+ end
12
+
13
+ def <<(item)
14
+ @items << item
15
+ end
16
+
17
+ def size
18
+ @items.size
19
+ end
20
+
21
+ def index(value)
22
+ @items.index(value)
23
+ end
24
+
25
+ def empty?
26
+ size == 0
27
+ end
28
+
29
+ def each
30
+ @items.each do |el|
31
+ yield el
32
+ end
33
+ end
34
+
35
+ def last
36
+ @items.last
37
+ end
38
+
39
+ def [](key)
40
+ @items[key]
41
+ end
42
+
43
+ def shuffle
44
+ @items = @items.shuffle
45
+ self
46
+ end
47
+
48
+ def parallelise(method=nil)
49
+ collected_responses = []
50
+ threads = []
51
+ @items.each do |item|
52
+ threads << Thread.new do
53
+ ret = item.send(method) if method
54
+ ret = yield(item) if block_given?
55
+ Thread.current[:response] = ret
56
+ end
57
+ end
58
+ threads.each do |t|
59
+ t.join
60
+ collected_responses << t[:response]
61
+ end
62
+ collected_responses
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,60 @@
1
+ module ActiveRestClient
2
+ module Validation
3
+ module ClassMethods
4
+ def validates(field_name, options={}, &block)
5
+ @_validations ||= []
6
+ @_validations << {field_name:field_name, options:options, block:block}
7
+ end
8
+
9
+ def _validations
10
+ @_validations ||= []
11
+ @_validations
12
+ end
13
+ end
14
+
15
+ def self.included(base)
16
+ base.extend(ClassMethods)
17
+ end
18
+
19
+ def valid?
20
+ @errors = Hash.new {|h,k| h[k] = []}
21
+ self.class._validations.each do |validation|
22
+ value = self.send(validation[:field_name])
23
+ validation[:options].each do |type, options|
24
+ if type == :presence
25
+ if value.nil?
26
+ @errors[validation[:field_name]] << "must be present"
27
+ end
28
+ elsif type == :length
29
+ if options[:within]
30
+ @errors[validation[:field_name]] << "must be within range #{options[:within]}" unless options[:within].include?(value.to_s.length )
31
+ end
32
+ if options[:minimum]
33
+ @errors[validation[:field_name]] << "must be at least #{options[:minimum]} characters long" unless value.to_s.length >= options[:minimum]
34
+ end
35
+ if options[:maximum]
36
+ @errors[validation[:field_name]] << "must be no more than #{options[:minimum]} characters long" unless value.to_s.length <= options[:maximum]
37
+ end
38
+ elsif type == :numericality
39
+ numeric = (true if Float(value) rescue false)
40
+ @errors[validation[:field_name]] << "must be numeric" unless numeric
41
+ elsif type == :minimum && !value.nil?
42
+ @errors[validation[:field_name]] << "must be at least #{options}" unless value.to_f >= options.to_f
43
+ elsif type == :maximum && !value.nil?
44
+ @errors[validation[:field_name]] << "must be no more than #{options}" unless value.to_f <= options.to_f
45
+ end
46
+ end
47
+ if validation[:block]
48
+ validation[:block].call(self, validation[:field_name], value)
49
+ end
50
+ end
51
+ @errors.empty?
52
+ end
53
+
54
+ def errors
55
+ @errors ||= Hash.new {|h,k| h[k] = []}
56
+ @errors
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRestClient
2
+ VERSION = "0.9.58"
3
+ end
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+
3
+ class EmptyExample < ActiveRestClient::Base
4
+ whiny_missing true
5
+ end
6
+
7
+ class TranslatorExample
8
+ def self.all(object)
9
+ ret = {}
10
+ ret["first_name"] = object["name"]
11
+ ret
12
+ end
13
+ end
14
+
15
+ class AlteringClientExample < ActiveRestClient::Base
16
+ translator TranslatorExample
17
+ base_url "http://www.example.com"
18
+
19
+ get :all, "/all", fake:"{\"name\":\"Billy\"}"
20
+ get :list, "/list", fake:"{\"name\":\"Billy\", \"country\":\"United Kingdom\"}"
21
+ get :iterate, "/iterate", fake:"{\"name\":\"Billy\", \"country\":\"United Kingdom\"}"
22
+ get :find, "/find/:id"
23
+ end
24
+
25
+ class RecordResponseExample < ActiveRestClient::Base
26
+ base_url "http://www.example.com"
27
+
28
+ record_response do |url, response|
29
+ raise Exception.new("#{url}|#{response.body}")
30
+ end
31
+
32
+ get :all, "/all"
33
+ end
34
+
35
+ describe ActiveRestClient::Base do
36
+ it 'should instantiate a new descendant' do
37
+ expect{EmptyExample.new}.to_not raise_error(Exception)
38
+ end
39
+
40
+ it "should not instantiate a new base class" do
41
+ expect{ActiveRestClient::Base.new}.to raise_error(Exception)
42
+ end
43
+
44
+ it "should save attributes passed in constructor" do
45
+ client = EmptyExample.new(:test => "Something")
46
+ expect(client._attributes[:test]).to be_a(String)
47
+ end
48
+
49
+ it "should allow attribute reading using missing method names" do
50
+ client = EmptyExample.new(:test => "Something")
51
+ expect(client.test).to eq("Something")
52
+ end
53
+
54
+ it "should allow attribute reading using [] array notation" do
55
+ client = EmptyExample.new(:test => "Something")
56
+ expect(client["test"]).to eq("Something")
57
+ end
58
+
59
+ it "allows iteration over attributes using each" do
60
+ client = AlteringClientExample.iterate
61
+ expect(client).to be_respond_to(:each)
62
+ keys = []
63
+ values = []
64
+ client.each do |key, value|
65
+ keys << key ; values << value
66
+ end
67
+ expect(keys).to eq(%i{name country})
68
+ expect(values).to eq(["Billy", "United Kingdom"])
69
+ end
70
+
71
+ it "should automatically parse ISO 8601 format dates" do
72
+ t = Time.now
73
+ client = EmptyExample.new(:test => t.iso8601)
74
+ expect(client["test"]).to be_an_instance_of(DateTime)
75
+ expect(client["test"].to_s).to eq(t.to_datetime.to_s)
76
+ end
77
+
78
+ it "should store attributes set using missing method names and mark them as dirty" do
79
+ client = EmptyExample.new()
80
+ client.test = "Something"
81
+ expect(client.test.to_s).to eq("Something")
82
+ expect(client).to be_dirty
83
+ end
84
+
85
+ it "should store attribute set using []= array notation and mark them as dirty" do
86
+ client = EmptyExample.new()
87
+ client["test"] = "Something"
88
+ expect(client["test"].to_s).to eq("Something")
89
+ expect(client).to be_dirty
90
+ end
91
+
92
+ it "should overwrite attributes already set and mark them as dirty" do
93
+ client = EmptyExample.new(:hello => "World")
94
+ client._clean!
95
+ expect(client).to_not be_dirty
96
+
97
+ client.hello = "Everybody"
98
+ expect(client).to be_dirty
99
+ end
100
+
101
+ it 'should respond_to? attributes defined in the response' do
102
+ client = EmptyExample.new(:hello => "World")
103
+ client.respond_to?(:hello).should be_true
104
+ client.respond_to?(:world).should be_false
105
+ end
106
+
107
+ it "should save the base URL for the API server" do
108
+ class BaseExample < ActiveRestClient::Base
109
+ base_url "https://www.example.com/api/v1"
110
+ end
111
+ expect(BaseExample.base_url).to eq("https://www.example.com/api/v1")
112
+ end
113
+
114
+ it "should allow changing the base_url while running" do
115
+ class OutsideBaseExample < ActiveRestClient::Base ; end
116
+
117
+ ActiveRestClient::Base.base_url = "https://www.example.com/api/v1"
118
+ expect(OutsideBaseExample.base_url).to eq("https://www.example.com/api/v1")
119
+
120
+ ActiveRestClient::Base.base_url = "https://www.example.com/api/v2"
121
+ expect(OutsideBaseExample.base_url).to eq("https://www.example.com/api/v2")
122
+ end
123
+
124
+ it "should include the Mapping module" do
125
+ expect(EmptyExample).to respond_to(:_calls)
126
+ expect(EmptyExample).to_not respond_to(:_non_existant)
127
+ end
128
+
129
+ it "should be able to easily clean all attributes" do
130
+ client = EmptyExample.new(hello:"World", goodbye:"Everyone")
131
+ expect(client).to be_dirty
132
+ client._clean!
133
+ expect(client).to_not be_dirty
134
+ end
135
+
136
+ it "should not overly pollute the instance method namespace to reduce chances of clashing (<10 instance methods)" do
137
+ instance_methods = EmptyExample.instance_methods - Object.methods
138
+ instance_methods = instance_methods - instance_methods.grep(/^_/)
139
+ expect(instance_methods.size).to be < 10
140
+ end
141
+
142
+ it "should raise an exception for missing attributes if whiny_missing is enabled" do
143
+ expect{EmptyExample.new.first_name}.to raise_error(ActiveRestClient::NoAttributeException)
144
+ end
145
+
146
+ it "should be able to lazy instantiate an object from a prefixed lazy_ method call" do
147
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with('/find/1', anything).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
148
+ example = AlteringClientExample.lazy_find(1)
149
+ expect(example).to be_an_instance_of(ActiveRestClient::LazyLoader)
150
+ expect(example.first_name).to eq("Billy")
151
+ end
152
+
153
+ it "should be able to lazy instantiate an object from a prefixed lazy_ method call from an instance" do
154
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with('/find/1', anything).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
155
+ example = AlteringClientExample.new.lazy_find(1)
156
+ expect(example).to be_an_instance_of(ActiveRestClient::LazyLoader)
157
+ expect(example.first_name).to eq("Billy")
158
+ end
159
+
160
+ context "accepts a Translator to reformat JSON" do
161
+ it "should log a deprecation warning when using a translator" do
162
+ ActiveRestClient::Logger.should_receive(:warn) do |message|
163
+ expect(message).to start_with("DEPRECATION")
164
+ end
165
+ Proc.new do
166
+ class DummyExample < ActiveRestClient::Base
167
+ translator TranslatorExample
168
+ end
169
+ end.call
170
+ end
171
+
172
+ it "should call Translator#method when calling the mapped method if it responds to it" do
173
+ TranslatorExample.should_receive(:all).with(an_instance_of(Hash)).and_return({})
174
+ AlteringClientExample.all
175
+ end
176
+
177
+ it "should not raise errors when calling Translator#method if it does not respond to it" do
178
+ expect {AlteringClientExample.list}.to_not raise_error
179
+ end
180
+
181
+ it "should translate JSON returned through the Translator" do
182
+ ret = AlteringClientExample.all
183
+ expect(ret.first_name).to eq("Billy")
184
+ expect(ret.name).to be_nil
185
+ end
186
+
187
+ it "should return original JSON for items that aren't handled by the Translator" do
188
+ ret = AlteringClientExample.list
189
+ expect(ret.name).to eq("Billy")
190
+ expect(ret.first_name).to be_nil
191
+ end
192
+ end
193
+
194
+ context "directly call a URL, rather than via a mapped method" do
195
+ it "should be able to directly call a URL" do
196
+ ActiveRestClient::Request.any_instance.should_receive(:do_request).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
197
+ EmptyExample._request("http://api.example.com/")
198
+ end
199
+
200
+ it "runs filters as usual" do
201
+ ActiveRestClient::Request.any_instance.should_receive(:do_request).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
202
+ EmptyExample.should_receive(:_filter_request).with(any_args)
203
+ EmptyExample._request("http://api.example.com/")
204
+ end
205
+
206
+ it "should make an HTTP request" do
207
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
208
+ EmptyExample._request("http://api.example.com/")
209
+ end
210
+
211
+ it "should map the response from the directly called URL in the normal way" do
212
+ ActiveRestClient::Request.any_instance.should_receive(:do_request).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
213
+ example = EmptyExample._request("http://api.example.com/")
214
+ expect(example.first_name).to eq("Billy")
215
+ end
216
+
217
+ it "should be able to lazy load a direct URL request" do
218
+ ActiveRestClient::Request.any_instance.should_receive(:do_request).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
219
+ example = EmptyExample._lazy_request("http://api.example.com/")
220
+ expect(example).to be_an_instance_of(ActiveRestClient::LazyLoader)
221
+ expect(example.first_name).to eq("Billy")
222
+ end
223
+
224
+ it "should be able to specify a method and parameters for the call" do
225
+ ActiveRestClient::Connection.any_instance.should_receive(:post).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
226
+ EmptyExample._request("http://api.example.com/", :post, {id:1234})
227
+ end
228
+
229
+ it "should be able to use mapped methods to create a request to pass in to _lazy_request" do
230
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with('/find/1', anything).and_return(OpenStruct.new(status:200, headers:{}, body:"{\"first_name\":\"Billy\"}"))
231
+ request = AlteringClientExample._request_for(:find, :id => 1)
232
+ example = AlteringClientExample._lazy_request(request)
233
+ expect(example.first_name).to eq("Billy")
234
+ end
235
+ end
236
+
237
+ context "Recording a response" do
238
+ it "calls back to the record_response callback with the url and response body" do
239
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with(any_args).and_return(OpenStruct.new(status:200, headers:{}, body:"Hello world"))
240
+ expect{RecordResponseExample.all}.to raise_error(Exception, "/all|Hello world")
241
+
242
+ end
243
+ end
244
+
245
+ end
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRestClient::Caching do
4
+ before :each do
5
+ ActiveRestClient::Base._reset_caching!
6
+ end
7
+
8
+ context "Configuration of caching" do
9
+ it "should not have caching enabled by default" do
10
+ class CachingExample1
11
+ include ActiveRestClient::Caching
12
+ end
13
+ expect(CachingExample1.perform_caching).to be_false
14
+ end
15
+
16
+ it "should be able to have caching enabled without affecting ActiveRestClient::Base" do
17
+ class CachingExample2
18
+ include ActiveRestClient::Caching
19
+ end
20
+ CachingExample2.perform_caching true
21
+ expect(CachingExample2.perform_caching).to be_true
22
+ expect(ActiveRestClient::Base.perform_caching).to be_false
23
+ end
24
+
25
+ it "should be possible to enable caching for all objects" do
26
+ class CachingExample3 < ActiveRestClient::Base ; end
27
+ ActiveRestClient::Base._reset_caching!
28
+
29
+ expect(ActiveRestClient::Base.perform_caching).to be_false
30
+
31
+ ActiveRestClient::Base.perform_caching = true
32
+ expect(ActiveRestClient::Base.perform_caching).to be_true
33
+ expect(EmptyExample.perform_caching).to be_true
34
+
35
+ ActiveRestClient::Base._reset_caching!
36
+ end
37
+
38
+ it "should use Rails.cache if available" do
39
+ begin
40
+ class Rails
41
+ def self.cache
42
+ true
43
+ end
44
+ end
45
+ expect(ActiveRestClient::Base.cache_store).to eq(true)
46
+ ensure
47
+ Object.send(:remove_const, :Rails) if defined?(Rails)
48
+ end
49
+
50
+ end
51
+
52
+ it "should use a custom cache store if a valid one is manually set" do
53
+ class CachingExampleCacheStore1
54
+ def read(key) ; end
55
+ def write(key, value, options={}) ; end
56
+ def fetch(key, &block) ; end
57
+ end
58
+ cache_store = CachingExampleCacheStore1.new
59
+ ActiveRestClient::Base.cache_store = cache_store
60
+ expect(ActiveRestClient::Base.cache_store).to eq(cache_store)
61
+ end
62
+
63
+ it "should error if you try to use a custom cache store that doesn't match the required interface" do
64
+ class CachingExampleCacheStore2
65
+ def write(key, value, options={}) ; end
66
+ def fetch(key, &block) ; end
67
+ end
68
+ class CachingExampleCacheStore3
69
+ def read(key) ; end
70
+ def fetch(key, &block) ; end
71
+ end
72
+ class CachingExampleCacheStore4
73
+ def read(key) ; end
74
+ def write(key, value, options={}) ; end
75
+ end
76
+
77
+ expect{ ActiveRestClient::Base.cache_store = CachingExampleCacheStore2.new }.to raise_error
78
+ expect{ ActiveRestClient::Base.cache_store = CachingExampleCacheStore3.new }.to raise_error
79
+ expect{ ActiveRestClient::Base.cache_store = CachingExampleCacheStore4.new }.to raise_error
80
+ end
81
+ end
82
+
83
+ context "Reading/writing to the cache" do
84
+ before :each do
85
+ Object.send(:remove_const, :CachingExampleCacheStore5) if defined?(CachingExampleCacheStore5)
86
+ class CachingExampleCacheStore5
87
+ def read(key) ; end
88
+ def write(key, value, options={}) ; end
89
+ def fetch(key, &block) ; end
90
+ end
91
+
92
+ class Person < ActiveRestClient::Base
93
+ perform_caching true
94
+ base_url "http://www.example.com"
95
+ get :all, "/"
96
+ end
97
+
98
+ Person.cache_store = CachingExampleCacheStore5.new
99
+
100
+ @etag = "6527914a91e0c5769f6de281f25bd891"
101
+ @cached_object = Person.new(first_name:"Johnny")
102
+ end
103
+
104
+ it "should read from the cache store, to check for an etag" do
105
+ cached_response = ActiveRestClient::CachedResponse.new(
106
+ status:200,
107
+ result:@cached_object,
108
+ etag:@etag)
109
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(cached_response)
110
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with("/", hash_including("If-None-Match" => @etag)).and_return(OpenStruct.new(status:304, headers:{}))
111
+ ret = Person.all
112
+ expect(ret.first_name).to eq("Johnny")
113
+ end
114
+
115
+ it "should read from the cache store, and not call the server if there's a hard expiry" do
116
+ cached_response = ActiveRestClient::CachedResponse.new(
117
+ status:200,
118
+ result:@cached_object,
119
+ expires:Time.now + 30)
120
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(cached_response)
121
+ ActiveRestClient::Connection.any_instance.should_not_receive(:get)
122
+ ret = Person.all
123
+ expect(ret.first_name).to eq("Johnny")
124
+ end
125
+
126
+ it "should read from the cache store and restore to the same object" do
127
+ cached_response = ActiveRestClient::CachedResponse.new(
128
+ status:200,
129
+ result:@cached_object,
130
+ expires:Time.now + 30)
131
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(cached_response)
132
+ ActiveRestClient::Connection.any_instance.should_not_receive(:get)
133
+ p = Person.new(first_name:"Billy")
134
+ ret = p.all({})
135
+ expect(ret.first_name).to eq("Johnny")
136
+ end
137
+
138
+ it "should restore a result iterator from the cache store, if there's a hard expiry" do
139
+ class CachingExample3 < ActiveRestClient::Base ; end
140
+ object = ActiveRestClient::ResultIterator.new(200)
141
+ object << CachingExample3.new(first_name:"Johnny")
142
+ object << CachingExample3.new(first_name:"Billy")
143
+ etag = "6527914a91e0c5769f6de281f25bd891"
144
+ cached_response = ActiveRestClient::CachedResponse.new(
145
+ status:200,
146
+ result:object,
147
+ etag:@etag,
148
+ expires:Time.now + 30)
149
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(cached_response)
150
+ ActiveRestClient::Connection.any_instance.should_not_receive(:get)
151
+ ret = Person.all
152
+ expect(ret.first.first_name).to eq("Johnny")
153
+ expect(ret._status).to eq(200)
154
+ end
155
+
156
+ it "should not write the response to the cache unless if has caching headers" do
157
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(nil)
158
+ CachingExampleCacheStore5.any_instance.should_not_receive(:write)
159
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with("/", an_instance_of(Hash)).and_return(OpenStruct.new(status:200, body:"{\"result\":true}", headers:{}))
160
+ ret = Person.all
161
+ end
162
+
163
+ it "should write the response to the cache if there's an etag" do
164
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(nil)
165
+ CachingExampleCacheStore5.any_instance.should_receive(:write).once.with("Person:/", an_instance_of(ActiveRestClient::CachedResponse), {})
166
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with("/", an_instance_of(Hash)).and_return(OpenStruct.new(status:200, body:"{\"result\":true}", headers:{etag:"1234567890"}))
167
+ ret = Person.all
168
+ end
169
+
170
+ it "should write the response to the cache if there's a hard expiry" do
171
+ CachingExampleCacheStore5.any_instance.should_receive(:read).once.with("Person:/").and_return(nil)
172
+ CachingExampleCacheStore5.any_instance.should_receive(:write).once.with("Person:/", an_instance_of(ActiveRestClient::CachedResponse), an_instance_of(Hash))
173
+ ActiveRestClient::Connection.any_instance.should_receive(:get).with("/", an_instance_of(Hash)).and_return(OpenStruct.new(status:200, body:"{\"result\":true}", headers:{expires:(Time.now + 30).rfc822}))
174
+ ret = Person.all
175
+ end
176
+
177
+ end
178
+
179
+ end