pennmarc 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb0bf4c30ad40bcee865ed6596fbfc6d6d16a5d3924d62947d270a3d5fa3aac5
4
- data.tar.gz: 33ca607af919156ac45a73067605b6ac298fef9c17ef983060e6a871c54ca26f
3
+ metadata.gz: 2b87c66becc36828ec6331d7261d0b71472a74f4af26f2b7a145ed54316ed11a
4
+ data.tar.gz: 0de62b7492b92ebe0902081aee1da5e5bcabac9e8d9042bab88db7887adda62e
5
5
  SHA512:
6
- metadata.gz: 5e5d316a7e1340aaf7438297e17198339d02ab797842b47ec2cece1daf75f96a387565b4fdc6ca273ef1a64630e1f486bc713ea75793ed3d783998234a83c517
7
- data.tar.gz: 6f6d6824e1aa5fecbcd2dc13bbc94ea575531e96ea5f822b992719f3b28189cce4c26febc2f31848f24008a57f6a839f787383752cfd2c915695b1f1e66fe5ca
6
+ metadata.gz: 0ffced7042a0c00a09c1a2b465e0d17506e55bf0a77255e8f1bce1acabdfabe8faa819864cb0376d7ac6a10285c1a810bd1ede17210829326d342998ed908aa4
7
+ data.tar.gz: 7aac0315dda59416fdd5b5ed6409b1ddc9a3f881bc75a5aa08c07d299d9824ed9c12a6f6cbe7cacc39a45980f36bcfb97e9ed6b42c379a3aa6364b56f397a244
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000`
3
- # on 2024-07-02 15:41:46 UTC using RuboCop version 1.51.0.
3
+ # on 2024-08-30 16:12:14 UTC using RuboCop version 1.51.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -14,7 +14,7 @@ Gemspec/RequireMFA:
14
14
  Exclude:
15
15
  - 'pennmarc.gemspec'
16
16
 
17
- # Offense count: 25
17
+ # Offense count: 26
18
18
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
19
19
  Metrics/AbcSize:
20
20
  Exclude:
@@ -31,7 +31,7 @@ Metrics/AbcSize:
31
31
  - 'lib/pennmarc/helpers/title.rb'
32
32
  - 'lib/pennmarc/util.rb'
33
33
 
34
- # Offense count: 8
34
+ # Offense count: 9
35
35
  # Configuration parameters: CountComments, Max, CountAsOne.
36
36
  Metrics/ClassLength:
37
37
  Exclude:
@@ -138,9 +138,10 @@ RSpec/FilePath:
138
138
  Exclude:
139
139
  - 'spec/lib/pennmarc/parser_spec.rb'
140
140
 
141
- # Offense count: 23
141
+ # Offense count: 27
142
142
  # Configuration parameters: Max, AllowedGroups.
143
143
  RSpec/NestedGroups:
144
144
  Exclude:
145
145
  - 'spec/lib/pennmarc/helpers/access_spec.rb'
146
146
  - 'spec/lib/pennmarc/helpers/format_spec.rb'
147
+ - 'spec/lib/pennmarc/helpers/location_spec.rb'
@@ -37,12 +37,12 @@ module PennMARC
37
37
  # @see https://developers.exlibrisgroup.com/alma/apis/docs/bibs/R0VUIC9hbG1hd3MvdjEvYmlicy97bW1zX2lkfQ==/
38
38
  # Alma documentation for these added fields
39
39
  # @param record [MARC::Record]
40
- # @param display_value [Symbol | String] field in location hash to retrieve
40
+ # @param display_value [Symbol,String] field in location hash to retrieve
41
41
  # @param location_map [Hash] hash with location_code as key and location hash as value
42
42
  # @return [Array<String>]
43
43
  def location(record:, display_value:, location_map:)
44
44
  # get enriched marc location tag and relevant subfields
45
- enriched_location_tag_and_subfields(record) => {tag:, location_code_sf:, call_num_sf:}
45
+ enriched_location_tag_and_subfields(record) => {tag:, location_code_sf:, call_num_sf:, call_num_type_sf:}
46
46
 
47
47
  record.fields(tag).flat_map { |field|
48
48
  field.filter_map { |subfield|
@@ -53,8 +53,10 @@ module PennMARC
53
53
 
54
54
  next if location_code_to_ignore?(location_map, location_code)
55
55
 
56
- override = specific_location_override(display_value: display_value, location_code: location_code,
57
- field: field, call_num_sf: call_num_sf)
56
+ override = if display_value.to_sym == :specific_location
57
+ specific_location_override(location_code: location_code, field: field,
58
+ call_num_sf: call_num_sf, call_num_type_sf: call_num_type_sf)
59
+ end
58
60
 
59
61
  override || location_map[location_code.to_sym][display_value.to_sym]
60
62
  }.flatten.compact_blank
@@ -70,6 +72,8 @@ module PennMARC
70
72
  # - `:tag` (String): The enriched marc location tag
71
73
  # - `:location_code_sf` (String): The subfield code where location code is stored
72
74
  # - `:call_num_sf` (String): The subfield code where call number is stored
75
+ # - `:call_num_type_sf` (String, nil): The subfield code where call number type is stored. nil if unavailable in a
76
+ # MARC field and we need to look for an indicator.
73
77
  def enriched_location_tag_and_subfields(record)
74
78
  # in holdings records, the shelving location is always the permanent location.
75
79
  # in item records, the current location takes into account
@@ -84,19 +88,22 @@ module PennMARC
84
88
  tag = Enriched::Pub::ITEM_TAG
85
89
  location_code_sf = Enriched::Pub::ITEM_CURRENT_LOCATION
86
90
  call_num_sf = Enriched::Pub::ITEM_CALL_NUMBER
91
+ call_num_type_sf = Enriched::Pub::ITEM_CALL_NUMBER_TYPE
87
92
  # if the record has API inventory tags, use them
88
93
  elsif field_defined?(record, Enriched::Api::PHYS_INVENTORY_TAG)
89
94
  tag = Enriched::Api::PHYS_INVENTORY_TAG
90
95
  location_code_sf = Enriched::Api::PHYS_LOCATION_CODE
91
96
  call_num_sf = Enriched::Api::PHYS_CALL_NUMBER
97
+ call_num_type_sf = Enriched::Api::PHYS_CALL_NUMBER_TYPE
92
98
  # otherwise use Pub holding tags
93
99
  else
94
100
  tag = Enriched::Pub::PHYS_INVENTORY_TAG
95
101
  location_code_sf = Enriched::Pub::PHYS_LOCATION_CODE
96
102
  call_num_sf = Enriched::Pub::HOLDING_CLASSIFICATION_PART
103
+ call_num_type_sf = nil # for hld tags, the call num type is indicator0
97
104
  end
98
105
 
99
- { tag: tag, location_code_sf: location_code_sf, call_num_sf: call_num_sf }
106
+ { tag: tag, location_code_sf: location_code_sf, call_num_sf: call_num_sf, call_num_type_sf: call_num_type_sf }
100
107
  end
101
108
 
102
109
  # Determines whether to ignore a location code.
@@ -105,32 +112,55 @@ module PennMARC
105
112
  # map, we ignore it, for faceting purposes. We also ignore the location code 'web'. We don't facet for 'web'
106
113
  # which is the 'Penn Library Web' location used in Voyager. This location should eventually go away completely
107
114
  # with data cleanup in Alma.
108
- # @param location_map [location_map] hash with location_code as key and location hash as value
109
- # @param location_code [location_code] retrieved from record
115
+ # @param location_map [Hash] hash with location_code as key and location hash as value
116
+ # @param location_code [String] retrieved from record
110
117
  # @return [Boolean]
111
118
  def location_code_to_ignore?(location_map, location_code)
112
- location_map.key?(location_code.to_sym) == false || location_code == WEB_LOCATION_CODE
119
+ !location_map.key?(location_code.to_sym) || location_code == WEB_LOCATION_CODE
113
120
  end
114
121
 
115
122
  # Retrieves a specific location override based on location code and call number. Specific location overrides are
116
123
  # located in `location_overrides.yml`.
117
- # @param display_value [String | Symbol]
118
124
  # @param location_code [String]
119
125
  # @param field [MARC::Field]
120
126
  # @param call_num_sf [String]
127
+ # @param call_num_type_sf [String, nil]
121
128
  # @return [String, Nil]
122
- def specific_location_override(display_value:, location_code:, field:, call_num_sf:)
123
- return unless display_value.to_sym == :specific_location
129
+ def specific_location_override(location_code:, field:, call_num_sf:, call_num_type_sf:)
130
+ callnum_type = callnum_type(field: field, call_num_type_sf: call_num_type_sf)
131
+ return unless callnum_type
124
132
 
125
- locations_overrides = Mappers.location_overrides
133
+ override = Mappers.location_overrides.find do |_key, override_data|
134
+ override_matching?(override_data: override_data, location_code: location_code, callnum_type: callnum_type,
135
+ call_numbers: subfield_values(field, call_num_sf))
136
+ end
126
137
 
127
- call_numbers = subfield_values(field, call_num_sf)
138
+ override&.last&.dig(:specific_location)
139
+ end
128
140
 
129
- override = locations_overrides.find do |_key, value|
130
- value[:location_code] == location_code && call_numbers.any? { |num| num.match?(value[:call_num_pattern]) }
141
+ # Check override_data hash for a matching location name override
142
+ # @param override_data [Hash]
143
+ # @param location_code [String]
144
+ # @param call_numbers [Array]
145
+ # @param callnum_type [String]
146
+ # @return [Boolean]
147
+ def override_matching?(override_data:, location_code:, call_numbers:, callnum_type:)
148
+ call_numbers.any? do |call_number|
149
+ override_data[:location_code] == location_code &&
150
+ override_data[:call_num_type] == callnum_type &&
151
+ call_number.match?(override_data[:call_num_pattern])
131
152
  end
153
+ end
132
154
 
133
- override&.last&.dig(:specific_location)
155
+ # Return call num type value for a given field. If no call number subfield is expected (publishing holding
156
+ # inventory case), the first indicator is checked.
157
+ # @param field [MARC::Field]
158
+ # @param call_num_type_sf [String, nil]
159
+ # @return [String, nil]
160
+ def callnum_type(field:, call_num_type_sf:)
161
+ return field.indicator1 if call_num_type_sf.nil?
162
+
163
+ subfield_values(field, call_num_type_sf).first
134
164
  end
135
165
  end
136
166
  end
@@ -35,6 +35,23 @@ module PennMARC
35
35
  series_values.uniq
36
36
  end
37
37
 
38
+ # Hash that associates {https://www.loc.gov/marc/bibliographic/bd830.html 830} and
39
+ # {https://www.loc.gov/marc/bibliographic/bd440.html 440} show values to query values to make building fielded
40
+ # search links easier in the downstream app.
41
+ # @param record [MARC::Record]
42
+ # @return [Hash]
43
+ def show_query_map(record)
44
+ record.fields(%w[830 440]).each_with_object({}) do |field, hash|
45
+ show_values = title_show_entries(record, field.tag) + [remaining_show_value(field)]
46
+
47
+ query_value = trim_punctuation(join_subfields(field, &subfield_in?(%w[a n p])))
48
+
49
+ show_values.each do |show_value|
50
+ hash[show_value] = query_value
51
+ end
52
+ end
53
+ end
54
+
38
55
  # Values from series fields for display.
39
56
  # @param record [MARC::Record]
40
57
  # @param relator_map [Hash]
@@ -141,10 +158,10 @@ module PennMARC
141
158
  # @note added 2017/04/10: filter out 0 (authority record numbers) added by Alma
142
159
  # @param record [MARC::Record]
143
160
  # @param tags_present [Array<String>]
144
- # @return [Array<Hash>] array of remaining show entry hashes
161
+ # @return [Array<String>] array of remaining show entry hashes
145
162
  def remaining_show_entries(record, tags_present)
146
163
  record.fields(tags_present.drop(1)).map do |field|
147
- join_subfields(field, &subfield_not_in?(%w[0 5 6 8]))
164
+ remaining_show_value(field)
148
165
  end || []
149
166
  end
150
167
 
@@ -200,6 +217,13 @@ module PennMARC
200
217
  join_subfields(field, &subfield_in?(%w[i a s t n d]))
201
218
  end
202
219
  end
220
+
221
+ # Parse the value for a given remaining show field
222
+ # @param field [MARC::Field]
223
+ # @return [String]
224
+ def remaining_show_value(field)
225
+ join_subfields(field, &subfield_not_in?(%w[0 5 6 8]))
226
+ end
203
227
  end
204
228
  end
205
229
  end
@@ -88,7 +88,6 @@ module PennMARC
88
88
  # Single-valued Title, for use in headings. Takes the first {https://www.oclc.org/bibformats/en/2xx/245.html 245}
89
89
  # value. Special consideration for
90
90
  # {https://www.oclc.org/bibformats/en/2xx/245.html#punctuation punctuation practices}.
91
- # @todo still consider ǂh? medium, which OCLC doc says DO NOT USE...but that is OCLC...
92
91
  # @todo is punctuation handling still as desired? treatment here is described in spreadsheet from 2011
93
92
  # @param record [MARC::Record]
94
93
  # @return [String] single title for display
@@ -98,15 +97,14 @@ module PennMARC
98
97
  [format_title(values[:title_or_form]), values[:punctuation], values[:other_info]].compact_blank.join(' ')
99
98
  end
100
99
 
101
- # Same as show, but with inclusive dates appended. For use on show page.
100
+ # Same as show, but with all subfields included as found - except for subfield c.
102
101
  # @param record [MARC::Record]
103
102
  # @return [String] detailed title for display
104
103
  def detailed_show(record)
105
104
  field = record.fields('245')&.first
106
- values = title_values(field)
107
- title = [format_title(values[:title_or_form]), values[:punctuation],
108
- trim_trailing(:period, values[:other_info])].compact_blank.join(' ')
109
- values[:inclusive_dates].present? ? [title, values[:inclusive_dates]].compact_blank.join(', ') : title
105
+ return unless field
106
+
107
+ join_subfields(field, &subfield_not_in?(%w[6 8]))
110
108
  end
111
109
 
112
110
  # Same structure as show, but linked alternate title.
@@ -124,17 +122,6 @@ module PennMARC
124
122
  [format_title(values[:title_or_form]), values[:punctuation], values[:other_info]].compact_blank.join(' ')
125
123
  end
126
124
 
127
- # Title statement of responsibility (field 245, subfield c) and linked alternate for display.
128
- # See https://www.oclc.org/bibformats/en/2xx/245.html#subfieldc for examples
129
- # @param [MARC::Record] record
130
- # @return [Array<String>] statement of responsibility and linked alternate
131
- def statement_of_responsibility_show(record)
132
- field = record.fields('245').first
133
- statement = field&.find { |sf| sf.code == 'c' }&.value
134
- alternate_statement = linked_alternate(record, '245', &subfield_in?(%w[c]))&.first
135
- [statement, alternate_statement].compact_blank
136
- end
137
-
138
125
  # Canonical title with non-filing characters relocated to the end.
139
126
  #
140
127
  # @note Currently we index two "title sort" fields: title_nssort (ssort type - regex token filter applied) and
@@ -269,7 +256,6 @@ module PennMARC
269
256
  title_or_form = field.find_all(&subfield_in?(%w[a k]))
270
257
  .map { |sf| trim_trailing(:comma, trim_trailing(:slash, sf.value).rstrip) }
271
258
  .first || ''
272
- inclusive_dates = field.find { |sf| sf.code == 'f' }&.value
273
259
  other_info = field.find_all(&subfield_in?(%w[b n p]))
274
260
  .map { |sf| trim_trailing(:slash, sf.value) }
275
261
  .join(' ')
@@ -283,7 +269,6 @@ module PennMARC
283
269
  [title_punctuation, medium_punctuation].include?(':') ? ':' : nil
284
270
  end
285
271
  { title_or_form: title_or_form,
286
- inclusive_dates: inclusive_dates,
287
272
  other_info: other_info,
288
273
  punctuation: punctuation }
289
274
  end
@@ -1,5 +1,6 @@
1
1
  albrecht:
2
2
  location_code: 'vanp'
3
3
  call_num_pattern: '^M.*'
4
+ call_num_type: '0'
4
5
  specific_location: 'Van Pelt - Albrecht Music Library'
5
6
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PennMARC
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.0'
5
5
  end
@@ -4,12 +4,13 @@ describe 'PennMARC::Location' do
4
4
  let(:helper) { PennMARC::Location }
5
5
  let(:enriched_marc) { PennMARC::Enriched }
6
6
  let(:mapping) { location_map }
7
+ let(:record) { marc_record(fields: fields) }
7
8
 
8
9
  describe 'location' do
9
10
  context "with only 'itm' field present" do
10
- let(:record) do
11
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
12
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' })])
11
+ let(:fields) do
12
+ [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
13
+ subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' })]
13
14
  end
14
15
 
15
16
  it 'returns expected value' do
@@ -21,9 +22,9 @@ describe 'PennMARC::Location' do
21
22
  end
22
23
 
23
24
  context "with only 'hld' field present" do
24
- let(:record) do
25
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
26
- subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'stor' })])
25
+ let(:fields) do
26
+ [marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
27
+ subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'stor' })]
27
28
  end
28
29
 
29
30
  it 'returns expected value' do
@@ -35,11 +36,11 @@ describe 'PennMARC::Location' do
35
36
  end
36
37
 
37
38
  context 'with both holding and item tag fields present=' do
38
- let(:record) do
39
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
40
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' }),
41
- marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
42
- subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'dent' })])
39
+ let(:fields) do
40
+ [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
41
+ subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor' }),
42
+ marc_field(tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
43
+ subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'dent' })]
43
44
  end
44
45
 
45
46
  it 'returns item location' do
@@ -49,7 +50,7 @@ describe 'PennMARC::Location' do
49
50
  end
50
51
 
51
52
  context 'with multiple library locations' do
52
- let(:record) { marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG, subfields: { g: %w[dent] })]) }
53
+ let(:fields) { [marc_field(tag: enriched_marc::Pub::ITEM_TAG, subfields: { g: %w[dent] })] }
53
54
 
54
55
  it 'returns expected value' do
55
56
  expect(helper.location(record: record, location_map: mapping,
@@ -59,7 +60,7 @@ describe 'PennMARC::Location' do
59
60
  end
60
61
 
61
62
  context 'without enriched marc location tag' do
62
- let(:record) { marc_record(fields: [marc_field(tag: '852', subfields: { g: 'stor' })]) }
63
+ let(:fields) { [marc_field(tag: '852', subfields: { g: 'stor' })] }
63
64
 
64
65
  it 'returns expected value' do
65
66
  expect(helper.location(record: record, location_map: mapping, display_value: :library)).to be_empty
@@ -67,13 +68,11 @@ describe 'PennMARC::Location' do
67
68
  end
68
69
 
69
70
  context 'with AVA fields' do
70
- let(:record) do
71
- marc_record(fields: [marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
72
- subfields: {
73
- enriched_marc::Api::PHYS_LIBRARY_CODE => 'Libra',
74
- enriched_marc::Api::PHYS_LOCATION_NAME => 'LIBRA',
75
- enriched_marc::Api::PHYS_LOCATION_CODE => 'stor'
76
- })])
71
+ let(:fields) do
72
+ [marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
73
+ subfields: { enriched_marc::Api::PHYS_LIBRARY_CODE => 'Libra',
74
+ enriched_marc::Api::PHYS_LOCATION_NAME => 'LIBRA',
75
+ enriched_marc::Api::PHYS_LOCATION_CODE => 'stor' })]
77
76
  end
78
77
 
79
78
  it 'returns expected values' do
@@ -84,23 +83,82 @@ describe 'PennMARC::Location' do
84
83
  end
85
84
 
86
85
  context 'with a specific location override' do
87
- let(:record) do
88
- marc_record(fields: [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
89
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
90
- enriched_marc::Pub::ITEM_CALL_NUMBER => 'ML3534 .D85 1984' }),
91
- marc_field(tag: enriched_marc::Pub::ITEM_TAG,
92
- subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor',
93
- enriched_marc::Pub::ITEM_CALL_NUMBER => 'L3534 .D85 1984' })])
86
+ context 'with item fields and LC call nums' do
87
+ let(:fields) do
88
+ [marc_field(tag: enriched_marc::Pub::ITEM_TAG,
89
+ subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
90
+ enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE =>
91
+ PennMARC::Classification::LOC_CALL_NUMBER_TYPE,
92
+ enriched_marc::Pub::ITEM_CALL_NUMBER => 'ML3534 .D85 1984' }),
93
+ marc_field(tag: enriched_marc::Pub::ITEM_TAG,
94
+ subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'stor',
95
+ enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE => '8',
96
+ enriched_marc::Pub::ITEM_CALL_NUMBER => 'L3534 .D85 1984' })]
97
+ end
98
+
99
+ it 'returns expected values' do
100
+ expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
101
+ .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
102
+ end
103
+
104
+ it 'returns expected values when receiving a string for display_value' do
105
+ expect(helper.location(record: record, display_value: 'specific_location', location_map: mapping))
106
+ .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
107
+ end
94
108
  end
95
109
 
96
- it 'returns expected values' do
97
- expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
98
- .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
110
+ context 'with item fields and microfilm call nums' do
111
+ let(:fields) do
112
+ [marc_field(tag: enriched_marc::Pub::ITEM_TAG, indicator1: ' ',
113
+ subfields: { enriched_marc::Pub::ITEM_CURRENT_LOCATION => 'vanp',
114
+ enriched_marc::Pub::ITEM_CALL_NUMBER_TYPE => '8',
115
+ enriched_marc::Pub::ITEM_CALL_NUMBER => 'Microfilm 3140 item 8' })]
116
+ end
117
+
118
+ it 'returns expected values' do
119
+ expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
120
+ .to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location]))
121
+ end
122
+ end
123
+
124
+ context 'with holding fields and both LC and non-LC call num type' do
125
+ let(:fields) do
126
+ [marc_field(indicator1: '8', tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
127
+ subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'vanp' }),
128
+ marc_field(indicator1: '0', tag: enriched_marc::Pub::PHYS_INVENTORY_TAG,
129
+ subfields: { enriched_marc::Pub::PHYS_LOCATION_CODE => 'vanp',
130
+ enriched_marc::Pub::HOLDING_CLASSIFICATION_PART => 'ML3534' })]
131
+ end
132
+
133
+ it 'returns expected values' do
134
+ expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
135
+ .to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location],
136
+ PennMARC::Mappers.location_overrides[:albrecht][:specific_location]))
137
+ end
99
138
  end
100
139
 
101
- it 'returns expected values when receiving a string for display_value' do
102
- expect(helper.location(record: record, display_value: 'specific_location', location_map: mapping))
103
- .to(contain_exactly(PennMARC::Mappers.location_overrides[:albrecht][:specific_location], 'LIBRA'))
140
+ context 'with a variety of holding fields from the Alma API enrichment' do
141
+ let(:fields) do
142
+ [marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
143
+ subfields: { enriched_marc::Api::PHYS_CALL_NUMBER => 'Locked Closet Floor',
144
+ enriched_marc::Api::PHYS_CALL_NUMBER_TYPE => '8' }),
145
+ marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
146
+ subfields: { enriched_marc::Api::PHYS_LOCATION_CODE => 'vanp',
147
+ enriched_marc::Api::PHYS_CALL_NUMBER => ['ML123 .P567 1875', 'ML123'],
148
+ enriched_marc::Api::PHYS_CALL_NUMBER_TYPE =>
149
+ PennMARC::Classification::LOC_CALL_NUMBER_TYPE }),
150
+ marc_field(tag: enriched_marc::Api::PHYS_INVENTORY_TAG,
151
+ subfields: { enriched_marc::Api::PHYS_LOCATION_CODE => 'vanp',
152
+ enriched_marc::Api::PHYS_CALL_NUMBER => 'P789 .D123 2012',
153
+ enriched_marc::Api::PHYS_CALL_NUMBER_TYPE =>
154
+ PennMARC::Classification::LOC_CALL_NUMBER_TYPE })]
155
+ end
156
+
157
+ it 'returns expected values' do
158
+ expect(helper.location(record: record, display_value: :specific_location, location_map: mapping))
159
+ .to(contain_exactly(PennMARC::Mappers.location[:vanp][:specific_location],
160
+ PennMARC::Mappers.location_overrides[:albrecht][:specific_location]))
161
+ end
104
162
  end
105
163
  end
106
164
  end
@@ -15,6 +15,24 @@ describe 'PennMARC::Series' do
15
15
  marc_record fields: [marc_field(tag: '666', subfields: { a: 'test' })]
16
16
  end
17
17
 
18
+ describe '.show_query_map' do
19
+ let(:record) do
20
+ marc_record fields: [
21
+ marc_field(tag: '440', subfields: { a: 'Teachings of the feathered pillow', n: 'number', p: 'section' }),
22
+ marc_field(tag: '490', subfields: { a: 'Ignored' }),
23
+ marc_field(tag: '830', subfields: { a: 'International litigation in practice', v: 'volume 13.' })
24
+ ]
25
+ end
26
+
27
+ it 'returns expected hash' do
28
+ expect(helper.show_query_map(record)).to eq(
29
+ { 'Teachings of the feathered pillow number section' => 'Teachings of the feathered pillow number section',
30
+ 'Teachings of the feathered pillow section number' => 'Teachings of the feathered pillow number section',
31
+ 'International litigation in practice volume 13.' => 'International litigation in practice' }
32
+ )
33
+ end
34
+ end
35
+
18
36
  describe '.show' do
19
37
  it 'returns the series values for display' do
20
38
  expect(helper.show(record, relator_map: mapping)).to contain_exactly(
@@ -139,15 +139,44 @@ describe 'PennMARC::Title' do
139
139
  end
140
140
 
141
141
  describe '.detailed_show' do
142
- let(:record) do
143
- marc_record fields: [
144
- marc_field(tag: '245', subfields: { k: 'Letters', f: '1972-1982', b: 'to Lewis Mumford.' })
145
- ]
146
- end
147
-
148
142
  context 'with subfields ǂk, ǂf and ǂc' do
143
+ let(:record) do
144
+ marc_record fields: [
145
+ marc_field(tag: '245', subfields: { k: 'Letters,', f: '1972-1982,', b: 'to Lewis Mumford.' })
146
+ ]
147
+ end
148
+
149
149
  it 'returns detailed title values' do
150
- expect(helper.detailed_show(record)).to eq 'Letters to Lewis Mumford, 1972-1982'
150
+ expect(helper.detailed_show(record)).to eq 'Letters, 1972-1982, to Lewis Mumford.'
151
+ end
152
+ end
153
+
154
+ context 'with subfields ǂk and ǂb' do
155
+ let(:record) do
156
+ marc_record fields: [
157
+ marc_field(tag: '245', subfields: { k: 'Letters', b: 'to Lewis Mumford.' })
158
+ ]
159
+ end
160
+
161
+ it 'returns title value without dates' do
162
+ expect(helper.detailed_show(record)).to eq 'Letters to Lewis Mumford.'
163
+ end
164
+ end
165
+
166
+ # e.g., 9977704838303681
167
+ context 'with ǂa containing an " : " as well as inclusive dates' do
168
+ let(:record) do
169
+ marc_record fields: [
170
+ marc_field(tag: '245', subfields: { a: 'The frugal housewife : ',
171
+ b: 'dedicated to those who are not ashamed of economy, ',
172
+ f: '1830 / ', c: 'by the author of Hobomok.' })
173
+ ]
174
+ end
175
+
176
+ it 'returns single title value with text from ǂa and ǂn' do
177
+ expect(helper.detailed_show(record)).to eq(
178
+ 'The frugal housewife : dedicated to those who are not ashamed of economy, 1830 / by the author of Hobomok.'
179
+ )
151
180
  end
152
181
  end
153
182
  end
@@ -179,25 +208,6 @@ describe 'PennMARC::Title' do
179
208
  end
180
209
  end
181
210
 
182
- describe '.statement_of_responsibility_show' do
183
- let(:record) do
184
- marc_record fields: [marc_field(tag: '245', subfields: { c: 'statement of responsibility' }),
185
- marc_field(tag: '880', subfields: { '6': '245', c: 'déclaration de responsabilité' })]
186
- end
187
-
188
- context 'with ǂc defined' do
189
- it 'returns statement of responsibility' do
190
- expect(helper.statement_of_responsibility_show(record)).to include 'statement of responsibility'
191
- end
192
- end
193
-
194
- context 'with linked alternate of 245 ǂc defined' do
195
- it 'returns alternate statement of responsibility' do
196
- expect(helper.statement_of_responsibility_show(record)).to include 'déclaration de responsabilité'
197
- end
198
- end
199
- end
200
-
201
211
  describe '.sort' do
202
212
  context 'with a record with a valid indicator2 value' do
203
213
  let(:record) do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pennmarc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Kanning
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2024-08-20 00:00:00.000000000 Z
15
+ date: 2024-08-30 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport