active-fedora 1.1.13 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,10 +19,16 @@ class FooHistory < ActiveFedora::Base
19
19
  end
20
20
  end
21
21
 
22
+ @@last_pid = 0
23
+
22
24
  describe ActiveFedora::Base do
25
+
26
+ def increment_pid
27
+ @@last_pid += 1
28
+ end
23
29
 
24
30
  before(:each) do
25
- Fedora::Repository.instance.stubs(:nextid).returns("_nextid_")
31
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
26
32
  @test_object = ActiveFedora::Base.new
27
33
  @test_object.new_object = true
28
34
  end
@@ -141,6 +147,7 @@ describe ActiveFedora::Base do
141
147
  mock_relationship = mock("relationship")
142
148
  mock_rels_ext = mock("rels-ext", :add_relationship)
143
149
  mock_rels_ext.expects(:dirty=).with(true)
150
+ @test_object.expects(:relationship_exists?).returns(false).once()
144
151
  @test_object.expects(:rels_ext).returns(mock_rels_ext).times(2)
145
152
  @test_object.add_relationship("predicate", "object")
146
153
  end
@@ -149,6 +156,7 @@ describe ActiveFedora::Base do
149
156
  mock_ds = mock("Rels-Ext")
150
157
  mock_ds.expects(:add_relationship).times(2)
151
158
  mock_ds.expects(:dirty=).with(true).times(2)
159
+ @test_object.expects(:relationship_exists?).returns(false).times(2)
152
160
  @test_object.datastreams["RELS-EXT"] = mock_ds
153
161
  test_relationships = [ActiveFedora::Relationship.new(:subject => :self, :predicate => :is_member_of, :object => "info:fedora/demo:5"),
154
162
  ActiveFedora::Relationship.new(:subject => :self, :predicate => :is_member_of, :object => "info:fedora/demo:10")]
@@ -156,7 +164,42 @@ describe ActiveFedora::Base do
156
164
  @test_object.add_relationship(rel.predicate, rel.object)
157
165
  end
158
166
  end
159
-
167
+
168
+ it 'should add a relationship to an object only if it does not exist already' do
169
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
170
+ @test_object3 = ActiveFedora::Base.new
171
+ @test_object.add_relationship(:has_part,@test_object3)
172
+ r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:dummy, :object=>@test_object3)
173
+ @test_object.relationships.should == {:self=>{:has_part=>[r.object]}}
174
+ #try adding again and make sure not there twice
175
+ @test_object.add_relationship(:has_part,@test_object3)
176
+ @test_object.relationships.should == {:self=>{:has_part=>[r.object]}}
177
+ end
178
+ end
179
+
180
+ it 'should provide #remove_relationship' do
181
+ @test_object.should respond_to(:remove_relationship)
182
+ end
183
+
184
+ describe '#remove_relationship' do
185
+ it 'should remove a relationship from the relationships hash' do
186
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
187
+ @test_object3 = ActiveFedora::Base.new
188
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
189
+ @test_object4 = ActiveFedora::Base.new
190
+ @test_object.add_relationship(:has_part,@test_object3)
191
+ @test_object.add_relationship(:has_part,@test_object4)
192
+ r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:dummy, :object=>@test_object3)
193
+ r2 = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:dummy, :object=>@test_object4)
194
+ #check both are there
195
+ @test_object.relationships.should == {:self=>{:has_part=>[r.object,r2.object]}}
196
+ @test_object.remove_relationship(:has_part,@test_object3)
197
+ #check only one item removed
198
+ @test_object.relationships.should == {:self=>{:has_part=>[r2.object]}}
199
+ @test_object.remove_relationship(:has_part,@test_object4)
200
+ #check last item removed and predicate removed since now emtpy
201
+ @test_object.relationships.should == {:self=>{}}
202
+ end
160
203
  end
161
204
 
162
205
  it 'should provide #relationships' do
@@ -279,7 +322,7 @@ describe ActiveFedora::Base do
279
322
  solr_doc = @test_object.to_solr
280
323
  solr_doc[:system_create_dt].should eql("cDate")
281
324
  solr_doc[:system_modified_dt].should eql("mDate")
282
- solr_doc[:id].should eql(@test_object.pid)
325
+ solr_doc[:id].should eql("#{@test_object.pid}")
283
326
  end
284
327
 
285
328
  it "should add self.class as the :active_fedora_model" do
@@ -319,7 +362,7 @@ describe ActiveFedora::Base do
319
362
  solr_doc = @test_object.to_solr
320
363
  solr_doc[:system_create_dt].should eql("cDate")
321
364
  solr_doc[:system_modified_dt].should eql("mDate")
322
- solr_doc[:id].should eql(@test_object.pid)
365
+ solr_doc[:id].should eql("#{@test_object.pid}")
323
366
  end
324
367
 
325
368
  it "should omit base metadata and RELS-EXT if :model_only==true" do
@@ -345,7 +388,7 @@ describe ActiveFedora::Base do
345
388
  solr_doc = @test_object.to_solr
346
389
  solr_doc[:system_create_dt].should eql(cdate)
347
390
  solr_doc[:system_modified_dt].should eql(mdate)
348
- solr_doc[:id].should eql(@test_object.pid)
391
+ solr_doc[:id].should eql("#{@test_object.pid}")
349
392
  solr_doc[:active_fedora_model_s].should eql(@test_object.class.inspect)
350
393
 
351
394
  ActiveFedora::SolrService.load_mappings(File.join(File.dirname(__FILE__), "..", "..", "config", "solr_mappings_af_0.1.yml"))
@@ -355,7 +398,7 @@ describe ActiveFedora::Base do
355
398
  end
356
399
  solr_doc[:system_create_date].should eql(cdate)
357
400
  solr_doc[:system_modified_date].should eql(mdate)
358
- solr_doc[:id].should eql(@test_object.pid)
401
+ solr_doc[:id].should eql("#{@test_object.pid}")
359
402
  solr_doc[:active_fedora_model_field].should eql(@test_object.class.inspect)
360
403
  end
361
404
 
@@ -557,6 +600,54 @@ describe ActiveFedora::Base do
557
600
  FooHistory.solr_search("pid: foobar", {:ding=>:dang}).should == {:baz=>:bif}
558
601
  end
559
602
 
603
+ it 'should provide #named_relationships' do
604
+ @test_object.should respond_to(:named_relationships)
605
+ end
606
+
607
+ describe '#named_relationships' do
608
+
609
+ class MockNamedRelationships < ActiveFedora::Base
610
+ has_relationship "testing", :has_part, :type=>ActiveFedora::Base
611
+ has_relationship "testing2", :has_member, :type=>ActiveFedora::Base
612
+ has_relationship "testing_inbound", :has_part, :type=>ActiveFedora::Base, :inbound=>true
613
+ end
614
+
615
+ it 'should return current named relationships' do
616
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
617
+ @test_object2 = MockNamedRelationships.new
618
+ @test_object2.add_relationship(:has_model, ActiveFedora::ContentModel.pid_from_ruby_class(MockNamedRelationships))
619
+ @test_object.add_relationship(:has_model, ActiveFedora::ContentModel.pid_from_ruby_class(ActiveFedora::Base))
620
+ #should return expected named relationships
621
+ @test_object2.named_relationships
622
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[],"testing2"=>[]}}
623
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:dummy,:object=>@test_object})
624
+ @test_object2.add_named_relationship("testing",@test_object)
625
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[r.object],"testing2"=>[]}}
626
+ end
627
+ end
560
628
 
561
-
629
+
630
+ describe '#create_named_relationship_methods' do
631
+ class MockCreateNamedRelationshipMethodsBase < ActiveFedora::Base
632
+ register_named_relationship :self, "testing", :is_part_of, :type=>ActiveFedora::Base
633
+ create_named_relationship_methods "testing"
634
+ end
635
+
636
+ it 'should append and remove using helper methods for each outbound relationship' do
637
+ Fedora::Repository.instance.stubs(:nextid).returns(increment_pid)
638
+ @test_object2 = MockCreateNamedRelationshipMethodsBase.new
639
+ @test_object2.should respond_to(:testing_append)
640
+ @test_object2.should respond_to(:testing_remove)
641
+ #test executing each one to make sure code added is correct
642
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(ActiveFedora::Base)})
643
+ @test_object.add_relationship(r.predicate,r.object)
644
+ @test_object2.add_relationship(r.predicate,r.object)
645
+ @test_object2.testing_append(@test_object)
646
+ #create relationship to access generate_uri method for an object
647
+ r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:dummy, :object=>@test_object)
648
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[r.object]}}
649
+ @test_object2.testing_remove(@test_object)
650
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[]}}
651
+ end
652
+ end
562
653
  end
@@ -20,6 +20,10 @@ describe ActiveFedora::NokogiriDatastream do
20
20
  after(:each) do
21
21
  end
22
22
 
23
+ it "should include the Solrizer::XML::TerminologyBasedSolrizer for .to_solr support" do
24
+ ActiveFedora::NokogiriDatastream.included_modules.should include(Solrizer::XML::TerminologyBasedSolrizer)
25
+ end
26
+
23
27
  describe '#new' do
24
28
  it 'should provide #new' do
25
29
  ActiveFedora::NokogiriDatastream.should respond_to(:new)
@@ -59,7 +63,7 @@ describe ActiveFedora::NokogiriDatastream do
59
63
  # In other words, { "fubar"=>"dork" } should have the same effect as { "fubar"=>{"0"=>"dork"} }
60
64
  result = @mods_ds.update_indexed_attributes( { [{":person"=>"0"}, "role"]=>"the role" } )
61
65
  result.should == {"person_0_role"=>{"0"=>"the role"}}
62
- @mods_ds.property_values('//oxns:name[@type="personal"][1]/oxns:role').first.should == "the role"
66
+ @mods_ds.term_values('//oxns:name[@type="personal"][1]/oxns:role').first.should == "the role"
63
67
  end
64
68
  it "should do nothing if field key is a string (must be an array or symbol). Will not accept xpath queries!" do
65
69
  xml_before = @mods_ds.to_xml
@@ -119,24 +123,36 @@ describe ActiveFedora::NokogiriDatastream do
119
123
  # end
120
124
  #
121
125
  # it "should allow deleting of values and should delete values so that to_xml does not return emtpy nodes" do
122
- # att= {"fubar"=>{"-1"=>"mork", "0"=>"york", "1"=>"mangle"}}
123
- # @test_ds.update_indexed_attributes(att)
124
- # @test_ds.fubar_values.should == ['mork', 'york', 'mangle']
126
+ # att= {[{"person"=>"0"},"description"]=>{"-1"=>"mork", "0"=>"york", "1"=>"mangle"}}
127
+ # @mods_ds.update_indexed_attributes(att)
128
+ # @mods_ds.fubar_values.should == ['mork', 'york', 'mangle']
125
129
  # rexml = REXML::Document.new(@test_ds.to_xml)
126
130
  # #puts rexml.root.elements.each {|el| el.to_s}
127
131
  # #puts rexml.root.elements.to_a.inspect
128
132
  # rexml.root.elements.to_a.length.should == 3
129
- # @test_ds.update_indexed_attributes({"fubar"=>{"1"=>""}})
130
- # @test_ds.fubar_values.should == ['mork', 'mangle']
133
+ # @mods_ds.update_indexed_attributes({[{"person"=>"0"},"description"]=>{"1"=>""}})
134
+ # @mods_ds.fubar_values.should == ['mork', 'mangle']
131
135
  # rexml = REXML::Document.new(@test_ds.to_xml)
132
136
  # rexml.root.elements.to_a.length.should == 2
133
- # @test_ds.update_indexed_attributes({"fubar"=>{"0"=>:delete}})
134
- # @test_ds.fubar_values.should == ['mangle']
137
+ # @mods_ds.update_indexed_attributes({[{"person"=>"0"},"description"]=>{"0"=>:delete}})
138
+ # @mods_ds.fubar_values.should == ['mangle']
135
139
  # rexml = REXML::Document.new(@test_ds.to_xml)
136
140
  # rexml.root.elements.to_a.length.should == 1
137
- #
141
+ # end
142
+ it "should allow deleting of values and should delete values so that to_xml does not return emtpy nodes" do
143
+ att= {[{"person"=>"0"},"description"]=>{"0"=>"york", "1"=>"mangle","2"=>"mork"}}
144
+ @mods_ds.update_indexed_attributes(att)
145
+ @mods_ds.get_values([{"person"=>"0"},"description"]).should == ['york', 'mangle', 'mork']
146
+
147
+ @mods_ds.update_indexed_attributes({[{"person"=>"0"},"description"]=>{"1"=>""}})
148
+ @mods_ds.get_values([{"person"=>"0"},"description"]).should == ['york', 'mork']
149
+
150
+ @mods_ds.update_indexed_attributes({[{"person"=>"0"},"description"]=>{"0"=>:delete}})
151
+ @mods_ds.get_values([{"person"=>"0"},"description"]).should == ['mork']
152
+ end
153
+ # it "should delete values so that to_xml does not return emtpy nodes" do
138
154
  # @test_ds.fubar_values = ["val1", nil, "val2"]
139
- # @test_ds.update_indexed_attributes({"fubar"=>{"1"=>""}})
155
+ # @test_ds.update_indexed_attributes({{[{"person"=>"0"},"description"]=>{"1"=>""}})
140
156
  # @test_ds.fubar_values.should == ["val1", "val2"]
141
157
  # end
142
158
 
@@ -154,12 +170,12 @@ describe ActiveFedora::NokogiriDatastream do
154
170
  end
155
171
 
156
172
  it "should call lookup with field_name and return the text values from each resulting node" do
157
- @mods_ds.expects(:property_values).with("--my xpath--").returns(["value1", "value2"])
173
+ @mods_ds.expects(:term_values).with("--my xpath--").returns(["value1", "value2"])
158
174
  @mods_ds.get_values("--my xpath--").should == ["value1", "value2"]
159
175
  end
160
- it "should assume that field_name that are strings are xpath queries" do
176
+ it "should assume that field_names that are strings are xpath queries" do
161
177
  ActiveFedora::NokogiriDatastream.expects(:accessor_xpath).never
162
- @mods_ds.expects(:property_values).with("--my xpath--").returns(["abstract1", "abstract2"])
178
+ @mods_ds.expects(:term_values).with("--my xpath--").returns(["abstract1", "abstract2"])
163
179
  @mods_ds.get_values("--my xpath--").should == ["abstract1", "abstract2"]
164
180
  end
165
181
  it "should assume field_names that are symbols or arrays are pointers to accessors declared in this datastreams model" do
@@ -263,136 +279,4 @@ describe ActiveFedora::NokogiriDatastream do
263
279
  end
264
280
  end
265
281
 
266
-
267
- describe ".to_solr" do
268
-
269
- after(:all) do
270
- # Revert to default mappings after running tests
271
- ActiveFedora::SolrService.load_mappings
272
- end
273
-
274
- it "should iterate through the class accessors, calling .solrize_accessor on each and passing in the solr doc" do
275
- mock_accessors = {:accessor1=>:accessor1_info, :accessor2=>:accessor2_info}
276
- ActiveFedora::NokogiriDatastream.stubs(:accessors).returns(mock_accessors)
277
- doc = Solr::Document.new
278
- mock_accessors.each_pair do |k,v|
279
- @test_ds.expects(:solrize_accessor).with(k, v, :solr_doc=>doc)
280
- end
281
- @test_ds.to_solr(doc)
282
- end
283
-
284
- it "should provide .to_solr and return a SolrDocument" do
285
- @test_ds.should respond_to(:to_solr)
286
- @test_ds.to_solr.should be_kind_of(Solr::Document)
287
- end
288
-
289
- it "should optionally allow you to provide the Solr::Document to add fields to and return that document when done" do
290
- doc = Solr::Document.new
291
- @test_ds.to_solr(doc).should equal(doc)
292
- end
293
-
294
- end
295
-
296
- describe ".solrize_accessor" do
297
- before(:all) do
298
- class AccessorizedDs < ActiveFedora::NokogiriDatastream
299
-
300
- root_property :mods, "mods", "http://www.loc.gov/mods/v3", :attributes=>["id", "version"], :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
301
-
302
- accessor :title_info, :relative_xpath=>'oxns:titleInfo', :children=>[
303
- {:main_title=>{:relative_xpath=>'oxns:title'}},
304
- {:language =>{:relative_xpath=>{:attribute=>"lang"} }}
305
- ]
306
- accessor :finnish_title_info, :relative_xpath=>'oxns:titleInfo[@lang="finnish"]', :children=>[
307
- {:main_title=>{:relative_xpath=>'oxns:title'}},
308
- {:language =>{:relative_xpath=>{:attribute=>"lang"} }}
309
- ]
310
- accessor :abstract
311
- accessor :topic_tag, :relative_xpath=>'oxns:subject/oxns:topic'
312
- accessor :person, :relative_xpath=>'oxns:name[@type="personal"]', :children=>[
313
- {:last_name=>{:relative_xpath=>'oxns:namePart[@type="family"]'}},
314
- {:first_name=>{:relative_xpath=>'oxns:namePart[@type="given"]'}},
315
- {:institution=>{:relative_xpath=>'oxns:affiliation'}},
316
- {:role=>{:children=>[
317
- {:text=>{:relative_xpath=>'oxns:roleTerm[@type="text"]'}},
318
- {:code=>{:relative_xpath=>'oxns:roleTerm[@type="code"]'}}
319
- ]}}
320
- ]
321
- end
322
- end
323
-
324
- before(:each) do
325
- file = fixture(File.join("mods_articles", "hydrangea_article1.xml"))
326
- @accessorized_ds = AccessorizedDs.new(:blob=>file)
327
- end
328
-
329
- it "should perform a lookup and iterate over nodes in the result set calling solrize_node then calling solrize_accessor on any of the children, adding accessor_name & node index to parents array" do
330
- mock_title_info_set = ["TI1", "TI2"]
331
- mock_main_title_set = ["main title"]
332
- mock_language_set = ["language"]
333
-
334
- solr_doc = Solr::Document.new
335
-
336
- AccessorizedDs.expects(:accessor_xpath).with( :title_info ).returns("title_info_xpath")
337
- @accessorized_ds.expects(:lookup).with( "title_info_xpath" ).returns(mock_title_info_set)
338
-
339
- mock_title_info_set.each do |tin|
340
- node_index = mock_title_info_set.index(tin)
341
- @accessorized_ds.expects(:solrize_node).with(tin, [:title_info], solr_doc)
342
-
343
- # Couldn't mock the recursive calls to solrize_accessor without preventing the initial one, so was forced to mock out the whole recursive stack.
344
- # @accessorized_ds.expects(:solrize_accessor).with(:main_title, AccessorizedDs.accessors[:title_info][:children][:main_title], :parents=>[{:title_info=>node_index}])
345
- # @accessorized_ds.expects(:solrize_accessor).with(:language, AccessorizedDs.accessors[:title_info][:children][:language], :parents=>[{:title_info=>node_index}])
346
- AccessorizedDs.expects(:accessor_xpath).with( {:title_info=>node_index}, :main_title ).returns("title_info_main_title_xpath")
347
- AccessorizedDs.expects(:accessor_xpath).with( {:title_info=>node_index}, :language ).returns("title_info_language_xpath")
348
- @accessorized_ds.expects(:lookup).with( "title_info_main_title_xpath" ).returns(mock_main_title_set)
349
- @accessorized_ds.expects(:lookup).with( "title_info_language_xpath" ).returns(mock_language_set)
350
- @accessorized_ds.expects(:solrize_node).with("main title", [{:title_info=>node_index}, :main_title], solr_doc)
351
- @accessorized_ds.expects(:solrize_node).with("language", [{:title_info=>node_index}, :language], solr_doc)
352
- end
353
-
354
- @accessorized_ds.solrize_accessor(:title_info, AccessorizedDs.accessors[:title_info], :solr_doc=>solr_doc)
355
-
356
- end
357
-
358
- it "should not call solrize_accessor once it reaches an accessor with no children accessors set" do
359
- pending "not sure how to test for this"
360
- @accessorized_ds.solrize_accessor(:text, AccessorizedDs.accessor_info( [{:person=>1}, :last_name] ), :parents=>[{:person=>1}])
361
- end
362
-
363
- it "should use values form parents array when requesting accessor_xpath and when generating solr field names" do
364
- parents_array = [{:person=>0}, {:role=>1}]
365
- AccessorizedDs.accessors[:person][:children][:role][:children][:text]
366
-
367
- # This should catch the "submitter" roleTerm from the second role node within the first person node and put it into a solr field called "person_0_role_2_text_0_t" and a solr field called "person_role_text_t"
368
- @accessorized_ds.solrize_accessor(:text, AccessorizedDs.accessor_info( *parents_array + [:text] ), :parents=>parents_array)
369
- end
370
-
371
- it "should use Solr mappings to generate field names" do
372
-
373
- solr_doc = @accessorized_ds.to_solr
374
- #should have these
375
-
376
- solr_doc[:abstract_t].should == "ABSTRACT"
377
- solr_doc[:title_info_1_language_t].should == "finnish"
378
- solr_doc[:person_1_role_0_text_t].should == "teacher"
379
- solr_doc[:finnish_title_info_language_t].should == "finnish"
380
- solr_doc[:finnish_title_info_main_title_t].should == "Artikkelin otsikko Hydrangea artiklan 1"
381
-
382
- # solr_doc[:mydate_date].should == "fake-date"
383
- #
384
- # solr_doc[:publisher_t].should be_nil
385
- # solr_doc[:coverage_t].should be_nil
386
- # solr_doc[:creation_date_dt].should be_nil
387
- # solr_doc.should == ""
388
-
389
- end
390
- end
391
-
392
- describe ".solrize_node" do
393
- it "should create a solr field containing node.text"
394
- it "should create hierarchical field entries if parents is not empty"
395
- it "should only create one node if parents is empty"
396
- end
397
-
398
282
  end
@@ -7,8 +7,20 @@ require 'xmlsimple'
7
7
  #include ActiveFedora::SemanticNode
8
8
  #include Mocha::Standalone
9
9
 
10
+ @@last_pid = 0
11
+
12
+ class SpecNode2
13
+ include ActiveFedora::SemanticNode
14
+
15
+ attr_accessor :pid
16
+ end
17
+
10
18
  describe ActiveFedora::SemanticNode do
11
19
 
20
+ def increment_pid
21
+ @@last_pid += 1
22
+ end
23
+
12
24
  before(:all) do
13
25
  @pid = "test:sample_pid"
14
26
  @uri = "info:fedora/#{@pid}"
@@ -18,10 +30,16 @@ describe ActiveFedora::SemanticNode do
18
30
  end
19
31
 
20
32
  before(:each) do
21
- class SpecNode
33
+ class SpecNode
22
34
  include ActiveFedora::SemanticNode
35
+
36
+ attr_accessor :pid
23
37
  end
38
+
24
39
  @node = SpecNode.new
40
+ @node.pid = increment_pid
41
+ @test_object = SpecNode2.new
42
+ @test_object.pid = increment_pid
25
43
  @stub_relationship = stub("mock_relationship", :subject => @pid, :predicate => "isMemberOf", :object => "demo:8", :class => ActiveFedora::Relationship)
26
44
  @test_relationship = ActiveFedora::Relationship.new(:subject => @pid, :predicate => "isMemberOf", :object => "demo:9")
27
45
  @test_relationship1 = ActiveFedora::Relationship.new(:subject => :self, :predicate => :is_member_of, :object => "demo:10")
@@ -31,6 +49,26 @@ describe ActiveFedora::SemanticNode do
31
49
 
32
50
  after(:each) do
33
51
  Object.send(:remove_const, :SpecNode)
52
+ begin
53
+ @test_object.delete
54
+ rescue
55
+ end
56
+ begin
57
+ @test_object2.delete
58
+ rescue
59
+ end
60
+ begin
61
+ @test_object3.delete
62
+ rescue
63
+ end
64
+ begin
65
+ @test_object4.delete
66
+ rescue
67
+ end
68
+ begin
69
+ @test_object5.delete
70
+ rescue
71
+ end
34
72
  end
35
73
 
36
74
  it 'should provide predicate mappings for entire Fedora Relationship Ontology' do
@@ -118,6 +156,64 @@ describe ActiveFedora::SemanticNode do
118
156
  containers_result.should include("container:B")
119
157
  end
120
158
 
159
+ class MockHasRelationship < SpecNode2
160
+ has_relationship "testing", :has_part, :type=>SpecNode2
161
+ has_relationship "testing2", :has_member, :type=>SpecNode2
162
+ has_relationship "testing_inbound", :has_part, :type=>SpecNode2, :inbound=>true
163
+ end
164
+
165
+ #can only duplicate predicates if not both inbound or not both outbound
166
+ class MockHasRelationshipDuplicatePredicate < SpecNode2
167
+ has_relationship "testing", :has_member, :type=>SpecNode2
168
+ had_exception = false
169
+ begin
170
+ has_relationship "testing2", :has_member, :type=>SpecNode2
171
+ rescue
172
+ had_exception = true
173
+ end
174
+ raise "Did not raise exception if duplicate predicate used" unless had_exception
175
+ end
176
+
177
+ #can only duplicate predicates if not both inbound or not both outbound
178
+ class MockHasRelationshipDuplicatePredicate2 < SpecNode2
179
+ has_relationship "testing", :has_member, :type=>SpecNode2, :inbound=>true
180
+ had_exception = false
181
+ begin
182
+ has_relationship "testing2", :has_member, :type=>SpecNode2, :inbound=>true
183
+ rescue
184
+ had_exception = true
185
+ end
186
+ raise "Did not raise exception if duplicate predicate used" unless had_exception
187
+ end
188
+
189
+ it 'should create relationship descriptions both inbound and outbound' do
190
+ @test_object2 = MockHasRelationship.new
191
+ @test_object2.pid = increment_pid
192
+ @test_object2.stubs(:testing_inbound).returns({})
193
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
194
+ @test_object2.add_relationship(r)
195
+ @test_object2.should respond_to(:testing_append)
196
+ @test_object2.should respond_to(:testing_remove)
197
+ @test_object2.should respond_to(:testing2_append)
198
+ @test_object2.should respond_to(:testing2_remove)
199
+ #make sure append/remove method not created for inbound rel
200
+ @test_object2.should_not respond_to(:testing_inbound_append)
201
+ @test_object2.should_not respond_to(:testing_inbound_remove)
202
+
203
+ @test_object2.named_relationships_desc.should ==
204
+ {:inbound=>{"testing_inbound"=>{:type=>SpecNode2,
205
+ :predicate=>:has_part,
206
+ :inbound=>true,
207
+ :singular=>nil}},
208
+ :self=>{"testing"=>{:type=>SpecNode2,
209
+ :predicate=>:has_part,
210
+ :inbound=>false,
211
+ :singular=>nil},
212
+ "testing2"=>{:type=>SpecNode2,
213
+ :predicate=>:has_member,
214
+ :inbound=>false,
215
+ :singular=>nil}}}
216
+ end
121
217
  end
122
218
 
123
219
  describe '#create_inbound_relationship_finders' do
@@ -134,6 +230,7 @@ describe ActiveFedora::SemanticNode do
134
230
  SpecNode.create_inbound_relationship_finders("containers", :is_member_of, :inbound => true)
135
231
  local_node.should respond_to(:containers_ids)
136
232
  local_node.should respond_to(:containers)
233
+ local_node.should respond_to(:containers_from_solr)
137
234
  end
138
235
 
139
236
  it "resulting finder should search against solr and use Model#load_instance to build an array of objects" do
@@ -195,7 +292,8 @@ describe ActiveFedora::SemanticNode do
195
292
  local_node.should_not respond_to(:containers)
196
293
  SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
197
294
  local_node.should respond_to(:containers_ids)
198
- local_node.should respond_to(:containers)
295
+ local_node.should respond_to(:containers)
296
+ local_node.should respond_to(:containers_from_solr)
199
297
  end
200
298
 
201
299
  describe " resulting finder" do
@@ -348,4 +446,383 @@ describe ActiveFedora::SemanticNode do
348
446
  @node.should respond_to(:outbound_relationships)
349
447
  end
350
448
 
449
+
450
+ it 'should provide #unregister_triple' do
451
+ @test_object.should respond_to(:unregister_triple)
452
+ end
453
+
454
+ describe '#unregister_triple' do
455
+ it 'should remove a triple from the relationships hash' do
456
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>"info:fedora/3"})
457
+ r2 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>"info:fedora/4"})
458
+ @test_object.add_relationship(r)
459
+ @test_object.add_relationship(r2)
460
+ #check both are there
461
+ @test_object.relationships.should == {:self=>{:has_part=>[r.object,r2.object]}}
462
+ @test_object.unregister_triple(r.subject,r.predicate,r.object)
463
+ #check returns false if relationship does not exist and does nothing
464
+ @test_object.unregister_triple(:self,:has_member,r2.object).should == false
465
+ #check only one item removed
466
+ @test_object.relationships.should == {:self=>{:has_part=>[r2.object]}}
467
+ @test_object.unregister_triple(r2.subject,r2.predicate,r2.object)
468
+ #check last item removed and predicate removed since now emtpy
469
+ @test_object.relationships.should == {:self=>{}}
470
+
471
+ end
472
+ end
473
+
474
+ it 'should provide #remove_relationship' do
475
+ @test_object.should respond_to(:remove_relationship)
476
+ end
477
+
478
+ describe '#remove_relationship' do
479
+ it 'should remove a relationship from the relationships hash' do
480
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>"info:fedora/3"})
481
+ r2 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>"info:fedora/4"})
482
+ @test_object.add_relationship(r)
483
+ @test_object.add_relationship(r2)
484
+ #check both are there
485
+ @test_object.relationships.should == {:self=>{:has_part=>[r.object,r2.object]}}
486
+ @test_object.remove_relationship(r)
487
+ #check returns false if relationship does not exist and does nothing with different predicate
488
+ rBad = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_member,:object=>"info:fedora/4"})
489
+ @test_object.remove_relationship(rBad).should == false
490
+ #check only one item removed
491
+ @test_object.relationships.should == {:self=>{:has_part=>[r2.object]}}
492
+ @test_object.remove_relationship(r2)
493
+ #check last item removed and predicate removed since now emtpy
494
+ @test_object.relationships.should == {:self=>{}}
495
+
496
+ end
497
+ end
498
+
499
+ it 'should provide #named_relationship_predicates' do
500
+ @test_object.should respond_to(:named_relationship_predicates)
501
+ end
502
+
503
+ describe '#named_relationship_predicates' do
504
+ class MockNamedRelationshipPredicates < SpecNode2
505
+ has_relationship "testing", :has_part, :type=>SpecNode2
506
+ has_relationship "testing2", :has_member, :type=>SpecNode2
507
+ has_relationship "testing_inbound", :has_part, :type=>SpecNode2, :inbound=>true
508
+ end
509
+
510
+ it 'should return a map of subject to relationship name to fedora ontology relationship predicate' do
511
+ @test_object2 = MockNamedRelationshipPredicates.new
512
+ @test_object2.pid = increment_pid
513
+ model_rel = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(MockNamedRelationshipPredicates)})
514
+ @test_object2.add_relationship(model_rel)
515
+ @test_object3 = SpecNode2.new
516
+ @test_object3.pid = increment_pid
517
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
518
+ @test_object3.add_relationship(r)
519
+ @test_object4 = SpecNode2.new
520
+ @test_object4.pid = increment_pid
521
+ @test_object4.add_relationship(r)
522
+ @test_object.add_relationship(r)
523
+ #create relationships that mirror "testing"
524
+ r3 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>@test_object3})
525
+ r4 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>@test_object4})
526
+ @test_object2.add_relationship(r3)
527
+ @test_object2.add_relationship(r4)
528
+ #create relationship mirroring testing2
529
+ r5 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_member,:object=>@test_object})
530
+ @test_object2.add_relationship(r5)
531
+ @test_object2.named_relationship_predicates.should == {:self=>{"testing"=>:has_part,"testing2"=>:has_member},
532
+ :inbound=>{"testing_inbound"=>:has_part}}
533
+
534
+ end
535
+ end
536
+
537
+ it 'should provide #kind_of_model?' do
538
+ @test_object.should respond_to(:kind_of_model?)
539
+ end
540
+
541
+ describe '#kind_of_model?' do
542
+ it 'should check if current object is the kind of model class supplied' do
543
+ #has_model relationship does not get created until save called
544
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
545
+ @test_object.add_relationship(r)
546
+ @test_object.kind_of_model?(SpecNode2).should == true
547
+ end
548
+ end
549
+
550
+ it 'should provide #assert_kind_of_model' do
551
+ @test_object.should respond_to(:assert_kind_of_model)
552
+ end
553
+
554
+ describe '#assert_kind_of_model' do
555
+ it 'should correctly assert if an object is the type of model supplied' do
556
+ @test_object3 = SpecNode2.new
557
+ @test_object3.pid = increment_pid
558
+ #has_model relationship does not get created until save called so need to add the has model rel here, is fine since not testing save
559
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
560
+ @test_object.add_relationship(r)
561
+ @test_object3.assert_kind_of_model('object',@test_object,SpecNode2)
562
+ end
563
+ end
564
+
565
+ it 'should provide #class_from_name' do
566
+ @test_object.should respond_to(:class_from_name)
567
+ end
568
+
569
+ describe '#class_from_name' do
570
+ it 'should return a class constant for a string passed in' do
571
+ @test_object.class_from_name("SpecNode2").should == SpecNode2
572
+ end
573
+ end
574
+
575
+ it 'should provide #relationship_exists?' do
576
+ @test_object.should respond_to(:relationship_exists?)
577
+ end
578
+
579
+ describe '#relationship_exists?' do
580
+ it 'should return true if a relationship does exist' do
581
+ @test_object3 = SpecNode2.new
582
+ @test_object3.pid = increment_pid
583
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_member,:object=>@test_object3})
584
+ @test_object.relationship_exists?(r.subject,r.predicate,r.object).should == false
585
+ @test_object.add_relationship(r)
586
+ @test_object.relationship_exists?(r.subject,r.predicate,r.object).should == true
587
+ end
588
+ end
589
+
590
+ it 'should provide #named_relationships' do
591
+ @test_object.should respond_to(:named_relationships)
592
+ end
593
+
594
+ describe '#named_relationships' do
595
+
596
+ class MockNamedRelationships3 < SpecNode2
597
+ has_relationship "testing", :has_part, :type=>SpecNode2
598
+ has_relationship "testing2", :has_member, :type=>SpecNode2
599
+ has_relationship "testing_inbound", :has_part, :type=>SpecNode2, :inbound=>true
600
+ end
601
+
602
+ it 'should return current named relationships' do
603
+ @test_object2 = MockNamedRelationships3.new
604
+ @test_object2.pid = increment_pid
605
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(MockNamedRelationships3)})
606
+ @test_object2.add_relationship(r)
607
+ r2 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
608
+ @test_object.add_relationship(r2)
609
+ #should return expected named relationships
610
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[],"testing2"=>[]},:inbound=>{"testing_inbound"=>[]}}
611
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>@test_object})
612
+ @test_object2.add_relationship(r)
613
+ @test_object2.named_relationships.should == {:self=>{"testing"=>[r.object],"testing2"=>[]},:inbound=>{"testing_inbound"=>[]}}
614
+ end
615
+
616
+ it 'should automatically update the named_relationships if relationships has changed (no refresh of named_relationships hash unless relationships hash has changed)' do
617
+ @test_object3 = MockNamedRelationships3.new
618
+ @test_object3.pid = increment_pid
619
+ r = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(MockNamedRelationships3)})
620
+ @test_object3.add_relationship(r)
621
+ r2 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_model,:object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2)})
622
+ @test_object.add_relationship(r2)
623
+ #should return expected named relationships
624
+ @test_object3.named_relationships.should == {:self=>{"testing"=>[],"testing2"=>[]},:inbound=>{"testing_inbound"=>[]}}
625
+ r3 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_part,:object=>@test_object})
626
+ @test_object3.add_relationship(r3)
627
+ @test_object3.named_relationships.should == {:self=>{"testing"=>[r3.object],"testing2"=>[]},:inbound=>{"testing_inbound"=>[]}}
628
+ r4 = ActiveFedora::Relationship.new({:subject=>:self,:predicate=>:has_member,:object=>"3"})
629
+ @test_object3.add_relationship(r4)
630
+ @test_object3.named_relationships.should == {:self=>{"testing"=>[r3.object],"testing2"=>[r4.object]},:inbound=>{"testing_inbound"=>[]}}
631
+ end
632
+ end
633
+
634
+ it 'should provide #assert_kind_of' do
635
+ @test_object.should respond_to(:assert_kind_of)
636
+ end
637
+
638
+ describe '#assert_kind_of' do
639
+ it 'should raise an exception if object supplied is not the correct type' do
640
+ had_exception = false
641
+ begin
642
+ @test_object.assert_kind_of 'SpecNode2', @test_object, ActiveFedora::Base
643
+ rescue
644
+ had_exception = true
645
+ end
646
+ raise "Failed to throw exception with kind of mismatch" unless had_exception
647
+ #now should not throw any exception
648
+ @test_object.assert_kind_of 'SpecNode2', @test_object, SpecNode2
649
+ end
650
+ end
651
+
652
+ it 'should provide #relationship_names' do
653
+ @test_object.should respond_to(:relationship_names)
654
+ end
655
+
656
+ describe '#relationship_names' do
657
+ class MockRelationshipNames < SpecNode2
658
+ has_relationship "testing", :has_part, :type=>SpecNode2
659
+ has_relationship "testing2", :has_member, :type=>SpecNode2
660
+ has_relationship "testing_inbound", :has_part, :type=>SpecNode2, :inbound=>true
661
+ has_relationship "testing_inbound2", :has_member, :type=>SpecNode2, :inbound=>true
662
+ end
663
+
664
+ it 'should return an array of relationship names for this model' do
665
+ @test_object2 = MockRelationshipNames.new
666
+ @test_object2.pid = increment_pid
667
+ @test_object2.relationship_names.include?("testing").should == true
668
+ @test_object2.relationship_names.include?("testing2").should == true
669
+ @test_object2.relationship_names.include?("testing_inbound").should == true
670
+ @test_object2.relationship_names.include?("testing_inbound2").should == true
671
+ @test_object2.relationship_names.size.should == 4
672
+ end
673
+ end
674
+
675
+ it 'should provide #inbound_relationship_names' do
676
+ @test_object.should respond_to(:inbound_relationship_names)
677
+ end
678
+
679
+ describe '#inbound_relationship_names' do
680
+ it 'should return an array of inbound relationship names for this model' do
681
+ @test_object2 = MockRelationshipNames.new
682
+ @test_object2.pid = increment_pid
683
+ @test_object2.inbound_relationship_names.include?("testing_inbound").should == true
684
+ @test_object2.inbound_relationship_names.include?("testing_inbound2").should == true
685
+ @test_object2.inbound_relationship_names.size.should == 2
686
+ end
687
+ end
688
+
689
+ it 'should provide #outbound_relationship_names' do
690
+ @test_object.should respond_to(:outbound_relationship_names)
691
+ end
692
+
693
+ describe '#outbound_relationship_names' do
694
+ it 'should return an array of outbound relationship names for this model' do
695
+ @test_object2 = MockRelationshipNames.new
696
+ @test_object2.pid = increment_pid
697
+ @test_object2.outbound_relationship_names.include?("testing").should == true
698
+ @test_object2.outbound_relationship_names.include?("testing2").should == true
699
+ @test_object2.outbound_relationship_names.size.should == 2
700
+ end
701
+ end
702
+
703
+ it 'should provide #named_outbound_relationships' do
704
+ @test_object.should respond_to(:named_outbound_relationships)
705
+ end
706
+
707
+ describe '#named_outbound_relationships' do
708
+ it 'should return hash of outbound relationship names to arrays of object uri' do
709
+ @test_object2 = MockRelationshipNames.new
710
+ @test_object2.pid = increment_pid
711
+ @test_object2.named_outbound_relationships.should == {"testing"=>[],
712
+ "testing2"=>[]}
713
+ end
714
+ end
715
+
716
+ it 'should provide #named_inbound_relationships' do
717
+ #testing execution of this in integration since touches solr
718
+ @test_object.should respond_to(:named_inbound_relationships)
719
+ end
720
+
721
+ it 'should provide #named_relationship' do
722
+ @test_object.should respond_to(:named_relationship)
723
+ end
724
+
725
+ describe '#named_relationship' do
726
+ it 'should return an array of object uri for a given relationship name' do
727
+ @test_object2 = MockRelationshipNames.new
728
+ @test_object2.pid = increment_pid
729
+ r = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:has_model, :object=>ActiveFedora::ContentModel.pid_from_ruby_class(MockRelationshipNames))
730
+ @test_object2.add_relationship(r)
731
+ @test_object3 = SpecNode2.new
732
+ @test_object3.pid = increment_pid
733
+ r2 = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:has_model, :object=>ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode2))
734
+ @test_object3.add_relationship(r2)
735
+ @test_object4 = SpecNode2.new
736
+ @test_object4.pid = increment_pid
737
+ @test_object4.add_relationship(r2)
738
+ @test_object.add_relationship(r2)
739
+ #add relationships that mirror 'testing' and 'testing2'
740
+ r3 = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:has_part, :object=>@test_object3)
741
+ r4 = ActiveFedora::Relationship.new(:subject=>:self, :predicate=>:has_member, :object=>@test_object4)
742
+ @test_object2.add_relationship(r3)
743
+ @test_object2.add_relationship(r4)
744
+ @test_object2.named_relationship("testing").should == [r3.object]
745
+ end
746
+ end
747
+
748
+ describe ActiveFedora::SemanticNode::ClassMethods do
749
+
750
+ after(:each) do
751
+ begin
752
+ @test_object2.delete
753
+ rescue
754
+ end
755
+ end
756
+
757
+ describe '#named_relationships_desc' do
758
+ it 'should initialize named_relationships_desc to a new hash containing self' do
759
+ @test_object2 = SpecNode2.new
760
+ @test_object2.pid = increment_pid
761
+ @test_object2.named_relationships_desc.should == {:self=>{}}
762
+ end
763
+ end
764
+
765
+ describe '#register_named_subject' do
766
+
767
+ class MockRegisterNamedSubject < SpecNode2
768
+ register_named_subject :test
769
+ end
770
+
771
+ it 'should add a new named subject to the named relationships only if it does not already exist' do
772
+ @test_object2 = MockRegisterNamedSubject.new
773
+ @test_object2.pid = increment_pid
774
+ @test_object2.named_relationships_desc.should == {:self=>{}, :test=>{}}
775
+ end
776
+ end
777
+
778
+ describe '#register_named_relationship' do
779
+
780
+ class MockRegisterNamedRelationship < SpecNode2
781
+ register_named_relationship :self, "testing", :is_part_of, :type=>SpecNode2
782
+ register_named_relationship :inbound, "testing2", :has_part, :type=>SpecNode2
783
+ end
784
+
785
+ it 'should add a new named subject to the named relationships only if it does not already exist' do
786
+ @test_object2 = MockRegisterNamedRelationship.new
787
+ @test_object2.pid = increment_pid
788
+ @test_object2.named_relationships_desc.should == {:inbound=>{"testing2"=>{:type=>SpecNode2, :predicate=>:has_part}}, :self=>{"testing"=>{:type=>SpecNode2, :predicate=>:is_part_of}}}
789
+ end
790
+ end
791
+
792
+ describe '#create_named_relationship_methods' do
793
+ class MockCreateNamedRelationshipMethods < SpecNode2
794
+ register_named_relationship :self, "testing", :is_part_of, :type=>SpecNode2
795
+ create_named_relationship_methods "testing"
796
+ end
797
+
798
+ it 'should create an append and remove method for each outbound relationship' do
799
+ @test_object2 = MockCreateNamedRelationshipMethods.new
800
+ @test_object2.pid = increment_pid
801
+ @test_object2.should respond_to(:testing_append)
802
+ @test_object2.should respond_to(:testing_remove)
803
+ #test execution in base_spec since method definitions include methods in ActiveFedora::Base
804
+ end
805
+ end
806
+
807
+ describe '#def named_predicate_exists_with_different_name?' do
808
+
809
+ it 'should return true if a predicate exists for same subject and different name but not different subject' do
810
+ class MockPredicateExists < SpecNode2
811
+ has_relationship "testing", :has_part, :type=>SpecNode2
812
+ has_relationship "testing2", :has_member, :type=>SpecNode2
813
+ has_relationship "testing_inbound", :is_part_of, :type=>SpecNode2, :inbound=>true
814
+
815
+ named_predicate_exists_with_different_name?(:self,"testing",:has_part).should == false
816
+ named_predicate_exists_with_different_name?(:self,"testing3",:has_part).should == true
817
+ named_predicate_exists_with_different_name?(:inbound,"testing",:has_part).should == false
818
+ named_predicate_exists_with_different_name?(:self,"testing2",:has_member).should == false
819
+ named_predicate_exists_with_different_name?(:self,"testing3",:has_member).should == true
820
+ named_predicate_exists_with_different_name?(:inbound,"testing2",:has_member).should == false
821
+ named_predicate_exists_with_different_name?(:self,"testing_inbound",:is_part_of).should == false
822
+ named_predicate_exists_with_different_name?(:inbound,"testing_inbound",:is_part_of).should == false
823
+ named_predicate_exists_with_different_name?(:inbound,"testing_inbound2",:is_part_of).should == true
824
+ end
825
+ end
826
+ end
827
+ end
351
828
  end