merb-admin 0.4.3

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 (129) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +58 -0
  3. data/Rakefile +64 -0
  4. data/app/controllers/application.rb +6 -0
  5. data/app/controllers/main.rb +145 -0
  6. data/app/helpers/application_helper.rb +64 -0
  7. data/app/helpers/main_helper.rb +122 -0
  8. data/app/views/layout/_message.html.erb +10 -0
  9. data/app/views/layout/dashboard.html.erb +34 -0
  10. data/app/views/layout/form.html.erb +48 -0
  11. data/app/views/layout/list.html.erb +42 -0
  12. data/app/views/main/_belongs_to.html.erb +29 -0
  13. data/app/views/main/_big_decimal.html.erb +12 -0
  14. data/app/views/main/_boolean.html.erb +7 -0
  15. data/app/views/main/_date.html.erb +12 -0
  16. data/app/views/main/_datetime.html.erb +12 -0
  17. data/app/views/main/_float.html.erb +12 -0
  18. data/app/views/main/_has_many.html.erb +16 -0
  19. data/app/views/main/_has_one.html.erb +30 -0
  20. data/app/views/main/_integer.html.erb +18 -0
  21. data/app/views/main/_properties.html.erb +18 -0
  22. data/app/views/main/_string.html.erb +12 -0
  23. data/app/views/main/_text.html.erb +11 -0
  24. data/app/views/main/_time.html.erb +12 -0
  25. data/app/views/main/_timestamp.html.erb +12 -0
  26. data/app/views/main/delete.html.erb +12 -0
  27. data/app/views/main/edit.html.erb +25 -0
  28. data/app/views/main/index.html.erb +22 -0
  29. data/app/views/main/list.html.erb +72 -0
  30. data/app/views/main/new.html.erb +22 -0
  31. data/lib/abstract_model.rb +67 -0
  32. data/lib/activerecord_support.rb +169 -0
  33. data/lib/datamapper_support.rb +157 -0
  34. data/lib/generic_support.rb +17 -0
  35. data/lib/merb-admin/merbtasks.rb +103 -0
  36. data/lib/merb-admin/slicetasks.rb +20 -0
  37. data/lib/merb-admin/spectasks.rb +53 -0
  38. data/lib/merb-admin.rb +99 -0
  39. data/public/images/arrow-down.gif +0 -0
  40. data/public/images/arrow-up.gif +0 -0
  41. data/public/images/changelist-bg.gif +0 -0
  42. data/public/images/changelist-bg_rtl.gif +0 -0
  43. data/public/images/chooser-bg.gif +0 -0
  44. data/public/images/chooser_stacked-bg.gif +0 -0
  45. data/public/images/default-bg-reverse.gif +0 -0
  46. data/public/images/default-bg.gif +0 -0
  47. data/public/images/deleted-overlay.gif +0 -0
  48. data/public/images/icon-no.gif +0 -0
  49. data/public/images/icon-unknown.gif +0 -0
  50. data/public/images/icon-yes.gif +0 -0
  51. data/public/images/icon_addlink.gif +0 -0
  52. data/public/images/icon_alert.gif +0 -0
  53. data/public/images/icon_calendar.gif +0 -0
  54. data/public/images/icon_changelink.gif +0 -0
  55. data/public/images/icon_clock.gif +0 -0
  56. data/public/images/icon_deletelink.gif +0 -0
  57. data/public/images/icon_error.gif +0 -0
  58. data/public/images/icon_searchbox.png +0 -0
  59. data/public/images/icon_success.gif +0 -0
  60. data/public/images/inline-delete-8bit.png +0 -0
  61. data/public/images/inline-delete.png +0 -0
  62. data/public/images/inline-restore-8bit.png +0 -0
  63. data/public/images/inline-restore.png +0 -0
  64. data/public/images/inline-splitter-bg.gif +0 -0
  65. data/public/images/nav-bg-grabber.gif +0 -0
  66. data/public/images/nav-bg-reverse.gif +0 -0
  67. data/public/images/nav-bg.gif +0 -0
  68. data/public/images/selector-add.gif +0 -0
  69. data/public/images/selector-addall.gif +0 -0
  70. data/public/images/selector-remove.gif +0 -0
  71. data/public/images/selector-removeall.gif +0 -0
  72. data/public/images/selector-search.gif +0 -0
  73. data/public/images/selector_stacked-add.gif +0 -0
  74. data/public/images/selector_stacked-remove.gif +0 -0
  75. data/public/images/tool-left.gif +0 -0
  76. data/public/images/tool-left_over.gif +0 -0
  77. data/public/images/tool-right.gif +0 -0
  78. data/public/images/tool-right_over.gif +0 -0
  79. data/public/images/tooltag-add.gif +0 -0
  80. data/public/images/tooltag-add_over.gif +0 -0
  81. data/public/images/tooltag-arrowright.gif +0 -0
  82. data/public/images/tooltag-arrowright_over.gif +0 -0
  83. data/public/javascripts/CollapsedFieldsets.js +85 -0
  84. data/public/javascripts/DateTimeShortcuts.js +255 -0
  85. data/public/javascripts/RelatedObjectLookups.js +96 -0
  86. data/public/javascripts/SelectBox.js +111 -0
  87. data/public/javascripts/SelectFilter2.js +113 -0
  88. data/public/javascripts/actions.js +39 -0
  89. data/public/javascripts/calendar.js +143 -0
  90. data/public/javascripts/core.js +176 -0
  91. data/public/javascripts/dateparse.js +233 -0
  92. data/public/javascripts/getElementsBySelector.js +167 -0
  93. data/public/javascripts/i18n.js +33 -0
  94. data/public/javascripts/master.js +0 -0
  95. data/public/javascripts/ordering.js +137 -0
  96. data/public/javascripts/timeparse.js +94 -0
  97. data/public/javascripts/urlify.js +140 -0
  98. data/public/stylesheets/base.css +746 -0
  99. data/public/stylesheets/changelists.css +269 -0
  100. data/public/stylesheets/dashboard.css +24 -0
  101. data/public/stylesheets/forms.css +327 -0
  102. data/public/stylesheets/global.css +142 -0
  103. data/public/stylesheets/ie.css +51 -0
  104. data/public/stylesheets/layout.css +29 -0
  105. data/public/stylesheets/login.css +54 -0
  106. data/public/stylesheets/master.css +2 -0
  107. data/public/stylesheets/null.css +1 -0
  108. data/public/stylesheets/patch-iewin.css +8 -0
  109. data/public/stylesheets/rtl.css +206 -0
  110. data/public/stylesheets/widgets.css +506 -0
  111. data/schema/migrations/001_create_divisions_migration.rb +15 -0
  112. data/schema/migrations/002_create_drafts_migration.rb +21 -0
  113. data/schema/migrations/003_create_leagues_migration.rb +13 -0
  114. data/schema/migrations/004_create_players_migration.rb +23 -0
  115. data/schema/migrations/005_create_teams_migration.rb +18 -0
  116. data/spec/controllers/main_spec.rb +25 -0
  117. data/spec/models/activerecord/division.rb +8 -0
  118. data/spec/models/activerecord/draft.rb +16 -0
  119. data/spec/models/activerecord/league.rb +6 -0
  120. data/spec/models/activerecord/player.rb +10 -0
  121. data/spec/models/activerecord/team.rb +11 -0
  122. data/spec/models/datamapper/division.rb +12 -0
  123. data/spec/models/datamapper/draft.rb +18 -0
  124. data/spec/models/datamapper/league.rb +11 -0
  125. data/spec/models/datamapper/player.rb +21 -0
  126. data/spec/models/datamapper/team.rb +15 -0
  127. data/spec/requests/main_spec.rb +475 -0
  128. data/spec/spec_helper.rb +112 -0
  129. metadata +209 -0
@@ -0,0 +1,11 @@
1
+ class League
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :name, String, :nullable => false, :index => true
8
+
9
+ has n, :divisions
10
+ has n, :teams
11
+ end
@@ -0,0 +1,21 @@
1
+ class Player
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :deleted_at, ParanoidDateTime
8
+ property :team_id, Integer, :nullable => false, :index => true
9
+ property :name, String, :length => 100, :nullable => false
10
+ property :number, Integer, :nullable => false
11
+ property :position, Enum[:pitcher, :catcher, :first, :second, :third, :shortstop, :left, :center, :right]
12
+ property :sex, Enum[:male, :female]
13
+ property :batting_average, Float, :default => 0.0, :precision => 4, :scale => 3
14
+ property :injured, Boolean, :default => false
15
+ property :born_on, Date
16
+ property :wake_at, Time
17
+ property :notes, Text
18
+
19
+ belongs_to :team
20
+ has 1, :draft
21
+ end
@@ -0,0 +1,15 @@
1
+ class Team
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :created_at, DateTime
6
+ property :updated_at, DateTime
7
+ property :league_id, Integer, :nullable => false, :index => true
8
+ property :division_id, Integer, :nullable => false, :index => true
9
+ property :name, String, :nullable => false, :index => true
10
+ property :colors, Flag[:beige, :black, :blue, :bronze, :brown, :cool, :copper, :cream, :gold, :gray, :green, :khaki, :maroon, :midnight, :navy, :orange, :pink, :purple, :red, :silver, :tan, :turquoise, :violet, :white, :yellow]
11
+
12
+ belongs_to :league
13
+ belongs_to :division
14
+ has n, :players
15
+ end
@@ -0,0 +1,475 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ given "a player exists" do
4
+ @player = MerbAdmin::AbstractModel.new("Player").create(:team_id => rand(99999), :number => rand(99), :name => "Player 1", :sex => :male, :position => :pitcher)
5
+ end
6
+
7
+ given "a draft exists" do
8
+ @draft = MerbAdmin::AbstractModel.new("Draft").create(:player_id => rand(99999), :team_id => rand(99999), :date => Date.today, :round => rand(50), :pick => rand(30), :overall => rand(1500))
9
+ end
10
+
11
+ given "two players exist" do
12
+ @players = []
13
+ 2.times do |i|
14
+ @players << MerbAdmin::AbstractModel.new("Player").create(:team_id => rand(99999), :number => rand(99), :name => "Player #{i}", :sex => :male, :position => :pitcher)
15
+ end
16
+ end
17
+
18
+ given "three teams exist" do
19
+ @teams = []
20
+ 3.times do |i|
21
+ @teams << MerbAdmin::AbstractModel.new("Team").create(:league_id => rand(99999), :division_id => rand(99999), :name => "Team #{i}")
22
+ end
23
+ end
24
+
25
+ given "a player exists and a draft exists" do
26
+ @player = MerbAdmin::AbstractModel.new("Player").create(:team_id => rand(99999), :number => rand(99), :name => "Player 1", :sex => :male, :position => :pitcher)
27
+ @draft = MerbAdmin::AbstractModel.new("Draft").create(:player_id => rand(99999), :team_id => rand(99999), :date => Date.today, :round => rand(50), :pick => rand(30), :overall => rand(1500))
28
+ end
29
+
30
+ given "a player exists and three teams exist" do
31
+ @player = MerbAdmin::AbstractModel.new("Player").create(:team_id => rand(99999), :number => rand(99), :name => "Player 1", :sex => :male, :position => :pitcher)
32
+ @teams = []
33
+ 3.times do |i|
34
+ @teams << MerbAdmin::AbstractModel.new("Team").create(:league_id => rand(99999), :division_id => rand(99999), :name => "Team #{i}")
35
+ end
36
+ end
37
+
38
+ given "a league exists and three teams exist" do
39
+ @league = League.create(:name => "League 1")
40
+ @teams = []
41
+ 3.times do |i|
42
+ @teams << MerbAdmin::AbstractModel.new("Team").create(:league_id => rand(99999), :division_id => rand(99999), :name => "Team #{i}")
43
+ end
44
+ end
45
+
46
+ given "twenty players exist" do
47
+ @players = []
48
+ 20.times do |i|
49
+ @players << MerbAdmin::AbstractModel.new("Player").create(:team_id => rand(99999), :number => rand(99), :name => "Player #{i}", :sex => :male, :position => :pitcher)
50
+ end
51
+ end
52
+
53
+ describe "MerbAdmin" do
54
+
55
+ before(:each) do
56
+ mount_slice
57
+ MerbAdmin::AbstractModel.new("Division").destroy_all!
58
+ MerbAdmin::AbstractModel.new("Draft").destroy_all!
59
+ MerbAdmin::AbstractModel.new("League").destroy_all!
60
+ MerbAdmin::AbstractModel.new("Player").destroy_all!
61
+ MerbAdmin::AbstractModel.new("Team").destroy_all!
62
+ end
63
+
64
+ describe "dashboard" do
65
+ before(:each) do
66
+ @response = request(url(:admin_dashboard))
67
+ end
68
+
69
+ it "should respond sucessfully" do
70
+ @response.should be_successful
71
+ end
72
+
73
+ it "should contain \"Site administration\"" do
74
+ @response.body.should contain("Site administration")
75
+ end
76
+ end
77
+
78
+ describe "list" do
79
+ before(:each) do
80
+ @response = request(url(:admin_list, :model_name => "player"))
81
+ end
82
+
83
+ it "should respond sucessfully" do
84
+ @response.should be_successful
85
+ end
86
+
87
+ it "should contain \"Select model to edit\"" do
88
+ @response.body.should contain("Select player to edit")
89
+ end
90
+ end
91
+
92
+ describe "list with 2 objects", :given => "two players exist" do
93
+ before(:each) do
94
+ MerbAdmin[:paginate] = true
95
+ MerbAdmin[:per_page] = 1
96
+ @response = request(url(:admin_list, :model_name => "player"))
97
+ end
98
+
99
+ it "should respond sucessfully" do
100
+ @response.should be_successful
101
+ end
102
+
103
+ it "should contain \"2 results\"" do
104
+ @response.body.should contain("2 players")
105
+ end
106
+ end
107
+
108
+ describe "list with 20 objects", :given => "twenty players exist" do
109
+ before(:each) do
110
+ MerbAdmin[:paginate] = true
111
+ MerbAdmin[:per_page] = 1
112
+ @response = request(url(:admin_list, :model_name => "player"))
113
+ end
114
+
115
+ it "should respond sucessfully" do
116
+ @response.should be_successful
117
+ end
118
+
119
+ it "should contain \"20 results\"" do
120
+ @response.body.should contain("20 players")
121
+ end
122
+ end
123
+
124
+ describe "list with 20 objects, page 8", :given => "twenty players exist" do
125
+ before(:each) do
126
+ MerbAdmin[:paginate] = true
127
+ MerbAdmin[:per_page] = 1
128
+ @response = request(url(:admin_list, :model_name => "player"), :params => {:page => 8})
129
+ end
130
+
131
+ it "should respond sucessfully" do
132
+ @response.should be_successful
133
+ end
134
+
135
+ it "should paginate correctly" do
136
+ @response.body.should contain(/1 2[^0-9]*5 6 7 8 9 10 11[^0-9]*19 20/)
137
+ end
138
+ end
139
+
140
+ describe "list with 20 objects, page 17", :given => "twenty players exist" do
141
+ before(:each) do
142
+ MerbAdmin[:paginate] = true
143
+ MerbAdmin[:per_page] = 1
144
+ @response = request(url(:admin_list, :model_name => "player"), :params => {:page => 17})
145
+ end
146
+
147
+ it "should respond sucessfully" do
148
+ @response.should be_successful
149
+ end
150
+
151
+ it "should paginate correctly" do
152
+ @response.body.should contain(/1 2[^0-9]*12 13 14 15 16 17 18 19 20/)
153
+ end
154
+ end
155
+
156
+ describe "list show all", :given => "two players exist" do
157
+ before(:each) do
158
+ MerbAdmin[:paginate] = true
159
+ MerbAdmin[:per_page] = 1
160
+ @response = request(url(:admin_list, :model_name => "player"), :params => {:all => true})
161
+ end
162
+
163
+ it "should respond sucessfully" do
164
+ @response.should be_successful
165
+ end
166
+ end
167
+
168
+ describe "new" do
169
+ before(:each) do
170
+ @response = request(url(:admin_new, :model_name => "player"))
171
+ end
172
+
173
+ it "should respond sucessfully" do
174
+ @response.should be_successful
175
+ end
176
+
177
+ it "should contain \"New model\"" do
178
+ @response.body.should contain("New player")
179
+ end
180
+ end
181
+
182
+ describe "new with has-one association", :given => "a draft exists" do
183
+ before(:each) do
184
+ @response = request(url(:admin_new, :model_name => "player"))
185
+ end
186
+
187
+ it "should respond sucessfully" do
188
+ @response.should be_successful
189
+ end
190
+ end
191
+
192
+ describe "new with has-many association", :given => "three teams exist" do
193
+ before(:each) do
194
+ @response = request(url(:admin_new, :model_name => "player"))
195
+ end
196
+
197
+ it "should respond sucessfully" do
198
+ @response.should be_successful
199
+ end
200
+ end
201
+
202
+ describe "edit", :given => "a player exists" do
203
+ before(:each) do
204
+ @response = request(url(:admin_edit, :model_name => "player", :id => @player.id))
205
+ end
206
+
207
+ it "should respond sucessfully" do
208
+ @response.should be_successful
209
+ end
210
+
211
+ it "should contain \"Edit model\"" do
212
+ @response.body.should contain("Edit player")
213
+ end
214
+ end
215
+
216
+ describe "edit with has-one association", :given => "a player exists and a draft exists" do
217
+ before(:each) do
218
+ @response = request(url(:admin_edit, :model_name => "player", :id => @player.id))
219
+ end
220
+
221
+ it "should respond sucessfully" do
222
+ @response.should be_successful
223
+ end
224
+ end
225
+
226
+ describe "edit with has-many association", :given => "a player exists and three teams exist" do
227
+ before(:each) do
228
+ @response = request(url(:admin_edit, :model_name => "player", :id => @player.id))
229
+ end
230
+
231
+ it "should respond sucessfully" do
232
+ @response.should be_successful
233
+ end
234
+ end
235
+
236
+
237
+ describe "edit with missing object" do
238
+ before(:each) do
239
+ @response = request(url(:admin_edit, :model_name => "player", :id => 1))
240
+ end
241
+
242
+ it "should raise NotFound" do
243
+ @response.status.should == 404
244
+ end
245
+ end
246
+
247
+ describe "create" do
248
+ before(:each) do
249
+ @response = request(url(:admin_create, :model_name => "player"), :method => "post", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :position => :second, :sex => :male}})
250
+ end
251
+
252
+ it "should redirect to list" do
253
+ @response.should redirect_to(url(:admin_list, :model_name => "player"))
254
+ end
255
+
256
+ it "should create a new object" do
257
+ MerbAdmin::AbstractModel.new("Player").first.should_not be_nil
258
+ end
259
+ end
260
+
261
+ describe "create and edit" do
262
+ before(:each) do
263
+ @response = request(url(:admin_create, :model_name => "player"), :method => "post", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :position => :second, :sex => :male}, :_continue => true})
264
+ end
265
+
266
+ it "should redirect to edit" do
267
+ @response.should redirect_to(url(:admin_edit, :model_name => "player", :id => MerbAdmin::AbstractModel.new("Player").first.id))
268
+ end
269
+
270
+ it "should create a new object" do
271
+ MerbAdmin::AbstractModel.new("Player").first.should_not be_nil
272
+ end
273
+ end
274
+
275
+ describe "create and add another" do
276
+ before(:each) do
277
+ @response = request(url(:admin_create, :model_name => "player"), :method => "post", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :position => :second, :sex => :male}, :_add_another => true})
278
+ end
279
+
280
+ it "should redirect to new" do
281
+ @response.should redirect_to(url(:admin_new, :model_name => "player"))
282
+ end
283
+
284
+ it "should create a new object" do
285
+ MerbAdmin::AbstractModel.new("Player").first.should_not be_nil
286
+ end
287
+ end
288
+
289
+ describe "create with has-one association", :given => "a draft exists" do
290
+ before(:each) do
291
+ @response = request(url(:admin_create, :model_name => "player"), :method => "post", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :position => :second, :sex => :male}, :associations => {:draft => @draft.id}})
292
+ end
293
+
294
+ it "should create a new object" do
295
+ MerbAdmin::AbstractModel.new("Player").first.should_not be_nil
296
+ end
297
+
298
+ it "should be associated with the correct object" do
299
+ MerbAdmin::AbstractModel.new("Player").first.draft.should == @draft
300
+ end
301
+ end
302
+
303
+ describe "create with has-many association", :given => "three teams exist" do
304
+ before(:each) do
305
+ @response = request(url(:admin_create, :model_name => "league"), :method => "post", :params => {:league => {:name => "National League"}, :associations => {:teams => [@teams[0].id, @teams[1].id]}})
306
+ end
307
+
308
+ it "should create a new object" do
309
+ MerbAdmin::AbstractModel.new("League").first.should_not be_nil
310
+ end
311
+
312
+ it "should be associated with the correct objects" do
313
+ MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[0])
314
+ MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[1])
315
+ end
316
+
317
+ it "should be not associated with an incorrect object" do
318
+ MerbAdmin::AbstractModel.new("League").first.teams.should_not include(@teams[2])
319
+ end
320
+ end
321
+
322
+ describe "create with invalid object" do
323
+ before(:each) do
324
+ @response = request(url(:admin_create, :model_name => "player"), :method => "post", :params => {:player => {}})
325
+ end
326
+
327
+ it "should contain an error message" do
328
+ @response.body.should contain("Player failed to be created")
329
+ end
330
+ end
331
+
332
+ describe "update", :given => "a player exists" do
333
+ before(:each) do
334
+ @response = request(url(:admin_update, :model_name => "player", :id => @player.id), :method => "put", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :sex => :male}})
335
+ end
336
+
337
+ it "should redirect to list" do
338
+ @response.should redirect_to(url(:admin_list, :model_name => "player"))
339
+ end
340
+
341
+ it "should update an object that already exists" do
342
+ MerbAdmin::AbstractModel.new("Player").first.name.should eql("Jackie Robinson")
343
+ end
344
+ end
345
+
346
+ describe "update and edit", :given => "a player exists" do
347
+ before(:each) do
348
+ @response = request(url(:admin_update, :model_name => "player", :id => @player.id), :method => "put", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :sex => :male}, :_continue => true})
349
+ end
350
+
351
+ it "should redirect to edit" do
352
+ @response.should redirect_to(url(:admin_edit, :model_name => "player", :id => @player.id))
353
+ end
354
+
355
+ it "should update an object that already exists" do
356
+ MerbAdmin::AbstractModel.new("Player").first.name.should eql("Jackie Robinson")
357
+ end
358
+ end
359
+
360
+ describe "update and add another", :given => "a player exists" do
361
+ before(:each) do
362
+ @response = request(url(:admin_update, :model_name => "player", :id => @player.id), :method => "put", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :sex => :male}, :_add_another => true})
363
+ end
364
+
365
+ it "should redirect to new" do
366
+ @response.should redirect_to(url(:admin_new, :model_name => "player"))
367
+ end
368
+
369
+ it "should update an object that already exists" do
370
+ MerbAdmin::AbstractModel.new("Player").first.name.should eql("Jackie Robinson")
371
+ end
372
+ end
373
+
374
+ describe "update with has-one association", :given => "a player exists and a draft exists" do
375
+ before(:each) do
376
+ @response = request(url(:admin_update, :model_name => "player", :id => @player.id), :method => "put", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :position => :second, :sex => :male}, :associations => {:draft => @draft.id}})
377
+ end
378
+
379
+ it "should update an object that already exists" do
380
+ MerbAdmin::AbstractModel.new("Player").first.name.should eql("Jackie Robinson")
381
+ end
382
+
383
+ it "should be associated with the correct object" do
384
+ MerbAdmin::AbstractModel.new("Player").first.draft.should == @draft
385
+ end
386
+ end
387
+
388
+ describe "update with has-many association", :given => "a league exists and three teams exist" do
389
+ before(:each) do
390
+ @response = request(url(:admin_update, :model_name => "league", :id => @league.id), :method => "put", :params => {:league => {:name => "National League"}, :associations => {:teams => [@teams[0].id, @teams[1].id]}})
391
+ end
392
+
393
+ it "should update an object that already exists" do
394
+ MerbAdmin::AbstractModel.new("League").first.name.should eql("National League")
395
+ end
396
+
397
+ it "should be associated with the correct objects" do
398
+ MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[0])
399
+ MerbAdmin::AbstractModel.new("League").first.teams.should include(@teams[1])
400
+ end
401
+
402
+ it "should not be associated with an incorrect object" do
403
+ MerbAdmin::AbstractModel.new("League").first.teams.should_not include(@teams[2])
404
+ end
405
+ end
406
+
407
+ describe "update with missing object" do
408
+ before(:each) do
409
+ @response = request(url(:admin_update, :model_name => "player", :id => 1), :method => "put", :params => {:player => {:name => "Jackie Robinson", :number => 42, :team_id => 1, :sex => :male}})
410
+ end
411
+
412
+ it "should raise NotFound" do
413
+ @response.status.should == 404
414
+ end
415
+ end
416
+
417
+ describe "update with invalid object", :given => "a player exists" do
418
+ before(:each) do
419
+ @response = request(url(:admin_update, :model_name => "player", :id => @player.id), :method => "put", :params => {:player => {:number => "a"}})
420
+ end
421
+
422
+ it "should contain an error message" do
423
+ @response.body.should contain("Player failed to be updated")
424
+ end
425
+ end
426
+
427
+ describe "delete", :given => "a player exists" do
428
+ before(:each) do
429
+ @response = request(url(:admin_delete, :model_name => "player", :id => @player.id))
430
+ end
431
+
432
+ it "should respond sucessfully" do
433
+ @response.should be_successful
434
+ end
435
+
436
+ it "should contain \"Delete model\"" do
437
+ @response.body.should contain("Delete player")
438
+ end
439
+ end
440
+
441
+ describe "delete with missing object" do
442
+ before(:each) do
443
+ @response = request(url(:admin_delete, :model_name => "player", :id => 1))
444
+ end
445
+
446
+ it "should raise NotFound" do
447
+ @response.status.should == 404
448
+ end
449
+ end
450
+
451
+ describe "destroy", :given => "a player exists" do
452
+ before(:each) do
453
+ @response = request(url(:admin_destroy, :model_name => "player", :id => @player.id), :method => "delete")
454
+ end
455
+
456
+ it "should redirect to list" do
457
+ @response.should redirect_to(url(:admin_list, :model_name => "player"))
458
+ end
459
+
460
+ it "should destroy an object" do
461
+ MerbAdmin::AbstractModel.new("Player").first.should be_nil
462
+ end
463
+ end
464
+
465
+ describe "destroy with missing object" do
466
+ before(:each) do
467
+ @response = request(url(:admin_destroy, :model_name => "player", :id => 1), :method => "delete")
468
+ end
469
+
470
+ it "should raise NotFound" do
471
+ @response.status.should == 404
472
+ end
473
+ end
474
+
475
+ end
@@ -0,0 +1,112 @@
1
+ require 'rubygems'
2
+ require 'merb-core'
3
+ require 'merb-slices'
4
+ require 'merb-helpers'
5
+ require 'merb-assets'
6
+ require 'spec'
7
+
8
+ # Add merb-admin.rb to the search path
9
+ Merb::Plugins.config[:merb_slices][:auto_register] = true
10
+ Merb::Plugins.config[:merb_slices][:search_path] = File.join(File.dirname(__FILE__), '..', 'lib', 'merb-admin.rb')
11
+
12
+ # Require merb-admin.rb explicitly so any dependencies are loaded
13
+ require Merb::Plugins.config[:merb_slices][:search_path]
14
+
15
+ # Using Merb.root below makes sure that the correct root is set for
16
+ # - testing standalone, without being installed as a gem and no host application
17
+ # - testing from within the host application; its root will be used
18
+ Merb.start_environment(
19
+ :testing => true,
20
+ :adapter => 'runner',
21
+ :environment => ENV['MERB_ENV'] || 'test',
22
+ :merb_root => Merb.root,
23
+ :session_store => 'memory'
24
+ )
25
+
26
+ module Merb
27
+ module Test
28
+ module SliceHelper
29
+
30
+ # The absolute path to the current slice
31
+ def current_slice_root
32
+ @current_slice_root ||= File.expand_path(File.join(File.dirname(__FILE__), '..'))
33
+ end
34
+
35
+ # Whether the specs are being run from a host application or standalone
36
+ def standalone?
37
+ Merb.root == ::MerbAdmin.root
38
+ end
39
+
40
+ def setup_orm(orm = nil)
41
+ orm = set_orm(orm)
42
+ orm = orm.to_s.downcase.to_sym
43
+ case orm
44
+ when :activerecord
45
+ require 'activerecord'
46
+ require_models(orm)
47
+
48
+ unless ActiveRecord::Base.connected?
49
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
50
+ ActiveRecord::Migration.verbose = false
51
+ ActiveRecord::Migrator.run(:up, "schema/migrations/", 1)
52
+ ActiveRecord::Migrator.run(:up, "schema/migrations/", 2)
53
+ ActiveRecord::Migrator.run(:up, "schema/migrations/", 3)
54
+ ActiveRecord::Migrator.run(:up, "schema/migrations/", 4)
55
+ ActiveRecord::Migrator.run(:up, "schema/migrations/", 5)
56
+ end
57
+ when :datamapper
58
+ require 'dm-core'
59
+ require 'dm-types'
60
+ require 'dm-aggregates'
61
+ require 'dm-validations'
62
+ require_models(orm)
63
+
64
+ unless DataMapper::Repository.adapters.key?(:default)
65
+ DataMapper.setup(:default, 'sqlite3::memory:')
66
+ DataMapper.auto_migrate!
67
+ end
68
+ when :sequel
69
+ require 'sequel'
70
+ else
71
+ raise "MerbAdmin does not support the #{orm} ORM"
72
+ end
73
+ Merb.orm = orm
74
+ end
75
+
76
+ private
77
+
78
+ def require_models(orm = nil)
79
+ orm ||= set_orm
80
+ Dir.glob(File.dirname(__FILE__) / "models" / orm.to_s.downcase / Merb.glob_for(:model)).each do |model_filename|
81
+ require model_filename
82
+ end
83
+ end
84
+
85
+ def set_orm(orm = nil)
86
+ orm || ENV['MERB_ORM'] || (Merb.orm != :none ? Merb.orm : nil) || :datamapper
87
+ end
88
+
89
+ end
90
+ end
91
+ end
92
+
93
+ Spec::Runner.configure do |config|
94
+ config.include(Merb::Test::ViewHelper)
95
+ config.include(Merb::Test::RouteHelper)
96
+ config.include(Merb::Test::ControllerHelper)
97
+ config.include(Merb::Test::SliceHelper)
98
+ config.before(:each) do
99
+ setup_orm
100
+ end
101
+ end
102
+
103
+ # You can add your own helpers here
104
+ #
105
+ Merb::Test.add_helpers do
106
+ def mount_slice
107
+ if standalone?
108
+ Merb::Router.reset!
109
+ Merb::Router.prepare{add_slice(:merb_admin, :name_prefix => nil, :path_prefix => "admin", :default_routes => false)}
110
+ end
111
+ end
112
+ end