gds-api-adapters 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +20 -10
- data/lib/gds_api/base.rb +14 -4
- data/lib/gds_api/contactotron.rb +0 -3
- data/lib/gds_api/json_utils.rb +15 -4
- data/lib/gds_api/panopticon.rb +8 -0
- data/lib/gds_api/version.rb +1 -1
- data/test/contactotron_api_test.rb +1 -1
- data/test/gds_api_base_test.rb +11 -1
- data/test/json_utils_test.rb +26 -1
- data/test/panopticon_api_test.rb +18 -0
- metadata +16 -16
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
A set of API adapters to work with the GDS APIs, extracted from the frontend
|
1
|
+
A set of API adapters to work with the GDS APIs, extracted from the frontend
|
2
|
+
app.
|
2
3
|
|
3
4
|
Example usage:
|
4
5
|
|
@@ -12,38 +13,47 @@ Very much still a work in progress.
|
|
12
13
|
|
13
14
|
## Logging
|
14
15
|
|
15
|
-
Each HTTP request
|
16
|
+
Each HTTP request can be logged as JSON. Example:
|
16
17
|
|
17
18
|
{
|
18
19
|
"request_uri":"http://contactotron.platform/contacts/1",
|
19
|
-
"start_time":
|
20
|
+
"start_time":1324035128.9056342,
|
20
21
|
"status":"success",
|
21
|
-
"end_time":
|
22
|
+
"end_time":1324035129.2017104
|
22
23
|
}
|
23
24
|
|
24
|
-
|
25
|
+
|
26
|
+
By default we log to a NullLogger since we don't want to pollute your test
|
27
|
+
results or logs. To log output you'll want to set `GdsApi::Base.logger` to
|
28
|
+
something that actually logs:
|
25
29
|
|
26
30
|
GdsApi::Base.logger = Logger.new("/path/to/file.log")
|
27
31
|
|
28
32
|
## Test Helpers
|
29
33
|
|
30
|
-
There are also test helpers for stubbing various requests in other apps.
|
31
|
-
the panopticon helper:
|
34
|
+
There are also test helpers for stubbing various requests in other apps.
|
35
|
+
Example usage of the panopticon helper:
|
32
36
|
|
33
37
|
In test_helper.rb:
|
34
38
|
|
35
39
|
require 'gds_api/test_helpers/panopticon'
|
36
|
-
|
40
|
+
|
37
41
|
class ActiveSupport::TestCase
|
38
42
|
include GdsApi::TestHelpers::Panopticon
|
39
43
|
end
|
40
44
|
|
41
45
|
In the test:
|
42
|
-
|
43
|
-
panopticon_has_metadata('id' => 12345, 'need_id' => need.id,
|
46
|
+
|
47
|
+
panopticon_has_metadata('id' => 12345, 'need_id' => need.id,
|
48
|
+
'slug' => 'my_slug')
|
44
49
|
|
45
50
|
This presumes you have webmock installed and enabled.
|
46
51
|
|
47
52
|
## To Do
|
48
53
|
|
49
54
|
* Make timeout handling work
|
55
|
+
|
56
|
+
## Licence
|
57
|
+
|
58
|
+
Released under the MIT Licence, a copy of which can be found in the file
|
59
|
+
`LICENCE`.
|
data/lib/gds_api/base.rb
CHANGED
@@ -5,6 +5,8 @@ require 'null_logger'
|
|
5
5
|
class GdsApi::Base
|
6
6
|
include GdsApi::JsonUtils
|
7
7
|
|
8
|
+
attr_reader :options
|
9
|
+
|
8
10
|
class << self
|
9
11
|
attr_writer :logger
|
10
12
|
end
|
@@ -13,12 +15,20 @@ class GdsApi::Base
|
|
13
15
|
@logger ||= NullLogger.instance
|
14
16
|
end
|
15
17
|
|
16
|
-
def initialize(platform,
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def initialize(platform, options_or_endpoint_url=nil, maybe_options=nil)
|
19
|
+
if options_or_endpoint_url.is_a?(String)
|
20
|
+
@options = maybe_options || {}
|
21
|
+
@options[:endpoint_url] = options_or_endpoint_url
|
22
|
+
else
|
23
|
+
@options = options_or_endpoint_url || {}
|
24
|
+
end
|
25
|
+
self.endpoint = options[:endpoint_url] || endpoint_for_platform(adapter_name, platform)
|
20
26
|
end
|
21
27
|
|
28
|
+
def adapter_name
|
29
|
+
self.class.to_s.split("::").last.downcase
|
30
|
+
end
|
31
|
+
|
22
32
|
def url_for_slug(slug, options={})
|
23
33
|
base = "#{base_url}/#{slug}.json#{query_string(options)}"
|
24
34
|
end
|
data/lib/gds_api/contactotron.rb
CHANGED
data/lib/gds_api/json_utils.rb
CHANGED
@@ -11,7 +11,7 @@ module GdsApi::JsonUtils
|
|
11
11
|
'Content-Type' => 'application/json',
|
12
12
|
'User-Agent' => "GDS Api Client v. #{GdsApi::VERSION}"
|
13
13
|
}
|
14
|
-
|
14
|
+
DEFAULT_TIMEOUT_IN_SECONDS = 0.5
|
15
15
|
|
16
16
|
def do_request(url, &block)
|
17
17
|
loggable = {request_uri: url, start_time: Time.now.to_f}
|
@@ -22,7 +22,7 @@ module GdsApi::JsonUtils
|
|
22
22
|
logger.debug "I will request #{request}"
|
23
23
|
|
24
24
|
response = Net::HTTP.start(url.host, url.port) do |http|
|
25
|
-
http.read_timeout =
|
25
|
+
http.read_timeout = options[:timeout] || DEFAULT_TIMEOUT_IN_SECONDS
|
26
26
|
yield http, request
|
27
27
|
end
|
28
28
|
|
@@ -30,14 +30,19 @@ module GdsApi::JsonUtils
|
|
30
30
|
logger.info loggable.merge(status: 'success', end_time: Time.now).to_json
|
31
31
|
JSON.parse(response.body)
|
32
32
|
else
|
33
|
-
|
33
|
+
body = begin
|
34
|
+
JSON.parse(response.body)
|
35
|
+
rescue
|
36
|
+
response.body
|
37
|
+
end
|
38
|
+
loggable.merge!(status: response.code, end_time: Time.now.to_f, body: body)
|
34
39
|
logger.warn loggable.to_json
|
35
40
|
nil
|
36
41
|
end
|
37
42
|
rescue Errno::ECONNREFUSED
|
38
43
|
logger.error loggable.merge(status: 'refused', end_time: Time.now.to_f).to_json
|
39
44
|
raise GdsApi::EndpointNotFound.new("Could not connect to #{url}")
|
40
|
-
rescue Timeout::Error, Errno::ECONNRESET
|
45
|
+
rescue Timeout::Error, Errno::ECONNRESET => e
|
41
46
|
logger.error loggable.merge(status: 'failed', end_time: Time.now.to_f).to_json
|
42
47
|
nil
|
43
48
|
end
|
@@ -59,6 +64,12 @@ module GdsApi::JsonUtils
|
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
67
|
+
def put_json(url, params)
|
68
|
+
do_request(url) do |http, path|
|
69
|
+
http.put(path, params.to_json, REQUEST_HEADERS)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
62
73
|
def to_ostruct(object)
|
63
74
|
case object
|
64
75
|
when Hash
|
data/lib/gds_api/panopticon.rb
CHANGED
@@ -13,6 +13,14 @@ class GdsApi::Panopticon < GdsApi::Base
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def create_artefact(artefact)
|
17
|
+
post_json(base_url + ".json", artefact)
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_artefact(id_or_slug, artefact)
|
21
|
+
put_json("#{base_url}/#{id_or_slug}.json", artefact)
|
22
|
+
end
|
23
|
+
|
16
24
|
private
|
17
25
|
def base_url
|
18
26
|
"#{endpoint}/artefacts"
|
data/lib/gds_api/version.rb
CHANGED
data/test/gds_api_base_test.rb
CHANGED
@@ -54,5 +54,15 @@ class GdsApiBaseTest < MiniTest::Unit::TestCase
|
|
54
54
|
u = URI.parse(url)
|
55
55
|
assert_match /^concreteapi\.test/, u.host
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
|
+
def test_should_treat_second_positional_arg_as_endpoint_url_if_string
|
59
|
+
api = ConcreteApi.new("test", "endpoint")
|
60
|
+
assert_equal "endpoint", api.options[:endpoint_url]
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_should_accept_options_as_second_arg
|
64
|
+
api = ConcreteApi.new("test", {endpoint_url: "endpoint", foo: "bar"})
|
65
|
+
assert_equal "endpoint", api.options[:endpoint_url]
|
66
|
+
assert_equal "bar", api.options[:foo]
|
67
|
+
end
|
58
68
|
end
|
data/test/json_utils_test.rb
CHANGED
@@ -1,6 +1,25 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'gds_api/json_utils'
|
3
|
+
require 'rack'
|
4
|
+
|
5
|
+
StubRackApp = lambda do |env|
|
6
|
+
sleep(30)
|
7
|
+
body = '{"some":"value"}'
|
8
|
+
[200, {"Content-Type" => "text/plain", "Content-Length" => body.length.to_s}, [body]]
|
9
|
+
end
|
10
|
+
|
1
11
|
class JsonUtilsTest < MiniTest::Unit::TestCase
|
2
12
|
include GdsApi::JsonUtils
|
3
13
|
|
14
|
+
def options; {}; end
|
15
|
+
def pending_test_long_requests_timeout
|
16
|
+
url = "http://www.example.com/timeout.json"
|
17
|
+
stub_request(:get, url).to_rack(StubRackApp)
|
18
|
+
assert_raises GdsApi::TimedOut do
|
19
|
+
get_json(url)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
4
23
|
def test_get_returns_nil_on_timeout
|
5
24
|
url = "http://some.endpoint/some.json"
|
6
25
|
stub_request(:get, url).to_raise(Timeout::Error)
|
@@ -40,5 +59,11 @@ class JsonUtilsTest < MiniTest::Unit::TestCase
|
|
40
59
|
stub_request(:get, url).to_return(:body => "{}", :status => 404)
|
41
60
|
assert_nil get_json(url)
|
42
61
|
end
|
43
|
-
|
62
|
+
|
63
|
+
def test_put_json_does_put_with_json_encoded_packet
|
64
|
+
url = "http://some.endpoint/some.json"
|
65
|
+
payload = {a:1}
|
66
|
+
stub_request(:put, url).with(body: payload.to_json).to_return(:body => "{}", :status => 200)
|
67
|
+
assert_equal({}, put_json(url, payload))
|
68
|
+
end
|
44
69
|
end
|
data/test/panopticon_api_test.rb
CHANGED
@@ -65,4 +65,22 @@ class PanopticonApiTest < MiniTest::Unit::TestCase
|
|
65
65
|
assert_equal 'Department for Environment, Food and Rural Affairs (Defra)', artefact.contact.name
|
66
66
|
assert_equal 'helpline@defra.gsi.gov.uk', artefact.contact.email_address
|
67
67
|
end
|
68
|
+
|
69
|
+
def test_can_create_a_new_artefact
|
70
|
+
url = "#{PANOPTICON_ENDPOINT}/artefacts.json"
|
71
|
+
stub_request(:post, url)
|
72
|
+
.with(body: basic_artefact.to_json)
|
73
|
+
.to_return(body: basic_artefact.merge(id: 1).to_json)
|
74
|
+
|
75
|
+
api.create_artefact(basic_artefact)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_can_update_existing_artefact
|
79
|
+
url = "#{PANOPTICON_ENDPOINT}/artefacts/1.json"
|
80
|
+
stub_request(:put, url)
|
81
|
+
.with(body: basic_artefact.to_json)
|
82
|
+
.to_return(status: 200, body: '{}')
|
83
|
+
|
84
|
+
api.update_artefact(1, basic_artefact)
|
85
|
+
end
|
68
86
|
end
|
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: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-21 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: plek
|
16
|
-
requirement: &
|
16
|
+
requirement: &70165614975140 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70165614975140
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: null_logger
|
27
|
-
requirement: &
|
27
|
+
requirement: &70165614974680 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70165614974680
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
requirement: &
|
38
|
+
requirement: &70165614974160 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.2.2
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70165614974160
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: webmock
|
49
|
-
requirement: &
|
49
|
+
requirement: &70165614973620 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '1.7'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70165614973620
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rack
|
60
|
-
requirement: &
|
60
|
+
requirement: &70165614973220 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70165614973220
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: simplecov
|
71
|
-
requirement: &
|
71
|
+
requirement: &70165614972680 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - =
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.4.2
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70165614972680
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: simplecov-rcov
|
82
|
-
requirement: &
|
82
|
+
requirement: &70165614972260 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70165614972260
|
91
91
|
description: A set of adapters providing easy access to the GDS gov.uk APIs
|
92
92
|
email:
|
93
93
|
- jystewart@gmail.com
|