# 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 using a single tif and jp2 of style=simple_image' 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 of style=simple_image' 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 of style=simple_image' 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 of style=simple_image' 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 of style=simple_image' 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 of style=simple_image' 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 a single tif and jp2 of style=map' 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(style: :map, 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('map') 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 of style=simple_image 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 of style=simple_image 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?('