gds-api-adapters 19.2.0 → 20.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/lib/gds_api/helpers.rb +0 -4
- data/lib/gds_api/json_client.rb +7 -16
- data/lib/gds_api/response.rb +14 -10
- data/lib/gds_api/test_helpers/content_store.rb +18 -2
- data/lib/gds_api/version.rb +1 -1
- data/test/json_client_test.rb +38 -0
- metadata +1 -5
- data/lib/gds_api/collections_api.rb +0 -15
- data/lib/gds_api/test_helpers/collections_api.rb +0 -128
- data/test/collections_api_test.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87f540ebb20c9b25a5f646a9fe87417175da9a69
|
4
|
+
data.tar.gz: 1d93e60b2b6a442d30b82b8b587fadfff26c85b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4b493b63635ccaac3987a6481699af88a63d95e55b42479d73b75bacda3c486f41d9bd7cded4783b59eb63239c02e9c5e3e867781dd6e99ba995e5c5b9dc254
|
7
|
+
data.tar.gz: a1416aa6e547c77cf7a5469494b00766878eec0d41f1038130b1f638d37c84b66ec9c4545fa969d831c64646b260754a74cc08ce692d738c2002b63f132213be
|
data/lib/gds_api/helpers.rb
CHANGED
@@ -24,10 +24,6 @@ module GdsApi
|
|
24
24
|
@business_support_api ||= GdsApi::BusinessSupportApi.new(Plek.current.find("business-support-api"), options)
|
25
25
|
end
|
26
26
|
|
27
|
-
def collections_api(options = {})
|
28
|
-
@collections_api ||= GdsApi::CollectionsApi.new(Plek.current.find("collections-api"), options)
|
29
|
-
end
|
30
|
-
|
31
27
|
def content_api(options = {})
|
32
28
|
@content_api ||= GdsApi::ContentApi.new(Plek.current.find("contentapi"), options)
|
33
29
|
end
|
data/lib/gds_api/json_client.rb
CHANGED
@@ -212,23 +212,14 @@ module GdsApi
|
|
212
212
|
# or nil if no cache information is provided
|
213
213
|
def response_cache_time(response)
|
214
214
|
if response.headers[:cache_control]
|
215
|
-
|
216
|
-
# so split this apart before we look for particular values
|
217
|
-
cache_parts = response.headers[:cache_control].split(',').map(&:strip)
|
218
|
-
|
219
|
-
# If no-cache is present, this takes precedent over any other value
|
220
|
-
# in this header
|
221
|
-
return Time.now.utc if cache_parts.include?("no-cache")
|
222
|
-
|
223
|
-
# Otherwise, look for a 'max-age=123' value, which is the number of
|
224
|
-
# seconds for which to cache the response.
|
225
|
-
max_age = cache_parts.map {|x| x.match(/max-age=(\d+)/) }.compact.first
|
226
|
-
if max_age
|
227
|
-
return Time.now.utc + max_age[1].to_i
|
228
|
-
end
|
229
|
-
end
|
215
|
+
cache_control = Rack::Cache::CacheControl.new(response.headers[:cache_control])
|
230
216
|
|
231
|
-
|
217
|
+
if cache_control.private? || cache_control.no_cache? || cache_control.no_store?
|
218
|
+
Time.now.utc
|
219
|
+
elsif cache_control.max_age
|
220
|
+
Time.now.utc + cache_control.max_age
|
221
|
+
end
|
222
|
+
elsif response.headers[:expires]
|
232
223
|
Time.httpdate response.headers[:expires]
|
233
224
|
end
|
234
225
|
end
|
data/lib/gds_api/response.rb
CHANGED
@@ -46,24 +46,28 @@ module GdsApi
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def expires_at
|
49
|
-
if headers[:date] &&
|
50
|
-
max_age = Rack::Cache::CacheControl.new(cache_control_headers)['max-age']
|
49
|
+
if headers[:date] && cache_control.max_age
|
51
50
|
response_date = Time.parse(headers[:date])
|
52
|
-
|
53
|
-
|
51
|
+
response_date + cache_control.max_age
|
52
|
+
elsif headers[:expires]
|
53
|
+
Time.parse(headers[:expires])
|
54
54
|
end
|
55
|
-
Time.parse(headers[:expires]) if headers[:expires]
|
56
55
|
end
|
57
56
|
|
58
57
|
def expires_in
|
59
58
|
return unless headers[:date]
|
60
59
|
|
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
60
|
age = Time.now.utc - Time.parse(headers[:date])
|
66
|
-
|
61
|
+
|
62
|
+
if cache_control.max_age
|
63
|
+
cache_control.max_age - age.to_i
|
64
|
+
elsif headers[:expires]
|
65
|
+
Time.parse(headers[:expires]).to_i - Time.now.utc.to_i
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def cache_control
|
70
|
+
@cache_control ||= Rack::Cache::CacheControl.new(headers[:cache_control])
|
67
71
|
end
|
68
72
|
|
69
73
|
def to_hash
|
@@ -9,10 +9,26 @@ module GdsApi
|
|
9
9
|
|
10
10
|
CONTENT_STORE_ENDPOINT = Plek.current.find('content-store')
|
11
11
|
|
12
|
-
|
12
|
+
# Stubs a content item in the content store.
|
13
|
+
# The following options can be passed in:
|
14
|
+
#
|
15
|
+
# :max_age will set the max-age of the Cache-Control header in the response. Defaults to 900
|
16
|
+
# :private if true, the Cache-Control header will include the "private" directive. By default it
|
17
|
+
# will include "public"
|
18
|
+
def content_store_has_item(base_path, body = content_item_for_base_path(base_path), options = {})
|
19
|
+
max_age = options.fetch(:max_age, 900)
|
20
|
+
visibility = options[:private] ? "private" : "public"
|
13
21
|
url = CONTENT_STORE_ENDPOINT + "/content" + base_path
|
14
22
|
body = body.to_json unless body.is_a?(String)
|
15
|
-
|
23
|
+
|
24
|
+
stub_request(:get, url).to_return(
|
25
|
+
status: 200,
|
26
|
+
body: body,
|
27
|
+
headers: {
|
28
|
+
cache_control: "#{visibility}, max-age=#{max_age}",
|
29
|
+
date: Time.now.httpdate
|
30
|
+
}
|
31
|
+
)
|
16
32
|
end
|
17
33
|
|
18
34
|
def content_store_does_not_have_item(base_path)
|
data/lib/gds_api/version.rb
CHANGED
data/test/json_client_test.rb
CHANGED
@@ -247,6 +247,44 @@ class JsonClientTest < MiniTest::Spec
|
|
247
247
|
end
|
248
248
|
end
|
249
249
|
|
250
|
+
def test_does_not_cache_responses_with_cache_control_private
|
251
|
+
url = "http://some.endpoint/private.json"
|
252
|
+
result = {"foo" => "bar"}
|
253
|
+
stub_request(:get, url).to_return(
|
254
|
+
:body => JSON.dump(result),
|
255
|
+
:status => 200,
|
256
|
+
:headers => { "Cache-Control" => "max-age=600, private" }
|
257
|
+
)
|
258
|
+
|
259
|
+
response_a = GdsApi::JsonClient.new.get_json(url)
|
260
|
+
|
261
|
+
Timecop.travel( 7 * 60 - 30) do # now + 6 mins 30 secs
|
262
|
+
response_b = GdsApi::JsonClient.new.get_json(url)
|
263
|
+
|
264
|
+
assert_requested :get, url, times: 2
|
265
|
+
assert_equal response_a.to_hash, response_b.to_hash
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_does_not_cache_responses_with_cache_control_no_store
|
270
|
+
url = "http://some.endpoint/private.json"
|
271
|
+
result = {"foo" => "bar"}
|
272
|
+
stub_request(:get, url).to_return(
|
273
|
+
:body => JSON.dump(result),
|
274
|
+
:status => 200,
|
275
|
+
:headers => { "Cache-Control" => "max-age=600, no-store" }
|
276
|
+
)
|
277
|
+
|
278
|
+
response_a = GdsApi::JsonClient.new.get_json(url)
|
279
|
+
|
280
|
+
Timecop.travel( 7 * 60 - 30) do # now + 6 mins 30 secs
|
281
|
+
response_b = GdsApi::JsonClient.new.get_json(url)
|
282
|
+
|
283
|
+
assert_requested :get, url, times: 2
|
284
|
+
assert_equal response_a.to_hash, response_b.to_hash
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
250
288
|
def test_should_respect_cache_control_headers_with_no_cache_and_max_age
|
251
289
|
url = "http://some.endpoint/no_cache_and_max_age.json"
|
252
290
|
result = {"foo" => "bar"}
|
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:
|
4
|
+
version: 20.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Stewart
|
@@ -275,7 +275,6 @@ files:
|
|
275
275
|
- lib/gds_api/asset_manager.rb
|
276
276
|
- lib/gds_api/base.rb
|
277
277
|
- lib/gds_api/business_support_api.rb
|
278
|
-
- lib/gds_api/collections_api.rb
|
279
278
|
- lib/gds_api/content_api.rb
|
280
279
|
- lib/gds_api/content_register.rb
|
281
280
|
- lib/gds_api/content_store.rb
|
@@ -315,7 +314,6 @@ files:
|
|
315
314
|
- lib/gds_api/test_helpers/asset_manager.rb
|
316
315
|
- lib/gds_api/test_helpers/business_support_api.rb
|
317
316
|
- lib/gds_api/test_helpers/business_support_helper.rb
|
318
|
-
- lib/gds_api/test_helpers/collections_api.rb
|
319
317
|
- lib/gds_api/test_helpers/common_responses.rb
|
320
318
|
- lib/gds_api/test_helpers/content_api.rb
|
321
319
|
- lib/gds_api/test_helpers/content_api/artefact_stub.rb
|
@@ -348,7 +346,6 @@ files:
|
|
348
346
|
- lib/gds_api/worldwide.rb
|
349
347
|
- test/asset_manager_test.rb
|
350
348
|
- test/business_support_api_test.rb
|
351
|
-
- test/collections_api_test.rb
|
352
349
|
- test/content_api_test.rb
|
353
350
|
- test/content_register_test.rb
|
354
351
|
- test/content_store_test.rb
|
@@ -442,7 +439,6 @@ test_files:
|
|
442
439
|
- test/response_test.rb
|
443
440
|
- test/organisations_api_test.rb
|
444
441
|
- test/imminence_api_test.rb
|
445
|
-
- test/collections_api_test.rb
|
446
442
|
- test/content_store_test.rb
|
447
443
|
- test/asset_manager_test.rb
|
448
444
|
- test/fixtures/hello.txt
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require_relative 'base'
|
2
|
-
require_relative 'exceptions'
|
3
|
-
|
4
|
-
class GdsApi::CollectionsApi < GdsApi::Base
|
5
|
-
|
6
|
-
def topic(base_path, options={})
|
7
|
-
get_json(collections_api_url(base_path, options))
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def collections_api_url(base_path, options={})
|
13
|
-
"#{endpoint}/specialist-sectors#{base_path}#{query_string(options)}"
|
14
|
-
end
|
15
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require 'gds_api/test_helpers/json_client_helper'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
module GdsApi
|
5
|
-
module TestHelpers
|
6
|
-
module CollectionsApi
|
7
|
-
COLLECTIONS_API_ENDPOINT = Plek.current.find('collections-api')
|
8
|
-
|
9
|
-
def collections_api_has_content_for(base_path, options={})
|
10
|
-
body_options = options.delete(:return_body_options) || {}
|
11
|
-
|
12
|
-
params = options.any? ? "?#{Rack::Utils.build_nested_query(options)}" : ''
|
13
|
-
url = COLLECTIONS_API_ENDPOINT + "/specialist-sectors" + base_path + params
|
14
|
-
|
15
|
-
stub_request(:get, url).to_return(
|
16
|
-
status: 200,
|
17
|
-
body: body_with_options(
|
18
|
-
body_options.merge(base_path: base_path)
|
19
|
-
).to_json,
|
20
|
-
)
|
21
|
-
end
|
22
|
-
|
23
|
-
def collections_api_has_no_content_for(base_path)
|
24
|
-
url = COLLECTIONS_API_ENDPOINT + "/specialist-sectors" + base_path
|
25
|
-
|
26
|
-
stub_request(:get, url).to_return(
|
27
|
-
status: 404
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
def collections_api_example_documents
|
32
|
-
[
|
33
|
-
{
|
34
|
-
title: "Oil rig safety requirements",
|
35
|
-
link: "http://example.com/documents/oil-rig-safety-requirements",
|
36
|
-
public_updated_at: "2014-10-27T09:35:57+00:00",
|
37
|
-
latest_change_note: "Updated topics"
|
38
|
-
},
|
39
|
-
{
|
40
|
-
title: "Undersea piping restrictions",
|
41
|
-
link: "http://example.com/documents/undersea-piping-restrictions",
|
42
|
-
public_updated_at: "2014-10-15T09:36:18+01:00",
|
43
|
-
latest_change_note: nil
|
44
|
-
},
|
45
|
-
{
|
46
|
-
title: "North sea shipping lanes",
|
47
|
-
link: "http://example.com/documents/north-sea-shipping-lanes",
|
48
|
-
public_updated_at: nil,
|
49
|
-
latest_change_note: "Corrected shipping lane"
|
50
|
-
},
|
51
|
-
{
|
52
|
-
title: "Oil rig staffing",
|
53
|
-
link: "http://example.com/documents/oil-rig-staffing",
|
54
|
-
public_updated_at: "2014-09-22T09:37:00+01:00",
|
55
|
-
latest_change_note: "Added annual leave allowances"
|
56
|
-
},
|
57
|
-
]
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
|
62
|
-
def body_with_options(options)
|
63
|
-
{
|
64
|
-
base_path: options.fetch(:base_path),
|
65
|
-
title: 'Example title',
|
66
|
-
description: 'example description',
|
67
|
-
public_updated_at: "2014-03-04T13:58:11+00:00",
|
68
|
-
parent: {
|
69
|
-
id: "http://example.com/oil-and-gas",
|
70
|
-
web_url: "http://example.com/browse/oil-and-gas",
|
71
|
-
details: {
|
72
|
-
description: nil,
|
73
|
-
short_description: nil,
|
74
|
-
type: "section",
|
75
|
-
},
|
76
|
-
content_with_tag: {
|
77
|
-
id: "http://example.com/with_tag.json?section=oil-and-gas",
|
78
|
-
web_url: "http://example.com/browse/oil-and-gas"
|
79
|
-
},
|
80
|
-
parent: nil,
|
81
|
-
title: "Oil and gas",
|
82
|
-
state: "live",
|
83
|
-
},
|
84
|
-
details: {
|
85
|
-
groups: [
|
86
|
-
# Curated content excluding untagged content
|
87
|
-
{
|
88
|
-
name: "Oil rigs",
|
89
|
-
contents: [
|
90
|
-
{
|
91
|
-
web_url: "http://example.com/api/oil-rig-safety-requirements.json",
|
92
|
-
title: "Oil rig safety requirements",
|
93
|
-
},
|
94
|
-
{
|
95
|
-
web_url: "http://example.com/api/oil-rig-staffing.json",
|
96
|
-
title: "Oil rig staffing",
|
97
|
-
}
|
98
|
-
]
|
99
|
-
},
|
100
|
-
{
|
101
|
-
name: "Piping",
|
102
|
-
contents: [
|
103
|
-
{
|
104
|
-
web_url: "http://example.com/api/undersea-piping-restrictions.json",
|
105
|
-
title: "Undersea piping restrictions",
|
106
|
-
}
|
107
|
-
]
|
108
|
-
},
|
109
|
-
# Uncurated content
|
110
|
-
{
|
111
|
-
name: "Other",
|
112
|
-
contents: [
|
113
|
-
{
|
114
|
-
web_url: "http://example.com/api/north-sea-shipping-lanes.json",
|
115
|
-
title: "North sea shipping lanes",
|
116
|
-
}
|
117
|
-
]
|
118
|
-
}
|
119
|
-
],
|
120
|
-
documents: collections_api_example_documents,
|
121
|
-
documents_start: options.fetch(:start, 0),
|
122
|
-
documents_total: options.fetch(:total, collections_api_example_documents.size),
|
123
|
-
}
|
124
|
-
}
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'gds_api/collections_api'
|
3
|
-
require 'gds_api/test_helpers/collections_api'
|
4
|
-
|
5
|
-
describe GdsApi::CollectionsApi do
|
6
|
-
include GdsApi::TestHelpers::CollectionsApi
|
7
|
-
|
8
|
-
before do
|
9
|
-
@base_api_url = Plek.current.find("collections-api")
|
10
|
-
@api = GdsApi::CollectionsApi.new(@base_api_url)
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "topic" do
|
14
|
-
it "should return the curated lists for a given base path" do
|
15
|
-
base_path = "/test/base-path"
|
16
|
-
collections_api_has_content_for(base_path)
|
17
|
-
response = @api.topic(base_path)
|
18
|
-
assert_equal base_path, response["base_path"]
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'accepts "start" and "count" parameters for pagination' do
|
22
|
-
base_path = "/test/base-path"
|
23
|
-
|
24
|
-
collections_api_has_content_for(base_path, start: '10', count: '20')
|
25
|
-
response = @api.topic(base_path, start: 10, count: 20)
|
26
|
-
|
27
|
-
assert_equal base_path, response['base_path']
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|