pennmarc 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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