Skip to content

Commit cbf2699

Browse files
committed
Implement tests for oai-pmh ingestor
1 parent 0080133 commit cbf2699

2 files changed

Lines changed: 198 additions & 10 deletions

File tree

lib/ingestors/oai_pmh_ingestor.rb

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ def read_oai_dublin_core(client)
6060

6161
def read_dublin_core_material(xml_doc)
6262
material = OpenStruct.new
63-
material.title = xml_doc.at_xpath('//dc:title', ns)&.text
63+
material.title = xml_doc.at_xpath('//dc:title', ns)&.text
64+
puts xml_doc.at_xpath('//dc:description', ns)&.text
6465
material.description = convert_description(xml_doc.at_xpath('//dc:description', ns)&.text)
6566
material.authors = xml_doc.xpath('//dc:creator', ns).map(&:text)
6667
material.contributors = xml_doc.xpath('//dc:contributor', ns).map(&:text)
@@ -92,18 +93,18 @@ def read_dublin_core_material(xml_doc)
9293
add_material material
9394
end
9495

95-
def read_dublin_core_event(_xml_doc)
96+
def read_dublin_core_event(xml_doc)
9697
event = OpenStruct.new
9798

98-
event.title = doc.at_xpath('//dc:title', ns)&.text
99-
event.description = convert_description(doc.at_xpath('//dc:description', ns)&.text)
100-
event.url = doc.xpath('//dc:identifier', ns).map(&:text).find { |id| id.start_with?('http://', 'https://') }
101-
event.contact = doc.at_xpath('//dc:publisher', ns)&.text
102-
event.organizer = doc.at_xpath('//dc:creator', ns)&.text
103-
event.keywords = doc.xpath('//dc:subject', ns).map(&:text)
104-
event.event_types = doc.xpath('//dc:type', ns).map(&:text)
99+
event.title = xml_doc.at_xpath('//dc:title', ns)&.text
100+
event.description = convert_description(xml_doc.at_xpath('//dc:description', ns)&.text)
101+
event.url = xml_doc.xpath('//dc:identifier', ns).map(&:text).find { |id| id.start_with?('http://', 'https://') }
102+
event.contact = xml_doc.at_xpath('//dc:publisher', ns)&.text
103+
event.organizer = xml_doc.at_xpath('//dc:creator', ns)&.text
104+
event.keywords = xml_doc.xpath('//dc:subject', ns).map(&:text)
105+
event.event_types = xml_doc.xpath('//dc:type', ns).map(&:text)
105106

106-
dates = doc.xpath('//dc:date', ns).map(&:text)
107+
dates = xml_doc.xpath('//dc:date', ns).map(&:text)
107108
parsed_dates = dates.map do |d|
108109
Date.parse(d)
109110
rescue StandardError
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
require 'test_helper'
2+
3+
class FakeClient
4+
def initialize(rdf_strings, dc_strings)
5+
@rdf_response = Minitest::Mock.new
6+
rdf_response = rdf_strings.map do |s|
7+
inner_mock = Minitest::Mock.new
8+
outer_mock = Minitest::Mock.new
9+
inner_mock.expect(:metadata, outer_mock, [])
10+
outer_mock.expect(:to_s, s, [])
11+
inner_mock
12+
end
13+
dc_response = dc_strings.map do |s|
14+
inner_mock = Minitest::Mock.new
15+
outer_mock = Minitest::Mock.new
16+
inner_mock.expect(:metadata, outer_mock, [])
17+
outer_mock.expect(:to_s, s, [])
18+
inner_mock
19+
end
20+
@rdf_response.expect(:full, rdf_response, [])
21+
@dc_response = Minitest::Mock.new
22+
@dc_response.expect(:full, dc_response, [])
23+
end
24+
25+
def list_records(metadata_prefix: nil)
26+
if metadata_prefix == 'rdf'
27+
@rdf_response
28+
else
29+
@dc_response
30+
end
31+
end
32+
end
33+
34+
class OaiPmhTest < ActiveSupport::TestCase
35+
setup do
36+
@ingestor = Ingestors::OaiPmhIngestor.new
37+
@user = users(:regular_user)
38+
@content_provider = content_providers(:another_portal_provider)
39+
end
40+
41+
test 'should read empty oai pmh endpoint' do
42+
OAI::Client.stub(:new, FakeClient.new([], [])) do
43+
@ingestor.read('https://example.org')
44+
end
45+
assert_equal @ingestor.materials, []
46+
assert_equal @ingestor.events, []
47+
end
48+
49+
test 'should read dublin core material' do
50+
record = <<~METADATA
51+
<metadata>
52+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
53+
<dc:title>dc_title</dc:title>
54+
<dc:description>dc_description &lt;b&gt;bold_text&lt;/b&gt;</dc:description>
55+
<dc:creator>A, Alice</dc:creator>
56+
<dc:creator>B, Bob</dc:creator>
57+
<dc:rights></dc:rights>
58+
<dc:rights>public access</dc:rights>
59+
<dc:rights>https://opensource.org/licenses/MIT</dc:rights>
60+
<dc:date>2023-06-26</dc:date>
61+
<dc:date>2026-06-26</dc:date>
62+
<dc:identifier>https://rodare.hzdr.de/record/2513</dc:identifier>
63+
<dc:identifier>10.14278/rodare.2269</dc:identifier>
64+
<dc:subject>kA</dc:subject>
65+
<dc:subject>kB</dc:subject>
66+
<dc:subject>kC</dc:subject>
67+
</oai_dc:dc>
68+
</metadata>
69+
METADATA
70+
71+
OAI::Client.stub(:new, FakeClient.new([], [record])) do
72+
@ingestor.read('https://example.org')
73+
end
74+
result = @ingestor.materials.first
75+
76+
assert_equal 'dc_title', result.title
77+
assert_equal 'dc\\_description **bold\\_text**', result.description
78+
assert_equal ['A, Alice', 'B, Bob'], result.authors
79+
assert_equal 'https://opensource.org/licenses/MIT', result.licence
80+
assert_equal Date.parse('2023-06-26'), result.date_created
81+
assert_equal Date.parse('2026-06-26'), result.date_modified
82+
assert_equal 'https://doi.org/10.14278/rodare.2269', result.doi
83+
assert_equal 'https://rodare.hzdr.de/record/2513', result.url
84+
assert_equal %w[kA kB kC], result.keywords
85+
end
86+
87+
test 'should read dublin core event' do
88+
record = <<~METADATA
89+
<metadata>
90+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
91+
<dc:type>http://purl.org/dc/dcmitype/Event</dc:type>
92+
<dc:title>dc_title</dc:title>
93+
<dc:description>dc_description &lt;b&gt;bold_text&lt;/b&gt;</dc:description>
94+
<dc:identifier>https://example.org/dc_url</dc:identifier>
95+
<dc:creator>A, Alice</dc:creator>
96+
<dc:creator>B, Bob</dc:creator>
97+
<dc:subject>kA</dc:subject>
98+
<dc:subject>kB</dc:subject>
99+
<dc:subject>kC</dc:subject>
100+
<dc:date>2026-01-01</dc:date>
101+
<dc:date>2026-01-02</dc:date>
102+
</oai_dc:dc>
103+
</metadata>
104+
METADATA
105+
106+
OAI::Client.stub(:new, FakeClient.new([], [record])) do
107+
@ingestor.read('https://example.org')
108+
end
109+
result = @ingestor.events.first
110+
111+
assert_equal 'dc_title', result.title
112+
assert_equal 'dc\\_description **bold\\_text**', result.description
113+
assert_equal 'https://example.org/dc_url', result.url
114+
assert_equal 'A, Alice', result.organizer
115+
assert_equal %w[kA kB kC], result.keywords
116+
assert_equal Date.parse('2026-01-01'), result.start
117+
assert_equal Date.parse('2026-01-02'), result.end
118+
end
119+
120+
test 'should read multiple dublin core events and materials' do
121+
event1 = <<~METADATA
122+
<metadata>
123+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
124+
<dc:type>http://purl.org/dc/dcmitype/Event</dc:type>
125+
<dc:title>title1</dc:title>
126+
</oai_dc:dc>
127+
</metadata>
128+
METADATA
129+
130+
event2 = <<~METADATA
131+
<metadata>
132+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
133+
<dc:type>http://purl.org/dc/dcmitype/Event</dc:type>
134+
<dc:title>title2</dc:title>
135+
</oai_dc:dc>
136+
</metadata>
137+
METADATA
138+
139+
material1 = <<~METADATA
140+
<metadata>
141+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
142+
<dc:title>title3</dc:title>
143+
</oai_dc:dc>
144+
</metadata>
145+
METADATA
146+
147+
material2 = <<~METADATA
148+
<metadata>
149+
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
150+
<dc:title>title4</dc:title>
151+
</oai_dc:dc>
152+
</metadata>
153+
METADATA
154+
155+
OAI::Client.stub(:new, FakeClient.new([], [material1, material2, event1, event2])) do
156+
@ingestor.read('https://example.org')
157+
end
158+
159+
assert_equal %w[title1 title2], @ingestor.events.map(&:title)
160+
assert_equal %w[title3 title4], @ingestor.materials.map(&:title)
161+
end
162+
163+
test 'should read bioschemas' do
164+
# TODO: add event and maybe course and course instance
165+
material = <<~METADATA
166+
<metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sdo="http://schema.org/" xmlns:dc="http://purl.org/dc/terms/">
167+
<sdo:LearningResource rdf:about="https://pan-training.eu/materials/python-laser-image-visualization">
168+
<dc:conformsTo>
169+
<sdo:CreativeWork rdf:about="https://bioschemas.org/profiles/TrainingMaterial/1.0-RELEASE">
170+
</sdo:CreativeWork>
171+
</dc:conformsTo>
172+
<sdo:name>bioschemas title</sdo:name>
173+
<sdo:url rdf:resource="https://example.org/bioschemas/material"/>
174+
</sdo:LearningResource>
175+
</rdf:RDF></metadata>
176+
METADATA
177+
178+
OAI::Client.stub(:new, FakeClient.new([material, material], [])) do
179+
@ingestor.read('https://example.org')
180+
end
181+
182+
assert_equal 1, @ingestor.materials.length
183+
result = @ingestor.materials.first
184+
assert_equal 'bioschemas title', result.title
185+
assert_equal 'https://example.org/bioschemas/material', result.url
186+
end
187+
end

0 commit comments

Comments
 (0)