assembly-objectfile 1.8.4 → 1.10.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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