assembly-objectfile 1.8.2 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,55 @@
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
+ filesets.each_with_index do |fileset, index| # iterate over all the resources
19
+ # start a new resource element
20
+ sequence = index + 1
21
+
22
+ resource_type_counters[fileset.resource_type_description] += 1 # each resource type description gets its own incrementing counter
23
+
24
+ xml.resource(id: "#{pid}_#{sequence}", sequence: sequence, type: fileset.resource_type_description) do
25
+ # create a generic resource label if needed
26
+ default_label = config.auto_labels ? "#{fileset.resource_type_description.capitalize} #{resource_type_counters[fileset.resource_type_description]}" : ''
27
+
28
+ # but if one of the files has a label, use it instead
29
+ resource_label = fileset.label_from_file(default: default_label)
30
+
31
+ xml.label(resource_label) unless resource_label.empty?
32
+ fileset.files.each do |obj| # iterate over all the files in a resource
33
+ xml_file_params = { id: obj.file_id(common_path: common_path, flatten_folder_structure: config.flatten_folder_structure) }
34
+ xml_file_params.merge!(obj.file_attributes(config.file_attributes)) if config.add_file_attributes
35
+ xml_file_params.merge!(mimetype: obj.mimetype, size: obj.filesize) if config.add_exif
36
+
37
+ xml.file(xml_file_params) do
38
+ if config.add_exif # add exif info if the user requested it
39
+ xml.checksum(obj.sha1, type: 'sha1')
40
+ xml.checksum(obj.md5, type: 'md5')
41
+ xml.imageData(obj.image_data) if obj.image? # add image data for an image
42
+ elsif obj.provider_md5 || obj.provider_sha1 # if we did not add exif info, see if there are user supplied checksums to add
43
+ xml.checksum(obj.provider_sha1, type: 'sha1') if obj.provider_sha1
44
+ xml.checksum(obj.provider_md5, type: 'md5') if obj.provider_md5
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ 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.2'.freeze
7
+ VERSION = '1.10.1'
6
8
  end
7
9
  end
@@ -1,609 +1,775 @@
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 is 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
149
292
 
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')
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
312
+
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 is 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('//resource').length).to eq 1
346
+ expect(xml.xpath('//resource/file').length).to eq 1
347
+ expect(xml.xpath('//resource/file/checksum').length).to eq 2
348
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('b965b5787e0100ec2d43733144120feab327e88c')
349
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('4eb54050d374291ece622d45e84f014d')
350
+ expect(xml.xpath('//label').length).to eq 1
351
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
352
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
353
+ expect(xml.xpath('//resource/file')[0].attributes['size'].value).to eq('306')
354
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype'].value).to eq('image/jp2')
355
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
356
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
357
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('yes')
358
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['width'].value).to eq('100')
359
+ expect(xml.xpath('//resource/file/imageData')[0].attributes['height'].value).to eq('100')
360
+ end
361
+ end
193
362
  end
194
- end
195
363
 
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')
364
+ context 'when style=map' do
365
+ context 'when using a single tif and jp2' do
366
+ it 'generates valid content metadata with overriding file attributes, including a default value, and no exif data' do
367
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_JP2_INPUT_FILE)]
368
+ result = described_class.create_content_metadata(style: :map,
369
+ druid: TEST_DRUID,
370
+ add_file_attributes: true,
371
+ file_attributes: { 'default' => { publish: 'yes', preserve: 'no', shelve: 'no' },
372
+ 'image/jp2' => { publish: 'yes', preserve: 'yes', shelve: 'yes' } },
373
+ objects: objects)
374
+ expect(result.class).to be String
375
+ xml = Nokogiri::XML(result)
376
+ expect(xml.errors.size).to eq 0
377
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('map')
378
+ expect(xml.xpath('//resource/file').length).to eq 2
379
+ expect(xml.xpath('//resource/file')[0].attributes['mimetype']).to be_nil
380
+ expect(xml.xpath('//resource/file')[0].attributes['publish'].value).to eq('yes')
381
+ expect(xml.xpath('//resource/file')[0].attributes['preserve'].value).to eq('no')
382
+ expect(xml.xpath('//resource/file')[0].attributes['shelve'].value).to eq('no')
383
+ expect(xml.xpath('//resource/file')[1].attributes['mimetype']).to be_nil
384
+ expect(xml.xpath('//resource/file')[1].attributes['publish'].value).to eq('yes')
385
+ expect(xml.xpath('//resource/file')[1].attributes['preserve'].value).to eq('yes')
386
+ expect(xml.xpath('//resource/file')[1].attributes['shelve'].value).to eq('yes')
387
+ (0..1).each do |i|
388
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
389
+ expect(xml.xpath('//label')[i].text).to eq("Image #{i + 1}")
390
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('image')
391
+ end
392
+ end
393
+ end
215
394
  end
216
- end
217
395
 
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')
396
+ context 'when style=simple_book' do
397
+ context 'when using two tifs, two associated jp2s, one combined pdf and one special tif using bundle=dpg' do
398
+ it 'generates valid content metadata and no exif data and no root xml node, flattening folder structure' do
399
+ 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)]
400
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, bundle: :dpg, objects: objects, include_root_xml: false, flatten_folder_structure: true)
401
+ expect(result.class).to be String
402
+ expect(result.include?('<?xml')).to be false
403
+ xml = Nokogiri::XML(result)
404
+ expect(xml.errors.size).to eq 0
405
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
406
+ expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(TEST_DRUID.to_s)
407
+ expect(xml.xpath('//resource').length).to eq 4
408
+ expect(xml.xpath('//resource/file').length).to eq 6
409
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
410
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
411
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
412
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
413
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_31_001.pdf')
414
+ expect(xml.xpath("//resource[@sequence='4']/file")[0].attributes['id'].value).to eq('oo000oo0001_50_001.tif')
415
+ expect(xml.xpath('//label').length).to eq 4
416
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
417
+ (0..1).each do |i|
418
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 2
419
+ expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
420
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
421
+ end
422
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
423
+ expect(xml.xpath('//label')[2].text).to eq('Object 1')
424
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
425
+ expect(xml.xpath("//resource[@sequence='4']/file").length).to eq 1
426
+ expect(xml.xpath('//label')[3].text).to eq('Object 2')
427
+ expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('object')
428
+ end
429
+ end
430
+
431
+ context "when item has a 'druid:' prefix. Using two tifs, two associated jp2s, two associated pdfs and one lingering PDF using bundle=dpg" do
432
+ it 'generates valid content metadata with flattening folder structure' do
433
+ objects = [Assembly::ObjectFile.new(TEST_DPG_TIF), Assembly::ObjectFile.new(TEST_DPG_JP),
434
+ Assembly::ObjectFile.new(TEST_DPG_PDF), Assembly::ObjectFile.new(TEST_DPG_TIF2),
435
+ Assembly::ObjectFile.new(TEST_DPG_JP2), Assembly::ObjectFile.new(TEST_DPG_PDF2),
436
+ Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)]
437
+ test_druid = "druid:#{TEST_DRUID}"
438
+ result = described_class.create_content_metadata(druid: test_druid, bundle: :dpg, objects: objects, style: :simple_book, flatten_folder_structure: true)
439
+ expect(result.class).to be String
440
+ expect(result.include?('<?xml')).to be true
441
+ xml = Nokogiri::XML(result)
442
+ expect(xml.errors.size).to eq 0
443
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
444
+ expect(xml.xpath('//contentMetadata')[0].attributes['objectId'].value).to eq(test_druid)
445
+ expect(test_druid).to eq("druid:#{TEST_DRUID}")
446
+ expect(xml.xpath('//resource').length).to eq 3
447
+ expect(xml.xpath('//resource/file').length).to be 7
448
+
449
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_001.tif')
450
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_001.jp2')
451
+ expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_001.pdf')
452
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('oo000oo0001_00_002.tif')
453
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('oo000oo0001_05_002.jp2')
454
+ expect(xml.xpath("//resource[@sequence='2']/file")[2].attributes['id'].value).to eq('oo000oo0001_15_002.pdf')
455
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
456
+ expect(xml.xpath('//label').length).to eq 3
457
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
458
+ (0..1).each do |i|
459
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 3
460
+ expect(xml.xpath('//label')[i].text).to eq("Page #{i + 1}")
461
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('page')
462
+ end
463
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
464
+ expect(xml.xpath('//label')[2].text).to eq('Object 1')
465
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
466
+ end
467
+ end
468
+
469
+ context 'when using two tifs' do
470
+ it 'generates valid content metadata for two tifs of style=simple_book' do
471
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
472
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
473
+ expect(result.class).to be String
474
+ xml = Nokogiri::XML(result)
475
+ expect(xml.errors.size).to eq 0
476
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
477
+ expect(xml.xpath('//resource').length).to eq 2
478
+ expect(xml.xpath('//resource/file').length).to eq 2
479
+ expect(xml.xpath('//label').length).to eq 2
480
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
481
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
482
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
483
+ (0..1).each do |i|
484
+ expect(xml.xpath('//resource/file')[i].attributes['size']).to be_nil
485
+ expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be_nil
486
+ expect(xml.xpath('//resource/file')[i].attributes['publish']).to be_nil
487
+ expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be_nil
488
+ expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be_nil
489
+ end
490
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
491
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
492
+ end
493
+ end
241
494
  end
242
- end
243
495
 
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')
496
+ context 'when using style=book_with_pdf' do
497
+ context 'when using two tiffs and a pdf' do
498
+ let(:objects) do
499
+ [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
500
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2),
501
+ Assembly::ObjectFile.new(TEST_PDF_FILE)]
502
+ end
503
+ let(:style) { :book_with_pdf }
504
+
505
+ before do
506
+ allow(Deprecation).to receive(:warn)
507
+ end
508
+
509
+ it 'generates valid content metadata for two tifs' do
510
+ expect(xml.errors.size).to eq 0
511
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
512
+ expect(xml.xpath('//resource').length).to eq 3
513
+ expect(xml.xpath('//resource/file').length).to eq 3
514
+ expect(xml.xpath('//label').length).to eq 3
515
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
516
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
517
+ expect(xml.xpath('//label')[2].text).to match(/Object 1/)
518
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
519
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
520
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
521
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
522
+ end
523
+ end
524
+
525
+ context 'when using two tifs, two associated jp2s, two associated pdfs and one lingering PDF using bundle=dpg' do
526
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :dpg, style: style, objects: objects) }
527
+
528
+ let(:objects) do
529
+ [
530
+ Assembly::ObjectFile.new(TEST_DPG_TIF),
531
+ Assembly::ObjectFile.new(TEST_DPG_JP),
532
+ Assembly::ObjectFile.new(TEST_DPG_PDF),
533
+ Assembly::ObjectFile.new(TEST_DPG_TIF2),
534
+ Assembly::ObjectFile.new(TEST_DPG_JP2),
535
+ Assembly::ObjectFile.new(TEST_DPG_SPECIAL_PDF1)
536
+ ]
537
+ end
538
+ let(:style) { :book_with_pdf }
539
+
540
+ before do
541
+ allow(Deprecation).to receive(:warn)
542
+ end
543
+
544
+ it 'generates valid content metadata' do
545
+ expect(xml.errors.size).to eq 0
546
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
547
+ expect(xml.xpath('//resource').length).to eq 3
548
+ expect(xml.xpath('//resource/file').length).to eq 6
549
+ expect(xml.xpath("//resource[@sequence='1']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_001.tif')
550
+ expect(xml.xpath("//resource[@sequence='1']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_001.jp2')
551
+ expect(xml.xpath("//resource[@sequence='1']/file")[2].attributes['id'].value).to eq('15/oo000oo0001_15_001.pdf')
552
+ expect(xml.xpath("//resource[@sequence='2']/file")[0].attributes['id'].value).to eq('00/oo000oo0001_00_002.tif')
553
+ expect(xml.xpath("//resource[@sequence='2']/file")[1].attributes['id'].value).to eq('05/oo000oo0001_05_002.jp2')
554
+ expect(xml.xpath("//resource[@sequence='3']/file")[0].attributes['id'].value).to eq('oo000oo0001_book.pdf')
555
+ expect(xml.xpath('//label').length).to eq 3
556
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
557
+ expect(xml.xpath("//resource[@sequence='1']/file").length).to eq 3
558
+ expect(xml.xpath('//label')[0].text).to eq('Object 1')
559
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('object')
560
+ expect(xml.xpath("//resource[@sequence='2']/file").length).to eq 2
561
+ expect(xml.xpath('//label')[1].text).to eq('Page 1')
562
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
563
+ expect(xml.xpath("//resource[@sequence='3']/file").length).to eq 1
564
+ expect(xml.xpath('//label')[2].text).to eq('Object 2')
565
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('object')
566
+ end
567
+ end
267
568
  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
569
 
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')
570
+ context 'when style=file' do
571
+ context 'when using two tifs and two associated jp2s' do
572
+ it 'generates valid content metadata using specific content metadata paths' do
573
+ 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)]
574
+ objects[0].relative_path = 'input/test.tif'
575
+ objects[1].relative_path = 'input/test.jp2'
576
+ objects[2].relative_path = 'input/test2.tif'
577
+ objects[3].relative_path = 'input/test2.jp2'
578
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :file, objects: objects)
579
+ expect(result.class).to be String
580
+ xml = Nokogiri::XML(result)
581
+ expect(xml.errors.size).to eq 0
582
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
583
+ expect(xml.xpath('//resource').length).to eq 4
584
+ expect(xml.xpath('//resource/file').length).to eq 4
585
+ expect(xml.xpath('//label').length).to eq 4
586
+ expect(xml.xpath('//resource/file')[0].attributes['id'].value).to eq('input/test.tif')
587
+ expect(xml.xpath('//resource/file')[1].attributes['id'].value).to eq('input/test.jp2')
588
+ expect(xml.xpath('//resource/file')[2].attributes['id'].value).to eq('input/test2.tif')
589
+ expect(xml.xpath('//resource/file')[3].attributes['id'].value).to eq('input/test2.jp2')
590
+ (0..3).each do |i|
591
+ expect(xml.xpath("//resource[@sequence='#{i + 1}']/file").length).to eq 1
592
+ expect(xml.xpath('//label')[i].text).to eq("File #{i + 1}")
593
+ expect(xml.xpath('//resource')[i].attributes['type'].value).to eq('file')
594
+ end
595
+ end
596
+ end
303
597
  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
598
 
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
599
+ context 'when using style=book_as_image' do
600
+ let(:objects) do
601
+ [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
602
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)]
603
+ end
604
+
605
+ let(:style) { :book_as_image }
336
606
 
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')
607
+ before do
608
+ allow(Deprecation).to receive(:warn)
609
+ end
610
+
611
+ it 'generates valid content metadata for two tifs' do
612
+ expect(xml.errors.size).to eq 0
613
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
614
+ expect(xml.xpath('//resource').length).to eq 2
615
+ expect(xml.xpath('//resource/file').length).to eq 2
616
+ expect(xml.xpath('//label').length).to eq 2
617
+ expect(xml.xpath('//label')[0].text).to match(/Image 1/)
618
+ expect(xml.xpath('//label')[1].text).to match(/Image 2/)
619
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
620
+ (0..1).each do |i|
621
+ file = xml.xpath('//resource/file')[i]
622
+
623
+ expect(file.attributes['size']).to be_nil
624
+ expect(file.attributes['mimetype']).to be_nil
625
+ expect(file.attributes['publish']).to be_nil
626
+ expect(file.attributes['preserve']).to be_nil
627
+ expect(file.attributes['shelve']).to be_nil
628
+ end
629
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('image')
630
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('image')
631
+ end
356
632
  end
357
- end
358
633
 
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')
634
+ context 'when using style=document' do
635
+ let(:objects) do
636
+ [Assembly::ObjectFile.new(TEST_PDF_FILE)]
637
+ end
638
+
639
+ let(:style) { :document }
640
+
641
+ it 'generates valid content metadata' do
642
+ expect(xml.errors.size).to eq 0
643
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('document')
644
+ expect(xml.xpath('//resource').length).to eq 1
645
+ expect(xml.xpath('//resource/file').length).to eq 1
646
+ expect(xml.xpath('//label').length).to eq 1
647
+ expect(xml.xpath('//label')[0].text).to match(/Document 1/)
648
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
649
+ file = xml.xpath('//resource/file').first
650
+ expect(file.attributes['size']).to be_nil
651
+ expect(file.attributes['mimetype']).to be_nil
652
+ expect(file.attributes['publish']).to be_nil
653
+ expect(file.attributes['preserve']).to be_nil
654
+ expect(file.attributes['shelve']).to be_nil
655
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('document')
656
+ end
378
657
  end
379
- end
380
658
 
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')
659
+ context 'when using user supplied checksums for two tifs and style=simple_book' do
660
+ it 'generates valid content metadata with no exif' do
661
+ obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
662
+ obj1.provider_md5 = '123456789'
663
+ obj1.provider_sha1 = 'abcdefgh'
664
+ obj2 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE2)
665
+ obj2.provider_md5 = 'qwerty'
666
+ objects = [obj1, obj2]
667
+ result = described_class.create_content_metadata(druid: TEST_DRUID, style: :simple_book, objects: objects)
668
+ expect(result.class).to be String
669
+ xml = Nokogiri::XML(result)
670
+ expect(xml.errors.size).to eq 0
671
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('book')
672
+ expect(xml.xpath('//resource').length).to eq 2
673
+ expect(xml.xpath('//resource/file').length).to eq 2
674
+ expect(xml.xpath('//resource/file/checksum').length).to eq 3
675
+ expect(xml.xpath('//label').length).to eq 2
676
+ expect(xml.xpath('//label')[0].text).to match(/Page 1/)
677
+ expect(xml.xpath('//label')[1].text).to match(/Page 2/)
678
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
679
+ expect(xml.xpath('//resource/file/checksum')[0].text).to eq('abcdefgh')
680
+ expect(xml.xpath('//resource/file/checksum')[1].text).to eq('123456789')
681
+ expect(xml.xpath('//resource/file/checksum')[2].text).to eq('qwerty')
682
+ (0..1).each do |i|
683
+ expect(xml.xpath('//resource/file')[i].attributes['size']).to be_nil
684
+ expect(xml.xpath('//resource/file')[i].attributes['mimetype']).to be_nil
685
+ expect(xml.xpath('//resource/file')[i].attributes['publish']).to be_nil
686
+ expect(xml.xpath('//resource/file')[i].attributes['preserve']).to be_nil
687
+ expect(xml.xpath('//resource/file')[i].attributes['shelve']).to be_nil
688
+ end
689
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('page')
690
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('page')
691
+ end
403
692
  end
404
- end
405
693
 
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
694
+ context 'when not all input files exist' do
695
+ it 'does not generate valid content metadata' do
696
+ expect(File.exist?(TEST_TIF_INPUT_FILE)).to be true
697
+ junk_file = '/tmp/flim_flam_floom.jp2'
698
+ expect(File.exist?(junk_file)).to be false
699
+ objects = [Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE), Assembly::ObjectFile.new(junk_file)]
700
+ expect { described_class.create_content_metadata(druid: TEST_DRUID, objects: objects) }.to raise_error(RuntimeError, "File '#{junk_file}' not found")
701
+ end
425
702
  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
703
 
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
704
+ 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
705
+ let(:objects) do
706
+ [Assembly::ObjectFile.new(TEST_OBJ_FILE),
707
+ Assembly::ObjectFile.new(TEST_PLY_FILE),
708
+ Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE),
709
+ Assembly::ObjectFile.new(TEST_PDF_FILE)]
710
+ end
711
+ let(:style) { :'3d' }
448
712
 
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
713
+ it 'generates valid content metadata' do
714
+ expect(xml.errors.size).to eq 0
715
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('3d')
716
+ expect(xml.xpath('//resource').length).to eq 4
717
+ expect(xml.xpath('//resource/file').length).to eq 4
718
+ expect(xml.xpath('//label').length).to eq 4
719
+ expect(xml.xpath('//label')[0].text).to match(/3d 1/)
720
+ expect(xml.xpath('//label')[1].text).to match(/File 1/)
721
+ expect(xml.xpath('//label')[2].text).to match(/File 2/)
722
+ expect(xml.xpath('//label')[3].text).to match(/File 3/)
723
+ expect(xml.xpath('//resource/file/imageData').length).to eq 0
724
+ expect(xml.xpath('//resource')[0].attributes['type'].value).to eq('3d')
725
+ expect(xml.xpath('//resource')[1].attributes['type'].value).to eq('file')
726
+ expect(xml.xpath('//resource')[2].attributes['type'].value).to eq('file')
727
+ expect(xml.xpath('//resource')[3].attributes['type'].value).to eq('file')
728
+ end
468
729
  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
730
 
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
731
+ context 'when providing file attributes' do
732
+ it 'generates role attributes for content metadata' do
733
+ obj1 = Assembly::ObjectFile.new(TEST_TIF_INPUT_FILE)
734
+ obj1.file_attributes = { publish: 'no', preserve: 'no', shelve: 'no', role: 'master-role' }
735
+ objects = [obj1]
736
+ result = described_class.create_content_metadata(druid: TEST_DRUID, add_exif: false, add_file_attributes: true, objects: objects)
737
+ expect(result.class).to be String
738
+ xml = Nokogiri::XML(result)
739
+ expect(xml.errors.size).to eq 0
740
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('image')
741
+ expect(xml.xpath('//resource').length).to eq 1
742
+ expect(xml.xpath('//resource/file').length).to eq 1
743
+ expect(xml.xpath('//resource/file').length).to eq 1
744
+ expect(xml.xpath('//resource/file')[0].attributes['role'].value).to eq('master-role')
745
+ end
501
746
  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
747
 
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
748
+ context 'when no objects are passed in' do
749
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: style, objects: objects) }
513
750
 
514
- it 'generates valid content metadata for a 3d object with two 3d type files and two other supporting files' 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(/3d 2/)
526
- expect(xml.xpath('//label')[2].text).to match(/File 1/)
527
- expect(xml.xpath('//label')[3].text).to match(/File 2/)
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('3d')
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
751
+ let(:objects) { [] }
534
752
 
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')
753
+ let(:style) { :file }
754
+
755
+ it 'generates content metadata even when no objects are passed in' do
756
+ expect(xml.errors.size).to eq 0
757
+ expect(xml.xpath('//contentMetadata')[0].attributes['type'].value).to eq('file')
758
+ expect(xml.xpath('//resource').length).to eq 0
759
+ expect(xml.xpath('//resource/file').length).to eq 0
760
+ end
572
761
  end
573
- end
574
762
 
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
763
+ context 'when an unknown style is passed in' do
764
+ subject(:result) { described_class.create_content_metadata(druid: TEST_DRUID, bundle: :prebundled, style: style, objects: objects) }
589
765
 
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
766
+ let(:objects) { [] }
767
+
768
+ let(:style) { :borked }
600
769
 
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
- }
770
+ it 'generates an error message' do
771
+ expect { result }.to raise_error 'Supplied style (borked) not valid'
772
+ end
773
+ end
608
774
  end
609
775
  end