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.
- data/.gitmodules +3 -0
- data/HELP.textile +87 -0
- data/README.textile +68 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/app/controllers/admin/banners_controller.rb +61 -0
- data/app/helpers/admin/banners_helper.rb +62 -0
- data/app/models/banner.rb +101 -0
- data/app/models/banner_placement.rb +7 -0
- data/app/views/admin/banners/_form.html.haml +76 -0
- data/app/views/admin/banners/_modify_banner.html.haml +8 -0
- data/app/views/admin/banners/deactivate.html.haml +10 -0
- data/app/views/admin/banners/edit.html.haml +8 -0
- data/app/views/admin/banners/index.html.haml +118 -0
- data/app/views/admin/banners/new.html.haml +5 -0
- data/app/views/admin/banners/remove.html.haml +12 -0
- data/app/views/admin/pages/_banner_info.html.haml +28 -0
- data/app/views/admin/pages/_banners_column.html.haml +11 -0
- data/app/views/admin/pages/_banners_column_header.html.haml +9 -0
- data/banner_rotator_extension.rb +41 -0
- data/config/initializers/radiant_config.rb +3 -0
- data/config/locales/en.yml +34 -0
- data/config/routes.rb +5 -0
- data/db/migrate/001_create_banners.rb +31 -0
- data/db/migrate/002_change_banners_default.rb +9 -0
- data/db/migrate/003_add_description.rb +9 -0
- data/lib/banner_rotator/page_extensions.rb +47 -0
- data/lib/banner_rotator/tags.rb +67 -0
- data/lib/tasks/banner_rotator_extension_tasks.rake +29 -0
- data/public/images/admin/deactivate.png +0 -0
- data/public/images/admin/pictures.png +0 -0
- data/public/images/admin/text_list_numbers.png +0 -0
- data/public/javascripts/lowpro.js +320 -0
- data/spec/controllers/admin_banners_controller_spec.rb +231 -0
- data/spec/datasets/banners_dataset.rb +26 -0
- data/spec/helpers/admin/banners_helper_spec.rb +9 -0
- data/spec/models/banner_placement_spec.rb +44 -0
- data/spec/models/banner_spec.rb +47 -0
- data/spec/models/page_extensions_spec.rb +25 -0
- data/spec/models/tags_spec.rb +69 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- 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
|