hydra-remote_identifier 0.0.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c555e2e358d784219f8aeae86457d9a456410470
4
+ data.tar.gz: 1e6e8f346332a2692a6c04001837cb18ca3ef6db
5
+ SHA512:
6
+ metadata.gz: 8ce31c0525b6c307bcebc30f9a227a87d047ad76da1a872c3a5454b900d2081f5aeedd67a0126bed876cba6337d0ec1efee78086f487c5a9377198b7fd68bd54
7
+ data.tar.gz: 8379665c7d8f1a022a3e09bf3f7ef4ed4fa126caebda959325f2585c437e3e4eb68ddb4c149e004f8c7b813997f404ee670ee56fa120d4e1b9b41e4f8bfc0c79
data/Gemfile CHANGED
@@ -6,4 +6,11 @@ gemspec
6
6
  group :test do
7
7
  gem 'guard-rspec'
8
8
  gem 'ruby_gntp'
9
+ gem 'vcr'
10
+ gem 'webmock'
11
+ end
12
+
13
+ group :doc do
14
+ gem 'yard'
15
+ gem 'redcarpet'
9
16
  end
data/README.md CHANGED
@@ -19,11 +19,18 @@ Or install it yourself as:
19
19
 
20
20
  ## Usage
21
21
 
22
- In your `./config/initializers` add a file that registers remote identification
23
- services for a list of models.
24
-
25
- Hydra::RemoteIdentifier.register(:doi, Book) do |map|
26
- map.what {|book| book.title + ": " book.subtitle }
27
- map.who :author_name
28
- map.set_identifier {|book, value| book.set_doi!(value)}
22
+ Configure your remote identifiers with credentials and what have you:
23
+
24
+ doi_credentials = Psych.load('/path/to/doi_credentials.yml')
25
+ Hydra::RemoteIdentifier.configure do |config|
26
+ config.configure_remote_service(:doi, doi_credentials) do |doi|
27
+ doi.register(target_class) do |map|
28
+ map.target :url
29
+ map.creator :creator
30
+ map.title :title
31
+ map.publisher :publisher
32
+ map.publicationyear :publicationyear
33
+ map.set_identifier(:set_identifier=)
34
+ end
35
+ end
29
36
  end
@@ -19,10 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'activesupport', '>= 3.2.13', '< 5.0'
22
+ spec.add_dependency 'rest-client', '~> 1.6.7'
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.3"
24
25
  spec.add_development_dependency "rake"
25
26
  spec.add_development_dependency 'rspec'
26
- spec.add_development_dependency 'yard'
27
- spec.add_development_dependency 'redcarpet'
28
27
  end
@@ -1,50 +1,34 @@
1
1
  require "hydra/remote_identifier/version"
2
+ require 'hydra/remote_identifier/configuration'
2
3
  require 'hydra/remote_identifier/registration'
3
4
  require 'hydra/remote_identifier/remote_service'
4
- require 'hydra/remote_identifier/remote_services'
5
5
 
6
6
  module Hydra::RemoteIdentifier
7
7
 
8
8
  class << self
9
9
 
10
- # For the given :remote_service_name and :target_classes register the Map
11
- # to use for minting a remote identifier for instances of the
12
- # :target_classes
10
+ # Used for configuring available RemoteService and any additional
11
+ # initialization requirements for those RemoteServices (i.e. credentials)
13
12
  #
14
13
  # @example
15
- # Hydra::RemoteIdentifier.register(:doi, Book) do |map|
16
- # map.what {|book| book.title + ": " book.subtitle }
17
- # map.who :author_name
18
- # map.set_identifier {|book, value| book.set_doi!(value)}
14
+ # Hydra::RemoteIdentifier.configure do |config|
15
+ # config.configure_remote_service(:doi, doi_credentials) do |doi|
16
+ # doi.register(target_class) do |map|
17
+ # map.target :url
18
+ # map.creator :creator
19
+ # map.title :title
20
+ # map.publisher :publisher
21
+ # map.publicationyear :publicationyear
22
+ # map.set_identifier(:set_identifier=)
23
+ # end
24
+ # end
19
25
  # end
20
26
  #
21
- # @param remote_service_name [#to_s] the name of a remote service we will
22
- # use to mint the corresponding remote identifier
23
- # @param target_classes [Array<Class>] a collection of classes who's
24
- # instances to which we will assign a remote identifier
25
- # @yieldparam map [Map] defines what attributes are required by the
26
- # :remote_service as well as what the callback for what the
27
- # :remote_resource should do (see Mapper::Wrapper)
28
- def register(remote_service_name, *target_classes, &map)
29
- Array(target_classes).flatten.compact.each do |target_class|
30
- Registration.new(remote_service(remote_service_name), target_class, &map)
31
- end
32
- end
33
-
34
-
35
- # Given a string retrieve an instance of the corresponding RemoteService.
36
- # @param string [#to_s]
37
- # @return [RemoteService]
38
- def remote_service(string)
39
- namespace_for_lookup = RemoteServices
40
- remote_service_class_name = string.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
41
- if namespace_for_lookup.const_defined?(remote_service_class_name)
42
- namespace_for_lookup.const_get(remote_service_class_name).new
43
- else
44
- raise NotImplementedError.new(
45
- "Unable to find #{self} remote_service '#{string}'. Consider creating #{namespace_for_lookup}::#{remote_service_class_name}"
46
- )
47
- end
27
+ # @yieldparam config [Configuration]
28
+ attr_accessor :configuration
29
+ def configure
30
+ self.configuration ||= Configuration.new
31
+ yield(configuration)
48
32
  end
49
33
 
50
34
  end
@@ -0,0 +1,46 @@
1
+ require File.expand_path('../remote_services', __FILE__)
2
+
3
+ module Hydra::RemoteIdentifier
4
+
5
+ # Configuration is responsible for exposing the available RemoteServices
6
+ # and configuring those RemoteServices.
7
+ class Configuration
8
+
9
+ def initialize(options = {})
10
+ @remote_service_namespace_container = options.fetch(:remote_service_namespace_container, Hydra::RemoteIdentifier::RemoteServices)
11
+ @remote_services = {}
12
+ end
13
+ attr_reader :remote_service_namespace_container
14
+ private :remote_service_namespace_container
15
+ attr_reader :remote_services
16
+
17
+ def find_remote_service(service_name)
18
+ remote_services.fetch(service_name, remote_service_class_lookup(service_name).new)
19
+ end
20
+
21
+ def remote_service(service_name, *args, &block)
22
+ remote_service_class_lookup(service_name).configure(*args, &block)
23
+ end
24
+
25
+ def configure_remote_service(service_name, *args, &block)
26
+ remote_service = remote_service_class_lookup(service_name).new(*args)
27
+ remote_services[service_name]
28
+ yield(Registration.new(remote_service))
29
+ remote_service
30
+ end
31
+
32
+ private
33
+
34
+ def remote_service_class_lookup(string)
35
+ remote_service_class_name = string.to_s.gsub(/(?:^|_)([a-z])/) { $1.upcase }
36
+ if remote_service_namespace_container.const_defined?(remote_service_class_name)
37
+ remote_service_namespace_container.const_get(remote_service_class_name)
38
+ else
39
+ raise NotImplementedError.new(
40
+ "Unable to find #{self} remote_service '#{string}'. Consider creating #{remote_service_namespace_container}::#{remote_service_class_name}"
41
+ )
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -2,10 +2,19 @@ require File.expand_path('../exceptions', __FILE__)
2
2
 
3
3
  module Hydra::RemoteIdentifier
4
4
 
5
- # Registry is responsible for associating a model with a set of remote services and defining the attribute map
6
- # The Mapper is responsible for transforming a target, via a Map, into an acceptable format for a Minter
5
+ # The Mapper is responsible for transforming a target, via a Map, into an
6
+ # acceptable format for a Minter
7
7
  class Mapper
8
8
 
9
+ attr_reader :map
10
+ def initialize(service_class, map_builder = Map, &mapping_block)
11
+ @map = map_builder.new(service_class, &mapping_block)
12
+ end
13
+
14
+ def call(target, wrapper_builder = Wrapper)
15
+ wrapper_builder.new(map, target)
16
+ end
17
+
9
18
  # The Wrapper provides the getting and setting behavior for a target based on a Map
10
19
  class Wrapper
11
20
  attr_reader :map, :target
@@ -33,7 +42,7 @@ module Hydra::RemoteIdentifier
33
42
  target.send(setter, value)
34
43
  elsif setter.is_a?(Hash)
35
44
  datastream = setter.fetch(:at)
36
- field = setter.fetch(:in, scheme)
45
+ field = setter.fetch(:in)
37
46
  target.datastreams["#{datastream}"].send("#{field}=", value)
38
47
  end
39
48
  end
@@ -83,15 +92,6 @@ module Hydra::RemoteIdentifier
83
92
  end
84
93
  end
85
94
 
86
- attr_reader :map
87
- def initialize(service_class, map_builder = Map, &mapping_block)
88
- @map = map_builder.new(service_class, &mapping_block)
89
- end
90
-
91
- def call(target, wrapper_builder = Wrapper)
92
- wrapper_builder.new(map, target)
93
- end
94
-
95
95
  end
96
96
 
97
97
  end
@@ -3,16 +3,32 @@ require File.expand_path('../minting_coordinator', __FILE__)
3
3
 
4
4
  module Hydra::RemoteIdentifier
5
5
 
6
- # The Registration is responsible for connecting a RemoteService, a Target
6
+ # The Registration is responsible for connecting a RemoteService and a Target
7
7
  # to a particular Map
8
8
  class Registration
9
- def initialize(service_class, target_class, minting_coordinator = MintingCoordinator, &map)
9
+ attr_reader :remote_service, :minting_coordinator
10
+ def initialize(remote_service, minting_coordinator = MintingCoordinator, &map)
11
+ @remote_service = remote_service
12
+ @minting_coordinator = minting_coordinator
13
+ end
14
+
15
+ def register(*target_classes, &map)
10
16
  if map.nil?
11
- raise RuntimeError, "You attempted to register the remote service #{service_class} for #{target_class} without a map"
17
+ raise RuntimeError, "You attempted to register the remote service #{remote_service} for #{target_classes} without a map"
18
+ end
19
+ Array(target_classes).flatten.compact.each {|target_class|
20
+ register_target(target_class, &map)
21
+ }
22
+ end
23
+
24
+ private
25
+
26
+ def register_target(target_class, &map)
27
+ unless target_class.respond_to?(:registered_remote_identifier_minters)
28
+ target_class.class_attribute :registered_remote_identifier_minters
12
29
  end
13
- target_class.class_attribute :registered_remote_identifier_minters unless target_class.respond_to?(:registered_remote_identifier_minters)
14
30
  target_class.registered_remote_identifier_minters ||= []
15
- target_class.registered_remote_identifier_minters += [minting_coordinator.new(service_class, &map)]
31
+ target_class.registered_remote_identifier_minters += [minting_coordinator.new(remote_service, &map)]
16
32
  end
17
33
  end
18
34
 
@@ -1,5 +1 @@
1
- module Hydra::RemoteIdentifier
2
- module RemoteServices
3
- # For namespace
4
- end
5
- end
1
+ require 'hydra/remote_identifier/remote_services/doi'
@@ -0,0 +1,51 @@
1
+ require 'uri'
2
+ require 'rest_client'
3
+ require 'hydra/remote_identifier/remote_service'
4
+ require 'active_support/core_ext/hash/indifferent_access'
5
+
6
+ module Hydra::RemoteIdentifier
7
+ module RemoteServices
8
+ class Doi < Hydra::RemoteIdentifier::RemoteService
9
+
10
+ attr_reader :uri
11
+ def initialize(configuration = {})
12
+ username = configuration.fetch(:username)
13
+ password = configuration.fetch(:password)
14
+ shoulder = configuration.fetch(:shoulder)
15
+ url = configuration.fetch(:url)
16
+
17
+ # This is specific for the creation of DOIs
18
+ @uri = URI.parse(File.join(url, 'shoulder', shoulder))
19
+ @uri.user = username
20
+ @uri.password = password
21
+ end
22
+
23
+ REQUIRED_ATTRIBUTES = ['target', 'creator', 'title', 'publisher', 'publicationyear' ].freeze
24
+ def valid_attribute?(attribute_name)
25
+ REQUIRED_ATTRIBUTES.include?(attribute_name.to_s)
26
+ end
27
+
28
+ def call(payload)
29
+ request(data_for_create(payload.with_indifferent_access))
30
+ end
31
+
32
+ private
33
+
34
+ def request(data)
35
+ response = RestClient.post(uri.to_s, data, content_type: 'text/plain')
36
+ matched_data = /\Asuccess:(.*)(?<doi>doi:[^\|]*)(.*)\Z/.match(response.body)
37
+ matched_data[:doi].strip
38
+ end
39
+
40
+ def data_for_create(payload)
41
+ [
42
+ "_target: #{payload.fetch(:target)}",
43
+ "datacite.creator: #{payload.fetch(:creator)}",
44
+ "datacite.title: #{payload.fetch(:title)}",
45
+ "datacite.publisher: #{payload.fetch(:publisher)}",
46
+ "datacite.publicationyear: #{payload.fetch(:publicationyear)}"
47
+ ].join("\n")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module RemoteIdentifier
3
- VERSION = "0.0.3"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,47 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://apitest:apitest@n2t.net/ezid/shoulder/doi:10.5072/FK2
6
+ body:
7
+ encoding: UTF-8
8
+ string: |-
9
+ _target: http://google.com
10
+ datacite.creator: Jeremy Friesen
11
+ datacite.title: My Article
12
+ datacite.publisher: Me Myself and I
13
+ datacite.publicationyear: 2013
14
+ headers:
15
+ Accept:
16
+ - '*/*; q=0.5, application/xml'
17
+ Accept-Encoding:
18
+ - gzip, deflate
19
+ Content-Type:
20
+ - text/plain
21
+ Content-Length:
22
+ - '153'
23
+ User-Agent:
24
+ - Ruby
25
+ response:
26
+ status:
27
+ code: 201
28
+ message: CREATED
29
+ headers:
30
+ Date:
31
+ - Thu, 03 Oct 2013 17:50:51 GMT
32
+ Server:
33
+ - Apache/2.2.17 (Unix) DAV/2 mod_wsgi/3.3 Python/2.7 mod_ssl/2.2.17 OpenSSL/0.9.8o
34
+ Vary:
35
+ - Cookie
36
+ Set-Cookie:
37
+ - sessionid=649cfcff023c40d4c8f1420673837ae6; Path=/ezid/
38
+ Content-Length:
39
+ - '53'
40
+ Content-Type:
41
+ - text/plain; charset=UTF-8
42
+ body:
43
+ encoding: UTF-8
44
+ string: 'success: doi:10.5072/FK23J3QV8 | ark:/b5072/fk23j3qv8'
45
+ http_version:
46
+ recorded_at: Thu, 03 Oct 2013 17:50:54 GMT
47
+ recorded_with: VCR 2.6.0
@@ -0,0 +1,47 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://apitest:apitest@n2t.net/ezid/shoulder/doi:10.5072/FK2
6
+ body:
7
+ encoding: UTF-8
8
+ string: |-
9
+ _target: http://google.com
10
+ datacite.creator: my creator
11
+ datacite.title: my title
12
+ datacite.publisher: my publisher
13
+ datacite.publicationyear: 2013
14
+ headers:
15
+ Accept:
16
+ - '*/*; q=0.5, application/xml'
17
+ Accept-Encoding:
18
+ - gzip, deflate
19
+ Content-Type:
20
+ - text/plain
21
+ Content-Length:
22
+ - '144'
23
+ User-Agent:
24
+ - Ruby
25
+ response:
26
+ status:
27
+ code: 201
28
+ message: CREATED
29
+ headers:
30
+ Date:
31
+ - Thu, 03 Oct 2013 19:10:22 GMT
32
+ Server:
33
+ - Apache/2.2.17 (Unix) DAV/2 mod_wsgi/3.3 Python/2.7 mod_ssl/2.2.17 OpenSSL/0.9.8o
34
+ Vary:
35
+ - Cookie
36
+ Set-Cookie:
37
+ - sessionid=995dadb966d7013e9251daf61b6122ba; Path=/ezid/
38
+ Content-Length:
39
+ - '53'
40
+ Content-Type:
41
+ - text/plain; charset=UTF-8
42
+ body:
43
+ encoding: UTF-8
44
+ string: 'success: doi:10.5072/FK2FT8XZZ | ark:/b5072/fk2ft8xzz'
45
+ http_version:
46
+ recorded_at: Thu, 03 Oct 2013 19:10:25 GMT
47
+ recorded_with: VCR 2.6.0
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../../../../../lib/hydra/remote_identifier/configuration', __FILE__)
2
+
3
+ module Hydra::RemoteIdentifier
4
+
5
+ describe Configuration do
6
+ around do |example|
7
+ module RemoteServices
8
+ class MyRemoteService
9
+ class << self
10
+ attr_reader :options
11
+ def configure(*args, &block)
12
+ @options = [args, block]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ example.run
18
+ RemoteServices.send(:remove_const, :MyRemoteService)
19
+ end
20
+
21
+ subject { Configuration.new }
22
+
23
+ context 'with a missing service' do
24
+ specify do
25
+ expect { subject.remote_service(:obviously_missing_service) }.to raise_error(NotImplementedError)
26
+ end
27
+ specify do
28
+ expect {
29
+ subject.find_remote_service(:obviously_missing_service)
30
+ }.to raise_error(NotImplementedError)
31
+ end
32
+ end
33
+
34
+ context 'with an existing service' do
35
+ let(:block) { lambda {} }
36
+ specify do
37
+ expect {
38
+ subject.remote_service(:my_remote_service, :arg, &block)
39
+ }.to change(RemoteServices::MyRemoteService, :options).from(nil).to([[:arg], block])
40
+ end
41
+ specify do
42
+ expect(subject.find_remote_service(:my_remote_service)).to be_an_instance_of(RemoteServices::MyRemoteService)
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -47,5 +47,111 @@ module Hydra::RemoteIdentifier
47
47
  }.to raise_error(InvalidServiceMapping)
48
48
  end
49
49
  end
50
+
51
+ describe Mapper::Wrapper do
52
+ subject { Mapper::Wrapper.new(map, target) }
53
+
54
+ context 'extract_payload' do
55
+ let(:target) { double(foo: :foo_value) }
56
+ describe 'with implicit getter' do
57
+ let(:map) { double(_getters: { bar: :foo } ) }
58
+ its(:extract_payload) { should == {bar: :foo_value} }
59
+ end
60
+
61
+ describe 'with lambda getter' do
62
+ let(:map) { double(_getters: { bar: lambda {|o| o.foo } } ) }
63
+ its(:extract_payload) { should == {bar: :foo_value} }
64
+ end
65
+
66
+ describe 'with implicit datastream getter' do
67
+ let(:target) {
68
+ double(datastreams: {'datastream' => double(foo: :foo_value)})
69
+ }
70
+ let(:map) {
71
+ double(_getters: { foo: { at: 'datastream' } } )
72
+ }
73
+ its(:extract_payload) { should == {foo: :foo_value} }
74
+ end
75
+
76
+ describe 'with explicit datastream getter' do
77
+ let(:target) {
78
+ double(datastreams: {'datastream' => double(blorg: :foo_value)})
79
+ }
80
+ let(:map) {
81
+ double(_getters: { foo: { at: 'datastream', in: :blorg } } )
82
+ }
83
+ its(:extract_payload) { should == {foo: :foo_value} }
84
+ end
85
+
86
+ end
87
+
88
+ context '#extract_payload' do
89
+
90
+ let(:target) { double(foo: :foo_value) }
91
+ describe 'with implicit getter' do
92
+ let(:map) { double(_getters: { bar: :foo } ) }
93
+ its(:extract_payload) { should == {bar: :foo_value} }
94
+ end
95
+
96
+ describe 'with lambda getter' do
97
+ let(:map) { double(_getters: { bar: lambda {|o| o.foo } } ) }
98
+ its(:extract_payload) { should == {bar: :foo_value} }
99
+ end
100
+
101
+ describe 'with implicit datastream getter' do
102
+ let(:target) {
103
+ double(datastreams: {'datastream' => double(foo: :foo_value)})
104
+ }
105
+ let(:map) {
106
+ double(_getters: { foo: { at: 'datastream' } } )
107
+ }
108
+ its(:extract_payload) { should == {foo: :foo_value} }
109
+ end
110
+
111
+ describe 'with explicit datastream getter' do
112
+ let(:target) {
113
+ double(datastreams: {'datastream' => double(blorg: :foo_value)})
114
+ }
115
+ let(:map) {
116
+ double(_getters: { foo: { at: 'datastream', in: :blorg } } )
117
+ }
118
+ its(:extract_payload) { should == {foo: :foo_value} }
119
+ end
120
+
121
+ end
122
+
123
+ context '#set_identifier' do
124
+ let(:target) { double }
125
+ describe 'with implicit setter' do
126
+ let(:map) { double(_setter: :bar) }
127
+ specify {
128
+ target.should_receive(:bar).with(:expected_identifier)
129
+ subject.set_identifier(:expected_identifier)
130
+ }
131
+ end
132
+
133
+ describe 'with lambda setter' do
134
+ let(:map) { double(_setter: lambda {|o, v| o.foo = v } ) }
135
+ specify {
136
+ target.should_receive(:foo=).with(:expected_identifier)
137
+ subject.set_identifier(:expected_identifier)
138
+ }
139
+ end
140
+
141
+ describe 'with explicit datastream getter' do
142
+ let(:target) { double(datastreams: datastreams ) }
143
+ let(:datastreams) { {'properties' => double } }
144
+ let(:map) {
145
+ double(_setter: { at: 'properties', in: :identifier } )
146
+ }
147
+ specify {
148
+ datastreams['properties'].should_receive(:identifier=).with(:expected_identifier)
149
+ subject.set_identifier(:expected_identifier)
150
+ }
151
+ end
152
+
153
+ end
154
+
155
+ end
50
156
  end
51
157
  end
@@ -5,21 +5,18 @@ module Hydra::RemoteIdentifier
5
5
  let(:minting_coordinator) { double(new: :minting_coordinator) }
6
6
  let(:target_class) { Class.new }
7
7
  let(:map) { lambda {|m| m.title :title } }
8
+ subject { Registration.new(:my_remote_service, minting_coordinator) }
8
9
  it 'requires a map' do
9
- expect { Registration.new(:my_remote_service, target_class, minting_coordinator) }.to raise_error(RuntimeError)
10
+ expect { subject.register(target_class) }.to raise_error(RuntimeError)
10
11
  end
11
12
  it 'adds a .registered_remote_identifier_minters method' do
12
13
  expect {
13
- Registration.new(:my_remote_service, target_class, minting_coordinator, &map)
14
+ subject.register(target_class, &map)
14
15
  }.to change{ target_class.respond_to?(:registered_remote_identifier_minters) }.from(false).to(true)
15
16
  end
16
17
  it 'adds a .registered_remote_identifier_minters method' do
17
- Registration.new(:my_remote_service, target_class, minting_coordinator, &map)
18
+ subject.register(target_class, &map)
18
19
  expect(target_class.registered_remote_identifier_minters).to eq [:minting_coordinator]
19
20
  end
20
-
21
- it 'should yield a map' do
22
- Registration.new(:my_remote_service, target_class, minting_coordinator, &map)
23
- end
24
21
  end
25
22
  end
@@ -3,12 +3,13 @@ require File.expand_path('../../../../../lib/hydra/remote_identifier/remote_serv
3
3
  module Hydra::RemoteIdentifier
4
4
 
5
5
  describe RemoteService do
6
- let(:payload) { 'abc' }
7
- subject { RemoteService.new }
8
-
9
- it { expect { subject.call(payload) }.to raise_error NotImplementedError }
10
- it { expect { subject.valid_attribute?(:attribute_name) }.to raise_error NotImplementedError }
11
6
 
7
+ describe 'instance methods' do
8
+ let(:payload) { 'abc' }
9
+ subject { RemoteService.new }
10
+ it { expect { subject.call(payload) }.to raise_error NotImplementedError }
11
+ it { expect { subject.valid_attribute?(:attribute_name) }.to raise_error NotImplementedError }
12
+ end
12
13
  end
13
14
 
14
15
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'hydra/remote_identifier/remote_services/doi'
3
+
4
+ module Hydra::RemoteIdentifier
5
+ module RemoteServices
6
+
7
+ describe Doi do
8
+ let(:configuration) {
9
+ {
10
+ username: 'apitest',
11
+ password: 'apitest',
12
+ shoulder: 'doi:10.5072/FK2',
13
+ url: "https://n2t.net/ezid/"
14
+ }
15
+ }
16
+ let(:payload) {
17
+ {
18
+ target: 'http://google.com',
19
+ creator: 'Jeremy Friesen',
20
+ title: 'My Article',
21
+ publisher: 'Me Myself and I',
22
+ publicationyear: "2013"
23
+ }
24
+ }
25
+ let(:expected_doi) {
26
+ # From the doi-create cassette
27
+ 'doi:10.5072/FK23J3QV8'
28
+ }
29
+ subject { RemoteServices::Doi.new(configuration) }
30
+
31
+ context '.call' do
32
+ it 'should post to remote service', VCR::SpecSupport.merge(cassette_name: 'doi-create') do
33
+ expect(subject.call(payload)).to eq(expected_doi)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,61 +1,60 @@
1
1
  require File.expand_path('../../../../lib/hydra/remote_identifier', __FILE__)
2
2
  module Hydra::RemoteIdentifier
3
3
 
4
- describe 'with custom remote service' do
5
- around do |example|
6
- module RemoteServices
7
- class MyRemoteService < ::Hydra::RemoteIdentifier::RemoteService
8
- def valid_attribute?(*)
9
- true
10
- end
11
- def call(payload)
12
- :remote_service_response
13
- end
14
- end
15
- end
16
- example.run
17
- RemoteServices.send(:remove_const, :MyRemoteService)
18
- end
4
+ describe '.configure' do
5
+
6
+ let(:target_class) {
7
+ Class.new {
8
+ def url; 'http://google.com'; end
9
+ def creator; 'my creator'; end
10
+ def title; 'my title'; end
11
+ def publisher; 'my publisher'; end
12
+ def publicationyear; '2013'; end
13
+ attr_accessor :set_identifier
14
+ }
15
+ }
19
16
 
20
- describe '.register' do
17
+ let(:target) { target_class.new }
21
18
 
22
- let(:target_class) {
23
- Class.new {
24
- attr_reader :identifier
25
- def title; 'a special title'; end
26
- def update_identifier(value); @identifier = value; end
27
- }
28
- }
29
- let(:target) { target_class.new }
19
+ let(:expected_doi) {
20
+ # From the doi-create cassette
21
+ 'doi:10.5072/FK2FT8XZZ'
22
+ }
30
23
 
31
- it 'should update the registered identifier based on the registered attributes' do
32
- Hydra::RemoteIdentifier.register(:my_remote_service, target_class) do |config|
33
- config.title :title
34
- config.set_identifier :update_identifier
24
+ let(:doi_options) {
25
+ {
26
+ username: 'apitest',
27
+ password: 'apitest',
28
+ shoulder: 'doi:10.5072/FK2',
29
+ url: "https://n2t.net/ezid/"
30
+ }
31
+ }
32
+
33
+ describe '.register API' do
34
+
35
+ before(:each) do
36
+ Hydra::RemoteIdentifier.configure do |config|
37
+ config.configure_remote_service(:doi, doi_options) do |doi|
38
+ doi.register(target_class) do |map|
39
+ map.target :url
40
+ map.creator :creator
41
+ map.title :title
42
+ map.publisher :publisher
43
+ map.publicationyear :publicationyear
44
+ map.set_identifier(:set_identifier=)
45
+ end
46
+ end
35
47
  end
48
+ end
36
49
 
50
+ it 'works!', VCR::SpecSupport.merge(record: :new_episodes, cassette_name: 'doi-integration') do
37
51
  expect {
38
52
  target_class.registered_remote_identifier_minters.each do |minter|
39
53
  minter.call(target)
40
54
  end
41
- }.to change(target, :identifier).from(nil).to(:remote_service_response)
42
-
55
+ }.to change(target, :set_identifier).from(nil).to(expected_doi)
43
56
  end
44
- end
45
57
 
46
- describe '.remote_service' do
47
- context 'with valid remote service' do
48
- subject { Hydra::RemoteIdentifier.remote_service(:my_remote_service) }
49
- it 'should return an instance of that service' do
50
- expect(subject).to be_instance_of RemoteServices::MyRemoteService
51
- end
52
- end
53
- context 'with invalid remote service' do
54
- subject { Hydra::RemoteIdentifier.remote_service(:undefined_service) }
55
- it 'should raise a NotImplementedError' do
56
- expect { subject }.to raise_error NotImplementedError
57
- end
58
- end
59
58
  end
60
59
 
61
60
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,21 @@
1
1
  GEM_ROOT = File.expand_path("../../", __FILE__)
2
2
  $:.unshift File.join(GEM_ROOT, "lib")
3
3
 
4
+ require 'vcr'
5
+
6
+ module VCR::SpecSupport
7
+ module_function
8
+ def merge(options = {})
9
+ {vcr: {record: :new_episodes}.merge(options)}
10
+ end
11
+ end
12
+
13
+ VCR.configure do |config|
14
+ config.cassette_library_dir = 'spec/fixtures/cassettes'
15
+ config.hook_into :webmock
16
+ config.configure_rspec_metadata!
17
+ end
18
+
4
19
  # This file was generated by the `rspec --init` command. Conventionally, all
5
20
  # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
21
  # Require this file using `require "spec_helper"` to ensure that it is only
metadata CHANGED
@@ -1,22 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-remote_identifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jeremy Friesen
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-02 00:00:00.000000000 Z
11
+ date: 2013-10-03 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.2.13
22
20
  - - <
@@ -25,92 +23,67 @@ dependencies:
25
23
  type: :runtime
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
- - - ! '>='
27
+ - - '>='
31
28
  - !ruby/object:Gem::Version
32
29
  version: 3.2.13
33
30
  - - <
34
31
  - !ruby/object:Gem::Version
35
32
  version: '5.0'
36
33
  - !ruby/object:Gem::Dependency
37
- name: bundler
34
+ name: rest-client
38
35
  requirement: !ruby/object:Gem::Requirement
39
- none: false
40
36
  requirements:
41
37
  - - ~>
42
38
  - !ruby/object:Gem::Version
43
- version: '1.3'
44
- type: :development
39
+ version: 1.6.7
40
+ type: :runtime
45
41
  prerelease: false
46
42
  version_requirements: !ruby/object:Gem::Requirement
47
- none: false
48
43
  requirements:
49
44
  - - ~>
50
45
  - !ruby/object:Gem::Version
51
- version: '1.3'
46
+ version: 1.6.7
52
47
  - !ruby/object:Gem::Dependency
53
- name: rake
54
- requirement: !ruby/object:Gem::Requirement
55
- none: false
56
- requirements:
57
- - - ! '>='
58
- - !ruby/object:Gem::Version
59
- version: '0'
60
- type: :development
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- none: false
64
- requirements:
65
- - - ! '>='
66
- - !ruby/object:Gem::Version
67
- version: '0'
68
- - !ruby/object:Gem::Dependency
69
- name: rspec
48
+ name: bundler
70
49
  requirement: !ruby/object:Gem::Requirement
71
- none: false
72
50
  requirements:
73
- - - ! '>='
51
+ - - ~>
74
52
  - !ruby/object:Gem::Version
75
- version: '0'
53
+ version: '1.3'
76
54
  type: :development
77
55
  prerelease: false
78
56
  version_requirements: !ruby/object:Gem::Requirement
79
- none: false
80
57
  requirements:
81
- - - ! '>='
58
+ - - ~>
82
59
  - !ruby/object:Gem::Version
83
- version: '0'
60
+ version: '1.3'
84
61
  - !ruby/object:Gem::Dependency
85
- name: yard
62
+ name: rake
86
63
  requirement: !ruby/object:Gem::Requirement
87
- none: false
88
64
  requirements:
89
- - - ! '>='
65
+ - - '>='
90
66
  - !ruby/object:Gem::Version
91
67
  version: '0'
92
68
  type: :development
93
69
  prerelease: false
94
70
  version_requirements: !ruby/object:Gem::Requirement
95
- none: false
96
71
  requirements:
97
- - - ! '>='
72
+ - - '>='
98
73
  - !ruby/object:Gem::Version
99
74
  version: '0'
100
75
  - !ruby/object:Gem::Dependency
101
- name: redcarpet
76
+ name: rspec
102
77
  requirement: !ruby/object:Gem::Requirement
103
- none: false
104
78
  requirements:
105
- - - ! '>='
79
+ - - '>='
106
80
  - !ruby/object:Gem::Version
107
81
  version: '0'
108
82
  type: :development
109
83
  prerelease: false
110
84
  version_requirements: !ruby/object:Gem::Requirement
111
- none: false
112
85
  requirements:
113
- - - ! '>='
86
+ - - '>='
114
87
  - !ruby/object:Gem::Version
115
88
  version: '0'
116
89
  description: Handles the registration and minting of remote identifiers (i.e. DOI,
@@ -131,6 +104,7 @@ files:
131
104
  - Rakefile
132
105
  - hydra-remote_identifier.gemspec
133
106
  - lib/hydra/remote_identifier.rb
107
+ - lib/hydra/remote_identifier/configuration.rb
134
108
  - lib/hydra/remote_identifier/exceptions.rb
135
109
  - lib/hydra/remote_identifier/mapper.rb
136
110
  - lib/hydra/remote_identifier/minter.rb
@@ -138,52 +112,54 @@ files:
138
112
  - lib/hydra/remote_identifier/registration.rb
139
113
  - lib/hydra/remote_identifier/remote_service.rb
140
114
  - lib/hydra/remote_identifier/remote_services.rb
115
+ - lib/hydra/remote_identifier/remote_services/doi.rb
141
116
  - lib/hydra/remote_identifier/version.rb
117
+ - spec/fixtures/cassettes/doi-create.yml
118
+ - spec/fixtures/cassettes/doi-integration.yml
119
+ - spec/lib/hydra/remote_identifier/configuration_spec.rb
142
120
  - spec/lib/hydra/remote_identifier/mapper_spec.rb
143
121
  - spec/lib/hydra/remote_identifier/minter_spec.rb
144
122
  - spec/lib/hydra/remote_identifier/minting_coordinator_spec.rb
145
123
  - spec/lib/hydra/remote_identifier/registration_spec.rb
146
124
  - spec/lib/hydra/remote_identifier/remote_service_spec.rb
125
+ - spec/lib/hydra/remote_identifier/remote_services/doi_spec.rb
147
126
  - spec/lib/hydra/remote_identifier_spec.rb
148
127
  - spec/spec_helper.rb
149
128
  homepage: https://github.com/jeremyf/hydra-remote_identifier
150
129
  licenses:
151
130
  - APACHE2
131
+ metadata: {}
152
132
  post_install_message:
153
133
  rdoc_options: []
154
134
  require_paths:
155
135
  - lib
156
136
  required_ruby_version: !ruby/object:Gem::Requirement
157
- none: false
158
137
  requirements:
159
- - - ! '>='
138
+ - - '>='
160
139
  - !ruby/object:Gem::Version
161
140
  version: '0'
162
- segments:
163
- - 0
164
- hash: 1218886598798334275
165
141
  required_rubygems_version: !ruby/object:Gem::Requirement
166
- none: false
167
142
  requirements:
168
- - - ! '>='
143
+ - - '>='
169
144
  - !ruby/object:Gem::Version
170
145
  version: '0'
171
- segments:
172
- - 0
173
- hash: 1218886598798334275
174
146
  requirements: []
175
147
  rubyforge_project:
176
- rubygems_version: 1.8.25
148
+ rubygems_version: 2.0.3
177
149
  signing_key:
178
- specification_version: 3
150
+ specification_version: 4
179
151
  summary: Handles the registration and minting of remote identifiers (i.e. DOI, ARK,
180
152
  ORCID)
181
153
  test_files:
154
+ - spec/fixtures/cassettes/doi-create.yml
155
+ - spec/fixtures/cassettes/doi-integration.yml
156
+ - spec/lib/hydra/remote_identifier/configuration_spec.rb
182
157
  - spec/lib/hydra/remote_identifier/mapper_spec.rb
183
158
  - spec/lib/hydra/remote_identifier/minter_spec.rb
184
159
  - spec/lib/hydra/remote_identifier/minting_coordinator_spec.rb
185
160
  - spec/lib/hydra/remote_identifier/registration_spec.rb
186
161
  - spec/lib/hydra/remote_identifier/remote_service_spec.rb
162
+ - spec/lib/hydra/remote_identifier/remote_services/doi_spec.rb
187
163
  - spec/lib/hydra/remote_identifier_spec.rb
188
164
  - spec/spec_helper.rb
189
165
  has_rdoc: