Commit cbcad8709000cc6f621633116248824c53ff7dbe

Authored by Rodrigo Souto
2 parents a6ea24fa beb05f86

Merge branch 'stable'

app/controllers/application_controller.rb
... ... @@ -21,7 +21,8 @@ class ApplicationController < ActionController::Base
21 21 include ApplicationHelper
22 22 layout :get_layout
23 23 def get_layout
24   - return nil if request.format == :js
  24 + return nil if request.format == :js or request.xhr?
  25 +
25 26 theme_layout = theme_option(:layout)
26 27 if theme_layout
27 28 theme_view_file('layouts/'+theme_layout) || theme_layout
... ...
app/controllers/my_profile/manage_products_controller.rb
... ... @@ -48,6 +48,7 @@ class ManageProductsController < ApplicationController
48 48 end
49 49  
50 50 def new
  51 + @no_design_blocks = true
51 52 @category = params[:selected_category_id] ? Category.find(params[:selected_category_id]) : nil
52 53 @product = @profile.products.build(:product_category => @category)
53 54 @categories = ProductCategory.top_level_for(environment)
... ...
app/controllers/public/account_controller.rb
... ... @@ -135,12 +135,8 @@ class AccountController < ApplicationController
135 135 params[:new_password_confirmation])
136 136 session[:notice] = _('Your password has been changed successfully!')
137 137 redirect_to :action => 'index'
138   - rescue User::IncorrectPassword => e
139   - session[:notice] = _('The supplied current password is incorrect.')
140   - render :action => 'change_password'
  138 + rescue Exception
141 139 end
142   - else
143   - render :action => 'change_password'
144 140 end
145 141 end
146 142  
... ...
app/helpers/layout_helper.rb
... ... @@ -4,7 +4,7 @@ module LayoutHelper
4 4 # Identify the current controller and action for the CSS:
5 5 " controller-#{@controller.controller_name}" +
6 6 " action-#{@controller.controller_name}-#{@controller.action_name}" +
7   - " template-#{profile.nil? ? "default" : profile.layout_template}" +
  7 + " template-#{@layout_template || if profile.blank? then 'default' else profile.layout_template end}" +
8 8 (!profile.nil? && profile.is_on_homepage?(request.path,@page) ? " profile-homepage" : "")
9 9 end
10 10  
... ...
app/helpers/manage_products_helper.rb
... ... @@ -26,27 +26,10 @@ module ManageProductsHelper
26 26 def hierarchy_category_navigation(current_category, options = {})
27 27 hierarchy = []
28 28 if current_category
29   - count_chars = 0
30   - unless options[:hide_current_category]
31   - hierarchy << current_category.name
32   - count_chars += current_category.name.length
33   - end
  29 + hierarchy << current_category.name unless options[:hide_current_category]
34 30 ancestors = current_category.ancestors
35   - toplevel = ancestors.pop
36   - if toplevel
37   - count_chars += toplevel.name.length
38   - end
39 31 ancestors.each do |category|
40   - if count_chars > 55
41   - hierarchy << hierarchy_category_item(category, options[:make_links], '( … )')
42   - break
43   - else
44   - hierarchy << hierarchy_category_item(category, options[:make_links])
45   - end
46   - count_chars += category.name.length
47   - end
48   - if toplevel
49   - hierarchy << hierarchy_category_item(toplevel, options[:make_links])
  32 + hierarchy << hierarchy_category_item(category, options[:make_links])
50 33 end
51 34 end
52 35 hierarchy.reverse.join(options[:separator] || ' &rarr; ')
... ... @@ -55,7 +38,7 @@ module ManageProductsHelper
55 38 def options_for_select_categories(categories, selected = nil)
56 39 categories.sort_by{|cat| cat.name.transliterate}.map do |category|
57 40 selected_attribute = selected.nil? ? '' : (category == selected ? "selected='selected'" : '')
58   - "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{truncate(category.name, :length => 33) + (category.leaf? ? '': ' &raquo;')}</option>"
  41 + "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' &raquo;')}</option>"
59 42 end.join("\n")
60 43 end
61 44  
... ...
app/models/event.rb
... ... @@ -102,20 +102,19 @@ class Event &lt; Article
102 102 html = Builder::XmlMarkup.new(:target => result)
103 103  
104 104 html.div(:class => 'event-info' ) {
105   -
106 105 html.ul(:class => 'event-data' ) {
107 106 html.li(:class => 'event-dates' ) {
108 107 html.span _('When:')
109 108 html.text! show_period(start_date, end_date)
110   - }
  109 + } if start_date.present? || end_date.present?
111 110 html.li {
112 111 html.span _('URL:')
113 112 html.a(self.link || "", 'href' => self.link || "")
114   - }
  113 + } if self.link.present?
115 114 html.li {
116 115 html.span _('Address:')
117 116 html.text! self.address || ""
118   - }
  117 + } if self.address.present?
119 118 }
120 119  
121 120 # TODO: some good soul, please clean this ugly hack:
... ...
app/models/user.rb
... ... @@ -253,7 +253,10 @@ class User &lt; ActiveRecord::Base
253 253 # current password.
254 254 # * Saves the record unless it is a new one.
255 255 def change_password!(current, new, confirmation)
256   - raise IncorrectPassword unless self.authenticated?(current)
  256 + unless self.authenticated?(current)
  257 + self.errors.add(:current_password, _('does not match.'))
  258 + raise IncorrectPassword
  259 + end
257 260 self.force_change_password!(new, confirmation)
258 261 end
259 262  
... ...
app/views/account/change_password.rhtml
1 1 <h1><%= _('Change password') %></h1>
2 2  
  3 +<%= error_messages_for :user %>
  4 +
3 5 <% form_tag do %>
4 6  
5 7 <p><label for="password"><%= _('Current password') %></label><br/>
... ...
app/views/layouts/application-ng.rhtml
... ... @@ -34,8 +34,8 @@
34 34 <%# Add custom tags/styles/etc via content_for %>
35 35 <%= yield :head %>
36 36 <%=
37   - @plugins.dispatch(:head_ending).collect do |content|
38   - content.respond_to?(:call) ? content.call : content
  37 + @plugins.dispatch(:head_ending).map do |content|
  38 + if content.respond_to?(:call) then instance_eval(&content).html_safe else content.html_safe end
39 39 end.join("\n")
40 40 %>
41 41  
... ... @@ -47,8 +47,8 @@
47 47 <a href="#content" id="link-go-content"><span><%= _("Go to the content") %></span></a>
48 48  
49 49 <%=
50   - @plugins.dispatch(:body_beginning).collect do |content|
51   - content.respond_to?(:call) ? content.call : content
  50 + @plugins.dispatch(:body_beginning).map do |content|
  51 + if content.respond_to?(:call) then instance_eval(&content).html_safe else content.html_safe end
52 52 end.join("\n")
53 53 %>
54 54  
... ...
app/views/profile_editor/edit.rhtml
... ... @@ -52,8 +52,8 @@
52 52 )%>
53 53  
54 54 <%=
55   - @plugins.dispatch(:profile_editor_extras).each do |content|
56   - content.respond_to?(:call) ? content.call : content
  55 + @plugins.dispatch(:profile_editor_extras).map do |content|
  56 + if content.respond_to?(:call) then instance_eval(&content).html_safe else content.html_safe end
57 57 end.join("\n")
58 58 %>
59 59  
... ...
debian/changelog
  1 +noosfero (0.47.1) unstable; urgency=low
  2 +
  3 + * Bugfix release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Mon, 05 May 2014 19:10:51 +0000
  6 +
1 7 noosfero (0.47.0) unstable; urgency=low
2 8  
3 9 * New features release
... ...
lib/noosfero.rb
... ... @@ -2,7 +2,7 @@
2 2 require 'fast_gettext'
3 3 module Noosfero
4 4 PROJECT = 'noosfero'
5   - VERSION = '0.47.0'
  5 + VERSION = '0.47.1'
6 6  
7 7 def self.pattern_for_controllers_in_directory(dir)
8 8 disjunction = controllers_in_directory(dir).join('|')
... ...
lib/noosfero/plugin.rb
... ... @@ -569,7 +569,7 @@ class Noosfero::Plugin
569 569 def content_actions
570 570 #FIXME 'new' and 'upload' only works for content_remove. It should work for
571 571 #content_expire too.
572   - %w[edit delete spread locale suggest home new upload]
  572 + %w[edit delete spread locale suggest home new upload undo]
573 573 end
574 574  
575 575 end
... ...
plugins/custom_forms/db/migrate/20130823151900_associate_fields_to_alternatives.rb
... ... @@ -15,14 +15,18 @@ class AssociateFieldsToAlternatives &lt; ActiveRecord::Migration
15 15 end
16 16  
17 17 CustomFormsPlugin::Answer.find_each do |answer|
18   - labels = []
19   - answer.value.split(',').each do |value|
20   - labels << answer.field.choices.invert[value]
21   - end
22   - labels.compact!
23   - if labels.present?
24   - answer.value = answer.field.alternatives.where('label IN (?)', labels).map(&:id).join(',')
25   - answer.save!
  18 + # Avoid crash due to database possible inconsistency on submissions without form
  19 + begin
  20 + labels = []
  21 + answer.value.split(',').each do |value|
  22 + labels << answer.field.choices.invert[value]
  23 + end
  24 + labels.compact!
  25 + if labels.present?
  26 + answer.value = answer.field.alternatives.where('label IN (?)', labels).map(&:id).join(',')
  27 + answer.save!
  28 + end
  29 + rescue
26 30 end
27 31 end
28 32  
... ...
plugins/custom_forms/db/migrate/20140505131703_remove_submissions_without_form.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class RemoveSubmissionsWithoutForm < ActiveRecord::Migration
  2 + def self.up
  3 + CustomFormsPlugin::Submission.find_each do |submission|
  4 + submission.destroy if submission.form.nil?
  5 + end
  6 + end
  7 +
  8 + def self.down
  9 + say "This migration is irreversible."
  10 + end
  11 +end
... ...
plugins/custom_forms/lib/custom_forms_plugin/form.rb
... ... @@ -4,7 +4,7 @@ class CustomFormsPlugin::Form &lt; Noosfero::Plugin::ActiveRecord
4 4 has_many :fields, :order => 'position', :class_name => 'CustomFormsPlugin::Field', :dependent => :destroy
5 5 accepts_nested_attributes_for :fields, :allow_destroy => true
6 6  
7   - has_many :submissions, :class_name => 'CustomFormsPlugin::Submission'
  7 + has_many :submissions, :class_name => 'CustomFormsPlugin::Submission', :dependent => :destroy
8 8  
9 9 serialize :access
10 10  
... ...
plugins/custom_forms/test/unit/custom_forms_plugin/form_test.rb
... ... @@ -260,4 +260,18 @@ class CustomFormsPlugin::FormTest &lt; ActiveSupport::TestCase
260 260 form2.destroy
261 261 assert_includes Task.canceled, task2
262 262 end
  263 +
  264 + should 'destroy submissions after form is destroyed' do
  265 + form = CustomFormsPlugin::Form.create!(:profile => fast_create(Profile), :name => 'Free Software')
  266 + s1 = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  267 + s2 = CustomFormsPlugin::Submission.create!(:form => form, :profile => fast_create(Profile))
  268 + form.destroy
  269 +
  270 + assert_raise ActiveRecord::RecordNotFound do
  271 + s1.reload
  272 + end
  273 + assert_raise ActiveRecord::RecordNotFound do
  274 + s2.reload
  275 + end
  276 + end
263 277 end
... ...
public/stylesheets/application.css
... ... @@ -3771,7 +3771,6 @@ h1#agenda-title {
3771 3771 -webkit-border-radius: 5px;
3772 3772 background: url(/images/ccc.gif); /* image ccc.gif from http://www.wannabegirl.org/translucent */
3773 3773 padding: 10px 30px 20px 30px;
3774   - width: 570px;
3775 3774 }
3776 3775 #categories_container_wrapper {
3777 3776 overflow-x: scroll;
... ...
test/functional/account_controller_test.rb
... ... @@ -203,6 +203,16 @@ class AccountControllerTest &lt; ActionController::TestCase
203 203 assert_equal users(:ze), @controller.send(:current_user)
204 204 end
205 205  
  206 + should "not change password when new password and new password confirmation don't match" do
  207 + login_as 'ze'
  208 + post :change_password, :current_password => 'test', :new_password => 'blabla', :new_password_confirmation => 'blibli'
  209 + assert_response :success
  210 + assert_template 'change_password'
  211 + assert !assigns(:current_user).authenticated?('blabla')
  212 + assert !assigns(:current_user).authenticated?('blibli')
  213 + assert_equal users(:ze), @controller.send(:current_user)
  214 + end
  215 +
206 216 should 'provide a "I forget my password" link at the login page' do
207 217 get :login
208 218 assert_tag :tag => 'a', :attributes => {
... ...
test/functional/application_controller_test.rb
... ... @@ -418,11 +418,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
418 418  
419 419 should 'include content in the beginning of body supplied by plugins regardless it is a block or html code' do
420 420 class TestBodyBeginning1Plugin < Noosfero::Plugin
421   - def plugin1_method
422   - '[[plugin1]]'
423   - end
424 421 def body_beginning
425   - lambda {"<span id='plugin1'>This is #{plugin1_method} speaking!</span>"}
  422 + lambda {"<span id='plugin1'>This is [[plugin1]] speaking!</span>"}
426 423 end
427 424 end
428 425 class TestBodyBeginning2Plugin < Noosfero::Plugin
... ... @@ -442,11 +439,8 @@ class ApplicationControllerTest &lt; ActionController::TestCase
442 439 should 'include content in the ending of head supplied by plugins regardless it is a block or html code' do
443 440  
444 441 class TestHeadEnding1Plugin < Noosfero::Plugin
445   - def plugin1_method
446   - '[[plugin1]]'
447   - end
448 442 def head_ending
449   - lambda {"<script>alert('This is #{plugin1_method} speaking!')</script>"}
  443 + lambda {"<script>alert('This is [[plugin1]] speaking!')</script>"}
450 444 end
451 445 end
452 446 class TestHeadEnding2Plugin < Noosfero::Plugin
... ...
test/unit/manage_products_helper_test.rb
... ... @@ -13,23 +13,6 @@ class ManageProductsHelperTest &lt; ActiveSupport::TestCase
13 13 @profile = create_user('blog_helper_test').person
14 14 end
15 15  
16   - should 'omit second category when lenght of all names is over 60 chars' do
17   - category_1 = fast_create(ProductCategory, :name => ('Category 1' * 5), :environment_id => @environment.id)
18   - category_2 = fast_create(ProductCategory, :name => ('Category 2' * 5), :environment_id => @environment.id, :parent_id => category_1.id)
19   - category_3 = fast_create(ProductCategory, :name => ('Category 3' * 5), :environment_id => @environment.id, :parent_id => category_2.id)
20   -
21   - assert_match /Category 1/, hierarchy_category_navigation(category_3)
22   - assert_no_match /Category 2/, hierarchy_category_navigation(category_3)
23   - end
24   -
25   - should 'show dots when lenght of all names is over 60 chars' do
26   - category_1 = fast_create(ProductCategory, :name => ('Category 1' * 5), :environment_id => @environment.id)
27   - category_2 = fast_create(ProductCategory, :name => ('Category 2' * 5), :environment_id => @environment.id, :parent_id => category_1.id)
28   - category_3 = fast_create(ProductCategory, :name => ('Category 3' * 5), :environment_id => @environment.id, :parent_id => category_2.id)
29   -
30   - assert_match /…/, hierarchy_category_navigation(category_3)
31   - end
32   -
33 16 should 'display select for categories' do
34 17 category_1 = fast_create(ProductCategory, :name => 'Category 1', :environment_id => @environment.id)
35 18 fast_create(ProductCategory, :name => 'Category 2.1', :environment_id => @environment.id, :parent_id => category_1.id)
... ...