assembly-objectfile 1.8.2 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Assembly
4
+ class ContentMetadata
5
+ # Builds a groups of related Files, based on bundle
6
+ class FileSetBuilder
7
+ # @param [Symbol] bundle one of: :default, :filename, :dpg or :prebundled
8
+ # @param [Array<Assembly::ObjectFile>] objects
9
+ # @param [Symbol] style one of: :simple_image, :file, :simple_book, :book_as_image, :book_with_pdf, :map, or :'3d'
10
+ def self.build(bundle:, objects:, style:)
11
+ new(bundle: bundle, objects: objects, style: style).build
12
+ end
13
+
14
+ def initialize(bundle:, objects:, style:)
15
+ @bundle = bundle
16
+ @objects = objects
17
+ @style = style
18
+ end
19
+
20
+ # @return [Array<FileSet>] a list of filesets in the object
21
+ def build
22
+ case bundle
23
+ when :default # one resource per object
24
+ objects.collect { |obj| FileSet.new(resource_files: [obj], style: style) }
25
+ when :filename # one resource per distinct filename (excluding extension)
26
+ build_for_filename
27
+ when :dpg # group by DPG filename
28
+ build_for_dpg
29
+ when :prebundled
30
+ # if the user specifies this method, they will pass in an array of arrays, indicating resources, so we don't need to bundle in the gem
31
+ # This is used by the assemblyWF if you have stubContentMetadata.xml
32
+ objects.map { |inner| FileSet.new(resource_files: inner, style: style) }
33
+ else
34
+ raise 'Invalid bundle method'
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :bundle, :objects, :style
41
+
42
+ def build_for_filename
43
+ # loop over distinct filenames, this determines how many resources we will have and
44
+ # create one resource node per distinct filename, collecting the relevant objects with the distinct filename into that resource
45
+ distinct_filenames = objects.collect(&:filename_without_ext).uniq # find all the unique filenames in the set of objects, leaving off extensions and base paths
46
+ distinct_filenames.map do |distinct_filename|
47
+ FileSet.new(resource_files: objects.collect { |obj| obj if obj.filename_without_ext == distinct_filename }.compact,
48
+ style: style)
49
+ end
50
+ end
51
+
52
+ def build_for_dpg
53
+ # loop over distinct dpg base names, this determines how many resources we will have and
54
+ # create one resource node per distinct dpg base name, collecting the relevant objects with the distinct names into that resource
55
+
56
+ distinct_filenames = objects.collect(&:dpg_basename).uniq # find all the unique DPG filenames in the set of objects
57
+ resources = distinct_filenames.map do |distinct_filename|
58
+ FileSet.new(dpg: true, resource_files: objects.collect { |obj| obj if obj.dpg_basename == distinct_filename && !ContentMetadata.special_dpg_folder?(obj.dpg_folder) }.compact, style: style)
59
+ end
60
+ objects.each { |obj| resources << FileSet.new(dpg: true, resource_files: [obj], style: style) if ContentMetadata.special_dpg_folder?(obj.dpg_folder) } # certain subfolders require individual resources for files within them regardless of file-naming convention
61
+ resources
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,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