programmable_scaffold_rails 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +116 -0
  8. data/Rakefile +1 -0
  9. data/config.ru +9 -0
  10. data/config/action_controller.yml +12 -0
  11. data/config/locales/en.yml +8 -0
  12. data/lib/programmable_scaffold_rails.rb +17 -0
  13. data/lib/programmable_scaffold_rails/action_controller_extensions.rb +72 -0
  14. data/lib/programmable_scaffold_rails/action_controller_helpers.rb +163 -0
  15. data/lib/programmable_scaffold_rails/config.rb +15 -0
  16. data/lib/programmable_scaffold_rails/engine.rb +6 -0
  17. data/lib/programmable_scaffold_rails/scaffold/create.rb +51 -0
  18. data/lib/programmable_scaffold_rails/scaffold/destroy.rb +53 -0
  19. data/lib/programmable_scaffold_rails/scaffold/edit.rb +21 -0
  20. data/lib/programmable_scaffold_rails/scaffold/index.rb +20 -0
  21. data/lib/programmable_scaffold_rails/scaffold/new.rb +21 -0
  22. data/lib/programmable_scaffold_rails/scaffold/show.rb +21 -0
  23. data/lib/programmable_scaffold_rails/scaffold/update.rb +49 -0
  24. data/lib/programmable_scaffold_rails/version.rb +3 -0
  25. data/programmable_scaffold_rails.gemspec +34 -0
  26. data/spec/action_controller_extensions.rb_spec.rb +60 -0
  27. data/spec/action_controller_helpers_spec.rb +90 -0
  28. data/spec/controllers/dummies_controller_spec.rb +416 -0
  29. data/spec/factories.rb +10 -0
  30. data/spec/internal/app/controllers/dummies_controller.rb +9 -0
  31. data/spec/internal/app/models/dummy.rb +11 -0
  32. data/spec/internal/app/views/dummies/edit.html.erb +0 -0
  33. data/spec/internal/app/views/dummies/index.html.erb +0 -0
  34. data/spec/internal/app/views/dummies/index.json.builder +4 -0
  35. data/spec/internal/app/views/dummies/new.html.erb +0 -0
  36. data/spec/internal/app/views/dummies/show.html.erb +0 -0
  37. data/spec/internal/app/views/dummies/show.json.builder +1 -0
  38. data/spec/internal/config/database.yml +4 -0
  39. data/spec/internal/config/routes.rb +6 -0
  40. data/spec/internal/db/schema.rb +7 -0
  41. data/spec/internal/log/.gitignore +1 -0
  42. data/spec/internal/public/favicon.ico +0 -0
  43. data/spec/programmable_scaffold_rails_spec.rb +38 -0
  44. data/spec/spec_helper.rb +49 -0
  45. metadata +276 -0
@@ -0,0 +1,416 @@
1
+ require 'spec_helper'
2
+ require 'internal/app/controllers/dummies_controller'
3
+
4
+
5
+ describe DummiesController do
6
+ before(:each) do
7
+ controller.stub(:authorize!).with(anything(), anything()).and_return(true)
8
+ end
9
+
10
+ it "GET #new" do
11
+ get :new
12
+
13
+ assigns(:dummy).should be_an_instance_of(Dummy)
14
+ end
15
+
16
+ it "POST #create" do
17
+ dummy_params = FactoryGirl.attributes_for(:dummy)
18
+
19
+ expect{post :create, dummy: dummy_params}.to change(Dummy, :count).by(1)
20
+ end
21
+
22
+ it "GET #index" do
23
+ dummies = FactoryGirl.create_list(:dummy, 2)
24
+
25
+ get :index
26
+
27
+ assigns(:dummies).should match_array(dummies)
28
+ end
29
+
30
+ it "GET #show" do
31
+ dummy = FactoryGirl.create(:dummy)
32
+
33
+ get :show, id: dummy.id
34
+
35
+ assigns(:dummy).should == dummy
36
+ end
37
+
38
+ it "GET #edit" do
39
+ dummy = FactoryGirl.create(:dummy)
40
+
41
+ get :edit, id: dummy.id
42
+
43
+ assigns(:dummy).should == dummy
44
+ end
45
+
46
+ it "PUT/PATCH #update" do
47
+ dummy_name = 'dummy2'
48
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
49
+
50
+ put :update, id: dummy.id, dummy: { name: dummy_name }
51
+
52
+ assigns(:dummy).name.should match dummy_name
53
+ end
54
+
55
+ it "DELETE #destroy" do
56
+ dummy = FactoryGirl.create(:dummy)
57
+
58
+ delete :destroy, id: dummy.id
59
+
60
+ expect{dummy.class.find(dummy.id)}.to raise_error(ActiveRecord::RecordNotFound)
61
+ end
62
+
63
+ context "with json disabled" do
64
+ before(:each) do
65
+ controller.programmable_scaffold_controller_helpers
66
+ .stub(:formats).and_return([:html])
67
+ end
68
+
69
+ it "POST #create" do
70
+ dummy_params = FactoryGirl.attributes_for(:dummy)
71
+
72
+ expect{post :create, dummy: dummy_params, format: :json}.to raise_error(ActionController::UnknownFormat)
73
+ end
74
+
75
+ it "PUT/PATCH #update" do
76
+ dummy_name = 'dummy2'
77
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
78
+
79
+ expect{put :update, id: dummy.id, dummy: { name: dummy_name }, format: :json}.to raise_error(ActionController::UnknownFormat)
80
+ end
81
+
82
+ it "DELETE #destroy" do
83
+ dummy = FactoryGirl.create(:dummy)
84
+
85
+ expect{delete :destroy, id: dummy.id, format: :json}.to raise_error(ActionController::UnknownFormat)
86
+ end
87
+
88
+ end
89
+
90
+ context "with json enabled" do
91
+ before(:each) do
92
+ controller.programmable_scaffold_controller_helpers
93
+ .stub(:formats).and_return([:html, :json])
94
+ end
95
+
96
+ it "POST #create" do
97
+ dummy_params = FactoryGirl.attributes_for(:dummy)
98
+
99
+ expect{post :create, dummy: dummy_params, format: :json}.not_to raise_error
100
+ end
101
+
102
+ it "PUT/PATCH #update" do
103
+ dummy_name = 'dummy2'
104
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
105
+
106
+ expect{put :update, id: dummy.id, dummy: { name: dummy_name }, format: :json}.not_to raise_error
107
+ end
108
+
109
+ it "DELETE #destroy" do
110
+ dummy = FactoryGirl.create(:dummy)
111
+
112
+ expect{delete :destroy, id: dummy.id, format: :json}.not_to raise_error
113
+ end
114
+
115
+ end
116
+
117
+ context "without authorization" do
118
+ before(:each) do
119
+ controller.stub(:authorize!).with(anything(), anything()).and_raise
120
+ end
121
+
122
+ it "GET #new" do
123
+ expect{get :new}.to raise_error
124
+ end
125
+
126
+ it "POST #create" do
127
+ dummy_params = FactoryGirl.attributes_for(:dummy)
128
+ expect{post :create, dummy: dummy_params}.to raise_error
129
+ end
130
+
131
+ it "GET #index" do
132
+ dummies = FactoryGirl.create_list(:dummy, 2)
133
+
134
+ expect{get :index}.to raise_error
135
+ end
136
+
137
+ it "GET #show" do
138
+ dummy = FactoryGirl.create(:dummy)
139
+
140
+ expect{get :show, id: dummy.id}.to raise_error
141
+ end
142
+
143
+ it "GET #edit" do
144
+ dummy = FactoryGirl.create(:dummy)
145
+
146
+ expect{get :edit, id: dummy.id}.to raise_error
147
+ end
148
+
149
+ it "PUT/PATCH #update" do
150
+ dummy_name = 'dummy2'
151
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
152
+
153
+ expect{put :update, id: dummy.id, dummy: { name: dummy_name }}.to raise_error
154
+ end
155
+
156
+ it "DELETE #destroy" do
157
+ dummy = FactoryGirl.create(:dummy)
158
+
159
+ expect{delete :destroy, id: dummy.id}.to raise_error
160
+ end
161
+
162
+ end
163
+
164
+ context "with errors" do
165
+
166
+ it "POST #create" do
167
+ dummy_params = FactoryGirl.attributes_for(:dummy_invalid)
168
+
169
+ post :create, dummy: dummy_params
170
+
171
+ response.should render_template('new')
172
+ end
173
+
174
+ it "PUT/PATCH #update" do
175
+ dummy_name = 'dummy2'
176
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
177
+
178
+ put :update, id: dummy.id, dummy: { name: dummy_name, will_invalidate: true }
179
+
180
+ response.should render_template('edit')
181
+ end
182
+
183
+ end
184
+
185
+ context "after_XXX_url" do
186
+ let(:controller_helpers) { controller_helpers = controller.programmable_scaffold_controller_helpers }
187
+
188
+ its "called during POST #create" do
189
+ dummy_params = FactoryGirl.attributes_for(:dummy)
190
+
191
+ controller_helpers.should_receive(:after_create_url)
192
+ .with(kind_of(ActiveRecord::Base))
193
+ .and_call_original
194
+ post :create, dummy: dummy_params
195
+ end
196
+
197
+ its "called during PUT/PATCH #update" do
198
+ dummy_name = 'dummy2'
199
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
200
+
201
+ controller_helpers.should_receive(:after_update_url)
202
+ .with(kind_of(ActiveRecord::Base))
203
+ .and_call_original
204
+ put :update, id: dummy.id, dummy: { name: dummy_name }
205
+ end
206
+
207
+ its "called during DELETE #destroy" do
208
+ dummy = FactoryGirl.create(:dummy)
209
+
210
+ controller_helpers.should_receive(:after_destroy_url)
211
+ .with(kind_of(ActiveRecord::Base))
212
+ .and_call_original
213
+
214
+ delete :destroy, id: dummy.id
215
+ end
216
+
217
+ context "runs with namespace set" do
218
+ let(:dummy) { FactoryGirl.create(:dummy) }
219
+
220
+ it "after_create_url returns an url with namespace when is set" do
221
+ controller_helpers.stub(:url_namespace).and_return('admin')
222
+
223
+ controller_helpers.send(:after_create_url, dummy).should end_with "/admin/dummies/#{ dummy.id }"
224
+ end
225
+
226
+ it "after_create_url returns an url without namespace when is not set" do
227
+ controller_helpers.send(:after_create_url, dummy).should end_with "/dummies/#{ dummy.id }"
228
+ end
229
+
230
+ it "after_update_url returns an url with namespace when is set" do
231
+ controller_helpers.stub(:url_namespace).and_return('admin')
232
+
233
+ controller_helpers.send(:after_update_url, dummy).should end_with "/admin/dummies/#{ dummy.id }"
234
+ end
235
+
236
+ it "after_update_url returns an url without namespace when is not set" do
237
+ controller_helpers.send(:after_update_url, dummy).should end_with "/dummies/#{ dummy.id }"
238
+ end
239
+
240
+ it "after_destroy_url returns an url with namespace when is set" do
241
+ controller_helpers.stub(:url_namespace).and_return('admin')
242
+
243
+ controller_helpers.send(:after_destroy_url, dummy).should end_with "/admin/dummies"
244
+ end
245
+
246
+ it "after_destroy_url returns an url without namespace when is not set" do
247
+ controller_helpers.send(:after_destroy_url, dummy).should end_with "/dummies"
248
+ end
249
+
250
+ end
251
+
252
+ [:create, :update, :destroy].each do |crud_action|
253
+ context "#{ crud_action }" do
254
+ let(:dummy) { FactoryGirl.create(:dummy) }
255
+ let(:old_options) { controller_helpers.send(:options).dup }
256
+
257
+ its "called with a symbol and runs a method on the controller with after_#{ crud_action }_url name" do
258
+ old_options[:"after_#{ crud_action }_url"] = :"dummy_after_#{ crud_action }_url"
259
+ controller_helpers.stub(:options).and_return(old_options.freeze)
260
+ controller.stub(:"dummy_after_#{ crud_action }_url").with(anything()).and_return(controller.dummies_url)
261
+
262
+ controller_helpers.send(:"after_#{ crud_action }_url", dummy).should match controller.dummies_url
263
+ end
264
+
265
+ its "called with a proc and runs it" do
266
+ # XXX: Notice that in this case self is == to controller because code is
267
+ # instance_exec-uted
268
+ old_options[:"after_#{ crud_action }_url"] = ->(obj) { self.dummies_url }
269
+ controller_helpers.stub(:options).and_return(old_options.freeze)
270
+
271
+ controller_helpers.send(:"after_#{ crud_action }_url", dummy).should match controller.dummies_url
272
+ end
273
+
274
+ its "called with a string and runs it" do
275
+ # XXX: Notice that in this case self is == to controller because code is
276
+ # instance_exec-uted
277
+ dummy_text = "http://www.dummy.com"
278
+ old_options[:"after_#{ crud_action }_url"] = dummy_text
279
+ controller_helpers.stub(:options).and_return(old_options.freeze)
280
+
281
+ controller_helpers.send(:"after_#{ crud_action }_url", dummy).should match dummy_text
282
+ end
283
+
284
+ end
285
+ end
286
+
287
+ context "I18n flash message" do
288
+ before(:each) do
289
+ request.env["HTTP_REFERER"] = controller.dummies_url
290
+ I18n.locale = :en
291
+ end
292
+
293
+ context "with valid data" do
294
+
295
+ it "POST #create calls I18n" do
296
+ dummy_params = FactoryGirl.attributes_for(:dummy)
297
+
298
+ I18n.should_receive(:t)
299
+ .with(any_args())
300
+ .and_call_original
301
+
302
+ post :create, dummy: dummy_params
303
+ end
304
+
305
+ it "PUT/PATCH #update calls I18n" do
306
+ dummy_name = 'dummy2'
307
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
308
+
309
+ I18n.should_receive(:t)
310
+ .with(any_args())
311
+ .and_call_original
312
+
313
+ put :update, id: dummy.id, dummy: { name: dummy_name }
314
+ end
315
+
316
+ it "DELETE #destroy calls I18n" do
317
+ dummy = FactoryGirl.create(:dummy)
318
+
319
+ I18n.should_receive(:t)
320
+ .with(any_args())
321
+ .and_call_original
322
+
323
+ delete :destroy, id: dummy.id
324
+ end
325
+
326
+ it "POST #create set correct flash notice" do
327
+ dummy_params = FactoryGirl.attributes_for(:dummy)
328
+ post :create, dummy: dummy_params
329
+
330
+ flash[:notice].should match 'Dummy was successfully created.'
331
+ end
332
+
333
+ it "PUT/PATCH #update set correct flash notice" do
334
+ dummy_name = 'dummy2'
335
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
336
+ put :update, id: dummy.id, dummy: { name: dummy_name }
337
+
338
+ flash[:notice].should match 'Dummy was successfully updated.'
339
+ end
340
+
341
+ it "DELETE #destroy set correct flash notice" do
342
+ dummy = FactoryGirl.create(:dummy)
343
+ delete :destroy, id: dummy.id
344
+
345
+ flash[:notice].should match 'Dummy was successfully destroyed.'
346
+ end
347
+
348
+ end
349
+
350
+ context "with invalid data" do
351
+
352
+ it "POST #create calls I18n" do
353
+ dummy_params = FactoryGirl.attributes_for(:dummy_invalid)
354
+
355
+ I18n.should_receive(:t)
356
+ .with(any_args())
357
+ .and_call_original
358
+
359
+ post :create, dummy: dummy_params
360
+ end
361
+
362
+ it "PUT/PATCH #update calls I18n" do
363
+ dummy_name = 'dummy2'
364
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
365
+
366
+ I18n.should_receive(:t)
367
+ .with(any_args())
368
+ .and_call_original
369
+
370
+ put :update, id: dummy.id, dummy: { name: dummy_name, will_invalidate: true }
371
+ end
372
+
373
+ it "DELETE #destroy calls I18n" do
374
+ dummy = FactoryGirl.create(:dummy)
375
+ dummy.stub(:destroy).and_return(false)
376
+ controller_helpers.stub(:find_by_id_or_friendly_id).with(any_args()).and_return(dummy)
377
+
378
+ I18n.should_receive(:t)
379
+ .with(any_args())
380
+ .and_call_original
381
+
382
+ delete :destroy, id: dummy.id
383
+ end
384
+
385
+ it "POST #create set correct flash alert" do
386
+ dummy_params = FactoryGirl.attributes_for(:dummy_invalid)
387
+ post :create, dummy: dummy_params
388
+
389
+ flash[:alert].should match 'Dummy cannot be created.'
390
+ end
391
+
392
+ it "PUT/PATCH #update set correct flash alert" do
393
+ dummy_name = 'dummy2'
394
+ dummy = FactoryGirl.create(:dummy, name: 'dummy1')
395
+ put :update, id: dummy.id, dummy: { name: dummy_name, will_invalidate: true }
396
+
397
+ flash[:alert].should match 'Dummy cannot be updated.'
398
+ end
399
+
400
+ it "DELETE #destroy set correct flash alert" do
401
+ dummy = FactoryGirl.create(:dummy)
402
+ dummy.stub(:destroy).and_return(false)
403
+ controller_helpers.stub(:find_by_id_or_friendly_id).with(any_args()).and_return(dummy)
404
+ delete :destroy, id: dummy.id
405
+
406
+ flash[:alert].should match 'Dummy cannot be destroyed.'
407
+ end
408
+
409
+ end
410
+
411
+ end
412
+
413
+
414
+ end
415
+
416
+ end
data/spec/factories.rb ADDED
@@ -0,0 +1,10 @@
1
+ FactoryGirl.define do
2
+
3
+ factory :dummy do
4
+ name { Faker::Name.first_name }
5
+
6
+ factory :dummy_invalid do
7
+ will_invalidate true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ class DummiesController < ActionController::Base
2
+ include ::ProgrammableScaffoldRails::ActionControllerExtensions
3
+
4
+ programmable_scaffold
5
+
6
+ def model_params
7
+ params.require(:dummy).permit(:name, :will_invalidate)
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class Dummy < ActiveRecord::Base
2
+
3
+ validate :dummy_will_invalidate?
4
+
5
+ def dummy_will_invalidate?
6
+ self.errors.add(:will_invalidate, '') if self.will_invalidate?
7
+
8
+ !self.will_invalidate?
9
+ end
10
+
11
+ end