assembly-objectfile 1.8.4 → 1.10.3

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