From c321ff8e7c64e37e83d555181dd47875674ddb1b Mon Sep 17 00:00:00 2001 From: Justin Coyne Date: Fri, 17 Nov 2023 15:47:36 -0600 Subject: [PATCH] Extract a resource deserializer So that the models don't have to know about their serialization --- app/models/embed/purl.rb | 2 +- app/models/embed/purl/resource.rb | 31 ++++--------- .../embed/purl/resource_xml_deserializer.rb | 29 ++++++++++++ spec/models/embed/purl/resource_spec.rb | 44 +++++++++---------- .../purl/resource_xml_deserializer_spec.rb | 28 ++++++++++++ 5 files changed, 89 insertions(+), 45 deletions(-) create mode 100644 app/models/embed/purl/resource_xml_deserializer.rb create mode 100644 spec/models/embed/purl/resource_xml_deserializer_spec.rb diff --git a/app/models/embed/purl.rb b/app/models/embed/purl.rb index 5a9c7c9d2..62a2035cd 100644 --- a/app/models/embed/purl.rb +++ b/app/models/embed/purl.rb @@ -32,7 +32,7 @@ def valid? def contents @contents ||= ng_xml.xpath('//contentMetadata/resource').map do |resource| - Purl::Resource.new(@druid, resource, rights) + ResourceXmlDeserializer.new(druid, resource, rights).deserialize end end diff --git a/app/models/embed/purl/resource.rb b/app/models/embed/purl/resource.rb index 71bd5b8da..1091a6db8 100644 --- a/app/models/embed/purl/resource.rb +++ b/app/models/embed/purl/resource.rb @@ -4,33 +4,20 @@ module Embed class Purl class Resource # @param [String] druid identifier without a namespace - # @param [Nokogiri::XML::Element] resource - # @param [Dor::RightsAuth] rights - def initialize(druid, resource, rights) + # @param [String] type the resource type + # @param [String] description the resource description + # @param [Array] files + def initialize(druid:, type:, description:, files: []) @druid = druid - @resource = resource - @rights = rights + @type = type + @description = description + @files = files end - attr_reader :druid - - def type - @resource.attributes['type'].value - end - - def description - @description ||= @resource.xpath('./label').text - end + attr_reader :druid, :type, :description, :files def three_dimensional? - @resource.attributes['type']&.value == '3d' - end - - # @return [Array] - def files - @files ||= @resource.xpath('./file').map do |file| - FileXmlDeserializer.new(druid, description, file, @rights).deserialize - end + type == '3d' end def size diff --git a/app/models/embed/purl/resource_xml_deserializer.rb b/app/models/embed/purl/resource_xml_deserializer.rb new file mode 100644 index 000000000..36a5c9815 --- /dev/null +++ b/app/models/embed/purl/resource_xml_deserializer.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Embed + class Purl + class ResourceXmlDeserializer + # @param [String] druid the identifier of the resource + # @param [Nokogiri::XML::Element] resource + # @param [Dor::RightsAuth] rights + def initialize(druid, resource, rights) + @druid = druid + @resource = resource + @rights = rights + end + + def deserialize + description = @resource.xpath('./label').text + files = @resource.xpath('./file').map do |file| + FileXmlDeserializer.new(@druid, description, file, @rights).deserialize + end + Resource.new( + druid: @druid, + type: @resource.attributes['type'].value, + description:, + files: + ) + end + end + end +end diff --git a/spec/models/embed/purl/resource_spec.rb b/spec/models/embed/purl/resource_spec.rb index ef6122d0a..9bb631620 100644 --- a/spec/models/embed/purl/resource_spec.rb +++ b/spec/models/embed/purl/resource_spec.rb @@ -20,35 +20,35 @@ end describe '#thumbnail' do - let(:resource) { described_class.new('12345', resource_element, instance_double(Dor::RightsAuth)) } + let(:resource) do + described_class.new( + druid: '12345', + type: 'file', + description: 'great', + files: [ + Embed::Purl::ResourceFile.new(filename: 'Non thumb', mimetype: 'image/tiff'), + Embed::Purl::ResourceFile.new(filename: 'The thumb', mimetype: 'image/jp2') + ] + ) + end context 'when the resource has a thumbnail' do - let(:resource_element) do - Nokogiri::XML( - <<~XML - - - - - XML - ).xpath('//resource').first - end - it 'is the thumbnail' do - expect(resource.thumbnail.title).to eq 'The Thumb' + expect(resource.thumbnail.title).to eq 'The thumb' end end context 'when the resource does not have a file specific thumbnail' do - let(:resource_element) do - Nokogiri::XML( - <<~XML - - - - - XML - ).xpath('//resource').first + let(:resource) do + described_class.new( + druid: '12345', + type: 'file', + description: 'bland', + files: [ + Embed::Purl::ResourceFile.new(filename: 'Non thumb', mimetype: 'image/tiff'), + Embed::Purl::ResourceFile.new(filename: 'Another non Thumb', mimetype: 'audio/aiff') + ] + ) end it 'is nil' do diff --git a/spec/models/embed/purl/resource_xml_deserializer_spec.rb b/spec/models/embed/purl/resource_xml_deserializer_spec.rb new file mode 100644 index 000000000..8296727c4 --- /dev/null +++ b/spec/models/embed/purl/resource_xml_deserializer_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Embed::Purl::ResourceXmlDeserializer do + describe '#deserialize' do + let(:resource_element) do + Nokogiri::XML( + <<~XML + + + + + + XML + ).xpath('//resource').first + end + + let(:resource) { described_class.new('abc123', resource_element, nil).deserialize } + + it 'creates a resource' do + expect(resource.druid).to eq 'abc123' + expect(resource.description).to eq 'What a great image' + expect(resource.type).to eq 'image' + expect(resource.files).to all(be_a Embed::Purl::ResourceFile) + end + end +end