radiant-banner_rotator-extension 1.0.0

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 (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