treequel 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/ChangeLog +130 -1
  2. data/Rakefile +8 -3
  3. data/Rakefile.local +2 -0
  4. data/bin/treeirb +6 -2
  5. data/bin/treequel +5 -4
  6. data/lib/treequel/branch.rb +133 -72
  7. data/lib/treequel/branchcollection.rb +16 -5
  8. data/lib/treequel/branchset.rb +37 -6
  9. data/lib/treequel/constants.rb +12 -0
  10. data/lib/treequel/directory.rb +96 -41
  11. data/lib/treequel/filter.rb +42 -1
  12. data/lib/treequel/model/objectclass.rb +111 -0
  13. data/lib/treequel/model.rb +363 -0
  14. data/lib/treequel/monkeypatches.rb +65 -0
  15. data/lib/treequel/schema/attributetype.rb +108 -18
  16. data/lib/treequel/schema/ldapsyntax.rb +15 -0
  17. data/lib/treequel/schema/matchingrule.rb +24 -0
  18. data/lib/treequel/schema/matchingruleuse.rb +24 -0
  19. data/lib/treequel/schema/objectclass.rb +70 -5
  20. data/lib/treequel/schema/table.rb +5 -15
  21. data/lib/treequel/schema.rb +64 -1
  22. data/lib/treequel.rb +5 -5
  23. data/rake/documentation.rb +27 -0
  24. data/rake/hg.rb +14 -2
  25. data/rake/manual.rb +1 -1
  26. data/spec/lib/constants.rb +9 -7
  27. data/spec/lib/control_behavior.rb +1 -0
  28. data/spec/lib/matchers.rb +1 -0
  29. data/spec/treequel/branch_spec.rb +229 -20
  30. data/spec/treequel/branchcollection_spec.rb +73 -39
  31. data/spec/treequel/branchset_spec.rb +59 -8
  32. data/spec/treequel/control_spec.rb +1 -0
  33. data/spec/treequel/controls/contentsync_spec.rb +1 -0
  34. data/spec/treequel/controls/pagedresults_spec.rb +1 -0
  35. data/spec/treequel/controls/sortedresults_spec.rb +1 -0
  36. data/spec/treequel/directory_spec.rb +46 -10
  37. data/spec/treequel/filter_spec.rb +28 -5
  38. data/spec/treequel/mixins_spec.rb +7 -14
  39. data/spec/treequel/model/objectclass_spec.rb +330 -0
  40. data/spec/treequel/model_spec.rb +433 -0
  41. data/spec/treequel/monkeypatches_spec.rb +118 -0
  42. data/spec/treequel/schema/attributetype_spec.rb +116 -0
  43. data/spec/treequel/schema/ldapsyntax_spec.rb +8 -0
  44. data/spec/treequel/schema/matchingrule_spec.rb +6 -1
  45. data/spec/treequel/schema/matchingruleuse_spec.rb +5 -0
  46. data/spec/treequel/schema/objectclass_spec.rb +41 -3
  47. data/spec/treequel/schema/table_spec.rb +31 -18
  48. data/spec/treequel/schema_spec.rb +13 -16
  49. data/spec/treequel_spec.rb +22 -0
  50. data.tar.gz.sig +1 -0
  51. metadata +40 -7
  52. metadata.gz.sig +0 -0
  53. data/spec/treequel/utils_spec.rb +0 -49
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -172,16 +173,38 @@ describe Treequel::Branchset do
172
173
  result.branchsets.should include( @branchset, other_branchset )
173
174
  end
174
175
 
175
- they "can be combined with a Branch into a BranchCollection by adding it" do
176
- other_branch = mock( "second treequel branch", :dn => 'theotherdn' )
177
- other_branch.stub!( :directory ).and_return( @directory )
176
+ they "return the results of the search with the additional Branch if one is added to it" do
177
+ other_branch = mock( "additional treequel branch", :dn => 'theotherdn' )
178
+ other_branch.stub!( :to_ary ).and_return( [other_branch] )
179
+ resultbranch = mock( "Result Branch" )
180
+ resultbranch2 = mock( "Result Branch 2" )
181
+
182
+ @branch.should_receive( :search ).
183
+ with( Treequel::Branchset::DEFAULT_SCOPE, @branchset.filter, @params ).
184
+ and_yield( resultbranch ).and_yield( resultbranch2 )
178
185
 
179
186
  result = @branchset + other_branch
180
- result.should be_a( Treequel::BranchCollection )
181
- result.branchsets.should have( 2 ).members
182
- result.branchsets.should include( @branchset )
183
- result.branchsets.select {|bs| bs != @branchset }.
184
- first.branch.should == other_branch
187
+ result.should have( 3 ).members
188
+ result.should include( other_branch, resultbranch, resultbranch2 )
189
+ end
190
+
191
+ #
192
+ # #-
193
+ #
194
+ they "return the results of the search without the specified object if an object is " +
195
+ "subtracted from it" do
196
+ resultbranch = stub( "Result Branch", :dn => TEST_PERSON_DN )
197
+ resultbranch2 = stub( "Result Branch 2", :dn => TEST_PERSON2_DN )
198
+
199
+ otherbranch = stub( "Subtracted Branch", :dn => TEST_PERSON2_DN )
200
+
201
+ @branch.should_receive( :search ).
202
+ with( Treequel::Branchset::DEFAULT_SCOPE, @branchset.filter, @params ).
203
+ and_yield( resultbranch ).and_yield( resultbranch2 )
204
+
205
+ result = @branchset - otherbranch
206
+ result.should have( 1 ).members
207
+ result.should_not include( resultbranch2 )
185
208
  end
186
209
 
187
210
  end
@@ -233,6 +256,24 @@ describe Treequel::Branchset do
233
256
  newset.filter_string.should == '(clothing=pants)'
234
257
  end
235
258
 
259
+ #
260
+ # #or
261
+ #
262
+
263
+ it "creates a new branchset cloned from itself with an OR clause added to to an " +
264
+ "existing filter" do
265
+ pantset = @branchset.filter( :clothing => 'pants' )
266
+ bothset = pantset.or( :clothing => 'shirt' )
267
+
268
+ bothset.filter_string.should == '(|(clothing=pants)(clothing=shirt))'
269
+ end
270
+
271
+ it "raises an exception if #or is invoked without an existing filter" do
272
+ expect {
273
+ @branchset.or( :clothing => 'shirt' )
274
+ }.to raise_exception( Treequel::ExpressionError, /no existing filter/i )
275
+ end
276
+
236
277
  #
237
278
  # #scope
238
279
  #
@@ -287,6 +328,12 @@ describe Treequel::Branchset do
287
328
  newset.select.should == [ 'l', 'cn', 'uid', 'firstName', 'lastName' ]
288
329
  end
289
330
 
331
+ it "adding attributes via #select_more should work even if there was no current " +
332
+ "attribute selection" do
333
+ newset = @branchset.select_more( :firstName, :uid, :lastName, :objectClass )
334
+ newset.select.should include( 'uid', 'firstName', 'lastName', 'objectClass' )
335
+ end
336
+
290
337
  it "uses its selection as the list of attributes to fetch when searching" do
291
338
  @branchset.options[:select] = [ :l, :cn, :uid ]
292
339
  @branch.should_receive( :search ).
@@ -432,6 +479,10 @@ describe Treequel::Branchset do
432
479
  @directory.stub!( :registered_controls ).and_return([ @control ])
433
480
  end
434
481
 
482
+ after( :each ) do
483
+ @directory = nil
484
+ end
485
+
435
486
  it "extends instances of itself with any controls registered with its Branch's Directory" do
436
487
  set = Treequel::Branchset.new( @branch )
437
488
  set.should respond_to( :yep )
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -6,6 +6,7 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
@@ -88,6 +89,22 @@ describe Treequel::Directory do
88
89
  @dir.base_dn.should == TEST_BASE_DN
89
90
  end
90
91
 
92
+ it "can return its root element as a Branch instance" do
93
+ @dir = Treequel::Directory.new( @options )
94
+ @dir.base.should be_a( Treequel::Branch )
95
+ @dir.base.dn.should == TEST_BASE_DN
96
+ end
97
+
98
+ it "can return its root element as an instance of its results class if it's been set" do
99
+ subtype = Class.new( Treequel::Branch )
100
+ @dir = Treequel::Directory.new( @options )
101
+
102
+ @dir.results_class = subtype
103
+
104
+ @dir.base.should be_a( subtype )
105
+ @dir.base.dn.should == TEST_BASE_DN
106
+ end
107
+
91
108
 
92
109
  describe "instances without existing connections" do
93
110
 
@@ -539,22 +556,40 @@ describe Treequel::Directory do
539
556
 
540
557
  ### Datatype conversion
541
558
 
542
- it "allows a mapping to be overridden by a block for a valid syntax OID" do
543
- @dir.add_syntax_mapping( OIDS::BIT_STRING_SYNTAX ) do |unconverted_value|
559
+ it "allows an attribute conversion to be overridden by a block for a valid syntax OID" do
560
+ @dir.add_attribute_conversion( OIDS::BIT_STRING_SYNTAX ) do |unconverted_value, directory|
544
561
  unconverted_value.to_sym
545
562
  end
546
- @dir.convert_syntax_value( OIDS::BIT_STRING_SYNTAX, 'a_value' ).should == :a_value
563
+ @dir.convert_to_object( OIDS::BIT_STRING_SYNTAX, 'a_value' ).should == :a_value
564
+ end
565
+
566
+ it "allows an attribute conversion to be overridden by a Hash for a valid syntax OID" do
567
+ @dir.add_attribute_conversion( OIDS::BOOLEAN_SYNTAX, {'true' => true, 'false' => false} )
568
+ @dir.convert_to_object( OIDS::BOOLEAN_SYNTAX, 'true' ).should == true
569
+ end
570
+
571
+ it "allows an attribute conversion to be cleared by adding a nil mapping" do
572
+ @dir.add_attribute_conversion( OIDS::BOOLEAN_SYNTAX, {'true' => true, 'false' => false} )
573
+ @dir.add_attribute_conversion( OIDS::BOOLEAN_SYNTAX )
574
+ @dir.convert_to_object( OIDS::BOOLEAN_SYNTAX, 'true' ).should == 'true'
575
+ end
576
+
577
+ it "allows an object conversion to be overridden by a block for a valid syntax OID" do
578
+ @dir.add_object_conversion( OIDS::BIT_STRING_SYNTAX ) do |unconverted_value, directory|
579
+ unconverted_value.to_s
580
+ end
581
+ @dir.convert_to_attribute( OIDS::BIT_STRING_SYNTAX, :a_value ).should == 'a_value'
547
582
  end
548
583
 
549
- it "allows a mapping to be overridden by a Hash for a valid syntax OID" do
550
- @dir.add_syntax_mapping( OIDS::BOOLEAN_SYNTAX, {'true' => true, 'false' => false} )
551
- @dir.convert_syntax_value( OIDS::BOOLEAN_SYNTAX, 'true' ).should == true
584
+ it "allows an object conversion to be overridden by a Hash for a valid syntax OID" do
585
+ @dir.add_object_conversion( OIDS::BOOLEAN_SYNTAX, {false => 'FALSE', true => 'TRUE'} )
586
+ @dir.convert_to_attribute( OIDS::BOOLEAN_SYNTAX, false ).should == 'FALSE'
552
587
  end
553
588
 
554
- it "allows a mapping to be cleared by adding a nil mapping" do
555
- @dir.add_syntax_mapping( OIDS::BOOLEAN_SYNTAX, {'true' => true, 'false' => false} )
556
- @dir.add_syntax_mapping( OIDS::BOOLEAN_SYNTAX )
557
- @dir.convert_syntax_value( OIDS::BOOLEAN_SYNTAX, 'true' ).should == 'true'
589
+ it "allows an object conversion to be cleared by adding a nil mapping" do
590
+ @dir.add_object_conversion( OIDS::BOOLEAN_SYNTAX, {'true' => true, 'false' => false} )
591
+ @dir.add_object_conversion( OIDS::BOOLEAN_SYNTAX )
592
+ @dir.convert_to_attribute( OIDS::BOOLEAN_SYNTAX, true ).should == 'true'
558
593
  end
559
594
 
560
595
 
@@ -591,6 +626,7 @@ describe Treequel::Directory do
591
626
  end
592
627
 
593
628
  it "raises an exception if a registered control doesn't define an OID" do
629
+ @control.const_set( :OID, nil )
594
630
  expect {
595
631
  @dir.register_controls( @control )
596
632
  }.to raise_error( NotImplementedError, /doesn't define/i )
@@ -6,12 +6,10 @@ BEGIN {
6
6
 
7
7
  libdir = basedir + "lib"
8
8
 
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
9
10
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
10
11
  }
11
12
 
12
- require 'rubygems'
13
- gem 'rspec', '>= 1.2.6'
14
-
15
13
  require 'spec'
16
14
  require 'spec/lib/constants'
17
15
  require 'spec/lib/helpers'
@@ -221,13 +219,27 @@ describe Treequel::Filter do
221
219
  result.should == @filter1
222
220
  end
223
221
 
222
+ it "creates a new OR filter out of two filters that are bitwise-ORed together" do
223
+ result = @filter1 | @filter2
224
+ result.should be_a( Treequel::Filter )
225
+ end
226
+
227
+ it "collapses two OR filters into a single OR clause when bitwise-ORed together" do
228
+ orfilter = @filter1 | @filter2
229
+ thirdfilter = Treequel::Filter.new( :l => :saturn )
230
+ result = ( orfilter | thirdfilter )
231
+
232
+ result.should be_a( Treequel::Filter )
233
+ result.to_s.should == '(|(uid=buckrogers)(l=mars)(l=saturn))'
234
+ end
235
+
224
236
  end
225
237
 
226
238
  describe "components:" do
227
239
 
228
240
  before( :each ) do
229
- @filter1 = stub( "filter1", :to_s => '(filter1)' )
230
- @filter2 = stub( "filter2", :to_s => '(filter2)' )
241
+ @filter1 = Treequel::Filter.new( '(filter1)' )
242
+ @filter2 = Treequel::Filter.new( '(filter2)' )
231
243
  end
232
244
 
233
245
 
@@ -236,6 +248,12 @@ describe Treequel::Filter do
236
248
  Treequel::Filter::FilterList.new( @filter1, @filter2 ).to_s.
237
249
  should == '(filter1)(filter2)'
238
250
  end
251
+
252
+ it "supports appending via the << operator" do
253
+ list = Treequel::Filter::FilterList.new( @filter1 )
254
+ ( list << @filter2 ).should == list
255
+ list.to_s.should == '(filter1)(filter2)'
256
+ end
239
257
  end
240
258
 
241
259
  describe Treequel::Filter::Component do
@@ -365,6 +383,11 @@ describe Treequel::Filter do
365
383
  should == '|(filter1)'
366
384
  end
367
385
 
386
+ it "allows futher alternations to be added to it" do
387
+ filter = Treequel::Filter::OrComponent.new( @filter1 )
388
+ filter.add_alternation( @filter2 )
389
+ filter.to_s.should == '|(filter1)(filter2)'
390
+ end
368
391
  end
369
392
 
370
393
  describe Treequel::Filter::NotComponent do
@@ -7,24 +7,17 @@ BEGIN {
7
7
  libdir = basedir + "lib"
8
8
  extdir = basedir + "ext"
9
9
 
10
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
10
11
  $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
11
12
  $LOAD_PATH.unshift( extdir ) unless $LOAD_PATH.include?( extdir )
12
13
  }
13
14
 
14
- begin
15
- require 'spec'
16
- require 'spec/lib/constants'
17
- require 'spec/lib/helpers'
18
-
19
- require 'treequel'
20
- require 'treequel/mixins'
21
- rescue LoadError
22
- unless Object.const_defined?( :Gem )
23
- require 'rubygems'
24
- retry
25
- end
26
- raise
27
- end
15
+ require 'spec'
16
+ require 'spec/lib/constants'
17
+ require 'spec/lib/helpers'
18
+
19
+ require 'treequel'
20
+ require 'treequel/mixins'
28
21
 
29
22
 
30
23
  include Treequel::TestConstants
@@ -0,0 +1,330 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BEGIN {
4
+ require 'pathname'
5
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent
6
+
7
+ libdir = basedir + "lib"
8
+
9
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
10
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
11
+ }
12
+
13
+ require 'spec'
14
+ require 'spec/lib/constants'
15
+ require 'spec/lib/helpers'
16
+ require 'spec/lib/matchers'
17
+
18
+ require 'treequel/model'
19
+ require 'treequel/model/objectclass'
20
+ require 'treequel/branchset'
21
+
22
+
23
+ include Treequel::TestConstants
24
+ include Treequel::Constants
25
+
26
+ #####################################################################
27
+ ### C O N T E X T S
28
+ #####################################################################
29
+
30
+ describe Treequel::Model::ObjectClass do
31
+ include Treequel::SpecHelpers,
32
+ Treequel::Matchers
33
+
34
+ class << self
35
+ alias_method :they, :it
36
+ end
37
+
38
+ before( :all ) do
39
+ setup_logging( :fatal )
40
+ end
41
+
42
+ after( :all ) do
43
+ reset_logging()
44
+ end
45
+
46
+
47
+ it "outputs a warning when it is included instead of used to extend a Module" do
48
+ Treequel::Model::ObjectClass.should_receive( :warn ).
49
+ with( /extending.*rather than appending/i )
50
+ mixin = Module.new do
51
+ include Treequel::Model::ObjectClass
52
+ end
53
+ end
54
+
55
+
56
+ describe "modules" do
57
+
58
+ after( :each ) do
59
+ Treequel::Model.objectclass_registry.clear
60
+ Treequel::Model.base_registry.clear
61
+ end
62
+
63
+ they "can declare a required objectClass" do
64
+ mixin = Module.new do
65
+ extend Treequel::Model::ObjectClass
66
+ model_objectclasses :inetOrgPerson
67
+ end
68
+
69
+ mixin.model_objectclasses.should == [:inetOrgPerson]
70
+ end
71
+
72
+ they "can declare multiple required objectClasses" do
73
+ mixin = Module.new do
74
+ extend Treequel::Model::ObjectClass
75
+ model_objectclasses :inetOrgPerson, :acmeAccount
76
+ end
77
+
78
+ mixin.model_objectclasses.should == [ :inetOrgPerson, :acmeAccount ]
79
+ end
80
+
81
+ they "can declare a single base" do
82
+ mixin = Module.new do
83
+ extend Treequel::Model::ObjectClass
84
+ model_objectclasses :device
85
+ model_bases TEST_PHONES_DN
86
+ end
87
+
88
+ mixin.model_bases.should == [TEST_PHONES_DN]
89
+ end
90
+
91
+ they "can declare base with spaces" do
92
+ mixin = Module.new do
93
+ extend Treequel::Model::ObjectClass
94
+ model_objectclasses :device
95
+ model_bases 'ou=phones, dc=acme, dc=com'
96
+ end
97
+
98
+ mixin.model_bases.should == ['ou=phones,dc=acme,dc=com']
99
+ end
100
+
101
+ they "can declare multiple bases" do
102
+ mixin = Module.new do
103
+ extend Treequel::Model::ObjectClass
104
+ model_objectclasses :ipHost
105
+ model_bases TEST_HOSTS_DN,
106
+ TEST_SUBHOSTS_DN
107
+ end
108
+
109
+ mixin.model_bases.should include( TEST_HOSTS_DN, TEST_SUBHOSTS_DN )
110
+ end
111
+
112
+ they "raises an exception when creating a search for a mixin that hasn't declared " +
113
+ "at least one objectClass or base" do
114
+ mixin = Module.new do
115
+ extend Treequel::Model::ObjectClass
116
+ end
117
+
118
+ expect {
119
+ mixin.search( @directory )
120
+ }.to raise_exception( Treequel::ModelError, /has no search criteria defined/ )
121
+ end
122
+
123
+ they "default to using Treequel::Model as their model class" do
124
+ mixin = Module.new do
125
+ extend Treequel::Model::ObjectClass
126
+ end
127
+
128
+ mixin.model_class.should == Treequel::Model
129
+ end
130
+
131
+ they "can declare a model class other than Treequel::Model" do
132
+ class MyModel < Treequel::Model; end
133
+ mixin = Module.new do
134
+ extend Treequel::Model::ObjectClass
135
+ model_class MyModel
136
+ end
137
+
138
+ mixin.model_class.should == MyModel
139
+ end
140
+
141
+ they "re-register objectClasses that have already been declared when declaring a " +
142
+ "new model class" do
143
+ class MyModel < Treequel::Model; end
144
+
145
+ mixin = Module.new do
146
+ extend Treequel::Model::ObjectClass
147
+ model_objectclasses :inetOrgPerson
148
+ model_class MyModel
149
+ end
150
+
151
+ Treequel::Model.objectclass_registry[:inetOrgPerson].should_not include( mixin )
152
+ MyModel.objectclass_registry[:inetOrgPerson].should include( mixin )
153
+ end
154
+
155
+ they "re-register bases that have already been declared when declaring a " +
156
+ "new model class" do
157
+ class MyModel < Treequel::Model; end
158
+
159
+ mixin = Module.new do
160
+ extend Treequel::Model::ObjectClass
161
+ model_bases 'ou=people,dc=acme,dc=com', 'ou=notpeople,dc=acme,dc=com'
162
+ model_class MyModel
163
+ end
164
+
165
+ Treequel::Model.base_registry['ou=people,dc=acme,dc=com'].should_not include( mixin )
166
+ MyModel.base_registry['ou=people,dc=acme,dc=com'].should include( mixin )
167
+ end
168
+
169
+ end
170
+
171
+ describe "module that has one required objectClass declared" do
172
+
173
+ before( :each ) do
174
+ @mixin = Module.new do
175
+ extend Treequel::Model::ObjectClass
176
+ model_objectclasses :inetOrgPerson
177
+ end
178
+ end
179
+
180
+ after( :each ) do
181
+ Treequel::Model.objectclass_registry.clear
182
+ end
183
+
184
+
185
+ it "is returned as one of the mixins for entries with only that objectClass" do
186
+ Treequel::Model.mixins_for_objectclasses( :inetOrgPerson ).
187
+ should include( @mixin )
188
+ end
189
+
190
+ it "is not returned in the list of mixins to apply to an entry without that objectClass" do
191
+ Treequel::Model.mixins_for_objectclasses( :device ).
192
+ should_not include( @mixin )
193
+ end
194
+
195
+ it "can set up a search for applicable entries given a Treequel::Directory to " +
196
+ "search" do
197
+ directory = mock( "Treequel directory", :registered_controls => [] )
198
+ directory.should_receive( :base_dn ).and_return( TEST_BASE_DN )
199
+
200
+ result = @mixin.search( directory )
201
+
202
+ result.should be_a( Treequel::Branchset )
203
+ result.base_dn.should == TEST_BASE_DN
204
+ result.filter.to_s.should == '(objectClass=inetOrgPerson)'
205
+ end
206
+
207
+ end
208
+
209
+ describe "module that has more than one required objectClass declared" do
210
+
211
+ before( :each ) do
212
+ @mixin = Module.new do
213
+ extend Treequel::Model::ObjectClass
214
+ model_objectclasses :device, :ipHost
215
+ end
216
+ end
217
+
218
+ after( :each ) do
219
+ Treequel::Model.objectclass_registry.clear
220
+ end
221
+
222
+
223
+ it "is returned as one of the mixins to apply to entries with all of its required " +
224
+ "objectClasses" do
225
+ Treequel::Model.mixins_for_objectclasses( :device, :ipHost ).
226
+ should include( @mixin )
227
+ end
228
+
229
+ it "is not returned in the list of mixins to apply to an entry with only one of its " +
230
+ "objectClasses" do
231
+ Treequel::Model.mixins_for_objectclasses( :device ).
232
+ should_not include( @mixin )
233
+ end
234
+
235
+ it "can set up a search for applicable entries given a Treequel::Directory to " +
236
+ "search" do
237
+ directory = mock( "Treequel directory", :registered_controls => [] )
238
+ directory.should_receive( :base_dn ).and_return( TEST_BASE_DN )
239
+
240
+ result = @mixin.search( directory )
241
+
242
+ result.should be_a( Treequel::Branchset )
243
+ result.base_dn.should == TEST_BASE_DN
244
+ result.filter.to_s.should == '(&(objectClass=device)(objectClass=ipHost))'
245
+ end
246
+
247
+ end
248
+
249
+ describe "module that has one base declared" do
250
+ before( :each ) do
251
+ @mixin = Module.new do
252
+ extend Treequel::Model::ObjectClass
253
+ model_bases TEST_PEOPLE_DN
254
+ end
255
+ end
256
+
257
+ after( :each ) do
258
+ Treequel::Model.base_registry.clear
259
+ end
260
+
261
+
262
+ it "is returned as one of the mixins to apply to an entry that is a child of its base" do
263
+ Treequel::Model.mixins_for_dn( TEST_PERSON_DN ).
264
+ should include( @mixin )
265
+ end
266
+
267
+ it "is not returned as one of the mixins to apply to an entry that is not a child of " +
268
+ "its base" do
269
+ Treequel::Model.mixins_for_dn( TEST_ROOM_DN ).
270
+ should_not include( @mixin )
271
+ end
272
+
273
+ it "can set up a search for applicable entries given a Treequel::Directory to " +
274
+ "search" do
275
+ directory = stub( "Treequel directory", :registered_controls => [] )
276
+
277
+ result = @mixin.search( directory )
278
+
279
+ result.should be_a( Treequel::Branchset )
280
+ result.base_dn.should == TEST_PEOPLE_DN
281
+ result.filter.to_s.should == '(objectClass=*)'
282
+ end
283
+
284
+ end
285
+
286
+ describe "module that has more than one base declared" do
287
+ before( :each ) do
288
+ @mixin = Module.new do
289
+ extend Treequel::Model::ObjectClass
290
+ model_bases TEST_HOSTS_DN,
291
+ TEST_SUBHOSTS_DN
292
+ end
293
+ end
294
+
295
+ after( :each ) do
296
+ Treequel::Model.base_registry.clear
297
+ end
298
+
299
+
300
+ it "is returned as one of the mixins to apply to an entry that is a child of one of " +
301
+ "its bases" do
302
+ Treequel::Model.mixins_for_dn( TEST_SUBHOST_DN ).
303
+ should include( @mixin )
304
+ end
305
+
306
+ it "is not returned as one of the mixins to apply to an entry that is not a child of " +
307
+ "its base" do
308
+ Treequel::Model.mixins_for_dn( TEST_PERSON_DN ).
309
+ should_not include( @mixin )
310
+ end
311
+
312
+ it "can set up a search for applicable entries given a Treequel::Directory to " +
313
+ "search" do
314
+ directory = stub( "Treequel directory", :registered_controls => [] )
315
+
316
+ result = @mixin.search( directory )
317
+
318
+ result.should be_a( Treequel::BranchCollection )
319
+ result.base_dns.should have( 2 ).members
320
+ result.base_dns.should include( TEST_HOSTS_DN, TEST_SUBHOSTS_DN )
321
+ result.branchsets.all? {|brset| brset.filter_string == '(objectClass=*)' }.
322
+ should be_true()
323
+ end
324
+
325
+ end
326
+
327
+ end
328
+
329
+
330
+ # vim: set nosta noet ts=4 sw=4: