assembly-objectfile 1.8.3 → 1.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Assembly
4
+ class ContentMetadata
5
+ # Builds a groups of related Files, based on bundle
6
+ class FileSetBuilder
7
+ # @param [Symbol] bundle one of: :default, :filename, :dpg or :prebundled
8
+ # @param [Array<Assembly::ObjectFile>] objects
9
+ # @param [Symbol] style one of: :simple_image, :file, :simple_book, :book_as_image, :book_with_pdf, :map, or :'3d'
10
+ def self.build(bundle:, objects:, style:)
11
+ new(bundle: bundle, objects: objects, style: style).build
12
+ end
13
+
14
+ def initialize(bundle:, objects:, style:)
15
+ @bundle = bundle
16
+ @objects = objects
17
+ @style = style
18
+ end
19
+
20
+ # @return [Array<FileSet>] a list of filesets in the object
21
+ def build
22
+ case bundle
23
+ when :default # one resource per object
24
+ objects.collect { |obj| FileSet.new(resource_files: [obj], style: style) }
25
+ when :filename # one resource per distinct filename (excluding extension)
26
+ build_for_filename
27
+ when :dpg # group by DPG filename
28
+ build_for_dpg
29
+ when :prebundled
30
+ # if the user specifies this method, they will pass in an array of arrays, indicating resources, so we don't need to bundle in the gem
31
+ # This is used by the assemblyWF if you have stubContentMetadata.xml
32
+ objects.map { |inner| FileSet.new(resource_files: inner, style: style) }
33
+ else
34
+ raise 'Invalid bundle method'
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :bundle, :objects, :style
41
+
42
+ def build_for_filename
43
+ # loop over distinct filenames, this determines how many resources we will have and
44
+ # create one resource node per distinct filename, collecting the relevant objects with the distinct filename into that resource
45
+ distinct_filenames = objects.collect(&:filename_without_ext).uniq # find all the unique filenames in the set of objects, leaving off extensions and base paths
46
+ distinct_filenames.map do |distinct_filename|
47
+ FileSet.new(resource_files: objects.collect { |obj| obj if obj.filename_without_ext == distinct_filename }.compact,
48
+ style: style)
49
+ end
50
+ end
51
+
52
+ def build_for_dpg
53
+ # loop over distinct dpg base names, this determines how many resources we will have and
54
+ # create one resource node per distinct dpg base name, collecting the relevant objects with the distinct names into that resource
55
+
56
+ distinct_filenames = objects.collect(&:dpg_basename).uniq # find all the unique DPG filenames in the set of objects
57
+ resources = distinct_filenames.map do |distinct_filename|
58
+ FileSet.new(dpg: true, resource_files: objects.collect { |obj| obj if obj.dpg_basename == distinct_filename && !ContentMetadata.special_dpg_folder?(obj.dpg_folder) }.compact, style: style)
59
+ end
60
+ objects.each { |obj| resources << FileSet.new(dpg: true, resource_files: [obj], style: style) if ContentMetadata.special_dpg_folder?(obj.dpg_folder) } # certain subfolders require individual resources for files within them regardless of file-naming convention
61
+ resources
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Assembly
4
+ class ContentMetadata
5
+ # Builds a nokogiri representation of the content metadata
6
+ class NokogiriBuilder
7
+ # @param [Array<Fileset>] filesets
8
+ # @param [String] druid
9
+ # @param [String] common_path
10
+ # @param [Config] config
11
+ def self.build(filesets:, druid:, common_path:, config:)
12
+ # a counter to use when creating auto-labels for resources, with incremenets for each type
13
+ resource_type_counters = Hash.new(0)
14
+ pid = druid.gsub('druid:', '') # remove druid prefix when creating IDs
15
+
16
+ Nokogiri::XML::Builder.new do |xml|
17
+ xml.contentMetadata(objectId: druid.to_s, type: config.type) do
18
+ xml.bookData(readingOrder: config.reading_order) if config.type == 'book'
19
+
20
+ filesets.each_with_index do |fileset, index| # iterate over all the resources
21
+ # start a new resource element
22
+ sequence = index + 1
23
+
24
+ resource_type_counters[fileset.resource_type_description] += 1 # each resource type description gets its own incrementing counter
25
+
26
+ xml.resource(id: "#{pid}_#{sequence}", sequence: sequence, type: fileset.resource_type_description) do
27
+ # create a generic resource label if needed
28
+ default_label = config.auto_labels ? "#{fileset.resource_type_description.capitalize} #{resource_type_counters[fileset.resource_type_description]}" : ''
29
+
30
+ # but if one of the files has a label, use it instead
31
+ resource_label = fileset.label_from_file(default: default_label)
32
+
33
+ xml.label(resource_label) unless resource_label.empty?
34
+ fileset.files.each do |obj| # iterate over all the files in a resource
35
+ xml_file_params = { id: obj.file_id(common_path: common_path, flatten_folder_structure: config.flatten_folder_structure) }
36
+ xml_file_params.merge!(obj.file_attributes(config.file_attributes)) if config.add_file_attributes
37
+ xml_file_params.merge!(mimetype: obj.mimetype, size: obj.filesize) if config.add_exif
38
+
39
+ xml.file(xml_file_params) do
40
+ if config.add_exif # add exif info if the user requested it
41
+ xml.checksum(obj.sha1, type: 'sha1')
42
+ xml.checksum(obj.md5, type: 'md5')
43
+ xml.imageData(obj.image_data) if obj.image? # add image data for an image
44
+ elsif obj.provider_md5 || obj.provider_sha1 # if we did not add exif info, see if there are user supplied checksums to add
45
+ xml.checksum(obj.provider_sha1, type: 'sha1') if obj.provider_sha1
46
+ xml.checksum(obj.provider_md5, type: 'md5') if obj.provider_md5
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Assembly
2
4
  # This class contains generic methods to operate on any file.
3
5
  class ObjectFile
@@ -17,10 +19,10 @@ module Assembly
17
19
  x = strings.last
18
20
  n += 1 while strings.all? { |s| s[n] && (s[n] == x[n]) }
19
21
  common_prefix = x[0...n]
20
- if common_prefix[-1, 1] != '/' # check if last element of the common string is the end of a directory
21
- return common_prefix.split('/')[0..-2].join('/') + '/' # if not, split string along directories, and reject last one
22
+ if common_prefix[-1, 1] == '/' # check if last element of the common string is the end of a directory
23
+ common_prefix # if not, split string along directories, and reject last one
22
24
  else
23
- return common_prefix # if it was, then return the common prefix directly
25
+ "#{common_prefix.split('/')[0..-2].join('/')}/" # if it was, then return the common prefix directly
24
26
  end
25
27
  end
26
28
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mini_exiftool'
2
4
  require 'mime/types'
3
- # require 'checksum-tools'
4
5
 
5
6
  module Assembly
6
7
  # Common behaviors we need for other classes in the gem
7
8
  module ObjectFileable
8
- attr_accessor :file_attributes, :label, :path, :provider_md5, :provider_sha1, :relative_path
9
+ attr_accessor :file_attributes, :label, :path, :provider_md5, :provider_sha1, :relative_path, :mime_type_order
10
+
11
+ VALID_MIMETYPE_METHODS = %i[exif file extension].freeze
9
12
 
10
13
  # @param [String] path full path to the file to be worked with
11
14
  # @param [Hash<Symbol => Object>] params options used during content metadata generation
@@ -14,6 +17,9 @@ module Assembly
14
17
  # @option params [String] :provider_md5 pre-computed MD5 checksum
15
18
  # @option params [String] :provider_sha1 pre-computed SHA1 checksum
16
19
  # @option params [String] :relative_path if you want the file ids in the content metadata it can be set, otherwise content metadata will get the full path
20
+ # @option params [Array] :mime_type_order can be set to the order in which you want mimetypes to be determined
21
+ # options are :exif (from exif if exists), :extension (from file extension), and :file (from unix file system command)
22
+ # the default is defined in the private `default_mime_type_order` method but you can override to set your own order
17
23
  # @example
18
24
  # Assembly::ObjectFile.new('/input/path_to_file.tif')
19
25
  def initialize(path, params = {})
@@ -23,6 +29,7 @@ module Assembly
23
29
  @relative_path = params[:relative_path]
24
30
  @provider_md5 = params[:provider_md5]
25
31
  @provider_sha1 = params[:provider_sha1]
32
+ @mime_type_order = params[:mime_type_order] || default_mime_type_order
26
33
  end
27
34
 
28
35
  # @return [String] DPG base filename, removing the extension and the '00','05', etc. placeholders
@@ -81,11 +88,11 @@ module Assembly
81
88
  # puts source_file.exif # hash with exif information
82
89
  def exif
83
90
  @exif ||= begin
84
- check_for_file
85
- MiniExiftool.new(path, replace_invalid_chars: '?')
86
- rescue StandardError
87
- nil
88
- end
91
+ check_for_file
92
+ MiniExiftool.new(path, replace_invalid_chars: '?')
93
+ rescue StandardError
94
+ nil
95
+ end
89
96
  end
90
97
 
91
98
  # Computes md5 checksum or returns cached value
@@ -108,22 +115,33 @@ module Assembly
108
115
  @sha1 ||= Digest::SHA1.file(path).hexdigest
109
116
  end
110
117
 
111
- # Returns mimetype information for the current file based on
112
- # (1) exifdata (if available), (2) unix file type or (3) file extension using the mimetypes gem, in this priority order
118
+ # Returns mimetype information for the current file based on the ordering set in default_mime_type_order
119
+ # We stop computing mimetypes as soon as we have a method that returns a value
113
120
  # @return [String] mime type
114
121
  # @example
115
122
  # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
116
123
  # puts source_file.mimetype # 'text/plain'
117
124
  def mimetype
118
125
  @mimetype ||= begin
119
- if exif_mimetype # first, try the exif data
120
- exif_mimetype
121
- elsif file_mimetype # next, try exif/unix file system command
122
- file_mimetype
123
- else # finally, get it from the mime-types gem (using the file extension) if both of those failed for some reason
124
- mtype = MIME::Types.type_for(path).first
125
- mtype ? mtype.content_type : ''
126
+ check_for_file
127
+ mimetype = ''
128
+ mime_type_order.each do |mime_type_method|
129
+ mimetype = public_send("#{mime_type_method}_mimetype") if VALID_MIMETYPE_METHODS.include?(mime_type_method)
130
+ break if !mimetype.nil? && mimetype != ''
126
131
  end
132
+ mimetype
133
+ end
134
+ end
135
+
136
+ # Returns mimetype information using the mime-types gem (based on a file extension lookup)
137
+ # @return [String] mime type for supplied file
138
+ # @example
139
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
140
+ # puts source_file.extension_mimetype # 'text/plain'
141
+ def extension_mimetype
142
+ @extension_mimetype ||= begin
143
+ mtype = MIME::Types.type_for(path).first
144
+ mtype ? mtype.content_type : ''
127
145
  end
128
146
  end
129
147
 
@@ -148,7 +166,8 @@ module Assembly
148
166
  @exif_mimetype ||= begin
149
167
  check_for_file
150
168
  prefer_exif = !Assembly::TRUSTED_MIMETYPES.include?(file_mimetype) # if it's not a "trusted" mimetype and there is exif data; get the mimetype from the exif
151
- exif.mimetype if exif && exif.mimetype && prefer_exif
169
+ exif.mimetype if
170
+ exif&.mimetype && prefer_exif
152
171
  end
153
172
  end
154
173
 
@@ -190,7 +209,7 @@ module Assembly
190
209
  def valid_image?
191
210
  return false unless image?
192
211
 
193
- mimetype == 'image/jp2' || jp2able? ? true : false
212
+ mimetype == 'image/jp2' || jp2able?
194
213
  end
195
214
 
196
215
  # @return [Boolean] true if image has a color profile, false if not.
@@ -231,11 +250,16 @@ module Assembly
231
250
  # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
232
251
  # puts source_file.file_exists? # true
233
252
  def file_exists?
234
- File.exist?(path) && !File.directory?(path)
253
+ @file_exists ||= (File.exist?(path) && !File.directory?(path))
235
254
  end
236
255
 
237
256
  private
238
257
 
258
+ # prive method defining default preferred ordering of how mimetypes are determined
259
+ def default_mime_type_order
260
+ %i[exif file extension]
261
+ end
262
+
239
263
  # private method to check for file existence before operating on it
240
264
  def check_for_file
241
265
  raise "input file #{path} does not exist" unless file_exists?
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Main Assembly namespace
2
4
  module Assembly
3
5
  class ObjectFile
4
6
  # Project version number
5
- VERSION = '1.8.3'.freeze
7
+ VERSION = '1.10.2'
6
8
  end
7
9
  end
@@ -1,609 +1,791 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- describe Assembly::ContentMetadata do
4
- it 'generates valid content metadata with exif for a single tif and jp2 of style=simple_image, adding file attributes' do
5
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
6
- result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects)
7
- expect(result.class).to be String
8
- xml = Nokogiri::XML(result)
9
- expect(xml.errors.size).to be 0
10
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
11
- expect(xml.xpath('//resource').length).to be 2
12
- expect(xml.xpath('//resource/file').length).to be 2
13
- expect(xml.xpath('//resource/file/checksum').length).to be 4
14
- expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41')
15
- expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101')
16
- expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
17
- expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d')
18
- expect(xml.xpath('//label').length).to be 2
19
- expect(xml.xpath('//label')[0].text).to match(/Image 1/)
20
- expect(xml.xpath('//label')[1].text).to match(/Image 2/)
21
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
22
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
23
- expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542')
24
- expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff')
25
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
26
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes')
27
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
28
- expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
29
- expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
30
- expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306')
31
- expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2')
32
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
33
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no')
34
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
35
- expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100')
36
- expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100')
37
- end
5
+ RSpec.describe Assembly::ContentMetadata do
6
+ describe '#create_content_metadata' do
7
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, style: style, objects: objects) }
38
8
 
39
- it 'generates valid content metadata with no exif for a single tif and jp2 of style=simple_image, adding specific file attributes for 2 objects, and defaults for 1 object' do
40
- obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
41
- obj2 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)
42
- obj3 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE2)
43
- obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no' }
44
- obj2.file_attributes = { publish: 'yes', preserve: 'yes', shelve: 'yes' }
45
- objects = [obj1, obj2, obj3]
46
- result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects)
47
- expect(result.class).to be String
48
- xml = Nokogiri::XML(result)
49
- expect(xml.errors.size).to be 0
50
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
51
- expect(xml.xpath('//resource').length).to be 3
52
- expect(xml.xpath('//resource/file').length).to be 3
53
- expect(xml.xpath('//resource/file/checksum').length).to be 0
54
- expect(xml.xpath('//resource/file/imageData').length).to be 0
55
- expect(xml.xpath('//label').length).to be 3
56
- expect(xml.xpath('//label')[0].text).to match(/Image 1/)
57
- expect(xml.xpath('//label')[1].text).to match(/Image 2/)
58
- expect(xml.xpath('//label')[2].text).to match(/Image 3/)
59
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
60
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
61
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('image')
62
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') # specificially set in object
63
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') # specificially set in object
64
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') # specificially set in object
65
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') # specificially set in object
66
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') # specificially set in object
67
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') # specificially set in object
68
- expect(xml.xpath('//resource/file')[2].attributes['publish'].value).to eq('yes') # defaults by mimetype
69
- expect(xml.xpath('//resource/file')[2].attributes['preserve'].value).to eq('no') # defaults by mimetype
70
- expect(xml.xpath('//resource/file')[2].attributes['shelve'].value).to eq('yes') # defaults by mimetype
71
- end
9
+ let(:xml) { Nokogiri::XML(result) }
72
10
 
73
- it 'generates valid content metadata with exif for a single tif and jp2 of style=simple_image overriding file labels' do
74
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE, label: 'Sample tif label!'), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE, label: 'Sample jp2 label!')]
75
- result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects)
76
- expect(result.class).to be String
77
- xml = Nokogiri::XML(result)
78
- expect(xml.errors.size).to be 0
79
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
80
- expect(xml.xpath('//resource').length).to be 2
81
- expect(xml.xpath('//resource/file').length).to be 2
82
- expect(xml.xpath('//resource/file/checksum').length).to be 4
83
- expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41')
84
- expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101')
85
- expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
86
- expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d')
87
- expect(xml.xpath('//label').length).to be 2
88
- expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/)
89
- expect(xml.xpath('//label')[1].text).to match(/Sample jp2 label!/)
90
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
91
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
92
- expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542')
93
- expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff')
94
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
95
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes')
96
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
97
- expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
98
- expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
99
- expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306')
100
- expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2')
101
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
102
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no')
103
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
104
- expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100')
105
- expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100')
106
- end
11
+ context 'when style=simple_image' do
12
+ context 'when using a single tif and jp2' do
13
+ it 'generates valid content metadata with exif, adding file attributes' do
14
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
15
+ result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects)
16
+ expect(result.class).to be String
17
+ xml = Nokogiri::XML(result)
18
+ expect(xml.errors.size).to eq 0
19
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
20
+ expect(xml.xpath('//resource').length).to eq 2
21
+ expect(xml.xpath('//resource/file').length).to eq 2
22
+ expect(xml.xpath('//resource/file/checksum').length).to eq 4
23
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41')
24
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101')
25
+ expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
26
+ expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d')
27
+ expect(xml.xpath('//label').length).to eq 2
28
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
29
+ expect(xml.xpath('//label')[1].text).to match(/Image 2/)
30
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
31
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
32
+ expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542')
33
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff')
34
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
35
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes')
36
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
37
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
38
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
39
+ expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306')
40
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2')
41
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
42
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no')
43
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
44
+ expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100')
45
+ expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100')
46
+ end
47
+ end
107
48
 
108
- it 'generates valid content metadata with exif for a single tif and jp2 of style=simple_image overriding file labels for one, and skipping auto labels for the others or for where the label is set but is blank' do
109
- 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: '')]
110
- result = described_class.create_content_metadata(druid: TEST_DRUID, auto_labels: false, add_file_attributes: true, objects: objects)
111
- expect(result.class).to be String
112
- xml = Nokogiri::XML(result)
113
- expect(xml.errors.size).to be 0
114
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
115
- expect(xml.xpath('//resource').length).to be 3
116
- expect(xml.xpath('//resource/file').length).to be 3
117
- expect(xml.xpath('//label').length).to be 1
118
- expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/)
119
- end
49
+ context 'when using a single tif and jp2' do
50
+ it 'generates valid content metadata with no exif adding specific file attributes for 2 objects, and defaults for 1 object' do
51
+ obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
52
+ obj2 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)
53
+ obj3 = Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE2)
54
+ obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no' }
55
+ obj2.file_attributes = { publish: 'yes', preserve: 'yes', shelve: 'yes' }
56
+ objects = [obj1, obj2, obj3]
57
+ result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects)
58
+ expect(result.class).to be String
59
+ xml = Nokogiri::XML(result)
60
+ expect(xml.errors.size).to eq 0
61
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
62
+ expect(xml.xpath('//resource').length).to eq 3
63
+ expect(xml.xpath('//resource/file').length).to eq 3
64
+ expect(xml.xpath('//resource/file/checksum').length).to eq 0
65
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
66
+ expect(xml.xpath('//label').length).to eq 3
67
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
68
+ expect(xml.xpath('//label')[1].text).to match(/Image 2/)
69
+ expect(xml.xpath('//label')[2].text).to match(/Image 3/)
70
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
71
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
72
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('image')
73
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no') # specificially set in object
74
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no') # specificially set in object
75
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no') # specificially set in object
76
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes') # specificially set in object
77
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes') # specificially set in object
78
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes') # specificially set in object
79
+ expect(xml.xpath('//resource/file')[2].attributes['publish'].value).to eq('yes') # defaults by mimetype
80
+ expect(xml.xpath('//resource/file')[2].attributes['preserve'].value).to eq('no') # defaults by mimetype
81
+ expect(xml.xpath('//resource/file')[2].attributes['shelve'].value).to eq('yes') # defaults by mimetype
82
+ end
83
+ end
120
84
 
121
- it 'generates valid content metadata for a single tif and jp2 of style=simple_image with overriding file attributes and no exif data' do
122
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
123
- 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)
124
- expect(result.class).to be String
125
- xml = Nokogiri::XML(result)
126
- expect(xml.errors.size).to be 0
127
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
128
- expect(xml.xpath('//resource').length).to be 2
129
- expect(xml.xpath('//resource/file').length).to be 2
130
- expect(xml.xpath('//label').length).to be 2
131
- expect(xml.xpath('//resource/file/imageData').length).to be 0
132
- expect(xml.xpath('//label')[0].text).to match(/Image 1/)
133
- expect(xml.xpath('//label')[1].text).to match(/Image 2/)
134
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
135
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
136
- expect(xml.xpath('//resource/file')[0].attributes['size']).to be nil
137
- expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be nil
138
- expect(xml.xpath('//resource/file')[0].attributes['role']).to be nil
139
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
140
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
141
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
142
- expect(xml.xpath('//resource/file')[1].attributes['size']).to be nil
143
- expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be nil
144
- expect(xml.xpath('//resource/file')[1].attributes['role']).to be nil
145
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
146
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
147
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
148
- end
85
+ context 'when using a single tif and jp2' do
86
+ it 'generates valid content metadata with exif, overriding file labels' do
87
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE, label: 'Sample tif label!'), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE, label: 'Sample jp2 label!')]
88
+ result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects)
89
+ expect(result.class).to be String
90
+ xml = Nokogiri::XML(result)
91
+ expect(xml.errors.size).to eq 0
92
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
93
+ expect(xml.xpath('//resource').length).to eq 2
94
+ expect(xml.xpath('//resource/file').length).to eq 2
95
+ expect(xml.xpath('//resource/file/checksum').length).to eq 4
96
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('8d11fab63089a24c8b17063d29a4b0eac359fb41')
97
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('a2400500acf21e43f5440d93be894101')
98
+ expect(xml.xpath('//resource/file/checksum')[2].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
99
+ expect(xml.xpath('//resource/file/checksum')[3].text).to eq('4eb54050d374291ece622d45e84f014d')
100
+ expect(xml.xpath('//label').length).to eq 2
101
+ expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/)
102
+ expect(xml.xpath('//label')[1].text).to match(/Sample jp2 label!/)
103
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
104
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
105
+ expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('63542')
106
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/tiff')
107
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
108
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('yes')
109
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
110
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
111
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
112
+ expect(xml.xpath('//resource/file')[1].attributes['size'].value).to eq('306')
113
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype'].value).to eq('image/jp2')
114
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
115
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('no')
116
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
117
+ expect(xml.xpath('//resource/file/imageData')[1].attributes['width'].value).to eq('100')
118
+ expect(xml.xpath('//resource/file/imageData')[1].attributes['height'].value).to eq('100')
119
+ end
120
+ end
121
+
122
+ context 'when using a single tif and jp2' do
123
+ 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
124
+ 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: '')]
125
+ result = described_class.create_content_metadata(druid: TEST_DRUID, auto_labels: false, add_file_attributes: true, objects: objects)
126
+ expect(result.class).to be String
127
+ xml = Nokogiri::XML(result)
128
+ expect(xml.errors.size).to eq 0
129
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
130
+ expect(xml.xpath('//resource').length).to eq 3
131
+ expect(xml.xpath('//resource/file').length).to eq 3
132
+ expect(xml.xpath('//label').length).to eq 1
133
+ expect(xml.xpath('//label')[0].text).to match(/Sample tif label!/)
134
+ end
135
+ end
136
+
137
+ context 'when using a single tif and jp2' do
138
+ it 'generates valid content metadata with overriding file attributes and no exif data' do
139
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
140
+ 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)
141
+ expect(result.class).to be String
142
+ xml = Nokogiri::XML(result)
143
+ expect(xml.errors.size).to eq 0
144
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
145
+ expect(xml.xpath('//resource').length).to eq 2
146
+ expect(xml.xpath('//resource/file').length).to eq 2
147
+ expect(xml.xpath('//label').length).to eq 2
148
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
149
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
150
+ expect(xml.xpath('//label')[1].text).to match(/Image 2/)
151
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
152
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
153
+ expect(xml.xpath('//resource/file')[0].attributes['size']).to be_nil
154
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil
155
+ expect(xml.xpath('//resource/file')[0].attributes['role']).to be_nil
156
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('no')
157
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
158
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
159
+ expect(xml.xpath('//resource/file')[1].attributes['size']).to be_nil
160
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil
161
+ expect(xml.xpath('//resource/file')[1].attributes['role']).to be_nil
162
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
163
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
164
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
165
+ end
166
+ end
167
+
168
+ context 'when using a single tif and jp2' do
169
+ it 'generates valid content metadata with overriding file attributes, including a default value, and no exif data' do
170
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
171
+ 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)
172
+ expect(result.class).to be String
173
+ xml = Nokogiri::XML(result)
174
+ expect(xml.errors.size).to eq 0
175
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
176
+ expect(xml.xpath('//resource/file').length).to eq 2
177
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil
178
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
179
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
180
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
181
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil
182
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
183
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
184
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
185
+ (0..1).each do |i|
186
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
187
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
188
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
189
+ end
190
+ end
191
+ end
192
+
193
+ context 'when using two tifs and two associated jp2s using bundle=filename' do
194
+ it 'generates valid content metadata and no exif data' do
195
+ 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)]
196
+ result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :filename, objects: objects)
197
+ expect(result.class).to be String
198
+ xml = Nokogiri::XML(result)
199
+ expect(xml.errors.size).to eq 0
200
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
201
+ expect(xml.xpath('//resource').length).to eq 2
202
+ expect(xml.xpath('//resource/file').length).to eq 4
203
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('test.tif')
204
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('test.jp2')
205
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('test2.tif')
206
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('test2.jp2')
207
+ expect(xml.xpath('//label').length).to eq 2
208
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
209
+ (0..1).each do |i|
210
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 2
211
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
212
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
213
+ end
214
+ end
215
+ end
216
+
217
+ context 'when using two tifs and two associated jp2s using bundle=dpg' do
218
+ it 'generates valid content metadata and no exif data and no root xml node' do
219
+ 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)]
220
+ test_druid = TEST_DRUID.to_s
221
+ result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, include_root_xml: false)
222
+ expect(result.class).to be String
223
+ expect(result.include?('<?xml')).to be false
224
+ xml = Nokogiri::XML(result)
225
+ expect(xml.errors.size).to eq 0
226
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
227
+ expect(test_druid).to eq(TEST_DRUID)
228
+ expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(TEST_DRUID.to_s)
229
+ expect(xml.xpath('//resource').length).to eq 2
230
+ expect(xml.xpath('//resource/file').length).to eq 4
231
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_001.tif')
232
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_001.jp2')
233
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_002.tif')
234
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_002.jp2')
235
+ expect(xml.xpath('//label').length).to eq 2
236
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
237
+ (0..1).each do |i|
238
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 2
239
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
240
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
241
+ end
242
+ end
243
+ end
244
+
245
+ context 'when using two tifs and two associated jp2s using bundle=default' do
246
+ it 'generates valid content metadata and no exif data' do
247
+ 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)]
248
+ result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :default, objects: objects)
249
+ expect(result.class).to be String
250
+ xml = Nokogiri::XML(result)
251
+ expect(xml.errors.size).to eq 0
252
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
253
+ expect(xml.xpath('//resource').length).to eq 4
254
+ expect(xml.xpath('//resource/file').length).to eq 4
255
+ expect(xml.xpath('//resource/file')[0].attributes['id'].value).to eq('test.tif')
256
+ expect(xml.xpath('//resource/file')[1].attributes['id'].value).to eq('test.jp2')
257
+ expect(xml.xpath('//resource/file')[2].attributes['id'].value).to eq('test2.tif')
258
+ expect(xml.xpath('//resource/file')[3].attributes['id'].value).to eq('test2.jp2')
259
+ expect(xml.xpath('//label').length).to eq 4
260
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
261
+ (0..3).each do |i|
262
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
263
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
264
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
265
+ end
266
+ end
267
+ end
268
+
269
+ context 'when using two tifs and two associated jp2s using bundle=default' do
270
+ it 'generates valid content metadata and no exif data, preserving full paths' do
271
+ 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)]
272
+ result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :default, objects: objects, preserve_common_paths: true)
273
+ expect(result.class).to be String
274
+ xml = Nokogiri::XML(result)
275
+ expect(xml.errors.size).to eq 0
276
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
277
+ expect(xml.xpath('//resource').length).to eq 4
278
+ expect(xml.xpath('//resource/file').length).to eq 4
279
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq(TEST_TIF_INPUT_FILE)
280
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq(TEST_JP2_INPUT_FILE)
281
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq(TEST_TIF_INPUT_FILE2)
282
+ expect(xml.xpath("//resource[@sequence='4']/file")[0].attributes['id'].value).to eq(TEST_JP2_INPUT_FILE2)
283
+ expect(xml.xpath('//label').length).to eq 4
284
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
285
+ (0..3).each do |i|
286
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
287
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
288
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
289
+ end
290
+ end
291
+ end
292
+
293
+ context 'when using bundle=prebundled' do
294
+ it 'generates valid content metadata for images and associated text files and no exif data' do
295
+ files = [[TEST_RES1_TIF1, TEST_RES1_JP1, TEST_RES1_TIF2, TEST_RES1_JP2, TEST_RES1_TEI, TEST_RES1_TEXT, TEST_RES1_PDF], [TEST_RES2_TIF1, TEST_RES2_JP1, TEST_RES2_TIF2, TEST_RES2_JP2, TEST_RES2_TEI, TEST_RES2_TEXT], [TEST_RES3_TIF1, TEST_RES3_JP1, TEST_RES3_TEI]]
296
+ objects = files.collect { |resource| resource.collect { |file| Assembly::ObjectFile.new(file) } }
297
+ result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: :simple_image, objects: objects)
298
+ expect(result.class).to be String
299
+ xml = Nokogiri::XML(result)
300
+ expect(xml.errors.size).to eq 0
301
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
302
+ expect(xml.xpath('//resource').length).to eq 3
303
+ expect(xml.xpath('//resource/file').length).to eq 16
304
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('res1_image1.tif')
305
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('res1_image1.jp2')
306
+ expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('res1_image2.tif')
307
+ expect(xml.xpath("//resource[@sequence='1']/file")[3].attributes['id'].value).to eq('res1_image2.jp2')
308
+ expect(xml.xpath("//resource[@sequence='1']/file")[4].attributes['id'].value).to eq('res1_teifile.txt')
309
+ expect(xml.xpath("//resource[@sequence='1']/file")[5].attributes['id'].value).to eq('res1_textfile.txt')
310
+ expect(xml.xpath("//resource[@sequence='1']/file")[6].attributes['id'].value).to eq('res1_transcript.pdf')
311
+ expect(xml.xpath("//resource[@sequence='1']/file").length).to be 7
149
312
 
150
- it 'generates valid content metadata for a single tif and jp2 of style=simple_image with overriding file attributes, including a default value, and no exif data' do
151
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
152
- 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)
153
- expect(result.class).to be String
154
- xml = Nokogiri::XML(result)
155
- expect(xml.errors.size).to be 0
156
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
157
- expect(xml.xpath('//resource/file').length).to be 2
158
- expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be nil
159
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
160
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
161
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
162
- expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be nil
163
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
164
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
165
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
166
- (0..1).each do |i|
167
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 1
168
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
169
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
313
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('res2_image1.tif')
314
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('res2_image1.jp2')
315
+ expect(xml.xpath("//resource[@sequence='2']/file")[2].attributes['id'].value).to eq('res2_image2.tif')
316
+ expect(xml.xpath("//resource[@sequence='2']/file")[3].attributes['id'].value).to eq('res2_image2.jp2')
317
+ expect(xml.xpath("//resource[@sequence='2']/file")[4].attributes['id'].value).to eq('res2_teifile.txt')
318
+ expect(xml.xpath("//resource[@sequence='2']/file")[5].attributes['id'].value).to eq('res2_textfile.txt')
319
+ expect(xml.xpath("//resource[@sequence='2']/file").length).to eq 6
320
+
321
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('res3_image1.tif')
322
+ expect(xml.xpath("//resource[@sequence='3']/file")[1].attributes['id'].value).to eq('res3_image1.jp2')
323
+ expect(xml.xpath("//resource[@sequence='3']/file")[2].attributes['id'].value).to eq('res3_teifile.txt')
324
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 3
325
+
326
+ expect(xml.xpath('//label').length).to eq 3
327
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
328
+ (0..2).each do |i|
329
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
330
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
331
+ end
332
+ end
333
+ end
170
334
  end
171
- end
172
335
 
173
- it 'generates valid content metadata for a single tif and jp2 of style=map with overriding file attributes, including a default value, and no exif data' do
174
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
175
- 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)
176
- expect(result.class).to be String
177
- xml = Nokogiri::XML(result)
178
- expect(xml.errors.size).to be 0
179
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('map')
180
- expect(xml.xpath('//resource/file').length).to be 2
181
- expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be nil
182
- expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
183
- expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
184
- expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
185
- expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be nil
186
- expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
187
- expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
188
- expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
189
- (0..1).each do |i|
190
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 1
191
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
192
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
336
+ context 'when style=webarchive-seed' do
337
+ context 'when using a jp2' do
338
+ it 'generates valid content metadata with exif, adding file attributes' do
339
+ objects = [Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
340
+ result = described_class.create_content_metadata(style: :'webarchive-seed', druid: TEST_DRUID, add_exif: true, add_file_attributes: true, objects: objects)
341
+ expect(result.class).to be String
342
+ xml = Nokogiri::XML(result)
343
+ expect(xml.errors.size).to eq 0
344
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('webarchive-seed')
345
+ expect(xml.xpath('//bookData').length).to eq 0
346
+ expect(xml.xpath('//resource').length).to eq 1
347
+ expect(xml.xpath('//resource/file').length).to eq 1
348
+ expect(xml.xpath('//resource/file/checksum').length).to eq 2
349
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
350
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('4eb54050d374291ece622d45e84f014d')
351
+ expect(xml.xpath('//label').length).to eq 1
352
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
353
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
354
+ expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('306')
355
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/jp2')
356
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
357
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
358
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('yes')
359
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
360
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
361
+ end
362
+ end
193
363
  end
194
- end
195
364
 
196
- it 'generates valid content metadata for two tifs two associated jp2s of style=simple_image using bundle=filename and no exif data' do
197
- 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)]
198
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :filename, objects: objects)
199
- expect(result.class).to be String
200
- xml = Nokogiri::XML(result)
201
- expect(xml.errors.size).to be 0
202
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
203
- expect(xml.xpath('//resource').length).to be 2
204
- expect(xml.xpath('//resource/file').length).to be 4
205
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('test.tif')
206
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('test.jp2')
207
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('test2.tif')
208
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('test2.jp2')
209
- expect(xml.xpath('//label').length).to be 2
210
- expect(xml.xpath('//resource/file/imageData').length).to be 0
211
- (0..1).each do |i|
212
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 2
213
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
214
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
365
+ context 'when style=map' do
366
+ context 'when using a single tif and jp2' do
367
+ it 'generates valid content metadata with overriding file attributes, including a default value, and no exif data' do
368
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
369
+ result = described_class.create_content_metadata(style: :map,
370
+ druid: TEST_DRUID,
371
+ add_file_attributes: true,
372
+ file_attributes: { 'default' => { publish: 'yes', preserve: 'no', shelve: 'no' },
373
+ 'image/jp2' => { publish: 'yes', preserve: 'yes', shelve: 'yes' } },
374
+ objects: objects)
375
+ expect(result.class).to be String
376
+ xml = Nokogiri::XML(result)
377
+ expect(xml.errors.size).to eq 0
378
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('map')
379
+ expect(xml.xpath('//bookData').length).to eq 0
380
+ expect(xml.xpath('//resource/file').length).to eq 2
381
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil
382
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
383
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
384
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
385
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil
386
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
387
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
388
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
389
+ (0..1).each do |i|
390
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
391
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
392
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
393
+ end
394
+ end
395
+ end
215
396
  end
216
- end
217
397
 
218
- it 'generates valid content metadata for two tifs two associated jp2s of style=simple_image using bundle=dpg and no exif data and no root xml node' do
219
- 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)]
220
- test_druid = TEST_DRUID.to_s
221
- result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, include_root_xml: false)
222
- expect(result.class).to be String
223
- expect(result.include?('<?xml')).to be false
224
- xml = Nokogiri::XML(result)
225
- expect(xml.errors.size).to be 0
226
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
227
- expect(test_druid).to eq(TEST_DRUID)
228
- expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(TEST_DRUID.to_s)
229
- expect(xml.xpath('//resource').length).to be 2
230
- expect(xml.xpath('//resource/file').length).to be 4
231
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_001.tif')
232
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_001.jp2')
233
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_002.tif')
234
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_002.jp2')
235
- expect(xml.xpath('//label').length).to be 2
236
- expect(xml.xpath('//resource/file/imageData').length).to be 0
237
- (0..1).each do |i|
238
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 2
239
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
240
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
398
+ context 'when style=simple_book' do
399
+ context 'when using two tifs, two associated jp2s, one combined pdf and one special tif using bundle=dpg' do
400
+ it 'generates valid content metadata and no exif data and no root xml node, flattening folder structure' do
401
+ 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)]
402
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, bundle: :dpg, objects: objects, include_root_xml: false, flatten_folder_structure: true)
403
+ expect(result.class).to be String
404
+ expect(result.include?('<?xml')).to be false
405
+ xml = Nokogiri::XML(result)
406
+ expect(xml.errors.size).to eq 0
407
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
408
+ expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(TEST_DRUID.to_s)
409
+ expect(xml.xpath('//bookData')[0].attributes['readingOrder'].value).to eq('ltr')
410
+ expect(xml.xpath('//resource').length).to eq 4
411
+ expect(xml.xpath('//resource/file').length).to eq 6
412
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
413
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
414
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
415
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
416
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_31_001.pdf')
417
+ expect(xml.xpath("//resource[@sequence='4']/file")[0].attributes['id'].value).to eq('oo000oo0001_50_001.tif')
418
+ expect(xml.xpath('//label').length).to eq 4
419
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
420
+ (0..1).each do |i|
421
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 2
422
+ expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
423
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
424
+ end
425
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
426
+ expect(xml.xpath('//label')[2].text).to eq('Object 1')
427
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
428
+ expect(xml.xpath("//resource[@sequence='4']/file").length).to eq 1
429
+ expect(xml.xpath('//label')[3].text).to eq('Object 2')
430
+ expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('object')
431
+ end
432
+ end
433
+
434
+ context "when item has a 'druid:' prefix and specified book order. Using two tifs, two associated jp2s, two associated pdfs and one lingering PDF using bundle=dpg" do
435
+ it 'generates valid content metadata with flattening folder structure' do
436
+ objects = [Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP),
437
+ Assembly::ObjectFile.new(TEST_DPG_PDF), Assembly::ObjectFile.new(TEST_DPG_TIF2),
438
+ Assembly::ObjectFile.new(TEST_DPG_JP2), Assembly::ObjectFile.new(TEST_DPG_PDF2),
439
+ Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)]
440
+ test_druid = "druid:#{TEST_DRUID}"
441
+ result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, style: :simple_book, flatten_folder_structure: true, reading_order: 'rtl')
442
+ expect(result.class).to be String
443
+ expect(result.include?('<?xml')).to be true
444
+ xml = Nokogiri::XML(result)
445
+ expect(xml.errors.size).to eq 0
446
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
447
+ expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(test_druid)
448
+ expect(xml.xpath('//bookData')[0].attributes['readingOrder'].value).to eq('rtl')
449
+ expect(test_druid).to eq("druid:#{TEST_DRUID}")
450
+ expect(xml.xpath('//resource').length).to eq 3
451
+ expect(xml.xpath('//resource/file').length).to be 7
452
+
453
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
454
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
455
+ expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_001.pdf')
456
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
457
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
458
+ expect(xml.xpath("//resource[@sequence='2']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_002.pdf')
459
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
460
+ expect(xml.xpath('//label').length).to eq 3
461
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
462
+ (0..1).each do |i|
463
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 3
464
+ expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
465
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
466
+ end
467
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
468
+ expect(xml.xpath('//label')[2].text).to eq('Object 1')
469
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
470
+ end
471
+ end
472
+
473
+ context 'throws an error with invalid reading order' do
474
+ subject(:result) { described_class.create_content_metadata(druid: "druid:#{TEST_DRUID}", bundle: :dpg, objects: [], style: :simple_book, flatten_folder_structure: true, reading_order: 'bogus') }
475
+
476
+ it 'generates valid content metadata with flattening folder structure' do
477
+ expect { result }.to raise_error(Dry::Struct::Error)
478
+ end
479
+ end
480
+
481
+ context 'when using two tifs' do
482
+ it 'generates valid content metadata for two tifs of style=simple_book' do
483
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
484
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
485
+ expect(result.class).to be String
486
+ xml = Nokogiri::XML(result)
487
+ expect(xml.errors.size).to eq 0
488
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
489
+ expect(xml.xpath('//resource').length).to eq 2
490
+ expect(xml.xpath('//resource/file').length).to eq 2
491
+ expect(xml.xpath('//label').length).to eq 2
492
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
493
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
494
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
495
+ (0..1).each do |i|
496
+ expect(xml.xpath('//resource/file')[i].attributes['size']).to be_nil
497
+ expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be_nil
498
+ expect(xml.xpath('//resource/file')[i].attributes['publish']).to be_nil
499
+ expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be_nil
500
+ expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be_nil
501
+ end
502
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
503
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
504
+ end
505
+ end
241
506
  end
242
- end
243
507
 
244
- it 'generates valid content metadata for two tifs, two associated jp2s, one combined pdf and one special tif of style=simple_book using bundle=dpg and no exif data and no root xml node, flattening folder structure' do
245
- 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)]
246
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, bundle: :dpg, objects: objects, include_root_xml: false, flatten_folder_structure: true)
247
- expect(result.class).to be String
248
- expect(result.include?('<?xml')).to be false
249
- xml = Nokogiri::XML(result)
250
- expect(xml.errors.size).to be 0
251
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
252
- expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(TEST_DRUID.to_s)
253
- expect(xml.xpath('//resource').length).to be 4
254
- expect(xml.xpath('//resource/file').length).to be 6
255
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
256
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
257
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
258
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
259
- expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_31_001.pdf')
260
- expect(xml.xpath("//resource[@sequence='4']/file")[0].attributes['id'].value).to eq('oo000oo0001_50_001.tif')
261
- expect(xml.xpath('//label').length).to be 4
262
- expect(xml.xpath('//resource/file/imageData').length).to be 0
263
- (0..1).each do |i|
264
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 2
265
- expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
266
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
508
+ context 'when style=book_with_pdf' do
509
+ context 'when using two tiffs and a pdf' do
510
+ let(:objects) do
511
+ [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
512
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2),
513
+ Assembly::ObjectFile.new(TEST_PDF_FILE)]
514
+ end
515
+ let(:style) { :book_with_pdf }
516
+
517
+ before do
518
+ allow(Deprecation).to receive(:warn)
519
+ end
520
+
521
+ it 'generates valid content metadata for two tifs' do
522
+ expect(xml.errors.size).to eq 0
523
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
524
+ expect(xml.xpath('//resource').length).to eq 3
525
+ expect(xml.xpath('//resource/file').length).to eq 3
526
+ expect(xml.xpath('//label').length).to eq 3
527
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
528
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
529
+ expect(xml.xpath('//label')[2].text).to match(/Object 1/)
530
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
531
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
532
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
533
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
534
+ end
535
+ end
536
+
537
+ context 'when using two tifs, two associated jp2s, two associated pdfs and one lingering PDF using bundle=dpg' do
538
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :dpg, style: style, objects: objects) }
539
+
540
+ let(:objects) do
541
+ [
542
+ Assembly::ObjectFile.new(TEST_DPG_TIF),
543
+ Assembly::ObjectFile.new(TEST_DPG_JP),
544
+ Assembly::ObjectFile.new(TEST_DPG_PDF),
545
+ Assembly::ObjectFile.new(TEST_DPG_TIF2),
546
+ Assembly::ObjectFile.new(TEST_DPG_JP2),
547
+ Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)
548
+ ]
549
+ end
550
+ let(:style) { :book_with_pdf }
551
+
552
+ before do
553
+ allow(Deprecation).to receive(:warn)
554
+ end
555
+
556
+ it 'generates valid content metadata' do
557
+ expect(xml.errors.size).to eq 0
558
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
559
+ expect(xml.xpath('//resource').length).to eq 3
560
+ expect(xml.xpath('//resource/file').length).to eq 6
561
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_001.tif')
562
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_001.jp2')
563
+ expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('15/oo000oo0001_15_001.pdf')
564
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_002.tif')
565
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_002.jp2')
566
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
567
+ expect(xml.xpath('//label').length).to eq 3
568
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
569
+ expect(xml.xpath("//resource[@sequence='1']/file").length).to eq 3
570
+ expect(xml.xpath('//label')[0].text).to eq('Object 1')
571
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('object')
572
+ expect(xml.xpath("//resource[@sequence='2']/file").length).to eq 2
573
+ expect(xml.xpath('//label')[1].text).to eq('Page 1')
574
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
575
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
576
+ expect(xml.xpath('//label')[2].text).to eq('Object 2')
577
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
578
+ end
579
+ end
267
580
  end
268
- expect(xml.xpath("//resource[@sequence='3']/file").length).to be 1
269
- expect(xml.xpath('//label')[2].text).to eq('Object 1')
270
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
271
- expect(xml.xpath("//resource[@sequence='4']/file").length).to be 1
272
- expect(xml.xpath('//label')[3].text).to eq('Object 2')
273
- expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('object')
274
- end
275
581
 
276
- it "generates valid content metadata with item having a 'druid:' prefix for two tifs,two associated jp2s,two associated pdfs, and one lingering PDF of style=simple_book using bundle=dpg, flattening folder structure" do
277
- objects = [Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP), Assembly::ObjectFile.new(TEST_DPG_PDF), Assembly::ObjectFile.new(TEST_DPG_TIF2), Assembly::ObjectFile.new(TEST_DPG_JP2), Assembly::ObjectFile.new(TEST_DPG_PDF2), Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)]
278
- test_druid = "druid:#{TEST_DRUID}"
279
- result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, style: :simple_book, flatten_folder_structure: true)
280
- expect(result.class).to be String
281
- expect(result.include?('<?xml')).to be true
282
- xml = Nokogiri::XML(result)
283
- expect(xml.errors.size).to be 0
284
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
285
- expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(test_druid)
286
- expect(test_druid).to eq("druid:#{TEST_DRUID}")
287
- expect(xml.xpath('//resource').length).to be 3
288
- expect(xml.xpath('//resource/file').length).to be 7
289
-
290
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
291
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
292
- expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_001.pdf')
293
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
294
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
295
- expect(xml.xpath("//resource[@sequence='2']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_002.pdf')
296
- expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
297
- expect(xml.xpath('//label').length).to be 3
298
- expect(xml.xpath('//resource/file/imageData').length).to be 0
299
- (0..1).each do |i|
300
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 3
301
- expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
302
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
582
+ context 'when style=file' do
583
+ context 'when using two tifs and two associated jp2s' do
584
+ it 'generates valid content metadata using specific content metadata paths' do
585
+ 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)]
586
+ objects[0].relative_path = 'input/test.tif'
587
+ objects[1].relative_path = 'input/test.jp2'
588
+ objects[2].relative_path = 'input/test2.tif'
589
+ objects[3].relative_path = 'input/test2.jp2'
590
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :file, objects: objects)
591
+ expect(result.class).to be String
592
+ xml = Nokogiri::XML(result)
593
+ expect(xml.errors.size).to eq 0
594
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
595
+ expect(xml.xpath('//bookData').length).to eq 0
596
+ expect(xml.xpath('//resource').length).to eq 4
597
+ expect(xml.xpath('//resource/file').length).to eq 4
598
+ expect(xml.xpath('//label').length).to eq 4
599
+ expect(xml.xpath('//resource/file')[0].attributes['id'].value).to eq('input/test.tif')
600
+ expect(xml.xpath('//resource/file')[1].attributes['id'].value).to eq('input/test.jp2')
601
+ expect(xml.xpath('//resource/file')[2].attributes['id'].value).to eq('input/test2.tif')
602
+ expect(xml.xpath('//resource/file')[3].attributes['id'].value).to eq('input/test2.jp2')
603
+ (0..3).each do |i|
604
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
605
+ expect(xml.xpath('//label')[i].text).to eq("File #{i + 1}")
606
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('file')
607
+ end
608
+ end
609
+ end
303
610
  end
304
- expect(xml.xpath("//resource[@sequence='3']/file").length).to be 1
305
- expect(xml.xpath('//label')[2].text).to eq('Object 1')
306
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
307
- end
308
611
 
309
- it 'generates valid content metadata for two tifs,two associated jp2s,two associated pdfs, and one lingering PDF of style=book_with_pdf using bundle=dpg' do
310
- objects = [Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP), Assembly::ObjectFile.new(TEST_DPG_PDF), Assembly::ObjectFile.new(TEST_DPG_TIF2), Assembly::ObjectFile.new(TEST_DPG_JP2), Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)]
311
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :dpg, objects: objects, style: :book_with_pdf)
312
- expect(result.class).to be String
313
- xml = Nokogiri::XML(result)
314
- expect(xml.errors.size).to be 0
315
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
316
- expect(xml.xpath('//resource').length).to be 3
317
- expect(xml.xpath('//resource/file').length).to be 6
318
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_001.tif')
319
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_001.jp2')
320
- expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('15/oo000oo0001_15_001.pdf')
321
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_002.tif')
322
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_002.jp2')
323
- expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
324
- expect(xml.xpath('//label').length).to be 3
325
- expect(xml.xpath('//resource/file/imageData').length).to be 0
326
- expect(xml.xpath("//resource[@sequence='1']/file").length).to be 3
327
- expect(xml.xpath('//label')[0].text).to eq('Object 1')
328
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('object')
329
- expect(xml.xpath("//resource[@sequence='2']/file").length).to be 2
330
- expect(xml.xpath('//label')[1].text).to eq('Page 1')
331
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
332
- expect(xml.xpath("//resource[@sequence='3']/file").length).to be 1
333
- expect(xml.xpath('//label')[2].text).to eq('Object 2')
334
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
335
- end
612
+ context 'when using style=book_as_image' do
613
+ let(:objects) do
614
+ [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
615
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
616
+ end
336
617
 
337
- it 'generates valid content metadata for two tifs two associated jp2s of style=simple_image using bundle=default and no exif data' do
338
- 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)]
339
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :default, objects: objects)
340
- expect(result.class).to be String
341
- xml = Nokogiri::XML(result)
342
- expect(xml.errors.size).to be 0
343
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
344
- expect(xml.xpath('//resource').length).to be 4
345
- expect(xml.xpath('//resource/file').length).to be 4
346
- expect(xml.xpath('//resource/file')[0].attributes['id'].value).to eq('test.tif')
347
- expect(xml.xpath('//resource/file')[1].attributes['id'].value).to eq('test.jp2')
348
- expect(xml.xpath('//resource/file')[2].attributes['id'].value).to eq('test2.tif')
349
- expect(xml.xpath('//resource/file')[3].attributes['id'].value).to eq('test2.jp2')
350
- expect(xml.xpath('//label').length).to be 4
351
- expect(xml.xpath('//resource/file/imageData').length).to be 0
352
- (0..3).each do |i|
353
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 1
354
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
355
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
618
+ let(:style) { :book_as_image }
619
+
620
+ before do
621
+ allow(Deprecation).to receive(:warn)
622
+ end
623
+
624
+ it 'generates valid content metadata for two tifs' do
625
+ expect(xml.errors.size).to eq 0
626
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
627
+ expect(xml.xpath('//bookData').length).to eq 1
628
+ expect(xml.xpath('//resource').length).to eq 2
629
+ expect(xml.xpath('//resource/file').length).to eq 2
630
+ expect(xml.xpath('//label').length).to eq 2
631
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
632
+ expect(xml.xpath('//label')[1].text).to match(/Image 2/)
633
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
634
+ (0..1).each do |i|
635
+ file = xml.xpath('//resource/file')[i]
636
+
637
+ expect(file.attributes['size']).to be_nil
638
+ expect(file.attributes['mimetype']).to be_nil
639
+ expect(file.attributes['publish']).to be_nil
640
+ expect(file.attributes['preserve']).to be_nil
641
+ expect(file.attributes['shelve']).to be_nil
642
+ end
643
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
644
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
645
+ end
356
646
  end
357
- end
358
647
 
359
- it 'generates valid content metadata for two tifs two associated jp2s of style=simple_image using bundle=default and no exif data, preserving full paths' do
360
- 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)]
361
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :default, objects: objects, preserve_common_paths: true)
362
- expect(result.class).to be String
363
- xml = Nokogiri::XML(result)
364
- expect(xml.errors.size).to be 0
365
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
366
- expect(xml.xpath('//resource').length).to be 4
367
- expect(xml.xpath('//resource/file').length).to be 4
368
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq(TEST_TIF_INPUT_FILE)
369
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq(TEST_JP2_INPUT_FILE)
370
- expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq(TEST_TIF_INPUT_FILE2)
371
- expect(xml.xpath("//resource[@sequence='4']/file")[0].attributes['id'].value).to eq(TEST_JP2_INPUT_FILE2)
372
- expect(xml.xpath('//label').length).to be 4
373
- expect(xml.xpath('//resource/file/imageData').length).to be 0
374
- (0..3).each do |i|
375
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 1
376
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
377
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
648
+ context 'when using style=document' do
649
+ let(:objects) do
650
+ [Assembly::ObjectFile.new(TEST_PDF_FILE)]
651
+ end
652
+
653
+ let(:style) { :document }
654
+
655
+ it 'generates valid content metadata' do
656
+ expect(xml.errors.size).to eq 0
657
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('document')
658
+ expect(xml.xpath('//bookData').length).to eq 0
659
+ expect(xml.xpath('//resource').length).to eq 1
660
+ expect(xml.xpath('//resource/file').length).to eq 1
661
+ expect(xml.xpath('//label').length).to eq 1
662
+ expect(xml.xpath('//label')[0].text).to match(/Document 1/)
663
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
664
+ file = xml.xpath('//resource/file').first
665
+ expect(file.attributes['size']).to be_nil
666
+ expect(file.attributes['mimetype']).to be_nil
667
+ expect(file.attributes['publish']).to be_nil
668
+ expect(file.attributes['preserve']).to be_nil
669
+ expect(file.attributes['shelve']).to be_nil
670
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('document')
671
+ end
378
672
  end
379
- end
380
673
 
381
- it 'generates valid content metadata for two tifs two associated jp2s of style=file using specific content metadata paths' do
382
- 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)]
383
- objects[0].relative_path = 'input/test.tif'
384
- objects[1].relative_path = 'input/test.jp2'
385
- objects[2].relative_path = 'input/test2.tif'
386
- objects[3].relative_path = 'input/test2.jp2'
387
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :file, objects: objects)
388
- expect(result.class).to be String
389
- xml = Nokogiri::XML(result)
390
- expect(xml.errors.size).to be 0
391
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
392
- expect(xml.xpath('//resource').length).to be 4
393
- expect(xml.xpath('//resource/file').length).to be 4
394
- expect(xml.xpath('//label').length).to be 4
395
- expect(xml.xpath('//resource/file')[0].attributes['id'].value).to eq('input/test.tif')
396
- expect(xml.xpath('//resource/file')[1].attributes['id'].value).to eq('input/test.jp2')
397
- expect(xml.xpath('//resource/file')[2].attributes['id'].value).to eq('input/test2.tif')
398
- expect(xml.xpath('//resource/file')[3].attributes['id'].value).to eq('input/test2.jp2')
399
- (0..3).each do |i|
400
- expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to be 1
401
- expect(xml.xpath('//label')[i].text).to eq("File #{i + 1}")
402
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('file')
674
+ context 'when using user supplied checksums for two tifs and style=simple_book' do
675
+ it 'generates valid content metadata with no exif' do
676
+ obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
677
+ obj1.provider_md5 = '123456789'
678
+ obj1.provider_sha1 = 'abcdefgh'
679
+ obj2 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)
680
+ obj2.provider_md5 = 'qwerty'
681
+ objects = [obj1, obj2]
682
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
683
+ expect(result.class).to be String
684
+ xml = Nokogiri::XML(result)
685
+ expect(xml.errors.size).to eq 0
686
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
687
+ expect(xml.xpath('//resource').length).to eq 2
688
+ expect(xml.xpath('//resource/file').length).to eq 2
689
+ expect(xml.xpath('//resource/file/checksum').length).to eq 3
690
+ expect(xml.xpath('//label').length).to eq 2
691
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
692
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
693
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
694
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('abcdefgh')
695
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('123456789')
696
+ expect(xml.xpath('//resource/file/checksum')[2].text).to eq('qwerty')
697
+ (0..1).each do |i|
698
+ expect(xml.xpath('//resource/file')[i].attributes['size']).to be_nil
699
+ expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be_nil
700
+ expect(xml.xpath('//resource/file')[i].attributes['publish']).to be_nil
701
+ expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be_nil
702
+ expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be_nil
703
+ end
704
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
705
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
706
+ end
403
707
  end
404
- end
405
708
 
406
- it 'generates valid content metadata for two tifs of style=simple_book' do
407
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
408
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
409
- expect(result.class).to be String
410
- xml = Nokogiri::XML(result)
411
- expect(xml.errors.size).to be 0
412
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
413
- expect(xml.xpath('//resource').length).to be 2
414
- expect(xml.xpath('//resource/file').length).to be 2
415
- expect(xml.xpath('//label').length).to be 2
416
- expect(xml.xpath('//label')[0].text).to match(/Page 1/)
417
- expect(xml.xpath('//label')[1].text).to match(/Page 2/)
418
- expect(xml.xpath('//resource/file/imageData').length).to be 0
419
- (0..1).each do |i|
420
- expect(xml.xpath('//resource/file')[i].attributes['size']).to be nil
421
- expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be nil
422
- expect(xml.xpath('//resource/file')[i].attributes['publish']).to be nil
423
- expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be nil
424
- expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be nil
709
+ context 'when not all input files exist' do
710
+ it 'does not generate valid content metadata' do
711
+ expect(File.exist?(TEST_TIF_INPUT_FILE)).to be true
712
+ junk_file = '/tmp/flim_flam_floom.jp2'
713
+ expect(File.exist?(junk_file)).to be false
714
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(junk_file)]
715
+ expect { described_class.create_content_metadata(druid: TEST_DRUID, objects: objects) }.to raise_error(RuntimeError, "File '#{junk_file}' not found")
716
+ end
425
717
  end
426
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
427
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
428
- end
429
718
 
430
- it 'generates valid content metadata for two tifs and one pdf of style=book_with_pdf' do
431
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2), Assembly::ObjectFile.new(TEST_PDF_FILE)]
432
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :book_with_pdf, objects: objects)
433
- expect(result.class).to be String
434
- xml = Nokogiri::XML(result)
435
- expect(xml.errors.size).to be 0
436
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
437
- expect(xml.xpath('//resource').length).to be 3
438
- expect(xml.xpath('//resource/file').length).to be 3
439
- expect(xml.xpath('//label').length).to be 3
440
- expect(xml.xpath('//label')[0].text).to match(/Page 1/)
441
- expect(xml.xpath('//label')[1].text).to match(/Page 2/)
442
- expect(xml.xpath('//label')[2].text).to match(/Object 1/)
443
- expect(xml.xpath('//resource/file/imageData').length).to be 0
444
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
445
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
446
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
447
- end
719
+ context 'when using a 3d object with one 3d type files and three other supporting files (where one supporting file is a non-viewable but downloadable 3d file)' do
720
+ let(:objects) do
721
+ [Assembly::ObjectFile.new(TEST_OBJ_FILE),
722
+ Assembly::ObjectFile.new(TEST_PLY_FILE),
723
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
724
+ Assembly::ObjectFile.new(TEST_PDF_FILE)]
725
+ end
726
+ let(:style) { :'3d' }
448
727
 
449
- it 'generates valid content metadata for two tifs of style=book_as_image' do
450
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
451
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :book_as_image, objects: objects)
452
- expect(result.class).to be String
453
- xml = Nokogiri::XML(result)
454
- expect(xml.errors.size).to be 0
455
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
456
- expect(xml.xpath('//resource').length).to be 2
457
- expect(xml.xpath('//resource/file').length).to be 2
458
- expect(xml.xpath('//label').length).to be 2
459
- expect(xml.xpath('//label')[0].text).to match(/Image 1/)
460
- expect(xml.xpath('//label')[1].text).to match(/Image 2/)
461
- expect(xml.xpath('//resource/file/imageData').length).to be 0
462
- (0..1).each do |i|
463
- expect(xml.xpath('//resource/file')[i].attributes['size']).to be nil
464
- expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be nil
465
- expect(xml.xpath('//resource/file')[i].attributes['publish']).to be nil
466
- expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be nil
467
- expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be nil
728
+ it 'generates valid content metadata' do
729
+ expect(xml.errors.size).to eq 0
730
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('3d')
731
+ expect(xml.xpath('//bookData').length).to eq 0
732
+ expect(xml.xpath('//resource').length).to eq 4
733
+ expect(xml.xpath('//resource/file').length).to eq 4
734
+ expect(xml.xpath('//label').length).to eq 4
735
+ expect(xml.xpath('//label')[0].text).to match(/3d 1/)
736
+ expect(xml.xpath('//label')[1].text).to match(/File 1/)
737
+ expect(xml.xpath('//label')[2].text).to match(/File 2/)
738
+ expect(xml.xpath('//label')[3].text).to match(/File 3/)
739
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
740
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('3d')
741
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('file')
742
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('file')
743
+ expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('file')
744
+ end
468
745
  end
469
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
470
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
471
- end
472
746
 
473
- it 'generates valid content metadata with no exif but with user supplied checksums for two tifs of style=simple_book' do
474
- obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
475
- obj1.provider_md5 = '123456789'
476
- obj1.provider_sha1 = 'abcdefgh'
477
- obj2 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)
478
- obj2.provider_md5 = 'qwerty'
479
- objects = [obj1, obj2]
480
- result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
481
- expect(result.class).to be String
482
- xml = Nokogiri::XML(result)
483
- expect(xml.errors.size).to be 0
484
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
485
- expect(xml.xpath('//resource').length).to be 2
486
- expect(xml.xpath('//resource/file').length).to be 2
487
- expect(xml.xpath('//resource/file/checksum').length).to be 3
488
- expect(xml.xpath('//label').length).to be 2
489
- expect(xml.xpath('//label')[0].text).to match(/Page 1/)
490
- expect(xml.xpath('//label')[1].text).to match(/Page 2/)
491
- expect(xml.xpath('//resource/file/imageData').length).to be 0
492
- expect(xml.xpath('//resource/file/checksum')[0].text).to eq('abcdefgh')
493
- expect(xml.xpath('//resource/file/checksum')[1].text).to eq('123456789')
494
- expect(xml.xpath('//resource/file/checksum')[2].text).to eq('qwerty')
495
- (0..1).each do |i|
496
- expect(xml.xpath('//resource/file')[i].attributes['size']).to be nil
497
- expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be nil
498
- expect(xml.xpath('//resource/file')[i].attributes['publish']).to be nil
499
- expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be nil
500
- expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be nil
747
+ context 'when providing file attributes' do
748
+ it 'generates role attributes for content metadata' do
749
+ obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
750
+ obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no', role: 'master-role' }
751
+ objects = [obj1]
752
+ result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects)
753
+ expect(result.class).to be String
754
+ xml = Nokogiri::XML(result)
755
+ expect(xml.errors.size).to eq 0
756
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
757
+ expect(xml.xpath('//resource').length).to eq 1
758
+ expect(xml.xpath('//resource/file').length).to eq 1
759
+ expect(xml.xpath('//resource/file').length).to eq 1
760
+ expect(xml.xpath('//resource/file')[0].attributes['role'].value).to eq('master-role')
761
+ end
501
762
  end
502
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
503
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
504
- end
505
763
 
506
- it 'does not generate valid content metadata if not all input files exist' do
507
- expect(File.exist?(TEST_TIF_INPUT_FILE)).to be true
508
- junk_file = '/tmp/flim_flam_floom.jp2'
509
- expect(File.exist?(junk_file)).to be false
510
- objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(junk_file)]
511
- expect { described_class.create_content_metadata(druid: TEST_DRUID, objects: objects) }.to raise_error(RuntimeError, "File '#{junk_file}' not found")
512
- end
764
+ context 'when no objects are passed in' do
765
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: style, objects: objects) }
513
766
 
514
- it 'generates valid content metadata for a 3d object with one 3d type files and three other supporting files (where one supporting file is a non-viewable but downloadable 3d file)' do
515
- objects=[Assembly::ObjectFile.new(TEST_OBJ_FILE),Assembly::ObjectFile.new(TEST_PLY_FILE),Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),Assembly::ObjectFile.new(TEST_PDF_FILE)]
516
- result = Assembly::ContentMetadata.create_content_metadata(:druid=>TEST_DRUID,:style=>:'3d',:objects=>objects)
517
- expect(result.class).to be String
518
- xml = Nokogiri::XML(result)
519
- expect(xml.errors.size).to be 0
520
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('3d')
521
- expect(xml.xpath('//resource').length).to be 4
522
- expect(xml.xpath('//resource/file').length).to be 4
523
- expect(xml.xpath('//label').length).to be 4
524
- expect(xml.xpath('//label')[0].text).to match(/3d 1/)
525
- expect(xml.xpath('//label')[1].text).to match(/File 1/)
526
- expect(xml.xpath('//label')[2].text).to match(/File 2/)
527
- expect(xml.xpath('//label')[3].text).to match(/File 3/)
528
- expect(xml.xpath('//resource/file/imageData').length).to be 0
529
- expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('3d')
530
- expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('file')
531
- expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('file')
532
- expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('file')
533
- end
767
+ let(:objects) { [] }
534
768
 
535
- it 'generates valid content metadata for images and associated text files, of style=simple_image using bundle=prebundled, and no exif data' do
536
- files = [[TEST_RES1_TIF1, TEST_RES1_JP1, TEST_RES1_TIF2, TEST_RES1_JP2, TEST_RES1_TEI, TEST_RES1_TEXT, TEST_RES1_PDF], [TEST_RES2_TIF1, TEST_RES2_JP1, TEST_RES2_TIF2, TEST_RES2_JP2, TEST_RES2_TEI, TEST_RES2_TEXT], [TEST_RES3_TIF1, TEST_RES3_JP1, TEST_RES3_TEI]]
537
- objects = files.collect { |resource| resource.collect { |file| Assembly::ObjectFile.new(file) } }
538
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: :simple_image, objects: objects)
539
- expect(result.class).to be String
540
- xml = Nokogiri::XML(result)
541
- expect(xml.errors.size).to be 0
542
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
543
- expect(xml.xpath('//resource').length).to be 3
544
- expect(xml.xpath('//resource/file').length).to be 16
545
- expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('res1_image1.tif')
546
- expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('res1_image1.jp2')
547
- expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('res1_image2.tif')
548
- expect(xml.xpath("//resource[@sequence='1']/file")[3].attributes['id'].value).to eq('res1_image2.jp2')
549
- expect(xml.xpath("//resource[@sequence='1']/file")[4].attributes['id'].value).to eq('res1_teifile.txt')
550
- expect(xml.xpath("//resource[@sequence='1']/file")[5].attributes['id'].value).to eq('res1_textfile.txt')
551
- expect(xml.xpath("//resource[@sequence='1']/file")[6].attributes['id'].value).to eq('res1_transcript.pdf')
552
- expect(xml.xpath("//resource[@sequence='1']/file").length).to be 7
553
-
554
- expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('res2_image1.tif')
555
- expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('res2_image1.jp2')
556
- expect(xml.xpath("//resource[@sequence='2']/file")[2].attributes['id'].value).to eq('res2_image2.tif')
557
- expect(xml.xpath("//resource[@sequence='2']/file")[3].attributes['id'].value).to eq('res2_image2.jp2')
558
- expect(xml.xpath("//resource[@sequence='2']/file")[4].attributes['id'].value).to eq('res2_teifile.txt')
559
- expect(xml.xpath("//resource[@sequence='2']/file")[5].attributes['id'].value).to eq('res2_textfile.txt')
560
- expect(xml.xpath("//resource[@sequence='2']/file").length).to be 6
561
-
562
- expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('res3_image1.tif')
563
- expect(xml.xpath("//resource[@sequence='3']/file")[1].attributes['id'].value).to eq('res3_image1.jp2')
564
- expect(xml.xpath("//resource[@sequence='3']/file")[2].attributes['id'].value).to eq('res3_teifile.txt')
565
- expect(xml.xpath("//resource[@sequence='3']/file").length).to be 3
566
-
567
- expect(xml.xpath('//label').length).to be 3
568
- expect(xml.xpath('//resource/file/imageData').length).to be 0
569
- (0..2).each do |i|
570
- expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
571
- expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
769
+ let(:style) { :file }
770
+
771
+ it 'generates content metadata even when no objects are passed in' do
772
+ expect(xml.errors.size).to eq 0
773
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
774
+ expect(xml.xpath('//resource').length).to eq 0
775
+ expect(xml.xpath('//resource/file').length).to eq 0
776
+ end
572
777
  end
573
- end
574
778
 
575
- it 'generates role attributes for content metadata for a tif' do
576
- obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
577
- obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no', role: 'master-role' }
578
- objects = [obj1]
579
- result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects)
580
- expect(result.class).to be String
581
- xml = Nokogiri::XML(result)
582
- expect(xml.errors.size).to be 0
583
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
584
- expect(xml.xpath('//resource').length).to be 1
585
- expect(xml.xpath('//resource/file').length).to be 1
586
- expect(xml.xpath('//resource/file').length).to be 1
587
- expect(xml.xpath('//resource/file')[0].attributes['role'].value).to eq('master-role')
588
- end
779
+ context 'when an unknown style is passed in' do
780
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: style, objects: objects) }
589
781
 
590
- it 'generates content metadata even when no objects are passed in' do
591
- objects = []
592
- result = described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: :file, objects: objects)
593
- expect(result.class).to be String
594
- xml = Nokogiri::XML(result)
595
- expect(xml.errors.size).to be 0
596
- expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
597
- expect(xml.xpath('//resource').length).to be 0
598
- expect(xml.xpath('//resource/file').length).to be 0
599
- end
782
+ let(:objects) { [] }
783
+
784
+ let(:style) { :borked }
600
785
 
601
- it 'generates an error message when an unknown style is passed in' do
602
- objects = []
603
- expect {
604
- described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: :borked, objects: objects)
605
- }.to raise_error { |error|
606
- expect(error.message).to eq('Supplied style (borked) not valid')
607
- }
786
+ it 'generates an error message' do
787
+ expect { result }.to raise_error 'Supplied style (borked) not valid'
788
+ end
789
+ end
608
790
  end
609
791
  end