ldaptic 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +104 -0
  3. data/Rakefile +41 -0
  4. data/lib/ldaptic.rb +151 -0
  5. data/lib/ldaptic/active_model.rb +37 -0
  6. data/lib/ldaptic/adapters.rb +90 -0
  7. data/lib/ldaptic/adapters/abstract_adapter.rb +123 -0
  8. data/lib/ldaptic/adapters/active_directory_adapter.rb +78 -0
  9. data/lib/ldaptic/adapters/active_directory_ext.rb +12 -0
  10. data/lib/ldaptic/adapters/ldap_conn_adapter.rb +262 -0
  11. data/lib/ldaptic/adapters/net_ldap_adapter.rb +173 -0
  12. data/lib/ldaptic/adapters/net_ldap_ext.rb +24 -0
  13. data/lib/ldaptic/attribute_set.rb +283 -0
  14. data/lib/ldaptic/dn.rb +365 -0
  15. data/lib/ldaptic/entry.rb +646 -0
  16. data/lib/ldaptic/error_set.rb +34 -0
  17. data/lib/ldaptic/errors.rb +136 -0
  18. data/lib/ldaptic/escape.rb +110 -0
  19. data/lib/ldaptic/filter.rb +282 -0
  20. data/lib/ldaptic/methods.rb +387 -0
  21. data/lib/ldaptic/railtie.rb +9 -0
  22. data/lib/ldaptic/schema.rb +246 -0
  23. data/lib/ldaptic/syntaxes.rb +319 -0
  24. data/test/core.schema +582 -0
  25. data/test/ldaptic_active_model_test.rb +40 -0
  26. data/test/ldaptic_adapters_test.rb +35 -0
  27. data/test/ldaptic_attribute_set_test.rb +57 -0
  28. data/test/ldaptic_dn_test.rb +110 -0
  29. data/test/ldaptic_entry_test.rb +22 -0
  30. data/test/ldaptic_errors_test.rb +23 -0
  31. data/test/ldaptic_escape_test.rb +47 -0
  32. data/test/ldaptic_filter_test.rb +53 -0
  33. data/test/ldaptic_hierarchy_test.rb +90 -0
  34. data/test/ldaptic_schema_test.rb +44 -0
  35. data/test/ldaptic_syntaxes_test.rb +66 -0
  36. data/test/mock_adapter.rb +47 -0
  37. data/test/rbslapd1.rb +111 -0
  38. data/test/rbslapd4.rb +172 -0
  39. data/test/test_helper.rb +2 -0
  40. metadata +146 -0
@@ -0,0 +1,40 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic'
3
+ require File.join(File.dirname(File.expand_path(__FILE__)),'/mock_adapter')
4
+ require 'active_model'
5
+
6
+ class LdapticActiveModelTest < Test::Unit::TestCase
7
+ include ActiveModel::Lint::Tests
8
+
9
+ class Mock < Ldaptic::Class(:adapter => :mock)
10
+ end
11
+
12
+ def setup
13
+ @model = Mock::Person.new
14
+ end
15
+
16
+ def test_changes
17
+ @model.description = 'Bar'
18
+ assert_equal ['Bar'], @model.changes['description']
19
+ end
20
+
21
+ def test_errors
22
+ assert @model.invalid?
23
+ assert_equal ['Common name is mandatory'], @model.errors.full_messages
24
+ @model.cn = 'Douglas'
25
+ @model.age = 'forty two'
26
+ assert @model.invalid?
27
+ assert_equal ['Age must be an integer'], @model.errors.full_messages
28
+ @model.age = 42
29
+ assert @model.valid?
30
+ @model[:userPassword] = 'lol'
31
+ assert @model.invalid?
32
+ assert_equal ['User password is forbidden'], @model.errors.full_messages
33
+ end
34
+
35
+ def test_before_type_cast
36
+ @model.description = ''
37
+ assert_equal [], @model.description_before_type_cast
38
+ end
39
+
40
+ end
@@ -0,0 +1,35 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic/adapters'
3
+ require 'ldaptic/adapters/net_ldap_adapter'
4
+ require 'ldaptic/adapters/ldap_conn_adapter'
5
+
6
+ class LdapticAdaptersTest < Test::Unit::TestCase
7
+ def setup
8
+ @ldap_conn = Ldaptic::Adapters::LDAPConnAdapter.allocate
9
+ @net_ldap = Ldaptic::Adapters::NetLDAPAdapter.allocate
10
+ end
11
+
12
+ def test_should_parameterize_search_options
13
+ assert_equal(
14
+ ["DC=org", 0, "(objectClass=*)", nil, false, 1, 10_000, "", nil],
15
+ @ldap_conn.instance_eval { search_parameters(
16
+ :base => "DC=org",
17
+ :scope => 0,
18
+ :filter => "(objectClass=*)",
19
+ :attributes_only => false,
20
+ :timeout => 1.01
21
+ )}
22
+ )
23
+ end
24
+
25
+ def test_should_recapitalize
26
+ assert_equal "objectClass", @net_ldap.instance_eval { recapitalize("objectclass") }
27
+ end
28
+
29
+ def test_should_reject_invalid_adapter_options
30
+ assert_raise(ArgumentError) { Ldaptic::Adapters.for(:adapter => "fake") }
31
+ assert_raise(TypeError) { Ldaptic::Adapters.for(Object.new) }
32
+ assert_not_nil Ldaptic::Adapters.for(@ldap_conn)
33
+ end
34
+
35
+ end
@@ -0,0 +1,57 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic'
3
+ require File.join(File.dirname(File.expand_path(__FILE__)),'/mock_adapter')
4
+
5
+ class LdapticAttributeSetTest < Test::Unit::TestCase
6
+ class Mock < Ldaptic::Class(:adapter => :mock)
7
+ end
8
+
9
+ def setup
10
+ @person = Mock::Person.new(:dn => "CN=Matz,DC=org", :description => "Foo")
11
+ @description = @person.description
12
+ end
13
+
14
+ def test_should_replace_description
15
+ assert_same @description, @description.replace("bar", "baz")
16
+ assert_equal ["bar", "baz"], @description
17
+ end
18
+
19
+ def test_should_add_to_description
20
+ assert_same @description, @description.add("bar")
21
+ assert_equal %w(Foo bar), @description
22
+ assert_same @description, @description << "baz"
23
+ assert_equal %w(Foo bar baz), @description
24
+ end
25
+
26
+ def test_should_delete_from_description
27
+ assert_equal "Foo", @description.delete("fOO")
28
+ assert_same @description, @description.delete("a", "b", "c")
29
+ end
30
+
31
+ def test_should_act_like_array
32
+ assert_equal ["Foo"], @description
33
+ @description.map! { |x| x.downcase }
34
+ assert_same @description, @description.concat(["bar"])
35
+ assert_equal ["foo", "bar"], @description
36
+ assert_same @description, @description.unshift([["baz"]])
37
+ assert_equal ["baz", "foo", "bar"], @description
38
+ assert_equal "foo", @description.delete("foo")
39
+ assert_nil @description.delete("foo")
40
+ @description.clear
41
+ assert_equal [], @description
42
+ end
43
+
44
+ def test_should_join_on_to_s
45
+ @description.replace("foo", "bar")
46
+ assert_equal "foo\nbar", @description.to_s
47
+ end
48
+
49
+ def test_should_add_angles_on_inspect
50
+ assert_equal '<["Foo"]>', @description.inspect
51
+ end
52
+
53
+ def test_should_humanize
54
+ assert_equal 'Description', @description.human_name
55
+ end
56
+
57
+ end
@@ -0,0 +1,110 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
2
+ require 'ldaptic/dn'
3
+ require 'test/unit'
4
+
5
+ class LdapticDNTest < Test::Unit::TestCase
6
+
7
+ class FakeSearch
8
+ def search(options)
9
+ [options] end
10
+ end
11
+
12
+ class FakeSearch2
13
+ def search2(*args)
14
+ [args]
15
+ end
16
+ alias search2_ext search2
17
+ end
18
+
19
+ def test_constructor
20
+ assert_equal "dc=foo,ba=\\23#\\20,zy=x", Ldaptic::DN([{"dc"=>"foo"},{"ba"=>"## "},{"zy"=>"x"}]).downcase
21
+ assert_equal %w(BA=bar DC=foo), Ldaptic::DN([{:dc=>"foo",:ba=>"bar"}]).split('+').sort
22
+ assert_equal "DC=pragprog,DC=com", Ldaptic::DN("pragprog.com")
23
+ assert_equal "DC=com", Ldaptic::DN(:dc=>"com")
24
+ assert_equal nil, Ldaptic::DN(nil)
25
+ end
26
+
27
+ def test_rdns
28
+ assert_equal [{:dc=>"pragprog"},{:dc=>"com"}], Ldaptic::DN("dc=pragprog,dc=com").rdns
29
+ assert_equal [{:a=>",",:b=>"+"},{:c=>"\\"}], Ldaptic::DN("a=\\,+b=\\+,c=\\\\").rdns
30
+ assert_equal [{:a=>" #"}], Ldaptic::DN("a=\\20\\#").rdns
31
+ assert_equal [{:a=>"bcdefg"}], Ldaptic::DN("a=#626364656667").rdns
32
+ assert Ldaptic::DN("DC=foo").include?(:dc=>"Foo")
33
+ assert !Ldaptic::DN("dc=foo").include?(:dc=>"Bar")
34
+ end
35
+
36
+ def test_parent
37
+ assert_equal Ldaptic::DN("dc=com"), Ldaptic::DN("dc=pragprog,dc=com").parent
38
+ assert_instance_of Ldaptic::RDN, Ldaptic::DN("dc=pragprog,dc=com").rdn
39
+ end
40
+
41
+ def test_children
42
+ assert_equal Ldaptic::DN("dc=pragprog,dc=com"), Ldaptic::DN("dc=com")/"dc=pragprog"
43
+ assert_equal Ldaptic::DN("DC=pragprog,DC=com"), Ldaptic::DN([:dc=>"com"])/{:dc=>"pragprog"}
44
+ assert_equal Ldaptic::DN("DC=pragprog,DC=com"), Ldaptic::DN([:dc=>"com"])[:dc=>"pragprog"]
45
+ dn = Ldaptic::DN("DC=com")
46
+ dn << {:dc=>"pragprog"}
47
+ assert_equal Ldaptic::DN("DC=pragprog,DC=com"), dn
48
+ end
49
+
50
+ def test_equality
51
+ assert_equal Ldaptic::DN("dc=foo"), Ldaptic::DN("DC=foo")
52
+ assert_equal Ldaptic::RDN(:dc => "com"), Ldaptic::RDN('DC' => 'COM')
53
+ assert Ldaptic::RDN(:dc => "com") != {Object.new => true}
54
+ assert Ldaptic::RDN(:dc => "com") != 42
55
+ end
56
+
57
+ def test_still_acts_like_a_string
58
+ dn = Ldaptic::DN("a=b")
59
+ assert_equal ?a, dn[0]
60
+ assert_equal dn, "a=b"
61
+ assert_kind_of String, Array(dn).first
62
+ assert_raise(NoMethodError) { dn.unknown_method }
63
+ assert dn.include?("=")
64
+ assert_equal "a=bc", (Ldaptic::DN("a=b") << "c")
65
+ end
66
+
67
+ def test_should_search
68
+ dn = Ldaptic::DN("a=b", FakeSearch.new)
69
+ assert_equal "a=b", dn.find[:base]
70
+ dn = Ldaptic::DN(dn, FakeSearch2.new)
71
+ assert_equal "a=b", dn.find.first
72
+ end
73
+
74
+ def test_rdn
75
+ rdn = Ldaptic::RDN.new("street=Main+cn=Doe, John")
76
+ assert_kind_of Ldaptic::RDN, rdn.dup
77
+ assert_kind_of Ldaptic::RDN, rdn.clone
78
+ assert_equal "CN=Doe\\2C John+STREET=Main", rdn.to_str
79
+ assert_equal "MAIN", rdn.upcase.street
80
+ assert_equal "Main", rdn["Street"]
81
+ rdn.downcase!
82
+ assert_equal "main", rdn.street
83
+ assert_equal "main", rdn.delete(:Street)
84
+ assert_equal "CN=doe\\2C john+STREET=Main", rdn.merge(:street=>"Main").to_str
85
+ end
86
+
87
+ def test_rdn_lookup
88
+ rdn = Ldaptic::RDN.new(:street=>"Main", :cn=>"Doe, John")
89
+ assert_equal "OU=Corporate,CN=Doe\\2C John+STREET=Main", rdn[:ou=>"Corporate"].to_str
90
+ assert rdn.has_key?(:street)
91
+ assert rdn.include?('Street')
92
+ assert_equal "CN=", rdn[(0..2)]
93
+ assert_equal ["Main", "Doe, John"], rdn.values_at(:street, 'CN')
94
+ error_class = {}.fetch(1) rescue $!.class
95
+ assert_raise(error_class) { rdn.fetch(:uid) }
96
+ assert_nothing_raised { rdn.fetch("STREET") }
97
+ end
98
+
99
+ def test_rdn_as_key
100
+ hash = {}
101
+ hash[Ldaptic::RDN(:cn => "Doe, John")] = true
102
+ assert hash[Ldaptic::RDN("Cn=doe\\, john")]
103
+ end
104
+
105
+ def test_rdn_should_raise_type_error
106
+ assert_raise(TypeError) { Ldaptic::RDN(Object.new) }
107
+ assert_raise(TypeError) { Ldaptic::RDN(Object.new => "whee") }
108
+ end
109
+
110
+ end
@@ -0,0 +1,22 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic'
3
+
4
+ class LdapticEntryTest < Test::Unit::TestCase
5
+
6
+ class Entry < Ldaptic::Entry
7
+ def self.namespace
8
+ Namespace.new
9
+ end
10
+ end
11
+
12
+ class Namespace
13
+ def attribute_type(attr)
14
+ end
15
+ end
16
+
17
+ def test_human_attribute_name
18
+ assert_equal 'Given name', Entry.human_attribute_name(:givenName)
19
+ assert_equal 'User PKCS12', Entry.human_attribute_name(:userPKCS12)
20
+ end
21
+
22
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic/errors'
3
+
4
+ class LdapticErrorsTest < Test::Unit::TestCase
5
+
6
+ NO_SUCH_OBJECT = 32
7
+
8
+ def test_should_not_raise_on_zero
9
+ assert_nothing_raised { Ldaptic::Errors.raise_unless_zero(0, "success") }
10
+ end
11
+
12
+ def test_should_raise_no_such_object
13
+ assert_raise(Ldaptic::Errors::NoSuchObject) { Ldaptic::Errors.raise_unless_zero(32, "no such object") }
14
+ end
15
+
16
+ def test_should_have_proper_error
17
+ exception = Ldaptic::Errors.raise_unless_zero(1, "some error") rescue $!
18
+ assert_equal 1, exception.code
19
+ assert_equal "some error", exception.message
20
+ assert_match(/^#{Regexp.escape(__FILE__)}/, exception.backtrace.first)
21
+ end
22
+
23
+ end
@@ -0,0 +1,47 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
2
+ require 'ldaptic/escape'
3
+ require 'test/unit'
4
+
5
+ class LdapticEscapeTest < Test::Unit::TestCase
6
+
7
+ PAIRS = [
8
+ ["\\28Hello\\5C\\2Aworld!\\29", "(Hello\\*world!)"],
9
+ ["\\23Good-bye\\2C world\\20", "#Good-bye, world "]
10
+ ]
11
+
12
+ def test_encode
13
+ assert_equal "FALSE", Ldaptic.encode(false)
14
+ assert_equal "20000101123456.000000Z", Ldaptic.encode(Time.utc(2000,1,1,12,34,56))
15
+ assert_equal "foo-bar", Ldaptic.encode(:foo_bar)
16
+ end
17
+
18
+ def test_escape
19
+ PAIRS.each do |escaped, unescaped|
20
+ assert_equal escaped, Ldaptic.escape(unescaped)
21
+ end
22
+ assert_equal "a*b\\2Ac\\00", Ldaptic.escape("a*b**c\0", true)
23
+ assert_equal "TRUE", Ldaptic.escape(true)
24
+ assert_equal "foo-bar", Ldaptic.escape(:foo_bar)
25
+ end
26
+
27
+ def test_should_not_mutate
28
+ x = ","
29
+ assert_equal "\\2C", Ldaptic.escape(x).upcase
30
+ assert_equal ",", x
31
+ end
32
+
33
+ def test_unescape
34
+ PAIRS.each do |escaped, unescaped|
35
+ assert_equal unescaped, Ldaptic.unescape(escaped)
36
+ end
37
+ assert_equal " whitespace!", Ldaptic.unescape(" \\20whitespace\\! ")
38
+ assert_equal "abcde", Ldaptic.unescape("#6162636465")
39
+ end
40
+
41
+ def test_split
42
+ assert_equal ["a","b"], Ldaptic.split("a*b", '*')
43
+ assert_equal ["a\\*b"], Ldaptic.split("a\\*b", '*')
44
+ assert_equal ["a\\\\","b"], Ldaptic.split("a\\\\*b", ?*)
45
+ end
46
+
47
+ end
@@ -0,0 +1,53 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__),'..','lib')).uniq!
2
+ require 'ldaptic/filter'
3
+ require 'test/unit'
4
+
5
+ class LdapticFilterTest < Test::Unit::TestCase
6
+
7
+ def assert_ldap_filter(string, filter)
8
+ assert_equal string.downcase, Ldaptic::Filter(filter).process.downcase
9
+ end
10
+
11
+ def test_filter_from_hash
12
+ assert_equal nil, Ldaptic::Filter({}).process
13
+ assert_ldap_filter "(x-y=*)", :x_y
14
+ assert_ldap_filter "(x=1)", :x => 1
15
+ assert_ldap_filter "(x=*)", :x => true
16
+ assert_ldap_filter "(!(x=1))", :x! => 1
17
+ assert_ldap_filter "(!(x=*))", :x => false
18
+ assert_ldap_filter "(|(x=1)(x=2))", :x => [1, 2]
19
+ assert_ldap_filter "(&(x>=1)(x<=2))", :x => (1..2)
20
+ assert_ldap_filter "(&(x=1)(y=2))", :x => 1, :y => 2
21
+ assert_ldap_filter "(&(x>=1)(!(x>=2)))", :x => (1...2)
22
+ end
23
+
24
+ def test_filter_from_array
25
+ assert_ldap_filter "(sn=Sm*)", ["(sn=?*)", "Sm"]
26
+ assert_ldap_filter "(sn=\\2a)", ["(sn=?)", "*"]
27
+ end
28
+
29
+ def test_filter_from_lambda
30
+ assert_ldap_filter "(x=1)", lambda { |ldap| ldap.x == 1 }
31
+ assert_ldap_filter "(&(x>=1)(cn=*))", lambda { (x >= 1) & cn }
32
+ end
33
+
34
+ def test_escape_asterisks
35
+ assert_ldap_filter "(x=\\2a)", :x => "*"
36
+ assert_ldap_filter "(x=*)", :x => "*", :* => true
37
+ end
38
+
39
+ def test_boolean_logic
40
+ assert_ldap_filter "(&(a=1)(b=2))", Ldaptic::Filter(:a => 1) & {:b => 2}
41
+ assert_ldap_filter "(|(a=1)(b=2))", Ldaptic::Filter(:a => 1) | "(b=2)"
42
+ assert_ldap_filter "(!(a=1))", ~Ldaptic::Filter(:a => 1)
43
+ end
44
+
45
+ def test_conversions
46
+ assert_equal "(a=1)", {:a => 1}.to_ldap_filter.to_s
47
+ end
48
+
49
+ def test_errors
50
+ assert_raise(TypeError) { Ldaptic::Filter(Object.new) }
51
+ end
52
+
53
+ end
@@ -0,0 +1,90 @@
1
+ require File.join(File.dirname(File.expand_path(__FILE__)),'test_helper')
2
+ require 'ldaptic'
3
+ require File.join(File.dirname(File.expand_path(__FILE__)),'/mock_adapter')
4
+
5
+ class LdapticHierarchyTest < Test::Unit::TestCase
6
+ class Mock < Ldaptic::Class(:adapter => :mock)
7
+ end
8
+
9
+ def test_inheritance
10
+ assert defined? Mock::Top
11
+ assert_raise(NoMethodError) { Mock.new }
12
+ assert_equal Mock::Top, Mock::Person.superclass
13
+ assert Mock::Person.method_defined?(:sn)
14
+ assert !Mock::Top.method_defined?(:sn)
15
+ assert_equal [], Mock::Top.aux
16
+ assert_equal %w(simpleSecurityObject), Mock::Person.aux
17
+ end
18
+
19
+ def test_new
20
+ person = Mock::Person.new(:dn => "CN=Matz,DC=org")
21
+ assert !person.persisted?
22
+ assert_equal "Matz", person.cn
23
+ person.sn = "Matsumoto"
24
+ assert_equal "Matsumoto", person.sn
25
+ assert_equal %w"Matsumoto", person[:sn]
26
+ assert_equal %w"Matsumoto", person['sn']
27
+ assert_equal Ldaptic::DN("cn=Matz,dc=org"), person.dn
28
+ assert_equal "CN=Matz", person.rdn
29
+ inspect = person.inspect
30
+ assert_raise(TypeError) { person.distinguishedName = "Why" }
31
+ assert_raise(NoMethodError) { person.fakeAttribute = 42 }
32
+ assert inspect.include?("Mock::Person CN=Matz,DC=org")
33
+ assert_match(/sn: .*Matsumoto/, inspect)
34
+ end
35
+
36
+ def test_new_with_aux
37
+ person = Mock::Person.new(:dn => "CN=Matz,DC=org")
38
+ assert_raise(NoMethodError) { person.userPassword }
39
+ person.instance_variable_get(:@attributes)["objectClass"] |= ["simpleSecurityObject"]
40
+ assert_equal [Mock::Person, Mock::Top, Mock::SimpleSecurityObject], person.ldap_ancestors
41
+ assert_nothing_raised { person.userPassword = ["ruby"] }
42
+ assert_equal %w(ruby), person.userPassword
43
+ end
44
+
45
+ def test_attributes
46
+ assert_equal %w(age sn), Mock::Person.may(false).sort
47
+ assert_equal %w(age description distinguishedName sn), Mock::Person.may.sort
48
+ assert_equal %w(cn), Mock::Person.must(false).sort
49
+ assert_equal %w(cn objectClass), Mock::Person.must.sort
50
+ assert_equal %w(cn description distinguishedName objectClass), Mock::Top.attributes
51
+ end
52
+
53
+ def test_search
54
+ assert_kind_of Hash, Mock.search(:limit => true, :instantiate => false)
55
+ assert_kind_of Array, Mock.search(:limit => false)
56
+ assert_kind_of String, Mock.search(:attributes => :filter, :limit => false).first
57
+ assert_kind_of Array, Mock.search(:attributes => :filter, :instantiate => false).first
58
+ end
59
+
60
+ def test_find
61
+ assert defined? Mock::SearchResult
62
+ result = Mock.find("CN=Matz,DC=org")
63
+ assert result.persisted?
64
+ assert_equal "CN=Matz,DC=org", result.dn
65
+ assert_equal 0, result.scope
66
+ result = Mock.find(["CN=Matz,DC=org", "CN=Why,DC=org"])
67
+ assert_equal 2, result.size
68
+ end
69
+
70
+ def test_children
71
+ matz = Mock.find("CN=Matz,DC=org")
72
+ assert_equal 0, (matz/{:child=>:data}).scope
73
+ assert_equal 0, matz[:child=>:data].scope
74
+ matz[:child=>:data].scope = 1
75
+ # Verify cache is working
76
+ assert_equal 1, matz[:child=>:data].scope
77
+ assert_equal "DC=org", matz.parent.dn
78
+ Mock.filter(true) do
79
+ Mock[:cn=>"Matz"].scope = 1
80
+ assert_equal 1, Mock[:cn=>"Matz"].scope
81
+ end
82
+ assert_equal 0, Mock[:cn=>"Matz"].scope
83
+ end
84
+
85
+ def test_schema
86
+ assert Mock.schema([:objectClass, :scope]).scope
87
+ end
88
+
89
+ end
90
+