Skip to content

Commit 4dcaf0f

Browse files
committed
Refactor for batch results processing
1 parent 02b680f commit 4dcaf0f

File tree

4 files changed

+165
-53
lines changed

4 files changed

+165
-53
lines changed

app/models/normalize_primo.rb renamed to app/models/normalize_primo_record.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Transforms results from Primo Search API into normalized records
2-
class NormalizePrimo
2+
class NormalizePrimoRecord
33
def initialize(record, query)
44
@record = record
55
@query = query
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Batch normalization for Primo Search API results
2+
class NormalizePrimoResults
3+
def initialize(results, query)
4+
@results = results
5+
@query = query
6+
end
7+
8+
def normalize
9+
return [] unless @results&.dig('docs')
10+
11+
@results['docs'].filter_map do |doc|
12+
next unless doc['pnx']
13+
14+
NormalizePrimoRecord.new(doc['pnx'], @query).normalize
15+
end
16+
end
17+
18+
def total_results
19+
@results&.dig('info', 'total') || 0
20+
end
21+
end

test/models/normalize_primo_test.rb renamed to test/models/normalize_primo_record_test.rb

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'test_helper'
22

3-
class NormalizePrimoTest < ActiveSupport::TestCase
3+
class NormalizePrimoRecordTest < ActiveSupport::TestCase
44
# Hopefully we won't need to create new records that often, but if it comes up, you can query the
55
# Primo Search API, grab a result, and use the structure in the `pnx` field as a starting point.
66
# From there, it's a manual process of filling in the data you need for the test assertions.
@@ -13,53 +13,53 @@ def minimal_record
1313
end
1414

1515
test 'normalizes title' do
16-
normalized = NormalizePrimo.new(full_record, 'test').normalize
16+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
1717
assert_equal 'Testing the Limits of Knowledge', normalized['title']
1818
end
1919

2020
test 'handles missing title' do
21-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
21+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
2222
assert_equal 'unknown title', normalized['title']
2323
end
2424

2525
test 'normalizes creators' do
26-
normalized = NormalizePrimo.new(full_record, 'test').normalize
26+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
2727
expected_creators = ['Smith, John A.', 'Jones, Mary B.', 'Brown, Robert C.']
2828
assert_equal expected_creators.sort, normalized['creators'].map { |c| c[:value] }.sort
2929
end
3030

3131
test 'handles missing creators' do
32-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
32+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
3333
assert_empty normalized['creators']
3434
end
3535

3636
test 'normalizes source' do
37-
normalized = NormalizePrimo.new(full_record, 'test').normalize
37+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
3838
assert_equal 'Primo', normalized['source']
3939
end
4040

4141
test 'normalizes year' do
42-
normalized = NormalizePrimo.new(full_record, 'test').normalize
42+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
4343
assert_equal '2023', normalized['year']
4444
end
4545

4646
test 'handles missing year' do
47-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
47+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
4848
assert_nil normalized['year']
4949
end
5050

5151
test 'normalizes format' do
52-
normalized = NormalizePrimo.new(full_record, 'test').normalize
52+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
5353
assert_equal 'Book', normalized['format']
5454
end
5555

5656
test 'handles missing format' do
57-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
57+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
5858
assert_nil normalized['format']
5959
end
6060

6161
test 'normalizes links' do
62-
normalized = NormalizePrimo.new(full_record, 'test').normalize
62+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
6363

6464
# First link should be the record link
6565
assert_equal 'full record', normalized['links'].first['kind']
@@ -69,144 +69,145 @@ def minimal_record
6969
end
7070

7171
test 'handles missing links' do
72-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
72+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
7373
assert_empty normalized['links']
7474
end
7575

7676
test 'normalizes citation' do
77-
normalized = NormalizePrimo.new(full_record, 'test').normalize
77+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
7878
assert_equal 'volume 2 issue 3', normalized['citation']
7979
end
8080

8181
test 'handles missing citation' do
82-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
82+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
8383
assert_nil normalized['citation']
8484
end
8585

8686
test 'normalizes container title' do
87-
normalized = NormalizePrimo.new(full_record, 'test').normalize
87+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
8888
assert_equal 'Journal of Testing', normalized['container']
8989
end
9090

9191
test 'handles missing container title' do
92-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
92+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
9393
assert_nil normalized['container']
9494
end
9595

9696
test 'normalizes identifier' do
97-
normalized = NormalizePrimo.new(full_record, 'test').normalize
97+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
9898
assert_equal 'MIT01000000001', normalized['identifier']
9999
end
100100

101101
test 'normalizes summary' do
102-
normalized = NormalizePrimo.new(full_record, 'test').normalize
102+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
103103
assert_equal 'A comprehensive study of testing methodologies', normalized['summary']
104104
end
105105

106106
test 'handles missing summary' do
107-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
107+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
108108
assert_nil normalized['summary']
109109
end
110110

111111
test 'handles missing identifier' do
112-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
112+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
113113
assert_nil normalized['identifier']
114114
end
115115

116116
test 'normalizes numbering' do
117-
normalized = NormalizePrimo.new(full_record, 'test').normalize
117+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
118118
assert_equal 'volume 2 issue 3', normalized['numbering']
119119
end
120120

121121
test 'handles missing numbering' do
122-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
122+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
123123
assert_nil normalized['numbering']
124124
end
125125

126126
test 'normalizes chapter numbering' do
127-
normalized = NormalizePrimo.new(full_record, 'test').normalize
127+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
128128
assert_equal '2023, pp. 123-145', normalized['chapter_numbering']
129129
end
130130

131131
test 'handles missing chapter numbering' do
132-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
132+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
133133
assert_nil normalized['chapter_numbering']
134134
end
135135

136136
test 'includes FRBRized dedup record link in links when available' do
137-
normalized = NormalizePrimo.new(full_record, 'test').normalize
137+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
138138
record_link = normalized['links'].find { |link| link['kind'] == 'full record' }
139139
assert_not_nil record_link
140-
# For frbrized records, should use dedup URL format
140+
141+
# For FRBRized records, should use dedup URL format
141142
assert_match %r{/discovery/search\?}, record_link['url']
142143
assert_match 'frbrgroupid', record_link['url']
143144
end
144145

145146
test 'generates thumbnail from ISBN' do
146-
normalized = NormalizePrimo.new(full_record, 'test').normalize
147+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
147148
expected_url = 'https://syndetics.com/index.php?client=primo&isbn=9781234567890/sc.jpg'
148149
assert_equal expected_url, normalized['thumbnail']
149150
end
150151

151152
test 'handles missing ISBN for thumbnail' do
152-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
153+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
153154
assert_nil normalized['thumbnail']
154155
end
155156

156157
test 'extracts publisher information' do
157-
normalized = NormalizePrimo.new(full_record, 'test').normalize
158+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
158159
assert_equal 'MIT Press', normalized['publisher']
159160
end
160161

161162
test 'handles missing publisher' do
162-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
163+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
163164
assert_nil normalized['publisher']
164165
end
165166

166167
test 'returns best location with call number' do
167-
normalized = NormalizePrimo.new(full_record, 'test').normalize
168+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
168169
expected_location = ['Hayden Library Stacks', 'QA76.73.R83 2023']
169170
assert_equal expected_location, normalized['location']
170171
end
171172

172173
test 'handles missing location' do
173-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
174+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
174175
assert_nil normalized['location']
175176
end
176177

177178
test 'extracts subjects' do
178-
normalized = NormalizePrimo.new(full_record, 'test').normalize
179+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
179180
expected_subjects = ['Computer Science', 'Software Testing']
180181
assert_equal expected_subjects, normalized['subjects']
181182
end
182183

183184
test 'handles missing subjects' do
184-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
185+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
185186
assert_empty normalized['subjects']
186187
end
187188

188189
test 'returns availability status' do
189-
normalized = NormalizePrimo.new(full_record, 'test').normalize
190+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
190191
assert_equal 'available', normalized['availability']
191192
end
192193

193194
test 'handles missing availability' do
194-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
195+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
195196
assert_nil normalized['availability']
196197
end
197198

198199
test 'detects other availability when multiple holdings exist' do
199-
normalized = NormalizePrimo.new(full_record, 'test').normalize
200+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
200201
assert normalized['other_availability']
201202
end
202203

203204
test 'handles missing other availability' do
204-
normalized = NormalizePrimo.new(minimal_record, 'test').normalize
205+
normalized = NormalizePrimoRecord.new(minimal_record, 'test').normalize
205206
assert_nil normalized['other_availability']
206207
end
207208

208209
test 'uses dedup URL as full record link for frbrized records' do
209-
normalized = NormalizePrimo.new(full_record, 'test').normalize
210+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
210211
full_record_link = normalized['links'].find { |link| link['kind'] == 'full record' }
211212
assert_not_nil full_record_link
212213

@@ -220,14 +221,14 @@ def minimal_record
220221
record_without_frbr = full_record.deep_dup
221222
record_without_frbr['pnx']['facets']['frbrtype'] = ['3']
222223

223-
normalized = NormalizePrimo.new(record_without_frbr, 'test').normalize
224+
normalized = NormalizePrimoRecord.new(record_without_frbr, 'test').normalize
224225
full_record_link = normalized['links'].find { |link| link['kind'] == 'full record' }
225226
assert_not_nil full_record_link
226227
assert_match %r{/discovery/fulldisplay\?}, full_record_link['url']
227228
end
228229

229230
test 'includes expected link types when available' do
230-
normalized = NormalizePrimo.new(full_record, 'test query').normalize
231+
normalized = NormalizePrimoRecord.new(full_record, 'test query').normalize
231232
link_kinds = normalized['links'].map { |link| link['kind'] }
232233

233234
assert_includes link_kinds, 'full record'
@@ -239,7 +240,7 @@ def minimal_record
239240
test 'handles multiple creators with semicolons' do
240241
record = full_record.deep_dup
241242
record['pnx']['display']['creator'] = ['Smith, John A.; Doe, Jane B.']
242-
normalized = NormalizePrimo.new(record, 'test').normalize
243+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
243244
creators = normalized['creators'].map { |c| c[:value] }
244245
assert_includes creators, 'Smith, John A.'
245246
assert_includes creators, 'Doe, Jane B.'
@@ -248,12 +249,12 @@ def minimal_record
248249
test 'sanitizes authors by removing $$ codes' do
249250
record = full_record.deep_dup
250251
record['pnx']['display']['creator'] = ['Smith, John A.$$QAuthor']
251-
normalized = NormalizePrimo.new(record, 'test').normalize
252+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
252253
assert_equal 'Smith, John A.', normalized['creators'].first[:value]
253254
end
254255

255256
test 'constructs author search links' do
256-
normalized = NormalizePrimo.new(full_record, 'test').normalize
257+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
257258
creator_link = normalized['creators'].first[:link]
258259
assert_match 'discovery/search?query=creator,exact,', creator_link
259260
assert_match 'Smith%2C%20John%20A.', creator_link
@@ -270,7 +271,7 @@ def minimal_record
270271
test_cases.each do |input, expected|
271272
record = full_record.deep_dup
272273
record['pnx']['display']['type'] = [input]
273-
normalized = NormalizePrimo.new(record, 'test').normalize
274+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
274275
assert_equal expected, normalized['format']
275276
end
276277
end
@@ -279,20 +280,20 @@ def minimal_record
279280
record = minimal_record.deep_dup
280281
record['pnx']['search'] = { 'creationdate' => ['2022'] }
281282

282-
normalized = NormalizePrimo.new(record, 'test').normalize
283+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
283284
assert_equal '2022', normalized['year']
284285
end
285286

286287
test 'handles different citation formats' do
287288
# Test with just volume
288289
record = full_record.deep_dup
289290
record['pnx']['addata'] = { 'volume' => ['5'] }
290-
normalized = NormalizePrimo.new(record, 'test').normalize
291+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
291292
assert_equal 'volume 5', normalized['citation']
292293

293294
# Test with date and pages
294295
record['pnx']['addata'] = { 'date' => ['2023'], 'pages' => ['10-20'] }
295-
normalized = NormalizePrimo.new(record, 'test').normalize
296+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
296297
assert_equal '2023, pp. 10-20', normalized['citation']
297298
end
298299

@@ -301,7 +302,7 @@ def minimal_record
301302
record['pnx']['addata']['jtitle'] = ['Journal Title']
302303
record['pnx']['addata']['btitle'] = ['Book Title']
303304

304-
normalized = NormalizePrimo.new(record, 'test').normalize
305+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
305306
assert_equal 'Journal Title', normalized['container']
306307
end
307308

@@ -310,20 +311,20 @@ def minimal_record
310311
record['pnx']['addata'].delete('jtitle') # Remove jtitle
311312
record['pnx']['addata']['btitle'] = ['Book Title Only']
312313

313-
normalized = NormalizePrimo.new(record, 'test').normalize
314+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
314315
assert_equal 'Book Title Only', normalized['container']
315316
end
316317

317318
test 'handles openurl server validation' do
318319
# Test with matching server
319-
normalized = NormalizePrimo.new(full_record, 'test').normalize
320+
normalized = NormalizePrimoRecord.new(full_record, 'test').normalize
320321
openurl_link = normalized['links'].find { |link| link['kind'] == 'openurl' }
321322
assert_not_nil openurl_link
322323

323324
# Test with mismatched server. Should log warning but still return URL
324325
record = full_record.deep_dup
325326
record['delivery']['almaOpenurl'] = 'https://different.server.com/openurl?param=value'
326-
normalized = NormalizePrimo.new(record, 'test').normalize
327+
normalized = NormalizePrimoRecord.new(record, 'test').normalize
327328
openurl_link = normalized['links'].find { |link| link['kind'] == 'openurl' }
328329
assert_not_nil openurl_link
329330
end

0 commit comments

Comments
 (0)