radiant-banner_rotator-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/.gitmodules +3 -0
  2. data/HELP.textile +87 -0
  3. data/README.textile +68 -0
  4. data/Rakefile +136 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/admin/banners_controller.rb +61 -0
  7. data/app/helpers/admin/banners_helper.rb +62 -0
  8. data/app/models/banner.rb +101 -0
  9. data/app/models/banner_placement.rb +7 -0
  10. data/app/views/admin/banners/_form.html.haml +76 -0
  11. data/app/views/admin/banners/_modify_banner.html.haml +8 -0
  12. data/app/views/admin/banners/deactivate.html.haml +10 -0
  13. data/app/views/admin/banners/edit.html.haml +8 -0
  14. data/app/views/admin/banners/index.html.haml +118 -0
  15. data/app/views/admin/banners/new.html.haml +5 -0
  16. data/app/views/admin/banners/remove.html.haml +12 -0
  17. data/app/views/admin/pages/_banner_info.html.haml +28 -0
  18. data/app/views/admin/pages/_banners_column.html.haml +11 -0
  19. data/app/views/admin/pages/_banners_column_header.html.haml +9 -0
  20. data/banner_rotator_extension.rb +41 -0
  21. data/config/initializers/radiant_config.rb +3 -0
  22. data/config/locales/en.yml +34 -0
  23. data/config/routes.rb +5 -0
  24. data/db/migrate/001_create_banners.rb +31 -0
  25. data/db/migrate/002_change_banners_default.rb +9 -0
  26. data/db/migrate/003_add_description.rb +9 -0
  27. data/lib/banner_rotator/page_extensions.rb +47 -0
  28. data/lib/banner_rotator/tags.rb +67 -0
  29. data/lib/tasks/banner_rotator_extension_tasks.rake +29 -0
  30. data/public/images/admin/deactivate.png +0 -0
  31. data/public/images/admin/pictures.png +0 -0
  32. data/public/images/admin/text_list_numbers.png +0 -0
  33. data/public/javascripts/lowpro.js +320 -0
  34. data/spec/controllers/admin_banners_controller_spec.rb +231 -0
  35. data/spec/datasets/banners_dataset.rb +26 -0
  36. data/spec/helpers/admin/banners_helper_spec.rb +9 -0
  37. data/spec/models/banner_placement_spec.rb +44 -0
  38. data/spec/models/banner_spec.rb +47 -0
  39. data/spec/models/page_extensions_spec.rb +25 -0
  40. data/spec/models/tags_spec.rb +69 -0
  41. data/spec/spec.opts +6 -0
  42. data/spec/spec_helper.rb +36 -0
  43. metadata +124 -0
@@ -0,0 +1,231 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require_dependency 'admin/banners_controller'
3
+ class Admin::BannersController < Admin::ResourceController; def rescue_action(e); raise e; end end
4
+
5
+ describe Admin::BannersController do
6
+ # Uses Admin::ResourceController, built into Radiant
7
+ dataset :users, :banners
8
+
9
+ before :each do
10
+ @banner = banners(:first)
11
+ @count = Banner.count
12
+ login_as(:admin)
13
+ end
14
+
15
+ it "should require login" do
16
+ logout
17
+ lambda { get :index }.should require_login
18
+ lambda { get :show, :id => 1 }.should require_login
19
+ lambda { get :new }.should require_login
20
+ lambda { post :create}.should require_login
21
+ lambda { get :edit, :id => 1 }.should require_login
22
+ lambda { put :update, :id => 1 }.should require_login
23
+ lambda { get :remove, :id => 1 }.should require_login
24
+ lambda { delete :destroy, :id => 1 }.should require_login
25
+ lambda { post :deactivate, :id => 1 }.should require_login
26
+ end
27
+
28
+ it "'create' should add 1 banner and redirect to index" do
29
+ post :create, :banner => min_valid_banner_params
30
+ Banner.count.should == @count + 1
31
+ response.should be_redirect
32
+ response.should redirect_to(admin_banners_path)
33
+ end
34
+
35
+ it "'update' should redirect to index" do
36
+ put :update, :id => @banner.id
37
+ Banner.count.should == @count
38
+ response.should be_redirect
39
+ response.should redirect_to(admin_banners_path)
40
+ end
41
+
42
+ it "'deactivate' should remove all banner placements and redirect to index" do
43
+ @banner.active?.should be_true
44
+ post :deactivate, :id => @banner.id
45
+ @banner.inactive?.should be_true
46
+ Banner.count.should == @count
47
+ response.should be_redirect
48
+ response.should redirect_to(admin_banners_path)
49
+ # flash notices are largely deprecated in as of 0.9
50
+ # flash[:notice].should include("Banner \"#{@banner.name}\" has been deactivated.")
51
+ end
52
+
53
+ it "'delete' should remove 1 banner and redirect to index" do
54
+ delete :destroy, :id => @banner.id
55
+ Banner.count.should == @count - 1
56
+ response.should be_redirect
57
+ response.should redirect_to(admin_banners_path)
58
+ # flash notices are largely deprecated in as of 0.9
59
+ # flash[:notice].should include("Banner has been deleted.")
60
+ end
61
+
62
+ describe "protected banners" do
63
+
64
+ def protected_banner_behavior_on_deactivate
65
+ response.should be_redirect
66
+ response.should redirect_to(admin_banners_path)
67
+ flash[:error].should == @banner.cannot_be_deactivated_msg
68
+ @banner.active?.should be_true
69
+ @banner.protected?.should be_true
70
+ end
71
+
72
+ def protected_banner_behavior_on_remove
73
+ response.should be_redirect
74
+ response.should redirect_to(admin_banners_path)
75
+ flash[:error].should == @banner.cannot_be_removed_msg
76
+ Banner.count.should == @count
77
+ end
78
+
79
+ def protected_from_removal_tests
80
+ get :remove, :id => @banner.id
81
+ protected_banner_behavior_on_remove
82
+ delete :destroy, :id => @banner.id
83
+ protected_banner_behavior_on_remove
84
+ end
85
+
86
+ def protected_from_deactivation_tests
87
+ get :deactivate, :id => @banner.id
88
+ protected_banner_behavior_on_deactivate
89
+ post :deactivate, :id => @banner.id
90
+ protected_banner_behavior_on_deactivate
91
+ end
92
+
93
+ it "should protect banners with 'protected' in the banner name from removal" do
94
+ @banner = banners(:protected)
95
+ protected_from_removal_tests
96
+ end
97
+
98
+ it "should protect banners with 'protected' in the banner name from deactivation" do
99
+ @banner = banners(:protected)
100
+ protected_from_deactivation_tests
101
+ end
102
+
103
+ it "should protect banners named in Radiant::Config['admin.protected_banners'] from removal" do
104
+ @banner = banners(:child_2_1)
105
+ Radiant::Config['admin.protected_banners'] = @banner.name
106
+ protected_from_removal_tests
107
+ end
108
+
109
+ it "should protect banners named in Radiant::Config['admin.protected_banners'] from deactivation" do
110
+ @banner = banners(:child_2_1)
111
+ Radiant::Config['admin.protected_banners'] = @banner.name
112
+ protected_from_deactivation_tests
113
+ end
114
+
115
+ end
116
+
117
+ [:admin, :designer].each do |user|
118
+ describe "#{user} user" do
119
+ before :each do
120
+ @banner = Banner.find(:first)
121
+ login_as user
122
+ end
123
+
124
+ def redirects_to_index
125
+ response.should be_redirect
126
+ response.should redirect_to(admin_banners_url)
127
+ end
128
+
129
+ it 'should have access to the index action' do
130
+ get :index
131
+ response.should be_success
132
+ end
133
+
134
+ it 'should have access to the show action' do
135
+ get :show, :id => @banner.id
136
+ response.should be_redirect
137
+ response.should redirect_to(edit_admin_banner_url(@banner))
138
+ end
139
+
140
+ it 'should have access to the new action' do
141
+ get :new
142
+ response.should be_success
143
+ end
144
+
145
+ it 'should have access to the create action' do
146
+ post :create, :banner => min_valid_banner_params
147
+ redirects_to_index
148
+ end
149
+
150
+ it 'should have access to the edit action' do
151
+ get :edit, :id => 1
152
+ response.should be_success
153
+ end
154
+
155
+ it 'should have access to the update action' do
156
+ put :update, :id => 1
157
+ redirects_to_index
158
+ end
159
+
160
+ it "should have access to the remove action" do
161
+ get :remove, :id => 1
162
+ response.should be_success
163
+ end
164
+
165
+ it 'should have access to the destroy action' do
166
+ delete :destroy, :id => 1
167
+ redirects_to_index
168
+ end
169
+
170
+ it 'should have access to the deactivate action' do
171
+ post :deactivate, :id => 1
172
+ redirects_to_index
173
+ end
174
+ end
175
+ end
176
+
177
+ [:existing, :non_admin].each do |user|
178
+ describe "#{user} user" do
179
+ before :each do
180
+ login_as user
181
+ end
182
+
183
+ def redirects_to_pages
184
+ response.should be_redirect
185
+ response.should redirect_to(admin_pages_path)
186
+ flash[:error].should == 'You must have designer privileges to perform this action.'
187
+ end
188
+
189
+ it 'should not have access to the index action' do
190
+ get :index
191
+ end
192
+
193
+ it 'should not have access to the show action' do
194
+ get :show, :id => 1
195
+ end
196
+
197
+ it 'should not have access to the new action' do
198
+ get :new
199
+ end
200
+
201
+ it 'should not have access to the create action' do
202
+ post :create
203
+ end
204
+
205
+ it 'should not have access to the edit action' do
206
+ get :edit, :id => 1
207
+ end
208
+
209
+ it 'should not have access to the update action' do
210
+ put :update, :id => 1
211
+ end
212
+
213
+ it 'should not have access to the remove action' do
214
+ put :remove, :id => 1
215
+ end
216
+
217
+ it 'should not have access to the destroy action' do
218
+ delete :destroy, :id => 1
219
+ end
220
+
221
+ it 'should not have access to the deactivate action' do
222
+ post :deactivate, :id => 1
223
+ end
224
+
225
+ after :each do
226
+ redirects_to_pages
227
+ end
228
+ end
229
+ end
230
+
231
+ end
@@ -0,0 +1,26 @@
1
+ class BannersDataset < Dataset::Base
2
+ uses :pages
3
+
4
+ def load
5
+ create_model Banner, :first, :id => 1, :name => "First", :background_image => "test.jpg", :foreground_image => 'front.jpg', :link_target => "_blank", :link_url => "/en/", :image_style => "text-align:right"
6
+ create_model Banner, :protected, :id => 2, :name => "First_protected", :background_image => "test.jpg", :foreground_image => 'front.jpg', :link_target => "_blank", :link_url => "/en/protected/", :image_style => "text-align:right"
7
+ create_model BannerPlacement, :first, :page_id => page_id(:home), :banner_id => banner_id(:first), :weight => 5
8
+ create_model BannerPlacement, :protected, :page_id => page_id(:home), :banner_id => banner_id(:protected), :weight => 5
9
+ Page.update_all({:show_banner => ! Page.columns_hash['show_banner'].default }, {:id => page_id(:radius)})
10
+ create_model Banner, :child_2_1, :name => "Child-2 first", :background_image => "test.jpg"
11
+ create_model BannerPlacement, :child_2_1, :page_id => page_id(:child_2), :banner_id => banner_id(:child_2_1), :weight => 1
12
+ create_model Banner, :child_2_2, :name => "Child-2 second", :background_image => "test.jpg"
13
+ create_model BannerPlacement, :child_2_2, :page_id => page_id(:child_2), :banner_id => banner_id(:child_2_2), :weight => 1
14
+ create_model Banner, :blank, min_valid_banner_params
15
+ create_model BannerPlacement, :blank, :page_id => page_id(:another), :banner_id => banner_id(:blank), :weight => 1
16
+ end
17
+
18
+ helpers do
19
+ def min_valid_banner_params
20
+ { :name => 'New Banner',
21
+ :background_image => 'pic.png'
22
+ }
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Admin::BannersHelper do
4
+ dataset :home_page
5
+
6
+ it "should create options for the placements select box from existing pages" do
7
+ helper.pages_for_select.should == [["Home", page_id(:home)]]
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe BannerPlacement do
4
+
5
+ dataset :banners
6
+
7
+ before(:each) do
8
+ @placement = banner_placements(:first)
9
+ end
10
+
11
+ it "should require a page" do
12
+ @placement.page_id = nil
13
+ @placement.should_not be_valid
14
+ @placement.should have(1).error_on(:page_id)
15
+ end
16
+
17
+ it "should require a banner" do
18
+ @placement.banner_id = nil
19
+ @placement.should_not be_valid
20
+ @placement.should have(1).error_on(:banner_id)
21
+ end
22
+
23
+ it "should require a weight" do
24
+ @placement.weight = nil
25
+ @placement.should_not be_valid
26
+ @placement.should have(1).error_on(:weight)
27
+ end
28
+
29
+ it "should require weight to be a number" do
30
+ @placement.weight = 'foo'
31
+ @placement.should_not be_valid
32
+ @placement.should have(1).error_on(:weight)
33
+ end
34
+
35
+ it "should be unique to a given page and banner" do
36
+ @placement.page_id = page_id(:home)
37
+ @placement.banner_id = banner_id(:protected)
38
+ @placement.should_not be_valid
39
+ end
40
+
41
+ it "should be valid with required parameters" do
42
+ @placement.should be_valid
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Banner do
4
+
5
+ dataset :banners
6
+
7
+ before(:each) do
8
+ @banner = banners(:first)
9
+ end
10
+
11
+ it "should require a name" do
12
+ @banner.name = nil
13
+ @banner.should_not be_valid
14
+ @banner.should have(1).error_on(:name)
15
+ end
16
+
17
+ it "should require a background image" do
18
+ @banner.background_image = nil
19
+ @banner.should_not be_valid
20
+ @banner.should have(1).error_on(:background_image)
21
+ end
22
+
23
+ it "should be valid with required parameters" do
24
+ @banner.should be_valid
25
+ end
26
+
27
+ describe "with page placements" do
28
+ before(:each) do
29
+ @banner.placements = [{'page_id' => '1', 'weight' => '10'}, {'page_id' => '2', 'weight' => '5'}]
30
+ @banner.save.should be_true
31
+ end
32
+ it "should save associated page placements" do
33
+ @banner.active?.should be_true
34
+ @banner.inactive?.should be_false
35
+ @banner.should have(2).banner_placements
36
+ @banner.placements.should be_all{|p| p.valid? }
37
+ end
38
+ it "should remove all page placements" do
39
+ @banner.remove_all_placements!
40
+ @banner.save.should be_true
41
+ @banner.active?.should be_false
42
+ @banner.inactive?.should be_true
43
+ @banner.should have(0).banner_placements
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "BannerRotator::PageExtensions" do
4
+ dataset :pages, :banners
5
+
6
+ it "should have some banner and banner placements" do
7
+ pages(:home).should respond_to(:banners)
8
+ pages(:home).should respond_to(:banner_placements)
9
+ pages(:home).should have(2).banners
10
+ end
11
+
12
+ it "should select a banner" do
13
+ [ banners(:first), banners(:protected) ].should include(pages(:home).select_banner)
14
+ end
15
+
16
+ it "should inherit banners from its ancestors" do
17
+ pages(:article).banner_placements.should == pages(:home).banner_placements
18
+ [ banners(:first), banners(:protected) ].should include(pages(:article).select_banner)
19
+ end
20
+
21
+ it "should not delete its parent's banner placements when destroyed" do
22
+ pages(:home).should == pages(:radius).parent
23
+ lambda { pages(:radius).destroy }.should_not change(BannerPlacement, :count)
24
+ end
25
+ end
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "BannerRotator::Tags" do
4
+ dataset :pages, :banners
5
+
6
+ describe "<r:banner> defaults and updating show_banner attribute" do
7
+ if Page.columns_hash['show_banner'].default == true
8
+ it "should show a banner if show_banner is true (default)" do
9
+ pages(:home).should render('<r:banner>true</r:banner>').as('true')
10
+ end
11
+
12
+ it "should not show a banner if show_banner is false" do
13
+ pages(:radius).should render('<r:banner>true</r:banner>').as('')
14
+ end
15
+ else
16
+ it "should not show a banner if show_banner is false (default)" do
17
+ pages(:home).should render('<r:banner>true</r:banner>').as('')
18
+ end
19
+
20
+ it "should show a banner if show_banner is true" do
21
+ pages(:radius).should render('<r:banner>true</r:banner>').as('true')
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "<r:banner> selection and inheritance" do
27
+ before :each do
28
+ Page.update_all({:show_banner => true })
29
+ banners(:protected).remove_all_placements! #deal with only 1 active banner for predictable results
30
+ end
31
+
32
+ it "should select a random banner from the associated banners" do
33
+ pages(:child_2).should render('<r:banner:name />').matching(/^Child\-2 (first|second)$/)
34
+ end
35
+
36
+ it "should inherit a banner placement from an ancestor" do
37
+ pages(:child).should render('<r:banner:name />').as('First')
38
+ end
39
+ end
40
+
41
+ describe "banner attributes, if_ and unless_ tags" do
42
+ before :each do
43
+ Page.update_all({:show_banner => true })
44
+ banners(:protected).remove_all_placements! #deal with only 1 active banner for predictable results
45
+ end
46
+ %w{name background_image foreground_image link_url link_target image_style}.each do |att|
47
+ describe "<r:banner:#{att}>" do
48
+ it "should render the '#{att}' attribute of the selected banner" do
49
+ pages(:home).should render("<r:banner:#{att} />").as(pages(:home).banners[0][att])
50
+ end
51
+ end
52
+ describe "<r:banner:if_#{att}>" do
53
+ it "should expand the tag contents if the '#{att}' attribute of the selected banner is not blank" do
54
+ pages(:home).should render("<r:banner:if_#{att}>Content</r:banner:if_#{att}>").as("Content")
55
+ end
56
+ end
57
+ describe "<r:banner:unless_#{att}>" do
58
+ it "should expand the tag contents if the '#{att}' attribute of the selected banner is blank" do
59
+ if pages(:another).banners[0][att].blank?
60
+ pages(:another).should render("<r:banner:unless_#{att}>Content</r:banner:unless_#{att}>").as("Content")
61
+ else
62
+ pages(:another).should render("<r:banner:unless_#{att}>Content</r:banner:unless_#{att}>").as("")
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ end