Commit 2084ef4738da4ceda0e44cf5ff80f5a0db2acf3a

Authored by AntonioTerceiro
1 parent b9adeec9

ActionItem490: "finishing" products block

git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@2152 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/my_profile/profile_design_controller.rb
@@ -18,6 +18,11 @@ class ProfileDesignController < BoxOrganizerController @@ -18,6 +18,11 @@ class ProfileDesignController < BoxOrganizerController
18 blocks << FavoriteEnterprisesBlock 18 blocks << FavoriteEnterprisesBlock
19 end 19 end
20 20
  21 + # blocks exclusive for enterprises
  22 + if profile.enterprise?
  23 + blocks << ProductsBlock
  24 + end
  25 +
21 blocks 26 blocks
22 end 27 end
23 28
app/helpers/boxes_helper.rb
@@ -121,12 +121,20 @@ module BoxesHelper @@ -121,12 +121,20 @@ module BoxesHelper
121 def block_edit_buttons(block) 121 def block_edit_buttons(block)
122 buttons = [] 122 buttons = []
123 123
124 - buttons << icon_button(:up, _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' }) unless block.first?  
125 - buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'}) unless block.last?  
126 - buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post'}) unless block.main? 124 + if !block.first?
  125 + buttons << icon_button(:up, _('Move block up'), { :action => 'move_block_up', :id => block.id }, { :method => 'post' })
  126 + end
  127 +
  128 + if !block.last?
  129 + buttons << icon_button(:down, _('Move block down'), { :action => 'move_block_down' ,:id => block.id }, { :method => 'post'})
  130 + end
  131 +
  132 + if block.editable?
  133 + buttons << lightbox_icon_button(:edit, _('Edit'), { :controller => 'profile_design', :action => 'edit', :id => block.id })
  134 + end
127 135
128 - if block.editor  
129 - buttons << lightbox_button(:edit, _('Edit'), block.editor) 136 + if !block.main?
  137 + buttons << icon_button(:delete, _('Remove block'), { :action => 'remove', :id => block.id }, { :method => 'post'})
130 end 138 end
131 139
132 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar') 140 content_tag('div', buttons.join("\n") + tag('br', :style => 'clear: left'), :class => 'button-bar')
app/helpers/lightbox_helper.rb
@@ -16,6 +16,10 @@ module LightboxHelper @@ -16,6 +16,10 @@ module LightboxHelper
16 button(type, label, url, lightbox_options(options)) 16 button(type, label, url, lightbox_options(options))
17 end 17 end
18 18
  19 + def lightbox_icon_button(type, label, url, options = {})
  20 + icon_button(type, label, url, lightbox_options(options))
  21 + end
  22 +
19 # options must be an HTML options hash as passed to link_to etc. 23 # options must be an HTML options hash as passed to link_to etc.
20 # 24 #
21 # returns a new hash with lightbox class added. Keeps existing classes. 25 # returns a new hash with lightbox class added. Keeps existing classes.
app/models/article_block.rb
@@ -36,8 +36,8 @@ class ArticleBlock &lt; Block @@ -36,8 +36,8 @@ class ArticleBlock &lt; Block
36 @article = obj 36 @article = obj
37 end 37 end
38 38
39 - def editor  
40 - { :controller => 'profile_design', :action => 'edit', :id => self.id } 39 + def editable?
  40 + true
41 end 41 end
42 42
43 end 43 end
app/models/block.rb
@@ -45,10 +45,9 @@ class Block &lt; ActiveRecord::Base @@ -45,10 +45,9 @@ class Block &lt; ActiveRecord::Base
45 nil 45 nil
46 end 46 end
47 47
48 - # must return a Hash with URL options poiting to the action that edits  
49 - # properties of the block  
50 - def editor  
51 - nil 48 + # Is this block editable? (Default to <tt>false</tt>)
  49 + def editable?
  50 + false
52 end 51 end
53 52
54 # must always return false, except on MainBlock clas. 53 # must always return false, except on MainBlock clas.
app/models/products_block.rb
@@ -8,15 +8,21 @@ class ProductsBlock &lt; Block @@ -8,15 +8,21 @@ class ProductsBlock &lt; Block
8 block_title(_('Products')) + 8 block_title(_('Products')) +
9 content_tag( 9 content_tag(
10 'ul', 10 'ul',
11 - owner.products.map {|product| content_tag('li', link_to(product.name, product.url, :style => 'background-image:url(%s)' % ( product.image ? product.image.public_filename(:minor) : '/images/icons-app/product-default-pic-minor.png' )), :class => 'product' )} 11 + products.map {|product| content_tag('li', link_to(product.name, product.url, :style => 'background-image:url(%s)' % ( product.image ? product.image.public_filename(:minor) : '/images/icons-app/product-default-pic-minor.png' )), :class => 'product' )}
12 ) 12 )
13 end 13 end
14 14
15 def footer 15 def footer
16 - link_to(_('View all'), owner.generate_url(:controller => 'catalog', :action => 'index')) 16 + link_to(_('View all products'), owner.generate_url(:controller => 'catalog', :action => 'index'))
17 end 17 end
18 18
19 settings_items :product_ids, Array 19 settings_items :product_ids, Array
  20 + def product_ids=(array)
  21 + self.settings[:product_ids] = array
  22 + if self.settings[:product_ids]
  23 + self.settings[:product_ids] = self.settings[:product_ids].map(&:to_i)
  24 + end
  25 + end
20 26
21 def products(reload = false) 27 def products(reload = false)
22 if product_ids.blank? 28 if product_ids.blank?
@@ -31,4 +37,8 @@ class ProductsBlock &lt; Block @@ -31,4 +37,8 @@ class ProductsBlock &lt; Block
31 end 37 end
32 end 38 end
33 39
  40 + def editable?
  41 + true
  42 + end
  43 +
34 end 44 end
app/views/box_organizer/_products_block.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<strong></strong>
  2 +
  3 +<p>
  4 +<strong>
  5 +<%= _('Select the products that must be shown.') %>
  6 +</strong>
  7 +</p>
  8 +
  9 +<% for product in @block.owner.products %>
  10 + <%= check_box_tag("block[product_ids][]", product.id, (!@block.product_ids.blank? && @block.product_ids.include?(product.id)), :id => "block_product_ids_#{product.id}" ) %>
  11 + <label for="block_product_ids_<%= product.id %>"><%= product.name %></label>
  12 + <br/>
  13 +<% end %>
test/fixtures/roles.yml
@@ -32,6 +32,8 @@ profile_admin: @@ -32,6 +32,8 @@ profile_admin:
32 key: 'profile_admin' 32 key: 'profile_admin'
33 name: 'Profile Administrator' 33 name: 'Profile Administrator'
34 system: true 34 system: true
  35 + permissions:
  36 + - edit_profile_design
35 profile_member: 37 profile_member:
36 id: 6 38 id: 6
37 key: 'profile_member' 39 key: 'profile_member'
test/functional/profile_design_controller_test.rb
@@ -5,12 +5,13 @@ class ProfileDesignController; def rescue_action(e) raise e end; end @@ -5,12 +5,13 @@ class ProfileDesignController; def rescue_action(e) raise e end; end
5 5
6 class ProfileDesignControllerTest < Test::Unit::TestCase 6 class ProfileDesignControllerTest < Test::Unit::TestCase
7 7
  8 + attr_reader :holder
8 def setup 9 def setup
9 @controller = ProfileDesignController.new 10 @controller = ProfileDesignController.new
10 @request = ActionController::TestRequest.new 11 @request = ActionController::TestRequest.new
11 @response = ActionController::TestResponse.new 12 @response = ActionController::TestResponse.new
12 13
13 - holder = create_user('designtestuser').person 14 + @holder = create_user('designtestuser').person
14 holder.save! 15 holder.save!
15 16
16 @box1 = Box.new 17 @box1 = Box.new
@@ -59,11 +60,11 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -59,11 +60,11 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
59 @request.env['HTTP_REFERER'] = '/editor' 60 @request.env['HTTP_REFERER'] = '/editor'
60 61
61 @controller.stubs(:boxes_holder).returns(holder) 62 @controller.stubs(:boxes_holder).returns(holder)
62 - login_as 'ze' 63 + login_as 'designtestuser'
63 end 64 end
64 65
65 def test_local_files_reference 66 def test_local_files_reference
66 - assert_local_files_reference :get, :index, :profile => 'ze' 67 + assert_local_files_reference :get, :index, :profile => 'designtestuser'
67 end 68 end
68 69
69 def test_valid_xhtml 70 def test_valid_xhtml
@@ -74,7 +75,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -74,7 +75,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
74 # BEGIN - tests for BoxOrganizerController features 75 # BEGIN - tests for BoxOrganizerController features
75 ###################################################### 76 ######################################################
76 def test_should_move_block_to_the_end_of_another_block 77 def test_should_move_block_to_the_end_of_another_block
77 - get :move_block, :profile => 'ze', :id => "block-#{@b1.id}", :target => "end-of-box-#{@box2.id}" 78 + get :move_block, :profile => 'designtestuser', :id => "block-#{@b1.id}", :target => "end-of-box-#{@box2.id}"
78 79
79 assert_response :success 80 assert_response :success
80 81
@@ -88,7 +89,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -88,7 +89,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
88 89
89 def test_should_move_block_to_the_middle_of_another_block 90 def test_should_move_block_to_the_middle_of_another_block
90 # block 4 is in box 2 91 # block 4 is in box 2
91 - get :move_block, :profile => 'ze', :id => "block-#{@b1.id}", :target => "before-block-#{@b4.id}" 92 + get :move_block, :profile => 'designtestuser', :id => "block-#{@b1.id}", :target => "before-block-#{@b4.id}"
92 93
93 assert_response :success 94 assert_response :success
94 95
@@ -101,7 +102,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -101,7 +102,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
101 end 102 end
102 103
103 def test_block_can_be_moved_up 104 def test_block_can_be_moved_up
104 - get :move_block, :profile => 'ze', :id => "block-#{@b4.id}", :target => "before-block-#{@b3.id}" 105 + get :move_block, :profile => 'designtestuser', :id => "block-#{@b4.id}", :target => "before-block-#{@b3.id}"
105 106
106 assert_response :success 107 assert_response :success
107 @b4.reload 108 @b4.reload
@@ -114,7 +115,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -114,7 +115,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
114 assert_equal [1,2,3], [@b3,@b4,@b5].map {|item| item.position} 115 assert_equal [1,2,3], [@b3,@b4,@b5].map {|item| item.position}
115 116
116 # b3 -> before b5 117 # b3 -> before b5
117 - get :move_block, :profile => 'ze', :id => "block-#{@b3.id}", :target => "before-block-#{@b5.id}" 118 + get :move_block, :profile => 'designtestuser', :id => "block-#{@b3.id}", :target => "before-block-#{@b5.id}"
118 119
119 [@b3,@b4,@b5].each do |item| 120 [@b3,@b4,@b5].each do |item|
120 item.reload 121 item.reload
@@ -124,7 +125,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -124,7 +125,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
124 end 125 end
125 126
126 def test_should_be_able_to_move_block_directly_down 127 def test_should_be_able_to_move_block_directly_down
127 - post :move_block_down, :profile => 'ze', :id => @b1.id 128 + post :move_block_down, :profile => 'designtestuser', :id => @b1.id
128 assert_response :redirect 129 assert_response :redirect
129 130
130 @b1.reload 131 @b1.reload
@@ -134,7 +135,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -134,7 +135,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
134 end 135 end
135 136
136 def test_should_be_able_to_move_block_directly_up 137 def test_should_be_able_to_move_block_directly_up
137 - post :move_block_up, :profile => 'ze', :id => @b2.id 138 + post :move_block_up, :profile => 'designtestuser', :id => @b2.id
138 assert_response :redirect 139 assert_response :redirect
139 140
140 @b1.reload 141 @b1.reload
@@ -145,7 +146,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -145,7 +146,7 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
145 146
146 def test_should_remove_block 147 def test_should_remove_block
147 assert_difference Block, :count, -1 do 148 assert_difference Block, :count, -1 do
148 - post :remove, :profile => 'ze', :id => @b2.id 149 + post :remove, :profile => 'designtestuser', :id => @b2.id
149 assert_response :redirect 150 assert_response :redirect
150 assert_redirected_to :action => 'index' 151 assert_redirected_to :action => 'index'
151 end 152 end
@@ -160,14 +161,14 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -160,14 +161,14 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
160 ###################################################### 161 ######################################################
161 162
162 should 'display popup for adding a new block' do 163 should 'display popup for adding a new block' do
163 - get :add_block, :profile => 'ze' 164 + get :add_block, :profile => 'designtestuser'
164 assert_response :success 165 assert_response :success
165 assert_no_tag :tag => 'body' # e.g. no layout 166 assert_no_tag :tag => 'body' # e.g. no layout
166 end 167 end
167 168
168 should 'actually add a new block' do 169 should 'actually add a new block' do
169 assert_difference Block, :count do 170 assert_difference Block, :count do
170 - post :add_block, :profile => 'ze', :box_id => @box1.id, :type => RecentDocumentsBlock.name 171 + post :add_block, :profile => 'designtestuser', :box_id => @box1.id, :type => RecentDocumentsBlock.name
171 assert_redirected_to :action => 'index' 172 assert_redirected_to :action => 'index'
172 end 173 end
173 end 174 end
@@ -175,19 +176,19 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -175,19 +176,19 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
175 should 'not allow to create unknown types' do 176 should 'not allow to create unknown types' do
176 assert_no_difference Block, :count do 177 assert_no_difference Block, :count do
177 assert_raise ArgumentError do 178 assert_raise ArgumentError do
178 - post :add_block, :profile => 'ze', :box_id => @box1.id, :type => "PleaseLetMeCrackYourSite" 179 + post :add_block, :profile => 'designtestuser', :box_id => @box1.id, :type => "PleaseLetMeCrackYourSite"
179 end 180 end
180 end 181 end
181 end 182 end
182 183
183 should 'provide edit screen for blocks' do 184 should 'provide edit screen for blocks' do
184 - get :edit, :profile => 'ze', :id => @b1.id 185 + get :edit, :profile => 'designtestuser', :id => @b1.id
185 assert_template 'edit' 186 assert_template 'edit'
186 assert_no_tag :tag => 'body' # e.g. no layout 187 assert_no_tag :tag => 'body' # e.g. no layout
187 end 188 end
188 189
189 should 'be able to save a block' do 190 should 'be able to save a block' do
190 - post :save, :profile => 'ze', :id => @b1.id, :block => { :article_id => 999 } 191 + post :save, :profile => 'designtestuser', :id => @b1.id, :block => { :article_id => 999 }
191 192
192 assert_redirected_to :action => 'index' 193 assert_redirected_to :action => 'index'
193 194
@@ -195,6 +196,45 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase @@ -195,6 +196,45 @@ class ProfileDesignControllerTest &lt; Test::Unit::TestCase
195 assert_equal 999, @b1.article_id 196 assert_equal 999, @b1.article_id
196 end 197 end
197 198
  199 + should 'be able to edit ProductsBlock' do
  200 + block = ProductsBlock.new
  201 +
  202 + enterprise = Enterprise.create!(:name => "test", :identifier => 'testenterprise')
  203 + p1 = enterprise.products.create!(:name => 'product one')
  204 + p2 = enterprise.products.create!(:name => 'product two')
  205 + enterprise.boxes.first.blocks << block
  206 + enterprise.add_admin(holder)
  207 +
  208 + @controller.stubs(:boxes_holder).returns(enterprise)
  209 + login_as('designtestuser')
  210 +
  211 + get :edit, :profile => 'testenterprise', :id => block.id
  212 +
  213 + assert_response :success
  214 + assert_tag :tag => 'input', :attributes => { :name => "block[product_ids][]", :value => p1.id.to_s }
  215 + assert_tag :tag => 'input', :attributes => { :name => "block[product_ids][]", :value => p2.id.to_s }
  216 + end
  217 +
  218 + should 'be able to save ProductsBlock' do
  219 + block = ProductsBlock.new
  220 +
  221 + enterprise = Enterprise.create!(:name => "test", :identifier => 'testenterprise')
  222 + p1 = enterprise.products.create!(:name => 'product one')
  223 + p2 = enterprise.products.create!(:name => 'product two')
  224 + enterprise.boxes.first.blocks << block
  225 + enterprise.add_admin(holder)
  226 +
  227 + @controller.stubs(:boxes_holder).returns(enterprise)
  228 + login_as('designtestuser')
  229 +
  230 + post :save, :profile => 'testenterprise', :id => block.id, :block => { :product_ids => [p1.id.to_s, p2.id.to_s ] }
  231 +
  232 + assert_response :redirect
  233 +
  234 + block.reload
  235 + assert_equal [p1.id, p2.id], block.product_ids
  236 +
  237 + end
198 238
199 end 239 end
200 240
test/unit/article_block_test.rb
@@ -52,4 +52,8 @@ class ArticleBlockTest &lt; Test::Unit::TestCase @@ -52,4 +52,8 @@ class ArticleBlockTest &lt; Test::Unit::TestCase
52 assert_nil block.article_id 52 assert_nil block.article_id
53 end 53 end
54 54
  55 + should 'be editable' do
  56 + assert ArticleBlock.new.editable?
  57 + end
  58 +
55 end 59 end
test/unit/block_test.rb
@@ -32,4 +32,8 @@ class BlockTest &lt; Test::Unit::TestCase @@ -32,4 +32,8 @@ class BlockTest &lt; Test::Unit::TestCase
32 assert_nil Block.new.footer 32 assert_nil Block.new.footer
33 end 33 end
34 34
  35 + should 'not be editable by default' do
  36 + assert !Block.new.editable?
  37 + end
  38 +
35 end 39 end
test/unit/lightbox_helper_test.rb
@@ -44,6 +44,12 @@ class LightboxHelperTest &lt; Test::Unit::TestCase @@ -44,6 +44,12 @@ class LightboxHelperTest &lt; Test::Unit::TestCase
44 assert_equal '[button]', lightbox_button('type', 'label', { :action => 'popup'}) 44 assert_equal '[button]', lightbox_button('type', 'label', { :action => 'popup'})
45 end 45 end
46 46
  47 + should 'provide lightbox_icon_button' do
  48 + expects(:icon_button).with('type', 'label', { :action => 'popup'}, { :class => 'lbOn' }).returns('[button]')
  49 +
  50 + assert_equal '[button]', lightbox_icon_button('type', 'label', { :action => 'popup'})
  51 + end
  52 +
47 should 'tell if rendering inside lightbox' do 53 should 'tell if rendering inside lightbox' do
48 request = mock 54 request = mock
49 expects(:request).returns(request) 55 expects(:request).returns(request)
test/unit/products_block_test.rb
@@ -11,14 +11,13 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase @@ -11,14 +11,13 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase
11 assert_kind_of Block, block 11 assert_kind_of Block, block
12 end 12 end
13 13
14 - should "list owner's products" do 14 + should "list owner products" do
15 15
16 enterprise = Enterprise.create!(:name => 'testenterprise', :identifier => 'testenterprise') 16 enterprise = Enterprise.create!(:name => 'testenterprise', :identifier => 'testenterprise')
17 enterprise.products.create!(:name => 'product one') 17 enterprise.products.create!(:name => 'product one')
18 enterprise.products.create!(:name => 'product two') 18 enterprise.products.create!(:name => 'product two')
19 19
20 - block.stubs(:owner).returns(enterprise)  
21 - 20 + block.expects(:products).returns(enterprise.products)
22 21
23 content = block.content 22 content = block.content
24 23
@@ -38,7 +37,7 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase @@ -38,7 +37,7 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase
38 37
39 footer = block.footer 38 footer = block.footer
40 39
41 - assert_tag_in_string footer, :tag => 'a', :attributes => { :href => /\/catalog\/testenterprise$/ }, :content => 'View all' 40 + assert_tag_in_string footer, :tag => 'a', :attributes => { :href => /\/catalog\/testenterprise$/ }, :content => 'View all products'
42 end 41 end
43 42
44 should 'list 4 random products by default' do 43 should 'list 4 random products by default' do
@@ -94,4 +93,14 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase @@ -94,4 +93,14 @@ class ProductsBlockTest &lt; ActiveSupport::TestCase
94 assert_equal [p1.id, p2.id], ProductsBlock.find(block.id).product_ids 93 assert_equal [p1.id, p2.id], ProductsBlock.find(block.id).product_ids
95 end 94 end
96 95
  96 + should 'accept strings in product_ids but store integers' do
  97 + block = ProductsBlock.new
  98 + block.product_ids = [ '1', '2']
  99 + assert_equal [1, 2], block.product_ids
  100 + end
  101 +
  102 + should 'be editable' do
  103 + assert ProductsBlock.new.editable?
  104 + end
  105 +
97 end 106 end