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

pulibrary / orangelight / 1f4a4078-318e-4cda-80e3-f689f19570eb

31 Mar 2025 08:05PM UTC coverage: 95.442% (+0.005%) from 95.437%
1f4a4078-318e-4cda-80e3-f689f19570eb

Pull #3386

circleci

christinach
Add browsables_controller spec to test facet and vocab_param
Test browsables helper vocab_type method, browsables_controllet vocabulary_search_on_facet
Pull Request #3386: Adds vocabulary column to subject table

42 of 43 new or added lines in 4 files covered. (97.67%)

3 existing lines in 1 file now uncovered.

6031 of 6319 relevant lines covered (95.44%)

1516.75 hits per line

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

94.78
/app/controllers/orangelight/browsables_controller.rb
1
# frozen_string_literal: true
2

3
class Orangelight::BrowsablesController < ApplicationController
3✔
4
  # GET /orangelight/names
5
  # GET /orangelight/names.json
6

7
  def index
3✔
8
    # if rpp isn't specified default is 50
9
    # if rpp has values other than 10, 25, 50, 100 then set it to 50
10
    # previous/next page links need to pass
11
    # manually set rpp
12

13
    assign_values
28✔
14

15
    # makes sure valid page is displayed
16
    if !(@last_id - @rpp + 1..@last_id).cover?(@start) && @is_last
28✔
17
      @start = @last_id - @rpp + 1
8✔
18
      @start = 1 if @start < 1 # catch for start ids higher than last id
8✔
19
    end
20

21
    assign_pagination_values
28✔
22

23
    @facet = facet
28✔
24
    @list_name = list_name
28✔
25

26
    respond_to do |format|
28✔
27
      format.html # index.html.erb
28✔
28
      format.json { render json: @orangelight_browsables }
46✔
29
    end
30
  end
31

32
  private
3✔
33

34
    def assign_values
3✔
35
      @model = model_table_name
28✔
36
      @rpp = rpp
28✔
37
      @page_link = page_link
28✔
38

39
      # @start gets the id of the first entry to display on page
40
      # specific ids are given based on search results
41
      @start = first_model_id
28✔
42

43
      populate_search_results
28✔
44

45
      # gets last page of table's results
46
      @last_id = last_model_id
28✔
47

48
      # makes sure no next page link is shown for last page
49
      @is_last = (@last_id - @rpp + 1) <= @start
28✔
50
    end
51

52
    def rpp
3✔
53
      if rpp_param.nil?
28✔
54
        50
12✔
55
      else
56
        validate_rpp(requested_rpp)
16✔
57
      end
58
    end
59

60
    def page_link
3✔
61
      if rpp_param.nil?
28✔
62
        '?'
12✔
63
      else
64
        size = validate_rpp(requested_rpp)
16✔
65
        "?rpp=#{size}&"
16✔
66
      end
67
    end
68

69
    def validate_rpp(size)
3✔
70
      rpp_range = [10, 25, 50, 100]
32✔
71
      if rpp_range.include? size
32✔
72
        size
24✔
73
      else
74
        50
8✔
75
      end
76
    end
77

78
    def populate_search_results
3✔
79
      return if query_param.nil?
28✔
80
      # 'subject_facet' is the default vocabulary type if there is no vocabulary type specified
81
      search_result = if vocabulary_search_on_facet == 'subject_facet'
12✔
82
                        model_param.where('sort <= ?', search_term).order('sort').last
12✔
83
                      else
NEW
84
                        model_param.where(sort: search_term).where(vocabulary: vocabulary_search_on_facet).first
×
85
                      end
86

87
      return if search_result.nil?
12✔
88

89
      populate_search_params(search_result)
11✔
90
    end
91

92
    def populate_search_params(search_result)
3✔
93
      @search_result = search_result.label
11✔
94
      @search_term = search_term
11✔
95
      @exact_match = search_term == search_result.sort
11✔
96
      @match = search_result.id
11✔
97
      @model == 'subjects' ? @match_vocabulary = search_result.vocabulary : nil
11✔
98
      @start = search_result.id - 1
11✔
99
      @start -= 1 if @exact_match
11✔
100
      @start = 1 if @start < 1
11✔
101
      @query = query_param
11✔
102
    end
103

104
    def assign_pagination_values
3✔
105
      @is_first = @start == 1
28✔
106

107
      @page_last = if (@start + @rpp - 1) > @last_id
28✔
108
                     @last_id
3✔
109
                   else
110
                     @start + @rpp - 1
25✔
111
                   end
112

113
      @prev = @start - @rpp
28✔
114
      @prev = 1 if @prev < 1
28✔
115
      @next = @start + @rpp
28✔
116

117
      @orangelight_browsables = model_param.where(id: @start..@page_last)
28✔
118
    end
119

120
    def facet
3✔
121
      if browsing_names?
29✔
122
        'author_s'
1✔
123
      elsif browsing_subjects?
28✔
124
        vocab_param
5✔
125
      elsif browsing_titles?
23✔
126
        'name_title_browse_s'
1✔
127
      end
128
    end
129

130
    # Retrieve the Model mapped to the request parameter
131
    # @return [Class]
132
    def model_param
3✔
133
      params[:model]
264✔
134
    end
135

136
    def vocab_param
3✔
137
      params[:vocab]
18✔
138
    end
139

140
    def vocabulary_search_on_facet
3✔
141
      # TODO: move vocab_types to a config file
142
      # the hash also exists in vocab_type method
143
      vocab_types = {
20✔
144
        'Library of Congress subject heading' => 'lc_subject_facet',
145
        'Library of Congress genre/form terms for library and archival materials' => 'lcgft_genre_facet',
146
        'Art & architecture thesaurus' => 'aat_genre_facet',
147
        'Homosaurus terms' => 'homoit_subject_facet',
148
        'Homosaurus genres' => 'homoit_genre_facet',
149
        'Rare books genre term' => 'rbgenr_genre_facet',
150
        'Chinese traditional subjects' => 'siku_subject_facet',
151
        'Locally assigned term' => 'local_subject_facet'
152
      }
153
      vocab_types_invert = vocab_types.invert
20✔
154
      vocab_types_invert.fetch(vocab_param, 'subject_facet')
20✔
155
    end
156

157
    # Generates the name of the table mapped to the model in the request
158
    # @return [String]
159
    def model_table_name
3✔
160
      model_name = model_param.name
169✔
161
      model_class = model_name.demodulize
169✔
162
      model_class.tableize
169✔
163
    end
164

165
    # Determines whether or not the client is requesting to browse call numbers
166
    # @return [Boolean]
167
    def browsing_call_numbers?
3✔
168
      model_table_name == 'call_numbers'
34✔
169
    end
170

171
    # Determines whether or not the client is requesting to browse names
172
    # @return [Boolean]
173
    def browsing_names?
3✔
174
      model_table_name == 'names'
29✔
175
    end
176

177
    # Determines whether or not the client is requesting to browse subjects
178
    # @return [Boolean]
179
    def browsing_subjects?
3✔
180
      model_table_name == 'subjects'
27✔
181
    end
182

183
    # Determines whether or not the client is requesting to browse titles
184
    # @return [Boolean]
185
    def browsing_titles?
3✔
186
      model_table_name == 'name_titles'
23✔
187
    end
188

189
    # Generates the name of the list (based upon the model for the request)
190
    # @return [String]
191
    def list_name
3✔
192
      value = model_table_name.humanize
28✔
193
      return 'author-title headings' if value == 'Name titles'
28✔
194
      value
27✔
195
    end
196

197
    # Retrieves the ID requested by the client
198
    # @return [String]
199
    def id_param
3✔
200
      params[:id]
×
201
    end
202

203
    # Retrieves the query transmitted by the client
204
    # @return [String]
205
    def query_param
3✔
206
      params[:q]
73✔
207
    end
208

209
    # Retrieves the ID for the first object requested by the client
210
    # @return [String]
211
    def start_param
3✔
212
      params[:start]
42✔
213
    end
214

215
    # Retrieves the ID of the first object for this request
216
    # @return [Integer]
217
    def first_model_id
3✔
218
      return 1 if start_param.nil?
28✔
219
      start_param.to_i
14✔
220
    end
221

222
    # Normalizes the query transmitted by the client
223
    # @return [String]
224
    def search_term
3✔
225
      return StringFunctions.cn_normalize(query_param) if browsing_call_numbers?
34✔
226

227
      query_param.normalize_em
×
228
    end
229

230
    # Retrieves the ID of the last object for this request
231
    # @return [Integer]
232
    def last_model_id
3✔
233
      return model_param.last.id if model_param.last
28✔
234
      1
×
235
    end
236

237
    # Retrieves the requested rows per page (rpp) from the client
238
    # @return [String]
239
    def rpp_param
3✔
240
      params[:rpp]
88✔
241
    end
242

243
    # Generates the requested rows per page as an Integer
244
    # @return [Integer]
245
    def requested_rpp
3✔
246
      rpp_param.to_i
32✔
247
    end
248

249
    # Use callbacks to share common setup or constraints between actions.
250
    def set_orangelight_browsable
3✔
251
      @orangelight_browsable = model_param.find(id_param) if model_param
×
252
    end
253

254
    # Never trust parameters from the scary internet; run the params we receive through an allowlist
255
    def orangelight_browsable_params
3✔
256
      params.require(:orangelight_browsable).permit(:model, :id)
×
257
    end
258
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