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

pulibrary / orangelight / d468d197-475b-45e5-b002-efe7b039dc42

14 Jul 2025 03:56PM UTC coverage: 95.35% (-0.02%) from 95.366%
d468d197-475b-45e5-b002-efe7b039dc42

Pull #4962

circleci

web-flow
Add a new bookmark button component (#4969)

* Add a new bookmark button component

This bookmark button replaces the bookmark checkbox on the search
results page.

The first time a non-logged in user presses the button, they are
shown a dialog that encourages them to sign in.  The bookmark is
added, whether or not they choose to sign in.  We then record
the timestamp in localStorage, and do not show them the dialog
again as long as that localStorage is present.

Advances #4910
Advances #4927

* set js: true in spec/features/bookmarks_spec.rb

* Update mocking in component test

Co-authored-by: Christina Chortaria <christinach@users.noreply.github.com>

---------

Co-authored-by: Christina Chortaria <actspatial@gmail.com>
Co-authored-by: Christina Chortaria <christinach@users.noreply.github.com>
Pull Request #4962: Orangelight pos workcycle 07-07-2025

80 of 84 new or added lines in 14 files covered. (95.24%)

1 existing line in 1 file now uncovered.

6029 of 6323 relevant lines covered (95.35%)

1515.9 hits per line

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

85.94
/app/helpers/holdings_helper.rb
1
# frozen_string_literal: false
2

3
# rubocop:disable Metrics/ModuleLength
4
module HoldingsHelper
3✔
5
  # Generate the markup block for individual search result items containing holding information
6
  # @param document [SolrDocument] the Solr Document retrieved in the search result set
7
  # @return [String] the markup
8

9
  def holding_block_search(document)
3✔
10
    block = ''.html_safe
817✔
11
    holdings_hash = document.holdings_all_display
817✔
12
    @scsb_multiple = false
817✔
13

14
    holdings_hash.first(2).each do |id, holding|
817✔
15
      block << first_two_holdings_block(document, id, holding)
746✔
16
    end
17

18
    block << controller.view_context.render(Holdings::OnlineHoldingsComponent.new(document:))
817✔
19

20
    if @scsb_multiple == true || holdings_hash.length > 2
817✔
21
      block << view_record_for_full_avail_li(document)
45✔
22
    elsif !holdings_hash.empty?
772✔
23
      block << view_record_for_full_avail_li_two(document)
637✔
24
    end
25

26
    if block.empty?
817✔
27
      content_tag(:div, t('blacklight.holdings.search_missing'))
39✔
28
    else
29
      content_tag(:ul, block)
778✔
30
    end
31
  end
32

33
  # rubocop:disable Metrics/MethodLength
34
  # Currently having trouble breaking up this method further due to the "check_availability" variable
35
  def first_two_holdings_block(document, id, holding)
3✔
36
    location = holding_location(holding)
746✔
37
    check_availability = render_availability?
746✔
38
    accumulator = ''.html_safe
746✔
39
    if holding['library'] == 'Online'
746✔
40
      rendered_online_holdings_block = controller.view_context.render(Holdings::OnlineHoldingsComponent.new(document:))
×
NEW
41
      return rendered_online_holdings_block if rendered_online_holdings_block.present?
×
42

43
      check_availability = render_availability?
×
NEW
44
      accumulator << empty_link_online_holding_block
×
45

46
    else
47
      if holding['dspace'] || holding['location_code'] == 'rare$num'
746✔
48
        check_availability = false
25✔
49
        accumulator << dspace_or_numismatics_holding_block(location)
25✔
50
      elsif /^scsb.+/.match? location[:code]
721✔
51
        check_availability = false
9✔
52
        unless holding['items'].nil?
9✔
53
          @scsb_multiple = true unless holding['items'].one?
9✔
54
          accumulator << scsb_item_block(holding)
9✔
55
        end
56
      elsif holding['dspace'].nil?
712✔
57
        accumulator << dspace_not_defined_block(location)
712✔
58
      else
59
        check_availability = false
×
60
        accumulator << under_embargo_block
×
61
      end
62
      accumulator << library_location_div(holding, document, id)
746✔
63
    end
64
    holding_status_li(accumulator, document, check_availability, id, holding)
746✔
65
  end
66
  # rubocop:enable Metrics/MethodLength
67

68
  def empty_link_online_holding_block
3✔
69
    data = content_tag(
×
70
      :span,
71
      'Link Missing',
72
      class: 'availability-icon badge bg-secondary'
73
    )
74
    data << content_tag(
×
75
      :div,
76
      'Online access is not currently available.',
77
      class: 'library-location'
78
    )
79
  end
80

81
  def onsite_access_span
3✔
82
    content_tag(
27✔
83
      :span,
84
      'Available',
85
      class: 'availability-icon badge bg-success'
86
    )
87
  end
88

89
  def dspace_or_numismatics_holding_block(_location)
3✔
90
    onsite_access_span
25✔
91
  end
92

93
  def scsb_item_block(holding)
3✔
94
    scsb_supervised_items?(holding) ? scsb_supervised_item : scsb_unsupervised_item(holding)
9✔
95
  end
96

97
  def scsb_supervised_item
3✔
98
    onsite_access_span
2✔
99
  end
100

101
  def scsb_unsupervised_item(holding)
3✔
102
    content_tag(
7✔
103
      :span,
104
      '',
105
      class: 'availability-icon badge',
106
      data: {
107
        'scsb-availability': 'true',
108
        'scsb-barcode': holding['items'].first['barcode'].to_s
109
      }
110
    )
111
  end
112

113
  def dspace_not_defined_block(_location)
3✔
114
    content_tag(
712✔
115
      :span,
116
      'Loading...',
117
      class: 'availability-icon badge bg-secondary'
118
    )
119
  end
120

121
  def under_embargo_block
3✔
122
    content_tag(
×
123
      :span,
124
      'Request',
125
      class: 'availability-icon badge bg-danger'
126
    )
127
  end
128

129
  def library_location_div(holding, document, id)
3✔
130
    content_tag(
746✔
131
      :div,
132
      search_location_display(holding),
133
      class: 'library-location',
134
      data: {
135
        location: true,
136
        record_id: document['id'],
137
        holding_id: id
138
      }
139
    )
140
  end
141

142
  def holding_status_li(accumulator, document, check_availability, id, holding)
3✔
143
    location = holding_location(holding)
746✔
144
    content_tag(
746✔
145
      :li,
146
      accumulator,
147
      class: 'holding-status',
148
      data: {
149
        availability_record: check_availability,
150
        record_id: document['id'],
151
        holding_id: id,
152
        temp_location_code: holding['temp_location_code'],
153
        aeon: aeon_location?(location),
154
        bound_with: document.bound_with?
155
      }.compact
156
    )
157
  end
158

159
  def view_record_for_full_avail_li(document)
3✔
160
    content_tag(
45✔
161
      :li,
162
      link_to(
163
        'Available',
164
        solr_document_path(document['id']),
165
        class: 'availability-icon badge bg-secondary more-info'
166
      )
167
    )
168
  end
169

170
  def view_record_for_full_avail_li_two(document)
3✔
171
    content_tag(
637✔
172
      :li,
173
      link_to(
174
        '',
175
        solr_document_path(document['id']),
176
        class: 'availability-icon more-info'
177
      ),
178
      class: 'empty',
179
      data: { record_id: document['id'] }
180
    )
181
  end
182
end
183
# rubocop:enable Metrics/ModuleLength
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