europeana 0.1.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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in europeana.gemspec
4
+ gemspec
data/LICENSE.pdf ADDED
Binary file
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Europeana
2
+
3
+ Ruby client library for the search and retrieval of records from the [Europeana
4
+ REST API](http://labs.europeana.eu/api/introduction/).
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'europeana'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install europeana
19
+
20
+ ## Usage
21
+
22
+ ### Authentication
23
+
24
+ Authentication is *required* for all requests to the Europeana API.
25
+
26
+ Only Basic Authentication (by API key) is supported.
27
+
28
+ Sign up for an API key at: http://labs.europeana.eu/api/registration/
29
+
30
+ Configure your application with the API key:
31
+
32
+ Europeana.api_key = "xyz"
33
+
34
+ ### Search
35
+
36
+ search = Europeana.search(:query => '"first world war"') # => { "success" => true, "items2 => [ ... ], "totalResults" => 1234, ... }
37
+ search["items"] # => [ item1, item2, ... ]
38
+ search["totalResults"] # => 1234
39
+
40
+ See http://labs.europeana.eu/api/search/ for details of the data returned in
41
+ the search response.
42
+
43
+ ### Record
44
+
45
+ record = Europeana.record("abc/1234") # => { "success" => true, "object" => { ... }, ... }
46
+ record["object"] # => { "title" => "...", "proxies" => [ ... ], "aggregations" => [ ... ]
47
+
48
+ See http://labs.europeana.eu/api/record/ for details of the data returned in
49
+ the record response.
50
+
51
+ ## Contributing
52
+
53
+ 1. Fork it
54
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
55
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
56
+ 4. Push to the branch (`git push origin my-new-feature`)
57
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/europeana.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'europeana/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "europeana"
8
+ spec.version = Europeana::VERSION
9
+ spec.authors = ["Richard Doe"]
10
+ spec.email = ["richard.doe@rwdit.net"]
11
+ spec.description = %q{Search and retrieve records from the Europeana REST API}
12
+ spec.summary = %q{Ruby client library for the Europeana API}
13
+ spec.homepage = "https://github.com/europeana/europeana-client-ruby"
14
+ spec.license = "EUPL 1.1"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "activesupport", "~> 3.0"
22
+ spec.add_dependency "multi_json", "~> 1.0"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "webmock", "~> 1.18.0"
28
+ end
@@ -0,0 +1,52 @@
1
+ module Europeana
2
+ module Errors
3
+ ##
4
+ # Raised if API requests are attempted without the API key having been set.
5
+ #
6
+ class MissingAPIKeyError < StandardError
7
+ def initialize(msg = nil)
8
+ msg ||= <<-MSG
9
+ Missing API key.
10
+
11
+ The Europeana API key has not been set.
12
+
13
+ Sign up for an API key at: http://labs.europeana.eu/api/registration/
14
+
15
+ Set the key with:
16
+
17
+ Europeana.api_key = "xyz"
18
+ MSG
19
+ super(msg)
20
+ end
21
+ end
22
+
23
+ ##
24
+ # Raised if the API response success flag is false, indicating a problem
25
+ # with the request.
26
+ #
27
+ class RequestError < StandardError
28
+ def initialize(msg = nil)
29
+ msg ||= <<-MSG
30
+ Request error.
31
+
32
+ There was a problem with your request to the Europeana API.
33
+ MSG
34
+ super(msg)
35
+ end
36
+ end
37
+
38
+ ##
39
+ # Raised if the API response is not valid JSON.
40
+ #
41
+ class ResponseError < StandardError
42
+ def initialize(msg = nil)
43
+ msg ||= <<-MSG
44
+ Response error.
45
+
46
+ Unable to parse the response from the Europeana API.
47
+ MSG
48
+ super(msg)
49
+ end
50
+ end
51
+ end # Europeana::Errors
52
+ end # Europeana
@@ -0,0 +1,105 @@
1
+ require "uri"
2
+
3
+ module Europeana
4
+ ##
5
+ # Interface to the Europeana API Record method
6
+ #
7
+ # @see http://labs.europeana.eu/api/record/
8
+ #
9
+ class Record
10
+ # Europeana ID of the record
11
+ attr_accessor :id
12
+
13
+ # Request parameters to send to the API
14
+ attr_accessor :params
15
+
16
+ ##
17
+ # @param [String] id Europeana ID of the record
18
+ # @param [Hash] params Request parameters
19
+ #
20
+ def initialize(id, params = {})
21
+ self.id = id
22
+ self.params = params
23
+ end
24
+
25
+ ##
26
+ # Returns query params with API key added
27
+ #
28
+ # @return [Hash]
29
+ #
30
+ def params_with_authentication
31
+ raise Europeana::Errors::MissingAPIKeyError unless Europeana.api_key.present?
32
+ params.merge(:wskey => Europeana.api_key)
33
+ end
34
+
35
+ ##
36
+ # Sets record ID attribute after validating format.
37
+ #
38
+ # @param [String] id Record ID
39
+ #
40
+ def id=(id)
41
+ raise ArgumentError, "Invalid Europeana record ID." unless id.is_a?(String) && id.match(/\A\/[^\/]+\/[^\/]+\B/)
42
+ @id = id
43
+ end
44
+
45
+ ##
46
+ # Sets request parameters after validating keys
47
+ #
48
+ # Valid parameter keys:
49
+ # * :callback
50
+ #
51
+ # For explanations of these request parameters, see: http://labs.europeana.eu/api/record/
52
+ #
53
+ # @param (see #initialize)
54
+ # @return [Hash] Request parameters
55
+ #
56
+ def params=(params = {})
57
+ params.assert_valid_keys(:callback)
58
+ @params = params
59
+ end
60
+
61
+ ##
62
+ # Gets the URI for this Record request with parameters
63
+ #
64
+ # @return [URI]
65
+ #
66
+ def request_uri
67
+ uri = URI.parse(Europeana::URL + "/record" + "#{@id}.json")
68
+ uri.query = params_with_authentication.to_query
69
+ uri
70
+ end
71
+
72
+ ##
73
+ # Sends a request for this record to the API
74
+ #
75
+ # @return [Hash] Record data
76
+ #
77
+ def get
78
+ uri = request_uri
79
+ http = Net::HTTP.new(uri.host, uri.port)
80
+ request = Net::HTTP::Get.new(uri.request_uri)
81
+ retries = Europeana.max_retries
82
+
83
+ begin
84
+ response = http.request(request)
85
+ rescue Timeout::Error, Errno::ECONNREFUSED, EOFError
86
+ retries -= 1
87
+ raise unless retries > 0
88
+ sleep Europeana.retry_delay
89
+ retry
90
+ end
91
+
92
+ json = JSON.parse(response.body)
93
+ raise Errors::RequestError, json['error'] unless json['success']
94
+ json
95
+ rescue JSON::ParserError
96
+ if response.code.to_i == 404
97
+ # Handle HTML 404 responses on malformed record ID, emulating API's
98
+ # JSON response.
99
+ raise Errors::RequestError, "Invalid record identifier: #{@id}"
100
+ else
101
+ raise Errors::ResponseError
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,101 @@
1
+ module Europeana
2
+ ##
3
+ # Interface to Europeana API's Search method
4
+ #
5
+ class Search
6
+ # Query params
7
+ attr_accessor :params
8
+
9
+ ##
10
+ # @param [Hash] params Europeana API request parameters for Search query
11
+ # @see #params=
12
+ #
13
+ def initialize(params = {})
14
+ self.params = params
15
+ end
16
+
17
+ ##
18
+ # Sends the Search request to the API
19
+ #
20
+ def execute
21
+ uri = request_uri
22
+ http = Net::HTTP.new(uri.host, uri.port)
23
+ request = Net::HTTP::Get.new(uri.request_uri)
24
+ retries = Europeana.max_retries
25
+
26
+ begin
27
+ response = http.request(request)
28
+ rescue Timeout::Error, Errno::ECONNREFUSED, EOFError
29
+ retries -= 1
30
+ raise unless retries > 0
31
+ sleep Europeana.retry_delay
32
+ retry
33
+ end
34
+
35
+ json = JSON.parse(response.body)
36
+ raise Errors::RequestError, json['error'] unless json['success']
37
+ json
38
+ rescue JSON::ParserError
39
+ raise Errors::ResponseError
40
+ end
41
+
42
+ ##
43
+ # Returns query params with API key added
44
+ #
45
+ # @return [Hash]
46
+ #
47
+ def params_with_authentication
48
+ raise Europeana::Errors::MissingAPIKeyError unless Europeana.api_key.present?
49
+ params.merge(:wskey => Europeana.api_key).reverse_merge(:query => "")
50
+ end
51
+
52
+ ##
53
+ # Sets request parameters after validating keys
54
+ #
55
+ # Valid parameter keys:
56
+ # * :query
57
+ # * :profile
58
+ # * :qf
59
+ # * :rows
60
+ # * :start
61
+ # * :callback
62
+ #
63
+ # For explanations of these request parameters, see: http://labs.europeana.eu/api/search/
64
+ #
65
+ # Multiple `qf` parameters can be passed as a {Hash}:
66
+ #
67
+ # Europeana::Search.new(:qf => { :what => "Photograph", :where => [ "Paris", "London" ] })
68
+ #
69
+ # @param (see #initialize)
70
+ # @return [Hash] Passed params, if valid
71
+ #
72
+ def params=(params = {})
73
+ params.assert_valid_keys(:query, :profile, :qf, :rows, :start, :callback)
74
+ @params = params
75
+ end
76
+
77
+ ##
78
+ # Gets the URI for this Search request with parameters
79
+ #
80
+ # @return [URI]
81
+ #
82
+ def request_uri
83
+ uri = URI.parse(Europeana::URL + "/search.json")
84
+ request_params = params_with_authentication
85
+
86
+ if request_params[:qf].is_a?(Hash)
87
+ qf = request_params.delete(:qf)
88
+ uri.query = request_params.to_query
89
+ qf.each_pair do |name, criteria|
90
+ [ criteria ].flatten.each do |criterion|
91
+ uri.query = uri.query + "&qf=" + CGI::escape(name.to_s) + ":" + CGI::escape(criterion)
92
+ end
93
+ end
94
+ else
95
+ uri.query = request_params.to_query
96
+ end
97
+
98
+ uri
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ module Europeana
2
+ VERSION = "0.1.0"
3
+ end
data/lib/europeana.rb ADDED
@@ -0,0 +1,77 @@
1
+ require "europeana/version"
2
+ require "net/http"
3
+ require "uri"
4
+ require "active_support/core_ext/object"
5
+
6
+ module Europeana
7
+ URL = 'http://www.europeana.eu/api/v2'
8
+
9
+ autoload :Errors, 'europeana/errors'
10
+ autoload :Record, 'europeana/record'
11
+ autoload :Search, 'europeana/search'
12
+
13
+ class << self
14
+ # The Europeana API key, required for authentication
15
+ attr_accessor :api_key
16
+
17
+ ##
18
+ # The maximum number of retries permitted
19
+ #
20
+ # Retries occur when a network request to the API fails. The default is 5
21
+ # retries before giving up.
22
+ #
23
+ # @return [Integer]
24
+ #
25
+ attr_accessor :max_retries
26
+
27
+ ##
28
+ # The number of seconds to wait between retries
29
+ #
30
+ # The default is 10 seconds.
31
+ #
32
+ # @return [Integer]
33
+ #
34
+ attr_accessor :retry_delay
35
+
36
+ ##
37
+ # Sets configuration values to their defaults
38
+ #
39
+ def defaults!
40
+ self.max_retries = 5
41
+ self.retry_delay = 10
42
+ end
43
+
44
+ ##
45
+ # Sends a Search request to the Europeana API
46
+ #
47
+ # Equivalent to:
48
+ # search = Europeana::Search.new(params)
49
+ # search.execute
50
+ #
51
+ # @param [Hash] params Query parameters
52
+ # @return [Hash] search response
53
+ # @see Europeana::Search#execute
54
+ #
55
+ def search(params = {})
56
+ Search.new(params).execute
57
+ end
58
+
59
+ ##
60
+ # Sends a Record request to the Europeana API
61
+ #
62
+ # Equivalent to:
63
+ # search = Europeana::Record.new(record_id, params)
64
+ # record.get
65
+ #
66
+ # @param [String] Record ID
67
+ # @param [Hash] params Query parameters
68
+ # @return [Hash] search response
69
+ # @see Europeana::Record#get
70
+ #
71
+ def record(record_id, params = {})
72
+ Record.new(record_id, params).get
73
+ end
74
+ end
75
+
76
+ self.defaults!
77
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ module Europeana
4
+ describe "Errors" do
5
+ describe "MissingAPIKeyError" do
6
+ subject { Europeana::Errors::MissingAPIKeyError.new }
7
+
8
+ it "has an informative message" do
9
+ expect(subject.message).to match("Missing API key.")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ module Europeana
4
+ describe Record do
5
+ before(:each) do
6
+ @api_key = "xyz"
7
+ Europeana.api_key = @api_key
8
+ @record_id = "/abc/1234"
9
+ @params = { :callback => "doSomething();" }
10
+ end
11
+
12
+ describe "#new" do
13
+ context "without record ID" do
14
+ it "raises error" do
15
+ expect { subject }.to raise_error(ArgumentError)
16
+ end
17
+ end
18
+
19
+ context "with record ID" do
20
+ context "without params" do
21
+ subject { Europeana::Record.new(@record_id) }
22
+
23
+ it "should not raise error" do
24
+ expect { subject }.to_not raise_error
25
+ end
26
+
27
+ it "sets id attribute" do
28
+ expect(subject.instance_variable_get(:@id)).to eq(@record_id)
29
+ end
30
+ end
31
+
32
+ context "with params" do
33
+ subject { Europeana::Record.new(@record_id, @params) }
34
+
35
+ it "should not raise error" do
36
+ expect { subject }.to_not raise_error
37
+ end
38
+
39
+ it "sets params attribute" do
40
+ expect(subject.instance_variable_get(:@params)).to eq(@params)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#id" do
47
+ subject { Europeana::Record.new(@record_id) }
48
+ it "gets id attribute" do
49
+ expect(subject.id).to eq(subject.instance_variable_get(:@id))
50
+ end
51
+ end
52
+
53
+ describe "#id=" do
54
+ subject { Europeana::Record.new(@record_id) }
55
+
56
+ context "with valid ID" do
57
+ it "sets id attribute" do
58
+ subject.id = "/xyz/5678"
59
+ expect(subject.instance_variable_get(:@id)).to eq("/xyz/5678")
60
+ end
61
+ end
62
+
63
+ context "invalid ID" do
64
+ it "raises error" do
65
+ expect { subject.id = "invalid" }.to raise_error("Invalid Europeana record ID.")
66
+
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ describe "#params" do
73
+ subject { Europeana::Record.new(@record_id, @params) }
74
+ it "gets params attribute" do
75
+ expect(subject.params).to eq(subject.instance_variable_get(:@params))
76
+ end
77
+ end
78
+
79
+ describe "#params=" do
80
+ subject { Europeana::Record.new(@record_id, {}) }
81
+
82
+ context "valid params" do
83
+ it "sets params attribute" do
84
+ subject.params = @params
85
+ expect(subject.instance_variable_get(:@params)).to eq(@params)
86
+ end
87
+ end
88
+
89
+ it "validates param names" do
90
+ expect { subject.params = { :invalid => "parameter" } }.to raise_error("Unknown key: invalid")
91
+ end
92
+ end
93
+
94
+ describe "#params_with_authentication" do
95
+ subject { Europeana::Record.new(@record_id, @params) }
96
+
97
+ context "with API key" do
98
+ it "adds API key to params" do
99
+ expect(subject.params_with_authentication).to eq(@params.merge(:wskey => @api_key))
100
+ end
101
+ end
102
+
103
+ context "without API key" do
104
+ it "raises an error" do
105
+ Europeana.api_key = nil
106
+ expect { subject.params_with_authentication }.to raise_error(Europeana::Errors::MissingAPIKeyError)
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "#request_uri" do
112
+ subject { Europeana::Record.new(@record_id, @params) }
113
+
114
+ it "returns a URI" do
115
+ expect(subject.request_uri).to be_a(URI)
116
+ end
117
+
118
+ it "includes the record ID" do
119
+ expect(subject.request_uri.to_s).to include(@record_id)
120
+ end
121
+
122
+ it "includes the query params" do
123
+ expect(subject.request_uri.to_s).to include(@params.to_query)
124
+ end
125
+ end
126
+
127
+ describe "#get" do
128
+ subject { Europeana::Record.new(@record_id, @params).get }
129
+ it_behaves_like "record request"
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ module Europeana
4
+ describe Search do
5
+ before(:all) do
6
+ @params = { :query => "test", :profile => "standard", :qf => "where:London", :rows => 100, :start => 1, :callback => "" }
7
+ @api_key = "xyz"
8
+ end
9
+
10
+ before(:each) do
11
+ Europeana.api_key = @api_key
12
+ end
13
+
14
+ describe "#new" do
15
+ context "with no API request params" do
16
+ subject { lambda { Europeana::Search.new } }
17
+ it { should_not raise_error }
18
+ end
19
+
20
+ context "with API request params" do
21
+ subject { Europeana::Search.new(@params) }
22
+ it "should not raise error" do
23
+ expect { subject }.not_to raise_error
24
+ end
25
+ it "stores the request params" do
26
+ expect(subject.instance_variable_get(:@params)).to eq(@params)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#params" do
32
+ subject { Europeana::Search.new(@params) }
33
+ it "gets params attribute" do
34
+ expect(subject.params).to eq(@params)
35
+ end
36
+ end
37
+
38
+ describe "#params=" do
39
+ subject { Europeana::Search.new }
40
+
41
+ context "valid params" do
42
+ it "sets params attribute" do
43
+ subject.params = @params
44
+ expect(subject.instance_variable_get(:@params)).to eq(@params)
45
+ end
46
+ end
47
+
48
+ it "validates param names" do
49
+ expect { subject.params = { :invalid => "parameter" } }.to raise_error("Unknown key: invalid")
50
+ end
51
+ end
52
+
53
+ describe "#request_uri" do
54
+ it "returns a URI" do
55
+ expect(subject.request_uri).to be_a(URI)
56
+ end
57
+
58
+ it "includes request params" do
59
+ expect(subject.request_uri.to_s).to eq("http://www.europeana.eu/api/v2/search.json?query=&wskey=#{@api_key}")
60
+ end
61
+
62
+ it "handles Hash of qf params" do
63
+ subject.params[:qf] = { :where => [ "London", "Paris" ], :what => "Photograph" }
64
+ expect(subject.request_uri.to_s).to eq("http://www.europeana.eu/api/v2/search.json?query=&wskey=#{@api_key}&qf=where:London&qf=where:Paris&qf=what:Photograph")
65
+ end
66
+ end
67
+
68
+ describe "#params_with_authentication" do
69
+ subject { Europeana::Search.new }
70
+
71
+ context "with API key" do
72
+ it "adds API key to params" do
73
+ subject.params = @params
74
+ expect(subject.params_with_authentication).to eq(@params.merge(:wskey => @api_key))
75
+ end
76
+ end
77
+
78
+ context "without API key" do
79
+ it "raises an error" do
80
+ subject.params = @params
81
+ Europeana.api_key = nil
82
+ expect { subject.params_with_authentication }.to raise_error(Europeana::Errors::MissingAPIKeyError)
83
+ end
84
+ end
85
+ end
86
+
87
+ describe "#execute" do
88
+ subject { Europeana::Search.new(@params).execute }
89
+ it_behaves_like "search request"
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe Europeana do
4
+ before(:each) do
5
+ Europeana.defaults!
6
+ end
7
+
8
+ describe "::URL" do
9
+ it "returns 'http://www.europeana.eu/api/v2'" do
10
+ expect(Europeana::URL).to eq("http://www.europeana.eu/api/v2")
11
+ end
12
+ end
13
+
14
+ describe ".api_key=" do
15
+ before(:all) do
16
+ @api_key = "xyz"
17
+ end
18
+ it "sets the API key" do
19
+ Europeana.api_key = @api_key
20
+ expect(Europeana.instance_variable_get(:@api_key)).to eq(@api_key)
21
+ end
22
+ end
23
+
24
+ describe ".api_key" do
25
+ before(:all) do
26
+ @api_key = "xyz"
27
+ end
28
+ it "gets the API key" do
29
+ Europeana.instance_variable_set(:@api_key, @api_key)
30
+ expect(Europeana.api_key).to eq(@api_key)
31
+ end
32
+ end
33
+
34
+ describe ".max_retries" do
35
+ it "defaults to 5" do
36
+ expect(Europeana.max_retries).to eq(5)
37
+ end
38
+ end
39
+
40
+ describe ".max_retries=" do
41
+ it "sets the maximum number of retries" do
42
+ Europeana.max_retries = 2
43
+ expect(Europeana.max_retries).to eq(2)
44
+ end
45
+ end
46
+
47
+ describe ".retry_delay" do
48
+ it "defaults to 10" do
49
+ expect(Europeana.retry_delay).to eq(10)
50
+ end
51
+ end
52
+
53
+ describe ".retry_delay=" do
54
+ it "sets the retry delay" do
55
+ Europeana.retry_delay = 3
56
+ expect(Europeana.retry_delay).to eq(3)
57
+ end
58
+ end
59
+
60
+ describe ".defaults!" do
61
+ it "sets retry delay to its default" do
62
+ Europeana.retry_delay = 3
63
+ expect { Europeana.defaults! }.to change { Europeana.retry_delay }.from(3).to(10)
64
+ end
65
+
66
+ it "sets max retries to its default" do
67
+ Europeana.max_retries = 3
68
+ expect { Europeana.defaults! }.to change { Europeana.max_retries }.from(3).to(5)
69
+ end
70
+ end
71
+
72
+ describe ".search" do
73
+ subject { Europeana.search(@params) }
74
+ it_behaves_like "search request"
75
+ end
76
+
77
+ describe ".search" do
78
+ subject { Europeana.record(@record_id, @params) }
79
+ it_behaves_like "record request"
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ require 'europeana'
2
+ require 'webmock/rspec'
3
+
4
+ Dir["./spec/support/**/*.rb"].each { |f| require f }
5
+
6
+ RSpec.configure do |config|
7
+ config.expect_with :rspec do |c|
8
+ c.syntax = :expect
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ shared_examples "API request" do
2
+ context "without API key" do
3
+ before(:each) do
4
+ Europeana.api_key = nil
5
+ end
6
+
7
+ it "sends no HTTP request" do
8
+ begin
9
+ subject
10
+ rescue Europeana::Errors::MissingAPIKeyError
11
+ end
12
+ expect(a_request(:get, /www.europeana.eu\/api\/v2/)).not_to have_been_made
13
+ end
14
+ end
15
+
16
+ context "with API key" do
17
+ before(:all) do
18
+ Europeana.api_key = "xyz"
19
+ end
20
+
21
+ it "returns the response as a Hash" do
22
+ response = subject
23
+ expect(response).to be_a(Hash)
24
+ end
25
+
26
+ context "when the API is unavailable" do
27
+ before(:each) do
28
+ Europeana.retry_delay = 0
29
+ end
30
+
31
+ it "waits then retries" do
32
+ stub_request(:get, /www.europeana.eu\/api\/v2/).
33
+ to_timeout.times(1).then.
34
+ to_return(:body => '{"success":true}')
35
+ subject
36
+ expect(a_request(:get, /www.europeana.eu\/api\/v2/)).to have_been_made.times(2)
37
+ end
38
+ end
39
+
40
+ context "when API response is unsuccessful" do
41
+ it "raises a RequestError" do
42
+ stub_request(:get, /www.europeana.eu\/api\/v2/).to_return(:body => '{"success":false,"error":"Something went wrong"}')
43
+ expect { subject }.to raise_error(Europeana::Errors::RequestError, "Something went wrong")
44
+ end
45
+ end
46
+
47
+ context "when API response is invalid JSON" do
48
+ it "raises a ResponseError" do
49
+ stub_request(:get, /www.europeana.eu\/api\/v2/).to_return(:body => 'invalid JSON')
50
+ expect { subject }.to raise_error(Europeana::Errors::ResponseError)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+
@@ -0,0 +1,32 @@
1
+ shared_examples "record request" do
2
+ before(:all) do
3
+ @api_key = "xyz"
4
+ @record_id = "/abc/1234"
5
+ @params = { :callback => "doSomething();" }
6
+ end
7
+
8
+ before(:each) do
9
+ stub_request(:get, /www.europeana.eu\/api\/v2\/record#{@record_id}\.json/).to_return(:body => '{"success":true}')
10
+ end
11
+
12
+ it_behaves_like "API request"
13
+
14
+ context "with API key" do
15
+ before(:all) do
16
+ Europeana.api_key = @api_key
17
+ end
18
+
19
+ it "sends a Record request to the API" do
20
+ subject
21
+ expect(a_request(:get, /www.europeana.eu\/api\/v2\/record#{@record_id}\.json/)).to have_been_made.once
22
+ end
23
+
24
+ context "when record ID is invalid" do
25
+ it "raises RequestError from HTML 404 response" do
26
+ stub_request(:get, /www.europeana.eu\/api\/v2\/record#{@record_id}\.json/).
27
+ to_return(:body => '<html></html>', :headers => { 'Content-Type' => 'text/html' }, :status => 404)
28
+ expect { subject }.to raise_error(Europeana::Errors::RequestError, "Invalid record identifier: #{@record_id}")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ shared_examples "search request" do
2
+ before(:all) do
3
+ @api_key = "xyz"
4
+ @params = {}
5
+ end
6
+
7
+ before(:each) do
8
+ stub_request(:get, /www.europeana.eu\/api\/v2\/search\.json/).to_return(:body => '{"success":true}')
9
+ end
10
+
11
+ it_behaves_like "API request"
12
+
13
+ context "with API key" do
14
+ before(:all) do
15
+ Europeana.api_key = @api_key
16
+ end
17
+
18
+ it "sends a Search request to the API" do
19
+ subject
20
+ expect(a_request(:get, /www.europeana.eu\/api\/v2\/search\.json/)).to have_been_made.once
21
+ end
22
+
23
+ context "without query" do
24
+ it "sets an empty query" do
25
+ subject
26
+ expect(a_request(:get, /www.europeana.eu\/api\/v2\/search\.json\?query=/)).to have_been_made.once
27
+ end
28
+ end
29
+
30
+ context "with query" do
31
+ before(:all) do
32
+ @params = { :query => "test" }
33
+ end
34
+ it "sends query" do
35
+ subject
36
+ expect(a_request(:get, /www.europeana.eu\/api\/v2\/search\.json\?query=test/)).to have_been_made.once
37
+ end
38
+ end
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: europeana
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Richard Doe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-06-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '3.0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '3.0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: webmock
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.18.0
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.18.0
110
+ description: Search and retrieve records from the Europeana REST API
111
+ email:
112
+ - richard.doe@rwdit.net
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - Gemfile
119
+ - LICENSE.pdf
120
+ - README.md
121
+ - Rakefile
122
+ - europeana.gemspec
123
+ - lib/europeana.rb
124
+ - lib/europeana/errors.rb
125
+ - lib/europeana/record.rb
126
+ - lib/europeana/search.rb
127
+ - lib/europeana/version.rb
128
+ - spec/europeana/errors_spec.rb
129
+ - spec/europeana/record_spec.rb
130
+ - spec/europeana/search_spec.rb
131
+ - spec/europeana_spec.rb
132
+ - spec/spec_helper.rb
133
+ - spec/support/shared_examples/api_request.rb
134
+ - spec/support/shared_examples/record_request.rb
135
+ - spec/support/shared_examples/search_request.rb
136
+ homepage: https://github.com/europeana/europeana-client-ruby
137
+ licenses:
138
+ - EUPL 1.1
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ none: false
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ requirements: []
156
+ rubyforge_project:
157
+ rubygems_version: 1.8.25
158
+ signing_key:
159
+ specification_version: 3
160
+ summary: Ruby client library for the Europeana API
161
+ test_files:
162
+ - spec/europeana/errors_spec.rb
163
+ - spec/europeana/record_spec.rb
164
+ - spec/europeana/search_spec.rb
165
+ - spec/europeana_spec.rb
166
+ - spec/spec_helper.rb
167
+ - spec/support/shared_examples/api_request.rb
168
+ - spec/support/shared_examples/record_request.rb
169
+ - spec/support/shared_examples/search_request.rb