blacklight_oai_provider 0.1.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +39 -0
- data/.rubocop_todo.yml +130 -0
- data/.solr_wrapper +8 -0
- data/.travis.yml +16 -0
- data/Gemfile +34 -2
- data/README.md +131 -0
- data/Rakefile +25 -0
- data/VERSION +1 -1
- data/app/assets/{xsl → stylesheets/blacklight_oai_provider}/oai2.xsl +12 -5
- data/app/controllers/concerns/blacklight_oai_provider/controller.rb +38 -0
- data/app/models/concerns/blacklight_oai_provider/solr_document.rb +23 -0
- data/blacklight_oai_provider.gemspec +17 -10
- data/config/initializers/oai_patches.rb +20 -0
- data/lib/blacklight_oai_provider/engine.rb +15 -2
- data/lib/blacklight_oai_provider/exceptions.rb +9 -0
- data/lib/blacklight_oai_provider/resumption_token.rb +51 -0
- data/lib/blacklight_oai_provider/routes.rb +15 -0
- data/lib/blacklight_oai_provider/solr_document_provider.rb +2 -2
- data/lib/blacklight_oai_provider/solr_document_wrapper.rb +55 -27
- data/lib/blacklight_oai_provider/version.rb +1 -2
- data/lib/blacklight_oai_provider.rb +16 -14
- data/lib/generators/blacklight_oai_provider/install_generator.rb +27 -0
- data/lib/railties/blacklight_oai_provider.rake +14 -0
- data/solr/conf/_rest_managed.json +3 -0
- data/solr/conf/admin-extra.html +31 -0
- data/solr/conf/elevate.xml +36 -0
- data/solr/conf/mapping-ISOLatin1Accent.txt +246 -0
- data/solr/conf/protwords.txt +21 -0
- data/solr/conf/schema.xml +629 -0
- data/solr/conf/scripts.conf +24 -0
- data/solr/conf/solrconfig.xml +401 -0
- data/solr/conf/spellings.txt +2 -0
- data/solr/conf/stopwords.txt +58 -0
- data/solr/conf/stopwords_en.txt +58 -0
- data/solr/conf/synonyms.txt +31 -0
- data/solr/conf/xslt/example.xsl +132 -0
- data/solr/conf/xslt/example_atom.xsl +67 -0
- data/solr/conf/xslt/example_rss.xsl +66 -0
- data/solr/conf/xslt/luke.xsl +337 -0
- data/solr/sample_solr_documents.yml +2722 -0
- data/spec/controllers/catalog_controller_spec.rb +39 -0
- data/spec/features/html_rendering_spec.rb +24 -0
- data/spec/models/solr_document_spec.rb +43 -0
- data/spec/requests/get_record_spec.rb +47 -0
- data/spec/requests/identify_spec.rb +53 -0
- data/spec/requests/list_identifiers_spec.rb +80 -0
- data/spec/requests/list_metadata_formats_spec.rb +43 -0
- data/spec/requests/list_records_spec.rb +126 -0
- data/spec/spec_helper.rb +15 -38
- data/spec/test_app_templates/config/solr.yml +9 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +86 -0
- metadata +146 -87
- data/Gemfile.lock +0 -187
- data/README.rdoc +0 -74
- data/config/routes.rb +0 -5
- data/lib/blacklight_oai_provider/README.rdoc +0 -0
- data/lib/blacklight_oai_provider/controller_extension.rb +0 -29
- data/lib/blacklight_oai_provider/route_sets.rb +0 -13
- data/lib/blacklight_oai_provider/solr_document_extension.rb +0 -10
- data/lib/generators/blacklight_oai_provider/blacklight_oai_provider_generator.rb +0 -27
- data/spec/acceptance/blacklight_oai_provider_spec.rb +0 -49
- data/spec/integration/blacklight_stub_spec.rb +0 -10
- data/spec/internal/app/controllers/application_controller.rb +0 -4
- data/spec/internal/app/models/solr_document.rb +0 -3
- data/spec/internal/config/database.yml +0 -3
- data/spec/internal/config/routes.rb +0 -6
- data/spec/internal/config/solr.yml +0 -18
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +0 -53
- data/spec/internal/log/.gitignore +0 -1
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/solr_document_extension_spec.rb +0 -6
- data/spec/vcr_cassettes/solr.yml +0 -113
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CatalogController do
|
4
|
+
it "has a Blacklight module" do
|
5
|
+
expect(Blacklight).to be_a_kind_of Module
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'has blacklight configuration' do
|
9
|
+
expect(described_class.blacklight_config).to be_a_kind_of Blacklight::Configuration
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#oai' do
|
13
|
+
it 'responds to oai' do
|
14
|
+
expect(controller).to respond_to :oai
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#oai_config' do
|
19
|
+
it 'returns correct configuration' do
|
20
|
+
expect(controller.oai_config).to match(
|
21
|
+
provider: {
|
22
|
+
repository_name: "Test Repository",
|
23
|
+
repository_url: "http://localhost",
|
24
|
+
record_prefix: "oai:test",
|
25
|
+
admin_email: "root@localhost",
|
26
|
+
deletion_support: "persistent",
|
27
|
+
sample_id: "109660"
|
28
|
+
},
|
29
|
+
document: { model: SolrDocument, limit: 25 }
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#oai_provider' do
|
35
|
+
it 'returns BlacklightOaiProvider::SolrDocumentProvider' do
|
36
|
+
expect(controller.oai_provider).to be_a BlacklightOaiProvider::SolrDocumentProvider
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Spot checking a few pages to ensure that the stylesheet is rendered correctly in browser.
|
4
|
+
describe 'HTML page rendering', js: true do
|
5
|
+
it "root page" do
|
6
|
+
visit '/catalog/oai'
|
7
|
+
expect(page).to have_content 'not a legal OAI-PMH verb'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "identify page" do
|
11
|
+
visit '/catalog/oai?verb=Identify'
|
12
|
+
expect(page).to have_xpath('//td[text()="Earliest Datestamp"]/parent::*/td[@class="value"]', text: '2014-02-03T18:42:53Z')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "lists records" do
|
16
|
+
visit '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc'
|
17
|
+
expect(page).to have_content('OAI Record: oai:test:00282214')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "document page" do
|
21
|
+
visit '/catalog/oai?verb=GetRecord&identifier=00282214&metadataPrefix=oai_dc'
|
22
|
+
expect(page).to have_xpath('//td[text()="Title"]/parent::*/td[@class="value"]', text: 'Fikr-i Ayāz')
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SolrDocument do
|
4
|
+
it 'includes BlacklightOaiProvider::SolrDocument' do
|
5
|
+
expect(described_class.ancestors.include?(BlacklightOaiProvider::SolrDocument)).to be true
|
6
|
+
end
|
7
|
+
|
8
|
+
subject(:document) { described_class.new }
|
9
|
+
|
10
|
+
describe '#timestamp' do
|
11
|
+
it 'responds to timestamp' do
|
12
|
+
expect(document).to respond_to :timestamp
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'throws error if timestamp field not available' do
|
16
|
+
expect {
|
17
|
+
document.timestamp
|
18
|
+
}.to raise_error BlacklightOaiProvider::Exceptions::MissingTimestamp
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns timestamp' do
|
22
|
+
doc = described_class.new({ timestamp: '2017-10-16T19:20:14Z' })
|
23
|
+
expect(doc.timestamp).to be_a Time
|
24
|
+
expect(doc.timestamp.xmlschema).to eql '2017-10-16T19:20:14Z'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#to_oai_dc' do
|
29
|
+
let(:valid_xml) do
|
30
|
+
'<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" '\
|
31
|
+
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ '\
|
32
|
+
'http://www.openarchives.org/OAI/2.0/oai_dc.xsd"></oai_dc:dc>'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'responds to to_oai_dc' do
|
36
|
+
expect(document).to respond_to :to_oai_dc
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns xml document" do
|
40
|
+
expect(document.to_oai_dc).to eql valid_xml
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'OIA-PMH GetRecord Request' do
|
4
|
+
let(:xml) { Nokogiri::XML(response.body) }
|
5
|
+
let(:namespaces) do
|
6
|
+
{
|
7
|
+
dc: 'http://purl.org/dc/elements/1.1/',
|
8
|
+
xmlns: 'http://www.openarchives.org/OAI/2.0/',
|
9
|
+
oai_dc: 'http://www.openarchives.org/OAI/2.0/oai_dc/'
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
get '/catalog/oai?verb=GetRecord&identifier=2007020969&metadataPrefix=oai_dc'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'contains header information' do
|
18
|
+
expect(xml.at_xpath('//xmlns:GetRecord/xmlns:record/xmlns:header/xmlns:identifier').text).to eql 'oai:test:2007020969'
|
19
|
+
expect(xml.at_xpath('//xmlns:GetRecord/xmlns:record/xmlns:header/xmlns:datestamp').text).to eql '2014-02-03T18:42:53Z'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'contains creator' do
|
23
|
+
expect(xml.at_xpath('//xmlns:metadata/oai_dc:dc/dc:creator', namespaces).text).to eql 'Hearth, Amy Hill, 1958-'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'contains date' do
|
27
|
+
expect(xml.at_xpath('//xmlns:metadata/oai_dc:dc/dc:date', namespaces).text).to eql '2008'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'contains subjects' do
|
31
|
+
nodes = xml.xpath('//xmlns:metadata/oai_dc:dc/dc:subject', namespaces)
|
32
|
+
expect(nodes.count).to be 4
|
33
|
+
expect(nodes.map(&:text)).to match_array ['Strong Medicine, 1922-', 'Delaware women', 'Indian women shamans', 'Delaware Indians']
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'contains title' do
|
37
|
+
expect(xml.at_xpath('//xmlns:metadata/oai_dc:dc/dc:title', namespaces).text).to eql '"Strong Medicine speaks"'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'contains language' do
|
41
|
+
expect(xml.at_xpath('//xmlns:metadata/oai_dc:dc/dc:language', namespaces).text).to eql 'English'
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'contains format' do
|
45
|
+
expect(xml.at_xpath('//xmlns:metadata/oai_dc:dc/dc:format', namespaces).text).to eql 'Book'
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'OIA-PMH Identify Request' do
|
4
|
+
let(:xml) { Nokogiri::XML(response.body) }
|
5
|
+
|
6
|
+
before do
|
7
|
+
get '/catalog/oai?verb=Identify'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "contains response date" do
|
11
|
+
expect(Time.parse(xml.at_xpath('//xmlns:responseDate').text)).to be_within(5.seconds).of(Time.now)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "contains repository name" do
|
15
|
+
expect(xml.at_xpath('//xmlns:repositoryName').text).to eql 'Test Repository'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "contains base url" do
|
19
|
+
expect(xml.at_xpath('//xmlns:baseURL').text).to eql 'http://localhost'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "contains protocol version" do
|
23
|
+
expect(xml.at_xpath('//xmlns:protocolVersion').text).to eql '2.0'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "contains earliest datestamp" do
|
27
|
+
expect(xml.at_xpath('//xmlns:earliestDatestamp').text).to eql '2014-02-03T18:42:53Z'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "contains delete records" do
|
31
|
+
expect(xml.at_xpath('//xmlns:deletedRecord').text).to eql 'persistent'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "contains granularity" do
|
35
|
+
expect(xml.at_xpath('//xmlns:granularity').text).to eql 'YYYY-MM-DDThh:mm:ssZ'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "contains admin email" do
|
39
|
+
expect(xml.at_xpath('//xmlns:adminEmail').text).to eql 'root@localhost'
|
40
|
+
end
|
41
|
+
|
42
|
+
it "contains repository prefix/identifier" do
|
43
|
+
expect(
|
44
|
+
xml.at_xpath('//oai-identifier:repositoryIdentifier', 'oai-identifier' => "http://www.openarchives.org/OAI/2.0/oai-identifier").text
|
45
|
+
).to eql 'test'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "contains sample identifier" do
|
49
|
+
expect(
|
50
|
+
xml.at_xpath('//oai-identifier:sampleIdentifier', 'oai-identifier' => "http://www.openarchives.org/OAI/2.0/oai-identifier").text
|
51
|
+
).to eql 'oai:test:109660'
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'OIA-PMH ListIdentifiers Request' do
|
4
|
+
let(:xml) { Nokogiri::XML(response.body) }
|
5
|
+
|
6
|
+
context 'for all documents' do
|
7
|
+
before do
|
8
|
+
get '/catalog/oai?verb=ListIdentifiers&metadataPrefix=oai_dc'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns 25 records' do
|
12
|
+
expect(xml.xpath('//xmlns:ListIdentifiers/xmlns:header').count).to be 25
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'first record has identifier and timestamp' do
|
16
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:identifier').text).not_to eql ''
|
17
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:datestamp').text).not_to eql ''
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'contains resumptionToken' do
|
21
|
+
expect(xml.at_xpath('//xmlns:resumptionToken').text).to eql 'oai_dc.f(2014-02-03T18:42:53Z).u(2014-03-03T18:42:53Z).t(30):25'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with resumption_token' do
|
26
|
+
before do
|
27
|
+
get '/catalog/oai?verb=ListIdentifiers&resumptionToken=oai_dc.f(2014-02-03T18:42:53Z).u(2014-03-03T18:42:53Z).t(30):25'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns 5 records' do
|
31
|
+
expect(xml.xpath('//xmlns:ListIdentifiers/xmlns:header').count).to be 5
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'first record has identifier and timestamp' do
|
35
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:identifier').text).not_to eql ''
|
36
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:datestamp').text).not_to eql ''
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not contain a resumptionToken' do
|
40
|
+
expect(xml.at_xpath('//xmlns:resumptionToken').text).to eql ''
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'for all documents within a time range' do
|
45
|
+
before do
|
46
|
+
get '/catalog/oai?verb=ListIdentifiers&metadataPrefix=oai_dc&from=2014-03-03&until=2014-04-03'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns 1 record' do
|
50
|
+
expect(xml.xpath('//xmlns:ListIdentifiers/xmlns:header').count).to be 1
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'does not contain a resumptionToken' do
|
54
|
+
expect(xml.at_xpath('//xmlns:resumptionToken')).to be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with different timestamp_field' do
|
59
|
+
before :all do
|
60
|
+
SolrDocument.timestamp_key = "record_creation_dt"
|
61
|
+
end
|
62
|
+
|
63
|
+
before do
|
64
|
+
get '/catalog/oai?verb=ListIdentifiers&metadataPrefix=oai_dc&from=2015-01-01'
|
65
|
+
end
|
66
|
+
|
67
|
+
after :all do
|
68
|
+
SolrDocument.timestamp_key = "timestamp"
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns correct document' do
|
72
|
+
expect(xml.xpath('//xmlns:ListIdentifiers/xmlns:header').count).to be 1
|
73
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:identifier').text).to eql 'oai:test:78908283'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'document displays correct timestamp' do
|
77
|
+
expect(xml.at_xpath('//xmlns:ListIdentifiers/xmlns:header/xmlns:datestamp').text).to eql '2015-02-03T18:42:53Z'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'OIA-PMH ListMetadataFormats Request' do
|
4
|
+
let(:xml) { Nokogiri::XML(response.body) }
|
5
|
+
|
6
|
+
context 'without identifier parameter' do
|
7
|
+
before do
|
8
|
+
get '/catalog/oai?verb=ListMetadataFormats'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'contains oai_dc schema' do
|
12
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:schema').text).to eql 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'contains oai_dc metadataPrefix' do
|
16
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:metadataPrefix').text).to eql 'oai_dc'
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'contains oai_dc metadataNamespace' do
|
21
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:metadataNamespace').text).to eql 'http://www.openarchives.org/OAI/2.0/oai_dc/'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with identifier parameter' do
|
26
|
+
before do
|
27
|
+
get '/catalog/oai?verb=ListMetadataFormats&identifier=2007020969'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'contains oai_dc schema' do
|
31
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:schema').text).to eql 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'contains oai_dc metadataPrefix' do
|
35
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:metadataPrefix').text).to eql 'oai_dc'
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'contains oai_dc metadataNamespace' do
|
40
|
+
expect(xml.at_xpath('//xmlns:ListMetadataFormats/xmlns:metadataFormat/xmlns:metadataNamespace').text).to eql 'http://www.openarchives.org/OAI/2.0/oai_dc/'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'OIA-PMH ListRecords Request' do
|
4
|
+
let(:xml) { Nokogiri::XML(response.body) }
|
5
|
+
let(:namespaces) do
|
6
|
+
{
|
7
|
+
dc: 'http://purl.org/dc/elements/1.1/',
|
8
|
+
xmlns: 'http://www.openarchives.org/OAI/2.0/',
|
9
|
+
oai_dc: 'http://www.openarchives.org/OAI/2.0/oai_dc/'
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'for all documents' do
|
14
|
+
before do
|
15
|
+
get '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns 25 records' do
|
19
|
+
expect(xml.xpath('//xmlns:ListRecords/xmlns:record/xmlns:header').count).to be 25
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'first record has oai_dc metadata element' do
|
23
|
+
expect(xml.at_xpath('//xmlns:ListRecords/xmlns:record/xmlns:metadata/oai_dc:dc', namespaces)).not_to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'contains resumptionToken' do
|
27
|
+
expect(xml.at_xpath('//xmlns:resumptionToken').text).to eql 'oai_dc.f(2014-02-03T18:42:53Z).u(2014-03-03T18:42:53Z).t(30):25'
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'metadata element' do
|
31
|
+
let(:metadata_node) do
|
32
|
+
xml.xpath(
|
33
|
+
'//xmlns:ListRecords/xmlns:record/xmlns:header/xmlns:identifier[text()="oai:test:2007020969"]/parent::*/parent::*/xmlns:metadata/oai_dc:dc',
|
34
|
+
namespaces
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'contains title' do
|
39
|
+
expect(metadata_node.at_xpath('dc:title', namespaces).text).to eql '"Strong Medicine speaks"'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'contains creator' do
|
43
|
+
expect(metadata_node.at_xpath('dc:creator', namespaces).text).to eql 'Hearth, Amy Hill, 1958-'
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'contains type' do
|
47
|
+
expect(metadata_node.at_xpath('dc:date', namespaces).text).to eql '2008'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'contains language' do
|
51
|
+
expect(metadata_node.at_xpath('dc:language', namespaces).text).to eql 'English'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'contains format' do
|
55
|
+
expect(metadata_node.at_xpath('dc:format', namespaces).text).to eql 'Book'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with resumption_token with date filter' do
|
61
|
+
before do
|
62
|
+
get '/catalog/oai?verb=ListRecords&resumptionToken=oai_dc.f(2014-02-03T18:42:53Z).u(2014-02-03T18:42:53Z).t(29):25'
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'returns 4 records' do
|
66
|
+
expect(xml.xpath('//xmlns:ListRecords/xmlns:record/xmlns:header').count).to be 4
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'first record has oai_dc metadata element' do
|
70
|
+
expect(xml.at_xpath('//xmlns:ListRecords/xmlns:record/xmlns:metadata/oai_dc:dc', namespaces)).not_to be_nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'does not contain a resumptionToken' do
|
74
|
+
expect(xml.at_xpath('//xmlns:resumptionToken').text).to eql ''
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'for all documents within a time range' do
|
79
|
+
before do
|
80
|
+
get '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc&from=2014-03-03&until=2014-04-03'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns 1 record' do
|
84
|
+
expect(xml.xpath('//xmlns:ListRecords/xmlns:record/xmlns:header').count).to be 1
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'does not contain a resumptionToken' do
|
88
|
+
expect(xml.at_xpath('//xmlns:resumptionToken')).to be_nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'for all document until a specified time' do
|
93
|
+
before do
|
94
|
+
get '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc&until=2014-02-03T18:42:53Z'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'throws noRecordsMatch error' do
|
99
|
+
before do
|
100
|
+
get '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc&from=2015-01-01'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'returns no records error' do
|
104
|
+
expect(xml.at_xpath('//xmlns:error').attribute('code').text).to eql 'noRecordsMatch'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'throws badArgument error' do
|
109
|
+
it 'when metadataPrefix argument missing' do
|
110
|
+
get '/catalog/oai?verb=ListRecords'
|
111
|
+
expect(xml.at_xpath('//xmlns:error[@code]').attribute('code').text).to eql 'badArgument'
|
112
|
+
end
|
113
|
+
|
114
|
+
it "when date is invalid" do
|
115
|
+
get '/catalog/oai?verb=ListRecords&metadataPrefix=oai_dc&from=2012-01-f01'
|
116
|
+
expect(xml.at_xpath('//xmlns:error[@code]').attribute('code').text).to eql 'badArgument'
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'throws badResumptionToken error' do
|
121
|
+
it 'when resumptionToken is invalid' do
|
122
|
+
get '/catalog/oai?verb=ListRecords&resumptionToken=blahblahblah'
|
123
|
+
expect(xml.at_xpath('//xmlns:error').attribute('code').text).to eql 'badResumptionToken'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,47 +1,24 @@
|
|
1
|
-
|
2
|
-
require 'bundler'
|
3
|
-
|
4
|
-
Bundler.require :default, :development
|
5
|
-
|
6
|
-
require 'blacklight/engine'
|
7
|
-
require 'blacklight_oai_provider/engine'
|
1
|
+
ENV["RAILS_ENV"] ||= 'test'
|
8
2
|
require 'rsolr'
|
9
|
-
require '
|
10
|
-
|
3
|
+
require 'engine_cart'
|
4
|
+
EngineCart.load_application!
|
5
|
+
|
6
|
+
require 'rspec/rails'
|
11
7
|
require 'capybara/rspec'
|
12
|
-
|
8
|
+
require 'selenium-webdriver'
|
13
9
|
|
10
|
+
Capybara.javascript_driver = :headless_chrome
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
Capybara.register_driver :headless_chrome do |app|
|
13
|
+
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
14
|
+
chromeOptions: { args: %w[headless disable-gpu] }
|
15
|
+
)
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
use_extension( Blacklight::Solr::Document::DublinCore)
|
23
|
-
field_semantics.merge!(
|
24
|
-
:title => "title_display",
|
25
|
-
:author => "author_display",
|
26
|
-
:language => "language_facet",
|
27
|
-
:format => "format"
|
28
|
-
)
|
29
|
-
|
17
|
+
Capybara::Selenium::Driver.new(app,
|
18
|
+
browser: :chrome,
|
19
|
+
desired_capabilities: capabilities)
|
30
20
|
end
|
31
21
|
|
32
|
-
require 'vcr'
|
33
|
-
|
34
|
-
VCR.configure do |config|
|
35
|
-
config.hook_into :fakeweb
|
36
|
-
config.cassette_library_dir = 'spec/vcr_cassettes'
|
37
|
-
config.default_cassette_options = { :serialize_with => :syck }
|
38
|
-
end
|
39
|
-
|
40
|
-
require 'rspec/rails'
|
41
|
-
require 'capybara/rails'
|
42
|
-
|
43
22
|
RSpec.configure do |config|
|
44
|
-
config.
|
45
|
-
|
23
|
+
config.infer_spec_type_from_file_location!
|
46
24
|
end
|
47
|
-
|
@@ -0,0 +1,9 @@
|
|
1
|
+
development:
|
2
|
+
adapter: solr
|
3
|
+
url: <%= ENV['SOLR_URL'] || "http://127.0.0.1:8983/solr/blacklight-core" %>
|
4
|
+
test: &test
|
5
|
+
adapter: solr
|
6
|
+
url: <%= ENV['SOLR_URL'] || "http://127.0.0.1:#{ENV['TEST_JETTY_PORT'] || 8983}/solr/blacklight-core" %>
|
7
|
+
production:
|
8
|
+
adapter: solr
|
9
|
+
url: <%= ENV['SOLR_URL'] || "http://127.0.0.1:8983/solr/blacklight-core" %>
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class TestAppGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../../../spec/test_app_templates", __FILE__)
|
5
|
+
|
6
|
+
# if you need to generate any additional configuration
|
7
|
+
# into the test app, this generator will be run immediately
|
8
|
+
# after setting up the application
|
9
|
+
|
10
|
+
def run_blacklight_generator
|
11
|
+
say_status("warning", "GENERATING BL", :yellow)
|
12
|
+
|
13
|
+
generate 'blacklight', '--devise'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add favicon.ico to asset path
|
17
|
+
# ADD THIS LINE Rails.application.config.assets.precompile += %w( favicon.ico )
|
18
|
+
# TO config/assets.rb
|
19
|
+
def add_favicon_to_asset_path
|
20
|
+
say_status("warning", "ADDING FAVICON TO ASSET PATH", :yellow)
|
21
|
+
|
22
|
+
append_to_file 'config/initializers/assets.rb' do
|
23
|
+
'Rails.application.config.assets.precompile += %w( favicon.ico )'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Override solr.yml to match settings needed for solr_wrapper.
|
28
|
+
def update_solr_config
|
29
|
+
say_status("warning", "COPYING SOLR.YML", :yellow)
|
30
|
+
|
31
|
+
remove_file "config/solr.yml"
|
32
|
+
copy_file "config/solr.yml", "config/solr.yml"
|
33
|
+
end
|
34
|
+
|
35
|
+
def install_engine
|
36
|
+
say_status("warning", "GENERATING BL OAI PLUGIN", :yellow)
|
37
|
+
|
38
|
+
generate 'blacklight_oai_provider:install'
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_test_blacklight_oai_config
|
42
|
+
say_status("warning", "ADDING BL OIA-PMH CONFIG")
|
43
|
+
|
44
|
+
insert_into_file "app/controllers/catalog_controller.rb", after: " config.default_solr_params = { \n" do
|
45
|
+
" :fl => '*',\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
insert_into_file "app/controllers/catalog_controller.rb", after: " configure_blacklight do |config|\n" do
|
49
|
+
<<-CONFIG
|
50
|
+
config.default_document_solr_params = {
|
51
|
+
:qt => 'search',
|
52
|
+
:fl => '*',
|
53
|
+
:rows => 1,
|
54
|
+
:q => '{!raw f=id v=$id}'
|
55
|
+
}
|
56
|
+
CONFIG
|
57
|
+
end
|
58
|
+
|
59
|
+
insert_into_file "app/controllers/catalog_controller.rb", after: "configure_blacklight do |config|\n" do
|
60
|
+
<<-CONFIG
|
61
|
+
config.oai = {
|
62
|
+
:provider => {
|
63
|
+
:repository_name => 'Test Repository',
|
64
|
+
:repository_url => 'http://localhost',
|
65
|
+
:record_prefix => 'oai:test',
|
66
|
+
:admin_email => 'root@localhost',
|
67
|
+
:deletion_support => 'persistent',
|
68
|
+
:sample_id => '109660'
|
69
|
+
},
|
70
|
+
:document => {
|
71
|
+
:model => SolrDocument,
|
72
|
+
:limit => 25
|
73
|
+
}
|
74
|
+
}
|
75
|
+
CONFIG
|
76
|
+
end
|
77
|
+
|
78
|
+
insert_into_file "app/models/solr_document.rb", after: " field_semantics.merge!( \n" do
|
79
|
+
<<-CONFIG
|
80
|
+
:creator => "author_display",
|
81
|
+
:date => "pub_date",
|
82
|
+
:subject => "subject_topic_facet",
|
83
|
+
CONFIG
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|