From a81b7f80a512d364755d366f15a0a82d993688c8 Mon Sep 17 00:00:00 2001 From: SWE-agent Date: Sun, 14 Sep 2025 20:39:30 +0000 Subject: [PATCH] Fix: {issue.title} Closes #{issue.number} --- app/controllers/links_controller.rb | 7 +- app/views/links/feed.atom.builder | 26 ++++-- test/controllers/links_controller_test.rb | 101 ++++++++++++++++++++++ 3 files changed, 126 insertions(+), 8 deletions(-) diff --git a/app/controllers/links_controller.rb b/app/controllers/links_controller.rb index e7eaab1..06f18d9 100644 --- a/app/controllers/links_controller.rb +++ b/app/controllers/links_controller.rb @@ -15,7 +15,12 @@ def index end def feed - @links = Link.order(created_at: :desc).limit(20) + # Get both links and papers, ordered by creation date + links = Link.order(created_at: :desc).limit(20) + papers = Paper.order(created_at: :desc).limit(20) + + # Combine and sort by created_at, then take the first 20 + @items = (links + papers).sort_by(&:created_at).reverse.first(20) respond_to do |format| format.atom end diff --git a/app/views/links/feed.atom.builder b/app/views/links/feed.atom.builder index ab0cf02..0520d5f 100644 --- a/app/views/links/feed.atom.builder +++ b/app/views/links/feed.atom.builder @@ -1,13 +1,25 @@ atom_feed do |feed| feed.title "#{Rails.application.config.site_name} - Interesting Links Feed" - feed.updated(@links.first.updated_at) + feed.updated(@items.first&.updated_at || Time.current) - @links.each do |link| - feed.entry(link, id: link.uuid, url: link.url) do |entry| - entry.title(link.title) - entry.content(link.description, type: "text") - entry.author do |author| - author.name "N/A" + @items.each do |item| + if item.is_a?(Link) + feed.entry(item, id: item.uuid, url: item.url) do |entry| + entry.title(item.title) + entry.content(item.description, type: "text") + entry.author do |author| + author.name "N/A" + end + end + elsif item.is_a?(Paper) + # Use display_url for arXiv papers, otherwise use the paper's url + entry_url = item.arxiv? ? item.display_url : item.url + feed.entry(item, id: "paper-#{item.id}", url: entry_url) do |entry| + entry.title(item.title) + entry.content(item.description, type: "text") + entry.author do |author| + author.name "N/A" + end end end end diff --git a/test/controllers/links_controller_test.rb b/test/controllers/links_controller_test.rb index 1a62691..bfb18cb 100644 --- a/test/controllers/links_controller_test.rb +++ b/test/controllers/links_controller_test.rb @@ -1,4 +1,5 @@ require "test_helper" +require "nokogiri" class LinksControllerTest < ActionDispatch::IntegrationTest def setup @@ -32,6 +33,106 @@ def setup assert_redirected_to links_path end + test "feed should include both links and papers" do + # Stub HTTP requests for link creation + stub_request(:get, "http://example.com/test-link1") + .to_return(status: 200, body: "Link 1", headers: { "Content-Type" => "text/html" }) + stub_request(:get, "http://example.com/test-link2") + .to_return(status: 200, body: "Link 2", headers: { "Content-Type" => "text/html" }) + + # Create some links + link1 = Link.create!(url: "http://example.com/test-link1") + link2 = Link.create!(url: "http://example.com/test-link2") + + # Create some papers + paper1 = Paper.create!(url: "http://example.com/test-paper1.pdf", title: "Paper 1", description: "Description 1") + paper2 = Paper.create!(url: "http://example.com/test-paper2.pdf", title: "Paper 2", description: "Description 2") + + # Make sure the papers have different created_at times + paper1.update(created_at: 2.days.ago) + paper2.update(created_at: 1.day.ago) + + get links_feed_url, params: { format: "atom" } + + assert_response :success + assert response.content_type.start_with?("application/atom+xml") + + # Check that both links and papers are in the feed + # Note: We might have more than 4 entries if there are existing fixtures + assert_select "entry title", text: "Link 1" + assert_select "entry title", text: "Link 2" + assert_select "entry title", text: "Paper 1" + assert_select "entry title", text: "Paper 2" + end + + test "feed should use proper URLs for arXiv papers" do + # Stub HTTP requests for link creation + stub_request(:get, "http://example.com/test-link") + .to_return(status: 200, body: "Regular Link", headers: { "Content-Type" => "text/html" }) + + # Create a regular link + link = Link.create!(url: "http://example.com/test-link") + + # Create a regular paper + regular_paper = Paper.create!(url: "http://example.com/test-paper.pdf", title: "Regular Paper", description: "Description") + + # Create an arXiv paper + arxiv_paper = Paper.create!(url: "https://arxiv.org/abs/1234.56789", title: "ArXiv Paper", description: "Description") + + get links_feed_url, params: { format: "atom" } + + assert_response :success + + # Check that the regular paper uses its own URL + assert_select "entry link[href='#{regular_paper.url}']", count: 1 + + # Check that the arXiv paper uses the PDF URL + assert_select "entry link[href='#{arxiv_paper.display_url}']", count: 1 + end + + test "feed should be ordered by creation date" do + # Stub HTTP requests for link creation + stub_request(:get, "http://example.com/test-oldest") + .to_return(status: 200, body: "Oldest Link", headers: { "Content-Type" => "text/html" }) + stub_request(:get, "http://example.com/test-newest") + .to_return(status: 200, body: "Newest Link", headers: { "Content-Type" => "text/html" }) + + # Create items at different times + oldest_link = Link.create!(url: "http://example.com/test-oldest") + oldest_link.update(created_at: 3.days.ago) + + middle_paper = Paper.create!(url: "http://example.com/test-middle.pdf", title: "Middle Paper", description: "Description") + middle_paper.update(created_at: 2.days.ago) + + newest_link = Link.create!(url: "http://example.com/test-newest") + newest_link.update(created_at: 1.day.ago) + + get links_feed_url, params: { format: "atom" } + + assert_response :success + + # Parse the XML to check ordering + xml = Nokogiri::XML(response.body) + entries = xml.xpath("//xmlns:entry") + + # Find our specific entries among possibly others + entry_titles = entries.map { |entry| entry.at_xpath(".//xmlns:title").text } + + # Find positions of our test entries + oldest_pos = entry_titles.index("Oldest Link") + middle_pos = entry_titles.index("Middle Paper") + newest_pos = entry_titles.index("Newest Link") + + # Verify that they exist + refute_nil oldest_pos, "Oldest Link should be in the feed" + refute_nil middle_pos, "Middle Paper should be in the feed" + refute_nil newest_pos, "Newest Link should be in the feed" + + # Verify ordering: newest should come before middle, which should come before oldest + assert newest_pos < middle_pos, "Newest Link should come before Middle Paper" + assert middle_pos < oldest_pos, "Middle Paper should come before Oldest Link" + end + private def sign_in(user)