gds-api-adapters 12.1.0 → 12.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.
data/README.md CHANGED
@@ -83,10 +83,6 @@ At time of writing, these are:
83
83
 
84
84
  * [WebMock](https://github.com/bblimke/webmock)
85
85
 
86
- ## To Do
87
-
88
- * Make timeout handling work
89
-
90
86
  ## Licence
91
87
 
92
88
  Released under the MIT Licence, a copy of which can be found in the file
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'ostruct'
3
3
  require 'forwardable'
4
+ require 'rack/cache'
4
5
  require_relative 'core-ext/openstruct'
5
6
 
6
7
  module GdsApi
@@ -44,6 +45,27 @@ module GdsApi
44
45
  @http_response.headers
45
46
  end
46
47
 
48
+ def expires_at
49
+ if headers[:date] && cache_control_headers = headers[:cache_control]
50
+ max_age = Rack::Cache::CacheControl.new(cache_control_headers)['max-age']
51
+ response_date = Time.parse(headers[:date])
52
+
53
+ return response_date + max_age.to_i if max_age
54
+ end
55
+ Time.parse(headers[:expires]) if headers[:expires]
56
+ end
57
+
58
+ def expires_in
59
+ return unless headers[:date]
60
+
61
+ max_age = Rack::Cache::CacheControl.new(headers[:cache_control])['max-age'] if headers[:cache_control]
62
+ max_age ||= Time.parse(headers[:expires]) - Time.parse(headers[:date]) if headers[:expires]
63
+ return unless max_age
64
+
65
+ age = Time.now.utc - Time.parse(headers[:date])
66
+ max_age.to_i - age.to_i
67
+ end
68
+
47
69
  def to_hash
48
70
  @parsed ||= transform_parsed(JSON.parse(@http_response.body))
49
71
  end
@@ -9,10 +9,10 @@ module GdsApi
9
9
 
10
10
  CONTENT_STORE_ENDPOINT = Plek.current.find('content-store')
11
11
 
12
- def content_store_has_item(base_path, body = item_for_base_path(base_path))
12
+ def content_store_has_item(base_path, body = item_for_base_path(base_path), expires_in = 900)
13
13
  url = CONTENT_STORE_ENDPOINT + "/content" + base_path
14
14
  body = body.to_json unless body.is_a?(String)
15
- stub_request(:get, url).to_return(status: 200, body: body, headers: {})
15
+ stub_request(:get, url).to_return(status: 200, body: body, headers: {cache_control: "public, max-age=#{expires_in}", date: Time.now.httpdate})
16
16
  end
17
17
 
18
18
  def content_store_does_not_have_item(base_path)
@@ -1,3 +1,3 @@
1
1
  module GdsApi
2
- VERSION = '12.1.0'
2
+ VERSION = '12.2.0'
3
3
  end
@@ -208,7 +208,7 @@ class JsonClientTest < MiniTest::Spec
208
208
  stub_request(:get, url).to_return(
209
209
  :body => JSON.dump(result),
210
210
  :status => 200,
211
- :headers => { "Cache-Control" => "max-age=420, public" } # 6 minutes
211
+ :headers => { "Cache-Control" => "max-age=420, public" } # 7 minutes
212
212
  )
213
213
 
214
214
  response_a = GdsApi::JsonClient.new.get_json(url)
@@ -5,7 +5,7 @@ describe GdsApi::Response do
5
5
 
6
6
  describe "accessing HTTP response details" do
7
7
  before :each do
8
- @mock_http_response = stub(:body => "A Response body", :code => 200, :headers => {'cache-control' => 'public'})
8
+ @mock_http_response = stub(:body => "A Response body", :code => 200, :headers => {:cache_control => 'public'})
9
9
  @response = GdsApi::Response.new(@mock_http_response)
10
10
  end
11
11
 
@@ -18,7 +18,86 @@ describe GdsApi::Response do
18
18
  end
19
19
 
20
20
  it "should pass-on the response headers" do
21
- assert_equal({'cache-control' => 'public'}, @response.headers)
21
+ assert_equal({:cache_control => 'public'}, @response.headers)
22
+ end
23
+ end
24
+
25
+ describe ".expires_at" do
26
+ it "should be calculated from cache-control max-age" do
27
+ Timecop.freeze(Time.parse("15:00")) do
28
+ cache_control_headers = { :cache_control => 'public, max-age=900' }
29
+ headers = cache_control_headers.merge(date: Time.now.httpdate)
30
+
31
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => headers)
32
+ response = GdsApi::Response.new(mock_http_response)
33
+
34
+ assert_equal Time.parse("15:15"), response.expires_at
35
+ end
36
+ end
37
+
38
+ it "should be same as the value of Expires header in absence of max-age" do
39
+ Timecop.freeze(Time.parse("15:00")) do
40
+ cache_headers = { :cache_control => 'public', :expires => (Time.now + 900).httpdate }
41
+ headers = cache_headers.merge(date: Time.now.httpdate)
42
+
43
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => headers)
44
+ response = GdsApi::Response.new(mock_http_response)
45
+
46
+ assert_equal Time.parse("15:15"), response.expires_at
47
+ end
48
+ end
49
+
50
+ it "should be nil in absence of Expires header and max-age" do
51
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => { :date => Time.now.httpdate })
52
+ response = GdsApi::Response.new(mock_http_response)
53
+
54
+ assert_nil response.expires_at
55
+ end
56
+
57
+ it "should be nil in absence of Date header and max-age" do
58
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => {})
59
+ response = GdsApi::Response.new(mock_http_response)
60
+
61
+ assert_nil response.expires_at
62
+ end
63
+ end
64
+
65
+ describe ".expires_in" do
66
+ it "should be seconds remaining from expiration time inferred from max-age" do
67
+ cache_control_headers = { :cache_control => 'public, max-age=900' }
68
+ headers = cache_control_headers.merge(date: Time.now.httpdate)
69
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => headers)
70
+
71
+ Timecop.travel(12 * 60) do
72
+ response = GdsApi::Response.new(mock_http_response)
73
+ assert_equal 180, response.expires_in
74
+ end
75
+ end
76
+
77
+ it "should be seconds remaining from expiration time inferred from Expires header" do
78
+ cache_headers = { :cache_control => 'public', :expires => (Time.now + 900).httpdate }
79
+ headers = cache_headers.merge(date: Time.now.httpdate)
80
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => headers)
81
+
82
+ Timecop.travel(12 * 60) do
83
+ response = GdsApi::Response.new(mock_http_response)
84
+ assert_equal 180, response.expires_in
85
+ end
86
+ end
87
+
88
+ it "should be nil in absence of Expires header and max-age" do
89
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => { :date => Time.now.httpdate })
90
+ response = GdsApi::Response.new(mock_http_response)
91
+
92
+ assert_nil response.expires_in
93
+ end
94
+
95
+ it "should be nil in absence of Date header" do
96
+ cache_control_headers = { :cache_control => 'public, max-age=900' }
97
+ mock_http_response = stub(:body => "A Response body", :code => 200, :headers => cache_control_headers)
98
+ response = GdsApi::Response.new(mock_http_response)
99
+
100
+ assert_nil response.expires_in
22
101
  end
23
102
  end
24
103
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gds-api-adapters
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.0
4
+ version: 12.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-16 00:00:00.000000000 Z
12
+ date: 2014-07-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: plek
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ~>
92
92
  - !ruby/object:Gem::Version
93
93
  version: 1.6.3
94
+ - !ruby/object:Gem::Dependency
95
+ name: rack-cache
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: rdoc
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -388,7 +404,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
388
404
  version: '0'
389
405
  segments:
390
406
  - 0
391
- hash: 2356146172275700055
407
+ hash: -2448133198351219130
392
408
  required_rubygems_version: !ruby/object:Gem::Requirement
393
409
  none: false
394
410
  requirements:
@@ -397,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
397
413
  version: '0'
398
414
  segments:
399
415
  - 0
400
- hash: 2356146172275700055
416
+ hash: -2448133198351219130
401
417
  requirements: []
402
418
  rubyforge_project:
403
419
  rubygems_version: 1.8.23