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

pulibrary / orangelight / f9480963-c7aa-4eee-b338-2fb5f623d117

16 Jul 2025 08:36PM UTC coverage: 95.367% (+0.005%) from 95.362%
f9480963-c7aa-4eee-b338-2fb5f623d117

Pull #4992

circleci

christinach
Display only the library name in search results
generate new reek

In the search results availability should only display the Library name.
Pull Request #4992: Display only the library name in search results

14 of 14 new or added lines in 1 file covered. (100.0%)

2 existing lines in 1 file now uncovered.

6052 of 6346 relevant lines covered (95.37%)

1513.17 hits per line

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

95.68
/app/helpers/application_helper.rb
1
# frozen_string_literal: false
2

3
module ApplicationHelper
3✔
4
  require './lib/orangelight/string_functions'
3✔
5

6
  # Check the Rails Environment. Currently used for Matomo to support production.
7
  def rails_env?
3✔
8
    Rails.env.production?
484✔
9
  end
10

11
  def show_regular_search?
3✔
12
    !((%w[generate numismatics advanced_search].include? params[:action]) || (%w[advanced].include? params[:controller]))
968✔
13
  end
14

15
  # Generate the markup for the block containing links for requests to item holdings
16
  # holding record fields: 'location', 'library', 'location_code', 'call_number', 'call_number_browse',
17
  # 'shelving_title', 'location_note', 'electronic_access_1display', 'location_has', 'location_has_current',
18
  # 'indexes', 'supplements'
19
  # process online and physical holding information at the same time
20
  # @param [SolrDocument] document - record display fields
21
  # @return [String] online - online holding info html
22
  # @return [String] physical - physical holding info html
23
  def holding_request_block(document)
3✔
24
    adapter = HoldingRequestsAdapter.new(document, Bibdata)
108✔
25
    markup_builder = HoldingRequestsBuilder.new(adapter:,
108✔
26
                                                online_markup_builder: OnlineHoldingsMarkupBuilder,
27
                                                physical_markup_builder: PhysicalHoldingsMarkupBuilder)
28
    online_markup, physical_markup = markup_builder.build
108✔
29
    [online_markup, physical_markup]
108✔
30
  end
31

32
  # Determine whether or not a ReCAP holding has items restricted to supervised use
33
  # @param holding [Hash] holding values
34
  # @return [TrueClass, FalseClass]
35
  def scsb_supervised_items?(holding)
3✔
36
    if holding.key? 'items'
12✔
37
      restricted_items = holding['items'].select { |item| item['use_statement'] == 'Supervised Use' }
63✔
38
      restricted_items.count == holding['items'].count
12✔
39
    else
40
      false
×
41
    end
42
  end
43

44
  # Blacklight index field helper for the facet "series_display"
45
  # @param args [Hash]
46
  def series_results(args)
3✔
47
    series_display =
48
      if params[:f1] == 'in_series'
3✔
49
        same_series_result(params[:q1], args[:document][args[:field]])
×
50
      else
51
        args[:document][args[:field]]
3✔
52
      end
53
    series_display.join(', ')
3✔
54
  end
55

56
  # Retrieve the same series for that one being displayed
57
  # @param series [String] series name
58
  # @param series_display [Array<String>] series being displayed
59
  # @param [Array<String>] similarly named series
60
  def same_series_result(series, series_display)
3✔
61
    series_display.select { |t| t.start_with?(series) }
8✔
62
  end
63

64
  # Determines whether or not this is an aeon location (for an item holding)
65
  # @param location [Hash] location values
66
  # @return [TrueClass, FalseClass]
67
  def aeon_location?(location)
3✔
68
    location.nil? ? false : location[:aeon_location]
755✔
69
  end
70

71
  # Retrieve the location information for a given item holding
72
  # @param [Hash] holding values
73
  def holding_location(holding)
3✔
74
    location_code = holding.fetch('location_code', '').to_sym
1,502✔
75
    resolved_location = Bibdata.holding_locations[location_code]
1,502✔
76
    resolved_location ? resolved_location : {}
1,502✔
77
  end
78

79
  # Location display in the search results page
80
  def search_location_display(holding)
3✔
81
    location = holding_library_label(holding)
751✔
82
    (location.present? && holding['call_number'].present?)
751✔
83

84
    location_display = content_tag(:div, location, class: 'results_location') + " " +
751✔
85
                       content_tag(:div, holding['call_number'], class: 'call-number')
86
    location_display.html_safe
751✔
87
  end
88

89
  def title_hierarchy(args)
3✔
90
    titles = JSON.parse(args[:document][args[:field]])
6✔
91
    all_links = []
6✔
92
    dirtags = []
6✔
93

94
    titles.each do |title|
6✔
95
      title_links = []
6✔
96
      title.each_with_index do |part, index|
6✔
97
        link_accum = StringFunctions.trim_punctuation(title[0..index].join(' '))
21✔
98
        title_links << link_to(part, "/?search_field=left_anchor&q=#{CGI.escape link_accum}", class: 'search-title', 'data-original-title' => "Search: #{link_accum}", title: "Search: #{link_accum}")
21✔
99
      end
100
      full_title = title.join(' ')
6✔
101
      dirtags << StringFunctions.trim_punctuation(full_title.dir.to_s)
6✔
102
      all_links << title_links.join('<span> </span>').html_safe
6✔
103
    end
104

105
    if all_links.length == 1
6✔
106
      all_links = content_tag(:div, all_links[0], dir: dirtags[0])
6✔
107
    else
108
      all_links = all_links.map.with_index { |l, i| content_tag(:li, l, dir: dirtags[i]) }
×
UNCOV
109
      all_links = content_tag(:ul, all_links.join.html_safe)
×
110
    end
111
    all_links
6✔
112
  end
113

114
  def action_notes_display(args)
3✔
115
    action_notes = JSON.parse(args[:document][args[:field]])
3✔
116
    lines = action_notes.map do |note|
3✔
117
      if note["uri"].present?
4✔
118
        link_to(note["description"], note["uri"])
1✔
119
      else
120
        note["description"]
3✔
121
      end
122
    end
123

124
    if lines.length == 1
3✔
125
      lines = content_tag(:div, lines[0])
2✔
126
    else
127
      lines = lines.map.with_index { |l| content_tag(:li, l) }
3✔
128
      lines = content_tag(:ul, lines.join.html_safe)
1✔
129
    end
130
    lines
3✔
131
  end
132

133
  def name_title_hierarchy(args)
3✔
134
    name_titles = JSON.parse(args[:document][args[:field]])
23✔
135
    all_links = []
23✔
136
    dirtags = []
23✔
137
    name_titles.each do |name_t|
23✔
138
      name_title_links = []
116✔
139
      name_t.each_with_index do |part, i|
116✔
140
        link_accum = StringFunctions.trim_punctuation(name_t[0..i].join(' '))
344✔
141
        if i.zero?
344✔
142
          next if args[:field] == 'name_uniform_title_1display'
116✔
143
          name_title_links << link_to(part, "/?f[author_s][]=#{CGI.escape link_accum}", class: 'search-name-title', 'data-original-title' => "Search: #{link_accum}")
103✔
144
        else
145
          name_title_links << link_to(part, "/?f[name_title_browse_s][]=#{CGI.escape link_accum}", class: 'search-name-title', 'data-original-title' => "Search: #{link_accum}")
228✔
146
        end
147
      end
148
      full_name_title = name_t.join(' ')
116✔
149
      dirtags << StringFunctions.trim_punctuation(full_name_title.dir.to_s)
116✔
150
      name_title_links << link_to('[Browse]', "/browse/name_titles?q=#{CGI.escape full_name_title}", class: 'browse-name-title', 'data-original-title' => "Browse: #{full_name_title}", dir: full_name_title.dir.to_s)
116✔
151
      all_links << name_title_links.join('<span> </span>').html_safe
116✔
152
    end
153

154
    if all_links.length == 1
23✔
155
      all_links = content_tag(:div, all_links[0], dir: dirtags[0])
8✔
156
    else
157
      all_links = all_links.map.with_index { |l, i| content_tag(:li, l, dir: dirtags[i]) }
123✔
158
      all_links = content_tag(:ul, all_links.join.html_safe)
15✔
159
    end
160
    all_links
23✔
161
  end
162

163
  def format_render(args)
3✔
164
    args[:document][args[:field]].join(', ')
107✔
165
  end
166

167
  def location_has(args)
3✔
168
    location_notes = JSON.parse(args[:document][:holdings_1display]).collect { |_k, v| v['location_has'] }.flatten
4✔
169
    if location_notes.length > 1
2✔
170
      content_tag(:ul) do
1✔
171
        location_notes.map { |note| content_tag(:li, note) }.join.html_safe
3✔
172
      end
173
    else
174
      location_notes
1✔
175
    end
176
  end
177

178
  def bibdata_location_code_to_sym(value)
3✔
179
    Bibdata.holding_locations[value.to_sym]
773✔
180
  end
181

182
  def render_location_code(value)
3✔
183
    values = normalize_location_code(value).map do |loc|
4,662✔
184
      location = Bibdata.holding_locations[loc.to_sym]
4,665✔
185
      location.nil? ? loc : "#{loc}: #{location_full_display(location)}"
4,665✔
186
    end
187
    values.one? ? values.first : values
4,662✔
188
  end
189

190
  # Depending on the url, we sometimes get strings, arrays, or hashes
191
  # Returns Array of locations
192
  def normalize_location_code(value)
3✔
193
    case value
4,662✔
194
    when String
195
      Array(value)
4,658✔
196
    when Array
197
      value
2✔
198
    when Hash, ActiveSupport::HashWithIndifferentAccess
199
      value.values
2✔
200
    else
UNCOV
201
      value
×
202
    end
203
  end
204

205
  def holding_location_label(holding)
3✔
206
    location_code = holding['location_code']
24✔
207
    bibdata_location = bibdata_location_code_to_sym(location_code) unless location_code.nil?
24✔
208
    # If the Bibdata location is nil, use the location value from the solr document.
209
    alma_location_display(holding, bibdata_location) unless bibdata_location.blank? && holding.blank?
24✔
210
  end
211

212
  def holding_library_label(holding)
3✔
213
    location_code = holding['location_code']
751✔
214
    bibdata_location = bibdata_location_code_to_sym(location_code) unless location_code.nil?
751✔
215
    return holding['library'] if bibdata_location.nil?
751✔
216

217
    alma_library_display(holding, bibdata_location) unless bibdata_location.blank? && holding.blank?
746✔
218
  end
219

220
  # Alma location display on search results
221
  def alma_location_display(holding, location)
3✔
222
    if location.nil?
23✔
223
      [holding['library'], holding['location']].select(&:present?).join(' - ')
3✔
224
    else
225
      [location['library']['label'], location['label']].select(&:present?).join(' - ')
20✔
226
    end
227
  end
228

229
  def alma_library_display(holding, bibdata_location)
3✔
230
    return holding['library'] if bibdata_location.nil?
746✔
231
    bibdata_location['library']['label']
746✔
232
  end
233

234
  # location = Bibdata.holding_locations[value.to_sym]
235
  def location_full_display(loc)
3✔
236
    loc['label'] == '' ? loc['library']['label'] : loc['library']['label'] + ' - ' + loc['label']
3,837✔
237
  end
238

239
  def html_safe(args)
3✔
240
    args[:document][args[:field]].each_with_index { |v, i| args[:document][args[:field]][i] = v.html_safe }
×
241
  end
242

243
  def current_year
3✔
244
    DateTime.now.year
1✔
245
  end
246

247
  # Construct an adapter for Solr Documents and the bib. data service
248
  # @return [HoldingRequestsAdapter]
249
  def holding_requests_adapter
3✔
250
    HoldingRequestsAdapter.new(@document, Bibdata)
121✔
251
  end
252

253
  # Returns true for locations with remote storage.
254
  # Remote storage locations have a value of 'recap_rmt' in Alma.
255
  def remote_storage?(location_code)
3✔
256
    Bibdata.holding_locations[location_code]["remote_storage"] == 'recap_rmt'
133✔
257
  end
258

259
  # Returns true for locations where the user can walk and fetch an item.
260
  # Currently this logic is duplicated in Javascript code in availability.es6
261
  def find_it_location?(location_code)
3✔
262
    return false if remote_storage?(location_code)
133✔
263
    return false if (location_code || "").start_with?("plasma$", "marquand$")
107✔
264

265
    return false if StackmapService::Url.missing_stackmap_reserves.include?(location_code)
103✔
266

267
    true
103✔
268
  end
269

270
  # Testing this feature with Voice Over - reading the Web content
271
  # If language defaults to english 'en' when no language_iana_primary_s exists then:
272
  # for cyrilic: for example russian, voice over will read each character as: cyrilic <character1>, cyrilic <character2>
273
  # for japanese it announces <character> ideograph
274
  # If there is no lang attribute it announces the same as having lang='en'
275
  def language_iana
3✔
276
    @document[:language_iana_s].present? ? @document[:language_iana_s].first : 'en'
129✔
277
  end
278

279
  def should_show_viewer?
3✔
280
    request.human? && controller.action_name != "librarian_view"
110✔
281
  end
282
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