oai 0.4.0 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +36 -10
- data/Rakefile +19 -52
- data/lib/oai/client.rb +3 -3
- data/lib/oai/provider.rb +47 -9
- data/lib/oai/provider/model.rb +17 -17
- data/lib/oai/provider/model/activerecord_caching_wrapper.rb +9 -10
- data/lib/oai/provider/model/activerecord_wrapper.rb +16 -9
- data/lib/oai/provider/response.rb +1 -1
- data/lib/oai/provider/response/record_response.rb +2 -1
- data/test/activerecord_provider/config/connection.rb +18 -1
- data/test/activerecord_provider/database/0001_oaipmh_tables.rb +1 -1
- data/test/activerecord_provider/helpers/providers.rb +16 -0
- data/test/activerecord_provider/models/exclusive_set_dc_field.rb +1 -1
- data/test/activerecord_provider/tc_ar_provider.rb +30 -6
- data/test/activerecord_provider/tc_ar_sets_provider.rb +1 -1
- data/test/activerecord_provider/tc_caching_paging_provider.rb +1 -1
- data/test/activerecord_provider/tc_simple_paging_provider.rb +1 -1
- data/test/activerecord_provider/{test_helper.rb → test_helper_ar_provider.rb} +0 -7
- data/test/client/helpers/provider.rb +8 -8
- data/test/client/tc_exception.rb +4 -4
- data/test/client/tc_get_record.rb +5 -6
- data/test/client/tc_http_client.rb +1 -1
- data/test/client/tc_identify.rb +1 -1
- data/test/client/tc_libxml.rb +4 -4
- data/test/client/tc_list_identifiers.rb +1 -1
- data/test/client/tc_list_metadata_formats.rb +3 -3
- data/test/client/tc_list_records.rb +1 -1
- data/test/client/tc_list_sets.rb +1 -1
- data/test/client/tc_low_resolution_dates.rb +5 -5
- data/test/client/tc_utf8_escaping.rb +2 -2
- data/test/client/tc_xpath.rb +2 -2
- data/test/client/test_helper_client.rb +5 -0
- data/test/provider/tc_exceptions.rb +8 -6
- data/test/provider/tc_functional_tokens.rb +2 -2
- data/test/provider/tc_provider.rb +1 -1
- data/test/provider/tc_resumption_tokens.rb +2 -2
- data/test/provider/tc_simple_provider.rb +8 -8
- data/test/provider/{test_helper.rb → test_helper_provider.rb} +0 -7
- metadata +42 -10
- data/test/client/test_helper.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a21ec21fadefca115987b42ef91f851406c9893ca6f0efc4bd2a1dfa71282514
|
4
|
+
data.tar.gz: c3ef94d3b809c4cba4d3ea0a02cfc9cc2db370eadc86f06ea3d259b0e4f8571b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6eba80e5c7c3b2b1ea7512b316796217fbeb45ebf11ec33b22d61790587b84f8a4c78db669eec9bbc38980c6b8a33dd59de3b3f4d5861010aea0c3f737c3c02
|
7
|
+
data.tar.gz: bb188698b9e5e5eddb1df8c87db491e312396547e3a8179ee1d4720c96aa4567391e602b93c4f2c33aa28c33134dda585035884e1c0a5f333b34b02f8071ed35
|
data/README.md
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
ruby-oai
|
2
2
|
========
|
3
3
|
|
4
|
+
[![Build Status](https://travis-ci.org/code4lib/ruby-oai.svg?branch=master)](https://travis-ci.org/code4lib/ruby-oai)
|
5
|
+
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/kithe.svg)](https://badge.fury.io/rb/oai)
|
7
|
+
|
4
8
|
ruby-oai is a Open Archives Protocol for Metadata Harvesting (OAI-PMH)
|
5
|
-
library for Ruby. [OAI-PMH](http://openarchives.org) is a somewhat
|
6
|
-
archaic protocol for sharing metadata between digital library repositories.
|
9
|
+
library for Ruby. [OAI-PMH](http://openarchives.org) is a somewhat
|
10
|
+
archaic protocol for sharing metadata between digital library repositories.
|
7
11
|
If you are looking to share metadata on the web you are probably better off
|
8
|
-
using a feed format like [RSS](http://www.rssboard.org/rss-specification) or
|
9
|
-
[Atom](http://www.atomenabled.org/). If have to work with a backwards
|
10
|
-
digital repository that only offers OAI-PMH access then ruby-oai is your
|
12
|
+
using a feed format like [RSS](http://www.rssboard.org/rss-specification) or
|
13
|
+
[Atom](http://www.atomenabled.org/). If have to work with a backwards
|
14
|
+
digital repository that only offers OAI-PMH access then ruby-oai is your
|
11
15
|
friend.
|
12
16
|
|
13
|
-
The [OAI-PMH](http://openarchives.org) spec defines six verbs
|
14
|
-
(`Identify`, `ListIdentifiers`, `ListRecords`,
|
17
|
+
The [OAI-PMH](http://openarchives.org) spec defines six verbs
|
18
|
+
(`Identify`, `ListIdentifiers`, `ListRecords`,
|
15
19
|
`GetRecords`, `ListSets`, `ListMetadataFormat`) used for discovery and sharing of
|
16
20
|
metadata.
|
17
21
|
|
@@ -21,7 +25,7 @@ a interactive harvesting shell.
|
|
21
25
|
Client
|
22
26
|
------
|
23
27
|
|
24
|
-
The OAI client library is used for harvesting metadata from repositories.
|
28
|
+
The OAI client library is used for harvesting metadata from repositories.
|
25
29
|
For example to initiate a ListRecords request to pubmed you can:
|
26
30
|
|
27
31
|
```ruby
|
@@ -29,7 +33,7 @@ For example to initiate a ListRecords request to pubmed you can:
|
|
29
33
|
client = OAI::Client.new 'http://www.pubmedcentral.gov/oai/oai.cgi', :headers => { "From" => "oai@example.com" }
|
30
34
|
response = client.list_records
|
31
35
|
# Get the first page of records
|
32
|
-
response.each do |record|
|
36
|
+
response.each do |record|
|
33
37
|
puts record.metadata
|
34
38
|
end
|
35
39
|
# Get the second page of records
|
@@ -60,7 +64,7 @@ The OAI provider library handles serving local content to other clients. Here's
|
|
60
64
|
end
|
61
65
|
```
|
62
66
|
|
63
|
-
See
|
67
|
+
See comment docs at top of [OAI::Provider](./lib/oai/provider.rb) for more details, including discussion of the `OAI::Provider::ActiveRecordWrapper` class for quich setup of an OAI provider for an ActiveRecord model class (single database table)
|
64
68
|
|
65
69
|
Interactive Harvester
|
66
70
|
---------------------
|
@@ -81,6 +85,28 @@ Alternately it can be installed globally using RubyGems:
|
|
81
85
|
|
82
86
|
$ gem install oai
|
83
87
|
|
88
|
+
Running tests
|
89
|
+
-------------
|
90
|
+
|
91
|
+
Tests are with Test::Unit, in a somewhat archaic/legacy style. Test setup especially is not how we would do things today. Run all tests with:
|
92
|
+
|
93
|
+
$ bundle exec rake test
|
94
|
+
|
95
|
+
There are also convenience tasks to run subsets of tests.
|
96
|
+
|
97
|
+
We use [appraisal](https://github.com/thoughtbot/appraisal) to test ActiveRecord-related functionality under multiple versions of ActiveRecord. While the above commands will test with latest ActiveRecord (allowed in our .gemspec development dependency), you can test under a particular version defined in the [Appraisals](./Appraisals) file like so:
|
98
|
+
|
99
|
+
$ bundle exec appraisal rails-52 rake test
|
100
|
+
$ bundle exec appraisal rails-60 rake test
|
101
|
+
|
102
|
+
If you run into trouble with appraisal's gemfiles getting out of date and bundler complaining,
|
103
|
+
try:
|
104
|
+
|
105
|
+
$ bundle exec appraisal clean
|
106
|
+
$ appraisal generate
|
107
|
+
|
108
|
+
That may make changes to appraisal gemfiles that you should commit to repo.
|
109
|
+
|
84
110
|
License
|
85
111
|
-------
|
86
112
|
|
data/Rakefile
CHANGED
@@ -14,73 +14,40 @@ require 'yard'
|
|
14
14
|
|
15
15
|
task :default => ["test", "yard"]
|
16
16
|
|
17
|
-
|
17
|
+
Rake::TestTask.new('test') do |t|
|
18
|
+
t.description = "Run all Test::Unit tests"
|
18
19
|
|
20
|
+
t.libs << ['lib', 'test/client', 'test/provider', 'test/activerecord_provider']
|
21
|
+
|
22
|
+
t.pattern = 'test/{client,provider,activerecord_provider}/tc_*.rb'
|
23
|
+
#t.verbose = true
|
24
|
+
t.warning = false
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
# To run just subsets of tests
|
19
29
|
namespace :test do
|
20
30
|
Rake::TestTask.new('client') do |t|
|
21
31
|
t.libs << ['lib', 'test/client']
|
22
32
|
t.pattern = 'test/client/tc_*.rb'
|
23
|
-
t.verbose = true
|
33
|
+
#t.verbose = true
|
34
|
+
t.warning = false
|
24
35
|
end
|
25
36
|
|
26
37
|
Rake::TestTask.new('provider') do |t|
|
27
38
|
t.libs << ['lib', 'test/provider']
|
28
39
|
t.pattern = 'test/provider/tc_*.rb'
|
29
|
-
t.verbose = true
|
40
|
+
#t.verbose = true
|
41
|
+
t.warning = false
|
30
42
|
end
|
31
43
|
|
32
|
-
desc "Active Record base Provider Tests"
|
33
44
|
Rake::TestTask.new('activerecord_provider') do |t|
|
45
|
+
t.description = "Active Record base Provider Tests"
|
46
|
+
|
34
47
|
t.libs << ['lib', 'test/activerecord_provider']
|
35
48
|
t.pattern = 'test/activerecord_provider/tc_*.rb'
|
36
|
-
t.verbose = true
|
37
|
-
|
38
|
-
|
39
|
-
desc 'Measures test coverage'
|
40
|
-
# borrowed from here: http://clarkware.com/cgi/blosxom/2007/01/05#RcovRakeTask
|
41
|
-
task :coverage do
|
42
|
-
rm_f "coverage"
|
43
|
-
rm_f "coverage.data"
|
44
|
-
if RUBY_VERSION =~ /^1.8/
|
45
|
-
Rake::Task['rcov:client'].invoke
|
46
|
-
Rake::Task['rcov:provider'].invoke
|
47
|
-
Rake::Task['rcov:activerecord_provider'].invoke
|
48
|
-
else
|
49
|
-
ENV['COVERAGE'] = 'true'
|
50
|
-
Rake::Task['test:client'].invoke
|
51
|
-
Rake::Task['test:provider'].invoke
|
52
|
-
Rake::Task['test:activerecord_provider'].invoke
|
53
|
-
end
|
54
|
-
|
55
|
-
system("open coverage/index.html") if (PLATFORM['darwin'] if Kernel.const_defined? :PLATFORM) || (RUBY_PLATFORM =~ /darwin/ if Kernel.const_defined? :RUBY_PLATFORM)
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
if RUBY_VERSION =~ /^1.8/
|
61
|
-
require 'rcov/rcovtask'
|
62
|
-
namespace :rcov do
|
63
|
-
Rcov::RcovTask.new do |t|
|
64
|
-
t.name = 'client'
|
65
|
-
t.libs << ['lib', 'test/client']
|
66
|
-
t.pattern = 'test/client/tc_*.rb'
|
67
|
-
t.verbose = true
|
68
|
-
t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
|
69
|
-
end
|
70
|
-
|
71
|
-
Rcov::RcovTask.new('provider') do |t|
|
72
|
-
t.libs << ['lib', 'test/provider']
|
73
|
-
t.pattern = 'test/provider/tc_*.rb'
|
74
|
-
t.verbose = true
|
75
|
-
t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
|
76
|
-
end
|
77
|
-
|
78
|
-
Rcov::RcovTask.new('activerecord_provider') do |t|
|
79
|
-
t.libs << ['lib', 'test/activerecord_provider']
|
80
|
-
t.pattern = 'test/activerecord_provider/tc_*.rb'
|
81
|
-
t.verbose = true
|
82
|
-
t.rcov_opts = ['--aggregate coverage.data', '--text-summary']
|
83
|
-
end
|
49
|
+
#t.verbose = true
|
50
|
+
t.warning = false
|
84
51
|
end
|
85
52
|
end
|
86
53
|
|
data/lib/oai/client.rb
CHANGED
@@ -92,11 +92,11 @@ module OAI
|
|
92
92
|
@http_client = options.fetch(:http) do
|
93
93
|
Faraday.new(:url => @base.clone) do |builder|
|
94
94
|
follow_redirects = options.fetch(:redirects, true)
|
95
|
-
if follow_redirects
|
96
|
-
count = follow_redirects.is_a?(Fixnum) ? follow_redirects : 5
|
95
|
+
follow_redirects = 5 if follow_redirects == true
|
97
96
|
|
97
|
+
if follow_redirects
|
98
98
|
require 'faraday_middleware'
|
99
|
-
builder.response :follow_redirects, :limit =>
|
99
|
+
builder.response :follow_redirects, :limit => follow_redirects.to_i
|
100
100
|
end
|
101
101
|
builder.adapter :net_http
|
102
102
|
end
|
data/lib/oai/provider.rb
CHANGED
@@ -58,7 +58,9 @@ end
|
|
58
58
|
# repository_url 'http://localhost/provider'
|
59
59
|
# record_prefix 'oai:localhost'
|
60
60
|
# admin_email 'root@localhost'
|
61
|
-
#
|
61
|
+
# # record_prefix will be automatically prepended to sample_id, so in this
|
62
|
+
# # case it becomes: oai:localhost:13900
|
63
|
+
# sample_id '13900'
|
62
64
|
# source_model MyModel.new
|
63
65
|
# end
|
64
66
|
# ```
|
@@ -107,7 +109,7 @@ end
|
|
107
109
|
# record_prefix 'oai:blog'
|
108
110
|
# admin_email 'root@localhost'
|
109
111
|
# source_model OAI::Provider::ActiveRecordWrapper.new(Post)
|
110
|
-
#
|
112
|
+
# sample_id '13900' # record prefix used, so becomes oai:blog:13900
|
111
113
|
# end
|
112
114
|
# ```
|
113
115
|
#
|
@@ -116,15 +118,25 @@ end
|
|
116
118
|
# ```ruby
|
117
119
|
# class OaiController < ApplicationController
|
118
120
|
# def index
|
119
|
-
# # Remove controller and action from the options. Rails adds them automatically.
|
120
|
-
# options = params.delete_if { |k,v| %w{controller action}.include?(k) }
|
121
121
|
# provider = BlogProvider.new
|
122
|
-
# response = provider.process_request(
|
123
|
-
# render :
|
122
|
+
# response = provider.process_request(oai_params.to_h)
|
123
|
+
# render :body => response, :content_type => 'text/xml'
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# private
|
127
|
+
#
|
128
|
+
# def oai_params
|
129
|
+
# params.permit(:verb, :identifier, :metadataPrefix, :set, :from, :until, :resumptionToken)
|
124
130
|
# end
|
125
131
|
# end
|
126
132
|
# ```
|
127
133
|
#
|
134
|
+
# And route to it in your `config/routes.rb` file:
|
135
|
+
#
|
136
|
+
# ```ruby
|
137
|
+
# match 'oai', to: "oai#index", via: [:get, :post]
|
138
|
+
# ```
|
139
|
+
#
|
128
140
|
# Special thanks to Jose Hales-Garcia for this solution.
|
129
141
|
#
|
130
142
|
# ## Supporting custom metadata formats
|
@@ -137,13 +149,19 @@ end
|
|
137
149
|
# It takes one required paramater, the class name of the AR class to wrap,
|
138
150
|
# and optional hash of options.
|
139
151
|
#
|
152
|
+
# As of `oai` gem 1.0.0, Rails 5.2.x and Rails 6.0.x are supported.
|
153
|
+
# Please check the .travis.yml file at root of repo to see what versions of ruby/rails
|
154
|
+
# are being tested, in case this is out of date.
|
155
|
+
#
|
140
156
|
# Valid options include:
|
141
157
|
#
|
142
|
-
# * `timestamp_field` - Specifies the model field to use as the update
|
158
|
+
# * `timestamp_field` - Specifies the model field/method to use as the update
|
143
159
|
# filter. Defaults to `updated_at`.
|
160
|
+
# * `identifier_field` -- specifies the model field/method to use to get value to use
|
161
|
+
# as oai identifier (method return value should not include prefix)
|
144
162
|
# * `limit` - Maximum number of records to return in each page/set.
|
145
|
-
# Defaults to 100.
|
146
|
-
#
|
163
|
+
# Defaults to 100, set to `nil` for all records in one page. Otherwise
|
164
|
+
# the wrapper will paginate the result via resumption tokens.
|
147
165
|
# _Caution: specifying too large a limit will adversely affect performance._
|
148
166
|
#
|
149
167
|
# Mapping from a ActiveRecord object to a specific metadata format follows
|
@@ -197,6 +215,26 @@ end
|
|
197
215
|
# end
|
198
216
|
# end
|
199
217
|
# ```
|
218
|
+
# ### Scopes for restrictions or eager-loading
|
219
|
+
#
|
220
|
+
# Instead of passing in a Model class to OAI::Provider::ActiveRecordWrapper, you can actually
|
221
|
+
# pass in any scope (or ActiveRecord::Relation). This means you can use it for restrictions:
|
222
|
+
#
|
223
|
+
# OAI::Provider::ActiveRecordWrapper.new(Post.where(published: true))
|
224
|
+
#
|
225
|
+
# Or eager-loading an association you will need to create serialization, to avoid n+1 query
|
226
|
+
# performance problems:
|
227
|
+
#
|
228
|
+
# OAI::Provider::ActiveRecordWrapper.new(Post.includes(:categories))
|
229
|
+
#
|
230
|
+
# Or both of those in combination, or anything else that returns an ActiveRecord::Relation,
|
231
|
+
# including using custom scopes, etc.
|
232
|
+
#
|
233
|
+
# ### Sets?
|
234
|
+
#
|
235
|
+
# There is some code written to support oai-pmh "sets" in the ActiveRecord::Wrapper, but
|
236
|
+
# it's somewhat inflexible, and not well-documented, and as I write this I don't understand
|
237
|
+
# it enough to say more. See https://github.com/code4lib/ruby-oai/issues/67
|
200
238
|
#
|
201
239
|
module OAI::Provider
|
202
240
|
class Base
|
data/lib/oai/provider/model.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
module OAI::Provider
|
2
2
|
# = OAI::Provider::Model
|
3
3
|
#
|
4
|
-
# Model implementers should subclass OAI::Provider::Model and override
|
4
|
+
# Model implementers should subclass OAI::Provider::Model and override
|
5
5
|
# Model#earliest, Model#latest, and Model#find. Optionally Model#sets and
|
6
|
-
# Model#deleted? can be used to support sets and record deletions. It
|
7
|
-
# is also the responsibility of the model implementer to account for
|
8
|
-
# resumption tokens if support is required. Models that don't support
|
9
|
-
# resumption tokens should raise an exception if a limit is requested
|
6
|
+
# Model#deleted? can be used to support sets and record deletions. It
|
7
|
+
# is also the responsibility of the model implementer to account for
|
8
|
+
# resumption tokens if support is required. Models that don't support
|
9
|
+
# resumption tokens should raise an exception if a limit is requested
|
10
10
|
# during initialization.
|
11
11
|
#
|
12
12
|
# earliest - should return the earliest update time in the repository.
|
@@ -14,8 +14,8 @@ module OAI::Provider
|
|
14
14
|
# sets - should return an array of sets supported by the repository.
|
15
15
|
# deleted? - individual records returned should respond true or false
|
16
16
|
# when sent the deleted? message.
|
17
|
-
# available_formats - if overridden, individual records should return an
|
18
|
-
# array of prefixes for all formats in which that record is available,
|
17
|
+
# available_formats - if overridden, individual records should return an
|
18
|
+
# array of prefixes for all formats in which that record is available,
|
19
19
|
# if other than ["oai_dc"]
|
20
20
|
# about - if overridden, should return a String or Array of XML Strings to
|
21
21
|
# insert into the OAI Record <about> chunks.
|
@@ -28,12 +28,12 @@ module OAI::Provider
|
|
28
28
|
# There are several helper models for dealing with resumption tokens please
|
29
29
|
# see the ResumptionToken class for more details.
|
30
30
|
#
|
31
|
-
|
32
31
|
class Model
|
33
|
-
attr_reader :timestamp_field
|
34
|
-
|
35
|
-
def initialize(limit = nil, timestamp_field = 'updated_at')
|
32
|
+
attr_reader :timestamp_field, :identifier_field
|
33
|
+
|
34
|
+
def initialize(limit = nil, timestamp_field = 'updated_at', identifier_field = 'id')
|
36
35
|
@limit = limit
|
36
|
+
@identifier_field = identifier_field
|
37
37
|
@timestamp_field = timestamp_field
|
38
38
|
end
|
39
39
|
|
@@ -41,16 +41,16 @@ module OAI::Provider
|
|
41
41
|
def earliest
|
42
42
|
raise NotImplementedError.new
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
# should return the latest timestamp available from this model.
|
46
46
|
def latest
|
47
47
|
raise NotImplementedError.new
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def sets
|
51
51
|
nil
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
# find is the core method of a model, it returns records from the model
|
55
55
|
# bases on the parameters passed in.
|
56
56
|
#
|
@@ -61,12 +61,12 @@ module OAI::Provider
|
|
61
61
|
# * :from => earliest timestamp to be included in the results
|
62
62
|
# * :until => latest timestamp to be included in the results
|
63
63
|
# * :set => the set from which to retrieve the results
|
64
|
-
# * :metadata_prefix => type of metadata requested (this may be useful if
|
64
|
+
# * :metadata_prefix => type of metadata requested (this may be useful if
|
65
65
|
# not all records are available in all formats)
|
66
66
|
def find(selector, options={})
|
67
67
|
raise NotImplementedError.new
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def deleted?
|
71
71
|
false
|
72
72
|
end
|
@@ -76,5 +76,5 @@ module OAI::Provider
|
|
76
76
|
nil
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
end
|
@@ -90,17 +90,16 @@ module OAI::Provider
|
|
90
90
|
# select a subset of the result set, and return it with a
|
91
91
|
# resumption token to get the next subset
|
92
92
|
def select_partial(token)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
93
|
+
oaitoken = OaiToken.find_by(token: token.to_s)
|
94
|
+
|
95
|
+
if 0 == token.last && oaitoken.nil?
|
96
|
+
oaitoken = OaiToken.create!(token: token.to_s)
|
97
|
+
OaiToken.connection.execute("insert into " +
|
98
|
+
"#{OaiEntry.table_name} (oai_token_id, record_id) " +
|
99
|
+
"select #{oaitoken.id}, id from #{model.table_name} where " +
|
100
|
+
"#{OaiToken.sanitize_sql(token_conditions(token))}")
|
101
101
|
end
|
102
102
|
|
103
|
-
oaitoken = OaiToken.find_by_token(token.to_s)
|
104
103
|
raise ResumptionTokenException.new unless oaitoken
|
105
104
|
|
106
105
|
PartialResult.new(
|
@@ -111,7 +110,7 @@ module OAI::Provider
|
|
111
110
|
end
|
112
111
|
|
113
112
|
def sweep_cache
|
114
|
-
OaiToken.
|
113
|
+
OaiToken.where(["created_at < ?", Time.now - expire]).destroy_all
|
115
114
|
end
|
116
115
|
|
117
116
|
def hydrate_records(records)
|
@@ -10,12 +10,19 @@ module OAI::Provider
|
|
10
10
|
#
|
11
11
|
class ActiveRecordWrapper < Model
|
12
12
|
|
13
|
-
attr_reader :model, :timestamp_field
|
14
|
-
|
13
|
+
attr_reader :model, :timestamp_field, :identifier_field
|
14
|
+
|
15
|
+
# If custom 'timestamp_field' is used, be aware this will be an ActiveRecord
|
16
|
+
# attribute that we will limit on, so perhaps should be indexe appropriately.
|
17
|
+
#
|
18
|
+
# If custom `identifier_field` is used, be aware this will be an ActiveRecord
|
19
|
+
# attribute that we will sort on, and use in WHERE clauses with `=` as well as
|
20
|
+
# greater than/less than, so should be indexed appropriately.
|
15
21
|
def initialize(model, options={})
|
16
22
|
@model = model
|
17
23
|
@timestamp_field = options.delete(:timestamp_field) || 'updated_at'
|
18
|
-
@
|
24
|
+
@identifier_field = options.delete(:identifier_field) || model.primary_key || "id"
|
25
|
+
@limit = options.delete(:limit) || 100
|
19
26
|
|
20
27
|
unless options.empty?
|
21
28
|
raise ArgumentError.new(
|
@@ -54,7 +61,7 @@ module OAI::Provider
|
|
54
61
|
find_scope.where(conditions)
|
55
62
|
end
|
56
63
|
else
|
57
|
-
find_scope.where(conditions).
|
64
|
+
find_scope.where(conditions).find_by!(identifier_field => selector)
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
@@ -105,7 +112,7 @@ module OAI::Provider
|
|
105
112
|
model.where(set: options[:set])
|
106
113
|
else
|
107
114
|
# Default to empty set, as we've tried everything else
|
108
|
-
model.
|
115
|
+
model.none
|
109
116
|
end
|
110
117
|
end
|
111
118
|
|
@@ -129,7 +136,7 @@ module OAI::Provider
|
|
129
136
|
else # end of result set
|
130
137
|
find_scope.where(token_conditions(token))
|
131
138
|
.limit(@limit)
|
132
|
-
.order("#{
|
139
|
+
.order("#{identifier_field} asc")
|
133
140
|
end
|
134
141
|
end
|
135
142
|
|
@@ -138,9 +145,9 @@ module OAI::Provider
|
|
138
145
|
def select_partial(find_scope, token)
|
139
146
|
records = find_scope.where(token_conditions(token))
|
140
147
|
.limit(@limit)
|
141
|
-
.order("#{
|
148
|
+
.order("#{identifier_field} asc")
|
142
149
|
raise OAI::ResumptionTokenException.new unless records
|
143
|
-
offset = records.last.send(
|
150
|
+
offset = records.last.send(identifier_field)
|
144
151
|
|
145
152
|
PartialResult.new(records, token.next(offset))
|
146
153
|
end
|
@@ -157,7 +164,7 @@ module OAI::Provider
|
|
157
164
|
|
158
165
|
return sql if 0 == last
|
159
166
|
# Now add last id constraint
|
160
|
-
sql.first << " AND #{
|
167
|
+
sql.first << " AND #{identifier_field} > :id"
|
161
168
|
sql.last[:id] = last
|
162
169
|
|
163
170
|
return sql
|
@@ -48,8 +48,9 @@ module OAI::Provider::Response
|
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
|
+
# Namespace syntax suggested in http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm
|
51
52
|
def identifier_for(record)
|
52
|
-
"#{provider.prefix}
|
53
|
+
"#{provider.prefix}:#{record.send( provider.model.identifier_field )}"
|
53
54
|
end
|
54
55
|
|
55
56
|
def timestamp_for(record)
|
@@ -3,7 +3,24 @@ require 'logger'
|
|
3
3
|
|
4
4
|
# Configure AR connection
|
5
5
|
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
6
|
+
|
7
|
+
if RUBY_PLATFORM == "java"
|
8
|
+
require 'jdbc/sqlite3'
|
9
|
+
Jdbc::SQLite3.load_driver
|
10
|
+
end
|
11
|
+
|
6
12
|
ActiveRecord::Migration.verbose = false
|
7
13
|
ActiveRecord::Base.establish_connection :adapter => "sqlite3",
|
8
14
|
:database => ":memory:"
|
9
|
-
|
15
|
+
|
16
|
+
if ActiveRecord.version < Gem::Version.new("6.0.0")
|
17
|
+
ActiveRecord::MigrationContext.new(
|
18
|
+
File.join(File.dirname(__FILE__), '..', 'database')
|
19
|
+
).migrate
|
20
|
+
else
|
21
|
+
ActiveRecord::MigrationContext.new(
|
22
|
+
File.join(File.dirname(__FILE__), '..', 'database'),
|
23
|
+
ActiveRecord::Base.connection.schema_migration
|
24
|
+
).migrate
|
25
|
+
end
|
26
|
+
|
@@ -12,6 +12,22 @@ class ARProvider < OAI::Provider::Base
|
|
12
12
|
source_model ActiveRecordWrapper.new(DCField)
|
13
13
|
end
|
14
14
|
|
15
|
+
class ARProviderCustomIdentifierField < OAI::Provider::Base
|
16
|
+
repository_name 'ActiveRecord Based Provider'
|
17
|
+
repository_url 'http://localhost'
|
18
|
+
record_prefix 'oai:test'
|
19
|
+
source_model ActiveRecordWrapper.new(DCField, identifier_field: "source")
|
20
|
+
end
|
21
|
+
|
22
|
+
class ARProviderWithScope < OAI::Provider::Base
|
23
|
+
DATE_LESS_THAN_RESTRICTION = Time.parse("2007-03-12 19:30:22 UTC")
|
24
|
+
|
25
|
+
repository_name 'ActiveRecord Based Provider'
|
26
|
+
repository_url 'http://localhost'
|
27
|
+
record_prefix 'oai:test'
|
28
|
+
source_model ActiveRecordWrapper.new(DCField.where("date < ?", DATE_LESS_THAN_RESTRICTION).includes(:sets))
|
29
|
+
end
|
30
|
+
|
15
31
|
class SimpleResumptionProvider < OAI::Provider::Base
|
16
32
|
repository_name 'ActiveRecord Resumption Provider'
|
17
33
|
repository_url 'http://localhost'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_ar_provider'
|
2
2
|
|
3
3
|
class ActiveRecordProviderTest < TransactionalTestCase
|
4
4
|
|
@@ -14,7 +14,7 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
14
14
|
|
15
15
|
def test_metadata_formats_for_record
|
16
16
|
record_id = DCField.first.id
|
17
|
-
assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats(:identifier => "oai:test
|
17
|
+
assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats(:identifier => "oai:test:#{record_id}")) }
|
18
18
|
doc = REXML::Document.new(@provider.list_metadata_formats)
|
19
19
|
assert doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text == 'oai_dc'
|
20
20
|
end
|
@@ -28,6 +28,30 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
28
28
|
assert_equal 100, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
29
29
|
end
|
30
30
|
|
31
|
+
def test_list_records_scope
|
32
|
+
@provider = ARProviderWithScope.new
|
33
|
+
|
34
|
+
doc = nil
|
35
|
+
assert_nothing_raised do
|
36
|
+
doc = REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
|
37
|
+
end
|
38
|
+
|
39
|
+
expected_count = DCField.where("date < ?", ARProviderWithScope::DATE_LESS_THAN_RESTRICTION).count
|
40
|
+
assert_equal expected_count, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_get_record_alternate_identifier_column
|
45
|
+
@provider = ARProviderCustomIdentifierField.new
|
46
|
+
|
47
|
+
record_id = DCField.first.send(@provider.class.model.identifier_field)
|
48
|
+
|
49
|
+
doc = REXML::Document.new(@provider.get_record(
|
50
|
+
:identifier => "oai:test:#{record_id}", :metadata_prefix => 'oai_dc'))
|
51
|
+
|
52
|
+
assert_equal "oai:test:#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
53
|
+
end
|
54
|
+
|
31
55
|
def test_list_identifiers
|
32
56
|
assert_nothing_raised { REXML::Document.new(@provider.list_identifiers) }
|
33
57
|
doc = REXML::Document.new(@provider.list_identifiers)
|
@@ -38,11 +62,11 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
38
62
|
record_id = DCField.first.id
|
39
63
|
assert_nothing_raised do
|
40
64
|
REXML::Document.new(@provider.get_record(
|
41
|
-
:identifier => "oai:test
|
65
|
+
:identifier => "oai:test:#{record_id}", :metadata_prefix => 'oai_dc'))
|
42
66
|
end
|
43
67
|
doc = REXML::Document.new(@provider.get_record(
|
44
68
|
:identifier => "#{record_id}", :metadata_prefix => 'oai_dc'))
|
45
|
-
assert_equal "oai:test
|
69
|
+
assert_equal "oai:test:#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
46
70
|
end
|
47
71
|
|
48
72
|
def test_deleted
|
@@ -50,8 +74,8 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
50
74
|
record.deleted = true;
|
51
75
|
record.save
|
52
76
|
doc = REXML::Document.new(@provider.get_record(
|
53
|
-
:identifier => "oai:test
|
54
|
-
assert_equal "oai:test
|
77
|
+
:identifier => "oai:test:#{record.id}", :metadata_prefix => 'oai_dc'))
|
78
|
+
assert_equal "oai:test:#{record.id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
55
79
|
assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
|
56
80
|
end
|
57
81
|
|
@@ -1,12 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
-
if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
|
4
|
-
require 'simplecov'
|
5
|
-
require 'simplecov-rcov'
|
6
|
-
|
7
|
-
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
8
|
-
SimpleCov.start
|
9
|
-
end
|
10
3
|
require 'test/unit'
|
11
4
|
require File.dirname(__FILE__) + '/config/connection'
|
12
5
|
require File.dirname(__FILE__) + '/helpers/providers'
|
@@ -1,20 +1,20 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
require File.dirname(__FILE__) + '/../../provider/models'
|
3
3
|
|
4
|
-
class ComplexProvider < OAI::Provider::Base
|
5
|
-
repository_name 'Complex Provider'
|
6
|
-
repository_url 'http://localhost'
|
7
|
-
record_prefix 'oai:test'
|
8
|
-
source_model ComplexModel.new(100)
|
9
|
-
end
|
10
4
|
|
11
5
|
class ProviderServer
|
6
|
+
class ComplexClientProvider < OAI::Provider::Base
|
7
|
+
repository_name 'Complex Provider'
|
8
|
+
repository_url 'http://localhost'
|
9
|
+
record_prefix 'oai:test'
|
10
|
+
source_model ComplexModel.new(100)
|
11
|
+
end
|
12
12
|
|
13
13
|
attr_reader :consumed, :server
|
14
14
|
|
15
15
|
def initialize(port, mount_point)
|
16
16
|
@consumed = []
|
17
|
-
@provider =
|
17
|
+
@provider = ComplexClientProvider.new
|
18
18
|
@server = WEBrick::HTTPServer.new(
|
19
19
|
:BindAddress => '127.0.0.1',
|
20
20
|
:Logger => WEBrick::Log.new('/dev/null'),
|
@@ -62,4 +62,4 @@ class ProviderServer
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
end
|
65
|
+
end
|
data/test/client/tc_exception.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class ExceptionTest < Test::Unit::TestCase
|
4
4
|
|
@@ -9,7 +9,7 @@ class ExceptionTest < Test::Unit::TestCase
|
|
9
9
|
|
10
10
|
def test_xml_error
|
11
11
|
client = OAI::Client.new 'http://www.yahoo.com'
|
12
|
-
begin
|
12
|
+
begin
|
13
13
|
client.identify
|
14
14
|
rescue OAI::Exception => e
|
15
15
|
assert_match /response not well formed XML/, e.to_s, 'xml error'
|
@@ -23,7 +23,7 @@ class ExceptionTest < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
# must pass in options as a hash
|
26
|
+
# must pass in options as a hash
|
27
27
|
def test_parameter_error
|
28
28
|
client = OAI::Client.new 'http://localhost:3333/oai'
|
29
29
|
assert_raises(OAI::ArgumentException) {client.get_record('foo')}
|
@@ -32,5 +32,5 @@ class ExceptionTest < Test::Unit::TestCase
|
|
32
32
|
assert_raises(OAI::ArgumentException) {client.list_metadata_formats('foo')}
|
33
33
|
assert_raises(OAI::ArgumentException) {client.list_sets('foo')}
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class GetRecordTest < Test::Unit::TestCase
|
4
|
-
|
4
|
+
|
5
5
|
def test_get_one
|
6
6
|
client = OAI::Client.new 'http://localhost:3333/oai'
|
7
|
-
response = client.get_record :identifier => 'oai:test
|
7
|
+
response = client.get_record :identifier => 'oai:test:3'
|
8
8
|
assert_kind_of OAI::GetRecordResponse, response
|
9
9
|
assert_kind_of OAI::Record, response.record
|
10
10
|
assert_kind_of REXML::Element, response.record._source
|
@@ -13,8 +13,7 @@ class GetRecordTest < Test::Unit::TestCase
|
|
13
13
|
assert_kind_of REXML::Element, response.record.about
|
14
14
|
|
15
15
|
# minimal check that the header is working
|
16
|
-
assert_equal 'oai:test
|
17
|
-
response.record.header.identifier
|
16
|
+
assert_equal 'oai:test:3', response.record.header.identifier
|
18
17
|
|
19
18
|
# minimal check that the metadata is working
|
20
19
|
#assert 'en', response.record.metadata.elements['.//dc:language'].text
|
@@ -33,7 +32,7 @@ class GetRecordTest < Test::Unit::TestCase
|
|
33
32
|
|
34
33
|
def test_deleted_record
|
35
34
|
client = OAI::Client.new 'http://localhost:3333/oai'
|
36
|
-
record = client.get_record :identifier => 'oai:test
|
35
|
+
record = client.get_record :identifier => 'oai:test:275'
|
37
36
|
assert record.deleted?
|
38
37
|
end
|
39
38
|
|
data/test/client/tc_identify.rb
CHANGED
data/test/client/tc_libxml.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class LibXMLTest < Test::Unit::TestCase
|
4
4
|
|
@@ -13,7 +13,7 @@ class LibXMLTest < Test::Unit::TestCase
|
|
13
13
|
def test_list_records
|
14
14
|
return unless have_libxml
|
15
15
|
|
16
|
-
# since there is regex magic going on to remove default oai namespaces
|
16
|
+
# since there is regex magic going on to remove default oai namespaces
|
17
17
|
# it's worth trying a few different oai targets
|
18
18
|
oai_targets = %w{
|
19
19
|
http://localhost:3333/oai
|
@@ -43,10 +43,10 @@ class LibXMLTest < Test::Unit::TestCase
|
|
43
43
|
|
44
44
|
uri = 'http://localhost:3333/oai'
|
45
45
|
client = OAI::Client.new(uri, :parser => 'libxml')
|
46
|
-
response = client.get_record :identifier => 'oai:test
|
46
|
+
response = client.get_record :identifier => 'oai:test:275'
|
47
47
|
assert response.record.deleted?
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
private
|
51
51
|
|
52
52
|
def have_libxml
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class ListMetadataFormatsTest < Test::Unit::TestCase
|
4
4
|
def test_list
|
5
|
-
client = OAI::Client.new 'http://localhost:3333/oai'
|
5
|
+
client = OAI::Client.new 'http://localhost:3333/oai'
|
6
6
|
response = client.list_metadata_formats
|
7
7
|
assert_kind_of OAI::ListMetadataFormatsResponse, response
|
8
8
|
assert response.entries.size > 0
|
@@ -13,6 +13,6 @@ class ListMetadataFormatsTest < Test::Unit::TestCase
|
|
13
13
|
assert_equal 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', format.schema
|
14
14
|
assert_equal 'http://www.openarchives.org/OAI/2.0/oai_dc/', format.namespace
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
end
|
18
18
|
|
data/test/client/tc_list_sets.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class LowResolutionDatesTest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def test_low_res_date_parsing
|
6
|
-
client = OAI::Client.new 'http://authors.library.caltech.edu/cgi/oai2'
|
6
|
+
client = OAI::Client.new 'http://authors.library.caltech.edu/cgi/oai2'
|
7
7
|
|
8
8
|
date = Date.new 2003, 1, 1
|
9
|
-
|
9
|
+
|
10
10
|
# get a list of identifier headers
|
11
|
-
assert_nothing_raised { client.list_identifiers :from => date }
|
11
|
+
assert_nothing_raised { client.list_identifiers :from => date }
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class UTF8Test < Test::Unit::TestCase
|
4
|
-
|
4
|
+
|
5
5
|
def test_escaping_invalid_utf_8_characters
|
6
6
|
client = OAI::Client.new 'http://localhost:3333/oai' #, :parser => 'libxml'
|
7
7
|
invalid_utf_8 = [2, 3, 4, 104, 5, 101, 6, 108, 66897, 108, 66535, 111, 1114112, 33, 55234123, 33].pack("U*")
|
data/test/client/tc_xpath.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_client'
|
2
2
|
|
3
3
|
class XpathTest < Test::Unit::TestCase
|
4
4
|
include OAI::XPath
|
@@ -11,7 +11,7 @@ class XpathTest < Test::Unit::TestCase
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_libxml
|
14
|
-
begin
|
14
|
+
begin
|
15
15
|
require 'xml/libxml'
|
16
16
|
rescue LoadError
|
17
17
|
# libxml not available so nothing to test!
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_provider'
|
2
2
|
|
3
3
|
class ProviderExceptions < Test::Unit::TestCase
|
4
4
|
|
@@ -36,7 +36,7 @@ class ProviderExceptions < Test::Unit::TestCase
|
|
36
36
|
|
37
37
|
def test_bad_format_raises_exception
|
38
38
|
assert_raise(OAI::FormatException) do
|
39
|
-
@provider.get_record(:identifier => 'oai:test
|
39
|
+
@provider.get_record(:identifier => 'oai:test:1', :metadata_prefix => 'html')
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -45,16 +45,18 @@ class ProviderExceptions < Test::Unit::TestCase
|
|
45
45
|
@provider.list_records()
|
46
46
|
end
|
47
47
|
assert_raise(OAI::ArgumentException) do
|
48
|
-
@provider.get_record(:identifier => 'oai:test
|
48
|
+
@provider.get_record(:identifier => 'oai:test:1')
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_bad_id_raises_exception
|
53
53
|
badIdentifiers = [
|
54
|
-
'oai:test
|
55
|
-
'oai:test
|
54
|
+
'oai:test:5000',
|
55
|
+
'oai:test:-1',
|
56
|
+
'oai:test:one',
|
56
57
|
'oai:test/one',
|
57
|
-
'oai:test
|
58
|
+
'oai:test/1',
|
59
|
+
'oai:test:\\$1\1!']
|
58
60
|
badIdentifiers.each do |id|
|
59
61
|
assert_raise(OAI::IdException) do
|
60
62
|
@provider.get_record(:identifier => id, :metadata_prefix => 'oai_dc')
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_provider'
|
2
2
|
|
3
3
|
class ResumptionTokenFunctionalTest < Test::Unit::TestCase
|
4
4
|
include REXML
|
@@ -44,4 +44,4 @@ class ResumptionTokenFunctionalTest < Test::Unit::TestCase
|
|
44
44
|
assert_equal 100, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
45
45
|
end
|
46
46
|
|
47
|
-
end
|
47
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_provider'
|
2
2
|
|
3
3
|
class ResumptionTokenTest < Test::Unit::TestCase
|
4
4
|
include REXML
|
@@ -43,4 +43,4 @@ class ResumptionTokenTest < Test::Unit::TestCase
|
|
43
43
|
assert_equal "#{@token.to_s}:#{@token.last}", doc.elements['/resumptionToken'].text
|
44
44
|
end
|
45
45
|
|
46
|
-
end
|
46
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'test_helper_provider'
|
2
2
|
|
3
3
|
class TestSimpleProvider < Test::Unit::TestCase
|
4
4
|
|
@@ -35,7 +35,7 @@ class TestSimpleProvider < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_metadata_formats_for_document
|
38
|
-
assert_nothing_raised { REXML::Document.new(@simple_provider.list_metadata_formats(:identifier => "oai:test
|
38
|
+
assert_nothing_raised { REXML::Document.new(@simple_provider.list_metadata_formats(:identifier => "oai:test:1")) }
|
39
39
|
doc = REXML::Document.new(@simple_provider.list_metadata_formats)
|
40
40
|
assert_equal "oai_dc",
|
41
41
|
doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text
|
@@ -85,18 +85,18 @@ class TestSimpleProvider < Test::Unit::TestCase
|
|
85
85
|
assert_nothing_raised do
|
86
86
|
REXML::Document.new(
|
87
87
|
@simple_provider.get_record(
|
88
|
-
:identifier => 'oai:test
|
88
|
+
:identifier => 'oai:test:1',
|
89
89
|
:metadataPrefix => 'oai_dc'
|
90
90
|
)
|
91
91
|
)
|
92
92
|
end
|
93
93
|
doc = REXML::Document.new(
|
94
94
|
@simple_provider.get_record(
|
95
|
-
:identifier => 'oai:test
|
95
|
+
:identifier => 'oai:test:1',
|
96
96
|
:metadataPrefix => 'oai_dc'
|
97
97
|
)
|
98
98
|
)
|
99
|
-
assert_equal 'oai:test
|
99
|
+
assert_equal 'oai:test:1',
|
100
100
|
doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
101
101
|
end
|
102
102
|
|
@@ -104,18 +104,18 @@ class TestSimpleProvider < Test::Unit::TestCase
|
|
104
104
|
assert_nothing_raised do
|
105
105
|
REXML::Document.new(
|
106
106
|
@simple_provider.get_record(
|
107
|
-
:identifier => 'oai:test
|
107
|
+
:identifier => 'oai:test:6',
|
108
108
|
:metadataPrefix => 'oai_dc'
|
109
109
|
)
|
110
110
|
)
|
111
111
|
end
|
112
112
|
doc = REXML::Document.new(
|
113
113
|
@simple_provider.get_record(
|
114
|
-
:identifier => 'oai:test
|
114
|
+
:identifier => 'oai:test:5',
|
115
115
|
:metadataPrefix => 'oai_dc'
|
116
116
|
)
|
117
117
|
)
|
118
|
-
assert_equal 'oai:test
|
118
|
+
assert_equal 'oai:test:5', doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
|
119
119
|
assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
|
120
120
|
end
|
121
121
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ed Summers
|
8
8
|
autorequire: oai
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -52,6 +52,40 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 5.2.0
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '6.1'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 5.2.0
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '6.1'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: appraisal
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
55
89
|
description:
|
56
90
|
email: ehs@pobox.com
|
57
91
|
executables:
|
@@ -119,7 +153,7 @@ files:
|
|
119
153
|
- test/activerecord_provider/tc_ar_sets_provider.rb
|
120
154
|
- test/activerecord_provider/tc_caching_paging_provider.rb
|
121
155
|
- test/activerecord_provider/tc_simple_paging_provider.rb
|
122
|
-
- test/activerecord_provider/
|
156
|
+
- test/activerecord_provider/test_helper_ar_provider.rb
|
123
157
|
- test/client/helpers/provider.rb
|
124
158
|
- test/client/helpers/test_wrapper.rb
|
125
159
|
- test/client/tc_exception.rb
|
@@ -134,14 +168,14 @@ files:
|
|
134
168
|
- test/client/tc_low_resolution_dates.rb
|
135
169
|
- test/client/tc_utf8_escaping.rb
|
136
170
|
- test/client/tc_xpath.rb
|
137
|
-
- test/client/
|
171
|
+
- test/client/test_helper_client.rb
|
138
172
|
- test/provider/models.rb
|
139
173
|
- test/provider/tc_exceptions.rb
|
140
174
|
- test/provider/tc_functional_tokens.rb
|
141
175
|
- test/provider/tc_provider.rb
|
142
176
|
- test/provider/tc_resumption_tokens.rb
|
143
177
|
- test/provider/tc_simple_provider.rb
|
144
|
-
- test/provider/
|
178
|
+
- test/provider/test_helper_provider.rb
|
145
179
|
- test/test.xml
|
146
180
|
homepage: http://github.com/code4lib/ruby-oai
|
147
181
|
licenses: []
|
@@ -157,15 +191,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
157
191
|
version: '0'
|
158
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
159
193
|
requirements:
|
160
|
-
- - "
|
194
|
+
- - ">"
|
161
195
|
- !ruby/object:Gem::Version
|
162
|
-
version:
|
196
|
+
version: 1.3.1
|
163
197
|
requirements: []
|
164
|
-
|
165
|
-
rubygems_version: 2.2.1
|
198
|
+
rubygems_version: 3.0.3
|
166
199
|
signing_key:
|
167
200
|
specification_version: 4
|
168
201
|
summary: A ruby library for working with the Open Archive Initiative Protocol for
|
169
202
|
Metadata Harvesting (OAI-PMH)
|
170
203
|
test_files: []
|
171
|
-
has_rdoc:
|
data/test/client/test_helper.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
|
2
|
-
require 'simplecov'
|
3
|
-
require 'simplecov-rcov'
|
4
|
-
|
5
|
-
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
6
|
-
SimpleCov.start
|
7
|
-
end
|
8
|
-
|
9
|
-
require 'oai'
|
10
|
-
require 'test/unit'
|
11
|
-
|
12
|
-
require File.dirname(__FILE__) + '/helpers/provider'
|
13
|
-
require File.dirname(__FILE__) + '/helpers/test_wrapper'
|