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