ad-framework 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +12 -0
  3. data/README.markdown +36 -0
  4. data/Rakefile +19 -0
  5. data/ad-framework.gemspec +25 -0
  6. data/doc/open_ldap_server.markdown +17 -0
  7. data/extras/adtest.schema +304 -0
  8. data/extras/slapd.conf +10 -0
  9. data/lib/ad-framework.rb +53 -0
  10. data/lib/ad-framework/attribute.rb +35 -0
  11. data/lib/ad-framework/attribute_type.rb +133 -0
  12. data/lib/ad-framework/auxiliary_class.rb +24 -0
  13. data/lib/ad-framework/config.rb +72 -0
  14. data/lib/ad-framework/config/attribute_definition.rb +18 -0
  15. data/lib/ad-framework/config/mapping.rb +26 -0
  16. data/lib/ad-framework/exceptions.rb +17 -0
  17. data/lib/ad-framework/fields.rb +44 -0
  18. data/lib/ad-framework/patterns/callbacks.rb +47 -0
  19. data/lib/ad-framework/patterns/has_schema.rb +127 -0
  20. data/lib/ad-framework/patterns/persistence.rb +67 -0
  21. data/lib/ad-framework/patterns/searchable.rb +117 -0
  22. data/lib/ad-framework/patterns/validations.rb +50 -0
  23. data/lib/ad-framework/schema.rb +118 -0
  24. data/lib/ad-framework/structural_class.rb +61 -0
  25. data/lib/ad-framework/utilities/entry_builder.rb +77 -0
  26. data/lib/ad-framework/utilities/transaction.rb +32 -0
  27. data/lib/ad-framework/utilities/validator.rb +26 -0
  28. data/lib/ad-framework/version.rb +5 -0
  29. data/test/helper.rb +71 -0
  30. data/test/integration/defined_array_test.rb +49 -0
  31. data/test/integration/defined_integer_test.rb +48 -0
  32. data/test/integration/defined_string_test.rb +48 -0
  33. data/test/integration/defined_top_test.rb +101 -0
  34. data/test/integration/defined_user_test.rb +140 -0
  35. data/test/irb.rb +2 -0
  36. data/test/support/factory.rb +67 -0
  37. data/test/support/ldap.yml +6 -0
  38. data/test/support/schema/attribute_types.rb +67 -0
  39. data/test/support/schema/attributes.rb +10 -0
  40. data/test/support/schema/auxiliary_classes.rb +12 -0
  41. data/test/support/schema/structural_classes.rb +46 -0
  42. data/test/support/seed.rb +28 -0
  43. data/test/support/state.rb +29 -0
  44. data/test/unit/ad-framework/attribute_test.rb +84 -0
  45. data/test/unit/ad-framework/attribute_type/class_methods_test.rb +146 -0
  46. data/test/unit/ad-framework/attribute_type_test.rb +114 -0
  47. data/test/unit/ad-framework/auxiliary_class_test.rb +39 -0
  48. data/test/unit/ad-framework/config/attribute_definition_test.rb +26 -0
  49. data/test/unit/ad-framework/config/mapping_test.rb +41 -0
  50. data/test/unit/ad-framework/config_test.rb +121 -0
  51. data/test/unit/ad-framework/fields_test.rb +44 -0
  52. data/test/unit/ad-framework/patterns/callbacks_test.rb +90 -0
  53. data/test/unit/ad-framework/patterns/has_schema/class_methods_test.rb +214 -0
  54. data/test/unit/ad-framework/patterns/has_schema_test.rb +96 -0
  55. data/test/unit/ad-framework/patterns/persistence_test.rb +126 -0
  56. data/test/unit/ad-framework/patterns/searchable_test.rb +201 -0
  57. data/test/unit/ad-framework/patterns/validations_test.rb +113 -0
  58. data/test/unit/ad-framework/schema_test.rb +268 -0
  59. data/test/unit/ad-framework/structural_class_test.rb +64 -0
  60. data/test/unit/ad-framework/utilities/entry_builder_test.rb +107 -0
  61. data/test/unit/ad-framework/utilities/transaction_test.rb +50 -0
  62. data/test/unit/ad-framework/utilities/validator_test.rb +46 -0
  63. data/test/unit/ad-framework_test.rb +116 -0
  64. metadata +225 -0
@@ -0,0 +1,114 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::AttributeType
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::AttributeType"
7
+ setup do
8
+ @class = AD::Framework::AttributeType
9
+ @ldap_name = "some"
10
+ @fields = { @ldap_name => [ "value" ] }
11
+ @object = Factory.mock_structural_class_instance({ :fields => @fields })
12
+ @attribute_type = @class.new(@object, @ldap_name)
13
+ end
14
+ subject{ @attribute_type }
15
+
16
+ should have_accessors :object, :attr_ldap_name, :value, :ldap_value
17
+ should have_instance_methods :value_from_field, :is_set?, :inspect
18
+ should have_class_methods :key, :define_attribute_type, :attribute_type_method
19
+ should have_class_methods :define_reader, :reader_method, :define_writer, :writer_method
20
+
21
+ should "have set the object correctly" do
22
+ assert_equal @object, subject.object
23
+ end
24
+ should "have set the attr_ldap_name correctly" do
25
+ assert_equal @ldap_name, subject.attr_ldap_name
26
+ end
27
+ should "have set the value correctly" do
28
+ assert_equal subject.value_from_field, subject.value
29
+ end
30
+ should "return the value from the object's fields with #value_from_field" do
31
+ assert_equal @fields[@ldap_name].first, subject.value_from_field
32
+ end
33
+
34
+ should "return a custom inspect" do
35
+ expected = "#<#{subject.class} attr_ldap_name: #{subject.attr_ldap_name.inspect}, "
36
+ expected += "ldap_value: #{subject.ldap_value.inspect}, "
37
+ expected += "object: #{@object.class} - #{@object.dn.inspect}, "
38
+ expected += "value: #{subject.value.inspect}>"
39
+ assert_equal expected, subject.inspect
40
+ end
41
+ end
42
+
43
+ class CreatedWithAValueTest < BaseTest
44
+ desc "created with a value"
45
+ setup do
46
+ @value = "amazing"
47
+ @attribute_type = @class.new(@object, @ldap_name, @value)
48
+ end
49
+
50
+ should "set the value from that arg" do
51
+ assert_equal @value, subject.value
52
+ end
53
+ end
54
+
55
+ class SetValueTest < BaseTest
56
+ desc "setting the value"
57
+ setup do
58
+ @value = "amazing"
59
+ @attribute_type.value = "amazing"
60
+ end
61
+
62
+ should "set the value and ldap_value" do
63
+ assert_equal @value, subject.value
64
+ assert_equal @value, subject.ldap_value
65
+ end
66
+ end
67
+
68
+ class SetLdapValueTest < BaseTest
69
+ desc "setting the ldap value"
70
+ setup do
71
+ @ldap_value = "amazing"
72
+ @attribute_type.ldap_value = @ldap_value
73
+ end
74
+
75
+ should "set the ldap value and the object's fields" do
76
+ assert_equal @ldap_value, subject.ldap_value
77
+ assert_equal [ @ldap_value ], subject.object.fields[subject.attr_ldap_name]
78
+ end
79
+ end
80
+
81
+ class SetLdapValueWithArrayTest < BaseTest
82
+ desc "setting the ldap value with an array"
83
+ setup do
84
+ @ldap_value = [ 1, "2" ]
85
+ @attribute_type.ldap_value = @ldap_value
86
+ end
87
+
88
+ should "convert all objects to strings for object's fields with a call to #ldap_value=" do
89
+ assert_equal @ldap_value, subject.ldap_value
90
+ expected = @ldap_value.collect(&:to_s)
91
+ assert_equal expected, subject.object.fields[subject.attr_ldap_name]
92
+ end
93
+ end
94
+
95
+ class IsSetTest < SetValueTest
96
+ desc "is_set with a non-nil value"
97
+
98
+ should "return true" do
99
+ assert subject.is_set?
100
+ end
101
+ end
102
+
103
+ class IsNotSetTest < BaseTest
104
+ desc "is_set with a nil value"
105
+ setup do
106
+ @attribute_type.value = nil
107
+ end
108
+
109
+ should "return false" do
110
+ assert_not subject.is_set?
111
+ end
112
+ end
113
+
114
+ end
@@ -0,0 +1,39 @@
1
+ require 'assert'
2
+
3
+ module AD::Framework::AuxiliaryClass
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::AuxiliaryClass"
7
+ setup do
8
+ @module = AD::Framework::AuxiliaryClass
9
+ end
10
+ subject{ @module }
11
+
12
+ end
13
+
14
+ class IncludedTest < BaseTest
15
+ setup_once do
16
+ RandomAuxiliaryClass = Factory.auxiliary_class do
17
+ ldap_name "testAuxiliaryClass"
18
+ end
19
+ end
20
+ setup do
21
+ included_module = @included_module = RandomAuxiliaryClass
22
+ @class = Factory.structural_class do
23
+ include included_module
24
+ end
25
+ end
26
+ subject{ @included_module }
27
+
28
+ should have_instance_methods :schema, :ldap_name, :treebase, :rdn, :attributes, :read_attributes
29
+ should have_instance_methods :write_attributes
30
+
31
+ should "have defined an included method on the class it was included on" do
32
+ assert_respond_to :included, subject
33
+ end
34
+ should "have added the included module to the class's schema it was included on" do
35
+ assert_includes subject, @class.schema.auxiliary_classes
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,26 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Config::AttributeDefinition
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::Config::AttributeDefinition"
7
+ setup do
8
+ @attr = { :name => "something", :ldap_name => "some", :type => "string" }
9
+ @definition = AD::Framework::Config::AttributeDefinition.new(@attr)
10
+ end
11
+ subject{ @definition }
12
+
13
+ should have_accessors :name, :ldap_name, :type
14
+
15
+ should "have set the name correctly" do
16
+ assert_equal @attr[:name], subject.name
17
+ end
18
+ should "have set the ldap_name correctly" do
19
+ assert_equal @attr[:ldap_name], subject.ldap_name
20
+ end
21
+ should "have set the type correctly" do
22
+ assert_equal @attr[:type], subject.type
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,41 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Config::Mapping
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::Config::Mapping"
7
+ setup do
8
+ @mapping = AD::Framework::Config::Mapping.new
9
+ end
10
+ subject{ @mapping }
11
+
12
+ should have_instance_methods :[], :[]=, :find, :add
13
+
14
+ should "be a kind of Hash" do
15
+ assert_kind_of Hash, subject
16
+ end
17
+
18
+ should "lookup an item with it's sym with a call to #[]" do
19
+ subject[:third] = true
20
+ assert_equal true, subject["third"]
21
+ assert_equal true, subject[:third]
22
+ end
23
+ should "lookup an item with it's sym with a call to #find" do
24
+ subject[:fourth] = false
25
+ assert_equal false, subject.find("fourth")
26
+ assert_equal false, subject.find(:fourth)
27
+ end
28
+
29
+ should "add an item to it's collection with a call to #[]=" do
30
+ subject["first"] = true
31
+ assert_equal true, subject["first"]
32
+ assert_equal true, subject[:first]
33
+ end
34
+ should "add an item to it's collection with a call to #add" do
35
+ subject.add(:second, false)
36
+ assert_equal false, subject["second"]
37
+ assert_equal false, subject[:second]
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,121 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Config
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Frameowrk::Config"
7
+ setup do
8
+ State.preserve
9
+ @config = AD::Framework::Config.new
10
+ @logger = mock()
11
+ @config.adapter.config.logger = @logger
12
+ end
13
+ subject{ @config }
14
+
15
+ should have_accessors :attributes, :attribute_types, :object_classes, :ldap_prefix
16
+ should have_accessors :logger, :search_size_supported, :mappings, :run_commands, :treebase
17
+ should have_instance_methods :ldap, :adapter, :add_attribute, :add_attribute_type
18
+ should have_instance_methods :add_object_class
19
+
20
+ [ :mappings, :attributes, :attribute_types, :object_classes ].each do |attr|
21
+ should "return a mapping with a call to ##{attr}" do
22
+ assert_instance_of AD::Framework::Config::Mapping, subject.send(attr)
23
+ end
24
+ end
25
+ should "include a basic mapping for dn" do
26
+ assert_equal subject.mappings[:dn], "distinguishedname"
27
+ end
28
+ should "return AD::LDAP with a call to #ldap" do
29
+ assert_equal AD::LDAP, subject.ldap
30
+ end
31
+
32
+ should "return the adapter's logger with a call to #logger" do
33
+ assert_equal subject.adapter.logger, subject.logger
34
+ end
35
+ should "set the adapter's logger with a call to #logger=" do
36
+ assert_equal @logger, subject.adapter.config.logger
37
+ end
38
+
39
+ [ :search_size_supported, :mappings, :run_commands, :treebase ].each do |attr|
40
+ should "return the adapter's config value for #{attr.inspect} with a call to ##{attr}" do
41
+ subject.adapter.config.send("#{attr}=", mock())
42
+ assert_equal subject.adapter.config.send(attr), subject.send(attr)
43
+ end
44
+ should "set the adapter's config value for #{attr.inspect} with a call to ##{attr}=" do
45
+ value = mock()
46
+ subject.send("#{attr}=", value)
47
+ assert_equal value, subject.adapter.config.send(attr)
48
+ end
49
+ end
50
+
51
+ teardown do
52
+ State.restore
53
+ end
54
+ end
55
+
56
+ class LdapTest < BaseTest
57
+ desc "ldap method"
58
+ setup do
59
+ @ldap_block = ::Proc.new{ true }
60
+ AD::LDAP.expects(:configure).with(&@ldap_block)
61
+ end
62
+
63
+ should "pass a block to AD::LDAP configure" do
64
+ assert_nothing_raised{ subject.ldap(&@ldap_block) }
65
+ end
66
+ end
67
+
68
+ class LdapPrefixTest < BaseTest
69
+ desc "setting the ldap prefix"
70
+ setup do
71
+ @prefix = "something-"
72
+ @structural_class = Factory.structural_class
73
+ @config.add_object_class(@structural_class)
74
+ @config.ldap_prefix = @prefix
75
+ end
76
+
77
+ should "re-register any object classes" do
78
+
79
+ stored = subject.object_classes["#{@prefix}#{@structural_class.ldap_name}"]
80
+ assert_equal @structural_class, stored
81
+ end
82
+ end
83
+
84
+ class AddAttributeTest < BaseTest
85
+ desc "add_attribute method"
86
+ setup do
87
+ @definition = { :name => "test_attr", :ldap_name => "testattr", :type => "string" }
88
+ @config.add_attribute(@definition)
89
+ end
90
+
91
+ should "add an attribute definition to the attributes" do
92
+ assert_equal @definition[:ldap_name], subject.mappings[@definition[:name]]
93
+ assert @definition, subject.attributes[@definition[:name]]
94
+ end
95
+ end
96
+
97
+ class AddAttributeTypeTest < BaseTest
98
+ desc "add_attribute_type method"
99
+ setup do
100
+ @attribute_type = Factory.mock_attribute_type
101
+ @config.add_attribute_type(@attribute_type)
102
+ end
103
+
104
+ should "add an attribute type to the attribute_types" do
105
+ assert_equal @attribute_type, subject.attribute_types[@attribute_type.key]
106
+ end
107
+ end
108
+
109
+ class AddObjectClass < BaseTest
110
+ desc "add_object_class method"
111
+ setup do
112
+ @object_class = Factory.structural_class
113
+ @config.add_object_class(@object_class)
114
+ end
115
+
116
+ should "add an object class to the object_classes" do
117
+ assert_equal @object_class, subject.object_classes[@object_class.ldap_name]
118
+ end
119
+ end
120
+
121
+ end
@@ -0,0 +1,44 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Fields
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::Fields"
7
+ setup do
8
+ @fields = AD::Framework::Fields.new({
9
+ :a => "a", :b => "b", :c => "c", :d => "d"
10
+ })
11
+ end
12
+ subject{ @fields }
13
+
14
+ should "be a kind of Hash" do
15
+ assert_kind_of Hash, subject
16
+ end
17
+ should "return an instance of a hash with a call to #to_hash" do
18
+ assert_instance_of Hash, subject.to_hash
19
+ assert_not_instance_of Hash, subject
20
+ assert_equal subject, subject.to_hash
21
+ end
22
+ should "lookup an item with the key as a string with a call to #[]" do
23
+ subject[:a] = true
24
+ assert_equal true, subject["a"]
25
+ assert_equal true, subject[:a]
26
+ end
27
+ should "add an item to it's collection with a call to #[]=" do
28
+ subject["b"] = true
29
+ assert_equal true, subject["b"]
30
+ assert_equal true, subject[:b]
31
+ end
32
+
33
+ should "have a custom inspect" do
34
+ key_len = subject.keys.collect(&:size).max + 1
35
+ expected = subject.collect do |(k, v)|
36
+ label = "#{k}:".rjust(key_len, ' ')
37
+ [ label, v.inspect ].join(" ")
38
+ end.join("\n")
39
+ expected = "\n#{expected}"
40
+ assert_equal expected, subject.inspect
41
+ end
42
+ end
43
+
44
+ end
@@ -0,0 +1,90 @@
1
+ require 'assert'
2
+
3
+ module AD::Framework::Patterns::Callbacks
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "callbacks pattern"
7
+ setup do
8
+ @structural_class = Factory.structural_class do
9
+ ldap_name "callbacksTestObject"
10
+ attributes :name, :system_flags
11
+ attr_accessor :has_saved
12
+
13
+ before_save :set_has_saved_before
14
+ after_save :set_has_saved_after
15
+ before_destroy :set_has_saved_before
16
+ after_destroy :set_has_saved_after
17
+
18
+ def initialize(*args)
19
+ super
20
+ self.has_saved = nil
21
+ end
22
+
23
+ protected
24
+
25
+ def set_has_saved_before
26
+ self.has_saved = false
27
+ self.system_flags = 1
28
+ end
29
+ def set_has_saved_after
30
+ self.has_saved = true
31
+ end
32
+ end
33
+ @instance = @structural_class.new({ :name => "test" })
34
+ @mock_connection = mock()
35
+ @instance.stubs(:connection).returns(@mock_connection)
36
+ end
37
+ subject{ @instance }
38
+
39
+ should have_instance_methods :create, :update, :destroy
40
+
41
+ end
42
+
43
+ class CreateTest < BaseTest
44
+ desc "create method"
45
+ setup do
46
+ @instance.fields[:distinguishedname] = @instance.dn
47
+ @instance.fields[:objectclass] = @instance.schema.object_classes.collect(&:ldap_name).compact
48
+ @mock_connection.expects(:add).with({
49
+ :dn => @instance.dn,
50
+ :attributes => @instance.fields.merge({ 'systemflags' => [ "1" ] })
51
+ })
52
+ @instance.expects(:reload)
53
+ end
54
+
55
+ should "run the callbacks" do
56
+ assert_nothing_raised{ subject.create }
57
+ assert subject.has_saved
58
+ end
59
+ end
60
+
61
+ class UpdateTest < BaseTest
62
+ desc "update method"
63
+ setup do
64
+ @mock_connection.expects(:open).yields(@mock_connection)
65
+ @instance.fields.changes.each do |name, value|
66
+ @mock_connection.expects(:replace_attribute).with(@instance.dn, name, value)
67
+ end
68
+ @mock_connection.expects(:replace_attribute).with(@instance.dn, "systemflags", [ "1" ])
69
+ @instance.expects(:reload)
70
+ end
71
+
72
+ should "run the callbacks" do
73
+ assert_nothing_raised{ subject.update }
74
+ assert subject.has_saved
75
+ end
76
+ end
77
+
78
+ class DestroyTest < BaseTest
79
+ desc "destroy method"
80
+ setup do
81
+ @mock_connection.expects(:delete).with(@instance.dn)
82
+ end
83
+
84
+ should "run the callbacks" do
85
+ assert_nothing_raised{ subject.destroy }
86
+ assert subject.has_saved
87
+ end
88
+ end
89
+
90
+ end