Skip to content

Commit

Permalink
Support typed EDTF data for the Etd#date field
Browse files Browse the repository at this point in the history
An `RDF::Literal` subclass for EDTF datatypes is introduced. This supports the
id.loc.gov namespaced datatype for EDTF and can accept any string value as its
lexical value. We test that when a date is set to this type, it is correctly
serialized in the object's `.ttl` view.

Handling is added to `EtdIndexer#generate_solr_document` to ensure edtf dates
are indexed text values (they are also indexed as dates, but we do not consume
them in catalog controller or elsewhere). The correct appearance of typed data
in the show view is tested.

Dates input through the `EtdForm` are cast to the typed literal so they can be
serialized to Fedora with the correct type. We assume any value put into the
"EDTF Date" form field is intended to be interpreted as typed data.

Factories are updated to set an EDTF date on build.

Closes #186.
  • Loading branch information
Tom Johnson authored and jenlindner committed Jan 24, 2018
1 parent f4ef5e7 commit 31c021f
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 3 deletions.
2 changes: 1 addition & 1 deletion app/controllers/catalog_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def self.modified_field
config.add_show_field solr_name("license", :stored_searchable)

# Core show fields
config.add_show_field solr_name('date', :stored_searchable)
config.add_show_field solr_name('date', :stored_searchable)

# ETD show fields
config.add_show_field solr_name('date_label', :stored_searchable)
Expand Down
11 changes: 11 additions & 0 deletions app/forms/hyrax/etd_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,16 @@ class EtdForm < Hyrax::Forms::WorkForm
self.single_valued_fields = [:degree, :school, :department, :institution].freeze
self.model_class = ::Etd
self.terms += [:degree, :date, :date_label, :department, :institution, :orcid_id, :resource_type, :rights_note, :school]

##
# Cast `:date` parameters from the form to EDTF.
#
# We don't care if the dates are valid. `"moomin"` is a perfectly acceptable
# EDTF date for our purposes.
def self.model_attributes(form_params)
result = super
result[:date].map! { |date| Mahonia::EdtfLiteral.new(date) }
result
end
end
end
14 changes: 14 additions & 0 deletions app/indexers/etd_indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,19 @@ class IndexingService < Hyrax::DeepIndexingService

stored_fields.delete(:license)
stored_fields.delete(:rights_statement)

##
# Index EDTF dates
def generate_solr_document
super.tap do |solr_doc|
if object.date.any?
date_key = Solrizer.solr_name('date')

solr_doc[date_key] ||= []
solr_doc[date_key] +=
object.date.select { |date| date.respond_to?(:edtf) }.map(&:edtf)
end
end
end
end
end
24 changes: 24 additions & 0 deletions app/lib/mahonia/edtf_literal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module Mahonia
class EdtfLiteral < RDF::Literal
DATATYPE = RDF::URI('http://id.loc.gov/datatypes/edtf/EDTF')

# support ActiveJob serialization
include GlobalID::Identification

def self.find(id)
new(id)
end

def initialize(value, **opts)
value = EDTF.parse(value) || value
@string = value.edtf if value.respond_to? :edtf
super
end

def id
value
end
end
end
2 changes: 1 addition & 1 deletion spec/factories/etds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
factory :moomins_thesis do
title ['Moomintroll']
creator ['Moomin', 'Hemulen']
date ['199?']
date [Mahonia::EdtfLiteral.new('199x')]
publisher ['A Publisher']
date_created [Date.parse('2016-12-25')]
date_label ['Winter in Moomin Valley']
Expand Down
6 changes: 6 additions & 0 deletions spec/features/create_etd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
fill_in 'Description', with: etd[:description].first
# term for license URI set in factory
select('Creative Commons BY-SA Attribution-ShareAlike 4.0 International', from: 'License')
fill_in 'EDTF Date', with: etd[:date].first
fill_in 'Publisher', with: etd[:publisher].first
fill_in 'Date Created', with: etd[:date_created].first
fill_in 'Subject', with: etd[:subject].first
Expand All @@ -66,6 +67,10 @@
# wait until we have a record
persisted_etd = Etd.where(title: etd[:title].first) while persisted_etd.nil?

# ensure the EDTF date is typed
expect(persisted_etd.first)
.to have_attributes(date: contain_exactly(*etd[:date].map(&:object)))

expect(page).to have_content etd[:title].first
expect(page).to have_content etd[:creator].first
expect(page).to have_content etd[:keyword].first
Expand All @@ -75,6 +80,7 @@
# license
expect(page).to have_content 'Creative Commons BY-SA Attribution-ShareAlike 4.0 International'
expect(page).to have_content etd[:publisher].first
expect(page).to have_content etd[:date].first
expect(page).to have_content etd[:subject].first
expect(page).to have_content etd[:language].first
# Identifier sets DOI
Expand Down
3 changes: 3 additions & 0 deletions spec/features/edit_etd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
fill_in 'Description', with: etd[:description].first
# term for license URI set in factory
select('Creative Commons BY-SA Attribution-ShareAlike 4.0 International', from: 'License')
fill_in 'EDTF Date', with: etd[:date].first
fill_in 'Date Created', with: etd[:date_created].first
fill_in 'Subject', with: etd[:subject].first
fill_in 'Language', with: etd[:language].first
Expand Down Expand Up @@ -73,6 +74,7 @@
fill_in 'Description', with: "Edited Description"
# term for license URI set in factory
select('Creative Commons BY-SA Attribution-ShareAlike 4.0 International', from: 'License')
fill_in 'EDTF Date', with: 'Edited Date'
fill_in 'Subject', with: "Edited Subject"
fill_in 'Language', with: "Edited Language"
fill_in 'Identifier', with: "Edited Identifier"
Expand Down Expand Up @@ -105,6 +107,7 @@
expect(page).to have_content "Edited Keyword"
expect(page).to have_content "In Copyright"
expect(page).to have_content "Edited Description"
expect(page).to have_content "Edited Date"
expect(page).to have_content "Edited Subject"
expect(page).to have_content "Edited Language"
expect(page).to have_content "Edited Identifier"
Expand Down
10 changes: 10 additions & 0 deletions spec/indexers/etd_indexer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
subject(:indexer) { described_class.new(etd) }
let(:etd) { FactoryGirl.build(:etd) }

describe '#generate_solr_document' do
let(:dates) { [Mahonia::EdtfLiteral.new('2999?'), '1999'] }
let(:etd) { FactoryGirl.build(:etd, date: dates) }

it 'indexes EDTF datatypes' do
expect(indexer.generate_solr_document)
.to include('date_tesim' => contain_exactly('1999', '2999?'))
end
end

describe '#rdf_service' do
it 'has facetable fields' do
expect(indexer.rdf_service.stored_and_facetable_fields)
Expand Down
12 changes: 12 additions & 0 deletions spec/lib/mahonia/edtf_literal_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true
require 'rails_helper'

RSpec.describe Mahonia::EdtfLiteral do
subject(:literal) { described_class.new(edtf_str) }
let(:edtf_str) { '199x' }

it 'has an EDTF datatype' do
expect(literal)
.to have_attributes(datatype: RDF::URI('http://id.loc.gov/datatypes/edtf/EDTF'))
end
end
4 changes: 4 additions & 0 deletions spec/presenters/hyrax/etd_presenter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
expect(presenter.export_as_ttl).to include(*predicates)
end

it 'has an ETDF date with datatype' do
expect(presenter.export_as_ttl).to include('<http://id.loc.gov/datatypes/edtf/EDTF>')
end

context 'with an embargo' do
let(:etd) { FactoryGirl.create(:embargoed_etd) }

Expand Down
2 changes: 1 addition & 1 deletion spec/views/hyrax/base/_metadata.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
it { is_expected.to have_show_field(:creator).with_values(*work.creator).and_label('Creator') }
# underspecify date values (they aren't necessarily sensible for all Date/DateTime values)
it { is_expected.to have_show_field(:date_created).with_label('Date created') }
it { is_expected.to have_show_field(:date).with_values(*work.date).and_label('EDTF Date') }
it { is_expected.to have_show_field(:date).with_values(*work.date.map(&:to_s)).and_label('EDTF Date') }
it { is_expected.to have_show_field(:date_label).with_values(*work.date_label).and_label('Date label') }
it { is_expected.to have_show_field(:degree).with_values(*work.degree).and_label('Degree Name') }
it { is_expected.to have_show_field(:department).with_values(*work.department).and_label('Department') }
Expand Down

0 comments on commit 31c021f

Please sign in to comment.