oai_talia 0.0.13

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.
Files changed (84) hide show
  1. data/README +81 -0
  2. data/Rakefile +127 -0
  3. data/bin/oai +68 -0
  4. data/examples/models/file_model.rb +63 -0
  5. data/examples/providers/dublin_core.rb +474 -0
  6. data/lib/oai/client/get_record.rb +15 -0
  7. data/lib/oai/client/header.rb +18 -0
  8. data/lib/oai/client/identify.rb +30 -0
  9. data/lib/oai/client/list_identifiers.rb +12 -0
  10. data/lib/oai/client/list_metadata_formats.rb +12 -0
  11. data/lib/oai/client/list_records.rb +21 -0
  12. data/lib/oai/client/list_sets.rb +19 -0
  13. data/lib/oai/client/metadata_format.rb +12 -0
  14. data/lib/oai/client/record.rb +26 -0
  15. data/lib/oai/client/response.rb +35 -0
  16. data/lib/oai/client.rb +301 -0
  17. data/lib/oai/constants.rb +34 -0
  18. data/lib/oai/exception.rb +75 -0
  19. data/lib/oai/harvester/config.rb +41 -0
  20. data/lib/oai/harvester/harvest.rb +150 -0
  21. data/lib/oai/harvester/logging.rb +70 -0
  22. data/lib/oai/harvester/mailer.rb +17 -0
  23. data/lib/oai/harvester/shell.rb +338 -0
  24. data/lib/oai/harvester.rb +39 -0
  25. data/lib/oai/provider/metadata_format/oai_dc.rb +29 -0
  26. data/lib/oai/provider/metadata_format/oai_europeana.rb +38 -0
  27. data/lib/oai/provider/metadata_format.rb +143 -0
  28. data/lib/oai/provider/model/activerecord_caching_wrapper.rb +134 -0
  29. data/lib/oai/provider/model/activerecord_wrapper.rb +139 -0
  30. data/lib/oai/provider/model.rb +74 -0
  31. data/lib/oai/provider/partial_result.rb +18 -0
  32. data/lib/oai/provider/response/error.rb +16 -0
  33. data/lib/oai/provider/response/get_record.rb +26 -0
  34. data/lib/oai/provider/response/identify.rb +25 -0
  35. data/lib/oai/provider/response/list_identifiers.rb +35 -0
  36. data/lib/oai/provider/response/list_metadata_formats.rb +34 -0
  37. data/lib/oai/provider/response/list_records.rb +34 -0
  38. data/lib/oai/provider/response/list_sets.rb +23 -0
  39. data/lib/oai/provider/response/record_response.rb +70 -0
  40. data/lib/oai/provider/response.rb +161 -0
  41. data/lib/oai/provider/resumption_token.rb +106 -0
  42. data/lib/oai/provider.rb +304 -0
  43. data/lib/oai/set.rb +29 -0
  44. data/lib/oai/xpath.rb +75 -0
  45. data/lib/oai.rb +8 -0
  46. data/lib/test.rb +25 -0
  47. data/test/activerecord_provider/config/connection.rb +5 -0
  48. data/test/activerecord_provider/config/database.yml +6 -0
  49. data/test/activerecord_provider/database/ar_migration.rb +59 -0
  50. data/test/activerecord_provider/database/oaipmhtest +0 -0
  51. data/test/activerecord_provider/fixtures/dc.yml +1501 -0
  52. data/test/activerecord_provider/helpers/providers.rb +44 -0
  53. data/test/activerecord_provider/helpers/set_provider.rb +36 -0
  54. data/test/activerecord_provider/models/dc_field.rb +7 -0
  55. data/test/activerecord_provider/models/dc_set.rb +6 -0
  56. data/test/activerecord_provider/models/oai_token.rb +3 -0
  57. data/test/activerecord_provider/tc_ar_provider.rb +113 -0
  58. data/test/activerecord_provider/tc_ar_sets_provider.rb +72 -0
  59. data/test/activerecord_provider/tc_caching_paging_provider.rb +55 -0
  60. data/test/activerecord_provider/tc_simple_paging_provider.rb +57 -0
  61. data/test/activerecord_provider/test_helper.rb +4 -0
  62. data/test/client/helpers/provider.rb +68 -0
  63. data/test/client/helpers/test_wrapper.rb +11 -0
  64. data/test/client/tc_exception.rb +36 -0
  65. data/test/client/tc_get_record.rb +37 -0
  66. data/test/client/tc_identify.rb +13 -0
  67. data/test/client/tc_libxml.rb +61 -0
  68. data/test/client/tc_list_identifiers.rb +52 -0
  69. data/test/client/tc_list_metadata_formats.rb +18 -0
  70. data/test/client/tc_list_records.rb +13 -0
  71. data/test/client/tc_list_sets.rb +19 -0
  72. data/test/client/tc_low_resolution_dates.rb +14 -0
  73. data/test/client/tc_utf8_escaping.rb +11 -0
  74. data/test/client/tc_xpath.rb +26 -0
  75. data/test/client/test_helper.rb +5 -0
  76. data/test/provider/models.rb +234 -0
  77. data/test/provider/tc_exceptions.rb +96 -0
  78. data/test/provider/tc_functional_tokens.rb +43 -0
  79. data/test/provider/tc_provider.rb +71 -0
  80. data/test/provider/tc_resumption_tokens.rb +46 -0
  81. data/test/provider/tc_simple_provider.rb +92 -0
  82. data/test/provider/test_helper.rb +36 -0
  83. data/test/test.xml +22 -0
  84. metadata +181 -0
@@ -0,0 +1,44 @@
1
+ require 'active_record'
2
+ require 'oai'
3
+ require "config/connection.rb"
4
+
5
+ Dir.glob(File.dirname(__FILE__) + "/../models/*.rb").each do |lib|
6
+ require lib
7
+ end
8
+
9
+ class ARProvider < OAI::Provider::Base
10
+ repository_name 'ActiveRecord Based Provider'
11
+ repository_url 'http://localhost'
12
+ record_prefix 'oai:test'
13
+ source_model ActiveRecordWrapper.new(DCField)
14
+ end
15
+
16
+ class SimpleResumptionProvider < OAI::Provider::Base
17
+ repository_name 'ActiveRecord Resumption Provider'
18
+ repository_url 'http://localhost'
19
+ record_prefix 'oai:test'
20
+ source_model ActiveRecordWrapper.new(DCField, :limit => 25)
21
+ end
22
+
23
+ class CachingResumptionProvider < OAI::Provider::Base
24
+ repository_name 'ActiveRecord Caching Resumption Provider'
25
+ repository_url 'http://localhost'
26
+ record_prefix 'oai:test'
27
+ source_model ActiveRecordCachingWrapper.new(DCField, :limit => 25)
28
+ end
29
+
30
+
31
+ class ARLoader
32
+ def self.load
33
+ fixtures = YAML.load_file(
34
+ File.join(File.dirname(__FILE__), '..', 'fixtures', 'dc.yml')
35
+ )
36
+ fixtures.keys.sort.each do |key|
37
+ DCField.create(fixtures[key])
38
+ end
39
+ end
40
+
41
+ def self.unload
42
+ DCField.delete_all
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ # Extend ActiveRecordModel to support sets
2
+ class SetModel < OAI::Provider::ActiveRecordWrapper
3
+
4
+ # Return all available sets
5
+ def sets
6
+ DCSet.find(:all)
7
+ end
8
+
9
+ # Scope the find to a set relation if we get a set in the options
10
+ def find(selector, opts={})
11
+ if opts[:set]
12
+ set = DCSet.find_by_spec(opts.delete(:set))
13
+ conditions = sql_conditions(opts)
14
+
15
+ if :all == selector
16
+ set.dc_fields.find(selector, :conditions => conditions)
17
+ else
18
+ set.dc_fields.find(selector, :conditions => conditions)
19
+ end
20
+ else
21
+ if :all == selector
22
+ model.find(selector, :conditions => sql_conditions(opts))
23
+ else
24
+ model.find(selector, :conditions => sql_conditions(opts))
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ class ARSetProvider < OAI::Provider::Base
32
+ repository_name 'ActiveRecord Set Based Provider'
33
+ repository_url 'http://localhost'
34
+ record_prefix = 'oai:test'
35
+ source_model SetModel.new(DCField, :timestamp_field => 'date')
36
+ end
@@ -0,0 +1,7 @@
1
+ class DCField < ActiveRecord::Base
2
+ set_inheritance_column 'DONOTINHERIT'
3
+ has_and_belongs_to_many :sets,
4
+ :join_table => "dc_fields_dc_sets",
5
+ :foreign_key => "dc_field_id",
6
+ :class_name => "DCSet"
7
+ end
@@ -0,0 +1,6 @@
1
+ class DCSet < ActiveRecord::Base
2
+ has_and_belongs_to_many :dc_fields,
3
+ :join_table => "dc_fields_dc_sets",
4
+ :foreign_key => "dc_set_id",
5
+ :class_name => "DCField"
6
+ end
@@ -0,0 +1,3 @@
1
+ class OaiToken < ActiveRecord::Base
2
+ serialize :params
3
+ end
@@ -0,0 +1,113 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveRecordProviderTest < Test::Unit::TestCase
4
+
5
+ def test_identify
6
+ assert @provider.identify =~ /ActiveRecord Based Provider/
7
+ end
8
+
9
+ def test_metadata_formats
10
+ assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats) }
11
+ doc = REXML::Document.new(@provider.list_metadata_formats)
12
+ assert doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text == 'oai_dc'
13
+ end
14
+
15
+ def test_metadata_formats_for_record
16
+ record_id = DCField.find(:first).id
17
+ assert_nothing_raised { REXML::Document.new(@provider.list_metadata_formats(:identifier => "oai:test/#{record_id}")) }
18
+ doc = REXML::Document.new(@provider.list_metadata_formats)
19
+ assert doc.elements['/OAI-PMH/ListMetadataFormats/metadataFormat/metadataPrefix'].text == 'oai_dc'
20
+ end
21
+
22
+ def test_list_records
23
+ assert_nothing_raised { REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc')) }
24
+ doc = REXML::Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
25
+ assert_equal 100, doc.elements['OAI-PMH/ListRecords'].to_a.size
26
+ end
27
+
28
+ def test_list_identifiers
29
+ assert_nothing_raised { REXML::Document.new(@provider.list_identifiers(:metadata_prefix => 'oai_dc')) }
30
+ doc = REXML::Document.new(@provider.list_identifiers(:metadata_prefix => 'oai_dc'))
31
+ assert_equal 100, doc.elements['OAI-PMH/ListIdentifiers'].to_a.size
32
+ end
33
+
34
+ def test_get_record
35
+ record_id = DCField.find(:first).id
36
+ assert_nothing_raised { REXML::Document.new(@provider.get_record(:identifier => "oai:test/#{record_id}", :metadata_prefix => 'oai_dc')) }
37
+ doc = REXML::Document.new(@provider.get_record(:identifier => "#{record_id}", :metadata_prefix => 'oai_dc'))
38
+ assert_equal "oai:test/#{record_id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
39
+ end
40
+
41
+ def test_deleted
42
+ record = DCField.find(:first)
43
+ record.deleted = true;
44
+ record.save
45
+ doc = REXML::Document.new(@provider.get_record(:identifier => "oai:test/#{record.id}", :metadata_prefix => 'oai_dc'))
46
+ assert_equal "oai:test/#{record.id}", doc.elements['OAI-PMH/GetRecord/record/header/identifier'].text
47
+ assert_equal 'deleted', doc.elements['OAI-PMH/GetRecord/record/header'].attributes["status"]
48
+ end
49
+
50
+ def test_from
51
+ first_id = DCField.find(:first, :order => "id asc").id
52
+ DCField.update_all(['updated_at = ?', Time.parse("January 1 2005")],
53
+ "id < #{first_id + 90}")
54
+ DCField.update_all(['updated_at = ?', Time.parse("June 1 2005")],
55
+ "id < #{first_id + 10}")
56
+
57
+ from_param = Time.parse("January 1 2006")
58
+
59
+ doc = REXML::Document.new(
60
+ @provider.list_records(:from => from_param, :metadata_prefix => 'oai_dc')
61
+ )
62
+ assert_equal DCField.find(:all, :conditions => ["updated_at >= ?", from_param]).size,
63
+ doc.elements['OAI-PMH/ListRecords'].size
64
+
65
+ doc = REXML::Document.new(
66
+ @provider.list_records(:from => Time.parse("May 30 2005"), :metadata_prefix => 'oai_dc')
67
+ )
68
+ assert_equal 20, doc.elements['OAI-PMH/ListRecords'].to_a.size
69
+ end
70
+
71
+ def test_until
72
+ first_id = DCField.find(:first, :order => "id asc").id
73
+ DCField.update_all(['updated_at = ?', Time.parse("June 1 2005")],
74
+ "id < #{first_id + 10}")
75
+
76
+ doc = REXML::Document.new(
77
+ @provider.list_records(:until => Time.parse("June 1 2005"), :metadata_prefix => 'oai_dc')
78
+ )
79
+ assert_equal 10, doc.elements['OAI-PMH/ListRecords'].to_a.size
80
+ end
81
+
82
+ def test_from_and_until
83
+ first_id = DCField.find(:first, :order => "id asc").id
84
+ DCField.update_all(['updated_at = ?', Time.parse("June 1 2005")])
85
+ DCField.update_all(['updated_at = ?', Time.parse("June 15 2005")],
86
+ "id < #{first_id + 50}")
87
+ DCField.update_all(['updated_at = ?', Time.parse("June 30 2005")],
88
+ "id < #{first_id + 10}")
89
+
90
+ doc = REXML::Document.new(
91
+ @provider.list_records(:from => Time.parse("June 3 2005"),
92
+ :until => Time.parse("June 16 2005"), :metadata_prefix => 'oai_dc')
93
+ )
94
+ assert_equal 40, doc.elements['OAI-PMH/ListRecords'].to_a.size
95
+ end
96
+
97
+ def test_bad_identifier_raises_correct_exception
98
+ assert_raise(OAI::IdException) do
99
+ @provider.get_record( :identifier => "fjsdklf",
100
+ :metadataPrefix => "oai_dc")
101
+ end
102
+ end
103
+
104
+ def setup
105
+ @provider = ARProvider.new
106
+ ARLoader.load
107
+ end
108
+
109
+ def teardown
110
+ ARLoader.unload
111
+ end
112
+
113
+ end
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveRecordSetProviderTest < Test::Unit::TestCase
4
+
5
+ def test_list_sets
6
+ doc = REXML::Document.new(@provider.list_sets)
7
+ sets = doc.elements["/OAI-PMH/ListSets"]
8
+ assert sets.size == 4
9
+ assert sets[0].elements["//setName"].text == "Set A"
10
+ end
11
+
12
+ def test_set_a
13
+ doc = REXML::Document.new(@provider.list_records(:set => "A", :metadata_prefix => 'oai_dc'))
14
+ assert_equal 20, doc.elements['OAI-PMH/ListRecords'].to_a.size
15
+ end
16
+
17
+ def test_set_b
18
+ doc = REXML::Document.new(@provider.list_records(:set => "B", :metadata_prefix => 'oai_dc'))
19
+ assert_equal 10, doc.elements['OAI-PMH/ListRecords'].to_a.size
20
+ end
21
+
22
+ def test_set_ab
23
+ doc = REXML::Document.new(@provider.list_records(:set => "A:B", :metadata_prefix => 'oai_dc'))
24
+ assert_equal 10, doc.elements['OAI-PMH/ListRecords'].to_a.size
25
+ end
26
+
27
+ def test_record_with_multiple_sets
28
+ record = DCSet.find(:first, :conditions => "spec = 'C'").dc_fields.first
29
+ assert_equal 2, record.sets.size
30
+ end
31
+
32
+ def setup
33
+ @provider = ARSetProvider.new
34
+ ARLoader.load
35
+ define_sets
36
+ end
37
+
38
+ def teardown
39
+ ARLoader.unload
40
+ DCSet.connection.execute("delete from dc_fields_dc_sets")
41
+ DCSet.delete_all
42
+ end
43
+
44
+ def define_sets
45
+ set_a = DCSet.create(:name => "Set A", :spec => "A")
46
+ set_b = DCSet.create(:name => "Set B", :spec => "B")
47
+ set_c = DCSet.create(:name => "Set C", :spec => "C")
48
+ set_ab = DCSet.create(:name => "Set A:B", :spec => "A:B")
49
+
50
+ next_id = 0
51
+ DCField.find(:all, :limit => 10, :order => "id asc").each do |record|
52
+ set_a.dc_fields << record
53
+ next_id = record.id
54
+ end
55
+
56
+ DCField.find(:all, :limit => 10, :order => "id asc", :conditions => "id > #{next_id}").each do |record|
57
+ set_b.dc_fields << record
58
+ next_id = record.id
59
+ end
60
+
61
+ DCField.find(:all, :limit => 10, :order => "id asc", :conditions => "id > #{next_id}").each do |record|
62
+ set_ab.dc_fields << record
63
+ next_id = record.id
64
+ end
65
+
66
+ DCField.find(:all, :limit => 10, :order => "id asc", :conditions => "id > #{next_id}").each do |record|
67
+ set_a.dc_fields << record
68
+ set_c.dc_fields << record
69
+ next_id = record.id
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class CachingPagingProviderTest < Test::Unit::TestCase
4
+ include REXML
5
+
6
+ def test_full_harvest
7
+ doc = Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
8
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
9
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].size
10
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
11
+ doc = Document.new(@provider.list_records(:resumption_token => token))
12
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
13
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
14
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].size
15
+ doc = Document.new(@provider.list_records(:resumption_token => token))
16
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
17
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
18
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].size
19
+ doc = Document.new(@provider.list_records(:resumption_token => token))
20
+ assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
21
+ assert_equal 25, doc.elements["/OAI-PMH/ListRecords"].size
22
+ end
23
+
24
+ def test_from_and_until
25
+ first_id = DCField.find(:first, :order => "id asc").id
26
+ DCField.update_all(['updated_at = ?', Time.parse("September 15 2005")],
27
+ "id <= #{first_id + 25}")
28
+ DCField.update_all(['updated_at = ?', Time.parse("November 1 2005")],
29
+ "id < #{first_id + 50} and id > #{first_id + 25}")
30
+
31
+ # Should return 50 records broken into 2 groups of 25.
32
+ doc = Document.new(
33
+ @provider.list_records(
34
+ :from => Time.parse("September 1 2005"),
35
+ :until => Time.parse("November 30 2005"),
36
+ :metadata_prefix => 'oai_dc')
37
+ )
38
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].size
39
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
40
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
41
+ doc = Document.new(@provider.list_records(:resumption_token => token))
42
+ assert_equal 25, doc.elements["/OAI-PMH/ListRecords"].size
43
+ assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
44
+ end
45
+
46
+ def setup
47
+ @provider = CachingResumptionProvider.new
48
+ ARLoader.load
49
+ end
50
+
51
+ def teardown
52
+ ARLoader.unload
53
+ end
54
+
55
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class SimpleResumptionProviderTest < Test::Unit::TestCase
4
+ include REXML
5
+
6
+ def test_full_harvest
7
+ doc = Document.new(@provider.list_records(:metadata_prefix => 'oai_dc'))
8
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
9
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
10
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
11
+ doc = Document.new(@provider.list_records(:resumption_token => token))
12
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
13
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
14
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
15
+ doc = Document.new(@provider.list_records(:resumption_token => token))
16
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
17
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
18
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
19
+ doc = Document.new(@provider.list_records(:resumption_token => token))
20
+ assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
21
+ assert_equal 25, doc.elements["/OAI-PMH/ListRecords"].to_a.size
22
+ end
23
+
24
+ def test_from_and_until
25
+ first_id = DCField.find(:first, :order => "id asc").id
26
+ DCField.update_all(['updated_at = ?', Time.parse("September 15 2005")],
27
+ "id < #{first_id + 25}")
28
+ DCField.update_all(['updated_at = ?', Time.parse("November 1 2005")],
29
+ "id <= #{first_id + 50} and id > #{first_id + 25}")
30
+
31
+ total = DCField.count(:id, :conditions => ["updated_at >= ? AND updated_at <= ?", Time.parse("September 1 2005"), Time.parse("November 30 2005")])
32
+
33
+ # Should return 50 records broken into 2 groups of 25.
34
+ doc = Document.new(
35
+ @provider.list_records(
36
+ :from => Time.parse("September 1 2005"),
37
+ :until => Time.parse("November 30 2005"),
38
+ :metadata_prefix => 'oai_dc')
39
+ )
40
+ assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
41
+ assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
42
+ token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
43
+ doc = Document.new(@provider.list_records(:resumption_token => token))
44
+ assert_equal 25, doc.elements["/OAI-PMH/ListRecords"].to_a.size
45
+ assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
46
+ end
47
+
48
+ def setup
49
+ @provider = SimpleResumptionProvider.new
50
+ ARLoader.load
51
+ end
52
+
53
+ def teardown
54
+ ARLoader.unload
55
+ end
56
+
57
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/helpers/providers'
4
+ require File.dirname(__FILE__) + '/helpers/set_provider'
@@ -0,0 +1,68 @@
1
+ require 'webrick'
2
+ require File.dirname(__FILE__) + '/../../provider/models'
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
+
11
+ class ProviderServer < WEBrick::HTTPServlet::AbstractServlet
12
+ @@server = nil
13
+
14
+ def initialize(server)
15
+ super(server)
16
+ @provider = ComplexProvider.new
17
+ end
18
+
19
+ def do_GET(req, res)
20
+ begin
21
+ res.body = @provider.process_request(req.query)
22
+ res.status = 200
23
+ res['Content-Type'] = 'text/xml'
24
+ rescue => err
25
+ puts err
26
+ puts err.backtrace.join("\n")
27
+ res.body = err.backtrace.join("\n")
28
+ res.status = 500
29
+ end
30
+ end
31
+
32
+ def self.start(port)
33
+ unless @@server
34
+ @@server = WEBrick::HTTPServer.new(
35
+ :BindAddress => '127.0.0.1',
36
+ :Logger => WEBrick::Log.new('/dev/null'),
37
+ :AccessLog => [],
38
+ :Port => port)
39
+ @@server.mount("/oai", ProviderServer)
40
+
41
+ trap("INT") { @@server.shutdown }
42
+ @@thread = Thread.new { @@server.start }
43
+ puts "Starting Webrick/Provider on port[#{port}]"
44
+ end
45
+ end
46
+
47
+ def self.stop
48
+ puts "Stopping Webrick/Provider"
49
+ if @@thread
50
+ @@thread.exit
51
+ end
52
+ end
53
+
54
+ def self.wrap(port = 3333)
55
+ begin
56
+ start(port)
57
+
58
+ # Wait for startup
59
+ sleep 2
60
+
61
+ yield
62
+
63
+ ensure
64
+ stop
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,11 @@
1
+ module Test::Unit
2
+ class AutoRunner
3
+ alias_method :real_run, :run
4
+
5
+ def run
6
+ ProviderServer.wrap { real_run }
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class ExceptionTest < Test::Unit::TestCase
4
+
5
+ def test_not_found
6
+ client = OAI::Client.new 'http://www.google.com'
7
+ assert_raises(ArgumentError) { client.identify }
8
+ end
9
+
10
+ def test_xml_error
11
+ client = OAI::Client.new 'http://www.yahoo.com'
12
+ begin
13
+ client.identify
14
+ rescue OAI::Exception => e
15
+ assert_match /response not well formed XML/, e.to_s, 'xml error'
16
+ end
17
+ end
18
+
19
+ def test_oai_error
20
+ client = OAI::Client.new 'http://localhost:3333/oai'
21
+ assert_raises(OAI::Exception) do
22
+ client.list_identifiers :resumption_token => 'bogus'
23
+ end
24
+ end
25
+
26
+ # must pass in options as a hash
27
+ def test_parameter_error
28
+ client = OAI::Client.new 'http://localhost:3333/oai'
29
+ assert_raises(OAI::ArgumentException) {client.get_record('foo')}
30
+ assert_raises(OAI::ArgumentException) {client.list_identifiers('foo')}
31
+ assert_raises(OAI::ArgumentException) {client.list_records('foo')}
32
+ assert_raises(OAI::ArgumentException) {client.list_metadata_formats('foo')}
33
+ assert_raises(OAI::ArgumentException) {client.list_sets('foo')}
34
+ end
35
+
36
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ class GetRecordTest < Test::Unit::TestCase
4
+
5
+ def test_get_one
6
+ client = OAI::Client.new 'http://localhost:3333/oai'
7
+ response = client.get_record :identifier => 'oai:test/3'
8
+ assert_kind_of OAI::GetRecordResponse, response
9
+ assert_kind_of OAI::Record, response.record
10
+ assert_kind_of REXML::Element, response.record.metadata
11
+ assert_kind_of OAI::Header, response.record.header
12
+
13
+ # minimal check that the header is working
14
+ assert_equal 'oai:test/3',
15
+ response.record.header.identifier
16
+
17
+ # minimal check that the metadata is working
18
+ #assert 'en', response.record.metadata.elements['.//dc:language'].text
19
+ end
20
+
21
+ def test_missing_identifier
22
+ client = OAI::Client.new 'http://localhost:3333/oai'
23
+ begin
24
+ client.get_record :metadata_prefix => 'oai_dc'
25
+ flunk 'invalid get_record did not throw OAI::Exception'
26
+ rescue OAI::Exception => e
27
+ assert_match /The request includes illegal arguments/, e.to_s
28
+ end
29
+ end
30
+
31
+ def test_deleted_record
32
+ client = OAI::Client.new 'http://localhost:3333/oai'
33
+ record = client.get_record :identifier => 'oai:test/275'
34
+ assert record.deleted?
35
+ end
36
+
37
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ class IdentifyTest < Test::Unit::TestCase
4
+
5
+ def test_ok
6
+ client = OAI::Client.new 'http://localhost:3333/oai'
7
+ response = client.identify
8
+ assert_kind_of OAI::IdentifyResponse, response
9
+ assert_equal 'Complex Provider [http://localhost]', response.to_s
10
+ #assert_equal 'PubMed Central (PMC3 - NLM DTD) [http://www.pubmedcentral.gov/oai/oai.cgi]', response.to_s
11
+ end
12
+
13
+ end
@@ -0,0 +1,61 @@
1
+ require 'test_helper'
2
+
3
+ class LibXMLTest < Test::Unit::TestCase
4
+
5
+ def test_oai_exception
6
+ return unless have_libxml
7
+
8
+ uri = 'http://localhost:3333/oai'
9
+ client = OAI::Client.new uri, :parser => 'libxml'
10
+ assert_raises(OAI::Exception) {client.get_record(:identifier => 'nosuchid')}
11
+ end
12
+
13
+ def test_list_records
14
+ return unless have_libxml
15
+
16
+ # since there is regex magic going on to remove default oai namespaces
17
+ # it's worth trying a few different oai targets
18
+ oai_targets = %w{
19
+ http://localhost:3333/oai
20
+ }
21
+
22
+ #oai_targets = %w{
23
+ # http://etd.caltech.edu:80/ETD-db/OAI/oai
24
+ # http://ir.library.oregonstate.edu/dspace-oai/request
25
+ # http://memory.loc.gov/cgi-bin/oai2_0
26
+ # http://libeprints.open.ac.uk/perl/oai2
27
+ #}
28
+
29
+
30
+ oai_targets.each do |uri|
31
+ client = OAI::Client.new uri, :parser => 'libxml'
32
+ records = client.list_records
33
+ records.each do |record|
34
+ assert record.header.identifier
35
+ next if record.deleted?
36
+ assert_kind_of LibXML::XML::Node, record.metadata
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_deleted_record
42
+ return unless have_libxml
43
+
44
+ uri = 'http://localhost:3333/oai'
45
+ client = OAI::Client.new(uri, :parser => 'libxml')
46
+ response = client.get_record :identifier => 'oai:test/275'
47
+ assert response.record.deleted?
48
+ end
49
+
50
+ private
51
+
52
+ def have_libxml
53
+ begin
54
+ require 'xml/libxml'
55
+ return true
56
+ rescue LoadError
57
+ return false
58
+ end
59
+ end
60
+
61
+ end