gds-api-adapters 0.0.52 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gds_api/base.rb CHANGED
@@ -17,7 +17,8 @@ class GdsApi::Base
17
17
  end
18
18
  end
19
19
 
20
- def_delegators :client, :get_json, :post_json, :put_json, :get_raw
20
+ def_delegators :client, :get_json, :post_json, :post_json!,
21
+ :put_json, :put_json!, :get_raw
21
22
 
22
23
  attr_reader :options
23
24
 
@@ -4,4 +4,20 @@ module GdsApi
4
4
 
5
5
  class TimedOutException < Exception
6
6
  end
7
+
8
+ class HTTPErrorResponse < StandardError
9
+ attr_accessor :code
10
+
11
+ def initialize(code)
12
+ @code = code
13
+ end
14
+ end
15
+
16
+ module ExceptionHandling
17
+ def ignoring(exception, &block)
18
+ yield
19
+ rescue exception
20
+ # Discard the exception
21
+ end
22
+ end
7
23
  end
@@ -6,6 +6,8 @@ require 'lrucache'
6
6
  module GdsApi
7
7
  class JsonClient
8
8
 
9
+ include GdsApi::ExceptionHandling
10
+
9
11
  def self.cache(size=DEFAULT_CACHE_SIZE)
10
12
  @cache ||= LRUCache.new(max_size: size)
11
13
  end
@@ -36,14 +38,32 @@ module GdsApi
36
38
  end
37
39
 
38
40
  def get_json(url)
41
+ ignoring GdsApi::HTTPErrorResponse do
42
+ get_json! url
43
+ end
44
+ end
45
+
46
+ def get_json!(url)
39
47
  @cache[url] ||= do_json_request(Net::HTTP::Get, url)
40
48
  end
41
49
 
42
50
  def post_json(url, params)
51
+ ignoring GdsApi::HTTPErrorResponse do
52
+ post_json! url, params
53
+ end
54
+ end
55
+
56
+ def post_json!(url, params)
43
57
  do_json_request(Net::HTTP::Post, url, params)
44
58
  end
45
59
 
46
60
  def put_json(url, params)
61
+ ignoring GdsApi::HTTPErrorResponse do
62
+ put_json! url, params
63
+ end
64
+ end
65
+
66
+ def put_json!(url, params)
47
67
  do_json_request(Net::HTTP::Put, url, params)
48
68
  end
49
69
 
@@ -67,7 +87,7 @@ module GdsApi
67
87
  end
68
88
  loggable.merge!(status: response.code, end_time: Time.now.to_f, body: body)
69
89
  logger.warn loggable.to_json
70
- nil
90
+ raise GdsApi::HTTPErrorResponse.new(response.code.to_i), body
71
91
  end
72
92
  end
73
93
 
@@ -1,7 +1,11 @@
1
1
  require_relative 'base'
2
2
  require_relative 'panopticon/registerer'
3
+ require_relative 'exceptions'
3
4
 
4
5
  class GdsApi::Panopticon < GdsApi::Base
6
+
7
+ include GdsApi::ExceptionHandling
8
+
5
9
  def all
6
10
  url = base_url + '.json'
7
11
  json = get_json url
@@ -14,11 +18,31 @@ class GdsApi::Panopticon < GdsApi::Base
14
18
  end
15
19
 
16
20
  def create_artefact(artefact)
17
- post_json(base_url + ".json", artefact)
21
+ ignoring GdsApi::HTTPErrorResponse do
22
+ create_artefact! artefact
23
+ end
24
+ end
25
+
26
+ def create_artefact!(artefact)
27
+ post_json!(base_url + ".json", artefact)
28
+ end
29
+
30
+ def put_artefact(id_or_slug, artefact)
31
+ ignoring GdsApi::HTTPErrorResponse do
32
+ put_artefact! id_or_slug, artefact
33
+ end
34
+ end
35
+
36
+ def put_artefact!(id_or_slug, artefact)
37
+ put_json!("#{base_url}/#{id_or_slug}.json", artefact)
18
38
  end
19
39
 
20
40
  def update_artefact(id_or_slug, artefact)
21
- put_json("#{base_url}/#{id_or_slug}.json", artefact)
41
+ self.class.logger.warn(
42
+ "The update_artefact method is deprecated and may be removed in a " +
43
+ "future release. You should use put_artefact instead."
44
+ )
45
+ put_artefact(id_or_slug, artefact)
22
46
  end
23
47
 
24
48
  def curated_lists
@@ -2,7 +2,7 @@ module GdsApi
2
2
  class Panopticon < GdsApi::Base
3
3
  class Registerer
4
4
  attr_accessor :logger, :owning_app, :kind
5
-
5
+
6
6
  def initialize(options)
7
7
  @logger = options[:logger] || GdsApi::Base.logger
8
8
  @owning_app = options[:owning_app]
@@ -10,35 +10,43 @@ module GdsApi
10
10
  @panopticon = options[:panopticon]
11
11
  @platform = options[:platform] || ENV['FACTER_govuk_platform'] || 'development'
12
12
  end
13
-
13
+
14
14
  def record_to_artefact(record)
15
- hash = {slug: record.slug, owning_app: owning_app, kind: kind, name: record.title}
16
- [:need_id, :section].each do |attr_name|
15
+ hash = {
16
+ slug: record.slug,
17
+ owning_app: owning_app,
18
+ kind: kind,
19
+ name: record.title,
20
+ live: record.live
21
+ }
22
+ [:need_id, :section, :indexable_content].each do |attr_name|
17
23
  if record.respond_to? attr_name
18
24
  hash[attr_name] = record.send(attr_name)
19
25
  end
20
26
  end
21
27
  hash
22
28
  end
23
-
29
+
24
30
  # record should respond to #slug and #title, or override #record_to_artefact
25
31
  def register(record)
26
32
  register_artefact(record_to_artefact(record))
27
33
  end
28
-
34
+
29
35
  protected
30
-
36
+
31
37
  def register_artefact(artefact)
32
- logger.info "Checking #{artefact[:slug]}"
33
- existing = panopticon.artefact_for_slug(artefact[:slug])
34
- if ! existing
35
- logger.info "Creating #{artefact[:slug]}"
36
- panopticon.create_artefact(artefact)
37
- elsif existing.owning_app == artefact[:owning_app]
38
- logger.info "Updating #{artefact[:slug]}"
39
- panopticon.update_artefact(artefact[:slug], artefact)
38
+ logger.info "Putting #{artefact[:slug]}"
39
+
40
+ # Error responses here are pretty fatal, so propagate them
41
+ response = panopticon.put_artefact!(artefact[:slug], artefact)
42
+ case response.code
43
+ when 200
44
+ logger.info "Updated #{artefact[:slug]}"
45
+ when 201
46
+ logger.info "Created #{artefact[:slug]}"
40
47
  else
41
- raise "Slug #{artefact[:slug]} already registered to application '#{existing.owning_app}'"
48
+ # Only expect 200 or 201 success codes, but best to have a fallback
49
+ logger.info "Registered #{artefact[:slug]} (code #{response.code})"
42
50
  end
43
51
  end
44
52
 
@@ -48,7 +56,7 @@ module GdsApi
48
56
  }
49
57
  @panopticon ||= GdsApi::Panopticon.new(@platform, options.merge(panopticon_api_credentials))
50
58
  end
51
-
59
+
52
60
  def panopticon_api_credentials
53
61
  Object::const_defined?(:PANOPTICON_API_CREDENTIALS) ? PANOPTICON_API_CREDENTIALS : {}
54
62
  end
@@ -25,23 +25,6 @@ class GdsApi::Publisher < GdsApi::Base
25
25
  end
26
26
  end
27
27
 
28
- def council_for_snac_code(snac)
29
- if json = get_json("#{@endpoint}/local_transactions/find_by_snac?snac=#{snac}")
30
- json.to_hash
31
- else
32
- nil
33
- end
34
- end
35
-
36
- def council_for_name(name)
37
- name = URI.escape(name)
38
- if json = get_json("#{@endpoint}/local_transactions/find_by_council_name?name=#{name}")
39
- json.to_hash
40
- else
41
- nil
42
- end
43
- end
44
-
45
28
  def licences_for_ids(ids)
46
29
  response = get_json("#{@endpoint}/licences.json?ids=#{ids.map(&:to_s).sort.join(',')}")
47
30
  if response
@@ -17,6 +17,11 @@ module GdsApi
17
17
  @parsed ||= JSON.parse(@net_http_response.body)
18
18
  end
19
19
 
20
+ def code
21
+ # Return an integer code for consistency with HTTPErrorResponse
22
+ @net_http_response.code.to_i
23
+ end
24
+
20
25
  def to_ostruct
21
26
  self.class.build_ostruct_recursively(to_hash)
22
27
  end
@@ -31,13 +31,6 @@ module GdsApi
31
31
  stub_request(:get, url).to_return(:status => 404, :body => "", :headers => {})
32
32
  end
33
33
 
34
- def stub_panopticon_default_artefact
35
- stub_request(:get, %r{\A#{PANOPTICON_ENDPOINT}/artefacts}).to_return { |request|
36
- # return a response with only a slug, and set that slug to match the requested artefact slug
37
- {:body => JSON.dump("slug" => request.uri.path.split('/').last.chomp('.json'))}
38
- }
39
- end
40
-
41
34
  end
42
35
  end
43
36
  end
@@ -1,3 +1,3 @@
1
1
  module GdsApi
2
- VERSION = '0.0.52'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -98,14 +98,14 @@ class JsonClientTest < MiniTest::Spec
98
98
  response = @client.put_json(url, payload)
99
99
  assert_equal 2, response.a.b
100
100
  end
101
-
101
+
102
102
  def test_accessing_non_existent_attribute_of_response_returns_nil
103
103
  url = "http://some.endpoint/some.json"
104
104
  stub_request(:put, url).to_return(:body => '{"a":1}', :status => 200)
105
105
  response = @client.put_json(url, {})
106
106
  assert_equal nil, response.does_not_exist
107
107
  end
108
-
108
+
109
109
  def test_response_does_not_claim_to_respond_to_methods_corresponding_to_non_existent_attributes
110
110
  # This mimics the behaviour of OpenStruct
111
111
  url = "http://some.endpoint/some.json"
@@ -113,7 +113,7 @@ class JsonClientTest < MiniTest::Spec
113
113
  response = @client.put_json(url, {})
114
114
  assert ! response.respond_to?(:does_not_exist)
115
115
  end
116
-
116
+
117
117
  def test_a_response_is_always_considered_present_and_not_blank
118
118
  url = "http://some.endpoint/some.json"
119
119
  stub_request(:put, url).to_return(:body => '{"a":1}', :status => 200)
@@ -121,7 +121,7 @@ class JsonClientTest < MiniTest::Spec
121
121
  assert ! response.blank?
122
122
  assert response.present?
123
123
  end
124
-
124
+
125
125
  def test_client_can_use_basic_auth
126
126
  client = GdsApi::JsonClient.new(basic_auth: {user: 'user', password: 'password'})
127
127
 
@@ -23,6 +23,16 @@ class PanopticonApiTest < MiniTest::Unit::TestCase
23
23
  }
24
24
  end
25
25
 
26
+ def registerable_artefact
27
+ {
28
+ slug: 'foo',
29
+ owning_app: 'my-app',
30
+ kind: 'custom-application',
31
+ name: 'MyFoo',
32
+ live: true
33
+ }
34
+ end
35
+
26
36
  def api
27
37
  GdsApi::Panopticon.new('test')
28
38
  end
@@ -93,12 +103,12 @@ class PanopticonApiTest < MiniTest::Unit::TestCase
93
103
 
94
104
  api.update_artefact(1, basic_artefact)
95
105
  end
96
-
106
+
97
107
  def test_can_register_new_artefacts_en_masse
98
- artefact = {slug: 'foo', owning_app: 'my-app', kind: 'custom-application', name: 'MyFoo'}
99
108
  r = GdsApi::Panopticon::Registerer.new(platform: "test", owning_app: 'my-app')
109
+ artefact = registerable_artefact()
100
110
  panopticon_has_no_metadata_for('foo')
101
-
111
+
102
112
  stub_request(:put, "#{PANOPTICON_ENDPOINT}/artefacts/foo.json")
103
113
  .with(body: artefact.to_json)
104
114
  .to_return(body: artefact.merge(id: 1).to_json)
@@ -107,13 +117,13 @@ class PanopticonApiTest < MiniTest::Unit::TestCase
107
117
  stub_request(:post, url)
108
118
  .with(body: artefact.to_json)
109
119
  .to_return(body: artefact.merge(id: 1).to_json)
110
-
120
+
111
121
  record = OpenStruct.new(artefact.merge(title: artefact[:name]))
112
122
  r.register(record)
113
123
  end
114
124
 
115
125
  def test_can_register_existing_artefacts_en_masse
116
- artefact = {slug: 'foo', owning_app: 'my-app', kind: 'custom-application', name: 'MyFoo'}
126
+ artefact = registerable_artefact()
117
127
  r = GdsApi::Panopticon::Registerer.new(platform: "test", owning_app: 'my-app')
118
128
 
119
129
  panopticon_has_metadata(artefact)
@@ -138,48 +138,5 @@ describe GdsApi::Publisher do
138
138
 
139
139
  assert_equal nil, api.licences_for_ids([123,124])
140
140
  end
141
-
142
- it "should return nil if a council snac code is not found" do
143
- stub_request(:get, "#{PUBLISHER_ENDPOINT}/local_transactions/find_by_snac?snac=bloop").
144
- with(:headers => GdsApi::JsonClient::REQUEST_HEADERS).
145
- to_return(:status => 404, :body => " ", :headers => {})
146
-
147
- assert_equal nil, api.council_for_snac_code("bloop")
148
- end
149
-
150
- it "should return a council hash for a snac code" do
151
- stub_request(:get, "#{PUBLISHER_ENDPOINT}/local_transactions/find_by_snac?snac=AA00").
152
- with(:headers => GdsApi::JsonClient::REQUEST_HEADERS).
153
- to_return(:status => 200, :body => '{"name": "Some Council", "snac": "AA00"}', :headers => {})
154
-
155
- expected = {"name" => "Some Council", "snac" => "AA00"}
156
- assert_equal expected, api.council_for_snac_code("AA00")
157
- end
158
-
159
- it "should return nil if a council name is not found" do
160
- stub_request(:get, "#{PUBLISHER_ENDPOINT}/local_transactions/find_by_council_name?name=bloop").
161
- with(:headers => GdsApi::JsonClient::REQUEST_HEADERS).
162
- to_return(:status => 404, :body => " ", :headers => {})
163
-
164
- assert_equal nil, api.council_for_name("bloop")
165
- end
166
-
167
- it "should return a council hash for a mixed case council name" do
168
- stub_request(:get, "#{PUBLISHER_ENDPOINT}/local_transactions/find_by_council_name?name=Some%20Council").
169
- with(:headers => GdsApi::JsonClient::REQUEST_HEADERS).
170
- to_return(:status => 200, :body => '{"name": "Some Council", "snac": "AA00"}', :headers => {})
171
-
172
- expected = {"name" => "Some Council", "snac" => "AA00"}
173
- assert_equal expected, api.council_for_name("Some Council")
174
- end
175
-
176
- it "should return a council hash for a lowercase council name" do
177
- stub_request(:get, "#{PUBLISHER_ENDPOINT}/local_transactions/find_by_council_name?name=some%20council").
178
- with(:headers => GdsApi::JsonClient::REQUEST_HEADERS).
179
- to_return(:status => 200, :body => '{"name": "Some Council", "snac": "AA00"}', :headers => {})
180
-
181
- expected = {"name" => "Some Council", "snac" => "AA00"}
182
- assert_equal expected, api.council_for_name("some council")
183
- end
184
141
  end
185
142
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: gds-api-adapters
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.52
5
+ version: 0.1.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - James Stewart
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-07-18 00:00:00 Z
13
+ date: 2012-06-29 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: plek
@@ -143,35 +143,35 @@ extensions: []
143
143
  extra_rdoc_files: []
144
144
 
145
145
  files:
146
- - lib/gds_api/version.rb
147
- - lib/gds_api/publisher.rb
148
- - lib/gds_api/panopticon/registerer.rb
146
+ - lib/gds_api/helpers.rb
147
+ - lib/gds_api/base.rb
148
+ - lib/gds_api/part_methods.rb
149
+ - lib/gds_api/exceptions.rb
149
150
  - lib/gds_api/typhoeus_client.rb
150
151
  - lib/gds_api/imminence.rb
152
+ - lib/gds_api/publisher.rb
151
153
  - lib/gds_api/contactotron.rb
152
- - lib/gds_api/test_helpers/publisher.rb
154
+ - lib/gds_api/panopticon.rb
155
+ - lib/gds_api/version.rb
156
+ - lib/gds_api/oauth2_client.rb
153
157
  - lib/gds_api/test_helpers/imminence.rb
158
+ - lib/gds_api/test_helpers/publisher.rb
154
159
  - lib/gds_api/test_helpers/contactotron.rb
155
160
  - lib/gds_api/test_helpers/panopticon.rb
156
161
  - lib/gds_api/test_helpers/json_client_helper.rb
157
- - lib/gds_api/base.rb
158
- - lib/gds_api/json_client.rb
159
162
  - lib/gds_api/response.rb
160
- - lib/gds_api/panopticon.rb
161
- - lib/gds_api/core-ext/openstruct.rb
162
- - lib/gds_api/oauth2_client.rb
163
- - lib/gds_api/part_methods.rb
163
+ - lib/gds_api/panopticon/registerer.rb
164
164
  - lib/gds_api/needotron.rb
165
- - lib/gds_api/exceptions.rb
166
- - lib/gds_api/helpers.rb
165
+ - lib/gds_api/json_client.rb
166
+ - lib/gds_api/core-ext/openstruct.rb
167
167
  - README.md
168
168
  - Rakefile
169
- - test/contactotron_api_test.rb
170
- - test/panopticon_api_test.rb
171
- - test/publisher_api_test.rb
172
- - test/json_client_test.rb
173
169
  - test/gds_api_base_test.rb
170
+ - test/json_client_test.rb
174
171
  - test/test_helper.rb
172
+ - test/publisher_api_test.rb
173
+ - test/panopticon_api_test.rb
174
+ - test/contactotron_api_test.rb
175
175
  homepage: http://github.com/alphagov/gds-api-adapters
176
176
  licenses: []
177
177
 
@@ -185,7 +185,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
185
  requirements:
186
186
  - - ">="
187
187
  - !ruby/object:Gem::Version
188
- hash: 2947988208479081559
188
+ hash: 3070109834685786037
189
189
  segments:
190
190
  - 0
191
191
  version: "0"
@@ -194,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
194
  requirements:
195
195
  - - ">="
196
196
  - !ruby/object:Gem::Version
197
- hash: 2947988208479081559
197
+ hash: 3070109834685786037
198
198
  segments:
199
199
  - 0
200
200
  version: "0"
@@ -206,9 +206,9 @@ signing_key:
206
206
  specification_version: 3
207
207
  summary: Adapters to work with GDS APIs
208
208
  test_files:
209
- - test/contactotron_api_test.rb
210
- - test/panopticon_api_test.rb
211
- - test/publisher_api_test.rb
212
- - test/json_client_test.rb
213
209
  - test/gds_api_base_test.rb
210
+ - test/json_client_test.rb
214
211
  - test/test_helper.rb
212
+ - test/publisher_api_test.rb
213
+ - test/panopticon_api_test.rb
214
+ - test/contactotron_api_test.rb