From d825e2257e6684dcf42fbe851109213d0d2314c5 Mon Sep 17 00:00:00 2001 From: Bess Sadler Date: Mon, 19 Sep 2022 16:52:11 -0400 Subject: [PATCH] Add an RSS feed for works, to be used by discovery for indexing (#418) * Add an RSS feed for works, to be used by discovery for indexing * Only approved works should appear in RSS feed --- app/controllers/works_controller.rb | 4 +++ app/views/layouts/application.html.erb | 1 + app/views/works/index.rss.builder | 19 ++++++++++++ spec/controllers/works_controller_spec.rb | 6 ++++ spec/system/rss_spec.rb | 37 +++++++++++++++++++++++ 5 files changed, 67 insertions(+) create mode 100644 app/views/works/index.rss.builder create mode 100644 spec/system/rss_spec.rb diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 1a7cd551..830b1ac8 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -12,6 +12,10 @@ class WorksController < ApplicationController def index @works = Work.all + respond_to do |format| + format.html + format.rss { render layout: false } + end end # Renders the "step 0" information page before creating a new dataset diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 88594642..04fa64e2 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -25,6 +25,7 @@ <%= favicon_link_tag asset_path('favicon.png') %> + <%= auto_discovery_link_tag :rss, works_url(:format => :rss) %> diff --git a/app/views/works/index.rss.builder b/app/views/works/index.rss.builder new file mode 100644 index 00000000..c245116d --- /dev/null +++ b/app/views/works/index.rss.builder @@ -0,0 +1,19 @@ +# frozen_string_literal: true +xml.instruct! :xml, version: "1.0" +xml.rss version: "2.0" do + xml.channel do + xml.title "Princeton Data Commons RSS Feed" + xml.description "Princeton Data Commons RSS Feed of approved submissions" + xml.link root_url + + @works.each do |work| + # Only include approved works in the RSS feed + next unless work.state == "approved" + xml.item do + xml.title work.title + xml.url datacite_work_url(work) + xml.date_changed work.updated_at + end + end + end +end diff --git a/spec/controllers/works_controller_spec.rb b/spec/controllers/works_controller_spec.rb index 71d73859..db27666a 100644 --- a/spec/controllers/works_controller_spec.rb +++ b/spec/controllers/works_controller_spec.rb @@ -21,6 +21,12 @@ expect(response).to render_template("index") end + it "has an rss feed" do + sign_in user + get :index, format: "rss" + expect(response.content_type).to eq "application/rss+xml; charset=utf-8" + end + it "renders the new submission wizard' step 0" do sign_in user get :new, params: { wizard: true } diff --git a/spec/system/rss_spec.rb b/spec/system/rss_spec.rb new file mode 100644 index 00000000..d19a1597 --- /dev/null +++ b/spec/system/rss_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +require "rails_helper" + +RSpec.describe "RSS feed of approved works, for harvesting and indexing", type: :system, mock_ezid_api: true do + let(:work1) { FactoryBot.create(:draft_work) } + let(:work2) { FactoryBot.create(:draft_work) } + let(:work3) { FactoryBot.create(:draft_work) } + let(:admin) { FactoryBot.create(:super_admin_user) } + let(:user) { FactoryBot.create(:princeton_submitter) } + + before do + stub_datacite(host: "api.datacite.org", body: datacite_register_body(prefix: "10.34770")) + allow(work1).to receive(:publish_doi).and_return(true) + allow(work2).to receive(:publish_doi).and_return(true) + + # Works 1 & 2 are approved, so they should show up in the RSS feed + work1.complete_submission!(admin) + work1.approve!(admin) + + work2.complete_submission!(admin) + work2.approve!(admin) + + # Ensure work3 exists before running the tests, but leave it in draft state. + # It should NOT appear in the RSS feed. + work3 + end + + it "provides a list of approved works, with links to their datacite records" do + sign_in user + visit "/works.rss" + doc = Nokogiri::XML(page.body) + expect(doc.xpath("//item").size).to eq 2 + urls = doc.xpath("//item/url/text()").map(&:to_s) + expect(urls.include?(datacite_work_url(work1))).to eq true + expect(urls.include?(datacite_work_url(work2))).to eq true + end +end