From fa22c14a23873dd32abbb4fcebb18bdbcd8e0e02 Mon Sep 17 00:00:00 2001 From: Daniel Pierce Date: Mon, 5 Mar 2018 11:40:51 -0500 Subject: [PATCH] Support ids containing slashes. --- .../persistence/fedora/metadata_adapter.rb | 6 ++--- .../fedora/metadata_adapter_spec.rb | 27 +++++++++++++++++-- .../persistence/fedora/persister_spec.rb | 27 +++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lib/valkyrie/persistence/fedora/metadata_adapter.rb b/lib/valkyrie/persistence/fedora/metadata_adapter.rb index 35fbfbb7c..7900d14ef 100644 --- a/lib/valkyrie/persistence/fedora/metadata_adapter.rb +++ b/lib/valkyrie/persistence/fedora/metadata_adapter.rb @@ -29,15 +29,15 @@ def resource_factory end def uri_to_id(uri) - Valkyrie::ID.new(uri.to_s.gsub(/^.*\//, '')) + Valkyrie::ID.new(CGI.unescape(uri.to_s.gsub(/^.*\//, ''))) end def id_to_uri(id) - RDF::URI("#{connection_prefix}/#{pair_path(id)}/#{id}") + RDF::URI("#{connection_prefix}/#{pair_path(id)}/#{CGI.escape(id.to_s)}") end def pair_path(id) - id.to_s.split("-").first.split("").each_slice(2).map(&:join).join("/") + id.to_s.split(/[-\/]/).first.split("").each_slice(2).map(&:join).join("/") end def connection_prefix diff --git a/spec/valkyrie/persistence/fedora/metadata_adapter_spec.rb b/spec/valkyrie/persistence/fedora/metadata_adapter_spec.rb index 75ee4e304..72a4d822c 100644 --- a/spec/valkyrie/persistence/fedora/metadata_adapter_spec.rb +++ b/spec/valkyrie/persistence/fedora/metadata_adapter_spec.rb @@ -3,7 +3,7 @@ require 'valkyrie/specs/shared_specs' RSpec.describe Valkyrie::Persistence::Fedora::MetadataAdapter do - let(:adapter) { described_class.new(connection: ::Ldp::Client.new("http://localhost:8988/rest"), base_path: "/test_fed") } + let(:adapter) { described_class.new(connection: ::Ldp::Client.new("http://localhost:8988/rest"), base_path: "test_fed") } it_behaves_like "a Valkyrie::MetadataAdapter" describe "#schema" do @@ -12,8 +12,31 @@ end context "with a custom schema" do - let(:adapter) { described_class.new(connection: ::Ldp::Client.new("http://localhost:8988/rest"), base_path: "/test_fed", schema: "custom-schema") } + let(:adapter) { described_class.new(connection: ::Ldp::Client.new("http://localhost:8988/rest"), base_path: "test_fed", schema: "custom-schema") } specify { expect(adapter.schema).to eq("custom-schema") } end end + + describe "#id_to_uri" do + it "converts ids with a slash" do + id = "test/default" + expect(adapter.id_to_uri(id).to_s).to eq "http://localhost:8988/rest/test_fed/te/st/test%2Fdefault" + end + end + + describe "#uri_to_id" do + it "converts ids with a slash" do + uri = adapter.id_to_uri("test/default") + expect(adapter.uri_to_id(uri).to_s).to eq "test/default" + end + end + + describe "#pair_path" do + it "creates pairs until the first dash" do + expect(adapter.pair_path('abcdef-ghijkl')).to eq('ab/cd/ef') + end + it "creates pairs until the first slash" do + expect(adapter.pair_path('admin_set/default')).to eq('ad/mi/n_/se/t') + end + end end diff --git a/spec/valkyrie/persistence/fedora/persister_spec.rb b/spec/valkyrie/persistence/fedora/persister_spec.rb index e1c022b17..64b4a6e2a 100644 --- a/spec/valkyrie/persistence/fedora/persister_spec.rb +++ b/spec/valkyrie/persistence/fedora/persister_spec.rb @@ -13,4 +13,31 @@ let(:persister) { adapter.persister } let(:query_service) { adapter.query_service } it_behaves_like "a Valkyrie::Persister" + + context "when given an id containing a slash" do + before do + raise 'persister must be set with `let(:persister)`' unless defined? persister + class CustomResource < Valkyrie::Resource + include Valkyrie::Resource::AccessControls + attribute :id, Valkyrie::Types::ID.optional + attribute :title + attribute :author + attribute :member_ids + attribute :nested_resource + end + end + after do + Object.send(:remove_const, :CustomResource) + end + let(:resource_class) { CustomResource } + + it "can store the resource" do + id = Valkyrie::ID.new("test/default") + expect(id.to_s).to eq "test/default" + persister.save(resource: resource_class.new(id: id)) + reloaded = query_service.find_by(id: id) + expect(reloaded.id).to eq id + expect(reloaded).to be_persisted + end + end end