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,113 @@
1
+ require 'assert'
2
+
3
+ module AD::Framework::Patterns::Validations
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "the validations pattern"
7
+ setup do
8
+ @structural_class = Factory.structural_class do
9
+ ldap_name "validationsTestObject"
10
+ attributes :name, :system_flags
11
+ must_set :name, :system_flags
12
+ end
13
+ @instance = @structural_class.new({ :name => "test", :system_flags => 1 })
14
+ @mock_connection = mock()
15
+ @instance.stubs(:connection).returns(@mock_connection)
16
+ end
17
+ subject{ @instance }
18
+
19
+ should have_accessors :errors
20
+ should have_instance_methods :valid?, :create, :update
21
+
22
+ should "default errors to a new hash" do
23
+ assert_equal({}, subject.errors)
24
+ end
25
+ end
26
+
27
+ class WithErrorsTest < BaseTest
28
+ desc "with errors"
29
+ setup do
30
+ @instance.attributes = { :name => nil, :system_flags => nil }
31
+ @instance.valid?
32
+ end
33
+
34
+ should "have added errors for the attributes to th errors hash" do
35
+ assert_not_empty subject.errors
36
+ subject.schema.attributes.each do |attribute_name|
37
+ assert_includes attribute_name.to_s, subject.errors.keys
38
+ end
39
+ end
40
+ end
41
+
42
+ class WithNoErrorsTest < BaseTest
43
+ desc "with no errors"
44
+ setup do
45
+ @instance.valid?
46
+ end
47
+
48
+ should "have no key/values in the errors hash" do
49
+ assert_empty subject.errors
50
+ end
51
+ end
52
+
53
+ class CreateInvalidTest < WithErrorsTest
54
+ desc "create method"
55
+ setup do
56
+ @instance.expects(:valid?)
57
+ end
58
+
59
+ should "check if the entry is valid and return if it added it" do
60
+ result = nil
61
+ assert_nothing_raised{ result = subject.create }
62
+ assert_equal false, result
63
+ end
64
+ end
65
+
66
+ class UpdateInvalidTest < WithErrorsTest
67
+ desc "update method"
68
+ setup do
69
+ @instance.expects(:valid?)
70
+ end
71
+
72
+ should "check if the entry is valid and return if it updated it" do
73
+ result = nil
74
+ assert_nothing_raised{ result = subject.update }
75
+ assert_equal false, result
76
+ end
77
+ end
78
+
79
+ class CreateValidTest < WithNoErrorsTest
80
+ desc "create method"
81
+ setup do
82
+ @mock_connection.expects(:add).with({
83
+ :dn => @instance.dn,
84
+ :attributes => @instance.fields
85
+ })
86
+ @instance.expects(:reload)
87
+ end
88
+
89
+ should "check if the entry is valid and return if it added it" do
90
+ result = nil
91
+ assert_nothing_raised{ result = subject.create }
92
+ assert_equal true, result
93
+ end
94
+ end
95
+
96
+ class UpdateValidTest < WithNoErrorsTest
97
+ desc "create method"
98
+ setup do
99
+ @mock_connection.expects(:open).yields(@mock_connection)
100
+ @instance.fields.changes.each do |name, value|
101
+ @mock_connection.expects(:replace_attribute).with(@instance.dn, name, value)
102
+ end
103
+ @instance.expects(:reload)
104
+ end
105
+
106
+ should "check if the entry is valid and return if it added it" do
107
+ result = nil
108
+ assert_nothing_raised{ result = subject.update }
109
+ assert_equal true, result
110
+ end
111
+ end
112
+
113
+ end
@@ -0,0 +1,268 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Schema
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::Schema"
7
+ setup do
8
+ State.preserve
9
+ @structural_class = Factory.structural_class do
10
+ attributes :name
11
+ must_set :name
12
+ before_create :something_amazing
13
+ end
14
+ @schema = AD::Framework::Schema.new(@structural_class)
15
+ end
16
+ subject{ @schema }
17
+
18
+ should have_accessors :ldap_name, :rdn, :attributes, :auxiliary_classes, :klass
19
+ should have_accessors :structural_classes, :mandatory, :callbacks
20
+ should have_instance_methods :treebase, :treebase=, :add_attributes, :add_read_attributes
21
+ should have_instance_methods :add_write_attributes, :add_auxiliary_class
22
+
23
+ should "default the rdn to :name" do
24
+ assert_equal :name, subject.rdn
25
+ end
26
+ should "default auxiliary classes to a new array" do
27
+ assert_instance_of Array, subject.auxiliary_classes
28
+ assert_empty subject.auxiliary_classes
29
+ end
30
+ should "default structural classes to a new array" do
31
+ assert_instance_of Array, subject.structural_classes
32
+ end
33
+ should "default attributes to a new set" do
34
+ assert_instance_of Set, subject.attributes
35
+ assert_empty subject.attributes
36
+ end
37
+ should "default mandatory to a new set" do
38
+ assert_instance_of Set, subject.mandatory
39
+ assert_empty subject.mandatory
40
+ end
41
+ should "default callbacks to a new hash" do
42
+ assert_instance_of Hash, subject.callbacks
43
+ end
44
+
45
+ teardown do
46
+ State.restore
47
+ end
48
+ end
49
+
50
+ class LdapNameWithPrefixTest < BaseTest
51
+ desc "ldap_name method with an ldap prefix set"
52
+ setup do
53
+ @ldap_prefix = "something-"
54
+ @ldap_name = "amazing"
55
+ AD::Framework.config.ldap_prefix = @ldap_prefix
56
+ @schema.ldap_name = @ldap_name
57
+ end
58
+
59
+ should "use the ldap_prefix with ldap_name" do
60
+ assert_equal [ @ldap_prefix, @ldap_name ].join, subject.ldap_name
61
+ end
62
+ end
63
+
64
+ class LdapNameWithoutPrefixTest < LdapNameWithPrefixTest
65
+ desc "ldap_name method without ldap prefix set"
66
+ setup do
67
+ AD::Framework.config.ldap_prefix = nil
68
+ end
69
+
70
+ should "just be the ldap name" do
71
+ assert_equal @ldap_name, subject.ldap_name
72
+ end
73
+ end
74
+
75
+ class ObjectClassesTest < BaseTest
76
+ desc "object_classes method"
77
+ setup do
78
+ @structural_classes = [ "structural" ]
79
+ @auxiliary_classes = [ "auxiliary" ]
80
+ @schema.structural_classes = @structural_classes
81
+ @schema.auxiliary_classes = @auxiliary_classes
82
+ end
83
+
84
+ should "return all its object classes in the correct order" do
85
+ expected = [
86
+ subject.structural_classes,
87
+ subject.klass,
88
+ subject.auxiliary_classes
89
+ ].flatten
90
+ assert_equal expected, subject.object_classes
91
+ end
92
+ end
93
+
94
+ class WithASuperclassSchemaTest < BaseTest
95
+ desc "with a superclass schema"
96
+ setup do
97
+ @child_class = Class.new(@structural_class)
98
+ @schema = AD::Framework::Schema.new(@child_class)
99
+ end
100
+ subject{ @schema }
101
+
102
+ should "default attributes to it's parent schema's attributes" do
103
+ assert_equal @structural_class.schema.attributes, subject.attributes
104
+ end
105
+ should "default structural classes to an array with its parent" do
106
+ assert_instance_of Array, subject.structural_classes
107
+ @structural_class.schema.structural_classes.each do |object_class|
108
+ assert_includes object_class, subject.structural_classes
109
+ end
110
+ assert_includes @structural_class, subject.structural_classes
111
+ end
112
+ should "default mandatory to it's parents" do
113
+ assert_equal @structural_class.schema.mandatory, subject.mandatory
114
+ end
115
+ end
116
+
117
+ class TreebaseTest < BaseTest
118
+ desc "treebase method"
119
+ setup do
120
+ @schema.treebase = nil
121
+ end
122
+
123
+ should "default the treebase to what is configured" do
124
+ assert_equal AD::Framework.config.treebase, subject.treebase
125
+ end
126
+
127
+ teardown do
128
+ @schema.treebase = nil
129
+ end
130
+ end
131
+
132
+ class WithPartialTreebaseTest < TreebaseTest
133
+ desc "with a partial treebase set"
134
+ setup do
135
+ @treebase = "CN=Incomplete"
136
+ @schema.treebase = @treebase
137
+ end
138
+
139
+ should "contact the treebase with what is configured, if it is not included" do
140
+ expected = [ @treebase, AD::Framework.config.treebase ].compact.join(", ")
141
+ assert_equal expected, subject.treebase
142
+ end
143
+ end
144
+
145
+ class WithFullTreebaseTest < TreebaseTest
146
+ desc "with a full treebase set"
147
+ setup do
148
+ @treebase = [ "CN=Complete", AD::Framework.config.treebase ].compact.join(", ")
149
+ @schema.treebase = @treebase
150
+ end
151
+
152
+ should "return the full treebase" do
153
+ assert_equal @treebase, subject.treebase
154
+ end
155
+ end
156
+
157
+ class AttributesMethodTest < BaseTest
158
+ desc "adding attribute methods"
159
+ setup do
160
+ @schema.attributes.clear
161
+ end
162
+
163
+ teardown do
164
+ @schema.attributes.clear
165
+ end
166
+ end
167
+
168
+ class AddAttributesTest < AttributesMethodTest
169
+ desc "with the add_attributes method"
170
+ setup do
171
+ @attribute_names = [ :name, :display_name, :system_flags ]
172
+ @schema.expects(:add_read_attributes).with(@attribute_names)
173
+ @schema.expects(:add_write_attributes).with(@attribute_names)
174
+ end
175
+
176
+ should "call add read and write attributes" do
177
+ assert_nothing_raised{ subject.add_attributes(@attribute_names) }
178
+ end
179
+ end
180
+
181
+ class AddReadAttributesTest < AttributesMethodTest
182
+ desc "with the add_read_attributes method"
183
+ setup do
184
+ @attribute_names = [ :display_name ]
185
+ @schema.add_read_attributes(@attribute_names)
186
+ @instance = @structural_class.new
187
+ end
188
+
189
+ should "define the reader and then be stored" do
190
+ assert_respond_to :display_name_attribute_type, @instance
191
+ assert_respond_to :display_name, @instance
192
+ assert_includes :display_name, subject.attributes
193
+ end
194
+ end
195
+
196
+ class AddWriteAttributesTest < AttributesMethodTest
197
+ desc "with the add_write_attributes method"
198
+ setup do
199
+ @attribute_names = [ :description ]
200
+ @schema.add_read_attributes(@attribute_names)
201
+ @instance = @structural_class.new
202
+ end
203
+
204
+ should "define the reader and then be stored" do
205
+ assert_respond_to :description_attribute_type, @instance
206
+ assert_respond_to :description, @instance
207
+ assert_includes :description, subject.attributes
208
+ end
209
+ end
210
+
211
+ class AddAuxiliaryClassesTest < BaseTest
212
+ desc "adding auxiliary classes"
213
+ setup do
214
+ @schema.auxiliary_classes.clear
215
+ @auxiliary_class = Factory.auxiliary_class do
216
+ attributes :sam_account_name
217
+ must_set :sam_account_name
218
+ after_destroy :fix_it_all
219
+ end
220
+ @schema.add_auxiliary_class(@auxiliary_class)
221
+ end
222
+
223
+ should "merge the auxiliary classes attributes and store it" do
224
+ assert_includes @auxiliary_class, subject.auxiliary_classes
225
+ @auxiliary_class.schema.attributes.each do |name|
226
+ assert_includes name, subject.attributes
227
+ end
228
+ @auxiliary_class.schema.mandatory.each do |name|
229
+ assert_includes name, subject.mandatory
230
+ end
231
+ end
232
+
233
+ teardown do
234
+ @schema.auxiliary_classes.clear
235
+ end
236
+ end
237
+
238
+ class AddMandatoryTest < BaseTest
239
+ desc "adding mandatory attributes"
240
+ setup do
241
+ @attribute_names = [ :display_name ]
242
+ @schema.add_mandatory(@attribute_names)
243
+ end
244
+
245
+ should "store the attribute in the mandatory set" do
246
+ @attribute_names.each do |attribute_name|
247
+ assert_includes attribute_name, subject.mandatory
248
+ end
249
+ end
250
+ end
251
+
252
+ class AddCallbackTest < BaseTest
253
+ desc "adding a callback"
254
+ setup do
255
+ @timing = :before
256
+ @action = :create
257
+ @method_name = "something_amazing"
258
+ @schema.add_callback(@timing, @action, @method_name)
259
+ end
260
+
261
+ should "store the callback in the callbacks hash" do
262
+ assert_instance_of Hash, subject.callbacks[@action]
263
+ assert_instance_of Array, subject.callbacks[@action][@timing]
264
+ assert_includes @method_name, subject.callbacks[@action][@timing]
265
+ end
266
+ end
267
+
268
+ end
@@ -0,0 +1,64 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::StructuralClass
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::StructuralClass"
7
+ setup do
8
+ @structural_class = AD::Framework::StructuralClass
9
+ @instance = @structural_class.new
10
+ end
11
+ subject{ @instance }
12
+
13
+ should have_accessors :meta_class, :fields
14
+ should have_instance_methods :connection, :treebase, :treebase=
15
+ should have_class_methods :connection
16
+
17
+ should have_instance_methods :schema
18
+ should have_class_methods :schema
19
+
20
+ should have_instance_methods :reload
21
+ should have_class_methods :find, :first, :all
22
+
23
+ should have_instance_methods :create, :update, :save, :destroy
24
+ should have_class_methods :create
25
+
26
+ should have_instance_methods :errors, :valid?
27
+
28
+ should "set fields to an instance of AD::Framework::Fields" do
29
+ assert_instance_of AD::Framework::Fields, subject.fields
30
+ end
31
+ should "return the framework's connection with a call to #connection" do
32
+ assert_equal AD::Framework.connection, subject.class.connection
33
+ assert_equal subject.class.connection, subject.connection
34
+ end
35
+ end
36
+
37
+ class InheritedTest < Assert::Context
38
+ desc "a structural class"
39
+ setup do
40
+ @treebase = "CN=somewhere"
41
+ @structural_class = Factory.structural_class do
42
+ ldap_name "something"
43
+ rdn :name
44
+ attributes :name
45
+ end
46
+ @instance = @structural_class.new({ :treebase => @treebase })
47
+ end
48
+ subject{ @instance }
49
+
50
+ should "have set it's treebase" do
51
+ expected = [ @treebase, AD::Framework.config.treebase ].join(", ")
52
+ assert_equal expected, subject.treebase
53
+ end
54
+ should "have a custom inspect" do
55
+ expected = "#<#{subject.class} "
56
+ attrs = subject.attributes.collect{|k, v| "#{k}: #{v.inspect}" }
57
+ attrs << "treebase: #{subject.treebase.inspect}"
58
+ expected += attrs.sort.join(", ")
59
+ expected += ">"
60
+ assert_equal expected, subject.inspect
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,107 @@
1
+ require 'assert'
2
+
3
+ class AD::Framework::Utilities::EntryBuilder
4
+
5
+ class BaseTest < Assert::Context
6
+ desc "AD::Framework::Utilities::EntryBuilder"
7
+ setup do
8
+ State.preserve
9
+ @structural_class = Factory.structural_class do
10
+ ldap_name "somethingAmazing"
11
+ attributes :name
12
+ end
13
+ AD::Framework.register_structural_class(@structural_class)
14
+ @ldap_entry = { "objectclass" => [ @structural_class.ldap_name ] }
15
+ @entry_builder = AD::Framework::Utilities::EntryBuilder.new(@ldap_entry)
16
+ end
17
+ subject{ @entry_builder }
18
+
19
+ should have_accessors :ldap_entry, :entry, :fields
20
+ should have_instance_methods :reload, :build
21
+
22
+ should "have build a fields object from the ldap entry" do
23
+ assert_instance_of AD::Framework::Fields, subject.fields
24
+ end
25
+
26
+ teardown do
27
+ State.restore
28
+ end
29
+ end
30
+
31
+ class BuildTest < BaseTest
32
+ desc "entry builder building a new entry"
33
+ subject{ @entry_builder.entry }
34
+
35
+ should "be a kind of the class in its object class" do
36
+ assert_instance_of @structural_class, subject
37
+ end
38
+ should "have set the fields on the entry to its" do
39
+ assert_equal @entry_builder.fields, subject.fields
40
+ end
41
+ end
42
+
43
+ class ReloadTest < BaseTest
44
+ desc "entry builder reloading an entry"
45
+ setup do
46
+ @entry = @entry_builder.entry
47
+ @entry.fields["something"] = "amazing"
48
+ @entry.name = "something new"
49
+ @entry_builder = AD::Framework::Utilities::EntryBuilder.new(@ldap_entry, {
50
+ :reload => @entry
51
+ })
52
+ end
53
+ subject{ @entry }
54
+
55
+ should "have reset it's fields" do
56
+ assert_not_equal "amazing", subject.fields["something"]
57
+ assert_nil subject.fields["something"]
58
+ end
59
+ should "have reset it's attributes" do
60
+ assert_not_equal "something new", subject.name
61
+ assert_nil subject.name
62
+ end
63
+ end
64
+
65
+ class WithLinkedAuxiliaryClassesTest < BaseTest
66
+ desc "entry builder building a new entry with linked aux classes"
67
+ setup do
68
+ @auxiliary_class = Factory.auxiliary_class do
69
+ ldap_name "displayIt"
70
+ attributes :display_name
71
+ end
72
+ AD::Framework.register_auxiliary_class(@auxiliary_class)
73
+ @ldap_entry = {
74
+ "objectclass" => [ @auxiliary_class.ldap_name, @structural_class.ldap_name ]
75
+ }
76
+ @entry_builder = AD::Framework::Utilities::EntryBuilder.new(@ldap_entry)
77
+ end
78
+ subject{ @entry_builder.entry }
79
+
80
+ should "be a kind of the class in its object class" do
81
+ assert_instance_of @structural_class, subject
82
+ end
83
+ should "have set the fields on the entry to its" do
84
+ assert_equal @entry_builder.fields, subject.fields
85
+ end
86
+ should "have add the auxiliary class to the entry" do
87
+ assert_includes @auxiliary_class, subject.schema.auxiliary_classes
88
+ assert_includes :display_name, subject.schema.attributes
89
+ assert_respond_to :display_name, subject
90
+ end
91
+ end
92
+
93
+ class UndefinedObjectClassTest < Assert::Context
94
+ desc "AD::Framework::Utilities::EntryBuilder"
95
+ setup do
96
+ @ldap_entry = { "objectclass" => [ "notdefinedatall" ] }
97
+ end
98
+ subject{ @ldap_entry }
99
+
100
+ should "raise an object class not defined exception" do
101
+ assert_raises(AD::Framework::ObjectClassNotDefined) do
102
+ AD::Framework::Utilities::EntryBuilder.new(@ldap_entry)
103
+ end
104
+ end
105
+ end
106
+
107
+ end