active-fedora 9.0.0.rc2 → 9.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/active-fedora.gemspec +2 -3
- data/lib/active_fedora/attributes.rb +8 -1
- data/lib/active_fedora/attributes/property_builder.rb +13 -5
- data/lib/active_fedora/fedora.rb +3 -0
- data/lib/active_fedora/file.rb +1 -1
- data/lib/active_fedora/fixity_service.rb +2 -5
- data/lib/active_fedora/indexing.rb +10 -8
- data/lib/active_fedora/nested_attributes.rb +12 -0
- data/lib/active_fedora/rdf/fcrepo4.rb +2 -0
- data/lib/active_fedora/version.rb +1 -1
- data/lib/tasks/active_fedora_dev.rake +0 -2
- data/spec/integration/datastream_rdf_nested_attributes_spec.rb +185 -0
- data/spec/integration/indexing_spec.rb +20 -7
- data/spec/integration/rdf_nested_attributes_spec.rb +38 -168
- data/spec/unit/active_fedora_spec.rb +18 -0
- data/spec/unit/base_spec.rb +2 -12
- data/spec/unit/property_predicate_spec.rb +40 -0
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a49c5a80114d75ddec80fc7ef09aa0e41f45331e
|
4
|
+
data.tar.gz: 3c7fd10c052aa997fd6d021140aeece4e9da5515
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a4843d2350b989d0785ec900fb722196339a989cf279ea619f7b470cae56d1210e922259d74d3146d60a72ba4e5df390164d0f9716cc43d6fa11b0b93db6cf5
|
7
|
+
data.tar.gz: 0bc39376a1dc54ea35bbf081b40106d88541c1e0282585f27fa5f8aaeb8d9960e090cf8d426d4bf2cb5b8864c10a8730a4b753fe762fa0bab8d7fff8a7e2fdfd
|
data/active-fedora.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_dependency 'om', '~> 3.1'
|
19
19
|
s.add_dependency 'nom-xml', '>= 0.5.1'
|
20
20
|
s.add_dependency "activesupport", '>= 4.1.0'
|
21
|
-
s.add_dependency "active-triples", '~> 0.
|
21
|
+
s.add_dependency "active-triples", '~> 0.6.0'
|
22
22
|
s.add_dependency "rdf-rdfxml", '~> 1.1.0'
|
23
23
|
s.add_dependency "linkeddata"
|
24
24
|
s.add_dependency "deprecation"
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_development_dependency "rdoc"
|
29
29
|
s.add_development_dependency "yard"
|
30
30
|
s.add_development_dependency "rake"
|
31
|
-
s.add_development_dependency "jettywrapper", ">=
|
31
|
+
s.add_development_dependency "jettywrapper", ">= 2.0.0"
|
32
32
|
s.add_development_dependency "rspec", "~> 3.0"
|
33
33
|
s.add_development_dependency "equivalent-xml"
|
34
34
|
s.add_development_dependency "simplecov", '~> 0.7.1'
|
@@ -43,4 +43,3 @@ Gem::Specification.new do |s|
|
|
43
43
|
s.require_paths = ["lib"]
|
44
44
|
|
45
45
|
end
|
46
|
-
|
@@ -171,16 +171,23 @@ module ActiveFedora
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def property name, properties={}, &block
|
174
|
+
warn_duplicate_predicates name, properties
|
174
175
|
properties = { multiple: true }.merge(properties)
|
175
176
|
find_or_create_defined_attribute(name, nil, properties)
|
176
177
|
raise ArgumentError, "#{name} is a keyword and not an acceptable property name." if protected_property_name? name
|
177
178
|
reflection = ActiveFedora::Attributes::PropertyBuilder.build(self, name, properties, &block)
|
178
|
-
# reflection = ActiveTriple::PropertyBuilder.build(self, name, properties, &block)
|
179
179
|
ActiveTriples::Reflection.add_reflection self, name, reflection
|
180
180
|
end
|
181
181
|
|
182
182
|
private
|
183
183
|
|
184
|
+
def warn_duplicate_predicates new_name, new_properties
|
185
|
+
new_predicate = new_properties[:predicate]
|
186
|
+
self.properties.select{|k, existing| existing.predicate == new_predicate}.each do |key, value|
|
187
|
+
ActiveFedora::Base.logger.warn "Same predicate (#{new_predicate}) used for properties #{key} and #{new_name}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
184
191
|
def find_or_create_defined_attribute(field, dsid, args)
|
185
192
|
delegated_attributes[field] ||= DelegatedAttribute.new(field, dsid, datastream_class_for_name(dsid), args)
|
186
193
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActiveFedora::Attributes
|
2
2
|
class PropertyBuilder < ActiveTriples::PropertyBuilder #:nodoc:
|
3
3
|
|
4
|
-
def self.define_accessors(model, reflection)
|
5
|
-
mixin = model.generated_property_methods
|
6
|
-
name = reflection.term
|
4
|
+
def self.define_accessors(model, reflection, options={})
|
7
5
|
if reflection.multiple?
|
8
|
-
|
9
|
-
define_writers(mixin, name)
|
6
|
+
super
|
10
7
|
else
|
8
|
+
mixin = model.generated_property_methods
|
9
|
+
name = reflection.term
|
11
10
|
define_singular_readers(mixin, name)
|
11
|
+
define_singular_id_reader(mixin, name) unless options[:cast] == false
|
12
12
|
define_singular_writers(mixin, name)
|
13
13
|
end
|
14
14
|
end
|
@@ -34,6 +34,14 @@ module ActiveFedora::Attributes
|
|
34
34
|
CODE
|
35
35
|
end
|
36
36
|
|
37
|
+
def self.define_singular_id_reader(mixin, name)
|
38
|
+
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
39
|
+
def #{name}_id(*args)
|
40
|
+
get_values(:#{name}, :cast => false)
|
41
|
+
end
|
42
|
+
CODE
|
43
|
+
end
|
44
|
+
|
37
45
|
def self.define_singular_writers(mixin, name)
|
38
46
|
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
|
39
47
|
def #{name}=(value)
|
data/lib/active_fedora/fedora.rb
CHANGED
@@ -26,6 +26,9 @@ module ActiveFedora
|
|
26
26
|
ActiveFedora::Base.logger.info "Attempted to init base path `#{root_resource_path}`, but it already exists" if ActiveFedora::Base.logger
|
27
27
|
return false
|
28
28
|
rescue Ldp::NotFound
|
29
|
+
if !host.downcase.end_with?("/rest")
|
30
|
+
ActiveFedora::Base.logger.warn "Fedora URL (#{host}) does not end with /rest. This could be a problem. Check your fedora.yml config"
|
31
|
+
end
|
29
32
|
connection.put(root_resource_path, BLANK).success?
|
30
33
|
end
|
31
34
|
|
data/lib/active_fedora/file.rb
CHANGED
@@ -118,7 +118,7 @@ module ActiveFedora
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def digest
|
121
|
-
response = metadata.ldp_source.graph.query(:
|
121
|
+
response = metadata.ldp_source.graph.query(predicate: ActiveFedora::RDF::Fcrepo4.digest)
|
122
122
|
response.map(&:object)
|
123
123
|
end
|
124
124
|
|
@@ -18,7 +18,7 @@ module ActiveFedora
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def status
|
21
|
-
fixity_graph.query(predicate:
|
21
|
+
fixity_graph.query(predicate: ActiveFedora::RDF::Fcrepo4.status).map(&:object).first.to_s
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
@@ -32,10 +32,7 @@ module ActiveFedora
|
|
32
32
|
::RDF::Graph.new << ::RDF::Reader.for(:ttl).new(response.body)
|
33
33
|
end
|
34
34
|
|
35
|
-
|
36
|
-
::RDF::URI("http://fedora.info/definitions/v4/repository#status")
|
37
|
-
end
|
38
|
-
|
35
|
+
# See https://jira.duraspace.org/browse/FCREPO-1247
|
39
36
|
def encoded_url uri
|
40
37
|
if uri.match("fcr:versions")
|
41
38
|
uri.gsub(/fcr:versions/,"fcr%3aversions")
|
@@ -56,9 +56,11 @@ module ActiveFedora
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def reindex_everything
|
59
|
-
|
59
|
+
descendants = descendant_uris(ActiveFedora::Base.id_to_uri(''))
|
60
|
+
descendants.shift # Discard the root uri
|
61
|
+
descendants.each do |uri|
|
60
62
|
logger.debug "Re-index everything ... #{uri}"
|
61
|
-
ActiveFedora::Base.find(
|
63
|
+
ActiveFedora::Base.find(ActiveFedora::Base.uri_to_id(uri)).update_index
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
@@ -77,17 +79,17 @@ module ActiveFedora
|
|
77
79
|
SolrInstanceLoader.new(self, id, solr_doc).object
|
78
80
|
end
|
79
81
|
|
80
|
-
def
|
82
|
+
def descendant_uris(uri)
|
81
83
|
resource = Ldp::Resource::RdfSource.new(ActiveFedora.fedora.connection, uri)
|
82
84
|
# GET could be slow if it's a big resource, we're using HEAD to avoid this problem,
|
83
85
|
# but this causes more requests to Fedora.
|
84
86
|
return [] unless Ldp::Response.rdf_source?(resource.head)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
immediate_descendant_uris = resource.graph.query(predicate: ::RDF::LDP.contains).map { |descendant| descendant.object.to_s }
|
88
|
+
all_descendants_uris = [uri]
|
89
|
+
immediate_descendant_uris.each do |descendant_uri|
|
90
|
+
all_descendants_uris += descendant_uris(descendant_uri)
|
89
91
|
end
|
90
|
-
|
92
|
+
all_descendants_uris
|
91
93
|
end
|
92
94
|
|
93
95
|
end
|
@@ -83,6 +83,18 @@ module ActiveFedora
|
|
83
83
|
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
|
84
84
|
end
|
85
85
|
eoruby
|
86
|
+
elsif reflection = reflect_on_property(association_name)
|
87
|
+
resource_class.accepts_nested_attributes_for(association_name, options)
|
88
|
+
|
89
|
+
# Delegate the setter to the resource.
|
90
|
+
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
91
|
+
remove_possible_method(:#{association_name}_attributes=)
|
92
|
+
|
93
|
+
def #{association_name}_attributes=(attributes)
|
94
|
+
attribute_will_change!(:#{association_name})
|
95
|
+
resource.#{association_name}_attributes=(attributes)
|
96
|
+
end
|
97
|
+
eoruby
|
86
98
|
else
|
87
99
|
raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?"
|
88
100
|
end
|
@@ -2,8 +2,10 @@ require 'rdf'
|
|
2
2
|
module ActiveFedora::RDF
|
3
3
|
class Fcrepo4 < RDF::StrictVocabulary("http://fedora.info/definitions/v4/repository#")
|
4
4
|
property :created
|
5
|
+
property :digest
|
5
6
|
property :hasVersion
|
6
7
|
property :hasVersionLabel
|
7
8
|
property :lastModified
|
9
|
+
property :status
|
8
10
|
end
|
9
11
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
APP_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../")
|
2
2
|
|
3
3
|
require 'jettywrapper'
|
4
|
-
Jettywrapper.hydra_jetty_version = "v8.1.1"
|
5
4
|
|
6
5
|
namespace :active_fedora do
|
7
6
|
# Use yard to build docs
|
@@ -40,7 +39,6 @@ namespace :active_fedora do
|
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
42
|
desc "CI build"
|
45
43
|
task :ci do
|
46
44
|
ENV['environment'] = "test"
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Nesting attribute behavior of RDFDatastream" do
|
4
|
+
describe ".attributes=" do
|
5
|
+
|
6
|
+
context "complex properties in a datastream" do
|
7
|
+
before do
|
8
|
+
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
9
|
+
# TODO this test is order dependent. It expects to use the object created in the previous test
|
10
|
+
# componentList and Types of components
|
11
|
+
property :componentList
|
12
|
+
property :Topic
|
13
|
+
property :Temporal
|
14
|
+
property :PersonalName
|
15
|
+
property :CorporateName
|
16
|
+
property :ComplexSubject
|
17
|
+
|
18
|
+
|
19
|
+
# elementList and elementList values
|
20
|
+
property :elementList
|
21
|
+
property :elementValue
|
22
|
+
property :TopicElement
|
23
|
+
property :TemporalElement
|
24
|
+
property :NameElement
|
25
|
+
property :FullNameElement
|
26
|
+
property :DateNameElement
|
27
|
+
end
|
28
|
+
|
29
|
+
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
30
|
+
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
31
|
+
property :personalName, predicate: DummyMADS.PersonalName, class_name: "PersonalName"
|
32
|
+
property :title, predicate: ::RDF::DC.title
|
33
|
+
|
34
|
+
|
35
|
+
accepts_nested_attributes_for :topic, :personalName
|
36
|
+
|
37
|
+
class Topic < ActiveTriples::Resource
|
38
|
+
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
39
|
+
accepts_nested_attributes_for :elementList
|
40
|
+
end
|
41
|
+
class PersonalName < ActiveTriples::Resource
|
42
|
+
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
43
|
+
property :extraProperty, predicate: DummyMADS.elementValue, class_name: "ComplexRDFDatastream::Topic"
|
44
|
+
accepts_nested_attributes_for :elementList, :extraProperty
|
45
|
+
end
|
46
|
+
class ElementList < ActiveTriples::List
|
47
|
+
configure type: DummyMADS.elementList
|
48
|
+
property :topicElement, predicate: DummyMADS.TopicElement, class_name: "ComplexRDFDatastream::MadsTopicElement"
|
49
|
+
property :temporalElement, predicate: DummyMADS.TemporalElement
|
50
|
+
property :fullNameElement, predicate: DummyMADS.FullNameElement
|
51
|
+
property :dateNameElement, predicate: DummyMADS.DateNameElement
|
52
|
+
property :nameElement, predicate: DummyMADS.NameElement
|
53
|
+
property :elementValue, predicate: DummyMADS.elementValue
|
54
|
+
accepts_nested_attributes_for :topicElement
|
55
|
+
end
|
56
|
+
class MadsTopicElement < ActiveTriples::Resource
|
57
|
+
configure :type => DummyMADS.TopicElement
|
58
|
+
property :elementValue, predicate: DummyMADS.elementValue
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
after do
|
63
|
+
Object.send(:remove_const, :ComplexRDFDatastream)
|
64
|
+
Object.send(:remove_const, :DummyMADS)
|
65
|
+
end
|
66
|
+
subject { ComplexRDFDatastream.new }
|
67
|
+
let(:params) do
|
68
|
+
{ myResource:
|
69
|
+
{
|
70
|
+
topic_attributes: {
|
71
|
+
'0' =>
|
72
|
+
{
|
73
|
+
elementList_attributes: [{
|
74
|
+
topicElement_attributes: [{
|
75
|
+
id: 'http://library.ucsd.edu/ark:/20775/bb3333333x',
|
76
|
+
elementValue:"Cosmology"
|
77
|
+
}]
|
78
|
+
}]
|
79
|
+
},
|
80
|
+
'1' =>
|
81
|
+
{
|
82
|
+
elementList_attributes: [{
|
83
|
+
topicElement_attributes: {'0' => {elementValue:"Quantum Behavior"}}
|
84
|
+
}]
|
85
|
+
}
|
86
|
+
},
|
87
|
+
personalName_attributes: [
|
88
|
+
{
|
89
|
+
id: 'http://library.ucsd.edu/ark:20775/jefferson',
|
90
|
+
elementList_attributes: [{
|
91
|
+
fullNameElement: "Jefferson, Thomas",
|
92
|
+
dateNameElement: "1743-1826"
|
93
|
+
}]
|
94
|
+
}
|
95
|
+
#, "Hemings, Sally"
|
96
|
+
],
|
97
|
+
}
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "on lists" do
|
102
|
+
subject { ComplexRDFDatastream::PersonalName.new(RDF::Graph.new) }
|
103
|
+
it "should accept a hash" do
|
104
|
+
subject.elementList_attributes = [{ topicElement_attributes: {'0' => { elementValue:"Quantum Behavior" }, '1' => { elementValue:"Wave Function" }}}]
|
105
|
+
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
106
|
+
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
107
|
+
|
108
|
+
end
|
109
|
+
it "should accept an array" do
|
110
|
+
subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue:"Quantum Behavior" }, { elementValue:"Wave Function" }]}]
|
111
|
+
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
112
|
+
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "from nested objects" do
|
117
|
+
before do
|
118
|
+
# Replace the graph's contents with the Hash
|
119
|
+
subject.attributes = params[:myResource]
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should have attributes' do
|
123
|
+
expect(subject.topic[0].elementList.first[0].elementValue).to eq ["Cosmology"]
|
124
|
+
expect(subject.topic[1].elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
125
|
+
expect(subject.personalName.first.elementList.first.fullNameElement).to eq ["Jefferson, Thomas"]
|
126
|
+
expect(subject.personalName.first.elementList.first.dateNameElement).to eq ["1743-1826"]
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should build nodes with ids' do
|
130
|
+
expect(subject.topic[0].elementList.first[0].rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bb3333333x'
|
131
|
+
expect(subject.personalName.first.rdf_subject).to eq 'http://library.ucsd.edu/ark:20775/jefferson'
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should fail when writing to a non-predicate' do
|
135
|
+
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate:"Cosmology" }] }]}}}
|
136
|
+
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should fail when writing to a non-predicate with a setter method' do
|
140
|
+
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name:"Cosmology" }] }]}}}
|
141
|
+
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "with an existing object" do
|
147
|
+
before(:each) do
|
148
|
+
class SpecDatastream < ActiveFedora::NtriplesRDFDatastream
|
149
|
+
property :parts, predicate: ::RDF::DC.hasPart, :class_name=>'Component'
|
150
|
+
accepts_nested_attributes_for :parts, allow_destroy: true
|
151
|
+
|
152
|
+
class Component < ActiveTriples::Resource
|
153
|
+
property :label, predicate: ::RDF::DC.title
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
after(:each) do
|
160
|
+
Object.send(:remove_const, :SpecDatastream)
|
161
|
+
end
|
162
|
+
subject { SpecDatastream.new }
|
163
|
+
before do
|
164
|
+
subject.attributes = { parts_attributes: [
|
165
|
+
{label: 'Alternator'},
|
166
|
+
{label: 'Distributor'},
|
167
|
+
{label: 'Transmission'},
|
168
|
+
{label: 'Fuel Filter'}]}
|
169
|
+
end
|
170
|
+
let (:replace_object_id) { subject.parts[1].rdf_subject.to_s }
|
171
|
+
let (:remove_object_id) { subject.parts[3].rdf_subject.to_s }
|
172
|
+
|
173
|
+
it "should update nested objects" do
|
174
|
+
subject.parts_attributes= [{id: replace_object_id, label: "Universal Joint"}, {label:"Oil Pump"}, {id: remove_object_id, _destroy: '1', label: "bar1 uno"}]
|
175
|
+
|
176
|
+
expect(subject.parts.map{|p| p.label.first}).to eq ['Alternator', 'Universal Joint', 'Transmission', 'Oil Pump']
|
177
|
+
|
178
|
+
end
|
179
|
+
it "create a new object when the id is provided" do
|
180
|
+
subject.parts_attributes= [{id: 'http://example.com/part#1', label: "Universal Joint"}]
|
181
|
+
expect(subject.parts.last.rdf_subject).to eq RDF::URI('http://example.com/part#1')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
@@last_id = 0
|
3
3
|
|
4
4
|
describe ActiveFedora::Base do
|
5
|
-
describe "
|
5
|
+
describe "descendant_uris" do
|
6
6
|
|
7
7
|
before :each do
|
8
8
|
ids.each do |id|
|
@@ -14,21 +14,21 @@ describe ActiveFedora::Base do
|
|
14
14
|
ActiveFedora::Base.id_to_uri(ids.first)
|
15
15
|
end
|
16
16
|
|
17
|
-
context 'when there there are no
|
17
|
+
context 'when there there are no descendants' do
|
18
18
|
|
19
19
|
let(:ids) { ['foo'] }
|
20
20
|
|
21
21
|
it 'returns an array containing only the URI passed to it' do
|
22
|
-
expect(ActiveFedora::Base.
|
22
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).to eq ids.map {|id| ActiveFedora::Base.id_to_uri(id) }
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
context 'when there are > 1
|
26
|
+
context 'when there are > 1 descendants' do
|
27
27
|
|
28
28
|
let(:ids) { ['foo', 'foo/bar', 'foo/bar/chu'] }
|
29
29
|
|
30
|
-
it 'returns an array containing the URI passed to it, as well as all
|
31
|
-
expect(ActiveFedora::Base.
|
30
|
+
it 'returns an array containing the URI passed to it, as well as all descendant URIs' do
|
31
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).to eq ids.map {|id| ActiveFedora::Base.id_to_uri(id) }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -42,7 +42,20 @@ describe ActiveFedora::Base do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should not put the datastream in the decendants list" do
|
45
|
-
expect(ActiveFedora::Base.
|
45
|
+
expect(ActiveFedora::Base.descendant_uris(root_uri(ids))).not_to include datastream.uri
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "reindex_everything" do
|
50
|
+
let(:ids) { ['foo', 'bar'] }
|
51
|
+
let(:solr) { ActiveFedora::SolrService.instance.conn }
|
52
|
+
before do
|
53
|
+
solr.delete_by_query('*:*', params: {'softCommit' => true})
|
54
|
+
end
|
55
|
+
it "should call update_index on every object represented in the sitemap" do
|
56
|
+
expect {
|
57
|
+
ActiveFedora::Base.reindex_everything
|
58
|
+
}.to change { ActiveFedora::SolrService.query('id:foo').size }.from(0).to(1)
|
46
59
|
end
|
47
60
|
end
|
48
61
|
end
|
@@ -1,185 +1,55 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "Nesting attribute behavior of
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
9
|
-
# TODO this test is order dependent. It expects to use the object created in the previous test
|
10
|
-
# componentList and Types of components
|
11
|
-
property :componentList
|
12
|
-
property :Topic
|
13
|
-
property :Temporal
|
14
|
-
property :PersonalName
|
15
|
-
property :CorporateName
|
16
|
-
property :ComplexSubject
|
17
|
-
|
18
|
-
|
19
|
-
# elementList and elementList values
|
20
|
-
property :elementList
|
21
|
-
property :elementValue
|
22
|
-
property :TopicElement
|
23
|
-
property :TemporalElement
|
24
|
-
property :NameElement
|
25
|
-
property :FullNameElement
|
26
|
-
property :DateNameElement
|
27
|
-
end
|
28
|
-
|
29
|
-
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
30
|
-
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
31
|
-
property :personalName, predicate: DummyMADS.PersonalName, class_name: "PersonalName"
|
32
|
-
property :title, predicate: ::RDF::DC.title
|
33
|
-
|
34
|
-
|
35
|
-
accepts_nested_attributes_for :topic, :personalName
|
36
|
-
|
37
|
-
class Topic < ActiveTriples::Resource
|
38
|
-
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
39
|
-
accepts_nested_attributes_for :elementList
|
40
|
-
end
|
41
|
-
class PersonalName < ActiveTriples::Resource
|
42
|
-
property :elementList, predicate: DummyMADS.elementList, class_name: "ComplexRDFDatastream::ElementList"
|
43
|
-
property :extraProperty, predicate: DummyMADS.elementValue, class_name: "ComplexRDFDatastream::Topic"
|
44
|
-
accepts_nested_attributes_for :elementList, :extraProperty
|
45
|
-
end
|
46
|
-
class ElementList < ActiveTriples::List
|
47
|
-
configure type: DummyMADS.elementList
|
48
|
-
property :topicElement, predicate: DummyMADS.TopicElement, class_name: "ComplexRDFDatastream::MadsTopicElement"
|
49
|
-
property :temporalElement, predicate: DummyMADS.TemporalElement
|
50
|
-
property :fullNameElement, predicate: DummyMADS.FullNameElement
|
51
|
-
property :dateNameElement, predicate: DummyMADS.DateNameElement
|
52
|
-
property :nameElement, predicate: DummyMADS.NameElement
|
53
|
-
property :elementValue, predicate: DummyMADS.elementValue
|
54
|
-
accepts_nested_attributes_for :topicElement
|
55
|
-
end
|
56
|
-
class MadsTopicElement < ActiveTriples::Resource
|
57
|
-
configure :type => DummyMADS.TopicElement
|
58
|
-
property :elementValue, predicate: DummyMADS.elementValue
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
after do
|
63
|
-
Object.send(:remove_const, :ComplexRDFDatastream)
|
64
|
-
Object.send(:remove_const, :DummyMADS)
|
65
|
-
end
|
66
|
-
subject { ComplexRDFDatastream.new }
|
67
|
-
let(:params) do
|
68
|
-
{ myResource:
|
69
|
-
{
|
70
|
-
topic_attributes: {
|
71
|
-
'0' =>
|
72
|
-
{
|
73
|
-
elementList_attributes: [{
|
74
|
-
topicElement_attributes: [{
|
75
|
-
id: 'http://library.ucsd.edu/ark:/20775/bb3333333x',
|
76
|
-
elementValue:"Cosmology"
|
77
|
-
}]
|
78
|
-
}]
|
79
|
-
},
|
80
|
-
'1' =>
|
81
|
-
{
|
82
|
-
elementList_attributes: [{
|
83
|
-
topicElement_attributes: {'0' => {elementValue:"Quantum Behavior"}}
|
84
|
-
}]
|
85
|
-
}
|
86
|
-
},
|
87
|
-
personalName_attributes: [
|
88
|
-
{
|
89
|
-
id: 'http://library.ucsd.edu/ark:20775/jefferson',
|
90
|
-
elementList_attributes: [{
|
91
|
-
fullNameElement: "Jefferson, Thomas",
|
92
|
-
dateNameElement: "1743-1826"
|
93
|
-
}]
|
94
|
-
}
|
95
|
-
#, "Hemings, Sally"
|
96
|
-
],
|
97
|
-
}
|
98
|
-
}
|
99
|
-
end
|
3
|
+
describe "Nesting attribute behavior of RDF resources" do
|
4
|
+
before do
|
5
|
+
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
6
|
+
property :Topic
|
7
|
+
end
|
100
8
|
|
101
|
-
|
102
|
-
|
103
|
-
it "should accept a hash" do
|
104
|
-
subject.elementList_attributes = [{ topicElement_attributes: {'0' => { elementValue:"Quantum Behavior" }, '1' => { elementValue:"Wave Function" }}}]
|
105
|
-
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
106
|
-
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
9
|
+
class ComplexResource < ActiveFedora::Base
|
10
|
+
property :topic, predicate: DummyMADS.Topic, class_name: "Topic"
|
107
11
|
|
108
|
-
|
109
|
-
|
110
|
-
subject.elementList_attributes = [{ topicElement_attributes: [{ elementValue:"Quantum Behavior" }, { elementValue:"Wave Function" }]}]
|
111
|
-
expect(subject.elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
112
|
-
expect(subject.elementList.first[1].elementValue).to eq ["Wave Function"]
|
113
|
-
end
|
12
|
+
class Topic < ActiveTriples::Resource
|
13
|
+
property :subject, predicate: ::RDF::DC.subject
|
114
14
|
end
|
15
|
+
end
|
16
|
+
end
|
115
17
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'should have attributes' do
|
123
|
-
expect(subject.topic[0].elementList.first[0].elementValue).to eq ["Cosmology"]
|
124
|
-
expect(subject.topic[1].elementList.first[0].elementValue).to eq ["Quantum Behavior"]
|
125
|
-
expect(subject.personalName.first.elementList.first.fullNameElement).to eq ["Jefferson, Thomas"]
|
126
|
-
expect(subject.personalName.first.elementList.first.dateNameElement).to eq ["1743-1826"]
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should build nodes with ids' do
|
130
|
-
expect(subject.topic[0].elementList.first[0].rdf_subject).to eq 'http://library.ucsd.edu/ark:/20775/bb3333333x'
|
131
|
-
expect(subject.personalName.first.rdf_subject).to eq 'http://library.ucsd.edu/ark:20775/jefferson'
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'should fail when writing to a non-predicate' do
|
135
|
-
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ fake_predicate:"Cosmology" }] }]}}}
|
136
|
-
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
137
|
-
end
|
18
|
+
after do
|
19
|
+
Object.send(:remove_const, :ComplexResource)
|
20
|
+
Object.send(:remove_const, :DummyMADS)
|
21
|
+
end
|
138
22
|
|
139
|
-
|
140
|
-
attributes = { topic_attributes: { '0' => { elementList_attributes: [{ topicElement_attributes: [{ name:"Cosmology" }] }]}}}
|
141
|
-
expect{ subject.attributes = attributes }.to raise_error ArgumentError
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
23
|
+
subject { ComplexResource.new }
|
145
24
|
|
146
|
-
|
147
|
-
before(:each) do
|
148
|
-
class SpecDatastream < ActiveFedora::NtriplesRDFDatastream
|
149
|
-
property :parts, predicate: ::RDF::DC.hasPart, :class_name=>'Component'
|
150
|
-
accepts_nested_attributes_for :parts, allow_destroy: true
|
25
|
+
let(:params) { [{ subject: 'Foo' }, { subject: 'Bar' }] }
|
151
26
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
27
|
+
before do
|
28
|
+
ComplexResource.accepts_nested_attributes_for *args
|
29
|
+
subject.topic_attributes = params
|
30
|
+
end
|
156
31
|
|
157
|
-
|
32
|
+
context "when no options are set" do
|
33
|
+
let(:args) { [:topic] }
|
158
34
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
before do
|
164
|
-
subject.attributes = { parts_attributes: [
|
165
|
-
{label: 'Alternator'},
|
166
|
-
{label: 'Distributor'},
|
167
|
-
{label: 'Transmission'},
|
168
|
-
{label: 'Fuel Filter'}]}
|
169
|
-
end
|
170
|
-
let (:replace_object_id) { subject.parts[1].rdf_subject.to_s }
|
171
|
-
let (:remove_object_id) { subject.parts[3].rdf_subject.to_s }
|
35
|
+
it "should set the attributes" do
|
36
|
+
expect(subject.topic.size).to eq 2
|
37
|
+
expect(subject.topic.map(&:subject)).to eq [['Foo'], ['Bar']]
|
38
|
+
end
|
172
39
|
|
173
|
-
|
174
|
-
|
40
|
+
it "should mark the attributes as changed" do
|
41
|
+
expect(subject.changed_attributes).to eq('topic' => [])
|
42
|
+
end
|
43
|
+
end
|
175
44
|
|
176
|
-
|
45
|
+
context "when reject_if is set" do
|
46
|
+
let(:args) { [:topic, reject_if: reject_proc] }
|
47
|
+
let(:reject_proc) { lambda { |attributes| attributes[:subject] == 'Bar' } }
|
48
|
+
let(:params) { [{ subject: 'Foo' }, { subject: 'Bar' }] }
|
177
49
|
|
178
|
-
|
179
|
-
|
180
|
-
subject.parts_attributes= [{id: 'http://example.com/part#1', label: "Universal Joint"}]
|
181
|
-
expect(subject.parts.last.rdf_subject).to eq RDF::URI('http://example.com/part#1')
|
182
|
-
end
|
50
|
+
it "should not add terms for which the proc is true" do
|
51
|
+
expect(subject.topic.map(&:subject)).to eq [['Foo']]
|
183
52
|
end
|
184
53
|
end
|
54
|
+
|
185
55
|
end
|
@@ -15,6 +15,24 @@ describe ActiveFedora do
|
|
15
15
|
restore_spec_configuration
|
16
16
|
end
|
17
17
|
|
18
|
+
describe "validate Fedora URL" do
|
19
|
+
|
20
|
+
let(:good_url) { ActiveFedora.fedora_config.credentials[:url] }
|
21
|
+
let(:bad_url) { good_url.gsub('/rest', '/') }
|
22
|
+
|
23
|
+
it "should connect OK" do
|
24
|
+
expect(ActiveFedora::Base.logger).to_not receive(:warn)
|
25
|
+
ActiveFedora::Fedora.new(url: good_url, base_path: '/test')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not connect and warn" do
|
29
|
+
expect(ActiveFedora::Base.logger).to receive(:warn)
|
30
|
+
expect {
|
31
|
+
ActiveFedora::Fedora.new(url: bad_url, base_path: '/test')
|
32
|
+
}.to raise_error Ldp::HttpError
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
18
36
|
describe "initialization methods" do
|
19
37
|
describe "environment" do
|
20
38
|
it "should use config_options[:environment] if set" do
|
data/spec/unit/base_spec.rb
CHANGED
@@ -10,18 +10,8 @@ describe ActiveFedora::Base do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
describe "reindex_everything" do
|
14
|
-
it "should call update_index on every object represented in the sitemap" do
|
15
|
-
allow(ActiveFedora::Base).to receive(:descendent_uris) { ['http://localhost/test/XXX', 'http://localhost/test/YYY', 'http://localhost/test/ZZZ'] }
|
16
|
-
mock_update = double(:mock_obj)
|
17
|
-
expect(mock_update).to receive(:update_index).exactly(3).times
|
18
|
-
expect(ActiveFedora::Base).to receive(:find).with(instance_of ActiveFedora::LdpResource ).and_return(mock_update).exactly(3).times
|
19
|
-
ActiveFedora::Base.reindex_everything
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
13
|
describe "With a test class" do
|
24
|
-
before
|
14
|
+
before do
|
25
15
|
class FooHistory < ActiveFedora::Base
|
26
16
|
has_metadata 'someData', type: ActiveFedora::SimpleDatastream, autocreate: true do |m|
|
27
17
|
m.field "fubar", :string
|
@@ -46,7 +36,7 @@ describe ActiveFedora::Base do
|
|
46
36
|
end
|
47
37
|
end
|
48
38
|
|
49
|
-
after
|
39
|
+
after do
|
50
40
|
Object.send(:remove_const, :FooHistory)
|
51
41
|
Object.send(:remove_const, :FooAdaptation)
|
52
42
|
Object.send(:remove_const, :FooInherited)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Properties with the same predicate' do
|
4
|
+
|
5
|
+
let(:warningMsg) {"Same predicate (http://purl.org/dc/terms/title) used for properties title1 and title2"}
|
6
|
+
|
7
|
+
it "should warn" do
|
8
|
+
|
9
|
+
# Note that the expect test must be before the class is parsed.
|
10
|
+
expect(ActiveFedora::Base.logger).to receive(:warn).with(warningMsg)
|
11
|
+
|
12
|
+
module TestModel1
|
13
|
+
class Book < ActiveFedora::Base
|
14
|
+
property :title1, predicate: ::RDF::DC.title
|
15
|
+
property :title2, predicate: ::RDF::DC.title
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
describe 'Properties with different predicate' do
|
25
|
+
|
26
|
+
it "should not warn" do
|
27
|
+
|
28
|
+
# Note that the expect test must be before the class is parsed.
|
29
|
+
expect(ActiveFedora::Base.logger).to_not receive(:warn)
|
30
|
+
|
31
|
+
module TestModel2
|
32
|
+
class Book < ActiveFedora::Base
|
33
|
+
property :title1, predicate: ::RDF::DC.title
|
34
|
+
property :title2, predicate: ::RDF::DC.creator
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
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.0.
|
4
|
+
version: 9.0.0.rc3
|
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-01-
|
13
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rsolr
|
@@ -74,14 +74,14 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - "~>"
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 0.
|
77
|
+
version: 0.6.0
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: 0.
|
84
|
+
version: 0.6.0
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: rdf-rdfxml
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -200,14 +200,14 @@ dependencies:
|
|
200
200
|
requirements:
|
201
201
|
- - ">="
|
202
202
|
- !ruby/object:Gem::Version
|
203
|
-
version:
|
203
|
+
version: 2.0.0
|
204
204
|
type: :development
|
205
205
|
prerelease: false
|
206
206
|
version_requirements: !ruby/object:Gem::Requirement
|
207
207
|
requirements:
|
208
208
|
- - ">="
|
209
209
|
- !ruby/object:Gem::Version
|
210
|
-
version:
|
210
|
+
version: 2.0.0
|
211
211
|
- !ruby/object:Gem::Dependency
|
212
212
|
name: rspec
|
213
213
|
requirement: !ruby/object:Gem::Requirement
|
@@ -438,6 +438,7 @@ files:
|
|
438
438
|
- spec/integration/bug_spec.rb
|
439
439
|
- spec/integration/collection_association_spec.rb
|
440
440
|
- spec/integration/complex_rdf_datastream_spec.rb
|
441
|
+
- spec/integration/datastream_rdf_nested_attributes_spec.rb
|
441
442
|
- spec/integration/delete_all_spec.rb
|
442
443
|
- spec/integration/eradicate_spec.rb
|
443
444
|
- spec/integration/fedora_solr_sync_spec.rb
|
@@ -513,6 +514,7 @@ files:
|
|
513
514
|
- spec/unit/om_datastream_spec.rb
|
514
515
|
- spec/unit/persistence_spec.rb
|
515
516
|
- spec/unit/predicates_spec.rb
|
517
|
+
- spec/unit/property_predicate_spec.rb
|
516
518
|
- spec/unit/property_spec.rb
|
517
519
|
- spec/unit/qualified_dublin_core_datastream_spec.rb
|
518
520
|
- spec/unit/query_result_builder_spec.rb
|