Commit f5922203e2dd09c952a7163baec39e98355bbca1

Authored by Joenio Costa
2 parents edfe30e8 db1cdcce

Merge branch 'stable'

Conflicts:
	app/models/qualifier.rb
	db/schema.rb
	test/unit/manage_products_helper_test.rb
	test/unit/qualifier_test.rb
Showing 46 changed files with 461 additions and 98 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
... ... @@ -49,6 +49,9 @@ class CmsController < MyProfileController
49 49 if profile.enterprise?
50 50 articles << EnterpriseHomepage
51 51 end
  52 + if @parent && @parent.blog?
  53 + articles -= Article.folder_types.map(&:constantize)
  54 + end
52 55 articles
53 56 end
54 57  
... ... @@ -109,6 +112,7 @@ class CmsController &lt; MyProfileController
109 112  
110 113 # user must choose an article type first
111 114  
  115 + @parent = profile.articles.find(params[:parent_id]) if params && params[:parent_id]
112 116 record_coming
113 117 @type = params[:type]
114 118 if @type.blank?
... ...
app/controllers/my_profile/tasks_controller.rb
... ... @@ -16,16 +16,18 @@ class TasksController &lt; MyProfileController
16 16 def close
17 17 failed = {}
18 18  
19   - params[:tasks].each do |id, value|
20   - decision = value[:decision]
21   - if request.post? && VALID_DECISIONS.include?(decision) && id && decision != 'skip'
22   - task = profile.find_in_all_tasks(id)
23   - task.update_attributes!(value[:task])
24   - begin
25   - task.send(decision)
26   - rescue Exception => ex
27   - message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
28   - failed[ex.clean_message] ? failed[ex.clean_message] << message : failed[ex.clean_message] = [message]
  19 + if params[:tasks]
  20 + params[:tasks].each do |id, value|
  21 + decision = value[:decision]
  22 + if request.post? && VALID_DECISIONS.include?(decision) && id && decision != 'skip'
  23 + task = profile.find_in_all_tasks(id)
  24 + begin
  25 + task.update_attributes(value[:task])
  26 + task.send(decision)
  27 + rescue Exception => ex
  28 + message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
  29 + failed[ex.clean_message] ? failed[ex.clean_message] << message : failed[ex.clean_message] = [message]
  30 + end
29 31 end
30 32 end
31 33 end
... ...
app/controllers/public/browse_controller.rb
... ... @@ -8,17 +8,20 @@ class BrowseController &lt; PublicController
8 8 more_popular
9 9 )
10 10  
  11 + def per_page
  12 + 27
  13 + end
  14 +
11 15 def people
12 16 @filter = filter
13 17 @title = self.filter_description(params[:action] + '_' + @filter )
14 18  
15 19 @results = @environment.people.visible.send(@filter)
16 20  
17   - if params[:query].blank?
18   - @results = @results.paginate(:per_page => 27, :page => params[:page])
19   - else
20   - @results = @results.find_by_contents(params[:query]).paginate(:per_page => 27, :page => params[:page])
  21 + if !params[:query].blank?
  22 + @results = @results.find_by_contents(params[:query])
21 23 end
  24 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
22 25 end
23 26  
24 27 def communities
... ... @@ -27,11 +30,10 @@ class BrowseController &lt; PublicController
27 30  
28 31 @results = @environment.communities.visible.send(@filter)
29 32  
30   - if params[:query].blank?
31   - @results = @results.paginate(:per_page => 27, :page => params[:page])
32   - else
33   - @results = @results.find_by_contents(params[:query]).paginate(:per_page => 27, :page => params[:page])
  33 + if !params[:query].blank?
  34 + @results = @results.find_by_contents(params[:query])
34 35 end
  36 + @results = @results.compact.paginate(:per_page => per_page, :page => params[:page])
35 37 end
36 38  
37 39 protected
... ...
app/controllers/public/profile_controller.rb
... ... @@ -105,6 +105,8 @@ class ProfileController &lt; PublicController
105 105 end
106 106 if request.xhr?
107 107 render :layout => false
  108 + else
  109 + redirect_to profile.url
108 110 end
109 111 end
110 112 end
... ...
app/helpers/search_helper.rb
... ... @@ -65,7 +65,7 @@ module SearchHelper
65 65 data << content_tag('strong', _('Address: ')) + profile.address + '<br/>'
66 66 end
67 67 unless profile.products.empty?
68   - data << content_tag('strong', _('Products/Services: ')) + profile.products.map{|i| link_to(i.name, :controller => 'catalog', :profile => profile.identifier, :action => 'show', :id => i)}.join(', ') + '<br/>'
  68 + data << content_tag('strong', _('Products/Services: ')) + profile.products.map{|i| link_to(i.name, :controller => 'catalog', :profile => profile.identifier, :action => 'show', :id => i.id)}.join(', ') + '<br/>'
69 69 end
70 70 if profile.respond_to?(:distance) and !profile.distance.nil?
71 71 data << content_tag('strong', _('Distance: ')) + "%.2f%" % profile.distance + '<br/>'
... ...
app/models/article.rb
... ... @@ -339,8 +339,13 @@ class Article &lt; ActiveRecord::Base
339 339 end
340 340 end
341 341  
  342 + def self.folder_types
  343 + ['Folder', 'Blog', 'Forum', 'Gallery']
  344 + end
  345 +
342 346 named_scope :published, :conditions => { :published => true }
343   - named_scope :folders, :conditions => { :type => ['Folder', 'Blog', 'Forum', 'Gallery'] }
  347 + named_scope :folders, :conditions => { :type => folder_types}
  348 + named_scope :no_folders, :conditions => ['type NOT IN (?)', folder_types]
344 349 named_scope :galleries, :conditions => { :type => 'Gallery' }
345 350 named_scope :images, :conditions => { :is_image => true }
346 351  
... ...
app/models/blog.rb
... ... @@ -2,6 +2,13 @@ class Blog &lt; Folder
2 2  
3 3 acts_as_having_posts
4 4  
  5 + #FIXME This should be used until there is a migration to fix all blogs that
  6 + # already have folders inside them
  7 + def posts_with_no_folders
  8 + posts_without_no_folders.no_folders
  9 + end
  10 + alias_method_chain :posts, :no_folders
  11 +
5 12 def self.short_description
6 13 _('Blog')
7 14 end
... ...
app/models/blog_archives_block.rb
... ... @@ -17,7 +17,7 @@ class BlogArchivesBlock &lt; Block
17 17 settings_items :blog_id, Integer
18 18  
19 19 def blog
20   - blog_id ? owner.blogs.find(blog_id) : owner.blog
  20 + blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog
21 21 end
22 22  
23 23 def content
... ...
app/models/change_password.rb
... ... @@ -68,6 +68,10 @@ class ChangePassword &lt; Task
68 68 user.force_change_password!(self.password, self.password_confirmation)
69 69 end
70 70  
  71 + def target_notification_description
  72 + _('%{requestor} wants to change its password.') % {:requestor => requestor.name}
  73 + end
  74 +
71 75 # overriding messages
72 76  
73 77 def task_cancelled_message
... ...
app/models/enterprise_activation.rb
... ... @@ -35,4 +35,8 @@ class EnterpriseActivation &lt; Task
35 35 {:type => :profile_image, :profile => requestor, :url => requestor.url}
36 36 end
37 37  
  38 + def target_notification_description
  39 + _('%{requestor} wants to activate enterprise %{enterprise}.') % {:requestor => requestor.name, :enterprise => enterprise.name}
  40 + end
  41 +
38 42 end
... ...
app/models/folder.rb
1 1 class Folder < Article
2 2  
  3 + validate :not_belong_to_blog
  4 +
  5 + def not_belong_to_blog
  6 + errors.add(:parent, "A folder should not belong to a blog.") if parent && parent.blog?
  7 + end
  8 +
3 9 acts_as_having_settings :field => :setting
4 10  
5 11 xss_terminate :only => [ :body ], :with => 'white_list', :on => 'validation'
... ...
app/models/invite_friend.rb
... ... @@ -23,6 +23,10 @@ class InviteFriend &lt; Invitation
23 23 {:type => :profile_image, :profile => requestor, :url => requestor.url}
24 24 end
25 25  
  26 + def target_notification_description
  27 + _('%{requestor} wants to be your friend.') % {:requestor => requestor.name}
  28 + end
  29 +
26 30 def permission
27 31 :manage_friends
28 32 end
... ...
app/models/invite_member.rb
... ... @@ -35,6 +35,10 @@ class InviteMember &lt; Invitation
35 35 {:type => :profile_image, :profile => community, :url => community.url}
36 36 end
37 37  
  38 + def target_notification_description
  39 + _('%{requestor} invited you to join %{community}.') % {:requestor => requestor.name, :community => community.name}
  40 + end
  41 +
38 42 def expanded_message
39 43 super.gsub /<community>/, community.name
40 44 end
... ...
app/models/qualifier.rb
... ... @@ -8,6 +8,8 @@ class Qualifier &lt; ActiveRecord::Base
8 8 validates_presence_of :environment_id
9 9 validates_presence_of :name
10 10  
  11 + has_many :product_qualifiers, :dependent => :destroy
  12 +
11 13 def <=>(b)
12 14 self.name.downcase.transliterate <=> b.name.downcase.transliterate
13 15 end
... ...
app/models/task_mailer.rb
... ... @@ -32,7 +32,7 @@ class TaskMailer &lt; ActionMailer::Base
32 32 recipients task.friend_email
33 33  
34 34 from self.class.generate_from(task)
35   - subject '[%s] %s' % [ task.requestor.environment.name, task.information ]
  35 + subject '[%s] %s' % [ task.requestor.environment.name, task.target_notification_description ]
36 36 body :message => msg
37 37 end
38 38  
... ... @@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base
52 52  
53 53 recipients task.requestor.notification_emails
54 54 from self.class.generate_from(task)
55   - subject '[%s] %s' % [task.requestor.environment.name, task.information]
  55 + subject '[%s] %s' % [task.requestor.environment.name, task.target_notification_description]
56 56 body :requestor => task.requestor.name,
57 57 :message => text,
58 58 :environment => task.requestor.environment.name,
... ...
app/views/profile_editor/header_footer.rhtml
... ... @@ -21,9 +21,9 @@
21 21 </div>
22 22 <% end %>
23 23 <h2><%= _('Content for header ') %></h2>
24   - <%= text_area_tag(:custom_header, @header, :style => 'width: 100%; height: 150px;') %>
  24 + <%= text_area_tag(:custom_header, @header, :style => 'width: 100%; height: 150px;', :class => 'mceEditor') %>
25 25 <h2><%= _('Content for footer') %></h2>
26   - <%= text_area_tag(:custom_footer, @footer, :style => 'width: 100%; height: 150px;') %>
  26 + <%= text_area_tag(:custom_footer, @footer, :style => 'width: 100%; height: 150px;', :class => 'mceEditor') %>
27 27 <% button_bar do %>
28 28 <%= submit_button(:save, _('Save')) %>
29 29 <%= button(:cancel, _('Cancel'), :action => 'index') %>
... ...
db/migrate/20110222211802_remove_action_tracker_records_with_nil_users.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class RemoveActionTrackerRecordsWithNilUsers < ActiveRecord::Migration
  2 + # This migration is a copy of 20110127174236_remove_action_tracker_record_with_nil_users.rb
  3 + def self.up
  4 + ActionTracker::Record.all.map {|record| record.destroy if record.user.nil?}
  5 + end
  6 +
  7 + def self.down
  8 + say "this migration can't be reverted"
  9 + end
  10 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20110221195242) do
  12 +ActiveRecord::Schema.define(:version => 20110222211802) do
13 13  
14 14 create_table "action_tracker", :force => true do |t|
15 15 t.integer "user_id"
... ...
debian/changelog
  1 +noosfero (0.28.6) unstable; urgency=low
  2 +
  3 + * Bugfixes Version release. (Closes: AI#1874 AI#1890 AI#1893 AI#1871 AI#1884 AI#1892 AI#1882 AI#1883 AI#1896 AI#1875 AI#1895 AI#1879)
  4 +
  5 + -- Joenio Costa <joenio@perl.org.br> Sun, 27 Feb 2011 23:56:51 -0300
  6 +
1 7 noosfero (0.28.5) unstable; urgency=low
2 8  
3 9 * Bugfixes Version release. (Closes: AI#1867 AI#1866 AI#1870 AI#1854 AI#1851 AI#1810 AI#1889 AI#1868 AI#1855 AI#1887)
... ...
lib/noosfero.rb
1 1 module Noosfero
2 2 PROJECT = 'noosfero'
3   - VERSION = '0.28.5'
  3 + VERSION = '0.28.6'
4 4  
5 5 def self.pattern_for_controllers_in_directory(dir)
6 6 disjunction = controllers_in_directory(dir).join('|')
... ...
public/stylesheets/application.css
... ... @@ -1314,8 +1314,8 @@ a.comment-picture {
1314 1314 }
1315 1315  
1316 1316 .comment-replies .comment-picture img {
1317   - width: 32px;
1318   - height: 32px;
  1317 + max-width: 32px;
  1318 + max-height: 32px;
1319 1319 }
1320 1320  
1321 1321 .article-comment .comment-replies .button-bar {
... ... @@ -2137,8 +2137,8 @@ input.disabled {
2137 2137  
2138 2138 .common-profile-list-block img {
2139 2139 border: none;
2140   - width: 50px;
2141   - height: 50px;
  2140 + max-width: 50px;
  2141 + max-height: 50px;
2142 2142 }
2143 2143  
2144 2144 .box-2 .common-profile-list-block span,
... ... @@ -4400,11 +4400,20 @@ h1#agenda-title {
4400 4400 padding: 0px;
4401 4401 list-style: none;
4402 4402 }
4403   -.controller-search #content .search-results-type-article li,
4404 4403 .controller-search #content .search-results-type-event li {
4405 4404 padding: 2px 0px 4px 0px;
4406 4405 }
4407 4406  
  4407 +.controller-search #content .search-results-type-article li {
  4408 + padding: 0px 0px 4px 20px;
  4409 + background-repeat: no-repeat;
  4410 + border-color: transparent;
  4411 +}
  4412 +
  4413 +.controller-search #content .search-results-type-article li:hover {
  4414 + background-color: transparent;
  4415 +}
  4416 +
4408 4417 .controller-search .search-results-type-article .item_meta,
4409 4418 .controller-search .search-results-type-event .item_meta {
4410 4419 font-size: 10px;
... ... @@ -5596,8 +5605,8 @@ h1#agenda-title {
5596 5605 padding: 1px;
5597 5606 border: 1px solid #ccc;
5598 5607 margin: 4px 3px 0 0;
5599   - width: 20px;
5600   - height: 20px;
  5608 + max-width: 20px;
  5609 + max-height: 20px;
5601 5610 }
5602 5611  
5603 5612 .profile-wall-image {
... ... @@ -5625,8 +5634,8 @@ h1#agenda-title {
5625 5634  
5626 5635 #profile-network .upload_image .profile-network-text span img,
5627 5636 #profile-activity .upload_image .profile-activity-text span img {
5628   - width: auto;
5629   - height: auto;
  5637 + max-width: none;
  5638 + max-height: none;
5630 5639 }
5631 5640  
5632 5641 #profile-network .upload_image .profile-network-text img,
... ...
test/factories.rb
... ... @@ -310,6 +310,8 @@ module Noosfero::Factory
310 310 { }
311 311 end
312 312  
  313 + alias :defaults_for_blog_archives_block :defaults_for_block
  314 +
313 315 ###############################################
314 316 # Task
315 317 ###############################################
... ... @@ -358,7 +360,9 @@ module Noosfero::Factory
358 360 # Certifier
359 361 ###############################################
360 362  
361   - alias :defaults_for_certifier :defaults_for_qualifier
  363 + def defaults_for_certifier
  364 + defaults_for_qualifier.merge({ :name => 'Certifier ' + factory_num_seq.to_s })
  365 + end
362 366  
363 367 ###############################################
364 368 # Scrap
... ...
test/functional/browse_controller_test.rb
... ... @@ -65,6 +65,25 @@ class BrowseControllerTest &lt; Test::Unit::TestCase
65 65 assert_tag :a, '', :attributes => {:class => 'next_page'}
66 66 end
67 67  
  68 + should 'not return nil results in the more_active people list' do
  69 + Profile.delete_all
  70 + p1 = fast_create(Person)
  71 + p2 = fast_create(Person)
  72 + p3 = fast_create(Person)
  73 + fast_create(Article, :profile_id => p1, :created_at => 1.day.ago)
  74 + fast_create(Article, :profile_id => p2, :created_at => 1.day.ago)
  75 + fast_create(Article, :profile_id => p2, :created_at => 1.day.ago)
  76 + fast_create(Article, :profile_id => p2, :created_at => 1.day.ago)
  77 + fast_create(Article, :profile_id => p3, :created_at => 1.day.ago)
  78 +
  79 + per_page = 1
  80 + @controller.stubs(:per_page).returns(per_page)
  81 +
  82 + get :people, :filter => 'more_active'
  83 +
  84 + assert_equal Person.count/per_page, assigns(:results).total_pages
  85 + end
  86 +
68 87 should 'list all people filter by more active' do
69 88 Person.delete_all
70 89 p1 = create(Person, :name => 'Testing person 1', :user_id => 1)
... ... @@ -160,6 +179,26 @@ class BrowseControllerTest &lt; Test::Unit::TestCase
160 179 assert_tag :a, '', :attributes => {:class => 'next_page'}
161 180 end
162 181  
  182 + should 'not return nil results in the more_active communities list' do
  183 + Profile.delete_all
  184 + c1 = fast_create(Community)
  185 + c2 = fast_create(Community)
  186 + c3 = fast_create(Community)
  187 + fast_create(Article, :profile_id => c1, :created_at => 1.day.ago)
  188 + fast_create(Article, :profile_id => c2, :created_at => 1.day.ago)
  189 + fast_create(Article, :profile_id => c2, :created_at => 1.day.ago)
  190 + fast_create(Article, :profile_id => c2, :created_at => 1.day.ago)
  191 + fast_create(Article, :profile_id => c3, :created_at => 1.day.ago)
  192 +
  193 + per_page = 1
  194 + @controller.stubs(:per_page).returns(per_page)
  195 +
  196 + get :communities, :filter => 'more_active'
  197 +
  198 + assert_equal Community.count/per_page, assigns(:results).total_pages
  199 + end
  200 +
  201 +
163 202 should 'list all communities filter by more active' do
164 203 c1 = create(Community, :name => 'Testing community 1')
165 204 c2 = create(Community, :name => 'Testing community 2')
... ...
test/functional/cms_controller_test.rb
... ... @@ -818,6 +818,15 @@ class CmsControllerTest &lt; Test::Unit::TestCase
818 818 assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/new?type=Forum"}
819 819 end
820 820  
  821 + should 'not offer folders if in a blog' do
  822 + blog = fast_create(Blog, :profile_id => profile.id)
  823 + get :new, :profile => profile.identifier, :parent_id => blog.id, :cms => true
  824 + types = assigns(:article_types).map {|t| t[:name]}
  825 + Article.folder_types.each do |type|
  826 + assert_not_includes types, type
  827 + end
  828 + end
  829 +
821 830 should 'offer to edit a blog' do
822 831 profile.articles << Blog.new(:name => 'blog test', :profile => profile)
823 832  
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -714,8 +714,8 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
714 714  
715 715 should 'add meta tag to rss feed on view post blog' do
716 716 login_as(profile.identifier)
717   - profile.articles << Blog.new(:name => 'Blog', :profile => profile)
718   - profile.blog.posts << TextileArticle.new(:name => 'first post', :parent => profile.blog, :profile => profile)
  717 + blog = Blog.create!(:name => 'Blog', :profile => profile)
  718 + TextileArticle.create!(:name => 'first post', :parent => blog, :profile => profile)
719 719 get :view_page, :profile => profile.identifier, :page => ['blog', 'first-post']
720 720 assert_tag :tag => 'link', :attributes => { :rel => 'alternate', :type => 'application/rss+xml', :title => 'Blog', :href => "http://#{environment.default_hostname}/testinguser/blog/feed" }
721 721 end
... ... @@ -1215,9 +1215,8 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
1215 1215 FastGettext.stubs(:locale).returns('es')
1216 1216 blog = fast_create(Blog, :profile_id => profile.id, :path => 'blog')
1217 1217 blog.stubs(:display_posts_in_current_language).returns(true)
1218   - en_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'en_article', :language => 'en')
1219   - es_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'es_article', :language => 'es', :translation_of_id => en_article)
1220   - blog.posts = [en_article, es_article]
  1218 + en_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'en_article', :language => 'en', :parent_id => blog.id)
  1219 + es_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'es_article', :language => 'es', :parent_id => blog.id, :translation_of_id => en_article)
1221 1220  
1222 1221 get :view_page, :profile => @profile.identifier, :page => blog.explode_path
1223 1222 assert_tag :div, :attributes => { :id => "post-#{es_article.id}" }
... ... @@ -1239,8 +1238,8 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
1239 1238 FastGettext.stubs(:locale).returns('es')
1240 1239 blog = fast_create(Blog, :profile_id => profile.id, :path => 'blog')
1241 1240 blog.stubs(:display_posts_in_current_language).returns(true)
1242   - en_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'en_article', :language => 'en')
1243   - es_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'es_article', :language => 'es', :translation_of_id => en_article)
  1241 + en_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'en_article', :language => 'en', :parent_id => blog.id)
  1242 + es_article = fast_create(TextileArticle, :profile_id => @profile.id, :path => 'es_article', :language => 'es', :parent_id => blog.id, :translation_of_id => en_article)
1244 1243 blog.posts = [en_article, es_article]
1245 1244  
1246 1245 get :view_page, :profile => @profile.identifier, :page => blog.explode_path
... ...
test/functional/profile_controller_test.rb
... ... @@ -482,9 +482,9 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
482 482  
483 483 should 'show number of published posts in index' do
484 484 profile.articles << blog = Blog.create(:name => 'Blog', :profile_id => profile.id)
485   - blog.posts << TextileArticle.new(:name => 'Published post', :parent => profile.blog, :profile => profile)
486   - blog.posts << TextileArticle.new(:name => 'Other published post', :parent => profile.blog, :profile => profile)
487   - blog.posts << TextileArticle.new(:name => 'Unpublished post', :parent => profile.blog, :profile => profile, :published => false)
  485 + fast_create(TextileArticle, :name => 'Published post', :parent_id => profile.blog.id, :profile_id => profile.id)
  486 + fast_create(TextileArticle, :name => 'Other published post', :parent_id => profile.blog.id, :profile_id => profile.id)
  487 + fast_create(TextileArticle, :name => 'Unpublished post', :parent_id => profile.blog.id, :profile_id => profile.id, :published => false)
488 488  
489 489 get :index, :profile => profile.identifier
490 490 assert_tag :tag => 'a', :content => '2 posts', :attributes => { :href => /\/testuser\/blog/ }
... ... @@ -1159,4 +1159,13 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
1159 1159 assert_tag :tag => 'div', :content => /#{plugin1_tab[:content]}/, :attributes => {:id => /#{plugin1_tab[:id]}/}
1160 1160 end
1161 1161  
  1162 + should 'redirect to profile page when try to request join_not_logged via GET method' do
  1163 + community = Community.create!(:name => 'my test community')
  1164 + login_as(profile.identifier)
  1165 + get :join_not_logged, :profile => community.identifier
  1166 + assert_nothing_raised do
  1167 + assert_redirected_to community.url
  1168 + end
  1169 + end
  1170 +
1162 1171 end
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -498,6 +498,12 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
498 498 assert_tag :tag => 'textarea', :content => 'my custom footer'
499 499 end
500 500  
  501 + should 'render TinyMce Editor for header and footer' do
  502 + get :header_footer, :profile => profile.identifier
  503 + assert_tag :tag => 'textarea', :attributes => { :id => 'custom_header', :class => 'mceEditor' }
  504 + assert_tag :tag => 'textarea', :attributes => { :id => 'custom_footer', :class => 'mceEditor' }
  505 + end
  506 +
501 507 should 'save footer and header' do
502 508 person = profile
503 509 post :header_footer, :profile => profile.identifier, :custom_header => 'new header', :custom_footer => 'new footer'
... ...
test/functional/tasks_controller_test.rb
... ... @@ -217,16 +217,18 @@ class TasksControllerTest &lt; Test::Unit::TestCase
217 217 assert_includes c_blog2.children(true), p_article
218 218 end
219 219  
220   - should 'raise error if there is an enterprise with the same identifier and keep the task active' do
  220 + should 'display error if there is an enterprise with the same identifier and keep the task active' do
221 221 e = Environment.default
222 222 e.add_admin(profile)
223 223 task = CreateEnterprise.create!(:name => "My Enterprise", :identifier => "my-enterprise", :requestor => profile, :target => e)
224 224 enterprise = fast_create(Enterprise, :name => "My Enterprise", :identifier => "my-enterprise")
225 225  
226   - assert_raise ActiveRecord::RecordInvalid do
227   - post :close, :tasks => {task.id => { :task => {:reject_explanation => "Bla bla"}, :decision => "cancel"}}
  226 + assert_nothing_raised do
  227 + post :close, :tasks => {task.id => {:decision => "finish"}}
228 228 end
229 229  
  230 + assert_match /Validation.failed/, @response.body
  231 +
230 232 task.reload
231 233 assert_equal Task::Status::ACTIVE, task.status
232 234 end
... ... @@ -280,4 +282,22 @@ class TasksControllerTest &lt; Test::Unit::TestCase
280 282 assert_equal 'new source', TinyMceArticle.find(:first).source_name
281 283 end
282 284  
  285 + should "not crash if accessing close without tasks parameter" do
  286 + assert_nothing_raised do
  287 + post :close
  288 + end
  289 + end
  290 +
  291 + should 'close create enterprise if trying to cancel even if there is already an existing identifier' do
  292 + identifier = "common-identifier"
  293 + task = CreateEnterprise.create!(:identifier => identifier, :name => identifier, :requestor => profile, :target => profile)
  294 + fast_create(Profile, :identifier => identifier)
  295 +
  296 + assert_nothing_raised do
  297 + post :close, :tasks => {task.id => {:task => {:reject_explanation => "Some explanation"}, :decision => 'cancel'}}
  298 + end
  299 +
  300 + task.reload
  301 + assert_equal Task::Status::CANCELLED, task.status
  302 + end
283 303 end
... ...
test/test_helper.rb
... ... @@ -189,7 +189,7 @@ end
189 189  
190 190 module NoosferoTestHelper
191 191 def link_to(content, url, options = {})
192   - "<a href='#{url.to_s}'>#{content}</a>"
  192 + "<a href='#{url.inspect}'>#{content}</a>"
193 193 end
194 194  
195 195 def content_tag(tag, content, options = {})
... ...
test/unit/approve_article_test.rb
... ... @@ -362,6 +362,14 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
362 362 assert_match(/#{task.requestor.name} wants to publish the article: #{article.name}/, email.subject)
363 363 end
364 364  
  365 + should 'deliver target finished message' do
  366 + task = ApproveArticle.new(:article => article, :target => community, :requestor => profile)
  367 +
  368 + email = TaskMailer.deliver_task_finished(task)
  369 +
  370 + assert_match(/#{task.requestor.name} wants to publish the article: #{article.name}/, email.subject)
  371 + end
  372 +
365 373 should 'approve an event' do
366 374 event = fast_create(Event, :profile_id => profile.id, :name => 'Event test', :slug => 'event-test', :abstract => 'Lead of article', :body => 'This is my event')
367 375 task = ApproveArticle.create!(:name => 'Event test', :article => event, :target => community, :requestor => profile)
... ...
test/unit/article_test.rb
... ... @@ -1444,4 +1444,34 @@ class ArticleTest &lt; Test::Unit::TestCase
1444 1444 assert !Article.new.tiny_mce?
1445 1445 end
1446 1446  
  1447 + should 'return only folders' do
  1448 + not_folders = [RssFeed, TinyMceArticle, Event, TextileArticle]
  1449 + folders = [Folder, Blog, Gallery, Forum]
  1450 +
  1451 + not_folders.each do |klass|
  1452 + item = fast_create(klass)
  1453 + assert_not_includes Article.folders, item
  1454 + end
  1455 +
  1456 + folders.each do |klass|
  1457 + item = fast_create(klass)
  1458 + assert_includes Article.folders, item
  1459 + end
  1460 + end
  1461 +
  1462 + should 'return no folders' do
  1463 + not_folders = [RssFeed, TinyMceArticle, Event, TextileArticle]
  1464 + folders = [Folder, Blog, Gallery, Forum]
  1465 +
  1466 + not_folders.each do |klass|
  1467 + item = fast_create(klass)
  1468 + assert_includes Article.no_folders, item
  1469 + end
  1470 +
  1471 + folders.each do |klass|
  1472 + item = fast_create(klass)
  1473 + assert_not_includes Article.no_folders, item
  1474 + end
  1475 + end
  1476 +
1447 1477 end
... ...
test/unit/blog_archives_block_test.rb
... ... @@ -134,4 +134,27 @@ class BlogArchivesBlockTest &lt; ActiveSupport::TestCase
134 134 assert_tag_in_string block.content, :tag => 'a', :content => 'January (2)', :attributes => {:href => /^http:\/\/.*\/flatline\/blog-one\?month=01&year=2008$/ }
135 135 end
136 136  
  137 + should 'not try to load a removed blog' do
  138 + block = fast_create(BlogArchivesBlock)
  139 + block.blog_id = profile.blog.id
  140 + block.save!
  141 + block.stubs(:owner).returns(profile)
  142 + profile.blog.destroy
  143 + assert_nothing_raised do
  144 + assert_nil block.blog
  145 + end
  146 + end
  147 +
  148 + should 'load next blog if configured blog was removed' do
  149 + other_blog = fast_create(Blog, :profile_id => profile.id)
  150 + block = fast_create(BlogArchivesBlock)
  151 + block.blog_id = profile.blog.id
  152 + block.save!
  153 + block.stubs(:owner).returns(profile)
  154 + profile.blog.destroy
  155 + assert_nothing_raised do
  156 + assert_equal other_blog, block.blog
  157 + end
  158 + end
  159 +
137 160 end
... ...
test/unit/blog_test.rb
... ... @@ -195,4 +195,15 @@ class BlogTest &lt; ActiveSupport::TestCase
195 195 assert !blog.reload.display_posts_in_current_language?
196 196 end
197 197  
  198 + #FIXME This should be used until there is a migration to fix all blogs that
  199 + # already have folders inside them
  200 + should 'not list folders in posts' do
  201 + blog = fast_create(Blog)
  202 + folder = fast_create(Folder, :parent_id => blog.id)
  203 + article = fast_create(TextileArticle, :parent_id => blog.id)
  204 +
  205 + assert_not_includes blog.posts, folder
  206 + assert_includes blog.posts, article
  207 + end
  208 +
198 209 end
... ...
test/unit/change_password_test.rb
... ... @@ -132,4 +132,21 @@ class ChangePasswordTest &lt; Test::Unit::TestCase
132 132 assert_equal c2.requestor, p2
133 133 end
134 134  
  135 + should 'have target notification description' do
  136 + person = fast_create(Person, :identifier => 'testuser')
  137 +
  138 + change = ChangePassword.create(:login => 'testuser', :email => 'test@example.com', :environment_id => Environment.default.id)
  139 +
  140 + assert_match(/#{change.requestor.name} wants to change its password/, change.target_notification_description)
  141 + end
  142 +
  143 + should 'deliver task created message' do
  144 + person = fast_create(Person, :identifier => 'testuser')
  145 +
  146 + task = ChangePassword.create(:login => 'testuser', :email => 'test@example.com', :environment_id => Environment.default.id)
  147 +
  148 + email = TaskMailer.deliver_task_created(task)
  149 + assert_match(/#{task.requestor.name} wants to change its password/, email.subject)
  150 + end
  151 +
135 152 end
... ...
test/unit/email_activation_test.rb
... ... @@ -49,4 +49,13 @@ class EmailActivationTest &lt; Test::Unit::TestCase
49 49 assert !anothertask.save
50 50 end
51 51  
  52 + should 'deliver activation email notification' do
  53 + user = create_user('testuser', :environment_id => Environment.default.id)
  54 +
  55 + task = EmailActivation.new(:requestor => user.person, :target => Environment.default)
  56 +
  57 + email = User::Mailer.deliver_activation_email_notify(user)
  58 + assert_match(/Welcome to #{task.requestor.environment.name} mail!/, email.subject)
  59 + end
  60 +
52 61 end
... ...
test/unit/enterprise_activation_test.rb
... ... @@ -64,5 +64,12 @@ class EnterpriseActivationTest &lt; ActiveSupport::TestCase
64 64 t.finish
65 65 end
66 66  
  67 + should 'have target notification description' do
  68 + ent = fast_create(Enterprise, :enabled => false)
  69 + task = EnterpriseActivation.create!(:enterprise => ent, :requestor => profiles(:ze))
  70 +
  71 + assert_match(/#{task.requestor.name} wants to activate enterprise #{ent.name}/, task.target_notification_description)
  72 + end
  73 +
67 74 end
68 75  
... ...
test/unit/folder_test.rb
... ... @@ -132,4 +132,12 @@ class FolderTest &lt; ActiveSupport::TestCase
132 132 assert_no_match /[<>]/, folder.body
133 133 end
134 134  
  135 + should 'not have a blog as parent' do
  136 + folder = Folder.new
  137 + folder.parent = Blog.new
  138 + folder.valid?
  139 +
  140 + assert folder.errors.on(:parent)
  141 + end
  142 +
135 143 end
... ...
test/unit/invite_friend_test.rb
... ... @@ -120,4 +120,22 @@ class InviteFriendTest &lt; ActiveSupport::TestCase
120 120 assert !task2.save
121 121 end
122 122  
  123 + should 'have target notification description' do
  124 + person = create_user('testuser1').person
  125 +
  126 + task = InviteFriend.create!(:person => person, :friend_email => 'test@test.com', :message => '<url>')
  127 +
  128 + assert_match(/#{task.requestor.name} wants to be your friend./, task.target_notification_description)
  129 + end
  130 +
  131 + should 'deliver invitation notification' do
  132 + person = create_user('testuser1').person
  133 +
  134 + task = InviteFriend.create!(:person => person, :friend_email => 'test@test.com', :message => '<url>')
  135 +
  136 + email = TaskMailer.deliver_invitation_notification(task)
  137 +
  138 + assert_match(/#{task.requestor.name} wants to be your friend./, email.subject)
  139 + end
  140 +
123 141 end
... ...
test/unit/invite_member_test.rb
... ... @@ -95,5 +95,25 @@ class InviteMemberTest &lt; ActiveSupport::TestCase
95 95 assert !task2.save
96 96 end
97 97  
  98 + should 'have target notification description' do
  99 + p = create_user('testuser1').person
  100 + community = fast_create(Community)
  101 +
  102 + task = InviteMember.create!(:person => p, :friend_email => 'test@test.com', :message => '<url>', :community_id => community.id)
  103 +
  104 + assert_match(/#{task.requestor.name} invited you to join #{community.name}/, task.target_notification_description)
  105 + end
  106 +
  107 + should 'deliver invitation notification' do
  108 + person = create_user('testuser1').person
  109 + community = fast_create(Community)
  110 +
  111 + task = InviteMember.create!(:person => person, :friend_email => 'test@test.com', :message => '<url>', :community_id => community.id)
  112 +
  113 + email = TaskMailer.deliver_invitation_notification(task)
  114 +
  115 + assert_match(/#{task.requestor.name} invited you to join #{community.name}/, email.subject)
  116 + end
  117 +
98 118 end
99 119  
... ...
test/unit/manage_products_helper_test.rb
... ... @@ -167,6 +167,38 @@ class ManageProductsHelperTest &lt; Test::Unit::TestCase
167 167 assert_equal ["Self declared", "Colivre", "FBES"], result.map{|i| i[0]}
168 168 end
169 169  
  170 + should 'list qualifiers and certifiers of a product' do
  171 + product = fast_create(Product)
  172 + qualifier = fast_create(Qualifier)
  173 + certifier = fast_create(Certifier)
  174 + ProductQualifier.create!(:product => product, :qualifier => qualifier, :certifier => certifier)
  175 + assert_match /✔ Qualifier \d+ certified by Certifier \d+/, display_qualifiers(product)
  176 + end
  177 +
  178 + should 'product survive to a Qualifier deletation' do
  179 + product = fast_create(Product)
  180 + qualifier = fast_create(Qualifier)
  181 + certifier = fast_create(Certifier)
  182 + ProductQualifier.create!(:product => product, :qualifier => qualifier, :certifier => certifier)
  183 + qualifier.destroy
  184 + assert_nothing_raised do
  185 + assert_no_match /✔ Qualifier \d+ certified by Certifier \d+/, display_qualifiers(product)
  186 + end
  187 + end
  188 +
  189 + should 'product consider its Qualifier self-declared when Certifier is deleted' do
  190 + product = fast_create(Product)
  191 + qualifier = fast_create(Qualifier)
  192 + certifier = fast_create(Certifier)
  193 + ProductQualifier.create!(:product => product, :qualifier => qualifier, :certifier => certifier)
  194 + certifier.destroy
  195 + assert_nothing_raised do
  196 + result = display_qualifiers(product)
  197 + assert_match /✔ Qualifier \d+ \(Self declared\)/, result
  198 + assert_no_match /certified by Certifier \d+/, result
  199 + end
  200 + end
  201 +
170 202 protected
171 203 include NoosferoTestHelper
172 204 include ActionView::Helpers::TextHelper
... ...
test/unit/qualifier_test.rb
... ... @@ -49,4 +49,16 @@ class QualifierTest &lt; Test::Unit::TestCase
49 49 assert_equal [first, last], Qualifier.all.sort
50 50 end
51 51  
  52 + should 'clean all ProductQualifier when destroy a Qualifier' do
  53 + product1 = fast_create(Product)
  54 + product2 = fast_create(Product)
  55 + qualifier = fast_create(Qualifier, :name => 'Free Software')
  56 + certifier = fast_create(Certifier, :name => 'FSF')
  57 + ProductQualifier.create!(:product => product1, :qualifier => qualifier, :certifier => certifier)
  58 + ProductQualifier.create!(:product => product2, :qualifier => qualifier, :certifier => certifier)
  59 + assert_equal [['Free Software', 'FSF']], product1.product_qualifiers.map{|i| [i.qualifier.name, i.certifier.name]}
  60 + Qualifier.destroy_all
  61 + assert_equal [], product1.product_qualifiers(true)
  62 + end
  63 +
52 64 end
... ...
test/unit/rss_feed_test.rb
... ... @@ -212,7 +212,10 @@ class RssFeedTest &lt; Test::Unit::TestCase
212 212 a = ApproveArticle.create!(:name => 'test name', :article => article, :target => profile, :requestor => fast_create(Person))
213 213 a.finish
214 214  
215   - blog.posts << published_article = article.class.last
  215 + published_article = article.class.last
  216 + published_article.parent = blog
  217 + published_article.save
  218 +
216 219 feed = RssFeed.new(:parent => blog, :profile => profile)
217 220  
218 221 assert_match "This is the content of the Sample Article", feed.data
... ...
test/unit/search_helper_test.rb
... ... @@ -10,25 +10,20 @@ class SearchHelperTest &lt; Test::Unit::TestCase
10 10  
11 11 def setup
12 12 @profile = mock
  13 + self.stubs(:profile_image).returns('profileimage.png')
  14 + self.stubs(:url_for).returns('link to profile')
  15 + profile.stubs(:name).returns('Name of Profile')
  16 + profile.stubs(:url).returns('')
  17 + profile.stubs(:products).returns([Product.new(:name => 'product test')])
  18 + profile.stubs(:identifier).returns('name-of-profile')
  19 + profile.stubs(:region).returns(Region.new(:name => 'Brazil'))
13 20 end
14 21 attr_reader :profile
15 22  
16   - include ActionView::Helpers::FormOptionsHelper
17   - include ActionView::Helpers::FormTagHelper
18   - include ActionView::Helpers::TagHelper
19 23 should 'display profile info' do
20   - profile.stubs(:name).returns('Name of Profile')
21 24 profile.stubs(:address).returns('Address of Profile')
22 25 profile.stubs(:contact_email).returns('Email of Profile')
23 26 profile.stubs(:contact_phone).returns('Phone of Profile')
24   - profile.stubs(:url).returns('')
25   - profile.stubs(:products).returns([Product.new(:name => 'product test')])
26   - profile.stubs(:identifier).returns('name-of-profile')
27   - profile.stubs(:region).returns(Region.new(:name => 'Brazil'))
28   -
29   - self.stubs(:profile_image).returns('profileimage.png')
30   - self.stubs(:url_for).returns('merda')
31   - self.stubs(:link_to).returns('link to profile')
32 27  
33 28 result = self.display_profile_info(profile)
34 29 assert_match /profileimage.png/, result
... ... @@ -39,18 +34,9 @@ class SearchHelperTest &lt; Test::Unit::TestCase
39 34 end
40 35  
41 36 should 'not display field if nil in profile info' do
42   - profile.stubs(:name).returns('Name of Profile')
43 37 profile.stubs(:address).returns('nil')
44 38 profile.stubs(:contact_email).returns('nil')
45 39 profile.stubs(:contact_phone).returns('nil')
46   - profile.stubs(:url).returns('')
47   - profile.stubs(:products).returns([Product.new(:name => 'product test')])
48   - profile.stubs(:identifier).returns('name-of-profile')
49   - profile.stubs(:region).returns(Region.new(:name => 'Brazil'))
50   -
51   - self.stubs(:profile_image).returns('profileimage.png')
52   - self.stubs(:url_for).returns('merda')
53   - self.stubs(:link_to).returns('link to profile')
54 40  
55 41 result = self.display_profile_info(profile)
56 42 assert_match /profileimage.png/, result
... ... @@ -60,4 +46,16 @@ class SearchHelperTest &lt; Test::Unit::TestCase
60 46 assert_no_match /Address of Profile/, result
61 47 end
62 48  
  49 + should 'link to products and services of an profile' do
  50 + enterprise = fast_create(Enterprise)
  51 + product1 = fast_create(Product, :enterprise_id => enterprise.id)
  52 + product2 = fast_create(Product, :enterprise_id => enterprise.id)
  53 + result = display_profile_info(enterprise)
  54 + assert_tag_in_string result, :tag => 'a', :attributes => {:href => /:id=>#{product1.id}/}, :content => product1.name
  55 + assert_tag_in_string result, :tag => 'a', :attributes => {:href => /:id=>#{product2.id}/}, :content => product2.name
  56 + end
  57 +
  58 + protected
  59 + include NoosferoTestHelper
  60 +
63 61 end
... ...
test/unit/task_mailer_test.rb
... ... @@ -17,7 +17,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
17 17  
18 18 task = Task.new
19 19 task.expects(:task_finished_message).returns('the message')
20   - task.expects(:information).returns('the task')
  20 + task.expects(:target_notification_description).returns('the task')
21 21  
22 22 requestor = mock()
23 23 requestor.expects(:notification_emails).returns(['requestor@example.com'])
... ... @@ -40,7 +40,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
40 40  
41 41 task = Task.new
42 42 task.expects(:task_cancelled_message).returns('the message')
43   - task.expects(:information).returns('the task')
  43 + task.expects(:target_notification_description).returns('the task')
44 44  
45 45 requestor = mock()
46 46 requestor.expects(:notification_emails).returns(['requestor@example.com'])
... ... @@ -64,7 +64,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
64 64 task = Task.new
65 65  
66 66 task.expects(:task_created_message).returns('the message')
67   - task.expects(:information).returns('the task')
  67 + task.expects(:target_notification_description).returns('the task')
68 68  
69 69 requestor = mock()
70 70 requestor.expects(:notification_emails).returns(['requestor@example.com'])
... ... @@ -129,6 +129,8 @@ class TaskMailerTest &lt; Test::Unit::TestCase
129 129  
130 130 mail = TaskMailer.create_invitation_notification(task)
131 131  
  132 + assert_match(/#{task.target_notification_description}/, mail.subject)
  133 +
132 134 assert_equal "Hello friend name, my name invite you, please follow this link: http://example.com/account/signup?invitation_code=123456", mail.body
133 135  
134 136 TaskMailer.deliver(mail)
... ...
vendor/plugins/action_tracker/lib/action_tracker_model.rb
... ... @@ -12,6 +12,11 @@ module ActionTracker
12 12  
13 13 validates_presence_of :verb
14 14 validates_presence_of :user
  15 + validate :user_existence
  16 +
  17 + def user_existence
  18 + errors.add(:user, "user doesn't exists") if user && !user.class.exists?(user)
  19 + end
15 20  
16 21 alias_method :subject, :user
17 22  
... ...
vendor/plugins/action_tracker/test/action_tracker_model_test.rb
... ... @@ -67,9 +67,32 @@ class ActionTrackerModelTest &lt; ActiveSupport::TestCase
67 67 end
68 68 end
69 69  
  70 + def test_user_is_mandatory
  71 + ta = ActionTracker::Record.new :user_type => 'SomeModel', :verb => :some_verb
  72 + ta.valid?
  73 + assert ta.errors.on(:user)
  74 + assert_raise ActiveRecord::RecordInvalid do
  75 + ta.save!
  76 + end
  77 +
  78 + ta = ActionTracker::Record.new :user_id => 2, :verb => :some_verb
  79 + ta.valid?
  80 + assert ta.errors.on(:user)
  81 + assert_raise ActiveRecord::RecordInvalid do
  82 + ta.save!
  83 + end
  84 + end
  85 +
70 86 def test_user_exists_indeed
71   - ta = ActionTracker::Record.new(:user_id => -1, :user_type => "SomeModel", :verb => :some_verb)
72   - assert !ta.valid?
  87 + ta = ActionTracker::Record.new(:verb => :some_verb)
  88 + ta.valid?
  89 + assert ta.errors.on(:user)
  90 + user = SomeModel.create!
  91 + ta.user = user
  92 + assert ta.valid?
  93 + user.destroy
  94 + ta.valid?
  95 + assert ta.errors.on(:user)
73 96 end
74 97  
75 98 def test_verb_must_be_declared_previously
... ... @@ -333,24 +356,4 @@ class ActionTrackerModelTest &lt; ActiveSupport::TestCase
333 356 assert_equal(["foo 1", "bar 2"], t.collect_group_with_index(:test){|x, i| "#{x} #{i+1}" })
334 357 end
335 358  
336   - def test_user_id_is_mandatory
337   - ActionTrackerConfig.verbs = { :some => { :description => "Some" } }
338   - ta = ActionTracker::Record.new :user_type => 'SomeModel', :verb => :some
339   - ta.valid?
340   - assert ta.errors.on(:user_id)
341   - assert_raise ActiveRecord::RecordInvalid do
342   - ta.save!
343   - end
344   - end
345   -
346   - def test_user_type_is_mandatory
347   - ActionTrackerConfig.verbs = { :some => { :description => "Some" } }
348   - ta = ActionTracker::Record.new :user_id => 2, :verb => :some
349   - ta.valid?
350   - assert ta.errors.on(:user_type)
351   - assert_raise ActiveRecord::RecordInvalid do
352   - ta.save!
353   - end
354   - end
355   -
356 359 end
... ...