• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pulibrary / orangelight / 0e37073d-109c-440c-949f-49d2aa86311b

18 Aug 2025 09:05PM UTC coverage: 0.482% (-94.9%) from 95.343%
0e37073d-109c-440c-949f-49d2aa86311b

push

circleci

web-flow
Replace per_page_options_for_select with custom component to avoid deprecation issue (#5186)

* Start creating new component to address deprecaton warning

* Replace per_page_options_for_select with custom component to avoid deprecation issue

Co-authored-by: Jane Sandberg <sandbergja@users.noreply.github.com>

---------

Co-authored-by: Ryan Jensen <rj1044@princeton.edu>
Co-authored-by: Jane Sandberg <sandbergja@users.noreply.github.com>

0 of 33 new or added lines in 1 file covered. (0.0%)

9374 existing lines in 213 files now uncovered.

47 of 9753 relevant lines covered (0.48%)

0.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/app/models/search_builder.rb
1
# frozen_string_literal: true
2

UNCOV
3
class SearchBuilder < Blacklight::SearchBuilder
×
UNCOV
4
  include Blacklight::Solr::SearchBuilderBehavior
×
UNCOV
5
  include BlacklightRangeLimit::RangeLimitBuilder
×
UNCOV
6
  include BlacklightHelper
×
7

UNCOV
8
  default_processor_chain.unshift(:conditionally_configure_json_query_dsl)
×
9

UNCOV
10
  self.default_processor_chain += %i[parslet_trick cleanup_boolean_operators
×
UNCOV
11
                                     cjk_mm wildcard_char_strip
×
UNCOV
12
                                     only_home_facets prepare_left_anchor_search
×
UNCOV
13
                                     series_title_results pul_holdings html_facets
×
UNCOV
14
                                     numismatics_advanced
×
UNCOV
15
                                     adjust_mm remove_unneeded_facets]
×
16

17
  # mutate the solr_parameters to remove words that are
18
  # boolean operators, but not intended as such.
UNCOV
19
  def cleanup_boolean_operators(solr_parameters)
×
UNCOV
20
    transform_queries!(solr_parameters) { |query| cleaned_query(query) }
×
UNCOV
21
  end
×
22

23
  # Blacklight uses Parslet https://rubygems.org/gems/parslet/versions/2.0.0 to parse the user query
24
  # and unfortunately Parslet gets confused when the user's query ends with "()". Here we tweak the
25
  # query to prevent the error and let the query to be parsed as if the ending "()" was not present.
26
  # Notice that we must update the value in `blacklight_params[:q]`
UNCOV
27
  def parslet_trick(_solr_parameters)
×
UNCOV
28
    return unless blacklight_params[:q].is_a?(String)
×
UNCOV
29
    return unless blacklight_params[:q].strip.end_with?("()")
×
30
    blacklight_params[:q] = blacklight_params[:q].strip.gsub("()", "")
×
UNCOV
31
  end
×
32

33
  # Only search for coin records when querying with the numismatics advanced search
UNCOV
34
  def numismatics_advanced(solr_parameters)
×
UNCOV
35
    return unless blacklight_params[:advanced_type] == 'numismatics'
×
UNCOV
36
    solr_parameters[:fq] ||= []
×
UNCOV
37
    solr_parameters[:fq] << "format:Coin"
×
UNCOV
38
  end
×
39

UNCOV
40
  def only_home_facets(solr_parameters)
×
UNCOV
41
    return if search_parameters? || advanced_search?
×
UNCOV
42
    solr_parameters['facet.field'] = blacklight_config.facet_fields.select { |_, v| v[:home] }.keys
×
UNCOV
43
    solr_parameters['facet.pivot'] = []
×
UNCOV
44
  end
×
45

46
  ##
47
  # Check if we are on an advanced search page
48
  # @return [Boolean]
UNCOV
49
  def advanced_search?
×
UNCOV
50
    blacklight_params[:advanced_type] == 'advanced' ||
×
UNCOV
51
      search_state.controller.try(:params).try(:[], :action) == 'advanced_search' ||
×
UNCOV
52
      blacklight_params[:advanced_type] == 'numismatics' ||
×
53
      # The next two are required for the advanced search gem
UNCOV
54
      blacklight_params[:search_field] == 'advanced' ||
×
UNCOV
55
      blacklight_params[:action] == 'numismatics'
×
UNCOV
56
  end
×
57

58
  ##
59
  # Check if any search parameters have been set
60
  # @return [Boolean]
UNCOV
61
  def search_parameters?
×
UNCOV
62
    search_query_present? || facet_query_present?
×
UNCOV
63
  end
×
64

UNCOV
65
  def conditionally_configure_json_query_dsl(_solr_parameters)
×
UNCOV
66
    advanced_fields = %w[all_fields title author subject left_anchor publisher in_series notes series_title isbn issn]
×
UNCOV
67
    add_edismax(advanced_fields:)
×
UNCOV
68
  end
×
69

UNCOV
70
  def adjust_mm(solr_parameters)
×
71
    # If the user is attempting a boolean OR query,
72
    # for example: activism OR "social justice"
73
    # don't want to cancel out the boolean OR with
74
    # an mm configuration that requires all the clauses
75
    # to be in the document
UNCOV
76
    return unless includes_written_boolean?
×
UNCOV
77
    solr_parameters['mm'] = 0
×
UNCOV
78
  end
×
79

UNCOV
80
  def includes_written_boolean?
×
UNCOV
81
    if advanced_search? && search_query_present?
×
UNCOV
82
      json_query_dsl_clauses&.any? { |clause| clause&.dig('query')&.include?('OR') }
×
UNCOV
83
    else
×
UNCOV
84
      blacklight_params[:q].to_s.split.include? 'OR'
×
UNCOV
85
    end
×
UNCOV
86
  end
×
87

88
  # When the user is viewing the values of a specific facet
89
  # by clicking the "more" link in a facet, solr doesn't
90
  # need to perform expensive calculations related to other
91
  # facets that the user is not displaying
92
  # :reek:FeatureEnvy
UNCOV
93
  def remove_unneeded_facets(solr_parameters)
×
UNCOV
94
    return unless facet
×
UNCOV
95
    remove_unneeded_stats(solr_parameters)
×
UNCOV
96
    solr_parameters.delete('facet.pivot') unless solr_parameters['facet.pivot']&.split(',')&.include? facet
×
UNCOV
97
    solr_parameters.delete('facet.query') unless solr_parameters['facet.query']&.any? { |query| query.partition(':').first == facet }
×
UNCOV
98
  end
×
99

UNCOV
100
  def wildcard_char_strip(solr_parameters)
×
UNCOV
101
    transform_queries!(solr_parameters) { |query| query.delete('?') }
×
UNCOV
102
  end
×
103

UNCOV
104
  private
×
105

UNCOV
106
    def search_query_present?
×
UNCOV
107
      !blacklight_params[:q].nil? || json_query_dsl_clauses&.any? { |clause| clause.dig('query')&.present? }
×
UNCOV
108
    end
×
109

UNCOV
110
    def facet_query_present?
×
UNCOV
111
      blacklight_params[:f].present? || blacklight_params[:action] == 'facet'
×
UNCOV
112
    end
×
113

UNCOV
114
    def json_query_dsl_clauses
×
UNCOV
115
      blacklight_params.dig('clause')&.values
×
UNCOV
116
    end
×
117

UNCOV
118
    def add_edismax(advanced_fields:)
×
UNCOV
119
      advanced_fields.each do |field|
×
UNCOV
120
        solr_params = blacklight_config.search_fields[field]['solr_parameters']
×
UNCOV
121
        edismax = solr_params.present? ? solr_params.dup : {}
×
UNCOV
122
        blacklight_config.search_fields[field]['clause_params'] = { edismax: }
×
UNCOV
123
      end
×
UNCOV
124
    end
×
125

126
    # :reek:FeatureEnvy
UNCOV
127
    def remove_unneeded_stats(solr_parameters)
×
UNCOV
128
      return if solr_parameters['stats.field'].to_a.include? facet
×
UNCOV
129
      solr_parameters.delete('stats')
×
UNCOV
130
      solr_parameters.delete('stats.field')
×
UNCOV
131
    end
×
132

133
    # :reek:DuplicateMethodCall
134
    # :reek:MissingSafeMethod
135
    # :reek:UtilityFunction
UNCOV
136
    def transform_queries!(solr_parameters)
×
UNCOV
137
      solr_parameters[:q] = yield solr_parameters[:q] if solr_parameters[:q]
×
UNCOV
138
      solr_parameters.dig('json', 'query', 'bool', 'must')&.map! do |search_element|
×
UNCOV
139
        search_element[:edismax][:query] = yield search_element[:edismax][:query]
×
UNCOV
140
        search_element
×
UNCOV
141
      end
×
UNCOV
142
    end
×
143

UNCOV
144
    def cleaned_query(query)
×
UNCOV
145
      return query if query.nil?
×
UNCOV
146
      query.gsub(/([A-Z]) (NOT|OR|AND) ([A-Z])/) do
×
UNCOV
147
        "#{Regexp.last_match(1)} #{Regexp.last_match(2).downcase} #{Regexp.last_match(3)}"
×
UNCOV
148
      end
×
UNCOV
149
    end
×
UNCOV
150
end
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc