Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ group :development, :test do
# Static analysis for security vulnerabilities [https://brakemanscanner.org/]
gem 'brakeman', require: false

gem 'retriable', '~> 3.1'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolves duplicate gem error (Your Gemfile lists the gem retriable (~> 3.1) more than once)


gem 'rspec-rails', '~> 8.0.0'

gem 'pry', '~> 0.15.0'
Expand Down
45 changes: 45 additions & 0 deletions lib/folio_sync/archives_space_to_folio/marc_record_enhancer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def enhance_marc_record!
update_datafield_099
update_datafield_100
update_datafield_856
add_948_field
add_965_no_export_auth
remove_corpname_punctuation
rescue StandardError => e
Expand Down Expand Up @@ -110,6 +111,23 @@ def update_datafield_856
end
end

# OCLC sync support: Add or update datafield 948
def add_948_field
current_date = Time.now.utc.strftime('%Y%m%d')
existing_oclc_field = find_folio_948_asoclc_field

oclc_field = if existing_oclc_field
update_948_date(existing_oclc_field, current_date)
else
MARC::DataField.new('948', ' ', ' ',
['a', current_date],
['b', 'STATORGL'],
['d', 'ASOCLC'])
end

@marc_record.append(oclc_field)
end

# Add 965 field
def add_965_no_export_auth
field_965 = MARC::DataField.new('965', ' ', ' ', ['a', '965noexportAUTH'])
Expand Down Expand Up @@ -144,6 +162,33 @@ def process_corpname_datafield(field)
end
end

def update_948_date(field, date)
updated_field = MARC::DataField.new(
field.tag,
field.indicator1,
field.indicator2,
*field.subfields.map { |sf| [sf.code, sf.value] }
)

subfield_a = updated_field.subfields.find { |sf| sf.code == 'a' }
if subfield_a
subfield_a.value = date
else
updated_field.append(MARC::Subfield.new('a', date))
end

updated_field
end

def find_folio_948_asoclc_field
return nil unless @folio_marc

@folio_marc.fields('948').find do |field|
subfield_d = field['d']
subfield_d == 'ASOCLC'
end
end

def remove_trailing_commas(value)
value.gsub(/[.]$/, '')
end
Expand Down
118 changes: 117 additions & 1 deletion spec/folio_sync/archives_space_to_folio/marc_record_enhancer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

before do
File.write(aspace_marc_path, aspace_mock)
File.write(folio_marc_path, folio_mock)
File.write(folio_marc_path, folio_mock) if folio_marc_path

# Mock FOLIO::Reader
folio_reader = instance_double(FolioSync::Folio::Reader)
Expand Down Expand Up @@ -170,6 +170,122 @@
end
end

describe '#add_948_field' do
let(:marc_record) { described_class.new(aspace_marc_path, folio_marc_path, hrid, instance_key) }

context 'when FOLIO record has no 948 field' do
it 'creates a new 948 field with subfields a, b and d' do
marc_record.send(:add_948_field)
field_948 = marc_record.marc_record['948']

expect(field_948).not_to be_nil
expect(field_948['a']).to match(/\A\d{8}\z/) # YYYYMMDD format
expect(field_948['b']).to eq('STATORGL')
expect(field_948['d']).to eq('ASOCLC')
end
end

context 'when FOLIO record has 948 field with d == ASOCLC' do
let(:folio_mock) do
<<-XML
<record xmlns="http://www.loc.gov/MARC21/slim">
<controlfield tag="001">7890</controlfield>
<datafield tag="948" ind1=" " ind2=" ">
<subfield code="a">20200101</subfield>
<subfield code="b">STATORGL</subfield>
<subfield code="d">ASOCLC</subfield>
</datafield>
</record>
XML
end

it 'preserves existing subfields and updates subfield a to current date' do
marc_record.send(:add_948_field)
field_948 = marc_record.marc_record['948']

expect(field_948['a']).to match(/\A\d{8}\z/)
expect(field_948['a']).not_to eq('20200101')
expect(field_948['b']).to eq('STATORGL')
expect(field_948['d']).to eq('ASOCLC')
end
end

context 'when FOLIO record has 948 field with different d value' do
let(:folio_mock) do
<<-XML
<record xmlns="http://www.loc.gov/MARC21/slim">
<controlfield tag="001">7890</controlfield>
<datafield tag="948" ind1=" " ind2=" ">
<subfield code="a">20200101</subfield>
<subfield code="d">MPS</subfield>
</datafield>
</record>
XML
end

it 'creates a new 948 field' do
marc_record.send(:add_948_field)
field_948 = marc_record.marc_record['948']

expect(field_948['d']).to eq('ASOCLC')
expect(field_948['b']).to eq('STATORGL')
end
end
end

describe '#find_folio_948_asoclc_field' do
let(:marc_record) { described_class.new(aspace_marc_path, folio_marc_path, hrid, instance_key) }

context 'when no folio_marc exists' do
let(:folio_marc_path) { nil }

it 'returns nil' do
result = marc_record.send(:find_folio_948_asoclc_field)
expect(result).to be_nil
end
end

context 'when folio_marc has 948 with d == ASOCLC' do
let(:folio_mock) do
<<-XML
<record xmlns="http://www.loc.gov/MARC21/slim">
<datafield tag="948" ind1=" " ind2=" ">
<subfield code="a">20200101</subfield>
<subfield code="d">ASOCLC</subfield>
</datafield>
</record>
XML
end

it 'returns the matching field' do
result = marc_record.send(:find_folio_948_asoclc_field)
expect(result).not_to be_nil
expect(result['d']).to eq('ASOCLC')
end
end
end

describe '#update_948_date' do
let(:marc_record) { described_class.new(aspace_marc_path, folio_marc_path, hrid, instance_key) }
let(:field) do
MARC::DataField.new('948', ' ', ' ',
['a', '20200101'],
['b', 'STATORGL'],
['d', 'ASOCLC'])
end

it 'updates subfield a to the new date' do
result = marc_record.send(:update_948_date, field, '20260202')
expect(result['a']).to eq('20260202')
end

it 'preserves other subfields' do
result = marc_record.send(:update_948_date, field, '20260202')
expect(result['b']).to eq('STATORGL')
expect(result['d']).to eq('ASOCLC')
end
end

describe 'helper methods' do
let(:marc_record) { described_class.new(aspace_marc_path, folio_marc_path, hrid, instance_key) }

Expand Down