active-fedora 9.0.6 → 9.0.8

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.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/History.txt +57 -0
  3. data/lib/active_fedora.rb +5 -0
  4. data/lib/active_fedora/associations/collection_association.rb +1 -18
  5. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +12 -10
  6. data/lib/active_fedora/core.rb +15 -17
  7. data/lib/active_fedora/core/fedora_id_translator.rb +12 -0
  8. data/lib/active_fedora/core/fedora_uri_translator.rb +9 -0
  9. data/lib/active_fedora/errors.rb +4 -0
  10. data/lib/active_fedora/fedora_attributes.rb +15 -5
  11. data/lib/active_fedora/file.rb +2 -0
  12. data/lib/active_fedora/inheritable_accessors.rb +26 -0
  13. data/lib/active_fedora/reflection.rb +3 -1
  14. data/lib/active_fedora/relation/finder_methods.rb +27 -3
  15. data/lib/active_fedora/version.rb +1 -1
  16. data/lib/active_fedora/versions_graph.rb +7 -8
  17. data/spec/integration/associations_spec.rb +34 -22
  18. data/spec/integration/belongs_to_association_spec.rb +118 -47
  19. data/spec/integration/collection_association_spec.rb +46 -0
  20. data/spec/integration/has_and_belongs_to_many_associations_spec.rb +178 -139
  21. data/spec/integration/versionable_spec.rb +38 -1
  22. data/spec/samples/samples.rb +0 -1
  23. data/spec/unit/base_spec.rb +51 -0
  24. data/spec/unit/core/fedora_id_translator_spec.rb +20 -0
  25. data/spec/unit/core/fedora_uri_translator_spec.rb +19 -0
  26. data/spec/unit/core_spec.rb +50 -0
  27. data/spec/unit/has_many_association_spec.rb +27 -2
  28. data/spec/unit/qualified_dublin_core_datastream_spec.rb +0 -6
  29. data/spec/unit/reflection_spec.rb +44 -0
  30. metadata +9 -13
  31. data/spec/samples/marpa-dc_datastream.rb +0 -102
  32. data/spec/samples/models/audio_record.rb +0 -29
  33. data/spec/samples/models/image.rb +0 -5
  34. data/spec/samples/models/oral_history.rb +0 -36
  35. data/spec/samples/models/seminar.rb +0 -29
  36. data/spec/samples/models/seminar_audio_file.rb +0 -32
  37. data/spec/samples/oral_history_sample_model.rb +0 -30
  38. data/spec/samples/special_thing.rb +0 -44
@@ -18,6 +18,43 @@ describe "a versionable class" do
18
18
 
19
19
  it { is_expected.to be_versionable }
20
20
 
21
+ describe 'sorting versions' do
22
+ before do
23
+ allow(subject).to receive(:fedora_versions) { versions }
24
+ end
25
+
26
+ let(:version1) { double('version1', uri: 'http://localhost:8983/fedora/rest/test/84/61/63/98/84616398-f63a-4572-ba01-0689339e4fcb/fcr:versions/87a0a8c317f1e711aa993d-e1d2-4a65-93ee-3a12fc9541ab', label: 'version1', created: '2015-04-02T19:54:45.962Z') }
27
+ let(:version2) { double('version2', uri: 'http://localhost:8983/fedora/rest/test/84/61/63/98/84616398-f63a-4572-ba01-0689339e4fcb/fcr:versions/87a0a8c317f1e790373a67-c9ee-447d-b740-4faa882b1a1f', label: 'version2', created: '2015-04-02T19:54:45.96Z') }
28
+ let(:versions) { [version1, version2] }
29
+
30
+ subject { ActiveFedora::VersionsGraph.new }
31
+
32
+ it 'sorts by DateTime' do
33
+ expect(subject.first).to eq version2
34
+ end
35
+
36
+ context 'with an unparseable created date' do
37
+ let(:version2) { double('version2', uri: 'http://localhost:8983/fedora/rest/test/84/61/63/98/84616398-f63a-4572-ba01-0689339e4fcb/fcr:versions/87a0a8c317f1e790373a67-c9ee-447d-b740-4faa882b1a1f', label: 'version2', created: '') }
38
+
39
+ it 'raises an exception' do
40
+ expect { subject.first }.to raise_error(ActiveFedora::VersionLacksCreateDate)
41
+ end
42
+ end
43
+
44
+ context 'with a missing created date' do
45
+ before do
46
+ # Because mocks raise RSpec::Mocks::MockExpectationError instead
47
+ allow(version2).to receive(:created) { raise NoMethodError }
48
+ end
49
+
50
+ let(:version2) { double('version2', uri: 'http://localhost:8983/fedora/rest/test/84/61/63/98/84616398-f63a-4572-ba01-0689339e4fcb/fcr:versions/87a0a8c317f1e790373a67-c9ee-447d-b740-4faa882b1a1f', label: 'version2') }
51
+
52
+ it 'raises an exception' do
53
+ expect { subject.first }.to raise_error(ActiveFedora::VersionLacksCreateDate)
54
+ end
55
+ end
56
+ end
57
+
21
58
  context "after saving" do
22
59
  before do
23
60
  subject.title = ["Greetings Earthlings"]
@@ -175,7 +212,7 @@ describe "a versionable rdf datastream" do
175
212
  end
176
213
 
177
214
  it "should have two unique versions" do
178
- expect(subject.versions.all.size).to eq 2
215
+ expect(subject.versions.all.size).to eq 2
179
216
  end
180
217
 
181
218
  it "should load the restored datastream's content" do
@@ -1,3 +1,2 @@
1
1
  # require all of the files in the samples directory
2
2
  require 'samples/models/mods_article'
3
- require 'samples/special_thing'
@@ -51,7 +51,58 @@ describe ActiveFedora::Base do
51
51
  end
52
52
  end
53
53
 
54
+ describe ".rdf_label" do
55
+ context "on a concrete class" do
56
+ before do
57
+ class FooHistory < ActiveFedora::Base
58
+ rdf_label ::RDF::DC.title
59
+ property :title, predicate: ::RDF::DC.title
60
+ end
61
+ end
62
+ after do
63
+ Object.send(:remove_const, :FooHistory)
64
+ end
65
+
66
+ let(:instance) { FooHistory.new(title: ['A label']) }
67
+ subject { instance.rdf_label }
68
+
69
+ it { is_expected.to eq ['A label'] }
70
+ end
71
+
72
+ context "on an inherited class" do
73
+ before do
74
+ class Agent < ActiveFedora::Base
75
+ rdf_label ::RDF::FOAF.name
76
+ property :foaf_name, predicate: ::RDF::FOAF.name
77
+ end
78
+ class Person < Agent
79
+ rdf_label ::RDF::URI('http://example.com/foo')
80
+ property :job, predicate: ::RDF::URI('http://example.com/foo')
81
+ end
82
+ class Creator < Person
83
+ end
84
+ end
85
+ after do
86
+ Object.send(:remove_const, :Person)
87
+ Object.send(:remove_const, :Agent)
88
+ Object.send(:remove_const, :Creator)
89
+ end
90
+
91
+ let(:instance) { Creator.new(foaf_name: ['Carolyn'], job: ['Developer']) }
92
+ subject { instance.rdf_label }
93
+
94
+ it { is_expected.to eq ['Developer'] }
95
+ end
96
+ end
97
+
54
98
  describe 'descendants' do
99
+ before do
100
+ class SpecialThing < ActiveFedora::Base
101
+ end
102
+ end
103
+ after do
104
+ Object.send(:remove_const, :SpecialThing)
105
+ end
55
106
  it "should record the decendants" do
56
107
  expect(ActiveFedora::Base.descendants).to include(ModsArticle, SpecialThing)
57
108
  end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveFedora::Core::FedoraIdTranslator do
4
+ describe ".call" do
5
+ let(:result) { described_class.call(id) }
6
+ context "when given an id" do
7
+ let(:good_uri) { ActiveFedora.fedora.host+ActiveFedora.fedora.base_path+"/banana" }
8
+ let(:id) { "banana" }
9
+ it "should return a fedora URI" do
10
+ expect(result).to eq good_uri
11
+ end
12
+ context "when given an id with a leading slash" do
13
+ let(:id) { "/banana" }
14
+ it "should return a good fedora URI" do
15
+ expect(result).to eq good_uri
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe ActiveFedora::Core::FedoraUriTranslator do
4
+ describe ".call" do
5
+ let(:result) { described_class.call(uri) }
6
+ context "when given a Fedora URI" do
7
+ let(:uri) { ActiveFedora.fedora.host + ActiveFedora.fedora.base_path+"/6" }
8
+ it "should return the id" do
9
+ expect(result).to eq '6'
10
+ end
11
+ end
12
+ context "when given a URI missing a slash" do
13
+ let(:uri) { ActiveFedora.fedora.host + ActiveFedora.fedora.base_path+"602-a" }
14
+ it "should return the id" do
15
+ expect(result).to eq "602-a"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -88,12 +88,54 @@ describe ActiveFedora::Base do
88
88
  end
89
89
  end
90
90
 
91
+ describe "#translate_id_to_uri" do
92
+ subject { ActiveFedora::Base.translate_id_to_uri }
93
+ context "when it's not set" do
94
+ it "should be a FedoraIdTranslator" do
95
+ expect(subject).to eq ActiveFedora::Core::FedoraIdTranslator
96
+ end
97
+ end
98
+ context "when it's set to nil" do
99
+ before do
100
+ ActiveFedora::Base.translate_id_to_uri = nil
101
+ end
102
+ it "should be a FedoraIdTranslator" do
103
+ expect(subject).to eq ActiveFedora::Core::FedoraIdTranslator
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#translate_uri_to_id" do
109
+ subject { ActiveFedora::Base.translate_uri_to_id }
110
+ context "when it's not set" do
111
+ it "should be a FedoraUriTranslator" do
112
+ expect(subject).to eq ActiveFedora::Core::FedoraUriTranslator
113
+ end
114
+ end
115
+ context "when it's set to nil" do
116
+ before do
117
+ ActiveFedora::Base.translate_uri_to_id = nil
118
+ end
119
+ it "should be a FedoraIdTranslator" do
120
+ expect(subject).to eq ActiveFedora::Core::FedoraUriTranslator
121
+ end
122
+ end
123
+ end
124
+
91
125
  describe "id_to_uri" do
92
126
  let(:id) { '123456w' }
93
127
  subject { ActiveFedora::Base.id_to_uri(id) }
94
128
 
95
129
  context "with no custom proc is set" do
96
130
  it { should eq "#{ActiveFedora.fedora.host}#{ActiveFedora.fedora.base_path}/123456w" }
131
+ it "should just call #translate_id_to_uri" do
132
+ allow(ActiveFedora::Base).to receive(:translate_id_to_uri).and_call_original
133
+ allow(ActiveFedora::Core::FedoraIdTranslator).to receive(:call).and_call_original
134
+
135
+ subject
136
+
137
+ expect(ActiveFedora::Core::FedoraIdTranslator).to have_received(:call).with(id)
138
+ end
97
139
  end
98
140
 
99
141
  context "when custom proc is set" do
@@ -126,6 +168,14 @@ describe ActiveFedora::Base do
126
168
 
127
169
  context "with no custom proc is set" do
128
170
  it { should eq 'foo/123456w' }
171
+ it "should just call #translate_uri_to_id" do
172
+ allow(ActiveFedora::Base).to receive(:translate_uri_to_id).and_call_original
173
+ allow(ActiveFedora::Core::FedoraUriTranslator).to receive(:call).and_call_original
174
+
175
+ subject
176
+
177
+ expect(ActiveFedora::Core::FedoraUriTranslator).to have_received(:call).with(uri)
178
+ end
129
179
  end
130
180
 
131
181
  context "when custom proc is set" do
@@ -23,7 +23,7 @@ describe ActiveFedora::Associations::HasManyAssociation do
23
23
  end
24
24
 
25
25
  let(:reflection) { Book.create_reflection(:has_many, 'pages', { predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf }, Book) }
26
- let(:association) { ActiveFedora::Associations::HasManyAssociation.new(book, reflection) }
26
+ let(:association) { described_class.new(book, reflection) }
27
27
 
28
28
  it "should set the book_id attribute" do
29
29
  expect(association).to receive(:callback).twice
@@ -40,7 +40,7 @@ describe ActiveFedora::Associations::HasManyAssociation do
40
40
  Page.has_and_belongs_to_many :contents, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ActiveFedora::Base'
41
41
  end
42
42
  let(:book_reflection) { Book.create_reflection(:has_many, 'pages', { predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf }, Book) }
43
- let(:association) { ActiveFedora::Associations::HasManyAssociation.new(book, book_reflection) }
43
+ let(:association) { described_class.new(book, book_reflection) }
44
44
 
45
45
  subject { association.send(:find_polymorphic_inverse, page) }
46
46
 
@@ -48,4 +48,29 @@ describe ActiveFedora::Associations::HasManyAssociation do
48
48
  expect(subject.name).to eq :contents
49
49
  end
50
50
  end
51
+
52
+
53
+ context "when inverse doesn't have a predictable name" do
54
+ before do
55
+ class TimeSpan < ActiveFedora::Base
56
+ has_many :images, inverse_of: :created # predicate: ::RDF::DC.created
57
+ end
58
+
59
+ class Image < ActiveFedora::Base
60
+ has_and_belongs_to_many :created, predicate: ::RDF::DC.created, class_name: 'TimeSpan'
61
+ end
62
+ end
63
+
64
+ after do
65
+ Object.send(:remove_const, :TimeSpan)
66
+ Object.send(:remove_const, :Image)
67
+ end
68
+
69
+ let(:owner) { TimeSpan.new }
70
+ let(:reflection) { TimeSpan.reflect_on_association(:images) }
71
+
72
+ it "finds the predicate" do
73
+ expect { described_class.new(owner, reflection) }.not_to raise_error
74
+ end
75
+ end
51
76
  end
@@ -3,12 +3,6 @@ require 'spec_helper'
3
3
  describe ActiveFedora::QualifiedDublinCoreDatastream do
4
4
  DC_ELEMENTS = [:contributor, :coverage, :creator, :date, :description, :identifier, :language, :publisher, :relation, :rights, :source]
5
5
 
6
- before(:all) do
7
- # Load Sample OralHistory Model
8
- require File.join( File.dirname(__FILE__), "..", "samples","oral_history_sample_model" )
9
- @dc_terms = []
10
- end
11
-
12
6
  let(:sample_xml) do "<dc xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:dcterms='http://purl.org/dc/terms/'>
13
7
  <dcterms:type xsi:type='DCMITYPE'>sound</dcterms:type>
14
8
  <dcterms:medium>medium</dcterms:medium>
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveFedora::Reflection::AssociationReflection do
4
+ describe "#derive_foreign_key" do
5
+ let(:name) { 'dummy' }
6
+ let(:options) { { inverse_of: :default_permissions } }
7
+ let(:active_fedora) { double }
8
+ let(:instance) { described_class.new(macro, name, options, active_fedora) }
9
+ subject { instance.send :derive_foreign_key }
10
+
11
+ context "when a has_many" do
12
+ let(:macro) { :has_many }
13
+
14
+ context "and the inverse is a collection association" do
15
+ let(:inverse) { double(collection?: true) }
16
+ before { allow(instance).to receive(:inverse_of).and_return(inverse) }
17
+ it { is_expected.to eq 'default_permission_ids' }
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "#automatic_inverse_of" do
23
+ before do
24
+ class Dummy < ActiveFedora::Base
25
+ belongs_to :foothing, predicate: ::RDF::DC.extent
26
+ end
27
+ end
28
+
29
+ after { Object.send(:remove_const, :Dummy) }
30
+ let(:name) { 'dummy' }
31
+ let(:options) { { as: 'foothing' } }
32
+ let(:active_fedora) { double }
33
+ let(:instance) { described_class.new(macro, name, options, active_fedora) }
34
+ subject { instance.send :automatic_inverse_of }
35
+
36
+ context "when a has_many" do
37
+ let(:macro) { :has_many }
38
+
39
+ context "and the inverse is a collection association" do
40
+ it { is_expected.to eq :foothing }
41
+ end
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-fedora
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.6
4
+ version: 9.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Zumwalt
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-03-27 00:00:00.000000000 Z
13
+ date: 2020-06-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rsolr
@@ -338,6 +338,8 @@ files:
338
338
  - lib/active_fedora/cleaner.rb
339
339
  - lib/active_fedora/config.rb
340
340
  - lib/active_fedora/core.rb
341
+ - lib/active_fedora/core/fedora_id_translator.rb
342
+ - lib/active_fedora/core/fedora_uri_translator.rb
341
343
  - lib/active_fedora/datastream.rb
342
344
  - lib/active_fedora/datastreams.rb
343
345
  - lib/active_fedora/datastreams/nokogiri_datastreams.rb
@@ -352,6 +354,7 @@ files:
352
354
  - lib/active_fedora/fixity_service.rb
353
355
  - lib/active_fedora/indexing.rb
354
356
  - lib/active_fedora/indexing_service.rb
357
+ - lib/active_fedora/inheritable_accessors.rb
355
358
  - lib/active_fedora/ldp_cache.rb
356
359
  - lib/active_fedora/ldp_resource.rb
357
360
  - lib/active_fedora/ldp_resource_service.rb
@@ -484,18 +487,10 @@ files:
484
487
  - spec/rcov.opts
485
488
  - spec/samples/hydra-mods_article_datastream.rb
486
489
  - spec/samples/hydra-rights_metadata_datastream.rb
487
- - spec/samples/marpa-dc_datastream.rb
488
- - spec/samples/models/audio_record.rb
489
- - spec/samples/models/image.rb
490
490
  - spec/samples/models/mods_article.rb
491
- - spec/samples/models/oral_history.rb
492
- - spec/samples/models/seminar.rb
493
- - spec/samples/models/seminar_audio_file.rb
494
491
  - spec/samples/oral_history_sample.xml
495
- - spec/samples/oral_history_sample_model.rb
496
492
  - spec/samples/oral_history_xml.xml
497
493
  - spec/samples/samples.rb
498
- - spec/samples/special_thing.rb
499
494
  - spec/spec.opts
500
495
  - spec/spec_helper.rb
501
496
  - spec/support/an_active_model.rb
@@ -513,6 +508,8 @@ files:
513
508
  - spec/unit/change_set_spec.rb
514
509
  - spec/unit/code_configurator_spec.rb
515
510
  - spec/unit/config_spec.rb
511
+ - spec/unit/core/fedora_id_translator_spec.rb
512
+ - spec/unit/core/fedora_uri_translator_spec.rb
516
513
  - spec/unit/core_spec.rb
517
514
  - spec/unit/file_configurator_spec.rb
518
515
  - spec/unit/file_path_builder_spec.rb
@@ -544,6 +541,7 @@ files:
544
541
  - spec/unit/rdf_vocab_spec.rb
545
542
  - spec/unit/rdfxml_datastream_spec.rb
546
543
  - spec/unit/readonly_spec.rb
544
+ - spec/unit/reflection_spec.rb
547
545
  - spec/unit/rspec_matchers/belong_to_associated_active_fedora_object_matcher_spec.rb
548
546
  - spec/unit/rspec_matchers/have_many_associated_active_fedora_objects_matcher_spec.rb
549
547
  - spec/unit/rspec_matchers/have_predicate_matcher_spec.rb
@@ -573,10 +571,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
573
571
  - !ruby/object:Gem::Version
574
572
  version: '0'
575
573
  requirements: []
576
- rubyforge_project:
577
- rubygems_version: 2.4.5
574
+ rubygems_version: 3.1.2
578
575
  signing_key:
579
576
  specification_version: 4
580
577
  summary: A convenience libary for manipulating documents in the Fedora Repository.
581
578
  test_files: []
582
- has_rdoc:
@@ -1,102 +0,0 @@
1
- require "active-fedora"
2
- module Marpa
3
-
4
- # This is an example of a OmDatastream that defines a terminology for Dublin Core xml
5
- #
6
- # Some things to observe about this Class:
7
- # * Defines a couple of custom terms, tibetan_title and english_title, that map to dc:title with varying @language attributes
8
- # * Indicates which terms should be indexed as facets using :index_as=>[:facetable]
9
- # * Defines an xml template that is an empty dublin core xml document with three namespaces set
10
- # * Sets the namespace using :xmlns argument on the root term
11
- # * Does not override or extend to_solr, so the default solrization approach will be used (Solrizer::XML::TerminologyBasedSolrizer)
12
- #
13
- class DcDatastream < ActiveFedora::OmDatastream
14
-
15
- set_terminology do |t|
16
- t.root(:path=>"dc", :xmlns=>'http://purl.org/dc/terms/')
17
- t.tibetan_title(:path=>"title", :attributes=>{:language=>"tibetan"})
18
- t.english_title(:path=>"title", :attributes=>{:language=>:none})
19
- t.contributor(:index_as=>[:facetable])
20
- t.coverage
21
- t.creator
22
- t.description
23
- t.format
24
- t.identifier
25
- t.language(:index_as=>[:facetable])
26
- t.publisher
27
- t.relation
28
- t.source
29
- t.title
30
- t.abstract
31
- t.accessRights
32
- t.accrualMethod
33
- t.accrualPeriodicity
34
- t.accrualPolicy
35
- t.alternative
36
- t.audience
37
- t.available
38
- t.bibliographicCitation
39
- t.conformsTo
40
- t.contributor
41
- t.coverage
42
- t.created
43
- t.creator
44
- t.date(:index_as=>[:facetable])
45
- t.dateAccepted
46
- t.dateCopyrighted
47
- t.dateSubmitted
48
- t.description
49
- t.educationLevel
50
- t.extent
51
- t.format
52
- t.hasFormat
53
- t.hasPart
54
- t.hasVersion
55
- t.identifier
56
- t.instructionalMethod
57
- t.isFormatOf
58
- t.isPartOf
59
- t.isReferencedBy
60
- t.isReplacedBy
61
- t.isRequiredBy
62
- t.issued
63
- t.isVersionOf
64
- t.language(:index_as=>[:facetable])
65
- t.license
66
- t.mediator
67
- t.medium
68
- t.modified
69
- t.provenance
70
- t.publisher
71
- t.references
72
- t.relation
73
- t.replaces
74
- t.requires
75
- t.rights
76
- t.rightsHolder
77
- t.source
78
- t.spatial(:index_as=>[:facetable])
79
- t.subject(:index_as=>[:facetable])
80
- t.tableOfContents
81
- t.temporal
82
- t.type
83
- t.valid
84
- end
85
-
86
- def self.xml_template
87
- builder = Nokogiri::XML::Builder.new do |xml|
88
- xml.dc("xmlns"=>'http://purl.org/dc/terms/',
89
- "xmlns:dcterms"=>'http://purl.org/dc/terms/',
90
- "xmlns:xsi"=>'http://www.w3.org/2001/XMLSchema-instance') {
91
- }
92
- end
93
- return builder.doc
94
- end
95
-
96
- def prefix
97
- "#{dsid.underscore}__"
98
- end
99
-
100
-
101
- end
102
- end