Commit cbcad8709000cc6f621633116248824c53ff7dbe
Exists in
master
and in
29 other branches
Merge branch 'stable'
Showing
21 changed files
with
81 additions
and
75 deletions
Show diff stats
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] || ' → ') |
... | ... | @@ -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? ? '': ' »')}</option>" | |
41 | + "<option value='#{category.id}' title='#{category.name}' #{selected_attribute}>#{category.name + (category.leaf? ? '': ' »')}</option>" | |
59 | 42 | end.join("\n") |
60 | 43 | end |
61 | 44 | ... | ... |
app/models/event.rb
... | ... | @@ -102,20 +102,19 @@ class Event < 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 < 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
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
lib/noosfero.rb
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 < 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 < 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 < 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 < 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 < 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 < 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 < 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) | ... | ... |