hobo 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +330 -0
- data/Manifest +12 -4
- data/Rakefile +4 -6
- data/dryml_generators/rapid/cards.dryml.erb +5 -1
- data/dryml_generators/rapid/forms.dryml.erb +8 -10
- data/dryml_generators/rapid/pages.dryml.erb +65 -36
- data/hobo.gemspec +28 -15
- data/lib/active_record/association_collection.rb +3 -22
- data/lib/hobo.rb +25 -258
- data/lib/hobo/accessible_associations.rb +131 -0
- data/lib/hobo/authentication_support.rb +15 -9
- data/lib/hobo/composite_model.rb +1 -1
- data/lib/hobo/controller.rb +7 -8
- data/lib/hobo/dryml.rb +9 -10
- data/lib/hobo/dryml/dryml_builder.rb +7 -1
- data/lib/hobo/dryml/dryml_doc.rb +161 -0
- data/lib/hobo/dryml/dryml_generator.rb +18 -9
- data/lib/hobo/dryml/part_context.rb +76 -42
- data/lib/hobo/dryml/tag_parameters.rb +1 -0
- data/lib/hobo/dryml/taglib.rb +2 -1
- data/lib/hobo/dryml/template.rb +39 -29
- data/lib/hobo/dryml/template_environment.rb +79 -37
- data/lib/hobo/dryml/template_handler.rb +66 -21
- data/lib/hobo/guest.rb +2 -10
- data/lib/hobo/hobo_helper.rb +125 -53
- data/lib/hobo/include_in_save.rb +0 -1
- data/lib/hobo/lifecycles.rb +54 -24
- data/lib/hobo/lifecycles/actions.rb +95 -31
- data/lib/hobo/lifecycles/creator.rb +18 -23
- data/lib/hobo/lifecycles/lifecycle.rb +86 -62
- data/lib/hobo/lifecycles/state.rb +1 -2
- data/lib/hobo/lifecycles/transition.rb +22 -28
- data/lib/hobo/model.rb +64 -176
- data/lib/hobo/model_controller.rb +67 -54
- data/lib/hobo/model_router.rb +5 -2
- data/lib/hobo/permissions.rb +397 -0
- data/lib/hobo/permissions/associations.rb +167 -0
- data/lib/hobo/scopes.rb +15 -38
- data/lib/hobo/scopes/association_proxy_extensions.rb +15 -5
- data/lib/hobo/scopes/automatic_scopes.rb +43 -18
- data/lib/hobo/scopes/named_scope_extensions.rb +2 -2
- data/lib/hobo/user.rb +10 -4
- data/lib/hobo/user_controller.rb +6 -5
- data/lib/hobo/view_hints.rb +58 -0
- data/rails_generators/hobo/hobo_generator.rb +7 -3
- data/rails_generators/hobo/templates/guest.rb +1 -13
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/rails_generators/hobo_model/hobo_model_generator.rb +4 -2
- data/rails_generators/hobo_model/templates/hints.rb +4 -0
- data/rails_generators/hobo_model/templates/model.rb +8 -8
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +10 -0
- data/rails_generators/hobo_model_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +91 -56
- data/rails_generators/hobo_rapid/templates/lowpro.js +15 -15
- data/rails_generators/hobo_rapid/templates/reset.css +36 -3
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +13 -17
- data/rails_generators/hobo_user_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_user_model/templates/model.rb +18 -16
- data/taglibs/core.dryml +60 -18
- data/taglibs/rapid.dryml +8 -401
- data/taglibs/rapid_core.dryml +586 -0
- data/taglibs/rapid_document_tags.dryml +28 -10
- data/taglibs/rapid_editing.dryml +92 -55
- data/taglibs/rapid_forms.dryml +406 -87
- data/taglibs/rapid_generics.dryml +1 -1
- data/taglibs/rapid_navigation.dryml +2 -1
- data/taglibs/rapid_pages.dryml +7 -16
- data/taglibs/rapid_plus.dryml +39 -14
- data/taglibs/rapid_support.dryml +1 -1
- data/taglibs/rapid_user_pages.dryml +14 -4
- data/tasks/{generate_tag_reference.rb → generate_tag_reference.rake} +49 -18
- data/tasks/hobo_tasks.rake +16 -0
- data/test/permissions/models/models.rb +134 -0
- data/test/permissions/models/schema.rb +55 -0
- data/test/permissions/models/test.sqlite3 +0 -0
- data/test/permissions/test_permissions.rb +436 -0
- metadata +27 -14
- data/lib/hobo/mass_assignment.rb +0 -64
- data/rails_generators/hobo/templates/patch_routing.rb +0 -30
- data/uninstall.rb +0 -1
Binary file
|
@@ -0,0 +1,436 @@
|
|
1
|
+
# Notes:
|
2
|
+
#
|
3
|
+
# create/update/delete by guest
|
4
|
+
# create/update/delete by non-permitted user
|
5
|
+
# create/update/delete by permitted user
|
6
|
+
#
|
7
|
+
# All of the above for has-many related records
|
8
|
+
# All of the above for has-many through related records
|
9
|
+
# All of the above for belongs-to related records
|
10
|
+
#
|
11
|
+
# a permitted user can't create/update/delete any of the obove related records without :accessible
|
12
|
+
|
13
|
+
|
14
|
+
require 'test/unit'
|
15
|
+
|
16
|
+
require File.join(File.dirname(__FILE__), "models/models.rb")
|
17
|
+
|
18
|
+
require 'shoulda'
|
19
|
+
|
20
|
+
Models.init
|
21
|
+
|
22
|
+
class PermissionsTest < Test::Unit::TestCase
|
23
|
+
|
24
|
+
def assert_create_prevented(*models)
|
25
|
+
counts = models.*.count
|
26
|
+
assert_raises(Hobo::PermissionDeniedError) { yield }
|
27
|
+
assert_equal(counts, models.*.count)
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_created(*args)
|
31
|
+
expectations = {}
|
32
|
+
args.in_groups_of(2) {|model, expected| expectations[model] = [model.count, expected]}
|
33
|
+
yield
|
34
|
+
expectations.each_pair do |model, nums|
|
35
|
+
count = model.count
|
36
|
+
delta = model.count - nums.first
|
37
|
+
assert_equal(nums.last, delta, "Expected #{nums.last} #{model.name.pluralize} to be created, but #{delta} were")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def assert_change_prevented(record, field)
|
42
|
+
was = record.send(field)
|
43
|
+
assert_raises(Hobo::PermissionDeniedError) { yield }
|
44
|
+
record.reload
|
45
|
+
assert_equal was, record.send(field)
|
46
|
+
end
|
47
|
+
|
48
|
+
def assert_deleted(record)
|
49
|
+
assert_raises(ActiveRecord::RecordNotFound) { record.class.find(record.id) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def assert_destroy_prevented(*records)
|
53
|
+
assert_raises(Hobo::PermissionDeniedError) { yield }
|
54
|
+
records.each { |record| assert record.class.find(record.id) }
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def existing_recipe(user=nil)
|
59
|
+
user ||= User.new :name => "existing recipe owner"
|
60
|
+
Recipe.create :name => "existing recipe", :user => user
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
context "The permission system" do
|
65
|
+
|
66
|
+
context "with a guest user acting" do
|
67
|
+
setup { @guest = Hobo::Guest.new }
|
68
|
+
|
69
|
+
should "prevent creation of a recipe" do
|
70
|
+
assert_create_prevented(Recipe) { Recipe.user_create! @guest, :name => "test recipe" }
|
71
|
+
end
|
72
|
+
|
73
|
+
should "prevent update of an exiting recipe" do
|
74
|
+
r = existing_recipe
|
75
|
+
assert_change_prevented(r, :name) { r.user_update_attributes!(@guest, :name => "pwned!") }
|
76
|
+
end
|
77
|
+
|
78
|
+
should "prevent deletion of an existing recipe" do
|
79
|
+
r = existing_recipe
|
80
|
+
assert_destroy_prevented(r) { r.user_destroy(@guest) }
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with a regular user acting" do
|
86
|
+
|
87
|
+
setup { @user = User.create! :name => "regular" }
|
88
|
+
|
89
|
+
|
90
|
+
# --- Permitted basic actions --- #
|
91
|
+
|
92
|
+
should "allow creation of a recipe" do
|
93
|
+
assert_created Recipe, 1 do
|
94
|
+
@recipe = Recipe.user_create! @user, :name => "test recipe"
|
95
|
+
end
|
96
|
+
assert_equal(@user, @recipe.user)
|
97
|
+
end
|
98
|
+
|
99
|
+
should "allow update of a recipe (owned by the acting user)" do
|
100
|
+
r = existing_recipe(@user)
|
101
|
+
r.user_update_attributes!(@user, :name => "new name")
|
102
|
+
r.reload
|
103
|
+
assert_equal("new name", r.name)
|
104
|
+
end
|
105
|
+
|
106
|
+
should "allow deletion of a recipe (owned by the acting user)" do
|
107
|
+
r = existing_recipe(@user)
|
108
|
+
r.user_destroy(@user)
|
109
|
+
assert_deleted r
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# ---- Prevented basic actions --- #
|
114
|
+
|
115
|
+
should "prevent creation of a recipe owned by another user" do
|
116
|
+
assert_create_prevented(Recipe) { Recipe.user_create! @user, :name => "test recipe", :user => User.new }
|
117
|
+
end
|
118
|
+
|
119
|
+
context "on a recipe owned by another user" do
|
120
|
+
setup { @r = existing_recipe(User.create!(:name => "a n other")) }
|
121
|
+
|
122
|
+
should "prevent update" do
|
123
|
+
assert_change_prevented(@r, :name) { @r.user_update_attributes!(@user, :name => "pwned!") }
|
124
|
+
end
|
125
|
+
|
126
|
+
should "prevent deletion" do
|
127
|
+
assert_destroy_prevented(@r) { @r.user_destroy(@user) }
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# --- Prevented actions on has_many related records --- #
|
134
|
+
|
135
|
+
# (sanity check)
|
136
|
+
should "prevent creation of images without a recipe" do
|
137
|
+
assert_create_prevented(Image) { Image.user_create! @user, :name => "test image" }
|
138
|
+
end
|
139
|
+
|
140
|
+
should "prevent creation of images along with a recipe" do # Only paid up users can
|
141
|
+
assert_create_prevented(Recipe, Image) do
|
142
|
+
Recipe.user_create! @user, :name => "test recipe",
|
143
|
+
:images => { '0' => { :name => "image 1" },
|
144
|
+
'1' => { :name => "image 2" } }
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "on an another's recipe with images" do
|
149
|
+
setup do
|
150
|
+
user = User.create :name => "a n other"
|
151
|
+
@r = Recipe.create! :name => "test recipe", :user => user
|
152
|
+
@i1 = @r.images.create(:name => "image 1")
|
153
|
+
@i2 = @r.images.create(:name => "image 2")
|
154
|
+
end
|
155
|
+
|
156
|
+
should "prevent update of those images" do
|
157
|
+
assert_change_prevented(@i1, :name) do
|
158
|
+
@r.user_update_attributes!(@user, :images => { '0' => { :id => @i1.id, :name => "pwned!" } })
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
should "prevent deletion of those images" do
|
163
|
+
assert_destroy_prevented(@i1, @i2) { @r.user_update_attributes!(@user, :images => { }) }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Note: permitted actions on has-many associated records are in the paid-up user section
|
168
|
+
# Tis the tyranny of the dominant hiearchy : )
|
169
|
+
|
170
|
+
|
171
|
+
# --- Permitted actions on has_many :through relationships --- #
|
172
|
+
|
173
|
+
context "" do
|
174
|
+
setup do
|
175
|
+
@c1 = User.create :name => "Collaborator 1"
|
176
|
+
@c2 = User.create :name => "Collaborator 2"
|
177
|
+
end
|
178
|
+
|
179
|
+
should "allow adding collaborators when creating a recipe" do
|
180
|
+
@r = Recipe.user_create! @user, :name => "my recipe",
|
181
|
+
:collaborators => { '0' => "@#{@c1.id}", '1' => "@#{@c2.id}" }
|
182
|
+
assert_equal(@r.collaborators, [@c1, @c2])
|
183
|
+
end
|
184
|
+
|
185
|
+
should "allow adding collaborators to a recipe" do
|
186
|
+
@r = existing_recipe(@user)
|
187
|
+
|
188
|
+
@r.user_update_attributes! @user, :collaborators => { '0' => "@#{@c1.id}", '1' => "@#{@c2.id}" }
|
189
|
+
assert_equal(@r.collaborators, [@c1, @c2])
|
190
|
+
end
|
191
|
+
|
192
|
+
should "allow removing collaborators from a recipe" do
|
193
|
+
@r = existing_recipe(@user)
|
194
|
+
@r.collaborators << @c1
|
195
|
+
@r.collaborators << @c2
|
196
|
+
join1, join2 = @r.collaboratorships
|
197
|
+
|
198
|
+
# sanity check
|
199
|
+
@r.reload
|
200
|
+
assert_equal(@r.collaborators.length, 2)
|
201
|
+
|
202
|
+
@r.user_update_attributes! @user, :collaborators => {}
|
203
|
+
assert_equal(@r.collaborators.length, 0)
|
204
|
+
|
205
|
+
assert_deleted(join1)
|
206
|
+
assert_deleted(join2)
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
# --- Prevented actions on has_many :through relationships --- #
|
211
|
+
|
212
|
+
context "on another's recipe" do
|
213
|
+
setup do
|
214
|
+
other_user = User.create :name => "a n other"
|
215
|
+
@r = existing_recipe(other_user)
|
216
|
+
end
|
217
|
+
|
218
|
+
should "prevent adding collaborators" do
|
219
|
+
assert_create_prevented(Collaboratorship) do
|
220
|
+
@r.user_update_attributes! @user, :collaborators => { '0' => "@#{@c1.id}", '1' => "@#{@c2.id}" }
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
should "prevent removing collaborators" do
|
225
|
+
c1 = User.create :name => "Collaborator 1"
|
226
|
+
c2 = User.create :name => "Collaborator 2"
|
227
|
+
@r.collaborators << c1
|
228
|
+
@r.collaborators << c2
|
229
|
+
join1, join2 = @r.collaboratorships
|
230
|
+
|
231
|
+
assert_destroy_prevented(join1, join2) do
|
232
|
+
@r.user_update_attributes! @user, :collaborators => {}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
# --- Permitted actions on a belongs_to related record --- #
|
240
|
+
|
241
|
+
should "allow creation of a code-example along with a recipe" do
|
242
|
+
assert_created(Recipe, 1, CodeExample, 1) do
|
243
|
+
@r = Recipe.user_create! @user, :name => "recipe with code example",
|
244
|
+
:code_example => { :filename => "code.zip" }
|
245
|
+
end
|
246
|
+
assert_equal("code.zip", @r.code_example.filename)
|
247
|
+
end
|
248
|
+
|
249
|
+
should "allow creation of a code-example for an existing recipe" do
|
250
|
+
@r = existing_recipe(@user)
|
251
|
+
assert_created(CodeExample, 1) do
|
252
|
+
@r.user_update_attributes! @user, :code_example => { :filename => "code.zip" }
|
253
|
+
end
|
254
|
+
assert_equal("code.zip", @r.code_example.filename)
|
255
|
+
end
|
256
|
+
|
257
|
+
context "on an existing recipe with a code example" do
|
258
|
+
setup do
|
259
|
+
@ce = CodeExample.create! :filename => "exmaple.zip"
|
260
|
+
@r = Recipe.create :name => "existing recipe", :user => @user, :code_example => @ce
|
261
|
+
end
|
262
|
+
|
263
|
+
should "allow update of the code-example" do
|
264
|
+
@r.user_update_attributes! @user, :code_example => { :filename => "changed.zip" }
|
265
|
+
assert_equal("changed.zip", @r.code_example.filename)
|
266
|
+
end
|
267
|
+
|
268
|
+
should "allow removal of the code-example" do
|
269
|
+
@r.user_update_attributes! @user, :code_example => { }
|
270
|
+
@r.reload
|
271
|
+
assert_nil @r.code_example
|
272
|
+
# Note - the code-example is not deleted from the database
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
# --- Prevented actions on a belongs_to related record --- #
|
279
|
+
|
280
|
+
context "on another's recipe" do
|
281
|
+
setup { @r = existing_recipe }
|
282
|
+
|
283
|
+
should "prevent creation of a code-example" do
|
284
|
+
assert_create_prevented(CodeExample) do
|
285
|
+
@r.user_update_attributes! @user, :code_example => { :filename => "code.zip" }
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context "with a code example" do
|
290
|
+
setup do
|
291
|
+
@ce = @r.code_example = CodeExample.create!(:filename => "exmaple.zip")
|
292
|
+
@r.save
|
293
|
+
end
|
294
|
+
|
295
|
+
should "prevent update of the code-example" do
|
296
|
+
assert_change_prevented(@ce, :filename) do
|
297
|
+
@r.user_update_attributes! @user, :code_example => { :filename => "changed.zip" }
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
should "prevent removal of the code-example" do
|
302
|
+
assert_change_prevented(@r, :code_example_id) do
|
303
|
+
@r.user_update_attributes! @user, :code_example => {}
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
# --- Actions on non-accesible has_many associations --- #
|
311
|
+
|
312
|
+
# When associations are not declared :accesssible => true, attemting to update them
|
313
|
+
# causes a type-mismatch
|
314
|
+
|
315
|
+
should "prevent creation of comments via a recipe" do
|
316
|
+
r = existing_recipe
|
317
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) do
|
318
|
+
r.user_update_attributes! @user, :comments => { '0' => { :body => "dodgy comment"} }
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
should "prevent update of comments via their recipe" do
|
323
|
+
r = existing_recipe
|
324
|
+
c = r.comments.create :body => "My nice comment"
|
325
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) do
|
326
|
+
r.user_update_attributes! @user, :comments => { '0' => { :id => c.id, :body => "dodgy comment"} }
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
should "prevent deletion of comments via their recipe" do
|
331
|
+
r = existing_recipe
|
332
|
+
c = r.comments.create :body => "My nice comment"
|
333
|
+
assert_destroy_prevented(c) do
|
334
|
+
r.user_update_attributes! @user, :comments => { }
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
# --- Actions on non-accessible belongs_to associations --- #
|
340
|
+
|
341
|
+
should "prevent creation of a recipe when creating a comment" do
|
342
|
+
count = Recipe.count
|
343
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) do
|
344
|
+
Comment.user_create! @user, :body => "my comment", :recipe => { :name => "I created a recipe!" }
|
345
|
+
end
|
346
|
+
assert_equal(count, Recipe.count)
|
347
|
+
end
|
348
|
+
|
349
|
+
should "prevent update of a recipe via one of its comments" do
|
350
|
+
r = existing_recipe
|
351
|
+
c = r.comments.create :body => "My comment"
|
352
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) do
|
353
|
+
c.user_update_attributes! @user, :recipe => { :id => r.id, :name => "pwned!" }
|
354
|
+
end
|
355
|
+
assert_equal("existing recipe", r.name)
|
356
|
+
end
|
357
|
+
|
358
|
+
should "prevent deletion of a recipe via one of its comments" do
|
359
|
+
r = existing_recipe
|
360
|
+
c = r.comments.create :body => "My comment"
|
361
|
+
assert_raises(ActiveRecord::AssociationTypeMismatch) do
|
362
|
+
c.user_update_attributes! @user, :recipe => { }
|
363
|
+
end
|
364
|
+
assert Recipe.find(r.id)
|
365
|
+
end
|
366
|
+
|
367
|
+
end
|
368
|
+
|
369
|
+
context "with a paid up user acting" do
|
370
|
+
setup { @user = User.create! :name => "paid up user", :paid_up => true }
|
371
|
+
|
372
|
+
should "prevent direct creation of images" do # images must belong to a recipe
|
373
|
+
assert_create_prevented(Image) { Image.user_create! @user, :name => "test image" }
|
374
|
+
end
|
375
|
+
|
376
|
+
# --- Permitted actions on has_many related records --- #
|
377
|
+
|
378
|
+
should "allow creation of images along with a recipe" do
|
379
|
+
|
380
|
+
assert_created Recipe, 1, Image, 2 do
|
381
|
+
@recipe = Recipe.user_create! @user, :images => { '0' => { :name => "image 1" },
|
382
|
+
'1' => { :name => "image 2" } }
|
383
|
+
|
384
|
+
assert_equal(2, @recipe.images.length)
|
385
|
+
i1, i2 = @recipe.images
|
386
|
+
assert_equal("image 1", i1.name)
|
387
|
+
assert_equal("image 2", i2.name)
|
388
|
+
|
389
|
+
assert_equal(@recipe, i1.recipe)
|
390
|
+
assert_equal(@recipe, i2.recipe)
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|
394
|
+
|
395
|
+
context "on an existing recipe with images" do
|
396
|
+
setup do
|
397
|
+
@recipe = Recipe.create! :name => "recipe with images", :user => @user
|
398
|
+
@i1 = @recipe.images.create! :name => "image 1"
|
399
|
+
@i2 = @recipe.images.create! :name => "image 2"
|
400
|
+
end
|
401
|
+
|
402
|
+
should "allow creation of images when updating a recipe" do
|
403
|
+
@recipe.user_update_attributes! @user, :images => { '0' => { :id => @i1.id },
|
404
|
+
'1' => { :id => @i2.id },
|
405
|
+
'2' => { :name => "new image" } }
|
406
|
+
@recipe.reload
|
407
|
+
assert_equal(3, @recipe.images.length)
|
408
|
+
assert_equal("image 1", Image.find(@i1.id).name)
|
409
|
+
assert_equal("image 2", Image.find(@i2.id).name)
|
410
|
+
assert_equal("new image", @recipe.images[2].name)
|
411
|
+
end
|
412
|
+
|
413
|
+
should "allow updates to images when updating a recipe" do
|
414
|
+
@recipe.user_update_attributes! @user, :images => { '0' => { :id => @i1.id, :name => "new name" },
|
415
|
+
'1' => { :id => @i2.id } }
|
416
|
+
@recipe.reload
|
417
|
+
assert_equal(2, @recipe.images.length)
|
418
|
+
assert_equal("new name", Image.find(@i1.id).name)
|
419
|
+
assert_equal("new name", @recipe.images[0].name)
|
420
|
+
end
|
421
|
+
|
422
|
+
should "allow deletion of images when updating a recipe" do
|
423
|
+
@recipe.user_update_attributes! @user, :images => { '0' => { :id => @i1.id } }
|
424
|
+
@recipe.reload
|
425
|
+
assert_equal(1, @recipe.images.length)
|
426
|
+
assert_deleted(@i2)
|
427
|
+
end
|
428
|
+
|
429
|
+
end
|
430
|
+
|
431
|
+
|
432
|
+
end
|
433
|
+
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hobo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Locke
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-12-06 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -18,9 +18,9 @@ dependencies:
|
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
|
-
- - "
|
21
|
+
- - "="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.8.
|
23
|
+
version: 0.8.4
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hobofields
|
@@ -28,9 +28,9 @@ dependencies:
|
|
28
28
|
version_requirement:
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.8.
|
33
|
+
version: 0.8.4
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rails
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
version: 2.2.2
|
44
44
|
version:
|
45
45
|
- !ruby/object:Gem::Dependency
|
46
46
|
name: mislav-will_paginate
|
@@ -65,12 +65,14 @@ extra_rdoc_files:
|
|
65
65
|
- lib/active_record/association_proxy.rb
|
66
66
|
- lib/active_record/association_reflection.rb
|
67
67
|
- lib/extensions/test_case.rb
|
68
|
+
- lib/hobo/accessible_associations.rb
|
68
69
|
- lib/hobo/authentication_support.rb
|
69
70
|
- lib/hobo/bundle.rb
|
70
71
|
- lib/hobo/composite_model.rb
|
71
72
|
- lib/hobo/controller.rb
|
72
73
|
- lib/hobo/dev_controller.rb
|
73
74
|
- lib/hobo/dryml/dryml_builder.rb
|
75
|
+
- lib/hobo/dryml/dryml_doc.rb
|
74
76
|
- lib/hobo/dryml/dryml_generator.rb
|
75
77
|
- lib/hobo/dryml/dryml_support_controller.rb
|
76
78
|
- lib/hobo/dryml/parser/attribute.rb
|
@@ -101,11 +103,12 @@ extra_rdoc_files:
|
|
101
103
|
- lib/hobo/lifecycles/state.rb
|
102
104
|
- lib/hobo/lifecycles/transition.rb
|
103
105
|
- lib/hobo/lifecycles.rb
|
104
|
-
- lib/hobo/mass_assignment.rb
|
105
106
|
- lib/hobo/model.rb
|
106
107
|
- lib/hobo/model_controller.rb
|
107
108
|
- lib/hobo/model_router.rb
|
108
109
|
- lib/hobo/model_support.rb
|
110
|
+
- lib/hobo/permissions/associations.rb
|
111
|
+
- lib/hobo/permissions.rb
|
109
112
|
- lib/hobo/rapid_helper.rb
|
110
113
|
- lib/hobo/scopes/apply_scopes.rb
|
111
114
|
- lib/hobo/scopes/association_proxy_extensions.rb
|
@@ -117,12 +120,13 @@ extra_rdoc_files:
|
|
117
120
|
- lib/hobo/undefined_access_error.rb
|
118
121
|
- lib/hobo/user.rb
|
119
122
|
- lib/hobo/user_controller.rb
|
123
|
+
- lib/hobo/view_hints.rb
|
120
124
|
- lib/hobo.rb
|
121
125
|
- LICENSE.txt
|
122
126
|
- README
|
123
127
|
- tasks/environments.rake
|
124
128
|
- tasks/fix_dryml.rake
|
125
|
-
- tasks/generate_tag_reference.
|
129
|
+
- tasks/generate_tag_reference.rake
|
126
130
|
- tasks/hobo_tasks.rake
|
127
131
|
files:
|
128
132
|
- bin/hobo
|
@@ -136,12 +140,14 @@ files:
|
|
136
140
|
- lib/active_record/association_proxy.rb
|
137
141
|
- lib/active_record/association_reflection.rb
|
138
142
|
- lib/extensions/test_case.rb
|
143
|
+
- lib/hobo/accessible_associations.rb
|
139
144
|
- lib/hobo/authentication_support.rb
|
140
145
|
- lib/hobo/bundle.rb
|
141
146
|
- lib/hobo/composite_model.rb
|
142
147
|
- lib/hobo/controller.rb
|
143
148
|
- lib/hobo/dev_controller.rb
|
144
149
|
- lib/hobo/dryml/dryml_builder.rb
|
150
|
+
- lib/hobo/dryml/dryml_doc.rb
|
145
151
|
- lib/hobo/dryml/dryml_generator.rb
|
146
152
|
- lib/hobo/dryml/dryml_support_controller.rb
|
147
153
|
- lib/hobo/dryml/parser/attribute.rb
|
@@ -172,11 +178,12 @@ files:
|
|
172
178
|
- lib/hobo/lifecycles/state.rb
|
173
179
|
- lib/hobo/lifecycles/transition.rb
|
174
180
|
- lib/hobo/lifecycles.rb
|
175
|
-
- lib/hobo/mass_assignment.rb
|
176
181
|
- lib/hobo/model.rb
|
177
182
|
- lib/hobo/model_controller.rb
|
178
183
|
- lib/hobo/model_router.rb
|
179
184
|
- lib/hobo/model_support.rb
|
185
|
+
- lib/hobo/permissions/associations.rb
|
186
|
+
- lib/hobo/permissions.rb
|
180
187
|
- lib/hobo/rapid_helper.rb
|
181
188
|
- lib/hobo/scopes/apply_scopes.rb
|
182
189
|
- lib/hobo/scopes/association_proxy_extensions.rb
|
@@ -188,6 +195,7 @@ files:
|
|
188
195
|
- lib/hobo/undefined_access_error.rb
|
189
196
|
- lib/hobo/user.rb
|
190
197
|
- lib/hobo/user_controller.rb
|
198
|
+
- lib/hobo/view_hints.rb
|
191
199
|
- lib/hobo.rb
|
192
200
|
- LICENSE.txt
|
193
201
|
- Manifest
|
@@ -197,7 +205,6 @@ files:
|
|
197
205
|
- rails_generators/hobo/templates/dryml-support.js
|
198
206
|
- rails_generators/hobo/templates/guest.rb
|
199
207
|
- rails_generators/hobo/templates/initializer.rb
|
200
|
-
- rails_generators/hobo/templates/patch_routing.rb
|
201
208
|
- rails_generators/hobo_front_controller/hobo_front_controller_generator.rb
|
202
209
|
- rails_generators/hobo_front_controller/templates/controller.rb
|
203
210
|
- rails_generators/hobo_front_controller/templates/functional_test.rb
|
@@ -206,6 +213,7 @@ files:
|
|
206
213
|
- rails_generators/hobo_front_controller/USAGE
|
207
214
|
- rails_generators/hobo_model/hobo_model_generator.rb
|
208
215
|
- rails_generators/hobo_model/templates/fixtures.yml
|
216
|
+
- rails_generators/hobo_model/templates/hints.rb
|
209
217
|
- rails_generators/hobo_model/templates/model.rb
|
210
218
|
- rails_generators/hobo_model/templates/unit_test.rb
|
211
219
|
- rails_generators/hobo_model/USAGE
|
@@ -254,6 +262,7 @@ files:
|
|
254
262
|
- script/generate
|
255
263
|
- taglibs/core.dryml
|
256
264
|
- taglibs/rapid.dryml
|
265
|
+
- taglibs/rapid_core.dryml
|
257
266
|
- taglibs/rapid_document_tags.dryml
|
258
267
|
- taglibs/rapid_editing.dryml
|
259
268
|
- taglibs/rapid_forms.dryml
|
@@ -266,12 +275,15 @@ files:
|
|
266
275
|
- taglibs/rapid_user_pages.dryml
|
267
276
|
- tasks/environments.rake
|
268
277
|
- tasks/fix_dryml.rake
|
269
|
-
- tasks/generate_tag_reference.
|
278
|
+
- tasks/generate_tag_reference.rake
|
270
279
|
- tasks/hobo_tasks.rake
|
271
280
|
- test/generators/test_generator_helper.rb
|
272
281
|
- test/generators/test_helper.rb
|
273
282
|
- test/generators/test_hobo_model_controller_generator.rb
|
274
|
-
-
|
283
|
+
- test/permissions/models/models.rb
|
284
|
+
- test/permissions/models/schema.rb
|
285
|
+
- test/permissions/models/test.sqlite3
|
286
|
+
- test/permissions/test_permissions.rb
|
275
287
|
- hobo.gemspec
|
276
288
|
has_rdoc: true
|
277
289
|
homepage: http://hobocentral.net/
|
@@ -300,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
312
|
requirements: []
|
301
313
|
|
302
314
|
rubyforge_project: hobo
|
303
|
-
rubygems_version: 1.
|
315
|
+
rubygems_version: 1.3.1
|
304
316
|
signing_key:
|
305
317
|
specification_version: 2
|
306
318
|
summary: The web app builder for Rails
|
@@ -309,3 +321,4 @@ test_files:
|
|
309
321
|
- test/generators/test_generator_helper.rb
|
310
322
|
- test/generators/test_helper.rb
|
311
323
|
- test/generators/test_hobo_model_controller_generator.rb
|
324
|
+
- test/permissions/test_permissions.rb
|