diff --git a/VERSION b/VERSION index 8e8299dc..35cee72d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4.2 +2.4.3 diff --git a/lib/generators/trln_argon/install_generator.rb b/lib/generators/trln_argon/install_generator.rb index a4e14e99..1387825a 100644 --- a/lib/generators/trln_argon/install_generator.rb +++ b/lib/generators/trln_argon/install_generator.rb @@ -90,14 +90,18 @@ def inject_local_env_loader end end - # rubocop:disable Layout/LineLength def inject_into_dev_env return if IO.read('config/environments/development.rb').include?('BetterErrors') insert_into_file 'config/environments/development.rb', after: 'Rails.application.configure do' do - "\n\n require 'socket'\n\n local_ip = IPSocket.getaddress(Socket.gethostname)\n\n BetterErrors::Middleware.allow_ip! local_ip if defined? BetterErrors && Rails.env == :development\n" + "\n\n require 'socket'\n" \ + " begin\n" \ + " local_ip = IPSocket.getaddress(Socket.gethostname)\n" \ + " rescue\n" \ + " local_ip = \"127.0.0.1\"\n" \ + " end\n" \ + " BetterErrors::Middleware.allow_ip! local_ip if defined?(BetterErrors) && Rails.env.development?\n" end end - # rubocop:enable Layout/LineLength def inject_catalog_controller_overrides return if IO.read('config/application.rb').include?('local_env.yml') diff --git a/lib/trln_argon/hathitrust_controller_behavior.rb b/lib/trln_argon/hathitrust_controller_behavior.rb index ffdff826..ace8368a 100644 --- a/lib/trln_argon/hathitrust_controller_behavior.rb +++ b/lib/trln_argon/hathitrust_controller_behavior.rb @@ -21,7 +21,7 @@ def render_hathitrust_partial_to_string(full_text_url) render_to_string('hathitrust/show', locals: { hathitrust_argon_url_hash: hathitrust_argon_url_hash(full_text_url) }, - layout: false) + layout: false).gsub(//m, '') end def hathitrust_argon_url_hash(full_text_url) diff --git a/lib/trln_argon/internet_archive_controller_behavior.rb b/lib/trln_argon/internet_archive_controller_behavior.rb index 82967683..6cd5b36e 100644 --- a/lib/trln_argon/internet_archive_controller_behavior.rb +++ b/lib/trln_argon/internet_archive_controller_behavior.rb @@ -26,10 +26,13 @@ def key_ia_id_pairs(ia_ids) end def render_ia_partial_to_string(full_text_url) - render_to_string('internet_archive/show', - locals: { internet_archive_argon_url_hash: - ia_argon_url_hash(full_text_url) }, - layout: false) + render_to_string( + 'internet_archive/show', + locals: { + internet_archive_argon_url_hash: ia_argon_url_hash(full_text_url) + }, + layout: false + ).gsub(//m, '') end def ia_argon_url_hash(full_text_url) diff --git a/lib/trln_argon/solr_document/citation.rb b/lib/trln_argon/solr_document/citation.rb index b4498f94..2838f6a7 100644 --- a/lib/trln_argon/solr_document/citation.rb +++ b/lib/trln_argon/solr_document/citation.rb @@ -94,15 +94,31 @@ def parse_authors_and_editors(docvalue) end def convert_to_bibtex_format(input) - identifier = input.detect { |key, _| key == 'id' }[1] - entry_type = input.detect { |key, _| key == 'type' }[1].split(',').first.strip.downcase - entry_type = map_entry_type(entry_type) + identifier = input.detect { |key, _| key == 'id' }&.last + entry_type = determine_entry_type(input) # The bibtex string should look like this # "@book{id, author = {Author, A.}, title = {Title}, journal = {Journal}, year = {2020}}" - formatted_pairs = input.reject { |key, _| ['id', 'type'].include?(key) }.map do |key, value| + formatted_pairs = generate_formatted_pairs(input) + "@#{entry_type}{#{identifier}, #{formatted_pairs.join(', ')}}" + rescue StandardError => e + puts "An error occurred: #{e.message}" + 'No citations for this item.' + end + + def determine_entry_type(input) + entry_type_value = input.detect { |key, _| key == 'type' }&.last + entry_type = if entry_type_value.to_s.strip.empty? + 'book' + else + entry_type_value + end + map_entry_type(entry_type) + end + + def generate_formatted_pairs(input) + input.reject { |key, _| ['id', 'type'].include?(key) }.map do |key, value| "#{key} = {#{value}}" end - "@#{entry_type}{#{identifier}, #{formatted_pairs.join(', ')}}" end def process_citations(bibliography, citation_hash) diff --git a/spec/lib/trln_argon/solr_document_spec.rb b/spec/lib/trln_argon/solr_document_spec.rb index 35f0a089..5d4fd271 100644 --- a/spec/lib/trln_argon/solr_document_spec.rb +++ b/spec/lib/trln_argon/solr_document_spec.rb @@ -931,4 +931,63 @@ class SolrDocumentTestClass end end end + + context 'when an error occurs during citation generation' do + describe '#generate_citation' do + let(:document) do + SolrDocument.new( + # Missing required fields + title: 'An Incomplete Title' + ) + end + + before do + allow(document).to receive(:generate_formatted_pairs).and_raise(StandardError) + end + + it 'prints a server error message' do + expect { document.send(:convert_to_bibtex_format, document) } + .to output(a_string_starting_with('An error occurred:')).to_stdout + end + + it 'returns a fallback message' do + expect(document.send(:convert_to_bibtex_format, document)).to eq('No citations for this item.') + end + end + end + + describe '#determine_entry_type' do + let(:document) { SolrDocument.new } + + context 'when type is present' do + it 'returns the correct entry type' do + input = { 'type' => 'Journal, Magazine, or Periodical' } + expect(document.send(:determine_entry_type, input)).to eq('article-journal') + end + end + + context 'when type is present but empty' do + it 'defaults to book' do + input = { 'type' => '' } + expect(document.send(:determine_entry_type, input)).to eq('book') + end + end + + context 'when type is not present' do + it 'defaults to book' do + input = {} + expect(document.send(:determine_entry_type, input)).to eq('book') + end + end + end + + describe '#generate_formatted_pairs' do + let(:document) { SolrDocument.new } + + it 'formats input pairs, excluding id and type' do + input = { 'id' => '123', 'type' => 'article', 'author' => 'Doe, John', 'title' => 'An Interesting Article' } + expected_output = ['author = {Doe, John}', 'title = {An Interesting Article}'] + expect(document.send(:generate_formatted_pairs, input)).to eq(expected_output) + end + end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6ccfd640..b1cbeb50 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -34,7 +34,12 @@ RSpec.configure do |config| # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" + # Update fixture paths configuration to be compatible with Rails 7.1 and later. + # Rails now expects `fixture_paths` to be an array rather than a singular string. + # This change is documented in the Rails 7.1 release notes: + # https://guides.rubyonrails.org/7_1_release_notes.html + # https://apidock.com/rails/v7.1.3.2/ActiveSupport/TestCase/fixture_paths%3D/class + config.fixture_paths = ["#{::Rails.root}/spec/fixtures"] # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false diff --git a/trln_argon.gemspec b/trln_argon.gemspec index 94681b2b..b2e8cc24 100644 --- a/trln_argon.gemspec +++ b/trln_argon.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.files = Dir['{app,config,db,lib}/**/*', 'MIT-LICENSE', 'Rakefile', 'README.md'] - s.add_dependency 'rails', '~> 7' + s.add_dependency 'rails', '~> 7.1' s.add_dependency 'blacklight', '~> 7.0' s.add_dependency 'blacklight_advanced_search', '~> 8.0.0.alpha2' s.add_dependency 'blacklight-hierarchy', '~> 6.3' @@ -36,7 +36,7 @@ Gem::Specification.new do |s| s.add_dependency 'csl-styles', '~> 1.0' s.add_dependency 'bibtex-ruby', '>= 4.4.6', '< 7' - s.add_development_dependency 'rspec-rails', '~> 5' + s.add_development_dependency 'rspec-rails', '~> 6' s.add_development_dependency 'capybara', '~> 3.29' s.add_development_dependency 'pry', '~> 0.14' s.add_development_dependency 'rubocop', '~> 1.0' @@ -52,7 +52,7 @@ Gem::Specification.new do |s| # Conditionally constrain nokogiri & sqlite3 to versions that still work with Ruby 2.7 # TODO: remove when we are all using Ruby 3+. - if Gem::Requirement.new('< 3.0').satisfied_by?(Gem::Version.new(RUBY_VERSION)) + if Gem::Requirement.new('< 3.1').satisfied_by?(Gem::Version.new(RUBY_VERSION)) s.add_dependency 'nokogiri', '< 1.16' s.add_dependency 'sqlite3', '< 1.7' end