pluginaweek-preferences 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ module Preferences
2
+ # Represents the definition of a preference for a particular model
3
+ class PreferenceDefinition
4
+ def initialize(name, *args) #:nodoc:
5
+ options = args.extract_options!
6
+ options.assert_valid_keys(:default)
7
+
8
+ @type = args.first ? args.first.to_s : 'boolean'
9
+
10
+ # Create a column that will be responsible for typecasting
11
+ @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == 'any' ? nil : @type)
12
+ end
13
+
14
+ # The name of the preference
15
+ def name
16
+ @column.name
17
+ end
18
+
19
+ # The default value to use for the preference in case none have been
20
+ # previously defined
21
+ def default_value
22
+ @column.default
23
+ end
24
+
25
+ # Typecasts the value based on the type of preference that was defined.
26
+ # This uses ActiveRecord's typecast functionality so the same rules for
27
+ # typecasting a model's columns apply here.
28
+ def type_cast(value)
29
+ @type == 'any' ? value : @column.type_cast(value)
30
+ end
31
+
32
+ # Typecasts the value to true/false depending on the type of preference
33
+ def query(value)
34
+ if !(value = type_cast(value))
35
+ false
36
+ elsif @column.number?
37
+ !value.zero?
38
+ else
39
+ !value.blank?
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,2 @@
1
+ class Car < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class Employee < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class Manager < Employee
2
+ preference :health_insurance
3
+ end
@@ -0,0 +1,7 @@
1
+ class User < ActiveRecord::Base
2
+ preference :hot_salsa
3
+ preference :dark_chocolate, :default => true
4
+ preference :color, :string
5
+ preference :car, :integer
6
+ preference :language, :string, :default => 'English'
7
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :login, :null => false
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :users
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateCars < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cars do |t|
4
+ t.string :name, :null => false
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :cars
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class CreateEmployees < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :employees do |t|
4
+ t.string :name, :null => false
5
+ t.string :type
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :employees
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class MigratePreferencesToVersion1 < ActiveRecord::Migration
2
+ def self.up
3
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
4
+ migration.migrate(:up)
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
10
+ migration.migrate(:down)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,65 @@
1
+ module Factory
2
+ # Build actions for the model
3
+ def self.build(model, &block)
4
+ name = model.to_s.underscore
5
+
6
+ define_method("#{name}_attributes", block)
7
+ define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)}
8
+ define_method("new_#{name}") {|*args| new_record(model, *args)}
9
+ define_method("create_#{name}") {|*args| create_record(model, *args)}
10
+ end
11
+
12
+ # Get valid attributes for the model
13
+ def valid_attributes_for(model, attributes = {})
14
+ name = model.to_s.underscore
15
+ send("#{name}_attributes", attributes)
16
+ attributes.stringify_keys!
17
+ attributes
18
+ end
19
+
20
+ # Build an unsaved record
21
+ def new_record(model, *args)
22
+ attributes = valid_attributes_for(model, *args)
23
+ record = model.new(attributes)
24
+ attributes.each {|attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr)}
25
+ record
26
+ end
27
+
28
+ # Build and save/reload a record
29
+ def create_record(model, *args)
30
+ record = new_record(model, *args)
31
+ record.save!
32
+ record.reload
33
+ record
34
+ end
35
+
36
+ build Car do |attributes|
37
+ attributes.reverse_merge!(
38
+ :name => 'Porsche'
39
+ )
40
+ end
41
+
42
+ build Employee do |attributes|
43
+ attributes.reverse_merge!(
44
+ :name => 'John Smith'
45
+ )
46
+ end
47
+
48
+ build Manager do |attributes|
49
+ valid_employee_attributes(attributes)
50
+ end
51
+
52
+ build Preference do |attributes|
53
+ attributes[:owner] = create_user unless attributes.include?(:owner)
54
+ attributes.reverse_merge!(
55
+ :name => 'notifications',
56
+ :value => false
57
+ )
58
+ end
59
+
60
+ build User do |attributes|
61
+ attributes.reverse_merge!(
62
+ :login => 'admin'
63
+ )
64
+ end
65
+ end
@@ -0,0 +1,426 @@
1
+ require "#{File.dirname(__FILE__)}/../test_helper"
2
+
3
+ class PreferencesTest < ActiveSupport::TestCase
4
+ def setup
5
+ User.preference :notifications, :boolean
6
+
7
+ @user = User.new
8
+ end
9
+
10
+ def test_should_raise_exception_if_invalid_options_specified
11
+ assert_raise(ArgumentError) {User.preference :notifications, :invalid => true}
12
+ assert_raise(ArgumentError) {User.preference :notifications, :boolean, :invalid => true}
13
+ end
14
+
15
+ def test_should_create_preferred_query_method
16
+ assert @user.respond_to?(:preferred_notifications?)
17
+ end
18
+
19
+ def test_should_create_prefers_query_method
20
+ assert @user.respond_to?(:prefers_notifications?)
21
+ end
22
+
23
+ def test_should_create_preferred_reader
24
+ assert @user.respond_to?(:preferred_notifications)
25
+ end
26
+
27
+ def test_should_create_prefers_reader
28
+ assert @user.respond_to?(:prefers_notifications)
29
+ end
30
+
31
+ def test_should_create_preferred_writer
32
+ assert @user.respond_to?(:preferred_notifications=)
33
+ end
34
+
35
+ def test_should_create_prefers_writer
36
+ assert @user.respond_to?(:prefers_notifications=)
37
+ end
38
+
39
+ def test_should_create_preference_definitions
40
+ assert User.respond_to?(:preference_definitions)
41
+ end
42
+
43
+ def test_should_create_default_preferences
44
+ assert User.respond_to?(:default_preferences)
45
+ end
46
+
47
+ def test_should_include_new_definitions_in_preference_definitions
48
+ assert_not_nil User.preference_definitions['notifications']
49
+ end
50
+
51
+ def teardown
52
+ User.preference_definitions.delete('notifications')
53
+ User.default_preferences.delete('notifications')
54
+ end
55
+ end
56
+
57
+ class UserByDefaultTest < ActiveSupport::TestCase
58
+ def setup
59
+ @user = User.new
60
+ end
61
+
62
+ def test_should_not_prefer_hot_salsa
63
+ assert_nil @user.preferred_hot_salsa
64
+ assert_nil @user.prefers_hot_salsa
65
+ end
66
+
67
+ def test_should_prefer_dark_chocolate
68
+ assert_equal true, @user.preferred_dark_chocolate
69
+ assert_equal true, @user.prefers_dark_chocolate
70
+ end
71
+
72
+ def test_should_not_have_a_preferred_color
73
+ assert_nil @user.preferred_color
74
+ end
75
+
76
+ def test_should_not_have_a_preferred_car
77
+ assert_nil @user.preferred_car
78
+ end
79
+
80
+ def test_should_have_a_preferred_language
81
+ assert_equal 'English', @user.preferred_language
82
+ end
83
+
84
+ def test_should_have_only_default_preferences
85
+ expected = {
86
+ 'hot_salsa' => nil,
87
+ 'dark_chocolate' => true,
88
+ 'color' => nil,
89
+ 'car' => nil,
90
+ 'language' => 'English'
91
+ }
92
+
93
+ assert_equal expected, @user.preferences
94
+ end
95
+ end
96
+
97
+ class UserTest < ActiveSupport::TestCase
98
+ def setup
99
+ @user = new_user
100
+ end
101
+
102
+ def test_should_be_able_to_change_hot_salsa_preference
103
+ @user.prefers_hot_salsa = false
104
+ assert_equal false, @user.prefers_hot_salsa?
105
+
106
+ @user.prefers_hot_salsa = true
107
+ assert_equal true, @user.prefers_hot_salsa?
108
+ end
109
+
110
+ def test_should_be_able_to_change_dark_chocolate_preference
111
+ @user.prefers_dark_chocolate = false
112
+ assert_equal false, @user.prefers_dark_chocolate?
113
+
114
+ @user.prefers_dark_chocolate = true
115
+ assert_equal true, @user.prefers_dark_chocolate?
116
+ end
117
+
118
+ def test_should_be_able_to_change_color_preference
119
+ @user.preferred_color = 'blue'
120
+ assert_equal 'blue', @user.preferred_color
121
+ end
122
+
123
+ def test_should_be_able_to_change_car_preference
124
+ @user.preferred_car = 1
125
+ assert_equal 1, @user.preferred_car
126
+ end
127
+
128
+ def test_should_be_able_to_change_language_preference
129
+ @user.preferred_language = 'Latin'
130
+ assert_equal 'Latin', @user.preferred_language
131
+ end
132
+
133
+ def test_should_be_able_to_use_generic_preferred_query_method
134
+ @user.prefers_hot_salsa = true
135
+ assert @user.preferred?(:hot_salsa)
136
+ end
137
+
138
+ def test_should_be_able_to_use_generic_prefers_query_method
139
+ @user.prefers_hot_salsa = true
140
+ assert @user.prefers?(:hot_salsa)
141
+ end
142
+
143
+ def test_should_be_able_to_use_generic_preferred_method
144
+ @user.preferred_color = 'blue'
145
+ assert_equal 'blue', @user.preferred(:color)
146
+ end
147
+
148
+ def test_should_be_able_to_use_generic_prefers_method
149
+ @user.preferred_color = 'blue'
150
+ assert_equal 'blue', @user.prefers(:color)
151
+ end
152
+
153
+ def test_should_be_able_to_use_generic_set_preference_method
154
+ @user.set_preference(:color, 'blue')
155
+ assert_equal 'blue', @user.preferred(:color)
156
+ end
157
+
158
+ def test_should_still_be_new_record_after_changing_preference
159
+ @user.preferred_color = 'blue'
160
+ assert @user.new_record?
161
+ assert @user.stored_preferences.empty?
162
+ end
163
+ end
164
+
165
+ class UserAfterBeingCreatedTest < ActiveSupport::TestCase
166
+ def setup
167
+ @user = create_user
168
+ end
169
+
170
+ def test_should_not_have_any_stored_preferences
171
+ assert @user.stored_preferences.empty?
172
+ end
173
+ end
174
+
175
+ class UserWithoutStoredPreferencesTest < ActiveSupport::TestCase
176
+ def setup
177
+ @user = create_user
178
+ end
179
+
180
+ def test_should_not_prefer_hot_salsa
181
+ assert_nil @user.preferred_hot_salsa
182
+ end
183
+
184
+ def test_should_prefer_dark_chocolate
185
+ assert_equal true, @user.preferred_dark_chocolate
186
+ end
187
+
188
+ def test_should_not_have_a_preferred_color
189
+ assert_nil @user.preferred_color
190
+ end
191
+
192
+ def test_should_not_have_a_preferred_car
193
+ assert_nil @user.preferred_car
194
+ end
195
+
196
+ def test_should_have_a_preferred_language
197
+ assert_equal 'English', @user.preferred_language
198
+ end
199
+
200
+ def test_should_not_save_record_after_changing_preference
201
+ @user.preferred_language = 'Latin'
202
+
203
+ user = User.find(@user.id)
204
+ assert_equal 'English', user.preferred_language
205
+ assert user.stored_preferences.empty?
206
+ end
207
+ end
208
+
209
+ class UserWithStoredPreferencesTest < ActiveSupport::TestCase
210
+ def setup
211
+ @user = create_user
212
+ @user.preferred_language = 'Latin'
213
+ @user.save!
214
+ end
215
+
216
+ def test_should_have_stored_preferences
217
+ assert_equal 1, @user.stored_preferences.size
218
+ end
219
+
220
+ def test_should_include_custom_and_default_preferences_in_preferences
221
+ expected = {
222
+ 'hot_salsa' => nil,
223
+ 'dark_chocolate' => true,
224
+ 'color' => nil,
225
+ 'car' => nil,
226
+ 'language' => 'Latin'
227
+ }
228
+
229
+ assert_equal expected, @user.preferences
230
+ end
231
+
232
+ def test_should_use_preferences_for_prefs
233
+ expected = {
234
+ 'hot_salsa' => nil,
235
+ 'dark_chocolate' => true,
236
+ 'color' => nil,
237
+ 'car' => nil,
238
+ 'language' => 'Latin'
239
+ }
240
+
241
+ assert_equal expected, @user.prefs
242
+ end
243
+
244
+ def test_should_not_remove_preference_if_set_to_default
245
+ @user.preferred_language = 'English'
246
+ @user.save!
247
+ @user.reload
248
+ assert_equal 1, @user.stored_preferences.size
249
+ end
250
+
251
+ def test_should_not_remove_preference_if_set_to_nil
252
+ @user.preferred_language = nil
253
+ @user.save!
254
+ @user.reload
255
+ assert_equal 1, @user.stored_preferences.size
256
+ end
257
+
258
+ def test_should_not_save_preference_if_model_is_not_saved
259
+ @user.preferred_language = 'English'
260
+
261
+ user = User.find(@user.id)
262
+ assert_equal 'Latin', user.preferred_language
263
+ end
264
+
265
+ def test_should_modify_existing_preferences_when_saved
266
+ @user.preferred_language = 'Spanish'
267
+ assert @user.save
268
+
269
+ @user.reload
270
+ assert_equal 'Spanish', @user.preferred_language
271
+ assert_equal 1, @user.stored_preferences.size
272
+ end
273
+
274
+ def test_should_add_new_preferences_when_saved
275
+ @user.preferred_color = 'blue'
276
+ assert @user.save
277
+
278
+ @user.reload
279
+ assert_equal 'blue', @user.preferred_color
280
+ assert_equal 2, @user.stored_preferences.size
281
+ end
282
+ end
283
+
284
+ class UserWithStoredPreferencesForBasicGroupsTest < ActiveSupport::TestCase
285
+ def setup
286
+ @user = create_user
287
+ @user.preferred_color = 'red', 'cars'
288
+ @user.save!
289
+ end
290
+
291
+ def test_should_have_stored_preferences
292
+ assert_equal 1, @user.stored_preferences.size
293
+ end
294
+
295
+ def test_should_include_group_in_preferences
296
+ expected = {
297
+ 'hot_salsa' => nil,
298
+ 'dark_chocolate' => true,
299
+ 'color' => nil,
300
+ 'car' => nil,
301
+ 'language' => 'English',
302
+ 'cars' => {
303
+ 'hot_salsa' => nil,
304
+ 'dark_chocolate' => true,
305
+ 'color' => 'red',
306
+ 'car' => nil,
307
+ 'language' => 'English'
308
+ }
309
+ }
310
+
311
+ assert_equal expected, @user.preferences
312
+ end
313
+
314
+ def test_should_be_able_to_show_all_preferences_just_for_the_owner
315
+ expected = {
316
+ 'hot_salsa' => nil,
317
+ 'dark_chocolate' => true,
318
+ 'color' => nil,
319
+ 'car' => nil,
320
+ 'language' => 'English'
321
+ }
322
+
323
+ assert_equal expected, @user.preferences(nil)
324
+ end
325
+
326
+ def test_should_be_able_to_show_all_preferences_for_a_single_group
327
+ expected = {
328
+ 'hot_salsa' => nil,
329
+ 'dark_chocolate' => true,
330
+ 'color' => 'red',
331
+ 'car' => nil,
332
+ 'language' => 'English'
333
+ }
334
+
335
+ assert_equal expected, @user.preferences('cars')
336
+ end
337
+
338
+ def test_should_not_have_preference_without_group
339
+ assert_nil @user.preferred_color
340
+ end
341
+
342
+ def test_should_have_preference_with_group
343
+ assert_equal 'red', @user.preferred_color('cars')
344
+ end
345
+
346
+ def test_should_modify_existing_preferences_when_saved
347
+ @user.preferred_color = 'blue', 'cars'
348
+ assert @user.save
349
+
350
+ @user.reload
351
+ assert_equal 'blue', @user.preferred_color('cars')
352
+ assert_equal 1, @user.stored_preferences.size
353
+ end
354
+
355
+ def test_should_be_able_to_differentiate_between_groups
356
+ @user.preferred_color = 'blue', 'boats'
357
+ assert @user.save
358
+
359
+ @user.reload
360
+ assert_equal 'red', @user.preferred_color('cars')
361
+ assert_equal 'blue', @user.preferred_color('boats')
362
+ assert_equal 2, @user.stored_preferences.size
363
+ end
364
+ end
365
+
366
+ class UserWithStoredPreferencesForActiveRecordGroupsTest < ActiveSupport::TestCase
367
+ def setup
368
+ @car = create_car
369
+
370
+ @user = create_user
371
+ @user.preferred_color = 'red', @car
372
+ @user.save!
373
+ end
374
+
375
+ def test_should_have_stored_preferences
376
+ assert_equal 1, @user.stored_preferences.size
377
+ end
378
+
379
+ def test_should_have_preferences_for_group
380
+ expected = {
381
+ 'hot_salsa' => nil,
382
+ 'dark_chocolate' => true,
383
+ 'color' => nil,
384
+ 'car' => nil,
385
+ 'language' => 'English',
386
+ @car => {
387
+ 'hot_salsa' => nil,
388
+ 'dark_chocolate' => true,
389
+ 'color' => 'red',
390
+ 'car' => nil,
391
+ 'language' => 'English'
392
+ }
393
+ }
394
+
395
+ assert_equal expected, @user.preferences
396
+ end
397
+
398
+ def test_should_not_have_preference_without_group
399
+ assert_nil @user.preferred_color
400
+ end
401
+
402
+ def test_should_have_preference_with_group
403
+ assert_equal 'red', @user.preferred_color(@car)
404
+ end
405
+
406
+ def test_should_modify_existing_preferences_when_saved
407
+ @user.preferred_color = 'blue', @car
408
+ assert @user.save
409
+
410
+ @user.reload
411
+ assert_equal 'blue', @user.preferred_color(@car)
412
+ assert_equal 1, @user.stored_preferences.size
413
+ end
414
+
415
+ def test_should_be_able_to_differentiate_between_groups
416
+ @different_car = create_car
417
+
418
+ @user.preferred_color = 'blue', @different_car
419
+ assert @user.save
420
+
421
+ @user.reload
422
+ assert_equal 'red', @user.preferred_color(@car)
423
+ assert_equal 'blue', @user.preferred_color(@different_car)
424
+ assert_equal 2, @user.stored_preferences.size
425
+ end
426
+ end