gds-api-adapters 5.5.0 → 6.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.
- data/lib/gds_api/base.rb +9 -1
- data/lib/gds_api/content_api.rb +5 -6
- data/lib/gds_api/helpers.rb +5 -0
- data/lib/gds_api/json_client.rb +48 -17
- data/lib/gds_api/{content_api/list_response.rb → list_response.rb} +5 -5
- data/lib/gds_api/null_cache.rb +13 -0
- data/lib/gds_api/response.rb +54 -13
- data/lib/gds_api/rummager.rb +12 -33
- data/lib/gds_api/test_helpers/common_responses.rb +36 -0
- data/lib/gds_api/test_helpers/content_api.rb +6 -33
- data/lib/gds_api/test_helpers/json_client_helper.rb +2 -14
- data/lib/gds_api/test_helpers/worldwide.rb +116 -0
- data/lib/gds_api/version.rb +1 -1
- data/lib/gds_api/worldwide.rb +21 -0
- data/test/fixtures/world_organisations_australia.json +490 -0
- data/test/gds_api_base_test.rb +5 -0
- data/test/json_client_test.rb +66 -30
- data/test/list_response_test.rb +179 -0
- data/test/response_test.rb +192 -0
- data/test/rummager_test.rb +8 -32
- data/test/test_helper.rb +2 -0
- data/test/worldwide_api_test.rb +71 -0
- metadata +17 -8
- data/lib/gds_api/content_api/response.rb +0 -56
- data/test/content_api_response_test.rb +0 -97
data/lib/gds_api/base.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative 'json_client'
|
|
2
2
|
require 'cgi'
|
3
3
|
require 'null_logger'
|
4
4
|
require 'plek'
|
5
|
+
require_relative 'list_response'
|
5
6
|
|
6
7
|
class GdsApi::Base
|
7
8
|
class InvalidAPIURL < StandardError
|
@@ -21,7 +22,8 @@ class GdsApi::Base
|
|
21
22
|
:post_json, :post_json!,
|
22
23
|
:put_json, :put_json!,
|
23
24
|
:delete_json!,
|
24
|
-
:get_raw, :
|
25
|
+
:get_raw, :get_raw!,
|
26
|
+
:post_multipart
|
25
27
|
|
26
28
|
attr_reader :options
|
27
29
|
|
@@ -50,6 +52,12 @@ class GdsApi::Base
|
|
50
52
|
base = "#{base_url}/#{slug}.json#{query_string(options)}"
|
51
53
|
end
|
52
54
|
|
55
|
+
def get_list!(url)
|
56
|
+
get_json!(url) do |r|
|
57
|
+
GdsApi::ListResponse.new(r, self)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
53
61
|
private
|
54
62
|
attr_accessor :endpoint
|
55
63
|
|
data/lib/gds_api/content_api.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative 'base'
|
2
2
|
require_relative 'exceptions'
|
3
|
-
|
4
|
-
require 'gds_api/content_api/list_response'
|
3
|
+
require_relative 'list_response'
|
5
4
|
|
6
5
|
class GdsApi::ContentApi < GdsApi::Base
|
7
6
|
include GdsApi::ExceptionHandling
|
@@ -95,26 +94,26 @@ class GdsApi::ContentApi < GdsApi::Base
|
|
95
94
|
|
96
95
|
def get_list!(url)
|
97
96
|
get_json!(url) { |r|
|
98
|
-
ListResponse.new(r, self, web_urls_relative_to: @web_urls_relative_to)
|
97
|
+
GdsApi::ListResponse.new(r, self, web_urls_relative_to: @web_urls_relative_to)
|
99
98
|
}
|
100
99
|
end
|
101
100
|
|
102
101
|
def get_list(url)
|
103
102
|
get_json(url) { |r|
|
104
|
-
ListResponse.new(r, self, web_urls_relative_to: @web_urls_relative_to)
|
103
|
+
GdsApi::ListResponse.new(r, self, web_urls_relative_to: @web_urls_relative_to)
|
105
104
|
}
|
106
105
|
end
|
107
106
|
|
108
107
|
def get_json(url, &create_response)
|
109
108
|
create_response = create_response || Proc.new { |r|
|
110
|
-
GdsApi::
|
109
|
+
GdsApi::Response.new(r, web_urls_relative_to: @web_urls_relative_to)
|
111
110
|
}
|
112
111
|
super(url, &create_response)
|
113
112
|
end
|
114
113
|
|
115
114
|
def get_json!(url, &create_response)
|
116
115
|
create_response = create_response || Proc.new { |r|
|
117
|
-
GdsApi::
|
116
|
+
GdsApi::Response.new(r, web_urls_relative_to: @web_urls_relative_to)
|
118
117
|
}
|
119
118
|
super(url, &create_response)
|
120
119
|
end
|
data/lib/gds_api/helpers.rb
CHANGED
@@ -4,6 +4,7 @@ require 'gds_api/panopticon'
|
|
4
4
|
require 'gds_api/content_api'
|
5
5
|
require 'gds_api/licence_application'
|
6
6
|
require 'gds_api/asset_manager'
|
7
|
+
require 'gds_api/worldwide'
|
7
8
|
|
8
9
|
module GdsApi
|
9
10
|
module Helpers
|
@@ -35,6 +36,10 @@ module GdsApi
|
|
35
36
|
Object::const_defined?(:PANOPTICON_API_CREDENTIALS) ? PANOPTICON_API_CREDENTIALS : {}
|
36
37
|
end
|
37
38
|
|
39
|
+
def worldwide_api(options = {})
|
40
|
+
@worldwide_api ||= GdsApi::Worldwide.new(Plek.current.find("whitehall-admin"), options)
|
41
|
+
end
|
42
|
+
|
38
43
|
def self.included(klass)
|
39
44
|
if klass.respond_to?(:helper_method)
|
40
45
|
klass.helper_method :publisher_api, :panopticon_api, :imminence_api, :content_api, :licence_application_api
|
data/lib/gds_api/json_client.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative 'response'
|
2
2
|
require_relative 'exceptions'
|
3
3
|
require_relative 'version'
|
4
|
+
require_relative 'null_cache'
|
4
5
|
require 'lrucache'
|
5
6
|
require 'rest-client'
|
6
7
|
|
@@ -20,10 +21,19 @@ module GdsApi
|
|
20
21
|
attr_accessor :logger, :options, :cache
|
21
22
|
|
22
23
|
def initialize(options = {})
|
24
|
+
if options[:disable_timeout] or options[:timeout].to_i < 0
|
25
|
+
raise "It is no longer possible to disable the timeout."
|
26
|
+
end
|
27
|
+
|
23
28
|
@logger = options[:logger] || GdsApi::Base.logger
|
24
|
-
|
25
|
-
|
26
|
-
|
29
|
+
|
30
|
+
if options[:disable_cache]
|
31
|
+
@cache = NullCache.new
|
32
|
+
else
|
33
|
+
cache_size = options[:cache_size] || DEFAULT_CACHE_SIZE
|
34
|
+
cache_ttl = options[:cache_ttl] || DEFAULT_CACHE_TTL
|
35
|
+
@cache = JsonClient.cache(cache_size, cache_ttl)
|
36
|
+
end
|
27
37
|
@options = options
|
28
38
|
end
|
29
39
|
|
@@ -33,12 +43,16 @@ module GdsApi
|
|
33
43
|
'User-Agent' => "GDS Api Client v. #{GdsApi::VERSION}"
|
34
44
|
}
|
35
45
|
DEFAULT_TIMEOUT_IN_SECONDS = 4
|
36
|
-
DEFAULT_CACHE_SIZE =
|
46
|
+
DEFAULT_CACHE_SIZE = 100
|
37
47
|
DEFAULT_CACHE_TTL = 15 * 60 # 15 minutes
|
38
48
|
|
49
|
+
def get_raw!(url)
|
50
|
+
do_raw_request(:get, url)
|
51
|
+
end
|
52
|
+
|
39
53
|
def get_raw(url)
|
40
54
|
ignoring GdsApi::HTTPNotFound do
|
41
|
-
|
55
|
+
get_raw!(url)
|
42
56
|
end
|
43
57
|
end
|
44
58
|
|
@@ -139,13 +153,9 @@ module GdsApi
|
|
139
153
|
# Take a hash of parameters for Request#execute; return a hash of
|
140
154
|
# parameters with timeouts included
|
141
155
|
def with_timeout(method_params)
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
method_params.merge(
|
146
|
-
timeout: options[:timeout] || DEFAULT_TIMEOUT_IN_SECONDS
|
147
|
-
)
|
148
|
-
end
|
156
|
+
method_params.merge(
|
157
|
+
timeout: options[:timeout] || DEFAULT_TIMEOUT_IN_SECONDS
|
158
|
+
)
|
149
159
|
end
|
150
160
|
|
151
161
|
def with_ssl_options(method_params)
|
@@ -157,11 +167,32 @@ module GdsApi
|
|
157
167
|
|
158
168
|
def do_request_with_cache(method, url, params = nil)
|
159
169
|
# Only read GET requests from the cache: any other request methods should
|
160
|
-
# always be passed through
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
170
|
+
# always be passed through. Note that this means HEAD requests won't get
|
171
|
+
# cached, but that would involve separating the cache by method and URL.
|
172
|
+
# Also, we don't generally make HEAD requests.
|
173
|
+
use_cache = (method == :get)
|
174
|
+
|
175
|
+
if use_cache
|
176
|
+
cached_response = @cache[url]
|
177
|
+
return cached_response if cached_response
|
178
|
+
end
|
179
|
+
|
180
|
+
response = do_request(method, url, params)
|
181
|
+
|
182
|
+
if use_cache
|
183
|
+
cache_time = response_cache_time(response)
|
184
|
+
# If cache_time is nil, this will fall back on @cache's default
|
185
|
+
@cache.store(url, response, cache_time)
|
186
|
+
end
|
187
|
+
|
188
|
+
response
|
189
|
+
end
|
190
|
+
|
191
|
+
# Return either a Time object representing the expiry time of the response
|
192
|
+
# or nil if no cache information is provided
|
193
|
+
def response_cache_time(response)
|
194
|
+
if response.headers[:expires]
|
195
|
+
Time.httpdate response.headers[:expires]
|
165
196
|
end
|
166
197
|
end
|
167
198
|
|
@@ -2,13 +2,13 @@ require "json"
|
|
2
2
|
require "gds_api/response"
|
3
3
|
require "link_header"
|
4
4
|
|
5
|
-
|
5
|
+
module GdsApi
|
6
6
|
|
7
|
-
# Response class for lists of multiple items
|
7
|
+
# Response class for lists of multiple items.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
# under the `results` key. The response may also have previous and
|
11
|
-
# pages, indicated by entries in the response's `Link` header.
|
9
|
+
# This expects responses to be in a common format, with the list of results
|
10
|
+
# contained under the `results` key. The response may also have previous and
|
11
|
+
# subsequent pages, indicated by entries in the response's `Link` header.
|
12
12
|
class ListResponse < Response
|
13
13
|
|
14
14
|
# The ListResponse is instantiated with a reference back to the API client,
|
data/lib/gds_api/response.rb
CHANGED
@@ -3,50 +3,91 @@ require 'ostruct'
|
|
3
3
|
require_relative 'core-ext/openstruct'
|
4
4
|
|
5
5
|
module GdsApi
|
6
|
+
|
7
|
+
# This wraps an HTTP response with a JSON body, and presents this as
|
8
|
+
# an object that has the read behaviour of both a Hash and an OpenStruct
|
9
|
+
#
|
10
|
+
# Responses can be configured to use relative URLs for `web_url` properties.
|
11
|
+
# API endpoints should return absolute URLs so that they make sense outside of the
|
12
|
+
# GOV.UK context. However on internal systems we want to present relative URLs.
|
13
|
+
# By specifying a base URI, this will convert all matching web_urls into relative URLs
|
14
|
+
# This is useful on non-canonical frontends, such as those in staging environments.
|
15
|
+
# See: https://github.com/alphagov/wiki/wiki/API-conventions for details on the API conventions
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# r = Response.new(response, web_urls_relative_to: "https://www.gov.uk")
|
20
|
+
# r.results[0].web_url
|
21
|
+
# => "/bank-holidays"
|
6
22
|
class Response
|
7
23
|
extend Forwardable
|
8
24
|
include Enumerable
|
9
25
|
|
26
|
+
WEB_URL_KEYS = ["web_url"]
|
27
|
+
|
10
28
|
def_delegators :to_hash, :[], :"<=>", :each
|
11
29
|
|
12
|
-
def initialize(http_response)
|
30
|
+
def initialize(http_response, options = {})
|
13
31
|
@http_response = http_response
|
32
|
+
@web_urls_relative_to = URI.parse(options[:web_urls_relative_to]) if options[:web_urls_relative_to]
|
14
33
|
end
|
15
34
|
|
16
35
|
def raw_response_body
|
17
36
|
@http_response.body
|
18
37
|
end
|
19
38
|
|
20
|
-
def to_hash
|
21
|
-
@parsed ||= JSON.parse(@http_response.body)
|
22
|
-
end
|
23
|
-
|
24
39
|
def code
|
25
40
|
# Return an integer code for consistency with HTTPErrorResponse
|
26
41
|
@http_response.code
|
27
42
|
end
|
28
43
|
|
44
|
+
def to_hash
|
45
|
+
@parsed ||= transform_parsed(JSON.parse(@http_response.body))
|
46
|
+
end
|
47
|
+
|
29
48
|
def to_ostruct
|
30
|
-
self.class.build_ostruct_recursively(to_hash)
|
49
|
+
@ostruct ||= self.class.build_ostruct_recursively(to_hash)
|
31
50
|
end
|
32
51
|
|
33
52
|
def method_missing(method)
|
34
|
-
|
35
|
-
to_ostruct.send(method)
|
36
|
-
else
|
37
|
-
nil
|
38
|
-
end
|
53
|
+
to_ostruct.send(method)
|
39
54
|
end
|
40
55
|
|
41
56
|
def respond_to_missing?(method, include_private)
|
42
|
-
|
57
|
+
to_ostruct.respond_to?(method, include_private)
|
43
58
|
end
|
44
59
|
|
45
|
-
def present?;
|
60
|
+
def present?; true; end
|
46
61
|
def blank?; false; end
|
47
62
|
|
48
63
|
private
|
49
64
|
|
65
|
+
def transform_parsed(value)
|
66
|
+
return value if @web_urls_relative_to.nil?
|
67
|
+
|
68
|
+
case value
|
69
|
+
when Hash
|
70
|
+
Hash[value.map { |k, v|
|
71
|
+
# NOTE: Don't bother transforming if the value is nil
|
72
|
+
if WEB_URL_KEYS.include?(k) && v
|
73
|
+
# Use relative URLs to route when the web_url value is on the
|
74
|
+
# same domain as the site root. Note that we can't just use the
|
75
|
+
# `route_to` method, as this would give us technically correct
|
76
|
+
# but potentially confusing `//host/path` URLs for URLs with the
|
77
|
+
# same scheme but different hosts.
|
78
|
+
relative_url = @web_urls_relative_to.route_to(v)
|
79
|
+
[k, relative_url.host ? v : relative_url.to_s]
|
80
|
+
else
|
81
|
+
[k, transform_parsed(v)]
|
82
|
+
end
|
83
|
+
}]
|
84
|
+
when Array
|
85
|
+
value.map { |v| transform_parsed(v) }
|
86
|
+
else
|
87
|
+
value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
50
91
|
def self.build_ostruct_recursively(value)
|
51
92
|
case value
|
52
93
|
when Hash
|
data/lib/gds_api/rummager.rb
CHANGED
@@ -1,56 +1,35 @@
|
|
1
|
+
require 'gds_api/base'
|
1
2
|
require 'rack/utils'
|
2
3
|
|
3
4
|
module GdsApi
|
4
|
-
class Rummager
|
5
|
-
class SearchUriNotSpecified < RuntimeError; end
|
6
|
-
class SearchError < RuntimeError; end
|
7
|
-
class SearchServiceError < SearchError; end
|
8
|
-
class SearchTimeout < SearchError; end
|
9
|
-
|
10
|
-
attr_accessor :search_uri
|
11
|
-
|
12
|
-
def initialize(search_uri)
|
13
|
-
raise SearchUriNotSpecified unless search_uri
|
14
|
-
self.search_uri = search_uri
|
15
|
-
end
|
5
|
+
class Rummager < Base
|
16
6
|
|
17
7
|
def search(query, format_filter = nil)
|
18
8
|
return [] if query.nil? || query == ""
|
19
|
-
|
9
|
+
get_json!(search_url(:search, query, format_filter))
|
20
10
|
end
|
21
11
|
|
22
12
|
def autocomplete(query, format_filter = nil)
|
23
13
|
return [] if query.nil? || query == ""
|
24
|
-
|
14
|
+
get_raw!(search_url(:autocomplete, query, format_filter)).body
|
25
15
|
end
|
26
16
|
|
27
17
|
def advanced_search(args)
|
28
18
|
return [] if args.nil? || args.empty?
|
29
|
-
|
19
|
+
request_path = "#{base_url}/advanced_search?#{Rack::Utils.build_nested_query(args)}"
|
20
|
+
get_json!(request_path)
|
30
21
|
end
|
31
22
|
|
32
|
-
|
33
|
-
|
34
|
-
def advanced_search_response(args)
|
35
|
-
request_path = "/advanced_search?#{Rack::Utils.build_nested_query(args)}"
|
36
|
-
get_response(request_path)
|
37
|
-
end
|
23
|
+
private
|
38
24
|
|
39
|
-
def
|
40
|
-
request_path = "/#{type}?q=#{CGI.escape(query)}"
|
25
|
+
def search_url(type, query, format_filter = nil)
|
26
|
+
request_path = "#{base_url}/#{type}?q=#{CGI.escape(query)}"
|
41
27
|
request_path << "&format_filter=#{CGI.escape(format_filter)}" if format_filter
|
42
|
-
|
28
|
+
request_path
|
43
29
|
end
|
44
30
|
|
45
|
-
def
|
46
|
-
|
47
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
48
|
-
http.use_ssl = true if uri.scheme == 'https'
|
49
|
-
response = http.get(uri.request_uri, {"Accept" => "application/json"})
|
50
|
-
raise SearchServiceError.new("#{response.code}: #{response.body}") unless response.code == "200"
|
51
|
-
response
|
52
|
-
rescue Timeout::Error
|
53
|
-
raise SearchTimeout
|
31
|
+
def base_url
|
32
|
+
endpoint
|
54
33
|
end
|
55
34
|
end
|
56
35
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module GdsApi
|
2
|
+
module TestHelpers
|
3
|
+
module CommonResponses
|
4
|
+
def titleize_slug(slug, options = {})
|
5
|
+
if options[:title_case]
|
6
|
+
slug.gsub("-", " ").gsub(/\b./) {|m| m.upcase }
|
7
|
+
else
|
8
|
+
slug.gsub("-", " ").capitalize
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def response_base
|
13
|
+
{
|
14
|
+
"_response_info" => {
|
15
|
+
"status" => "ok"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
alias_method :singular_response_base, :response_base
|
20
|
+
|
21
|
+
def plural_response_base
|
22
|
+
response_base.merge(
|
23
|
+
{
|
24
|
+
"description" => "Tags!",
|
25
|
+
"total" => 100,
|
26
|
+
"start_index" => 1,
|
27
|
+
"page_size" => 100,
|
28
|
+
"current_page" => 1,
|
29
|
+
"pages" => 1,
|
30
|
+
"results" => []
|
31
|
+
}
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'gds_api/test_helpers/json_client_helper'
|
2
2
|
require 'cgi'
|
3
|
-
|
3
|
+
require 'gds_api/test_helpers/common_responses'
|
4
4
|
|
5
5
|
module GdsApi
|
6
6
|
module TestHelpers
|
7
7
|
module ContentApi
|
8
|
+
include GdsApi::TestHelpers::CommonResponses
|
8
9
|
# Generally true. If you are initializing the client differently,
|
9
10
|
# you could redefine/override the constant or stub directly.
|
10
11
|
CONTENT_API_ENDPOINT = Plek.current.find('contentapi')
|
@@ -295,38 +296,10 @@ module GdsApi
|
|
295
296
|
raise "Need a licence identifier" if details[:licence_identifier].nil?
|
296
297
|
@stubbed_content_api_licences << details
|
297
298
|
end
|
298
|
-
|
299
|
-
private
|
300
|
-
|
301
|
-
def titleize_slug(slug)
|
302
|
-
slug.gsub("-", " ").capitalize
|
303
|
-
end
|
304
|
-
|
305
|
-
def response_base
|
306
|
-
{
|
307
|
-
"_response_info" => {
|
308
|
-
"status" => "ok"
|
309
|
-
}
|
310
|
-
}
|
311
|
-
end
|
312
|
-
|
313
|
-
def singular_response_base
|
314
|
-
response_base
|
315
|
-
end
|
316
|
-
|
317
|
-
def plural_response_base
|
318
|
-
response_base.merge(
|
319
|
-
{
|
320
|
-
"description" => "Tags!",
|
321
|
-
"total" => 100,
|
322
|
-
"startIndex" => 1,
|
323
|
-
"pageSize" => 100,
|
324
|
-
"currentPage" => 1,
|
325
|
-
"pages" => 1,
|
326
|
-
"results" => []
|
327
|
-
}
|
328
|
-
)
|
329
|
-
end
|
330
299
|
end
|
331
300
|
end
|
332
301
|
end
|
302
|
+
|
303
|
+
# This has to be after the definition of TestHelpers::ContentApi, otherwise, this doesn't pick up
|
304
|
+
# the include of TestHelpers::CommonResponses
|
305
|
+
require_relative 'content_api/artefact_stub'
|
@@ -1,16 +1,4 @@
|
|
1
1
|
require 'gds_api/json_client'
|
2
|
+
require 'gds_api/null_cache'
|
2
3
|
|
3
|
-
|
4
|
-
module TestHelpers
|
5
|
-
class NullCache
|
6
|
-
def [](k)
|
7
|
-
nil
|
8
|
-
end
|
9
|
-
|
10
|
-
def []=(k, v)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
GdsApi::JsonClient.cache = GdsApi::TestHelpers::NullCache.new
|
4
|
+
GdsApi::JsonClient.cache = GdsApi::NullCache.new
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'gds_api/test_helpers/json_client_helper'
|
2
|
+
require 'gds_api/test_helpers/common_responses'
|
3
|
+
|
4
|
+
module GdsApi
|
5
|
+
module TestHelpers
|
6
|
+
module Worldwide
|
7
|
+
include GdsApi::TestHelpers::CommonResponses
|
8
|
+
|
9
|
+
WORLDWIDE_API_ENDPOINT = Plek.current.find('whitehall-admin')
|
10
|
+
|
11
|
+
# Sets up the index endpoints for the given country slugs
|
12
|
+
# The stubs are setup to paginate in chunks of 20
|
13
|
+
#
|
14
|
+
# This also sets up the individual endpoints for each slug
|
15
|
+
# by calling worldwide_api_has_location below
|
16
|
+
def worldwide_api_has_locations(location_slugs)
|
17
|
+
location_slugs.each {|s| worldwide_api_has_location(s) }
|
18
|
+
pages = []
|
19
|
+
location_slugs.each_slice(20) do |slugs|
|
20
|
+
pages << slugs.map {|s| world_location_details_for_slug(s) }
|
21
|
+
end
|
22
|
+
|
23
|
+
pages.each_with_index do |page, i|
|
24
|
+
page_details = plural_response_base.merge({
|
25
|
+
"results" => page,
|
26
|
+
"total" => location_slugs.size,
|
27
|
+
"pages" => pages.size,
|
28
|
+
"current_page" => i + 1,
|
29
|
+
"page_size" => 20,
|
30
|
+
"start_index" => i * 20 + 1,
|
31
|
+
})
|
32
|
+
|
33
|
+
links = {:self => "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i + 1}" }
|
34
|
+
links[:next] = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i + 2}" if pages[i+1]
|
35
|
+
links[:previous] = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations?page=#{i}" unless i == 0
|
36
|
+
page_details["_response_info"]["links"] = []
|
37
|
+
link_headers = []
|
38
|
+
links.each do |rel, href|
|
39
|
+
page_details["_response_info"]["links"] << {"rel" => rel, "href" => href}
|
40
|
+
link_headers << "<#{href}>; rel=\"#{rel}\""
|
41
|
+
end
|
42
|
+
|
43
|
+
stub_request(:get, links[:self]).
|
44
|
+
to_return(:status => 200, :body => page_details.to_json, :headers => {"Link" => link_headers.join(", ")})
|
45
|
+
if i == 0
|
46
|
+
# First page exists at URL with and without page param
|
47
|
+
stub_request(:get, links[:self].sub(/\?page=1/, '')).
|
48
|
+
to_return(:status => 200, :body => page_details.to_json, :headers => {"Link" => link_headers.join(", ")})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def worldwide_api_has_selection_of_locations
|
54
|
+
worldwide_api_has_locations %w(
|
55
|
+
afghanistan angola australia bahamas belarus brazil brunei cambodia chad
|
56
|
+
croatia denmark eritrea france ghana iceland japan laos luxembourg malta
|
57
|
+
micronesia mozambique nicaragua panama portugal sao-tome-and-principe singapore
|
58
|
+
south-korea sri-lanka uk-delegation-to-council-of-europe
|
59
|
+
uk-delegation-to-organization-for-security-and-co-operation-in-europe
|
60
|
+
united-kingdom venezuela vietnam
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
def worldwide_api_has_location(location_slug, details=nil)
|
65
|
+
details ||= world_location_for_slug(location_slug)
|
66
|
+
stub_request(:get, "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}").
|
67
|
+
to_return(:status => 200, :body => details.to_json)
|
68
|
+
end
|
69
|
+
|
70
|
+
def worldwide_api_does_not_have_location(location_slug)
|
71
|
+
stub_request(:get, "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}").to_return(:status => 404)
|
72
|
+
end
|
73
|
+
|
74
|
+
def worldwide_api_has_organisations_for_location(location_slug, json_or_hash)
|
75
|
+
json = json_or_hash.is_a?(Hash) ? json_or_hash.to_json : json_or_hash
|
76
|
+
url = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}/organisations"
|
77
|
+
stub_request(:get, url).
|
78
|
+
to_return(:status => 200, :body => json, :headers => {"Link" => "<#{url}; rel\"self\""})
|
79
|
+
end
|
80
|
+
|
81
|
+
def worldwide_api_has_no_organisations_for_location(location_slug)
|
82
|
+
details = {"results" => [], "total" => 0, "_response_info" => { "status" => "ok" } }
|
83
|
+
url = "#{WORLDWIDE_API_ENDPOINT}/api/world-locations/#{location_slug}/organisations"
|
84
|
+
stub_request(:get, url).
|
85
|
+
to_return(:status => 200, :body => details.to_json, :headers => {"Link" => "<#{url}; rel\"self\""})
|
86
|
+
end
|
87
|
+
|
88
|
+
def world_location_for_slug(slug)
|
89
|
+
singular_response_base.merge(world_location_details_for_slug(slug))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Constructs a sample world_location
|
93
|
+
#
|
94
|
+
# if the slug contains 'delegation' or 'mission' the format will be set to 'International delegation'
|
95
|
+
# othersiwe it will be set to 'World location'
|
96
|
+
def world_location_details_for_slug(slug)
|
97
|
+
{
|
98
|
+
"id" => "https://www.gov.uk/api/world-locations/#{slug}",
|
99
|
+
"title" => titleize_slug(slug, :title_case => true),
|
100
|
+
"format" => (slug =~ /(delegation|mission)/ ? "International delegation" : "World location"),
|
101
|
+
"updated_at" => "2013-03-25T13:06:42+00:00",
|
102
|
+
"web_url" => "https://www.gov.uk/government/world/#{slug}",
|
103
|
+
"details" => {
|
104
|
+
"slug" => slug,
|
105
|
+
"iso2" => slug[0..1].upcase,
|
106
|
+
},
|
107
|
+
"organisations" => {
|
108
|
+
"id" => "https://www.gov.uk/api/world-locations/#{slug}/organisations",
|
109
|
+
"web_url" => "https://www.gov.uk/government/world/#{slug}#organisations"
|
110
|
+
},
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/gds_api/version.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
class GdsApi::Worldwide < GdsApi::Base
|
4
|
+
|
5
|
+
def world_locations
|
6
|
+
get_list! "#{base_url}/world-locations"
|
7
|
+
end
|
8
|
+
|
9
|
+
def world_location(location_slug)
|
10
|
+
get_json "#{base_url}/world-locations/#{location_slug}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def organisations_for_world_location(location_slug)
|
14
|
+
get_list! "#{base_url}/world-locations/#{location_slug}/organisations"
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def base_url
|
19
|
+
"#{endpoint}/api"
|
20
|
+
end
|
21
|
+
end
|