ad-framework 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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