# frozen_string_literal: true require 'spec_helper' RSpec.describe Assembly::ContentMetadata do describe '#create_content_metadata' do subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, style: style, objects: objects) } let(:xml) { Nokogiri::XML(result) } context 'when style=simple_image' do context 'when using a single tif and jp2' do it 'generates valid content metadata with exif, adding file attributes' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)] result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 2 expect(xml.xpath('//resource/file').length).to eq 2 expect(xml.xpath('//resource/file/checksum').length).to eq 4 expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41') expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101') expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c') expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d') expect(xml.xpath('//label').length).to eq 2 expect(xml.xpath('//label')[0].text).to match(/Image 1/) expect(xml.xpath('//label')[1].text).to match(/Image 2/) expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image') expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542') expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff') expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes') expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100') expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100') expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306') expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2') expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no') expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100') expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100') end end context 'when using a single tif and jp2' do it 'generates valid content metadata with no exif adding specific file attributes for 2 objects, and defaults for 1 object' do obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE) obj2 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE) obj3 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE2) obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no' } obj2.file_attributes = { publish: 'yes', preserve: 'yes', shelve: 'yes' } objects = [obj1, obj2, obj3] result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 3 expect(xml.xpath('//resource/file').length).to eq 3 expect(xml.xpath('//resource/file/checksum').length).to eq 0 expect(xml.xpath('//resource/file/imageData').length).to eq 0 expect(xml.xpath('//label').length).to eq 3 expect(xml.xpath('//label')[0].text).to match(/Image 1/) expect(xml.xpath('//label')[1].text).to match(/Image 2/) expect(xml.xpath('//label')[2].text).to match(/Image 3/) expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image') expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('image') expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') # specificially set in object expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') # specificially set in object expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') # specificially set in object expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') # specificially set in object expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') # specificially set in object expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') # specificially set in object expect(xml.xpath('//resource/file')[2].attributes['publish'].value).to eq('yes') # defaults by mimetype expect(xml.xpath('//resource/file')[2].attributes['preserve'].value).to eq('no') # defaults by mimetype expect(xml.xpath('//resource/file')[2].attributes['shelve'].value).to eq('yes') # defaults by mimetype end end context 'when using a single tif and jp2' do it 'generates valid content metadata with exif, overriding file labels' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE, label: 'Sample tif label!'), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE, label: 'Sample jp2 label!')] result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 2 expect(xml.xpath('//resource/file').length).to eq 2 expect(xml.xpath('//resource/file/checksum').length).to eq 4 expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41') expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101') expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c') expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d') expect(xml.xpath('//label').length).to eq 2 expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/) expect(xml.xpath('//label')[1].text).to match(/Sample jp2 label!/) expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image') expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542') expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff') expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes') expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100') expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100') expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306') expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2') expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no') expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100') expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100') end end context 'when using a single tif and jp2' do it 'generates valid content metadata with exif, overriding file labels for one, and skipping auto labels for the others or for where the label is set but is blank' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE, label: 'Sample tif label!'), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE, label: '')] result = described_class.create_content_metadata(druid: TEST_DRUID, auto_labels: false, add_file_attributes: true, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 3 expect(xml.xpath('//resource/file').length).to eq 3 expect(xml.xpath('//label').length).to eq 1 expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/) end end context 'when using a single tif and jp2' do it 'generates valid content metadata with overriding file attributes and no exif data' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)] result = described_class.create_content_metadata(druid: TEST_DRUID, add_file_attributes: true, file_attributes: { 'image/tiff' => { publish: 'no', preserve: 'no', shelve: 'no' }, 'image/jp2' => { publish: 'yes', preserve: 'yes', shelve: 'yes' } }, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 2 expect(xml.xpath('//resource/file').length).to eq 2 expect(xml.xpath('//label').length).to eq 2 expect(xml.xpath('//resource/file/imageData').length).to eq 0 expect(xml.xpath('//label')[0].text).to match(/Image 1/) expect(xml.xpath('//label')[1].text).to match(/Image 2/) expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image') expect(xml.xpath('//resource/file')[0].attributes['size']).to be_nil expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[0].attributes['role']).to be_nil expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') expect(xml.xpath('//resource/file')[1].attributes['size']).to be_nil expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[1].attributes['role']).to be_nil expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') end end context 'when using a single tif and jp2' do it 'generates valid content metadata with overriding file attributes, including a default value, and no exif data' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)] result = described_class.create_content_metadata(druid: TEST_DRUID, add_file_attributes: true, file_attributes: { 'default' => { publish: 'yes', preserve: 'no', shelve: 'no' }, 'image/jp2' => { publish: 'yes', preserve: 'yes', shelve: 'yes' } }, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource/file').length).to eq 2 expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') (0..1).each do |i| expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1 expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}") expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image') end end end context 'when using two tifs and two associated jp2s using bundle=filename' do it 'generates valid content metadata and no exif data' do objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE2)] result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :filename, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image') expect(xml.xpath('//resource').length).to eq 2 expect(xml.xpath('//resource/file').length).to eq 4 expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('test.tif') expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('test.jp2') expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('test2.tif') expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('test2.jp2') expect(xml.xpath('//label').length).to eq 2 expect(xml.xpath('//resource/file/imageData').length).to eq 0 (0..1).each do |i| expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 2 expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}") expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image') end end end context 'when using two tifs and two associated jp2s using bundle=dpg' do it 'generates valid content metadata and no exif data and no root xml node' do objects = [Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP), Assembly::ObjectFile.new(TEST_DPG_TIF2), Assembly::ObjectFile.new(TEST_DPG_JP2)] test_druid = TEST_DRUID.to_s result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, include_root_xml: false) expect(result.class).to be String expect(result.include?(' { publish: 'yes', preserve: 'no', shelve: 'no' }, 'image/jp2' => { publish: 'yes', preserve: 'yes', shelve: 'yes' } }, objects: objects) expect(result.class).to be String xml = Nokogiri::XML(result) expect(xml.errors.size).to eq 0 expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('map') expect(xml.xpath('//bookData').length).to eq 0 expect(xml.xpath('//resource/file').length).to eq 2 expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') (0..1).each do |i| expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1 expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}") expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image') end end end end context 'when style=simple_book' do context 'when using two tifs, two associated jp2s, one combined pdf and one special tif using bundle=dpg' do it 'generates valid content metadata and no exif data and no root xml node, flattening folder structure' do objects = [Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF2), Assembly::ObjectFile.new(TEST_DPG_SPECIAL_TIF), Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP), Assembly::ObjectFile.new(TEST_DPG_TIF2), Assembly::ObjectFile.new(TEST_DPG_JP2)] result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, bundle: :dpg, objects: objects, include_root_xml: false, flatten_folder_structure: true) expect(result.class).to be String expect(result.include?('