hobo 0.8.3 → 0.8.4
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.
- 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
|