hydra-remote_identifier 0.0.3 → 0.2.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.
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: