diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 86ec50080..3060ccf97 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -67,6 +67,7 @@ def show format.json format.json_api { render json: @event } format.ics { send_data @event.to_ical, type: 'text/calendar', disposition: 'attachment', filename: "#{@event.slug}.ics" } + format.jsonld { render plain: @bioschemas.first.to_json } end end diff --git a/app/controllers/materials_controller.rb b/app/controllers/materials_controller.rb index 7f5813c9b..4d9a54723 100644 --- a/app/controllers/materials_controller.rb +++ b/app/controllers/materials_controller.rb @@ -35,6 +35,7 @@ def show format.html format.json format.json_api { render json: @material } + format.jsonld { render plain: @bioschemas.first.to_json } end end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index e48527aad..4556d2926 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -4,3 +4,4 @@ # Mime::Type.register "text/richtext", :rtf Mime::Type.register 'application/vnd.api+json', :json_api +Mime::Type.register 'application/ld+json', :jsonld, ['application/vnd.schemaorg.ld+json'] diff --git a/lib/bioschemas/generator.rb b/lib/bioschemas/generator.rb index 5f5afc783..7dd8cd424 100644 --- a/lib/bioschemas/generator.rb +++ b/lib/bioschemas/generator.rb @@ -96,10 +96,10 @@ def self.address(event) 'addressRegion' => event.county, 'addressCountry' => event.country, 'postalCode' => event.postcode - }.compact, + }.compact_blank, 'latitude' => event.latitude, 'longitude' => event.longitude - }.compact + }.compact_blank end # Reverse the process used by TeSS_RDF_Extractors to turn a list of values into a markdown list. @@ -137,15 +137,6 @@ def self.external_resources(resource) def self.provider(resource) p = [] - if resource.respond_to?(:host_institutions) - resource.host_institutions.each do |i| - p << { - '@type' => 'Organization', - 'name' => i - } - end - end - if resource.content_provider p << { '@type' => 'Organization', @@ -162,6 +153,17 @@ def self.provider(resource) } end + if resource.respond_to?(:host_institutions) + resource.host_institutions.each do |i| + p << { + '@type' => 'Organization', + 'name' => i + } + end + end + + p.uniq! { |o| o['name'].downcase.strip } + p.any? ? p : nil end end diff --git a/test/controllers/events_controller_test.rb b/test/controllers/events_controller_test.rb index 83400a930..aa905acca 100644 --- a/test/controllers/events_controller_test.rb +++ b/test/controllers/events_controller_test.rb @@ -323,6 +323,31 @@ class EventsControllerTest < ActionController::TestCase assert_equal 'hybrid', body['data']['attributes']['presence'] end + test 'should show event as bioschemas JSON-LD' do + @event.scientific_topic_uris = ['http://edamontology.org/topic_0654'] + @event.materials << @material + @event.collections << @collection + @event.save! + + get :show, params: { id: @event, format: :jsonld } + assert_response :success + assert assigns(:event) + + body = nil + assert_nothing_raised do + body = JSON.parse(response.body) + end + + assert_equal 'http://schema.org', body['@context'] + assert_equal 'Course', body['@type'] + assert_equal 'https://bioschemas.org/profiles/Course/1.0-RELEASE', body['dct:conformsTo']['@id'] + assert_equal @event.title, body['name'] + assert_equal @event.url, body['url'] + assert_equal @event.scientific_topic_uris.first, body['about'].first['@id'] + assert_equal event_url(assigns(:event), host: TeSS::Config.base_url), body['@id'] + assert_equal @event.external_resources.first.url, body['mentions'].first['url'] + end + # UPDATE TEST test 'should update event' do sign_in @event.user diff --git a/test/controllers/materials_controller_test.rb b/test/controllers/materials_controller_test.rb index 19ff0a250..e41945e12 100644 --- a/test/controllers/materials_controller_test.rb +++ b/test/controllers/materials_controller_test.rb @@ -398,6 +398,29 @@ class MaterialsControllerTest < ActionController::TestCase assert_equal @collection.id.to_s, body['data']['relationships']['collections']['data'][0]['id'] end + test 'should show material as bioschemas JSON-LD' do + @material.scientific_topic_uris = ['http://edamontology.org/topic_0654'] + @material.events << @event + @material.collections << @collection + @material.save! + + get :show, params: { id: @material, format: :jsonld } + assert_response :success + assert assigns(:material) + body = nil + assert_nothing_raised do + body = JSON.parse(response.body) + end + + assert_equal 'http://schema.org', body['@context'] + assert_equal 'LearningResource', body['@type'] + assert_equal 'https://bioschemas.org/profiles/TrainingMaterial/1.0-RELEASE', body['dct:conformsTo']['@id'] + assert_equal @material.title, body['name'] + assert_equal @material.url, body['url'] + assert_equal @material.scientific_topic_uris.first, body['about'].first['@id'] + assert_equal material_url(assigns(:material), host: TeSS::Config.base_url), body['@id'] + end + #UPDATE TEST test 'should update material' do sign_in @material.user diff --git a/test/models/event_test.rb b/test/models/event_test.rb index 90ff91ef3..5ec81805d 100644 --- a/test/models/event_test.rb +++ b/test/models/event_test.rb @@ -757,4 +757,22 @@ class EventTest < ActiveSupport::TestCase refute event.valid? assert event.errors.added?(:keywords, :too_long, count: 20) end + + test 'blank address fields are removed from event bioschemas json' do + e = Event.new(city: 'Manchester', country: '', event_types: ['workshops_and_courses']) + bioschemas = e.to_bioschemas.first.generate + address = bioschemas[:hasCourseInstance].first[:location]['address'] + assert_equal 'Manchester', address['addressLocality'] + assert_equal ['@type', 'addressLocality'].sort, address.keys.sort + end + + test 'de-duplicates provider in event bioschemas json' do + e = Event.new(content_provider: content_providers(:goblet), host_institutions: 'Goblet', + event_types: ['workshops_and_courses']) + + bioschemas = e.to_bioschemas.first.generate + assert_equal 1, bioschemas[:provider].length + assert_equal 'Goblet', bioschemas[:provider].first['name'] + assert_equal 'http://mygoblet.org', bioschemas[:provider].first['url'] + end end