Skip to content

Commit b5d3164

Browse files
committed
Address code review feedback
1 parent a516eec commit b5d3164

File tree

4 files changed

+60
-51
lines changed

4 files changed

+60
-51
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ may have unexpected consequences if applied to other TIMDEX UI apps.
116116
- `REQUEST_PERIOD` - time in minutes used along with `REQUESTS_PER_PERIOD`
117117
- `REDIRECT_REQUESTS_PER_PERIOD`- number of requests that can be made that the query string starts with our legacy redirect parameter to throttle per `REQUEST_PERIOD`
118118
- `REDIRECT_REQUEST_PERIOD`- time in minutes used along with `REDIRECT_REQUEST_PERIOD`
119-
- `RESULTS_PER_PAGE`: The number of results to display per page. Use an odd number to avoid peculiarities. Defaults to 20 if unset.
119+
- `RESULTS_PER_PAGE`: The number of results to display per page. Use an even number to avoid peculiarities. Defaults to 20 if unset.
120120
- `SENTRY_DSN`: Client key for Sentry exception logging.
121121
- `SENTRY_ENV`: Sentry environment for the application. Defaults to 'unknown' if unset.
122122
- `TACOS_SOURCE`: If set, this value is sent to TACOS (as the `sourceSystem` value) to distinguish which application

app/controllers/search_controller.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def load_geodata_results
6666
return unless @errors.nil?
6767

6868
hits = response.dig(:data, 'search', 'hits') || 0
69-
@pagination = Analyzer.new(@enhanced_query, { hits: hits }, :timdex).pagination
69+
@pagination = Analyzer.new(@enhanced_query, hits, :timdex).pagination
7070
raw_results = extract_results(response)
7171
@results = NormalizeTimdexResults.new(raw_results, @enhanced_query[:q]).normalize
7272
@filters = extract_filters(response)
@@ -98,7 +98,8 @@ def load_all_results
9898
@results = merge_results(primo_data[:results], timdex_data[:results])
9999

100100
# Use Analyzer for combined pagination calculation
101-
@pagination = Analyzer.new(@enhanced_query, { hits: timdex_data[:hits] }, :all, { hits: primo_data[:hits] }).pagination
101+
@pagination = Analyzer.new(@enhanced_query, timdex_data[:hits], :all,
102+
primo_data[:hits]).pagination
102103

103104
# Handle primo continuation for high page numbers
104105
@show_primo_continuation = primo_data[:show_continuation] || false
@@ -124,8 +125,7 @@ def merge_results(primo_results, timdex_results)
124125
def fetch_primo_data
125126
current_page = @enhanced_query[:page] || 1
126127
per_page = if @active_tab == 'all'
127-
ENV.fetch('RESULTS_PER_PAGE',
128-
'20').to_i / 2
128+
ENV.fetch('RESULTS_PER_PAGE', '20').to_i / 2
129129
else
130130
ENV.fetch('RESULTS_PER_PAGE', '20').to_i
131131
end
@@ -139,7 +139,7 @@ def fetch_primo_data
139139
primo_response = query_primo(per_page, offset)
140140
hits = primo_response.dig('info', 'total') || 0
141141
results = NormalizePrimoResults.new(primo_response, @enhanced_query[:q]).normalize
142-
pagination = Analyzer.new(@enhanced_query, { hits: hits }, :primo).pagination
142+
pagination = Analyzer.new(@enhanced_query, hits , :primo).pagination
143143

144144
# Handle empty results from Primo API. Sometimes Primo will return no results at a given offset,
145145
# despite claiming in the initial query that more are available. This happens randomly and
@@ -183,7 +183,7 @@ def fetch_timdex_data
183183

184184
if errors.nil?
185185
hits = response.dig(:data, 'search', 'hits') || 0
186-
pagination = Analyzer.new(@enhanced_query, { hits: hits }, :timdex).pagination
186+
pagination = Analyzer.new(@enhanced_query, hits, :timdex).pagination
187187
raw_results = extract_results(response)
188188
results = NormalizeTimdexResults.new(raw_results, @enhanced_query[:q]).normalize
189189
{ results: results, pagination: pagination, errors: nil, hits: hits }

app/models/analyzer.rb

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,52 @@ class Analyzer
66
# likely due to performance constraints.
77
PRIMO_MAX_OFFSET = 960
88

9-
def initialize(enhanced_query, response, source, secondary_response = nil)
9+
# Initializes pagination analysis for search results.
10+
#
11+
# @param enhanced_query [Hash] Query parameters including :page (current page number)
12+
# @param hits [Integer] Number of hits from primary source (TIMDEX for :all, source-specific otherwise)
13+
# @param source [Symbol] Source tab (:primo, :timdex, or :all)
14+
# @param secondary_hits [Integer, nil] Optional hit count from secondary source (Primo hits for :all)
15+
def initialize(enhanced_query, hits, source, secondary_hits = nil)
1016
@source = source
1117
@enhanced_query = enhanced_query
1218
@pagination = {}
13-
calculate_pagination(response, secondary_response)
19+
set_pagination(hits, secondary_hits)
1420
end
1521

1622
private
1723

18-
def calculate_pagination(response, secondary_response = nil)
24+
# Sets the pagination hash with hit counts and per_page values.
25+
#
26+
# @param hits [Integer] Hit count from primary source
27+
# @param secondary_hits [Integer, nil] Optional hit count from secondary source
28+
def set_pagination(hits, secondary_hits = nil)
1929
if @source == :all
20-
@pagination[:hits] = (secondary_response&.dig(:hits) || 0) + (response&.dig(:hits) || 0)
30+
@pagination[:hits] = (secondary_hits || 0) + (hits || 0)
2131
@pagination[:per_page] = ENV.fetch('RESULTS_PER_PAGE', '20').to_i
22-
calculate_all_pagination
32+
calculate_pagination_values
2333
else
24-
@pagination[:hits] = response&.dig(:hits) || 0
34+
@pagination[:hits] = hits || 0
2535
@pagination[:per_page] = ENV.fetch('RESULTS_PER_PAGE', '20').to_i
26-
calculate_standard_pagination
36+
calculate_pagination_values
2737
end
2838
end
2939

30-
def calculate_standard_pagination
40+
# Calculates and sets pagination navigation values (start, end, prev, next).
41+
# Uses the already-set @pagination[:hits] and @pagination[:per_page] values.
42+
def calculate_pagination_values
3143
page = @enhanced_query[:page] || 1
3244
@pagination[:start] = ((page - 1) * @pagination[:per_page]) + 1
3345
@pagination[:end] = [page * @pagination[:per_page], @pagination[:hits]].min
3446
@pagination[:prev] = page - 1 if page > 1
3547
@pagination[:next] = next_page(page, @pagination[:hits]) if next_page(page, @pagination[:hits])
3648
end
3749

38-
def calculate_all_pagination
39-
page = @enhanced_query[:page] || 1
40-
@pagination[:start] = ((page - 1) * @pagination[:per_page]) + 1
41-
@pagination[:end] = [page * @pagination[:per_page], @pagination[:hits]].min
42-
@pagination[:prev] = page - 1 if page > 1
43-
@pagination[:next] = page + 1 if page * @pagination[:per_page] < @pagination[:hits]
44-
end
45-
50+
# Calculates the next page number if more results are available.
51+
#
52+
# @param page [Integer] Current page number
53+
# @param hits [Integer] Total number of results available
54+
# @return [Integer, nil] Next page number or nil if no more pages
4655
def next_page(page, hits)
4756
page + 1 if page * @pagination[:per_page] < hits
4857
end

test/models/analyzer_test.rb

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class AnalyzerTest < ActiveSupport::TestCase
88
page: 1
99
}
1010

11-
pagination = Analyzer.new(eq, { hits: hit_count }, :timdex).pagination
11+
pagination = Analyzer.new(eq, hit_count, :timdex).pagination
1212

1313
assert pagination.key?(:hits)
1414
assert pagination.key?(:start)
@@ -28,7 +28,7 @@ class AnalyzerTest < ActiveSupport::TestCase
2828
page: 2
2929
}
3030

31-
pagination = Analyzer.new(eq, { hits: hit_count }, :timdex).pagination
31+
pagination = Analyzer.new(eq, hit_count, :timdex).pagination
3232

3333
assert pagination.key?(:hits)
3434
assert pagination.key?(:start)
@@ -48,7 +48,7 @@ class AnalyzerTest < ActiveSupport::TestCase
4848
page: 5
4949
}
5050

51-
pagination = Analyzer.new(eq, { hits: hit_count }, :timdex).pagination
51+
pagination = Analyzer.new(eq, hit_count, :timdex).pagination
5252

5353
assert pagination.key?(:hits)
5454
assert pagination.key?(:start)
@@ -67,7 +67,7 @@ class AnalyzerTest < ActiveSupport::TestCase
6767
page: 1
6868
}
6969

70-
pagination = Analyzer.new(eq, { hits: 45 }, :primo).pagination
70+
pagination = Analyzer.new(eq, 45, :primo).pagination
7171

7272
assert_equal 45, pagination[:hits]
7373
assert_equal 1, pagination[:start]
@@ -82,7 +82,7 @@ class AnalyzerTest < ActiveSupport::TestCase
8282
page: 2
8383
}
8484

85-
pagination = Analyzer.new(eq, { hits: 75 }, :timdex).pagination
85+
pagination = Analyzer.new(eq, 75, :timdex).pagination
8686

8787
assert_equal 75, pagination[:hits]
8888
assert_equal 21, pagination[:start]
@@ -97,7 +97,7 @@ class AnalyzerTest < ActiveSupport::TestCase
9797
page: 1
9898
}
9999

100-
pagination = Analyzer.new(eq, { hits: 0 }, :primo).pagination
100+
pagination = Analyzer.new(eq, 0, :primo).pagination
101101

102102
assert_equal 0, pagination[:hits]
103103
assert_equal 1, pagination[:start]
@@ -112,7 +112,7 @@ class AnalyzerTest < ActiveSupport::TestCase
112112
page: 1
113113
}
114114

115-
pagination = Analyzer.new(eq, { hits: 68_644_281 }, :primo).pagination
115+
pagination = Analyzer.new(eq, 68_644_281, :primo).pagination
116116

117117
# Should show the actual hit count from the API response
118118
assert_equal 68_644_281, pagination[:hits]
@@ -128,7 +128,7 @@ class AnalyzerTest < ActiveSupport::TestCase
128128
page: 1
129129
}
130130

131-
pagination = Analyzer.new(eq, { hits: 68_644_281 }, :timdex).pagination
131+
pagination = Analyzer.new(eq, 68_644_281, :timdex).pagination
132132

133133
# Should show the actual hit count from the API response
134134
assert_equal 68_644_281, pagination[:hits]
@@ -144,7 +144,7 @@ class AnalyzerTest < ActiveSupport::TestCase
144144
page: 1
145145
}
146146

147-
pagination = Analyzer.new(eq, { hits: 0 }, :unknown_source).pagination
147+
pagination = Analyzer.new(eq, 0, :unknown_source).pagination
148148

149149
# Should default to 0 hits for unknown source types
150150
assert_equal 0, pagination[:hits]
@@ -160,7 +160,7 @@ class AnalyzerTest < ActiveSupport::TestCase
160160
page: 1
161161
}
162162

163-
pagination = Analyzer.new(eq, { hits: 250 }, :all, { hits: 150 }).pagination
163+
pagination = Analyzer.new(eq, 250, :all, 150).pagination
164164

165165
# Should combine hits from both APIs: 150 + 250 = 400
166166
assert_equal 400, pagination[:hits]
@@ -191,7 +191,7 @@ class AnalyzerTest < ActiveSupport::TestCase
191191
page: 2
192192
}
193193

194-
pagination = Analyzer.new(eq, { hits: 500 }, :all, { hits: 300 }).pagination
194+
pagination = Analyzer.new(eq, 500, :all, 300).pagination
195195

196196
# Should combine hits: 300 + 500 = 800
197197
# Page 2 should show results 21-40 of 800
@@ -208,7 +208,7 @@ class AnalyzerTest < ActiveSupport::TestCase
208208
page: 1
209209
}
210210

211-
pagination = Analyzer.new(eq, { hits: 5 }, :all, { hits: 10_000 }).pagination
211+
pagination = Analyzer.new(eq, 5, :all, 10_000).pagination
212212

213213
# Should still combine hits and calculate pagination as expected
214214
assert_equal 10_005, pagination[:hits]
@@ -218,13 +218,13 @@ class AnalyzerTest < ActiveSupport::TestCase
218218
refute pagination.key?(:prev)
219219
end
220220

221-
test 'analyzer handles one API returning zero results for all tab' do
221+
test 'analyzer handles second API returning zero results for all tab' do
222222
eq = {
223223
q: 'data',
224224
page: 1
225225
}
226226

227-
pagination = Analyzer.new(eq, { hits: 150 }, :all, { hits: 0 }).pagination
227+
pagination = Analyzer.new(eq, 150, :all, 0).pagination
228228

229229
assert_equal 150, pagination[:hits]
230230
assert_equal 1, pagination[:start]
@@ -233,33 +233,33 @@ class AnalyzerTest < ActiveSupport::TestCase
233233
refute pagination.key?(:prev)
234234
end
235235

236-
test 'analyzer handles both APIs returning zero results for all tab' do
236+
test 'analyzer handles missing second API response for all tab' do
237237
eq = {
238238
q: 'data',
239239
page: 1
240240
}
241241

242-
pagination = Analyzer.new(eq, { hits: 0 }, :all, { hits: 0 }).pagination
242+
pagination = Analyzer.new(eq, 100, :all).pagination
243243

244-
assert_equal 0, pagination[:hits]
244+
assert_equal 100, pagination[:hits]
245245
assert_equal 1, pagination[:start]
246-
assert_equal 0, pagination[:end]
247-
refute pagination.key?(:next)
246+
assert_equal 20, pagination[:end]
247+
assert_equal 2, pagination[:next]
248248
refute pagination.key?(:prev)
249249
end
250250

251-
test 'analyzer handles missing primo response for all tab' do
251+
test 'analyzer handles both APIs returning zero results for all tab' do
252252
eq = {
253253
q: 'data',
254254
page: 1
255255
}
256256

257-
pagination = Analyzer.new(eq, { hits: 100 }, :all).pagination
257+
pagination = Analyzer.new(eq, 0, :all, 0).pagination
258258

259-
assert_equal 100, pagination[:hits]
259+
assert_equal 0, pagination[:hits]
260260
assert_equal 1, pagination[:start]
261-
assert_equal 20, pagination[:end]
262-
assert_equal 2, pagination[:next]
261+
assert_equal 0, pagination[:end]
262+
refute pagination.key?(:next)
263263
refute pagination.key?(:prev)
264264
end
265265

@@ -269,7 +269,7 @@ class AnalyzerTest < ActiveSupport::TestCase
269269
page: 500
270270
}
271271

272-
pagination = Analyzer.new(eq, { hits: 75_000_000 }, :all, { hits: 25_000_000 }).pagination
272+
pagination = Analyzer.new(eq, 75_000_000, :all, 25_000_000).pagination
273273

274274
assert_equal 100_000_000, pagination[:hits]
275275
assert_equal 9981, pagination[:start] # (500-1) * 20 + 1
@@ -284,20 +284,20 @@ class AnalyzerTest < ActiveSupport::TestCase
284284
page: 2
285285
}
286286

287-
pagination = Analyzer.new(eq, { hits: 100 }, :timdex).pagination
287+
pagination = Analyzer.new(eq, 100, :timdex).pagination
288288
assert_equal 20, pagination[:per_page]
289289
assert_equal 21, pagination[:start] # (2-1) * 20 + 1
290290
assert_equal 40, pagination[:end] # 2 * 20
291291

292292
ClimateControl.modify RESULTS_PER_PAGE: '10' do
293-
pagination = Analyzer.new(eq, { hits: 100 }, :timdex).pagination
293+
pagination = Analyzer.new(eq, 100, :timdex).pagination
294294
assert_equal 10, pagination[:per_page]
295295
assert_equal 11, pagination[:start] # (2-1) * 10 + 1
296296
assert_equal 20, pagination[:end] # 2 * 10
297297
end
298298

299299
ClimateControl.modify RESULTS_PER_PAGE: '50' do
300-
pagination = Analyzer.new(eq, { hits: 200 }, :timdex).pagination
300+
pagination = Analyzer.new(eq, 200, :timdex).pagination
301301
assert_equal 50, pagination[:per_page]
302302
assert_equal 51, pagination[:start] # (2-1) * 50 + 1
303303
assert_equal 100, pagination[:end] # 2 * 50

0 commit comments

Comments
 (0)