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

pulibrary / orangelight / c34af396-9531-4b7f-871a-07eb9ec54cda

11 Dec 2024 06:14PM UTC coverage: 96.407% (-0.03%) from 96.437%
c34af396-9531-4b7f-871a-07eb9ec54cda

push

circleci

web-flow
Merge pull request #4628 from pulibrary/move-excessive-paging

Move excessive paging out of search builder into controllers

14 of 14 new or added lines in 2 files covered. (100.0%)

2 existing lines in 2 files now uncovered.

6038 of 6263 relevant lines covered (96.41%)

1548.31 hits per line

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

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

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

8
  default_processor_chain.unshift(:conditionally_configure_json_query_dsl)
3✔
9

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

17
  # mutate the solr_parameters to remove words that are
18
  # boolean operators, but not intended as such.
19
  def cleanup_boolean_operators(solr_parameters)
3✔
20
    solr_parameters[:q] = cleaned_query(solr_parameters[:q])
233✔
21
    return solr_parameters unless using_json_query_dsl(solr_parameters)
233✔
22

23
    solr_parameters.dig('json', 'query', 'bool', 'must').map! do |search_element|
82✔
24
      search_element[:edismax][:query] = cleaned_query(search_element[:edismax][:query])
84✔
25
      search_element
84✔
26
    end
27
  end
28

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

39
  # Only search for coin records when querying with the numismatics advanced search
40
  def numismatics_advanced(solr_parameters)
3✔
41
    return unless blacklight_params[:advanced_type] == 'numismatics'
228✔
42
    solr_parameters[:fq] ||= []
5✔
43
    solr_parameters[:fq] << "format:Coin"
5✔
44
  end
45

46
  def numismatics_facets(solr_parameters)
3✔
47
    return unless blacklight_params[:action] == 'numismatics'
228✔
48
    blacklight_config.advanced_search[:form_solr_parameters]['facet.field'] = blacklight_config.numismatics_search['facet_fields']
7✔
49
    solr_parameters['facet.field'] = blacklight_config.numismatics_search['facet_fields']
7✔
50
  end
51

52
  def cleaned_query(query)
3✔
53
    return query if query.nil?
317✔
54
    query.gsub(/([A-Z]) (NOT|OR|AND) ([A-Z])/) do
123✔
55
      "#{Regexp.last_match(1)} #{Regexp.last_match(2).downcase} #{Regexp.last_match(3)}"
3✔
56
    end
57
  end
58

59
  def facets_for_advanced_search_form(solr_p)
3✔
60
    # Reject any facets that are meant to display on the advanced
61
    # search form, so that the form displays accurate counts for
62
    # them in its dropdowns
63
    advanced_search_facets = blacklight_config.advanced_search.form_solr_parameters['facet.field']
8✔
64
    solr_p[:fq]&.compact!
8✔
65
    solr_p[:fq]&.reject! do |facet_from_query|
8✔
66
      advanced_search_facets.any? { |facet_to_exclude| facet_from_query.include? facet_to_exclude }
29✔
67
    end
68
  end
69

70
  def only_home_facets(solr_parameters)
3✔
71
    return if search_parameters? || advanced_search?
231✔
72
    solr_parameters['facet.field'] = blacklight_config.facet_fields.select { |_, v| v[:home] }.keys
2,873✔
73
    solr_parameters['facet.pivot'] = []
36✔
74
  end
75

76
  ##
77
  # Check if we are on an advanced search page
78
  # @return [Boolean]
79
  def advanced_search?
3✔
80
    blacklight_params[:advanced_type] == 'advanced' ||
92✔
81
      search_state.controller.try(:params).try(:[], :action) == 'advanced_search' ||
82
      blacklight_params[:advanced_type] == 'numismatics' ||
83
      # The next two are required for the advanced search gem
84
      blacklight_params[:search_field] == 'advanced' ||
85
      blacklight_params[:action] == 'numismatics'
86
  end
87

88
  ##
89
  # Check if any search parameters have been set
90
  # @return [Boolean]
91
  def search_parameters?
3✔
92
    search_query_present? || facet_query_present?
231✔
93
  end
94

95
  def conditionally_configure_json_query_dsl(_solr_parameters)
3✔
96
    advanced_fields = %w[all_fields title author subject left_anchor publisher in_series notes series_title isbn issn]
230✔
97
    add_edismax(advanced_fields:)
230✔
98
  end
99

100
  def adjust_mm(solr_parameters)
3✔
101
    # If the user is attempting a boolean OR query,
102
    # for example: activism OR "social justice"
103
    # don't want to cancel out the boolean OR with
104
    # an mm configuration that requires all the clauses
105
    # to be in the document
106
    return unless blacklight_params[:q].to_s.split.include? 'OR'
230✔
107
    solr_parameters['mm'] = 0
3✔
108
  end
109

110
  private
3✔
111

112
    def search_query_present?
3✔
113
      !blacklight_params[:q].nil? || json_query_dsl_clauses&.any? { |clause| clause.dig('query')&.present? }
281✔
114
    end
115

116
    def facet_query_present?
3✔
117
      blacklight_params[:f].present?
107✔
118
    end
119

120
    def json_query_dsl_clauses
3✔
121
      blacklight_params.dig('clause')&.values
138✔
122
    end
123

124
    def q_param_needs_boolean_cleanup(solr_parameters)
3✔
125
      solr_parameters[:q].present? &&
×
126
        cleaned_query(solr_parameters[:q]) == solr_parameters[:q]
127
    end
128

129
    def using_json_query_dsl(solr_parameters)
3✔
130
      solr_parameters.fetch('json', nil)&.fetch('query', nil)&.fetch('bool', nil)&.fetch('must', nil)&.present?
233✔
131
    end
132

133
    def add_edismax(advanced_fields:)
3✔
134
      advanced_fields.each do |field|
230✔
135
        solr_params = blacklight_config.search_fields[field]['solr_parameters']
2,530✔
136
        edismax = solr_params.present? ? solr_params.dup : {}
2,530✔
137
        blacklight_config.search_fields[field]['clause_params'] = { edismax: }
2,530✔
138
      end
139
    end
140
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