active-fedora 3.2.0.pre1 → 3.2.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/Gemfile.lock +1 -1
  2. data/History.txt +3 -1
  3. data/lib/active_fedora.rb +3 -3
  4. data/lib/active_fedora/associations.rb +0 -2
  5. data/lib/active_fedora/associations/association_collection.rb +15 -1
  6. data/lib/active_fedora/associations/belongs_to_association.rb +5 -1
  7. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +5 -1
  8. data/lib/active_fedora/base.rb +36 -92
  9. data/lib/active_fedora/datastream.rb +1 -2
  10. data/lib/active_fedora/file_management.rb +73 -0
  11. data/lib/active_fedora/metadata_datastream_helper.rb +3 -1
  12. data/lib/active_fedora/model.rb +6 -18
  13. data/lib/active_fedora/relationships.rb +634 -0
  14. data/lib/active_fedora/samples/special_thing.rb +4 -4
  15. data/lib/active_fedora/semantic_node.rb +97 -236
  16. data/lib/active_fedora/version.rb +1 -1
  17. data/spec/integration/base_file_management_spec.rb +1 -0
  18. data/spec/integration/base_spec.rb +114 -68
  19. data/spec/integration/full_featured_model_spec.rb +0 -1
  20. data/spec/integration/mods_article_integration_spec.rb +0 -1
  21. data/spec/integration/nokogiri_datastream_spec.rb +0 -1
  22. data/spec/integration/rels_ext_datastream_spec.rb +10 -7
  23. data/spec/integration/semantic_node_spec.rb +10 -16
  24. data/spec/samples/models/hydrangea_article.rb +1 -2
  25. data/spec/samples/oral_history_sample_model.rb +1 -1
  26. data/spec/unit/base_spec.rb +26 -16
  27. data/spec/unit/metadata_datastream_spec.rb +1 -0
  28. data/spec/unit/qualified_dublin_core_datastream_spec.rb +1 -0
  29. data/spec/unit/relationship_spec.rb +1 -0
  30. data/spec/unit/relationships_spec.rb +846 -0
  31. data/spec/unit/semantic_node_spec.rb +2 -338
  32. metadata +8 -7
  33. data/lib/active_fedora/relationships_helper.rb +0 -881
  34. data/spec/unit/relationships_helper_spec.rb +0 -800
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
  require 'rexml/document'
3
- require "active_fedora/samples"
4
3
 
5
4
  include ActiveFedora
6
5
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require "active_fedora/samples"
3
2
 
4
3
  describe ActiveFedora::Base do
5
4
 
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require "active_fedora/samples"
3
2
  require "solrizer"
4
3
 
5
4
  describe ActiveFedora::NokogiriDatastream do
@@ -3,12 +3,6 @@ require 'spec_helper'
3
3
  require 'active_fedora'
4
4
  require "rexml/document"
5
5
 
6
- class MockAFRelsSolr < ActiveFedora::Base
7
- has_relationship "testing", :has_part, :type=>MockAFRelsSolr
8
- has_relationship "testing2", :has_member, :type=>MockAFRelsSolr
9
- has_relationship "testing_inbound", :has_part, :type=>MockAFRelsSolr, :inbound=>true
10
- has_relationship "testing_inbound2", :has_member, :type=>MockAFRelsSolr, :inbound=>true
11
- end
12
6
 
13
7
  describe ActiveFedora::RelsExtDatastream do
14
8
 
@@ -85,7 +79,16 @@ describe ActiveFedora::RelsExtDatastream do
85
79
  end
86
80
 
87
81
  describe '#from_solr' do
88
-
82
+ before do
83
+ ActiveSupport::Deprecation.stubs(:warn)
84
+ class MockAFRelsSolr < ActiveFedora::Base
85
+ include ActiveFedora::FileManagement
86
+ has_relationship "testing", :has_part, :type=>MockAFRelsSolr
87
+ has_relationship "testing2", :has_member, :type=>MockAFRelsSolr
88
+ has_relationship "testing_inbound", :has_part, :type=>MockAFRelsSolr, :inbound=>true
89
+ has_relationship "testing_inbound2", :has_member, :type=>MockAFRelsSolr, :inbound=>true
90
+ end
91
+ end
89
92
  it "should respond_to from_solr" do
90
93
  @test_datastream.respond_to?(:from_solr).should be_true
91
94
  end
@@ -6,8 +6,6 @@ describe ActiveFedora::SemanticNode do
6
6
 
7
7
  before(:all) do
8
8
  class SNSpecNode < ActiveFedora::Base
9
- # include ActiveFedora::RelationshipsHelper
10
- # include ActiveFedora::SemanticNode
11
9
  # has_relationship "collection_members", :has_collection_member
12
10
  # attr_accessor :rels_ext
13
11
  # def initialize
@@ -163,11 +161,11 @@ describe ActiveFedora::SemanticNode do
163
161
  describe "inbound relationship finders" do
164
162
  describe "when inheriting from parents" do
165
163
  before do
164
+ @part4 = ActiveFedora::Base.new()
165
+ @part4.parts ## Includes the FileManagement onto AF::Base. This happens in another test (and caries into this one) if you run the whole suite, but it doesn't get set up if you just run this test.
166
166
  class Test2 < ActiveFedora::Base
167
- # has_bidirectional_relationship "components", :has_component, :is_component_of
168
167
  end
169
168
  class Test3 < Test2
170
- # has_bidirectional_relationship "components", :has_component, :is_component_of
171
169
  has_relationship "testing", :has_member
172
170
  end
173
171
 
@@ -181,7 +179,6 @@ describe ActiveFedora::SemanticNode do
181
179
 
182
180
  @test_object2 = Test2.new
183
181
  @test_object2.save
184
- @part4 = ActiveFedora::Base.new()
185
182
  end
186
183
  it "should have relationships defined" do
187
184
  # puts "Test2 relationships_desc:"
@@ -433,17 +430,14 @@ describe ActiveFedora::SemanticNode do
433
430
 
434
431
  #putting this test here instead of relationships_helper because testing that relationships_by_name hash gets refreshed if the relationships hash is changed
435
432
  describe "relationships_by_name" do
436
- class MockSemNamedRelationships < ActiveFedora::Base
437
- # include ActiveFedora::RelationshipsHelper
438
- # include ActiveFedora::SemanticNode
439
- has_relationship "testing", :has_part
440
- has_relationship "testing2", :has_member
441
- has_relationship "testing_inbound", :has_part, :inbound=>true
442
- # attr_accessor :rels_ext
443
- # def initialize
444
- # self.rels_ext = ActiveFedora::RelsExtDatastream.new(nil, nil)
445
- # rels_ext.model = self
446
- # end
433
+ before do
434
+ ActiveSupport::Deprecation.stubs(:warn)
435
+ class MockSemNamedRelationships < ActiveFedora::Base
436
+ include ActiveFedora::FileManagement
437
+ has_relationship "testing", :has_part
438
+ has_relationship "testing2", :has_member
439
+ has_relationship "testing_inbound", :has_part, :inbound=>true
440
+ end
447
441
  end
448
442
 
449
443
  it 'should automatically update the relationships_by_name if relationships has changed (no refresh of relationships_by_name hash unless relationships hash has changed' do
@@ -1,5 +1,4 @@
1
1
  require "active-fedora"
2
- require "active_fedora/samples"
3
2
 
4
3
  # This Model is used to load & index the hydrangea:fixture_mods_article1 fixture for use in tests.
5
4
  #
@@ -9,4 +8,4 @@ class HydrangeaArticle < ActiveFedora::Base
9
8
  has_metadata :name => "descMetadata", :type=> Hydra::ModsArticleDatastream
10
9
  has_metadata :name => "rightsMetadata", :type => Hydra::RightsMetadataDatastream
11
10
 
12
- end
11
+ end
@@ -1,7 +1,7 @@
1
1
  require "active_fedora"
2
2
  class OralHistorySampleModel < ActiveFedora::Base
3
3
 
4
- has_relationship "parts", :is_part_of, :inbound => true
4
+ #has_relationship "parts", :is_part_of, :inbound => true
5
5
 
6
6
  has_metadata :name => "properties", :type => ActiveFedora::MetadataDatastream do |m|
7
7
  m.field "narrator", :string
@@ -40,7 +40,7 @@ describe ActiveFedora::Base do
40
40
  after(:each) do
41
41
  begin
42
42
  ActiveFedora::SolrService.stubs(:instance)
43
- @test_object.delete
43
+ #@test_object.delete
44
44
  rescue
45
45
  end
46
46
  end
@@ -830,16 +830,17 @@ describe ActiveFedora::Base do
830
830
  FooHistory.solr_search("pid: foobar", {:ding=>:dang}).should == {:baz=>:bif}
831
831
  end
832
832
 
833
- it 'should provide #relationships_by_name' do
834
- @test_object.should respond_to(:relationships_by_name)
835
- end
836
-
837
833
  describe '#relationships_by_name' do
838
834
 
839
- class MockNamedRelationships < ActiveFedora::Base
840
- has_relationship "testing", :has_part, :type=>ActiveFedora::Base
841
- has_relationship "testing2", :has_member, :type=>ActiveFedora::Base
842
- has_relationship "testing_inbound", :has_part, :type=>ActiveFedora::Base, :inbound=>true
835
+ before do
836
+ ActiveSupport::Deprecation.stubs(:warn)
837
+
838
+ class MockNamedRelationships < ActiveFedora::Base
839
+ include ActiveFedora::FileManagement
840
+ has_relationship "testing", :has_part, :type=>ActiveFedora::Base
841
+ has_relationship "testing2", :has_member, :type=>ActiveFedora::Base
842
+ has_relationship "testing_inbound", :has_part, :type=>ActiveFedora::Base, :inbound=>true
843
+ end
843
844
  end
844
845
 
845
846
  it 'should return current relationships by name' do
@@ -851,17 +852,26 @@ describe ActiveFedora::Base do
851
852
  @test_object.add_relationship(:has_model, ActiveFedora::ContentModel.pid_from_ruby_class(ActiveFedora::Base))
852
853
  #should return expected named relationships
853
854
  @test_object2.relationships_by_name
854
- @test_object2.relationships_by_name.should == {:self=>{"testing2"=>[], "collection_members"=>[], "part_of"=>[], "testing"=>[], "parts_outbound"=>[]}}
855
+ @test_object2.relationships_by_name[:self]["testing"].should == []
856
+ @test_object2.relationships_by_name[:self]["testing2"].should == []
857
+ @test_object2.relationships_by_name[:self]["parts_outbound"].should == []
855
858
  @test_object2.add_relationship_by_name("testing",@test_object)
856
- @test_object2.relationships_by_name.should == {:self=>{"testing"=>[@test_object.internal_uri],"testing2"=>[],"part_of"=>[], "parts_outbound"=>[@test_object.internal_uri], "collection_members"=>[]}}
859
+ # @test_object2.relationships_by_name.should == {:self=>{"testing"=>[@test_object.internal_uri],"testing2"=>[],"part_of"=>[], "parts_outbound"=>[@test_object.internal_uri], "collection_members"=>[]}}
860
+
861
+ @test_object2.relationships_by_name[:self]["testing"].should == [@test_object.internal_uri]
862
+ @test_object2.relationships_by_name[:self]["testing2"].should == []
863
+ @test_object2.relationships_by_name[:self]["parts_outbound"].should == [@test_object.internal_uri]
857
864
  end
858
865
  end
859
866
 
860
867
 
861
868
  describe '#create_relationship_name_methods' do
862
- class MockCreateNamedRelationshipMethodsBase < ActiveFedora::Base
863
- register_relationship_desc :self, "testing", :is_part_of, :type=>ActiveFedora::Base
864
- create_relationship_name_methods "testing"
869
+ before do
870
+ ActiveSupport::Deprecation.stubs(:warn)
871
+ class MockCreateNamedRelationshipMethodsBase < ActiveFedora::Base
872
+ register_relationship_desc :self, "testing", :is_part_of, :type=>ActiveFedora::Base
873
+ create_relationship_name_methods "testing"
874
+ end
865
875
  end
866
876
 
867
877
  it 'should append and remove using helper methods for each outbound relationship' do
@@ -877,9 +887,9 @@ describe ActiveFedora::Base do
877
887
  @test_object2.add_relationship(:has_model,model_pid)
878
888
  @test_object2.testing_append(@test_object)
879
889
  #create relationship to access generate_uri method for an object
880
- @test_object2.relationships_by_name.should == {:self=>{"testing"=>[@test_object.internal_uri],"collection_members"=>[], "part_of"=>[@test_object.internal_uri], "parts_outbound"=>[]}}
890
+ @test_object2.relationships_by_name[:self]["testing"].should == [@test_object.internal_uri]
881
891
  @test_object2.testing_remove(@test_object)
882
- @test_object2.relationships_by_name.should == {:self=>{"testing"=>[],"collection_members"=>[], "part_of"=>[], "parts_outbound"=>[]}}
892
+ @test_object2.relationships_by_name[:self]["testing"].should == []
883
893
  end
884
894
  end
885
895
 
@@ -44,6 +44,7 @@ describe ActiveFedora::MetadataDatastream do
44
44
  @mock_repo.expects(:datastream).with(:pid => nil, :dsid => 'mdDs')
45
45
  @mock_repo.expects(:add_datastream).with(:pid => nil, :dsid => 'mdDs', :checksumType => 'DISABLED', :versionable => true, :content => 'fake xml', :controlGroup => 'M', :dsState => 'A', :mimeType=>'text/xml')
46
46
  @test_ds.expects(:to_xml).returns("fake xml")
47
+ @test_ds.expects(:dirty?).returns(true)
47
48
  @test_ds.serialize!
48
49
  @test_ds.save
49
50
  @test_ds.mimeType.should == 'text/xml'
@@ -129,6 +129,7 @@ describe ActiveFedora::QualifiedDublinCoreDatastream do
129
129
  it "should call .content= with to_dc_xml" do
130
130
  result = @test_ds.to_dc_xml
131
131
  @test_ds.expects(:content=).with(result)
132
+ @test_ds.expects(:dirty?).returns(true)
132
133
  @test_ds.serialize!
133
134
  end
134
135
  end
@@ -87,5 +87,6 @@ describe ActiveFedora::Relationship do
87
87
  @test_relationship.predicate.should == "isComponentOf"
88
88
  end
89
89
  end
90
+
90
91
 
91
92
  end
@@ -0,0 +1,846 @@
1
+ require 'spec_helper'
2
+
3
+ @@last_pid = 0
4
+
5
+ describe ActiveFedora::Relationships do
6
+ def increment_pid
7
+ @@last_pid += 1
8
+ end
9
+
10
+ before(:each) do
11
+ class SpecNode
12
+ include ActiveFedora::Relationships
13
+ include ActiveFedora::SemanticNode
14
+
15
+ attr_accessor :pid
16
+ def initialize (params={})
17
+ self.pid = params[:pid]
18
+ end
19
+ def internal_uri
20
+ 'info:fedora/' + pid.to_s
21
+ end
22
+ end
23
+ end
24
+ after(:each) do
25
+ Object.send(:remove_const, :SpecNode)
26
+ end
27
+
28
+ it 'should provide #has_relationship' do
29
+ SpecNode.should respond_to(:has_relationship)
30
+ SpecNode.should respond_to(:has_relationship)
31
+ end
32
+ describe '#relationships' do
33
+
34
+ it "should return a hash" do
35
+ SpecNode.relationships.class.should == Hash
36
+ end
37
+
38
+ end
39
+
40
+ describe '#has_relationship' do
41
+ it "should create finders based on provided relationship name" do
42
+ SpecNode.has_relationship("parts", :is_part_of, :inbound => true)
43
+ local_node = SpecNode.new
44
+ local_node.should respond_to(:parts_ids)
45
+ local_node.should respond_to(:parts_query)
46
+ # local_node.should respond_to(:parts)
47
+ local_node.should_not respond_to(:containers)
48
+ SpecNode.has_relationship("containers", :is_member_of)
49
+ local_node.should respond_to(:containers_ids)
50
+ local_node.should respond_to(:containers_query)
51
+ end
52
+
53
+ it "should add a subject and predicate to the relationships array" do
54
+ SpecNode.has_relationship("parents", :is_part_of)
55
+ SpecNode.relationships.should have_key(:self)
56
+ SpecNode.relationships[:self].should have_key(:is_part_of)
57
+ end
58
+
59
+ it "should use :inbound as the subject if :inbound => true" do
60
+ SpecNode.has_relationship("parents", :is_part_of, :inbound => true)
61
+ SpecNode.relationships.should have_key(:inbound)
62
+ SpecNode.relationships[:inbound].should have_key(:is_part_of)
63
+ end
64
+
65
+ it 'should create inbound relationship finders' do
66
+ SpecNode.expects(:create_inbound_relationship_finders)
67
+ SpecNode.has_relationship("parts", :is_part_of, :inbound => true)
68
+ end
69
+
70
+ it 'should create outbound relationship finders' do
71
+ SpecNode.expects(:create_outbound_relationship_finders).times(2)
72
+ SpecNode.has_relationship("parts", :is_part_of, :inbound => false)
73
+ SpecNode.has_relationship("container", :is_member_of)
74
+ end
75
+
76
+ it "should create outbound relationship finders that return an array of fedora PIDs" do
77
+ SpecNode.has_relationship("containers", :is_member_of, :inbound => false)
78
+ local_node = SpecNode.new
79
+ #local_node.internal_uri = "info:fedora/#{@pid}"
80
+ local_node.pid = @pid
81
+
82
+ local_node.expects(:rels_ext).returns(stub("rels_ext", :dirty= => true, :content=>'')).at_least_once
83
+ local_node.add_relationship(:is_member_of, "info:fedora/container:A")
84
+ local_node.add_relationship(:is_member_of, "info:fedora/container:B")
85
+
86
+ containers_result = local_node.containers_ids
87
+ containers_result.should be_instance_of(Array)
88
+ containers_result.should include("container:A")
89
+ containers_result.should include("container:B")
90
+ end
91
+
92
+ describe "has_relationship" do
93
+ before do
94
+ class MockHasRelationship
95
+ include ActiveFedora::SemanticNode
96
+ include ActiveFedora::Relationships
97
+ has_relationship "testing", :has_part, :type=>String
98
+ has_relationship "testing2", :has_member, :type=>String
99
+ has_relationship "testing_inbound", :has_part, :type=>String, :inbound=>true
100
+ attr_accessor :pid
101
+ def internal_uri
102
+ 'info:fedora/' + pid.to_s
103
+ end
104
+ end
105
+ end
106
+ after(:each) do
107
+ Object.send(:remove_const, :MockHasRelationship)
108
+ end
109
+
110
+ it 'should create relationship descriptions both inbound and outbound' do
111
+ @test_object2 = MockHasRelationship.new
112
+ @test_object2.pid = increment_pid
113
+ @test_object2.stubs(:testing_inbound).returns({})
114
+ @test_object2.expects(:rels_ext).returns(stub("rels_ext", :dirty= => true, :content =>'')).at_least_once
115
+ @test_object2.add_relationship(:has_model, ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode))
116
+ @test_object2.should respond_to(:testing_append)
117
+ @test_object2.should respond_to(:testing_remove)
118
+ @test_object2.should respond_to(:testing2_append)
119
+ @test_object2.should respond_to(:testing2_remove)
120
+ #make sure append/remove method not created for inbound rel
121
+ @test_object2.should_not respond_to(:testing_inbound_append)
122
+ @test_object2.should_not respond_to(:testing_inbound_remove)
123
+
124
+ @test_object2.class.relationships_desc.should ==
125
+ {:inbound=>{"testing_inbound"=>{:type=>String,
126
+ :predicate=>:has_part,
127
+ :inbound=>true,
128
+ :singular=>nil}},
129
+ :self=>{"testing"=>{:type=>String,
130
+ :predicate=>:has_part,
131
+ :inbound=>false,
132
+ :singular=>nil},
133
+ "testing2"=>{:type=>String,
134
+ :predicate=>:has_member,
135
+ :inbound=>false,
136
+ :singular=>nil}}}
137
+ end
138
+ end
139
+ end
140
+
141
+ describe '#create_inbound_relationship_finders' do
142
+
143
+ it 'should respond to #create_inbound_relationship_finders' do
144
+ SpecNode.should respond_to(:create_inbound_relationship_finders)
145
+ end
146
+
147
+ it "should create finders based on provided relationship name" do
148
+ SpecNode.create_inbound_relationship_finders("parts", :is_part_of, :inbound => true)
149
+ local_node = SpecNode.new
150
+ local_node.should respond_to(:parts_ids)
151
+ local_node.should_not respond_to(:containers)
152
+ SpecNode.create_inbound_relationship_finders("containers", :is_member_of, :inbound => true)
153
+ local_node.should respond_to(:containers_ids)
154
+ local_node.should respond_to(:containers)
155
+ local_node.should respond_to(:containers_from_solr)
156
+ local_node.should respond_to(:containers_query)
157
+ end
158
+
159
+ it "resulting finder should search against solr and use Model#load_instance to build an array of objects" do
160
+ @sample_solr_hits = [{"id"=>"_PID1_", "has_model_s"=>["info:fedora/afmodel:AudioRecord"]},
161
+ {"id"=>"_PID2_", "has_model_s"=>["info:fedora/afmodel:AudioRecord"]},
162
+ {"id"=>"_PID3_", "has_model_s"=>["info:fedora/afmodel:AudioRecord"]}]
163
+ solr_result = mock("solr result", :hits => @sample_solr_hits)
164
+ SpecNode.create_inbound_relationship_finders("parts", :is_part_of, :inbound => true)
165
+ local_node = SpecNode.new()
166
+ local_node.expects(:pid).returns("test:sample_pid")
167
+ SpecNode.expects(:relationships_desc).returns({:inbound=>{"parts"=>{:predicate=>:is_part_of}}}).at_least_once()
168
+ ActiveFedora::SolrService.instance.conn.expects(:query).with("is_part_of_s:info\\:fedora/test\\:sample_pid", :rows=>25).returns(solr_result)
169
+ local_node.parts_ids.should == ["_PID1_", "_PID2_", "_PID3_"]
170
+ end
171
+
172
+ it "resulting finder should accept :solr as :response_format value and return the raw Solr Result" do
173
+ solr_result = mock("solr result")
174
+ SpecNode.create_inbound_relationship_finders("constituents", :is_constituent_of, :inbound => true)
175
+ local_node = SpecNode.new
176
+ mock_repo = mock("repo")
177
+ mock_repo.expects(:find_model).never
178
+ local_node.expects(:pid).returns("test:sample_pid")
179
+ SpecNode.expects(:relationships_desc).returns({:inbound=>{"constituents"=>{:predicate=>:is_constituent_of}}}).at_least_once()
180
+ ActiveFedora::SolrService.instance.conn.expects(:query).with("is_constituent_of_s:info\\:fedora/test\\:sample_pid", :rows=>101).returns(solr_result)
181
+ local_node.constituents(:response_format => :solr, :rows=>101).should equal(solr_result)
182
+ end
183
+
184
+
185
+ it "resulting _ids finder should search against solr and return an array of fedora PIDs" do
186
+ SpecNode.create_inbound_relationship_finders("parts", :is_part_of, :inbound => true)
187
+ local_node = SpecNode.new
188
+ local_node.expects(:pid).returns("test:sample_pid")
189
+ SpecNode.expects(:relationships_desc).returns({:inbound=>{"parts"=>{:predicate=>:is_part_of}}}).at_least_once()
190
+ ActiveFedora::SolrService.instance.conn.expects(:query).with("is_part_of_s:info\\:fedora/test\\:sample_pid", :rows=>25).returns(mock("solr result", :hits => [Hash["id"=>"pid1"], Hash["id"=>"pid2"]]))
191
+ local_node.parts(:response_format => :id_array).should == ["pid1", "pid2"]
192
+ end
193
+
194
+ it "resulting _ids finder should call the basic finder with :result_format => :id_array" do
195
+ SpecNode.create_inbound_relationship_finders("parts", :is_part_of, :inbound => true)
196
+ local_node = SpecNode.new
197
+ local_node.expects(:parts).with(:response_format => :id_array)
198
+ local_node.parts_ids
199
+ end
200
+
201
+ it "resulting _query finder should call relationship_query" do
202
+ SpecNode.create_inbound_relationship_finders("parts", :is_part_of, :inbound => true)
203
+ local_node = SpecNode.new
204
+ local_node.expects(:relationship_query).with("parts")
205
+ local_node.parts_query
206
+ end
207
+ end
208
+
209
+ describe '#create_outbound_relationship_finders' do
210
+
211
+ it 'should respond to #create_outbound_relationship_finders' do
212
+ SpecNode.should respond_to(:create_outbound_relationship_finders)
213
+ end
214
+
215
+ it "should create finders based on provided relationship name" do
216
+ SpecNode.create_outbound_relationship_finders("parts", :is_part_of)
217
+ local_node = SpecNode.new
218
+ local_node.should respond_to(:parts_ids)
219
+ #local_node.should respond_to(:parts) #.with(:type => "AudioRecord")
220
+ local_node.should_not respond_to(:containers)
221
+ SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
222
+ local_node.should respond_to(:containers_ids)
223
+ local_node.should respond_to(:containers)
224
+ local_node.should respond_to(:containers_from_solr)
225
+ local_node.should respond_to(:containers_query)
226
+ end
227
+
228
+ describe " resulting finder" do
229
+ it "should read from relationships array and use Repository.find_model to build an array of objects" do
230
+ SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
231
+ local_node = SpecNode.new
232
+ local_node.expects(:ids_for_outbound).with(:is_member_of).returns(["my:_PID1_", "my:_PID2_", "my:_PID3_"])
233
+ mock_repo = mock("repo")
234
+ solr_result = mock("solr result", :is_a? => true)
235
+ solr_result.expects(:hits).returns(
236
+ [{"id"=> "my:_PID1_", "has_model_s"=>["info:fedora/afmodel:SpecNode"]},
237
+ {"id"=> "my:_PID2_", "has_model_s"=>["info:fedora/afmodel:SpecNode"]},
238
+ {"id"=> "my:_PID3_", "has_model_s"=>["info:fedora/afmodel:SpecNode"]}])
239
+
240
+ ActiveFedora::SolrService.instance.conn.expects(:query).with("id:my\\:_PID1_ OR id:my\\:_PID2_ OR id:my\\:_PID3_").returns(solr_result)
241
+ local_node.containers.map(&:pid).should == ["my:_PID1_", "my:_PID2_", "my:_PID3_"]
242
+ end
243
+
244
+ it "should accept :solr as :response_format value and return the raw Solr Result" do
245
+ solr_result = mock("solr result")
246
+ SpecNode.create_outbound_relationship_finders("constituents", :is_constituent_of)
247
+ local_node = SpecNode.new
248
+ mock_repo = mock("repo")
249
+ mock_repo.expects(:find_model).never
250
+ local_node.expects(:rels_ext).returns(stub('rels-ext', :content=>''))
251
+ ActiveFedora::SolrService.instance.conn.expects(:query).returns(solr_result)
252
+ local_node.constituents(:response_format => :solr).should equal(solr_result)
253
+ end
254
+
255
+ it "(:response_format => :id_array) should read from relationships array" do
256
+ SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
257
+ local_node = SpecNode.new
258
+ local_node.expects(:ids_for_outbound).with(:is_member_of).returns([])
259
+ local_node.containers_ids
260
+ end
261
+
262
+ it "(:response_format => :id_array) should return an array of fedora PIDs" do
263
+ SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
264
+ local_node = SpecNode.new
265
+ local_node.expects(:rels_ext).returns(stub("rels_ext", :dirty= => true, :content=>'')).at_least_once
266
+ local_node.add_relationship(:is_member_of, "demo:10")
267
+ result = local_node.containers_ids
268
+ result.should be_instance_of(Array)
269
+ result.should include("demo:10")
270
+ end
271
+
272
+ end
273
+
274
+ describe " resulting _ids finder" do
275
+ it "should call the basic finder with :result_format => :id_array" do
276
+ SpecNode.create_outbound_relationship_finders("parts", :is_part_of)
277
+ local_node = SpecNode.new
278
+ local_node.expects(:parts).with(:response_format => :id_array)
279
+ local_node.parts_ids
280
+ end
281
+ end
282
+
283
+ it "resulting _query finder should call relationship_query" do
284
+ SpecNode.create_outbound_relationship_finders("containers", :is_member_of)
285
+ local_node = SpecNode.new
286
+ local_node.expects(:relationship_query).with("containers")
287
+ local_node.containers_query
288
+ end
289
+ end
290
+
291
+ describe ".create_bidirectional_relationship_finder" do
292
+ before(:each) do
293
+ SpecNode.create_bidirectional_relationship_finders("all_parts", :has_part, :is_part_of)
294
+ @local_node = SpecNode.new
295
+ @pid = "test:sample_pid"
296
+ @local_node.pid = @pid
297
+ #@local_node.internal_uri = @uri
298
+ end
299
+ it "should create inbound & outbound finders" do
300
+ @local_node.should respond_to(:all_parts_inbound)
301
+ @local_node.should respond_to(:all_parts_outbound)
302
+ end
303
+ it "should rely on inbound & outbound finders" do
304
+ @local_node.expects(:all_parts_inbound).with(:rows => 25).returns(["foo1"])
305
+ @local_node.expects(:all_parts_outbound).with(:rows => 25).returns(["foo2"])
306
+ @local_node.all_parts.should == ["foo1", "foo2"]
307
+ end
308
+ it "(:response_format => :id_array) should rely on inbound & outbound finders" do
309
+ @local_node.expects(:all_parts_inbound).with(:response_format=>:id_array, :rows => 34).returns(["fooA"])
310
+ @local_node.expects(:all_parts_outbound).with(:response_format=>:id_array, :rows => 34).returns(["fooB"])
311
+ @local_node.all_parts(:response_format=>:id_array, :rows => 34).should == ["fooA", "fooB"]
312
+ end
313
+ it "(:response_format => :solr) should construct a solr query that combines inbound and outbound searches" do
314
+ # get the id array for outbound relationships then construct solr query by combining id array with inbound relationship search
315
+ @local_node.expects(:ids_for_outbound).with(:has_part).returns(["mypid:1"])
316
+ id_array_query = ActiveFedora::SolrService.construct_query_for_pids(["mypid:1"])
317
+ solr_result = mock("solr result")
318
+ ActiveFedora::SolrService.instance.conn.expects(:query).with("#{id_array_query} OR (is_part_of_s:info\\:fedora/test\\:sample_pid)", :rows=>25).returns(solr_result)
319
+ @local_node.all_parts(:response_format=>:solr)
320
+ end
321
+
322
+ it "should register both inbound and outbound predicate components" do
323
+ @local_node.class.relationships[:inbound].has_key?(:is_part_of).should == true
324
+ @local_node.class.relationships[:self].has_key?(:has_part).should == true
325
+ end
326
+
327
+ it "should register finder methods for the bidirectional relationship name" do
328
+ @local_node.should respond_to(:all_parts)
329
+ @local_node.should respond_to(:all_parts_ids)
330
+ @local_node.should respond_to(:all_parts_query)
331
+ @local_node.should respond_to(:all_parts_from_solr)
332
+ end
333
+
334
+ it "resulting _query finder should call relationship_query" do
335
+ SpecNode.create_bidirectional_relationship_finders("containers", :is_member_of, :has_member)
336
+ local_node = SpecNode.new
337
+ local_node.expects(:relationship_query).with("containers")
338
+ local_node.containers_query
339
+ end
340
+ end
341
+
342
+ describe "#has_bidirectional_relationship" do
343
+ it "should ..." do
344
+ SpecNode.expects(:create_bidirectional_relationship_finders).with("all_parts", :has_part, :is_part_of, {})
345
+ SpecNode.has_bidirectional_relationship("all_parts", :has_part, :is_part_of)
346
+ end
347
+
348
+ it "should have relationships_by_name and relationships hashes contain bidirectionally related objects" do
349
+ SpecNode.has_bidirectional_relationship("all_parts", :has_part, :is_part_of)
350
+ @local_node = SpecNode.new
351
+ @local_node.pid = "mypid1"
352
+ @local_node2 = SpecNode.new
353
+ @local_node2.pid = "mypid2"
354
+ model_def = ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode)
355
+ @local_node.expects(:rels_ext).returns(stub("rels_ext", :dirty= => true, :content=>'')).at_least_once
356
+ @local_node.add_relationship(:has_model, model_def)
357
+ @local_node2.expects(:rels_ext).returns(stub("rels_ext", :dirty= => true, :content=>'')).at_least_once
358
+ @local_node2.add_relationship(:has_model, model_def)
359
+ @local_node.add_relationship(:has_part, @local_node2)
360
+ @local_node2.add_relationship(:has_part, @local_node)
361
+ @local_node.ids_for_outbound(:has_part).should == [@local_node2.pid]
362
+ @local_node.ids_for_outbound(:has_model).should == ['afmodel:SpecNode']
363
+ @local_node2.ids_for_outbound(:has_part).should == [@local_node.pid]
364
+ @local_node2.ids_for_outbound(:has_model).should == ['afmodel:SpecNode']
365
+ @local_node.relationships_by_name(false).should == {:self=>{"all_parts_outbound"=>[@local_node2.internal_uri]},:inbound=>{"all_parts_inbound"=>[]}}
366
+ @local_node2.relationships_by_name(false).should == {:self=>{"all_parts_outbound"=>[@local_node.internal_uri]},:inbound=>{"all_parts_inbound"=>[]}}
367
+ end
368
+ end
369
+
370
+
371
+ it 'should provide #inbound_relationship_names' do
372
+ SpecNode.new.should respond_to(:inbound_relationship_names)
373
+ end
374
+
375
+ describe '#inbound_relationship_names' do
376
+ before do
377
+ class MockRelationshipNames < SpecNode
378
+ register_relationship_desc(:self, "testing", :has_part, :type=>SpecNode)
379
+ create_relationship_name_methods("testing")
380
+ register_relationship_desc(:self, "testing2", :has_member, :type=>SpecNode)
381
+ create_relationship_name_methods("testing2")
382
+ register_relationship_desc(:inbound, "testing_inbound", :has_part, :type=>SpecNode)
383
+ register_relationship_desc(:inbound, "testing_inbound2", :has_member, :type=>SpecNode)
384
+ end
385
+ end
386
+ it 'should return an array of inbound relationship names for this model' do
387
+ @test_object2 = MockRelationshipNames.new
388
+ @test_object2.pid = increment_pid
389
+ @test_object2.inbound_relationship_names.include?("testing_inbound").should == true
390
+ @test_object2.inbound_relationship_names.include?("testing_inbound2").should == true
391
+ @test_object2.inbound_relationship_names.size.should == 2
392
+ end
393
+ end
394
+
395
+ it 'should provide #outbound_relationship_names' do
396
+ SpecNode.new.should respond_to(:outbound_relationship_names)
397
+ end
398
+
399
+ describe '#outbound_relationship_names' do
400
+ it 'should return an array of outbound relationship names for this model' do
401
+ @test_object2 = MockRelationshipNames.new
402
+ @test_object2.pid = increment_pid
403
+ @test_object2.outbound_relationship_names.include?("testing").should == true
404
+ @test_object2.outbound_relationship_names.include?("testing2").should == true
405
+ @test_object2.outbound_relationship_names.size.should == 2
406
+ end
407
+ end
408
+
409
+ it 'should provide #inbound_relationships_by_name' do
410
+ #testing execution of this in integration since touches solr
411
+ SpecNode.new.should respond_to(:inbound_relationships_by_name)
412
+ end
413
+
414
+ it 'should provide #find_relationship_by_name' do
415
+ SpecNode.new.should respond_to(:find_relationship_by_name)
416
+ end
417
+
418
+ describe '#find_relationship_by_name' do
419
+ it 'should return an array of object uri for a given relationship name' do
420
+ @test_object2 = MockRelationshipNames.new
421
+ @test_object2.pid = increment_pid
422
+ @test_object3 = SpecNode.new
423
+ @test_object3.pid = increment_pid
424
+ @test_object4 = SpecNode.new
425
+ @test_object4.pid = increment_pid
426
+ #add relationships that mirror 'testing' and 'testing2'
427
+ graph = RDF::Graph.new
428
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
429
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_model), RDF::URI.new(ActiveFedora::ContentModel.pid_from_ruby_class(MockRelationshipNames)))
430
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_member), RDF::URI.new(@test_object4.internal_uri))
431
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_part), RDF::URI.new(@test_object3.internal_uri))
432
+ @test_object2.expects(:relationships).returns(graph).at_least_once
433
+ @test_object2.find_relationship_by_name("testing").should == [@test_object3.internal_uri]
434
+ end
435
+ end
436
+
437
+ describe "relationship_query" do
438
+ before do
439
+ class MockNamedRelationshipQuery < SpecNode
440
+ register_relationship_desc(:inbound, "testing_inbound_query", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
441
+ register_relationship_desc(:inbound, "testing_inbound_no_solr_fq", :is_part_of, :type=>SpecNode)
442
+ register_relationship_desc(:self, "testing_outbound_query", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
443
+ register_relationship_desc(:self, "testing_outbound_no_solr_fq", :is_part_of, :type=>SpecNode)
444
+ #for bidirectional relationship testing need to register both outbound and inbound names
445
+ register_relationship_desc(:self, "testing_bi_query_outbound", :has_part, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
446
+ register_relationship_desc(:inbound, "testing_bi_query_inbound", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
447
+ register_relationship_desc(:self, "testing_bi_no_solr_fq_outbound", :has_part, :type=>SpecNode)
448
+ register_relationship_desc(:inbound, "testing_bi_no_solr_fq_inbound", :is_part_of, :type=>SpecNode)
449
+ end
450
+ end
451
+ after do
452
+ Object.send(:remove_const, :MockNamedRelationshipQuery)
453
+ end
454
+
455
+ before(:each) do
456
+ @mockrelsquery = MockNamedRelationshipQuery.new
457
+ end
458
+
459
+ it "should call bidirectional_relationship_query if a bidirectional relationship" do
460
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4"]
461
+ @mockrelsquery.expects(:ids_for_outbound).with(:has_part).returns(ids).at_least_once
462
+ @mockrelsquery.expects(:pid).returns("changeme:5")
463
+ MockNamedRelationshipQuery.expects(:bidirectional_relationship_query).with("changeme:5","testing_bi_query",ids)
464
+ @mockrelsquery.relationship_query("testing_bi_query")
465
+ end
466
+
467
+ it "should call outbound_relationship_query if an outbound relationship" do
468
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4"]
469
+ @mockrelsquery.expects(:ids_for_outbound).with(:is_part_of).returns(ids).at_least_once
470
+ MockNamedRelationshipQuery.expects(:outbound_relationship_query).with("testing_outbound_no_solr_fq",ids)
471
+ @mockrelsquery.relationship_query("testing_outbound_no_solr_fq")
472
+ end
473
+
474
+ it "should call inbound_relationship_query if an inbound relationship" do
475
+ @mockrelsquery.expects(:pid).returns("changeme:5")
476
+ MockNamedRelationshipQuery.expects(:inbound_relationship_query).with("changeme:5","testing_inbound_query")
477
+ @mockrelsquery.relationship_query("testing_inbound_query")
478
+ end
479
+ end
480
+
481
+ describe '#relationship_predicates' do
482
+ before do
483
+ class MockNamedRelationshipPredicates < SpecNode
484
+ register_relationship_desc(:self, "testing", :has_part, :type=>SpecNode)
485
+ create_relationship_name_methods("testing")
486
+ register_relationship_desc(:self, "testing2", :has_member, :type=>SpecNode)
487
+ create_relationship_name_methods("testing2")
488
+ register_relationship_desc(:inbound, "testing_inbound", :has_part, :type=>SpecNode)
489
+ end
490
+ end
491
+ after do
492
+ Object.send(:remove_const, :MockNamedRelationshipPredicates)
493
+ end
494
+
495
+ it 'should provide #relationship_predicates' do
496
+ SpecNode.new.should respond_to(:relationship_predicates)
497
+ end
498
+
499
+ it 'should return a map of subject to relationship name to fedora ontology relationship predicate' do
500
+ @test_object2 = MockNamedRelationshipPredicates.new
501
+ @test_object2.relationship_predicates.should == {:self=>{"testing"=>:has_part,"testing2"=>:has_member},
502
+ :inbound=>{"testing_inbound"=>:has_part}}
503
+
504
+ end
505
+ end
506
+
507
+ describe '#conforms_to?' do
508
+ before do
509
+ @test_object = SpecNode.new
510
+ end
511
+ it 'should provide #conforms_to?' do
512
+ @test_object.should respond_to(:conforms_to?)
513
+ end
514
+
515
+ it 'should check if current object is the kind of model class supplied' do
516
+ #has_model relationship does not get created until save called
517
+ graph = RDF::Graph.new
518
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
519
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_model), RDF::URI.new(ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode)))
520
+ @test_object.expects(:relationships).returns(graph).at_least_once
521
+ @test_object.conforms_to?(SpecNode).should == true
522
+ end
523
+ end
524
+
525
+ describe '#assert_conforms_to' do
526
+ before do
527
+ @test_object = SpecNode.new
528
+ end
529
+ it 'should provide #assert_conforms_to' do
530
+ @test_object.should respond_to(:assert_conforms_to)
531
+ end
532
+
533
+ it 'should correctly assert if an object is the type of model supplied' do
534
+ @test_object3 = SpecNode.new
535
+ @test_object3.pid = increment_pid
536
+ #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
537
+ graph = RDF::Graph.new
538
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
539
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_model), RDF::URI.new(ActiveFedora::ContentModel.pid_from_ruby_class(SpecNode)))
540
+ @test_object.expects(:relationships).returns(graph).at_least_once
541
+ @test_object3.assert_conforms_to('object',@test_object,SpecNode)
542
+ end
543
+ end
544
+
545
+ it 'should provide #class_from_name' do
546
+ SpecNode.new.should respond_to(:class_from_name)
547
+ end
548
+
549
+ describe '#class_from_name' do
550
+ it 'should return a class constant for a string passed in' do
551
+ SpecNode.new.class_from_name("SpecNode").should == SpecNode
552
+ end
553
+ end
554
+
555
+ describe '#relationships_by_name' do
556
+
557
+ before do
558
+ class MockNamedRelationships3 < SpecNode
559
+ register_relationship_desc(:self, "testing", :has_part, :type=>SpecNode)
560
+ create_relationship_name_methods("testing")
561
+ register_relationship_desc(:self, "testing2", :has_member, :type=>SpecNode)
562
+ create_relationship_name_methods("testing2")
563
+ register_relationship_desc(:inbound, "testing_inbound", :has_part, :type=>SpecNode)
564
+ end
565
+ end
566
+ after do
567
+ Object.send(:remove_const, :MockNamedRelationships3)
568
+ end
569
+
570
+ it 'should provide #relationships_by_name' do
571
+ @test_object = SpecNode.new
572
+ @test_object.should respond_to(:relationships_by_name)
573
+ end
574
+
575
+ it 'should return current named relationships' do
576
+ @test_object = SpecNode.new
577
+ @test_object.pid = increment_pid
578
+ @test_object2 = MockNamedRelationships3.new
579
+ @test_object2.pid = increment_pid
580
+ @test_object3 = MockNamedRelationships3.new
581
+ @test_object3.pid = increment_pid
582
+ model_pid = ActiveFedora::ContentModel.pid_from_ruby_class(MockNamedRelationships3)
583
+ graph = RDF::Graph.new
584
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
585
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_model), RDF::URI.new(model_pid))
586
+ @test_object2.expects(:relationships).returns(graph).at_least_once
587
+ #should return expected named relationships
588
+ @test_object2.relationships_by_name.should == {:self=>{"testing"=>[],"testing2"=>[]}}
589
+ graph = RDF::Graph.new
590
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
591
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_model), RDF::URI.new(model_pid))
592
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Predicates.find_graph_predicate(:has_part), RDF::URI.new(@test_object.internal_uri))
593
+ @test_object3.expects(:relationships).returns(graph).at_least_once
594
+ @test_object3.relationships_by_name.should == {:self=>{"testing"=>[@test_object.internal_uri],"testing2"=>[]}}
595
+ end
596
+ end
597
+ describe '#relationship_has_solr_filter_query' do
598
+ before do
599
+ class RelsHasSolrFilter < SpecNode
600
+ register_relationship_desc :self, "testing", :is_part_of, :solr_fq=>"testing:value"
601
+ register_relationship_desc :self, "no_query_testing", :is_part_of
602
+ register_relationship_desc :inbound, "inbound_testing", :has_part, :solr_fq=>"in_testing:value_in"
603
+ register_relationship_desc :inbound, "inbound_testing_no_query", :has_part
604
+ end
605
+ @test_object = RelsHasSolrFilter.new
606
+ end
607
+ after do
608
+ Object.send(:remove_const, :RelsHasSolrFilter)
609
+ end
610
+
611
+ it 'should return true if an object has an inbound relationship with solr filter query' do
612
+ @test_object.relationship_has_solr_filter_query?(:inbound,"inbound_testing").should == true
613
+ end
614
+
615
+ it 'should return false if an object does not have inbound relationship with solr filter query' do
616
+ @test_object.relationship_has_solr_filter_query?(:inbound,"inbound_testing_no_query").should == false
617
+ end
618
+
619
+ it 'should return true if an object has an outbound relationship with solr filter query' do
620
+ @test_object.relationship_has_solr_filter_query?(:self,"testing").should == true
621
+ end
622
+
623
+ it 'should return false if an object does not have outbound relationship with solr filter query' do
624
+ @test_object.relationship_has_solr_filter_query?(:self,"testing_no_query").should == false
625
+ end
626
+ end
627
+
628
+ describe ActiveFedora::Relationships::ClassMethods do
629
+
630
+ after(:each) do
631
+ begin
632
+ @test_object2.delete
633
+ rescue
634
+ end
635
+ end
636
+
637
+ describe '#relationships_desc' do
638
+ it 'should initialize relationships_desc to a new hash containing self' do
639
+ @test_object2 = SpecNode.new
640
+ @test_object2.pid = increment_pid
641
+ @test_object2.relationships_desc.should == {:self=>{}}
642
+ end
643
+ end
644
+
645
+ describe '#register_relationship_desc_subject' do
646
+
647
+ before do
648
+ class MockRegisterNamedSubject < SpecNode
649
+ register_relationship_desc_subject :test
650
+ end
651
+ end
652
+
653
+ it 'should add a new named subject to the named relationships only if it does not already exist' do
654
+ @test_object2 = MockRegisterNamedSubject.new
655
+ @test_object2.pid = increment_pid
656
+ @test_object2.relationships_desc.should == {:self=>{}, :test=>{}}
657
+ end
658
+ end
659
+
660
+ describe '#register_relationship_desc' do
661
+
662
+ before do
663
+ class MockRegisterNamedRelationship < SpecNode
664
+ register_relationship_desc :self, "testing", :is_part_of, :type=>SpecNode
665
+ register_relationship_desc :inbound, "testing2", :has_part, :type=>SpecNode
666
+ end
667
+ end
668
+
669
+ it 'should add a new named subject to the named relationships only if it does not already exist' do
670
+ @test_object2 = MockRegisterNamedRelationship.new
671
+ @test_object2.pid = increment_pid
672
+ @test_object2.relationships_desc.should == {:inbound=>{"testing2"=>{:type=>SpecNode, :predicate=>:has_part}}, :self=>{"testing"=>{:type=>SpecNode, :predicate=>:is_part_of}}}
673
+ end
674
+ end
675
+
676
+ describe "#is_bidirectional_relationship?" do
677
+
678
+ before do
679
+ class MockIsBiRegisterNamedRelationship < SpecNode
680
+ register_relationship_desc(:self, "testing_outbound", :is_part_of, :type=>SpecNode)
681
+ register_relationship_desc(:inbound, "testing_inbound", :has_part, :type=>SpecNode)
682
+ register_relationship_desc(:self, "testing2", :is_member_of,{})
683
+ end
684
+ end
685
+
686
+ it "should return true if both inbound and outbound predicates exist, otherwise false" do
687
+ MockIsBiRegisterNamedRelationship.is_bidirectional_relationship?("testing").should == true
688
+ MockIsBiRegisterNamedRelationship.is_bidirectional_relationship?("testing2").should == false
689
+ #the inbound and outbound internal relationships will not be bidirectional by themselves
690
+ MockIsBiRegisterNamedRelationship.is_bidirectional_relationship?("testing_inbound").should == false
691
+ MockIsBiRegisterNamedRelationship.is_bidirectional_relationship?("testing_outbound").should == false
692
+ end
693
+ end
694
+
695
+
696
+ describe '#create_relationship_name_methods' do
697
+ before do
698
+ class MockCreateNamedRelationshipMethods < SpecNode
699
+ register_relationship_desc :self, "testing", :is_part_of, :type=>SpecNode
700
+ create_relationship_name_methods "testing"
701
+ end
702
+ end
703
+ after do
704
+ Object.send(:remove_const, :MockCreateNamedRelationshipMethods)
705
+ end
706
+
707
+ it 'should create an append and remove method for each outbound relationship' do
708
+ @test_object2 = MockCreateNamedRelationshipMethods.new
709
+ @test_object2.pid = increment_pid
710
+ @test_object2.should respond_to(:testing_append)
711
+ @test_object2.should respond_to(:testing_remove)
712
+ #test execution in base_spec since method definitions include methods in ActiveFedora::Base
713
+ end
714
+ end
715
+
716
+ describe '#create_bidirectional_relationship_name_methods' do
717
+ before do
718
+ class MockCreateNamedRelationshipMethods < SpecNode
719
+ register_relationship_desc(:self, "testing_outbound", :is_part_of, :type=>SpecNode)
720
+ create_bidirectional_relationship_name_methods "testing", "testing_outbound"
721
+ end
722
+ end
723
+ after do
724
+ Object.send(:remove_const, :MockCreateNamedRelationshipMethods)
725
+ end
726
+
727
+ it 'should create an append and remove method for each outbound relationship' do
728
+ @test_object2 = MockCreateNamedRelationshipMethods.new
729
+ @test_object2.pid = increment_pid
730
+ @test_object2.should respond_to(:testing_append)
731
+ @test_object2.should respond_to(:testing_remove)
732
+ #test execution in base_spec since method definitions include methods in ActiveFedora::Base
733
+ end
734
+ end
735
+
736
+
737
+ #
738
+ # HYDRA-541
739
+ #
740
+
741
+ describe "bidirectional_relationship_query" do
742
+ before do
743
+ class MockBiNamedRelationshipQuery < SpecNode
744
+ register_relationship_desc(:self, "testing_query_outbound", :has_part, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
745
+ register_relationship_desc(:inbound, "testing_query_inbound", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
746
+ create_bidirectional_relationship_name_methods("testing","testing_outbound")
747
+ register_relationship_desc(:self, "testing_no_solr_fq_outbound", :has_part, :type=>SpecNode)
748
+ register_relationship_desc(:inbound, "testing_no_solr_fq_inbound", :is_part_of, :type=>SpecNode)
749
+ create_bidirectional_relationship_name_methods("testing_no_solr_fq","testing_no_solr_fq_outbound")
750
+ end
751
+ end
752
+ after do
753
+ Object.send(:remove_const, :MockBiNamedRelationshipQuery)
754
+ end
755
+
756
+ #
757
+ # HYDRA-541
758
+ #
759
+ it "should rely on outbound query if inbound query is empty" do
760
+ query = MockBiNamedRelationshipQuery.bidirectional_relationship_query("PID",:testing_query,[])
761
+ query.should_not include("OR ()")
762
+ query2 = MockBiNamedRelationshipQuery.bidirectional_relationship_query("PID",:testing_no_solr_fq,[])
763
+ query2.should_not include("OR ()")
764
+ end
765
+
766
+ it "should return a properly formatted query for a relationship that has a solr filter query defined" do
767
+ expected_string = ""
768
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4","changeme:5"]
769
+ ids.each_with_index do |id,index|
770
+ expected_string << " OR " if index > 0
771
+ expected_string << "(id:" + id.gsub(/(:)/, '\\:') + " AND has_model_s:info\\:fedora/SpecialPart)"
772
+ end
773
+ expected_string << " OR "
774
+ expected_string << "(is_part_of_s:info\\:fedora/changeme\\:6 AND has_model_s:info\\:fedora/SpecialPart)"
775
+ MockBiNamedRelationshipQuery.bidirectional_relationship_query("changeme:6","testing_query",ids).should == expected_string
776
+ end
777
+
778
+ it "should return a properly formatted query for a relationship that does not have a solr filter query defined" do
779
+ expected_string = ""
780
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4","changeme:5"]
781
+ ids.each_with_index do |id,index|
782
+ expected_string << " OR " if index > 0
783
+ expected_string << "id:" + id.gsub(/(:)/, '\\:')
784
+ end
785
+ expected_string << " OR "
786
+ expected_string << "(is_part_of_s:info\\:fedora/changeme\\:6)"
787
+ MockBiNamedRelationshipQuery.bidirectional_relationship_query("changeme:6","testing_no_solr_fq",ids).should == expected_string
788
+ end
789
+ end
790
+
791
+ describe "inbound_relationship_query" do
792
+ before do
793
+ class MockInboundNamedRelationshipQuery < SpecNode
794
+ register_relationship_desc(:inbound, "testing_inbound_query", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
795
+ register_relationship_desc(:inbound, "testing_inbound_no_solr_fq", :is_part_of, :type=>SpecNode)
796
+ end
797
+ end
798
+ after(:each) do
799
+ Object.send(:remove_const, :MockInboundNamedRelationshipQuery)
800
+ end
801
+
802
+ it "should return a properly formatted query for a relationship that has a solr filter query defined" do
803
+ MockInboundNamedRelationshipQuery.inbound_relationship_query("changeme:1","testing_inbound_query").should == "is_part_of_s:info\\:fedora/changeme\\:1 AND has_model_s:info\\:fedora/SpecialPart"
804
+ end
805
+
806
+ it "should return a properly formatted query for a relationship that does not have a solr filter query defined" do
807
+ MockInboundNamedRelationshipQuery.inbound_relationship_query("changeme:1","testing_inbound_no_solr_fq").should == "is_part_of_s:info\\:fedora/changeme\\:1"
808
+ end
809
+ end
810
+
811
+
812
+
813
+
814
+ describe "outbound_relationship_query" do
815
+ before do
816
+ class MockOutboundNamedRelationshipQuery < SpecNode
817
+ register_relationship_desc(:self, "testing_query", :is_part_of, :type=>SpecNode, :solr_fq=>"has_model_s:info\\:fedora/SpecialPart")
818
+ register_relationship_desc(:self,"testing_no_solr_fq", :is_part_of, :type=>SpecNode)
819
+ end
820
+ end
821
+ after(:each) do
822
+ Object.send(:remove_const, :MockOutboundNamedRelationshipQuery)
823
+ end
824
+
825
+ it "should return a properly formatted query for a relationship that has a solr filter query defined" do
826
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4"]
827
+ expected_string = ""
828
+ ids.each_with_index do |id,index|
829
+ expected_string << " OR " if index > 0
830
+ expected_string << "(id:" + id.gsub(/(:)/, '\\:') + " AND has_model_s:info\\:fedora/SpecialPart)"
831
+ end
832
+ MockOutboundNamedRelationshipQuery.outbound_relationship_query("testing_query",ids).should == expected_string
833
+ end
834
+
835
+ it "should return a properly formatted query for a relationship that does not have a solr filter query defined" do
836
+ expected_string = ""
837
+ ids = ["changeme:1","changeme:2","changeme:3","changeme:4"]
838
+ ids.each_with_index do |id,index|
839
+ expected_string << " OR " if index > 0
840
+ expected_string << "id:" + id.gsub(/(:)/, '\\:')
841
+ end
842
+ MockOutboundNamedRelationshipQuery.outbound_relationship_query("testing_no_solr_fq",ids).should == expected_string
843
+ end
844
+ end
845
+ end
846
+ end