Skip to content

Commit

Permalink
i425 Export FileSet filenames (and i424 fix) (#441)
Browse files Browse the repository at this point in the history
* add new #build_file_set_metadata method to #build_export_metadata

* add specific error message, add unit tests for #build_file_set_metadata

* properly export FileSet filenames and files

* #424 fix relationship exporting

* update specs for filename exporting

* move collection membership parsing to its own method, update specs

* add #build_files specs for Works

* add method to handle join parsing

* fix bug, update specs

* add unit specs for #handle_join_on_export

* remove #build_collection_memberships in favor of #build_relationship_metadata
  • Loading branch information
bkiahstroud authored Mar 23, 2022
1 parent 8e93a18 commit 4949647
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 30 deletions.
42 changes: 22 additions & 20 deletions app/models/bulkrax/csv_entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,6 @@ def build_export_metadata
self.parsed_metadata['model'] = hyrax_record.has_model.first
build_relationship_metadata
build_mapping_metadata

# TODO: fix the "send" parameter in the conditional below
# currently it returns: "NoMethodError - undefined method 'bulkrax_identifier' for #<Collection:0x00007fbe6a3b4248>"
if mapping['collection']&.[]('join')
self.parsed_metadata['collection'] = hyrax_record.member_of_collection_ids.join('; ')
# self.parsed_metadata['collection'] = hyrax_record.member_of_collections.map { |c| c.send(work_identifier)&.first }.compact.uniq.join(';')
else
hyrax_record.member_of_collections.each_with_index do |collection, i|
self.parsed_metadata["collection_#{i + 1}"] = collection.id
# self.parsed_metadata["collection_#{i + 1}"] = collection.send(work_identifier)&.first
end
end

build_files unless hyrax_record.is_a?(Collection)
self.parsed_metadata
end
Expand All @@ -133,18 +120,24 @@ def build_relationship_metadata
relationship_methods.each do |relationship_key, methods|
next if relationship_key.blank?

parsed_metadata[relationship_key] ||= []
values = []
methods.each do |m|
parsed_metadata[relationship_key] << hyrax_record.public_send(m) if hyrax_record.respond_to?(m)
values << hyrax_record.public_send(m) if hyrax_record.respond_to?(m)
end
parsed_metadata[relationship_key] = parsed_metadata[relationship_key].flatten.uniq
values = values.flatten.uniq
next if values.blank?

handle_join_on_export(relationship_key, values, mapping[related_parents_parsed_mapping]['join'].present?)
end
end

def build_mapping_metadata
mapping.each do |key, value|
next if Bulkrax.reserved_properties.include?(key) && !field_supported?(key)
next if key == "model"
# relationships handled by #build_relationship_metadata
next if [related_parents_parsed_mapping, related_children_parsed_mapping].include?(key)
next if key == 'file' # handled by #build_files
next if value['excluded']

object_key = key if value.key?('object')
Expand Down Expand Up @@ -219,12 +212,21 @@ def object_metadata(data)
end

def build_files
if mapping['file']&.[]('join')
self.parsed_metadata['file'] = hyrax_record.file_sets.map { |fs| filename(fs).to_s if filename(fs).present? }.compact.join('; ')
file_mapping = mapping['file']&.[]('from')&.first || 'file'
file_sets = hyrax_record.file_set? ? Array.wrap(hyrax_record) : hyrax_record.file_sets

filenames = file_sets.map { |fs| filename(fs).to_s if filename(fs).present? }.compact
handle_join_on_export(file_mapping, filenames, mapping['file']&.[]('join')&.present?)
end

def handle_join_on_export(key, values, join)
if join
parsed_metadata[key] = values.join(' | ') # TODO: make split char dynamic
else
hyrax_record.file_sets.each_with_index do |fs, i|
self.parsed_metadata["file_#{i + 1}"] = filename(fs).to_s if filename(fs).present?
values.each_with_index do |value, i|
parsed_metadata["#{key}_#{i + 1}"] = value
end
parsed_metadata.delete(key)
end
end

Expand Down
4 changes: 3 additions & 1 deletion app/models/concerns/bulkrax/export_behavior.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def hyrax_record

def write_files
return if hyrax_record.is_a?(Collection)
hyrax_record.file_sets.each do |fs|

file_sets = hyrax_record.file_set? ? Array.wrap(hyrax_record) : hyrax_record.file_sets
file_sets.each do |fs|
path = File.join(exporter_export_path, 'files')
FileUtils.mkdir_p(path)
file = filename(fs)
Expand Down
195 changes: 186 additions & 9 deletions spec/models/bulkrax/csv_entry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -681,14 +681,10 @@ module Bulkrax
entry.build_relationship_metadata
end

it 'adds the relationship keys to the parsed_metadata' do
expect(entry.parsed_metadata.keys).to include('parents', 'children')
end

context "when the entry's record does not have any relationships" do
it 'adds empty arrays to the relationship mappings in the parsed_metadata' do
expect(entry.parsed_metadata['parents']).to eq([])
expect(entry.parsed_metadata['children']).to eq([])
it 'does not add any relationships to the parsed_metadata' do
expect(entry.parsed_metadata.keys).not_to include('parents')
expect(entry.parsed_metadata.keys).not_to include('children')
end
end

Expand All @@ -705,13 +701,194 @@ module Bulkrax
end

it 'adds all the parent relationships to the parent field mapping' do
expect(entry.parsed_metadata['parents']).to eq(%w[pc1 pc2 pw1 pw2 pw3 pw4])
expect(entry.parsed_metadata['parents_1']).to eq('pc1')
expect(entry.parsed_metadata['parents_2']).to eq('pc2')
expect(entry.parsed_metadata['parents_3']).to eq('pw1')
expect(entry.parsed_metadata['parents_4']).to eq('pw2')
expect(entry.parsed_metadata['parents_5']).to eq('pw3')
expect(entry.parsed_metadata['parents_6']).to eq('pw4')
end

it 'adds all the child relationships to the child field mapping' do
expect(entry.parsed_metadata['children']).to eq(%w[cc1 cc2 cw1 cw2 cfs1 cfs2])
expect(entry.parsed_metadata['children_1']).to eq('cc1')
expect(entry.parsed_metadata['children_2']).to eq('cc2')
expect(entry.parsed_metadata['children_3']).to eq('cw1')
expect(entry.parsed_metadata['children_4']).to eq('cw2')
expect(entry.parsed_metadata['children_5']).to eq('cfs1')
expect(entry.parsed_metadata['children_6']).to eq('cfs2')
end

context 'with a join setting' do
let(:exporter) { create(:bulkrax_exporter, field_mapping: field_mapping) }
let(:field_mapping) do
{
'parents' => { 'from' => ['parents_column'], join: true, split: /\s*[|]\s*/, related_parents_field_mapping: true },
'children' => { 'from' => ['children_column'], join: true, split: /\s*[|]\s*/, related_children_field_mapping: true }
}
end

it 'joins the values into a single column' do
expect(entry.parsed_metadata['parents']).to eq('pc1 | pc2 | pw1 | pw2 | pw3 | pw4')
expect(entry.parsed_metadata['children']).to eq('cc1 | cc2 | cw1 | cw2 | cfs1 | cfs2')
end
end
end
end
end

describe '#build_files' do
subject(:entry) { described_class.new(importerexporter: exporter) }
let(:exporter) { create(:bulkrax_exporter) }

before do
allow(entry).to receive(:hyrax_record).and_return(hyrax_record)
end

context 'when entry#hyrax_record is a Collection' do
let(:hyrax_record) do
OpenStruct.new(
has_model: ['Collection'],
source: 'test',
member_of_collections: [],
file_set?: false
)
end

before do
allow(hyrax_record).to receive(:is_a?).with(FileSet).and_return(false)
allow(hyrax_record).to receive(:is_a?).with(Collection).and_return(true)
end

it 'does not get called by #build_export_metadata' do
expect(entry).not_to receive(:build_files)
entry.build_export_metadata
end
end

context 'when entry#hyrax_record is a FileSet' do
let(:hyrax_record) do
OpenStruct.new(
has_model: ['FileSet'],
file_set?: true
)
end

before do
entry.parsed_metadata = {}
allow(hyrax_record).to receive(:is_a?).with(FileSet).and_return(true)
allow(hyrax_record).to receive(:is_a?).with(Collection).and_return(false)
allow(entry).to receive(:filename).and_return('hello.png')
end

it 'gets called by #build_export_metadata' do
expect(entry).to receive(:build_files).once
entry.build_export_metadata
end

context 'when the parser has a file field mapping' do
context 'with join set to true' do
let(:exporter) { create(:bulkrax_exporter, field_mapping: { 'file' => { from: ['filename'], join: true } }) }

it "adds the file set's filename to the file mapping in parsed_metadata" do
entry.build_files

expect(entry.parsed_metadata['filename']).to eq('hello.png')
end
end
end

context 'when the parser does not have a file field mapping' do
it "adds the file set's filename to the 'file' key in parsed_metadata" do
entry.build_files

expect(entry.parsed_metadata['file_1']).to eq('hello.png')
end
end
end

context 'when entry#hyrax_record is a Work' do
let(:hyrax_record) do
OpenStruct.new(
has_model: ['Work'],
file_set?: false,
file_sets: [file_set_1, file_set_2],
member_of_collections: []
)
end
let(:file_set_1) do
OpenStruct.new(
id: 'file_set_1',
original_file: OpenStruct.new(
file_name: ['hello.png'],
mime_type: 'image/png'
)
)
end
let(:file_set_2) do
OpenStruct.new(
id: 'file_set_2',
original_file: OpenStruct.new(
file_name: ['world.jpg'],
mime_type: 'image/jpeg'
)
)
end

before do
entry.parsed_metadata = {}
allow(hyrax_record).to receive(:is_a?).with(FileSet).and_return(false)
allow(hyrax_record).to receive(:is_a?).with(Collection).and_return(false)
end

it 'gets called by #build_export_metadata' do
expect(entry).to receive(:build_files).once
entry.build_export_metadata
end

context 'when the parser has a file field mapping' do
context 'with join set to true' do
let(:exporter) { create(:bulkrax_exporter, field_mapping: { 'file' => { from: ['filename'], join: true } }) }

it "adds the work's file set's filenames to the file mapping in parsed_metadata" do
entry.build_files

expect(entry.parsed_metadata['filename']).to eq('hello.png | world.jpg')
end
end
end

context 'when the parser does not have a file field mapping' do
it "adds the work's file set's filenames to the 'file' key in parsed_metadata" do
entry.build_files

expect(entry.parsed_metadata['file_1']).to eq('hello.png')
expect(entry.parsed_metadata['file_2']).to eq('world.jpg')
end
end
end
end

describe '#handle_join_on_export' do
subject(:entry) { described_class.new(importerexporter: exporter, parsed_metadata: {}) }
let(:exporter) { create(:bulkrax_exporter) }

context 'when a field mapping is configured to join values' do
it 'joins the values into a single column' do
entry.handle_join_on_export('dummy', %w[a1 b2 c3], true)

expect(entry.parsed_metadata['dummy']).to eq('a1 | b2 | c3')
end
end

context 'when a field mapping is not configured to join values' do
it 'lists the values in separate, numerated columns' do
entry.handle_join_on_export('dummy', %w[a1 b2 c3], false)

expect(entry.parsed_metadata['dummy']).to be_nil
expect(entry.parsed_metadata['dummy_1']).to eq('a1')
expect(entry.parsed_metadata['dummy_2']).to eq('b2')
expect(entry.parsed_metadata['dummy_3']).to eq('c3')
end
end
end
end
Expand Down

0 comments on commit 4949647

Please sign in to comment.