active-fedora 9.0.6 → 9.0.8

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