oai 1.0.0 → 1.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 +4 -4
- data/README.md +19 -4
- data/Rakefile +7 -0
- data/bin/oai +0 -2
- data/examples/models/file_model.rb +2 -2
- data/lib/oai/client/response.rb +8 -8
- data/lib/oai/client.rb +34 -10
- data/lib/oai/exception.rb +46 -38
- data/lib/oai/harvester/config.rb +1 -1
- data/lib/oai/harvester/harvest.rb +37 -25
- data/lib/oai/harvester/logging.rb +3 -5
- data/lib/oai/harvester.rb +4 -1
- data/lib/oai/provider/model/activerecord_caching_wrapper.rb +5 -8
- data/lib/oai/provider/model/activerecord_wrapper.rb +41 -25
- data/lib/oai/provider/model.rb +1 -1
- data/lib/oai/provider/response/list_records.rb +12 -0
- data/lib/oai/provider/response.rb +7 -4
- data/lib/oai/provider/resumption_token.rb +70 -21
- data/lib/oai/provider.rb +129 -7
- data/test/activerecord_provider/database/0001_oaipmh_tables.rb +7 -1
- data/test/activerecord_provider/helpers/providers.rb +10 -1
- data/test/activerecord_provider/helpers/transactional_test_case.rb +2 -1
- data/test/activerecord_provider/models/dc_field.rb +8 -0
- data/test/activerecord_provider/models/dc_lang.rb +3 -0
- data/test/activerecord_provider/models/exclusive_set_dc_field.rb +6 -0
- data/test/activerecord_provider/tc_activerecord_wrapper.rb +63 -0
- data/test/activerecord_provider/tc_ar_provider.rb +54 -26
- data/test/activerecord_provider/tc_ar_sets_provider.rb +10 -9
- data/test/activerecord_provider/tc_caching_paging_provider.rb +9 -7
- data/test/activerecord_provider/tc_simple_paging_provider.rb +28 -7
- data/test/client/tc_exception.rb +1 -1
- data/test/client/tc_get_record.rb +1 -1
- data/test/client/tc_http_client.rb +2 -2
- data/test/client/tc_libxml.rb +1 -1
- data/test/client/tc_utf8_escaping.rb +8 -1
- data/test/harvester/tc_harvest.rb +42 -0
- data/test/harvester/test_helper_harvester.rb +6 -0
- data/test/provider/models.rb +3 -3
- data/test/provider/tc_functional_tokens.rb +17 -11
- data/test/provider/tc_instance_provider.rb +41 -0
- data/test/provider/tc_provider.rb +26 -0
- data/test/provider/tc_resumption_tokens.rb +6 -0
- data/test/provider/test_helper_provider.rb +17 -0
- metadata +28 -17
@@ -81,30 +81,30 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
81
81
|
|
82
82
|
def test_from
|
83
83
|
first_id = DCField.order("id asc").first.id
|
84
|
-
DCField.where("id < #{first_id + 90}").update_all(updated_at: Time.parse("January 1 2005"))
|
84
|
+
DCField.where("dc_fields.id < #{first_id + 90}").update_all(updated_at: Time.parse("January 1 2005"))
|
85
85
|
|
86
|
-
DCField.where("id < #{first_id + 10}").update_all(updated_at: Time.parse("June 1 2005"))
|
86
|
+
DCField.where("dc_fields.id < #{first_id + 10}").update_all(updated_at: Time.parse("June 1 2005"))
|
87
87
|
|
88
88
|
|
89
|
-
from_param = Time.parse("January 1 2006")
|
89
|
+
from_param = Time.parse("January 1 2006").getutc.iso8601
|
90
90
|
|
91
91
|
doc = REXML::Document.new(
|
92
92
|
@provider.list_records(
|
93
93
|
:metadata_prefix => 'oai_dc', :from => from_param)
|
94
94
|
)
|
95
|
-
assert_equal DCField.where(["updated_at >= ?", from_param]).size,
|
95
|
+
assert_equal DCField.where(["dc_fields.updated_at >= ?", from_param]).size,
|
96
96
|
doc.elements['OAI-PMH/ListRecords'].size
|
97
97
|
|
98
98
|
doc = REXML::Document.new(
|
99
99
|
@provider.list_records(
|
100
|
-
:metadata_prefix => 'oai_dc', :from => Time.parse("May 30 2005"))
|
100
|
+
:metadata_prefix => 'oai_dc', :from => Time.parse("May 30 2005").getutc.iso8601)
|
101
101
|
)
|
102
102
|
assert_equal 20, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
103
103
|
end
|
104
104
|
|
105
105
|
def test_until
|
106
|
-
first_id = DCField.order(
|
107
|
-
DCField.where("id <
|
106
|
+
first_id = DCField.order(id: :asc).first.id
|
107
|
+
DCField.where("dc_fields.id < ?", first_id + 10).update_all(updated_at: Time.parse("June 1 2005"))
|
108
108
|
|
109
109
|
doc = REXML::Document.new(
|
110
110
|
@provider.list_records(
|
@@ -114,19 +114,46 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def test_from_and_until
|
117
|
-
first_id = DCField.order(
|
117
|
+
first_id = DCField.order(id: :asc).first.id
|
118
118
|
DCField.update_all(updated_at: Time.parse("June 1 2005"))
|
119
|
-
DCField.where("id <
|
120
|
-
DCField.where("id <
|
119
|
+
DCField.where("dc_fields.id < ?", first_id + 50).update_all(updated_at: Time.parse("June 15 2005"))
|
120
|
+
DCField.where("dc_fields.id < ?", first_id + 10).update_all(updated_at: Time.parse("June 30 2005"))
|
121
121
|
|
122
122
|
doc = REXML::Document.new(
|
123
123
|
@provider.list_records(
|
124
124
|
:metadata_prefix => 'oai_dc',
|
125
|
-
:from => Time.parse("June 3 2005"),
|
126
|
-
:until => Time.parse("June 16 2005"))
|
125
|
+
:from => Time.parse("June 3 2005").getutc.iso8601,
|
126
|
+
:until => Time.parse("June 16 2005").getutc.iso8601)
|
127
127
|
)
|
128
128
|
assert_equal 40, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
129
129
|
end
|
130
|
+
|
131
|
+
def test_bad_until_raises_exception
|
132
|
+
DCField.order(id: :asc).limit(10).update_all(updated_at: 1.year.ago)
|
133
|
+
DCField.order(id: :desc).limit(10).update_all(updated_at: 1.year.from_now)
|
134
|
+
badTimes = [
|
135
|
+
'junk',
|
136
|
+
'February 92nd, 2015']
|
137
|
+
badTimes.each do |time|
|
138
|
+
assert_raise(OAI::ArgumentException) do
|
139
|
+
@provider.list_records(:metadata_prefix => 'oai_dc', :until => time)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_bad_from_raises_exception
|
145
|
+
DCField.order(id: :asc).limit(10).update_all(updated_at: 1.year.ago)
|
146
|
+
DCField.order(id: :desc).limit(10).update_all(updated_at: 1.year.from_now)
|
147
|
+
|
148
|
+
badTimes = [
|
149
|
+
'junk',
|
150
|
+
'February 92nd, 2015']
|
151
|
+
badTimes.each do |time|
|
152
|
+
assert_raise(OAI::ArgumentException) do
|
153
|
+
@provider.list_records(:metadata_prefix => 'oai_dc', :from => time)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
130
157
|
|
131
158
|
def test_handles_empty_collections
|
132
159
|
DCField.delete_all
|
@@ -142,6 +169,21 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
142
169
|
REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
|
143
170
|
end
|
144
171
|
end
|
172
|
+
|
173
|
+
def test_bad_id_raises_exception
|
174
|
+
badIdentifiers = [
|
175
|
+
'invalid"id',
|
176
|
+
'oai:test/5000',
|
177
|
+
'oai:test/-1',
|
178
|
+
'oai:test/one',
|
179
|
+
'oai:test/\\$1\1!']
|
180
|
+
badIdentifiers.each do |id|
|
181
|
+
assert_raise(OAI::IdException) do
|
182
|
+
@provider.get_record(:identifier => id, :metadata_prefix => 'oai_dc')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
145
187
|
|
146
188
|
def setup
|
147
189
|
@provider = ARProvider.new
|
@@ -149,18 +191,4 @@ class ActiveRecordProviderTest < TransactionalTestCase
|
|
149
191
|
|
150
192
|
end
|
151
193
|
|
152
|
-
class ActiveRecordProviderTimezoneTest < ActiveRecordProviderTest
|
153
|
-
|
154
|
-
def setup
|
155
|
-
require 'active_record'
|
156
|
-
ActiveRecord::Base.default_timezone = :utc
|
157
|
-
super
|
158
|
-
end
|
159
194
|
|
160
|
-
def teardown
|
161
|
-
require 'active_record'
|
162
|
-
ActiveRecord::Base.default_timezone = :local
|
163
|
-
super
|
164
|
-
end
|
165
|
-
|
166
|
-
end
|
@@ -51,22 +51,22 @@ class ActiveRecordSetProviderTest < TransactionalTestCase
|
|
51
51
|
set_ab = DCSet.create(:name => "Set A:B", :spec => "A:B")
|
52
52
|
|
53
53
|
next_id = 0
|
54
|
-
DCField.limit(10).order(
|
54
|
+
DCField.limit(10).order(id: :asc).each do |record|
|
55
55
|
set_a.dc_fields << record
|
56
56
|
next_id = record.id
|
57
57
|
end
|
58
58
|
|
59
|
-
DCField.where("id >
|
59
|
+
DCField.where("dc_fields.id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
60
60
|
set_b.dc_fields << record
|
61
61
|
next_id = record.id
|
62
62
|
end
|
63
63
|
|
64
|
-
DCField.where("id >
|
64
|
+
DCField.where("dc_fields.id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
65
65
|
set_ab.dc_fields << record
|
66
66
|
next_id = record.id
|
67
67
|
end
|
68
68
|
|
69
|
-
DCField.where("id >
|
69
|
+
DCField.where("dc_fields.id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
70
70
|
set_a.dc_fields << record
|
71
71
|
set_c.dc_fields << record
|
72
72
|
next_id = record.id
|
@@ -117,25 +117,25 @@ class ActiveRecordExclusiveSetsProviderTest < TransactionalTestCase
|
|
117
117
|
def define_sets
|
118
118
|
next_id = 0
|
119
119
|
|
120
|
-
ExclusiveSetDCField.limit(10).order(
|
120
|
+
ExclusiveSetDCField.limit(10).order(id: :asc).each do |record|
|
121
121
|
record.set = "A"
|
122
122
|
record.save!
|
123
123
|
next_id = record.id
|
124
124
|
end
|
125
125
|
|
126
|
-
ExclusiveSetDCField.where("id >
|
126
|
+
ExclusiveSetDCField.where("id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
127
127
|
record.set = "B"
|
128
128
|
record.save!
|
129
129
|
next_id = record.id
|
130
130
|
end
|
131
131
|
|
132
|
-
ExclusiveSetDCField.where("id >
|
132
|
+
ExclusiveSetDCField.where("id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
133
133
|
record.set = "A:B"
|
134
134
|
record.save!
|
135
135
|
next_id = record.id
|
136
136
|
end
|
137
137
|
|
138
|
-
ExclusiveSetDCField.where("id >
|
138
|
+
ExclusiveSetDCField.where("id > ?", next_id).limit(10).order(id: :asc).each do |record|
|
139
139
|
record.set = "A"
|
140
140
|
record.save!
|
141
141
|
next_id = record.id
|
@@ -150,7 +150,8 @@ class ActiveRecordExclusiveSetsProviderTest < TransactionalTestCase
|
|
150
150
|
)
|
151
151
|
disable_logging do
|
152
152
|
fixtures.keys.sort.each do |key|
|
153
|
-
|
153
|
+
lang = DCLang.create(name: fixtures[key].delete('language'))
|
154
|
+
ExclusiveSetDCField.create(fixtures[key].merge(dc_lang: lang))
|
154
155
|
end
|
155
156
|
end
|
156
157
|
end
|
@@ -17,14 +17,15 @@ class CachingPagingProviderTest < TransactionalTestCase
|
|
17
17
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
18
18
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].size
|
19
19
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
20
|
-
|
21
|
-
|
20
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
21
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
22
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
22
23
|
end
|
23
24
|
|
24
25
|
def test_from_and_until
|
25
|
-
first_id = DCField.order(
|
26
|
-
DCField.where("id <=
|
27
|
-
DCField.where("id <
|
26
|
+
first_id = DCField.order(id: :asc).first.id
|
27
|
+
DCField.where("dc_fields.id <= ?", first_id + 25).update_all(updated_at: Time.parse("September 15 2005"))
|
28
|
+
DCField.where(["dc_fields.id < ? and dc_fields.id > ?", first_id + 50, first_id + 25]).update_all(updated_at: Time.parse("November 1 2005"))
|
28
29
|
|
29
30
|
# Should return 50 records broken into 2 groups of 25.
|
30
31
|
doc = Document.new(
|
@@ -37,8 +38,9 @@ class CachingPagingProviderTest < TransactionalTestCase
|
|
37
38
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
38
39
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
39
40
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
40
|
-
|
41
|
-
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
41
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
42
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
43
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
42
44
|
end
|
43
45
|
|
44
46
|
def setup
|
@@ -8,25 +8,45 @@ class SimpleResumptionProviderTest < TransactionalTestCase
|
|
8
8
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
9
9
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
10
10
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
11
|
+
|
11
12
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
12
13
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
13
14
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
14
15
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
16
|
+
|
15
17
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
16
18
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
17
19
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
18
20
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
21
|
+
|
19
22
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
20
|
-
|
21
|
-
|
23
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
24
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
25
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_non_integer_identifiers_resumption
|
29
|
+
@provider = SimpleResumptionProviderWithNonIntegerID.new
|
30
|
+
|
31
|
+
doc = Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
|
32
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
33
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
34
|
+
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
35
|
+
|
36
|
+
next_doc = Document.new(@provider.list_records(:resumption_token => token))
|
37
|
+
assert_not_nil next_doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
38
|
+
next_token = next_doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
39
|
+
assert_equal 26, next_doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
40
|
+
|
41
|
+
assert_not_equal token, next_token
|
22
42
|
end
|
23
43
|
|
24
44
|
def test_from_and_until
|
25
45
|
first_id = DCField.order("id asc").first.id
|
26
|
-
DCField.where("id <
|
27
|
-
DCField.where("id <=
|
46
|
+
DCField.where("dc_fields.id < ?", first_id + 25).update_all(updated_at: Time.parse("September 15 2005"))
|
47
|
+
DCField.where(["dc_fields.id <= ? and dc_fields.id > ?", first_id + 50, first_id + 25]).update_all(updated_at: Time.parse("November 1 2005"))
|
28
48
|
|
29
|
-
total = DCField.where(["updated_at >= ? AND updated_at <= ?", Time.parse("September 1 2005"), Time.parse("November 30 2005")]).count
|
49
|
+
total = DCField.where(["dc_fields.updated_at >= ? AND dc_fields.updated_at <= ?", Time.parse("September 1 2005"), Time.parse("November 30 2005")]).count
|
30
50
|
|
31
51
|
# Should return 50 records broken into 2 groups of 25.
|
32
52
|
doc = Document.new(
|
@@ -39,8 +59,9 @@ class SimpleResumptionProviderTest < TransactionalTestCase
|
|
39
59
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
40
60
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
41
61
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
42
|
-
|
43
|
-
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
62
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
63
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
64
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
44
65
|
end
|
45
66
|
|
46
67
|
def setup
|
data/test/client/tc_exception.rb
CHANGED
@@ -18,7 +18,7 @@ class ExceptionTest < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
def test_oai_error
|
20
20
|
client = OAI::Client.new 'http://localhost:3333/oai'
|
21
|
-
assert_raises(OAI::
|
21
|
+
assert_raises(OAI::ResumptionTokenException) do
|
22
22
|
client.list_identifiers :resumption_token => 'bogus'
|
23
23
|
end
|
24
24
|
end
|
@@ -25,7 +25,7 @@ class GetRecordTest < Test::Unit::TestCase
|
|
25
25
|
begin
|
26
26
|
client.get_record :metadata_prefix => 'oai_dc'
|
27
27
|
flunk 'invalid get_record did not throw OAI::Exception'
|
28
|
-
rescue OAI::
|
28
|
+
rescue OAI::ArgumentException => e
|
29
29
|
assert_match /The request includes illegal arguments/, e.to_s
|
30
30
|
end
|
31
31
|
end
|
@@ -58,8 +58,8 @@ eos
|
|
58
58
|
end
|
59
59
|
|
60
60
|
faraday_stub = Faraday.new do |builder|
|
61
|
-
require '
|
62
|
-
builder.use
|
61
|
+
require 'faraday/follow_redirects'
|
62
|
+
builder.use Faraday::FollowRedirects::Middleware
|
63
63
|
builder.adapter :test, stubs
|
64
64
|
end
|
65
65
|
|
data/test/client/tc_libxml.rb
CHANGED
@@ -7,7 +7,7 @@ class LibXMLTest < Test::Unit::TestCase
|
|
7
7
|
|
8
8
|
uri = 'http://localhost:3333/oai'
|
9
9
|
client = OAI::Client.new uri, :parser => 'libxml'
|
10
|
-
assert_raises(OAI::
|
10
|
+
assert_raises(OAI::IdException) {client.get_record(:identifier => 'nosuchid')}
|
11
11
|
end
|
12
12
|
|
13
13
|
def test_list_records
|
@@ -1,12 +1,19 @@
|
|
1
1
|
require 'test_helper_client'
|
2
2
|
|
3
3
|
class UTF8Test < Test::Unit::TestCase
|
4
|
+
def client
|
5
|
+
@client ||= OAI::Client.new 'http://localhost:3333/oai'
|
6
|
+
end
|
4
7
|
|
5
8
|
def test_escaping_invalid_utf_8_characters
|
6
|
-
client = OAI::Client.new 'http://localhost:3333/oai' #, :parser => 'libxml'
|
7
9
|
invalid_utf_8 = [2, 3, 4, 104, 5, 101, 6, 108, 66897, 108, 66535, 111, 1114112, 33, 55234123, 33].pack("U*")
|
8
10
|
invalid_utf_8 = invalid_utf_8.force_encoding("binary") if invalid_utf_8.respond_to? :force_encoding
|
9
11
|
assert_equal("hello!!", client.send(:strip_invalid_utf_8_chars, invalid_utf_8).gsub(/\?/, ''))
|
10
12
|
end
|
11
13
|
|
14
|
+
def test_unescaped_ampersand_content_correction
|
15
|
+
src = '<test>Frankie & Johnny <character>♥</character></test>'
|
16
|
+
expected = '<test>Frankie & Johnny <character>♥</character></test>'
|
17
|
+
assert_equal(expected, client.sanitize_xml(src))
|
18
|
+
end
|
12
19
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper_harvester'
|
2
|
+
|
3
|
+
class HarvestTest < Test::Unit::TestCase
|
4
|
+
ONE_HOUR = 3600
|
5
|
+
EARLIEST_FIXTURE = "1998-05-02T04:00:00Z"
|
6
|
+
LATEST_FIXTURE = "2005-12-25T05:00:00Z"
|
7
|
+
def test_harvest
|
8
|
+
until_value = Time.now.utc - ONE_HOUR
|
9
|
+
config = OpenStruct.new(sites: { 'test' => { 'url' => 'http://localhost:3333/oai' }})
|
10
|
+
OAI::Harvester::Harvest.new(config).start
|
11
|
+
last = config.sites.dig('test', 'last')
|
12
|
+
assert_kind_of Time, last
|
13
|
+
assert last >= (until_value + ONE_HOUR), "#{last} < #{(until_value + ONE_HOUR)}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_harvest_from_last
|
17
|
+
from_value = Time.parse(LATEST_FIXTURE).utc
|
18
|
+
now = Time.now.utc
|
19
|
+
config = OpenStruct.new(sites: { 'test' => { 'url' => 'http://localhost:3333/oai' }})
|
20
|
+
OAI::Harvester::Harvest.new(config, nil, from_value).start
|
21
|
+
last = config.sites.dig('test', 'last')
|
22
|
+
assert last >= now, "#{last} < #{now}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_harvest_after_last
|
26
|
+
from_value = Time.parse(LATEST_FIXTURE).utc + 1
|
27
|
+
config = OpenStruct.new(sites: { 'test' => { 'url' => 'http://localhost:3333/oai' }})
|
28
|
+
OAI::Harvester::Harvest.new(config, nil, from_value).start
|
29
|
+
last = config.sites.dig('test', 'last')
|
30
|
+
assert_kind_of NilClass, last
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_harvest_with_until
|
34
|
+
until_value = Time.parse(EARLIEST_FIXTURE).utc + ONE_HOUR
|
35
|
+
config = OpenStruct.new(sites: { 'test' => { 'url' => 'http://localhost:3333/oai' }})
|
36
|
+
OAI::Harvester::Harvest.new(config, nil, nil, until_value).start
|
37
|
+
last = config.sites.dig('test', 'last')
|
38
|
+
assert_kind_of Time, last
|
39
|
+
assert_equal last, until_value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
data/test/provider/models.rb
CHANGED
@@ -68,7 +68,7 @@ class TestModel < OAI::Provider::Model
|
|
68
68
|
if token.last < @groups.size - 1
|
69
69
|
PartialResult.new(@groups[token.last], token.next(token.last + 1))
|
70
70
|
else
|
71
|
-
@groups[token.last]
|
71
|
+
PartialResult.new(@groups[token.last], token.next(nil))
|
72
72
|
end
|
73
73
|
rescue
|
74
74
|
raise OAI::ResumptionTokenException.new
|
@@ -76,8 +76,8 @@ class TestModel < OAI::Provider::Model
|
|
76
76
|
else
|
77
77
|
records = @records.select do |rec|
|
78
78
|
((opts[:set].nil? || rec.in_set(opts[:set])) &&
|
79
|
-
(opts[:from].nil? || rec.updated_at >= opts[:from]) &&
|
80
|
-
(opts[:until].nil? || rec.updated_at <= opts[:until]))
|
79
|
+
(opts[:from].nil? || rec.updated_at >= opts[:from].to_time) &&
|
80
|
+
(opts[:until].nil? || rec.updated_at <= opts[:until].to_time))
|
81
81
|
#else
|
82
82
|
# ((opts[:set].nil? || rec.in_set(opts[:set])) &&
|
83
83
|
# (opts[:from].nil? || rec.updated_at >= opts[:from]) &&
|
@@ -13,15 +13,16 @@ class ResumptionTokenFunctionalTest < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
doc = Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
|
15
15
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
16
|
-
assert_equal
|
16
|
+
assert_equal (@provider.model.limit + 1), doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
17
17
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
18
18
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
19
19
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
20
|
-
assert_equal
|
20
|
+
assert_equal (@provider.model.limit + 1), doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_from_and_until_with_resumption_tokens
|
24
|
-
# Should return
|
24
|
+
# Should return 550 records broken into 5 groups of 100, and a final group of 50.
|
25
|
+
# checked elements under ListRecords are limit + 1, accounting for the resumptionToken element
|
25
26
|
assert_nothing_raised do
|
26
27
|
Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
|
27
28
|
end
|
@@ -29,19 +30,24 @@ class ResumptionTokenFunctionalTest < Test::Unit::TestCase
|
|
29
30
|
@provider.list_records(
|
30
31
|
:metadata_prefix => 'oai_dc',
|
31
32
|
:from => Time.parse("September 1 2004"),
|
32
|
-
:until => Time.parse("
|
33
|
+
:until => Time.parse("December 25 2005"))
|
33
34
|
)
|
34
|
-
assert_equal
|
35
|
-
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
36
|
-
|
37
|
-
doc = Document.new(@provider.list_records(:resumption_token => token))
|
35
|
+
assert_equal (@provider.model.limit + 1), doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
38
36
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
39
|
-
assert_equal 101, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
40
37
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
41
38
|
|
39
|
+
4.times do
|
40
|
+
doc = Document.new(@provider.list_records(:resumption_token => token))
|
41
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
42
|
+
assert_equal (@provider.model.limit + 1), doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
43
|
+
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
44
|
+
end
|
45
|
+
|
42
46
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
43
|
-
|
44
|
-
assert_equal
|
47
|
+
# assert that ListRecords includes remaining records and an empty resumption token
|
48
|
+
assert_equal (551 % @provider.model.limit), doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
49
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
50
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
45
51
|
end
|
46
52
|
|
47
53
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'test_helper_provider'
|
2
|
+
|
3
|
+
class TestInstanceProvider < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# Prior to the commit introducing this code, the InstanceProvider#identify
|
6
|
+
# method would instantiate a Response::Identify object, passing the
|
7
|
+
# InstanceProvider class as the provider for the Response::Identify
|
8
|
+
# instance. With the commit introducing this test, the
|
9
|
+
# InstanceProvider#identify now passes the instance of InstanceProvider
|
10
|
+
# to the instantiation of Response::Identify.
|
11
|
+
#
|
12
|
+
# Thus we can override, on an instance by instance basis, the behavior of a
|
13
|
+
# response object.
|
14
|
+
def test_instance_used_in_responses
|
15
|
+
@url_path = "/stringy-mc-string-face"
|
16
|
+
@instance_provider = InstanceProvider.new({ :provider_context => :instance_based, :url_path => @url_path })
|
17
|
+
|
18
|
+
xml = @instance_provider.identify
|
19
|
+
doc = REXML::Document.new(xml)
|
20
|
+
assert_equal "http://localhost#{@url_path}", doc.elements["OAI-PMH/Identify/baseURL"].text
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_class_used_in_responses
|
24
|
+
@url_path = "/stringy-mc-string-face"
|
25
|
+
@instance_provider = InstanceProvider.new({ :provider_context => :class_based, :url_path => @url_path })
|
26
|
+
|
27
|
+
xml = @instance_provider.identify
|
28
|
+
doc = REXML::Document.new(xml)
|
29
|
+
assert_equal "http://localhost", doc.elements["OAI-PMH/Identify/baseURL"].text
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_by_default_class_used_in_responses
|
33
|
+
@url_path = "/stringy-mc-string-face"
|
34
|
+
@instance_provider = InstanceProvider.new({ :url_path => @url_path })
|
35
|
+
|
36
|
+
xml = @instance_provider.identify
|
37
|
+
doc = REXML::Document.new(xml)
|
38
|
+
assert_equal "http://localhost", doc.elements["OAI-PMH/Identify/baseURL"].text
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -78,6 +78,32 @@ class OaiTest < Test::Unit::TestCase
|
|
78
78
|
)
|
79
79
|
assert_equal 100, doc.elements['OAI-PMH/ListRecords'].to_a.size
|
80
80
|
end
|
81
|
+
|
82
|
+
def test_from_and_until_match
|
83
|
+
assert_nothing_raised do
|
84
|
+
@big_provider.list_records(
|
85
|
+
:metadata_prefix => 'oai_dc',
|
86
|
+
:from => "2000-11-01T05:00:00Z",
|
87
|
+
:until => "2000-11-30T05:00:00Z"
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
assert_nothing_raised do
|
92
|
+
@big_provider.list_records(
|
93
|
+
:metadata_prefix => 'oai_dc',
|
94
|
+
:from => "2000-11-01",
|
95
|
+
:until => "2000-11-30"
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
assert_raise(OAI::ArgumentException) do
|
100
|
+
@big_provider.list_records(
|
101
|
+
:metadata_prefix => 'oai_dc',
|
102
|
+
:from => "2000-11-01T05:00:00Z",
|
103
|
+
:until => "2000-11-30"
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
81
107
|
|
82
108
|
def test_from_and_until
|
83
109
|
assert_nothing_raised do
|
@@ -43,4 +43,10 @@ class ResumptionTokenTest < Test::Unit::TestCase
|
|
43
43
|
assert_equal "#{@token.to_s}:#{@token.last}", doc.elements['/resumptionToken'].text
|
44
44
|
end
|
45
45
|
|
46
|
+
def test_resumption_token_id_does_not_need_to_be_numeric
|
47
|
+
serialized = "oai_dc.s(A).f(2005-01-01T17:00:00Z).u(2005-01-31T17:00:00Z):FA129C"
|
48
|
+
|
49
|
+
token = ResumptionToken.parse(serialized)
|
50
|
+
assert_equal serialized, token.send(:encode_conditions)
|
51
|
+
end
|
46
52
|
end
|
@@ -43,3 +43,20 @@ class DescribedProvider < Provider::Base
|
|
43
43
|
sample_id '13900'
|
44
44
|
extra_description "<my_custom_xml />"
|
45
45
|
end
|
46
|
+
|
47
|
+
class InstanceProvider < Provider::Base
|
48
|
+
repository_name 'Instance Provider'
|
49
|
+
record_prefix 'oai:test'
|
50
|
+
repository_url 'http://localhost'
|
51
|
+
source_model SimpleModel.new
|
52
|
+
|
53
|
+
def initialize(options = {})
|
54
|
+
super
|
55
|
+
@url_path = options.fetch(:url_path)
|
56
|
+
end
|
57
|
+
attr_reader :url_path
|
58
|
+
|
59
|
+
def url
|
60
|
+
File.join(super, url_path)
|
61
|
+
end
|
62
|
+
end
|