gds-api-adapters 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gds_api/base.rb CHANGED
@@ -1,28 +1,36 @@
1
1
  require_relative 'json_utils'
2
+ require 'cgi'
2
3
 
3
4
  class GdsApi::Base
4
5
  include GdsApi::JsonUtils
5
6
 
6
- def initialize(platform, endpoint_url = nil)
7
+ def initialize(platform, endpoint_url=nil)
7
8
  adapter_name = self.class.to_s.split("::").last.downcase
8
9
 
9
- # This should get simpler if we can be more consistent with our domain names
10
- if endpoint_url
11
- self.endpoint = endpoint_url
12
- elsif platform == 'development'
13
- self.endpoint = "http://#{adapter_name}.dev.gov.uk"
10
+ self.endpoint = endpoint_url || endpoint_for_platform(adapter_name, platform)
11
+ end
12
+
13
+ def url_for_slug(slug, options={})
14
+ base = "#{base_url}/#{slug}.json#{query_string(options)}"
15
+ end
16
+
17
+ private
18
+ attr_accessor :endpoint
19
+
20
+ # This should get simpler if we can be more consistent with our domain names
21
+ def endpoint_for_platform(adapter_name, platform)
22
+ if platform == 'development'
23
+ "http://#{adapter_name}.dev.gov.uk"
14
24
  else
15
- self.endpoint = "http://#{adapter_name}.#{platform}.alphagov.co.uk"
25
+ "http://#{adapter_name}.#{platform}.alphagov.co.uk"
16
26
  end
17
27
  end
18
-
19
- def url_for_slug(slug,options={})
20
- base = "#{base_url}/#{slug}.json"
21
- params = options.map { |k,v| "#{k}=#{v}" }
22
- base = base + "?#{params.join("&")}" unless options.empty?
23
- base
28
+
29
+ def query_string(params)
30
+ return "" if params.empty?
31
+
32
+ "?" << params.sort.map { |kv|
33
+ kv.map { |a| CGI.escape(a.to_s) }.join("=")
34
+ }.join("&")
24
35
  end
25
-
26
- private
27
- attr_accessor :endpoint
28
- end
36
+ end
@@ -4,6 +4,7 @@ require_relative 'base'
4
4
  # the full URI for a contact and just want to grab its json serialization
5
5
  # and convert it to an ostruct.
6
6
  class GdsApi::Contactotron < GdsApi::Base
7
+
7
8
  def initialize
8
9
  end
9
10
 
@@ -1,4 +1,5 @@
1
1
  class OpenStruct
2
+
2
3
  def to_json
3
4
  table.to_json
4
5
  end
@@ -1,18 +1,21 @@
1
1
  require_relative 'base'
2
2
 
3
3
  class GdsApi::Imminence < GdsApi::Base
4
- def api_url(type,lat,lon,limit=5)
4
+
5
+ def api_url(type, lat, lon, limit=5)
5
6
  "#{@endpoint}/places/#{type}.json?limit=#{limit}&lat=#{lat}&lng=#{lon}"
6
7
  end
7
8
 
8
- def places(type,lat,lon,limit=5)
9
- places = get_json(api_url(type,lat,lon,limit)) || []
10
- places.map do |o|
11
- o['latitude'] = o['location'][0]
9
+ def places(type, lat, lon, limit=5)
10
+ places = get_json(api_url(type, lat, lon, limit)) || []
11
+ places.map { |o|
12
+ o['latitude'] = o['location'][0]
12
13
  o['longitude'] = o['location'][1]
13
- o['address'] = [o['address1'], o['address2']].reject { |a| a.nil? or a == '' }.map { |a| a.strip }.join(', ')
14
+ o['address'] = [
15
+ o['address1'],
16
+ o['address2']
17
+ ].reject { |a| a.nil? or a == '' }.map(&:strip).join(', ')
14
18
  o
15
- end
19
+ }
16
20
  end
17
-
18
21
  end
@@ -6,7 +6,7 @@ require_relative 'version'
6
6
 
7
7
  module GdsApi::JsonUtils
8
8
  USER_AGENT = "GDS Api Client v. #{GdsApi::VERSION}"
9
-
9
+
10
10
  def get_json(url)
11
11
  url = URI.parse(url)
12
12
  request = url.path
@@ -21,8 +21,8 @@ module GdsApi::JsonUtils
21
21
  return JSON.parse(response.body)
22
22
  end
23
23
  end
24
-
25
- def post_json(url,params)
24
+
25
+ def post_json(url, params)
26
26
  url = URI.parse(url)
27
27
  Net::HTTP.start(url.host, url.port) do |http|
28
28
  post_response = http.post(url.path, params.to_json, {'Content-Type' => 'application/json', 'User-Agent' => USER_AGENT})
@@ -43,4 +43,4 @@ module GdsApi::JsonUtils
43
43
  object
44
44
  end
45
45
  end
46
- end
46
+ end
@@ -2,14 +2,19 @@ require_relative 'base'
2
2
 
3
3
  class GdsApi::Panopticon < GdsApi::Base
4
4
 
5
- def artefact_for_slug(slug)
5
+ def artefact_for_slug(slug, opts = {})
6
6
  return nil if slug.nil? or slug == ''
7
7
 
8
- to_ostruct get_json(url_for_slug(slug))
8
+ details = get_json(url_for_slug(slug))
9
+ if opts[:as_hash]
10
+ details
11
+ else
12
+ to_ostruct(details)
13
+ end
9
14
  end
10
15
 
11
- private
12
- def base_url
13
- "#{endpoint}/artefacts"
14
- end
16
+ private
17
+ def base_url
18
+ "#{endpoint}/artefacts"
19
+ end
15
20
  end
@@ -1,4 +1,5 @@
1
1
  module GdsApi::PartMethods
2
+
2
3
  def part_index(slug)
3
4
  parts.index { |p| p.slug == slug }
4
5
  end
@@ -8,37 +9,33 @@ module GdsApi::PartMethods
8
9
  parts[index]
9
10
  end
10
11
 
11
- def part_after(part)
12
- return nil unless index = part_index(part.slug)
13
- next_index = index + 1
14
- return nil if next_index >= parts.length
15
- parts[next_index]
16
- end
17
-
18
12
  def has_parts?(part)
19
- prev_part = has_previous_part?(part)
20
- next_part = has_next_part?(part)
21
- if prev_part || next_part
22
- true
23
- else
24
- false
25
- end
13
+ !! (has_previous_part?(part) || has_next_part?(part))
26
14
  end
27
15
 
28
16
  def has_previous_part?(part)
29
17
  index = part_index(part.slug)
30
- !index.nil? && index > 0 && true
18
+ !! (index && index > 0)
31
19
  end
32
20
 
33
21
  def has_next_part?(part)
34
22
  index = part_index(part.slug)
35
- !index.nil? && (index + 1) < parts.length && true
23
+ !! (index && (index + 1) < parts.length)
24
+ end
25
+
26
+ def part_after(part)
27
+ part_at(part, 1)
36
28
  end
37
29
 
38
30
  def part_before(part)
39
- return nil unless index = part_index(part.slug)
40
- previous_index = index - 1
41
- return nil if previous_index < 0
42
- parts[previous_index]
31
+ part_at(part, -1)
32
+ end
33
+
34
+ private
35
+ def part_at(part, relative_offset)
36
+ return nil unless current_index = part_index(part.slug)
37
+ other_index = current_index + relative_offset
38
+ return nil unless (0 ... parts.length).include?(other_index)
39
+ parts[other_index]
43
40
  end
44
41
  end
@@ -2,40 +2,41 @@ require_relative 'base'
2
2
  require_relative 'part_methods'
3
3
 
4
4
  class GdsApi::Publisher < GdsApi::Base
5
+
5
6
  def publications
6
- get_json(base_url)
7
+ get_json(base_url)
7
8
  end
8
9
 
9
10
  def publication_for_slug(slug,options = {})
10
11
  return nil if slug.nil? or slug == ''
11
-
12
+
12
13
  publication_hash = get_json(url_for_slug(slug, options))
13
- if publication_hash
14
+ if publication_hash
14
15
  container = to_ostruct(publication_hash)
15
16
  container.extend(GdsApi::PartMethods) if container.parts
16
17
  convert_updated_date(container)
17
18
  container
18
19
  else
19
- return nil
20
+ nil
20
21
  end
21
22
  end
22
-
23
+
23
24
  def council_for_transaction(transaction,snac_codes)
24
25
  if json = post_json("#{@endpoint}/local_transactions/#{transaction.slug}/verify_snac.json",{'snac_codes' => snac_codes})
25
- return json['snac']
26
+ json['snac']
26
27
  else
27
- return nil
28
+ nil
28
29
  end
29
30
  end
30
-
31
- private
32
- def convert_updated_date(container)
33
- if container.updated_at && container.updated_at.class == String
34
- container.updated_at = Time.parse(container.updated_at)
35
- end
36
- end
37
-
38
- def base_url
39
- "#{@endpoint}/publications"
31
+
32
+ private
33
+ def convert_updated_date(container)
34
+ if container.updated_at && container.updated_at.class == String
35
+ container.updated_at = Time.parse(container.updated_at)
40
36
  end
37
+ end
38
+
39
+ def base_url
40
+ "#{@endpoint}/publications"
41
+ end
41
42
  end
@@ -1,3 +1,3 @@
1
1
  module GdsApi
2
- VERSION = '0.0.3'
2
+ VERSION = '0.0.4'
3
3
  end
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+ require 'gds_api/base'
3
+ require 'uri'
4
+
5
+ class GdsApiBaseTest < MiniTest::Unit::TestCase
6
+
7
+ class ConcreteApi < GdsApi::Base
8
+ def base_url
9
+ endpoint
10
+ end
11
+ end
12
+
13
+ def setup
14
+ @api = ConcreteApi.new('test')
15
+ end
16
+
17
+ def test_should_construct_escaped_query_string
18
+ api = ConcreteApi.new('test')
19
+ url = api.url_for_slug("slug", "a" => " ", "b" => "/")
20
+ u = URI.parse(url)
21
+ assert_equal "a=+&b=%2F", u.query
22
+ end
23
+
24
+ def test_should_not_add_a_question_mark_if_there_are_no_parameters
25
+ api = ConcreteApi.new('test')
26
+ url = api.url_for_slug("slug")
27
+ refute_match /\?/, url
28
+ end
29
+
30
+ def test_should_use_platform_in_url
31
+ api = ConcreteApi.new("test")
32
+ url = api.url_for_slug("slug")
33
+ u = URI.parse(url)
34
+ assert_match /test\.alphagov\.co\.uk$/, u.host
35
+ end
36
+
37
+ def test_should_override_platform_with_endpoint_url
38
+ api = ConcreteApi.new("test", "http://foo.bar")
39
+ url = api.url_for_slug("slug")
40
+ u = URI.parse(url)
41
+ assert_equal "foo.bar", u.host
42
+ end
43
+
44
+ def test_should_use_dev_for_development_platform
45
+ api = ConcreteApi.new("development")
46
+ url = api.url_for_slug("slug")
47
+ u = URI.parse(url)
48
+ assert_match /dev\.gov\.uk$/, u.host
49
+ end
50
+
51
+ def test_should_derive_adapter_name_from_class
52
+ api = ConcreteApi.new("test")
53
+ url = api.url_for_slug("slug")
54
+ u = URI.parse(url)
55
+ assert_match /^concreteapi\.test/, u.host
56
+ end
57
+
58
+ end
@@ -17,6 +17,15 @@ class PanopticonApiTest < MiniTest::Unit::TestCase
17
17
  assert_equal 'An artefact', artefact.name
18
18
  end
19
19
 
20
+ def test_given_a_slug_can_fetch_artefact_as_hash
21
+ slug = 'an-artefact'
22
+ artefact_json = { name: 'An artefact' }.to_json
23
+ stub_request(:get, "#{EXPECTED_ENDPOINT}/artefacts/#{slug}.json").to_return(body: artefact_json)
24
+
25
+ artefact = api.artefact_for_slug(slug, :as_hash => true)
26
+ assert artefact.is_a?(Hash)
27
+ end
28
+
20
29
  def should_fetch_and_parse_JSON_into_hash
21
30
  url = "#{EXPECTED_ENDPOINT}/some.json"
22
31
  stub_request(:get, url).to_return(body: {}.to_json)
@@ -3,11 +3,11 @@ require 'gds_api/publisher'
3
3
 
4
4
  class GdsApi::PublisherTest < MiniTest::Unit::TestCase
5
5
  EXPECTED_ENDPOINT = "http://publisher.test.alphagov.co.uk"
6
-
6
+
7
7
  def api
8
8
  GdsApi::Publisher.new("test")
9
9
  end
10
-
10
+
11
11
  def test_given_a_slug__should_go_get_resource_from_publisher_app
12
12
  slug = "a-publication"
13
13
  publication = %@{"audiences":[""],
@@ -18,8 +18,8 @@ class GdsApi::PublisherTest < MiniTest::Unit::TestCase
18
18
  "body":"Something",
19
19
  "title":"A publication"}@
20
20
  stub_request(:get, "#{EXPECTED_ENDPOINT}/publications/#{slug}.json").to_return(
21
- :body => publication,:status=>200)
22
-
21
+ :body => publication,:status=>200)
22
+
23
23
  pub = api.publication_for_slug(slug)
24
24
 
25
25
  assert_equal "Something",pub.body
@@ -35,22 +35,22 @@ class GdsApi::PublisherTest < MiniTest::Unit::TestCase
35
35
  "body":"Something",
36
36
  "title":"A publication"}@
37
37
  stub_request(:get, "#{EXPECTED_ENDPOINT}/publications/#{slug}.json?edition=678").to_return(
38
- :body => publication,:status=>200)
39
-
38
+ :body => publication,:status=>200)
39
+
40
40
  pub = api.publication_for_slug(slug,{:edition => 678})
41
41
  end
42
42
 
43
43
  def test_should_fetch_and_parse_json_into_hash
44
44
  url = "#{EXPECTED_ENDPOINT}/some.json"
45
45
  stub_request(:get, url).to_return(
46
- :body => "{}",:status=>200)
46
+ :body => "{}",:status=>200)
47
47
  assert_equal Hash,api.get_json(url).class
48
48
  end
49
49
 
50
50
  def test_should_return_nil_if_404_returned_from_endpoint
51
51
  url = "#{EXPECTED_ENDPOINT}/some.json"
52
52
  stub_request(:get, url).to_return(
53
- :body => "{}",:status=>404)
53
+ :body => "{}",:status=>404)
54
54
  assert_nil api.get_json(url)
55
55
  end
56
56
 
@@ -92,8 +92,8 @@ class GdsApi::PublisherTest < MiniTest::Unit::TestCase
92
92
  slug = "a-publication"
93
93
  publication = publication_with_parts(slug)
94
94
  stub_request(:get, "#{EXPECTED_ENDPOINT}/publications/#{slug}.json").to_return(
95
- :body => publication,:status=>200)
96
-
95
+ :body => publication,:status=>200)
96
+
97
97
  pub = api.publication_for_slug(slug)
98
98
  assert_equal 3, pub.parts.size
99
99
  assert_equal "introduction", pub.parts.first.slug
@@ -103,8 +103,8 @@ class GdsApi::PublisherTest < MiniTest::Unit::TestCase
103
103
  slug = "a-publication"
104
104
  publication = publication_with_parts(slug)
105
105
  stub_request(:get, "#{EXPECTED_ENDPOINT}/publications/#{slug}.json").to_return(
106
- :body => publication,:status=>200)
107
-
106
+ :body => publication,:status=>200)
107
+
108
108
  pub = api.publication_for_slug(slug)
109
109
  assert_equal pub.part_index("introduction"),0
110
110
  end
@@ -113,8 +113,8 @@ class GdsApi::PublisherTest < MiniTest::Unit::TestCase
113
113
  slug = "a-publication"
114
114
  publication = publication_with_parts(slug)
115
115
  stub_request(:get, "#{EXPECTED_ENDPOINT}/publications/#{slug}.json").to_return(
116
- :body => publication,:status=>200)
117
-
116
+ :body => publication,:status=>200)
117
+
118
118
  pub = api.publication_for_slug(slug)
119
119
  assert_equal Time, pub.updated_at.class
120
120
  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.3
4
+ version: 0.0.4
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-06 00:00:00.000000000Z
12
+ date: 2011-12-07 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: plek
16
- requirement: &70126514816420 !ruby/object:Gem::Requirement
16
+ requirement: &70227649209100 !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: *70126514816420
24
+ version_requirements: *70227649209100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70126514812480 !ruby/object:Gem::Requirement
27
+ requirement: &70227649208160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70126514812480
35
+ version_requirements: *70227649208160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: webmock
38
- requirement: &70126514790760 !ruby/object:Gem::Requirement
38
+ requirement: &70227649207100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.7'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70126514790760
46
+ version_requirements: *70227649207100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &70126514787500 !ruby/object:Gem::Requirement
49
+ requirement: &70227649206060 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70126514787500
57
+ version_requirements: *70227649206060
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: simplecov
60
- requirement: &70126514775900 !ruby/object:Gem::Requirement
60
+ requirement: &70227649205440 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - =
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: 0.4.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70126514775900
68
+ version_requirements: *70227649205440
69
69
  description: A set of adapters providing easy access to the GDS gov.uk APIs
70
70
  email:
71
71
  - jystewart@gmail.com
@@ -85,6 +85,7 @@ files:
85
85
  - README.md
86
86
  - Rakefile
87
87
  - test/contactotron_api_test.rb
88
+ - test/gds_api_base_test.rb
88
89
  - test/panopticon_api_test.rb
89
90
  - test/publisher_api_test.rb
90
91
  - test/test_helper.rb
@@ -114,6 +115,7 @@ specification_version: 3
114
115
  summary: Adapters to work with GDS APIs
115
116
  test_files:
116
117
  - test/contactotron_api_test.rb
118
+ - test/gds_api_base_test.rb
117
119
  - test/panopticon_api_test.rb
118
120
  - test/publisher_api_test.rb
119
121
  - test/test_helper.rb