Commit 6e10728cbf0394dfdab909beb8f9cba71a8bf7c9

Authored by Rodrigo Souto
2 parents 67fdc2f1 ca78d2e2

Merge branch 'stable'

Conflicts:
	app/views/themes/index.rhtml
	db/schema.rb
	plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb
	test/unit/person_test.rb
Showing 75 changed files with 665 additions and 233 deletions   Show diff stats
app/helpers/cache_counter_helper.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +module CacheCounterHelper
  2 + def update_cache_counter(name, object, value)
  3 + if object.present?
  4 + object.class.update_counters(object.id, name => value)
  5 + end
  6 + end
  7 +end
... ...
app/helpers/comment_helper.rb
... ... @@ -2,7 +2,6 @@ module CommentHelper
2 2  
3 3 def article_title(article, args = {})
4 4 title = article.title
5   - title = article.display_title if article.kind_of?(UploadedFile) && article.image?
6 5 title = content_tag('h1', h(title), :class => 'title')
7 6 if article.belongs_to_blog?
8 7 unless args[:no_link]
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -14,8 +14,7 @@ module ContentViewerHelper
14 14 end
15 15  
16 16 def article_title(article, args = {})
17   - title = article.display_title if article.kind_of?(UploadedFile) && article.image?
18   - title = article.title if title.blank?
  17 + title = article.title
19 18 title = content_tag('h1', h(title), :class => 'title')
20 19 if article.belongs_to_blog? || article.belongs_to_forum?
21 20 unless args[:no_link]
... ...
app/models/comment.rb
... ... @@ -172,7 +172,7 @@ class Comment < ActiveRecord::Base
172 172 def mail(comment)
173 173 profile = comment.article.profile
174 174 recipients comment.notification_emails
175   - from "#{profile.environment.name} <#{profile.environment.contact_email}>"
  175 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
176 176 subject _("[%s] you got a new comment!") % [profile.environment.name]
177 177 body :recipient => profile.nickname || profile.name,
178 178 :sender => comment.author_name,
... ... @@ -187,7 +187,7 @@ class Comment &lt; ActiveRecord::Base
187 187 def mail_to_followers(comment, emails)
188 188 profile = comment.article.profile
189 189 bcc emails
190   - from "#{profile.environment.name} <#{profile.environment.contact_email}>"
  190 + from "#{profile.environment.name} <#{profile.environment.noreply_email}>"
191 191 subject _("[%s] %s commented on a content of %s") % [profile.environment.name, comment.author_name, profile.short_name]
192 192 body :recipient => profile.nickname || profile.name,
193 193 :sender => comment.author_name,
... ...
app/models/contact.rb
... ... @@ -26,7 +26,7 @@ class Contact &lt; ActiveRecord::Base #WithoutTable
26 26 content_type 'text/html'
27 27 emails = contact.dest.notification_emails
28 28 recipients emails
29   - from "#{contact.name} <#{contact.dest.environment.contact_email}>"
  29 + from "#{contact.name} <#{contact.dest.environment.noreply_email}>"
30 30 reply_to contact.email
31 31 if contact.sender
32 32 headers 'X-Noosfero-Sender' => contact.sender.identifier
... ...
app/models/environment.rb
... ... @@ -606,7 +606,7 @@ class Environment &lt; ActiveRecord::Base
606 606 # only one environment can be the default one
607 607 validates_uniqueness_of :is_default, :if => (lambda do |environment| environment.is_default? end), :message => N_('Only one Virtual Community can be the default one')
608 608  
609   - validates_format_of :contact_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda { |record| ! record.contact_email.blank? })
  609 + validates_format_of :contact_email, :noreply_email, :with => Noosfero::Constants::EMAIL_FORMAT, :allow_blank => true
610 610  
611 611 xss_terminate :only => [ :message_for_disabled_enterprise ], :with => 'white_list', :on => 'validation'
612 612  
... ... @@ -793,7 +793,7 @@ class Environment &lt; ActiveRecord::Base
793 793 end
794 794  
795 795 def notification_emails
796   - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email)
  796 + [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email)
797 797 end
798 798  
799 799 after_create :create_templates
... ...
app/models/friendship.rb
1 1 class Friendship < ActiveRecord::Base
2 2 track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person
3   -
  3 +
  4 + extend CacheCounterHelper
  5 +
4 6 belongs_to :person, :foreign_key => :person_id
5 7 belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id'
  8 +
  9 + after_create do |friendship|
  10 + update_cache_counter(:friends_count, friendship.person, 1)
  11 + update_cache_counter(:friends_count, friendship.friend, 1)
  12 + end
  13 +
  14 + after_destroy do |friendship|
  15 + update_cache_counter(:friends_count, friendship.person, -1)
  16 + update_cache_counter(:friends_count, friendship.friend, -1)
  17 + end
6 18 end
... ...
app/models/layout_template.rb
... ... @@ -16,15 +16,15 @@ class LayoutTemplate
16 16 end
17 17  
18 18 def name
19   - @config['name']
  19 + _ @config['name']
20 20 end
21 21  
22 22 def title
23   - @config['title']
  23 + _ @config['title']
24 24 end
25 25  
26 26 def description
27   - @config['description']
  27 + _ @config['description']
28 28 end
29 29  
30 30 def number_of_boxes
... ...
app/models/mailing.rb
... ... @@ -17,7 +17,7 @@ class Mailing &lt; ActiveRecord::Base
17 17 end
18 18  
19 19 def generate_from
20   - "#{source.name} <#{source.contact_email}>"
  20 + "#{source.name} <#{if source.is_a? Environment then source.noreply_email else source.contact_email end}>"
21 21 end
22 22  
23 23 def generate_subject
... ...
app/models/organization.rb
... ... @@ -26,18 +26,7 @@ class Organization &lt; Profile
26 26  
27 27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source'
28 28  
29   - named_scope :more_popular,
30   - :select => "#{Profile.qualified_column_names}, count(resource_id) as total",
31   - :group => Profile.qualified_column_names,
32   - :joins => "LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id",
33   - :order => "total DESC"
34   -
35   - named_scope :more_active,
36   - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",
37   - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id",
38   - :group => Profile.qualified_column_names,
39   - :order => 'total DESC',
40   - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago]
  29 + named_scope :more_popular, :order => 'members_count DESC'
41 30  
42 31 def validation_methodology
43 32 self.validation_info ? self.validation_info.validation_methodology : nil
... ...
app/models/organization_mailing.rb
1 1 class OrganizationMailing < Mailing
2 2  
3 3 def generate_from
4   - "#{person.name} <#{source.environment.contact_email}>"
  4 + "#{person.name} <#{source.environment.noreply_email}>"
5 5 end
6 6  
7 7 def recipients(offset=0, limit=100)
... ...
app/models/pending_task_notifier.rb
... ... @@ -2,7 +2,7 @@ class PendingTaskNotifier &lt; ActionMailer::Base
2 2  
3 3 def notification(person)
4 4 recipients person.email
5   - from "#{person.environment.name} <#{person.environment.contact_email}>"
  5 + from "#{person.environment.name} <#{person.environment.noreply_email}>"
6 6 subject _("[%s] Pending tasks") % person.environment.name
7 7 body :person => person,
8 8 :tasks => person.tasks.pending,
... ...
app/models/person.rb
... ... @@ -71,18 +71,7 @@ class Person &lt; Profile
71 71 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
72 72 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
73 73  
74   - named_scope :more_popular,
75   - :select => "#{Profile.qualified_column_names}, count(friend_id) as total",
76   - :group => Profile.qualified_column_names,
77   - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id",
78   - :order => "total DESC"
79   -
80   - named_scope :more_active,
81   - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",
82   - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id",
83   - :group => Profile.qualified_column_names,
84   - :order => 'total DESC',
85   - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago]
  74 + named_scope :more_popular, :order => 'friends_count DESC'
86 75  
87 76 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*'
88 77 named_scope :non_abusers, :joins => "LEFT JOIN tasks ON profiles.id = tasks.requestor_id AND tasks.type='AbuseComplaint'", :conditions => ["tasks.status != 3 OR tasks.id is NULL"], :select => "DISTINCT profiles.*"
... ...
app/models/profile.rb
... ... @@ -92,10 +92,6 @@ class Profile &lt; ActiveRecord::Base
92 92 members.order(:name)
93 93 end
94 94  
95   - def members_count
96   - members.count
97   - end
98   -
99 95 class << self
100 96 def count_with_distinct(*args)
101 97 options = args.last || {}
... ... @@ -118,10 +114,11 @@ class Profile &lt; ActiveRecord::Base
118 114  
119 115 named_scope :visible, :conditions => { :visible => true }
120 116 named_scope :public, :conditions => { :visible => true, :public_profile => true }
121   - # Subclasses must override these methods
  117 +
  118 + # Subclasses must override this method
122 119 named_scope :more_popular
123   - named_scope :more_active
124 120  
  121 + named_scope :more_active, :order => 'activities_count DESC'
125 122 named_scope :more_recent, :order => "created_at DESC"
126 123  
127 124 acts_as_trackable :dependent => :destroy
... ... @@ -616,10 +613,10 @@ private :generate_url, :url_options
616 613 # Adds a person as member of this Profile.
617 614 def add_member(person)
618 615 if self.has_members?
619   - if self.closed? && members_count > 0
  616 + if self.closed? && members.count > 0
620 617 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
621 618 else
622   - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0
  619 + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0
623 620 self.affiliate(person, Profile::Roles.member(environment.id))
624 621 end
625 622 else
... ...
app/models/scrap.rb
... ... @@ -14,7 +14,7 @@ class Scrap &lt; ActiveRecord::Base
14 14  
15 15 named_scope :not_replies, :conditions => {:scrap_id => nil}
16 16  
17   - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target
  17 + track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target
18 18  
19 19 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver}
20 20  
... ... @@ -59,7 +59,7 @@ class Scrap &lt; ActiveRecord::Base
59 59 sender, receiver = scrap.sender, scrap.receiver
60 60 recipients receiver.email
61 61  
62   - from "#{sender.environment.name} <#{sender.environment.contact_email}>"
  62 + from "#{sender.environment.name} <#{sender.environment.noreply_email}>"
63 63 subject _("[%s] You received a scrap!") % [sender.environment.name]
64 64 body :recipient => receiver.name,
65 65 :sender => sender.name,
... ...
app/models/task_mailer.rb
... ... @@ -60,7 +60,7 @@ class TaskMailer &lt; ActionMailer::Base
60 60 end
61 61  
62 62 def self.generate_from(task)
63   - "#{task.environment.name} <#{task.environment.contact_email}>"
  63 + "#{task.environment.name} <#{task.environment.noreply_email}>"
64 64 end
65 65  
66 66 def generate_environment_url(task, url = {})
... ...
app/models/theme.rb
... ... @@ -42,17 +42,25 @@ class Theme
42 42 end
43 43  
44 44 def approved_themes(owner)
45   - Dir.glob(File.join(system_themes_dir, '*')).select do |item|
46   - if File.exists?( File.join(item, 'theme.yml') )
47   - config = YAML.load_file(File.join(item, 'theme.yml'))
48   - (config['owner_type'] == owner.class.base_class.name) &&
49   - (config['owner_id'] == owner.id) || config['public']
  45 + Dir.glob(File.join(system_themes_dir, '*')).map do |item|
  46 + next unless File.exists? File.join(item, 'theme.yml')
  47 + id = File.basename item
  48 + config = YAML.load_file File.join(item, 'theme.yml')
  49 +
  50 + approved = config['public']
  51 + unless approved
  52 + begin
  53 + approved = owner.kind_of?(config['owner_type'].constantize)
  54 + rescue
  55 + end
  56 + approved &&= config['owner_id'] == owner.id if config['owner_id'].present?
50 57 end
51   - end.map do |desc|
52   - new(File.basename(desc))
  58 +
  59 + [id, config] if approved
  60 + end.compact.map do |id, config|
  61 + new id, config
53 62 end
54 63 end
55   -
56 64 end
57 65  
58 66 class DuplicatedIdentifier < Exception; end
... ...
app/models/uploaded_file.rb
... ... @@ -12,15 +12,12 @@ class UploadedFile &lt; Article
12 12  
13 13 include ShortFilename
14 14  
15   - settings_items :title, :type => 'string'
16   - xss_terminate :only => [ :title ]
17   -
18   - def title_with_default
19   - title_without_default || short_filename(name, 60)
  15 + def title
  16 + if self.name.present? then self.name else self.filename end
  17 + end
  18 + def title= value
  19 + self.name = value
20 20 end
21   - alias_method_chain :title, :default
22   -
23   - validates_size_of :title, :maximum => 60, :if => (lambda { |file| !file.title.blank? })
24 21  
25 22 sanitize_filename
26 23  
... ... @@ -32,10 +29,6 @@ class UploadedFile &lt; Article
32 29 self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil
33 30 end
34 31  
35   - def display_title
36   - title.blank? ? name : title
37   - end
38   -
39 32 def first_paragraph
40 33 ''
41 34 end
... ... @@ -109,7 +102,7 @@ class UploadedFile &lt; Article
109 102 alias :orig_set_filename :filename=
110 103 def filename=(value)
111 104 orig_set_filename(value)
112   - self.name = self.filename
  105 + self.name ||= self.filename
113 106 end
114 107  
115 108 def download_headers
... ...
app/models/user.rb
... ... @@ -54,7 +54,7 @@ class User &lt; ActiveRecord::Base
54 54 def activation_email_notify(user)
55 55 user_email = "#{user.login}@#{user.email_domain}"
56 56 recipients user_email
57   - from "#{user.environment.name} <#{user.environment.contact_email}>"
  57 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
58 58 subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name }
59 59 body :name => user.name,
60 60 :email => user_email,
... ... @@ -66,7 +66,7 @@ class User &lt; ActiveRecord::Base
66 66 def activation_code(user)
67 67 recipients user.email
68 68  
69   - from "#{user.environment.name} <#{user.environment.contact_email}>"
  69 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
70 70 subject _("[%s] Activate your account") % [user.environment.name]
71 71 body :recipient => user.name,
72 72 :activation_code => user.activation_code,
... ... @@ -82,7 +82,7 @@ class User &lt; ActiveRecord::Base
82 82 content_type 'text/html'
83 83 recipients user.email
84 84  
85   - from "#{user.environment.name} <#{user.environment.contact_email}>"
  85 + from "#{user.environment.name} <#{user.environment.noreply_email}>"
86 86 subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject
87 87 body email_body
88 88 end
... ...
app/views/admin_panel/_site_info.rhtml
1 1 <%= required labelled_form_field(_('Site name'), text_field(:environment, :name)) %>
2 2 <%= labelled_form_field(_('Contact email'), text_field(:environment, :contact_email)) %>
  3 +<%= labelled_form_field(_('No reply email'), text_field(:environment, :noreply_email)) %>
3 4 <% themes_options = Theme.system_themes.map {|theme| [theme.name, theme.id] }.sort %>
4 5 <%= labelled_form_field(_('Theme'), select(:environment, :theme, options_for_select(themes_options, environment.theme))) %>
5 6 <%= required f.text_field(:reports_lower_bound, :size => 3) %>
... ...
app/views/blocks/profile_image.rhtml
1 1 <div class="vcard">
2 2  
3   -<p><%= block.title %></p>
  3 +<% if block.title.present? %>
  4 + <p><%= block.title %></p>
  5 +<% end %>
4 6  
5 7 <div class="profile-big-image">
6 8 <div class="profile-big-image-inner1">
... ...
app/views/themes/_select_template.rhtml
... ... @@ -12,7 +12,7 @@
12 12 "/designs/templates/#{template.id}/thumbnail.png",
13 13 :alt => _('The "%s" template')) +
14 14 '<div class="opt-info">'.html_safe +
15   - content_tag('strong', template.name, :class => 'name') +
  15 + content_tag('strong', template.name, :title => template.title, :class => 'name') +
16 16 ' <br/> '.html_safe
17 17  
18 18 if @current_template == template.id # selected
... ...
config/initializers/activities_counter_cache.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +job = Delayed::Backend::ActiveRecord::Job.all :conditions => ['handler LIKE ?', "%ActivitiesCounterCacheJob%"]
  2 +if job.blank?
  3 + Delayed::Backend::ActiveRecord::Job.enqueue(ActivitiesCounterCacheJob.new, -3)
  4 +end
... ...
config/initializers/delayed_job_config.rb
1 1 Delayed::Worker.backend = :active_record
2 2 Delayed::Worker.max_attempts = 2
3   -Delayed::Worker.max_run_time = 10.minutes
  3 +
  4 +# TODO This is consuming ton of space on development with a postgres connection
  5 +# error on the jobs. This must be verified before going into production.
  6 +# Logging jobs backtraces
  7 +#class Delayed::Worker
  8 +# def handle_failed_job_with_loggin(job, error)
  9 +# handle_failed_job_without_loggin(job,error)
  10 +# Delayed::Worker.logger.error(error.message)
  11 +# Delayed::Worker.logger.error(error.backtrace.join("\n"))
  12 +# end
  13 +# alias_method_chain :handle_failed_job, :loggin
  14 +#end
... ...
config/initializers/noosfero_extensions.rb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +require 'noosfero/role_assignment_ext'
  2 +require 'noosfero/action_tracker_ext'
... ...
db/migrate/20140221142304_move_title_virtual_field_to_name_in_uploaded_file.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class MoveTitleVirtualFieldToNameInUploadedFile < ActiveRecord::Migration
  2 + def self.up
  3 + UploadedFile.find_each do |uploaded_file|
  4 + uploaded_file.name = uploaded_file.setting.delete :title
  5 + uploaded_file.send :update_without_callbacks
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + say "this migration can't be reverted"
  11 + end
  12 +end
... ...
db/migrate/20140303173209_move_contact_email_to_noreply_email_at_environment.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class MoveContactEmailToNoreplyEmailAtEnvironment < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :environments, :noreply_email, :string
  4 + Environment.reset_column_information
  5 +
  6 + Environment.find_each do |environment|
  7 + environment.noreply_email = environment.contact_email
  8 + environment.contact_email = nil
  9 + environment.save!
  10 + end
  11 + end
  12 +
  13 + def self.down
  14 + say "this migration can't be reverted"
  15 + end
  16 +end
... ...
db/migrate/20140312132212_add_indexes_for_article_search.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class AddIndexesForArticleSearch < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :articles, :created_at
  4 + add_index :articles, :hits
  5 + add_index :articles, :comments_count
  6 + end
  7 +
  8 + def self.down
  9 + remove_index :articles, :created_at
  10 + remove_index :articles, :hits
  11 + remove_index :articles, :comments_count
  12 + end
  13 +end
... ...
db/migrate/20140312134218_add_indexes_for_profile_search.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddIndexesForProfileSearch < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :profiles, :created_at
  4 + end
  5 +
  6 + def self.down
  7 + remove_index :profiles, :created_at
  8 + end
  9 +end
... ...
db/migrate/20140312141805_create_cache_counts_for_profiles.rb 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +class CreateCacheCountsForProfiles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :profiles, :friends_count, :integer, :null => false, :default => 0
  4 + add_column :profiles, :members_count, :integer, :null => false, :default => 0
  5 + add_column :profiles, :activities_count, :integer, :null => false, :default => 0
  6 + add_index :profiles, :friends_count
  7 + add_index :profiles, :members_count
  8 + add_index :profiles, :activities_count
  9 + end
  10 +
  11 + def self.down
  12 + remove_column :profiles, :friends_count
  13 + remove_column :profiles, :members_count
  14 + remove_column :profiles, :activities_count
  15 + remove_index :profiles, :friends_count
  16 + remove_index :profiles, :members_count
  17 + remove_index :profiles, :activities_count
  18 + end
  19 +end
... ...
db/migrate/20140312144156_define_initial_value_for_profiles_friends_count.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class DefineInitialValueForProfilesFriendsCount < ActiveRecord::Migration
  2 + def self.up
  3 + friends_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles INNER JOIN friendships ON ( profiles.id = friendships.friend_id AND profiles.type = E'Person') GROUP BY profiles.id;")
  4 + friends_counts.each do |count|
  5 + execute("UPDATE profiles SET friends_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};")
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + execute("UPDATE profiles SET friends_count=0;")
  11 + end
  12 +end
... ...
db/migrate/20140312151857_define_initial_value_for_profiles_activities_count.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class DefineInitialValueForProfilesActivitiesCount < ActiveRecord::Migration
  2 + def self.up
  3 + person_activities_counts = execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= '#{30.days.ago.to_s(:db)}') AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;")
  4 + organization_activities_counts = execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= '#{30.days.ago.to_s(:db)}') AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;")
  5 + activities_counts = person_activities_counts.entries + organization_activities_counts.entries
  6 + activities_counts.each do |count|
  7 + execute("UPDATE profiles SET activities_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};")
  8 + end
  9 + end
  10 +
  11 + def self.down
  12 + execute("UPDATE profiles SET activities_count=0;")
  13 + end
  14 +end
... ...
db/migrate/20140313213142_define_initial_value_for_profiles_members_count.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class DefineInitialValueForProfilesMembersCount < ActiveRecord::Migration
  2 + def self.up
  3 + members_counts = execute("SELECT profiles.id, count(profiles.id) FROM profiles LEFT OUTER JOIN role_assignments ON profiles.id = role_assignments.resource_id WHERE (profiles.type = 'Organization' OR profiles.type = 'Community' OR profiles.type = 'Enterprise') GROUP BY profiles.id;")
  4 + members_counts.each do |count|
  5 + execute("UPDATE profiles SET members_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};")
  6 + end
  7 + end
  8 +
  9 + def self.down
  10 + execute("UPDATE profiles SET members_count=0;")
  11 + end
  12 +end
... ...
db/migrate/20140314200103_add_indexes_for_products_search.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddIndexesForProductsSearch < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :products, :created_at
  4 + end
  5 +
  6 + def self.down
  7 + remove_index :products, :created_at
  8 + end
  9 +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 => 20140312184749) do
  12 +ActiveRecord::Schema.define(:version => 20140314200103) do
13 13  
14 14 create_table "abuse_reports", :force => true do |t|
15 15 t.integer "reporter_id"
... ... @@ -140,6 +140,9 @@ ActiveRecord::Schema.define(:version =&gt; 20140312184749) do
140 140 t.integer "position"
141 141 end
142 142  
  143 + add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
  144 + add_index "articles", ["created_at"], :name => "index_articles_on_created_at"
  145 + add_index "articles", ["hits"], :name => "index_articles_on_hits"
143 146 add_index "articles", ["name"], :name => "index_articles_on_name"
144 147 add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id"
145 148 add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id"
... ... @@ -283,6 +286,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140312184749) do
283 286 t.string "languages"
284 287 t.string "default_language"
285 288 t.string "redirection_after_signup", :default => "keep_on_same_page"
  289 + t.string "noreply_email"
286 290 end
287 291  
288 292 create_table "external_feeds", :force => true do |t|
... ... @@ -433,6 +437,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140312184749) do
433 437 t.boolean "archived", :default => false
434 438 end
435 439  
  440 + add_index "products", ["created_at"], :name => "index_products_on_created_at"
  441 + add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id"
436 442 add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id"
437 443 add_index "products", ["profile_id"], :name => "index_products_on_profile_id"
438 444  
... ... @@ -471,10 +477,17 @@ ActiveRecord::Schema.define(:version =&gt; 20140312184749) do
471 477 t.string "redirection_after_login"
472 478 t.string "personal_website"
473 479 t.string "jabber_id"
  480 + t.integer "friends_count", :default => 0, :null => false
  481 + t.integer "members_count", :default => 0, :null => false
  482 + t.integer "activities_count", :default => 0, :null => false
474 483 end
475 484  
  485 + add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count"
  486 + add_index "profiles", ["created_at"], :name => "index_profiles_on_created_at"
476 487 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
  488 + add_index "profiles", ["friends_count"], :name => "index_profiles_on_friends_count"
477 489 add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier"
  490 + add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count"
478 491 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id"
479 492  
480 493 create_table "qualifier_certifiers", :force => true do |t|
... ...
debian/changelog
  1 +noosfero (0.46.2) unstable; urgency=low
  2 +
  3 + * Bugfix release
  4 +
  5 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 19 Mar 2014 23:41:06 +0000
  6 +
1 7 noosfero (0.46.1) unstable; urgency=low
2 8  
3 9 * Bugfixes release
... ...
lib/activities_counter_cache_job.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class ActivitiesCounterCacheJob
  2 + def perform
  3 + person_activities_counts = ActiveRecord::Base.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id WHERE (action_tracker.created_at >= '#{ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db)}') AND ( (profiles.type = 'Person' ) ) GROUP BY profiles.id;")
  4 + organization_activities_counts = ActiveRecord::Base.connection.execute("SELECT profiles.id, count(action_tracker.id) as count FROM profiles LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.target_id WHERE (action_tracker.created_at >= '#{ActionTracker::Record::RECENT_DELAY.days.ago.to_s(:db)}') AND ( (profiles.type = 'Community' OR profiles.type = 'Enterprise' OR profiles.type = 'Organization' ) ) GROUP BY profiles.id;")
  5 + activities_counts = person_activities_counts.entries + organization_activities_counts.entries
  6 + activities_counts.each do |count|
  7 + ActiveRecord::Base.connection.execute("UPDATE profiles SET activities_count=#{count['count'].to_i} WHERE profiles.id=#{count['id']};")
  8 + end
  9 + Delayed::Job.enqueue(ActivitiesCounterCacheJob.new, -3, 1.day.from_now)
  10 + end
  11 +end
... ...
lib/feed_updater.rb
... ... @@ -24,8 +24,8 @@ class FeedUpdater
24 24 environment = Environment.default
25 25  
26 26 recipients NOOSFERO_CONF['exception_recipients']
27   - from environment.contact_email
28   - reply_to environment.contact_email
  27 + from environment.noreply_email
  28 + reply_to environment.noreply_email
29 29 subject "[#{environment.name}] Feed-updater: #{error.message}"
30 30 body render(:text => "
31 31 Container:
... ...
lib/file_presenter.rb
... ... @@ -13,6 +13,10 @@ class FilePresenter
13 13 klass.accepts?(f) ? klass.new(f) : f
14 14 end
15 15  
  16 + def self.base_class
  17 + Article
  18 + end
  19 +
16 20 def initialize(f)
17 21 @file = f
18 22 end
... ... @@ -31,6 +35,10 @@ class FilePresenter
31 35 self
32 36 end
33 37  
  38 + def kind_of?(klass)
  39 + @file.kind_of?(klass)
  40 + end
  41 +
34 42 # This method must be overridden in subclasses.
35 43 #
36 44 # If the class accepts the file, return a number that represents the
... ... @@ -43,7 +51,12 @@ class FilePresenter
43 51 end
44 52  
45 53 def short_description
46   - _("File (%s)") % content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '')
  54 + file_type = if content_type.present?
  55 + content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '')
  56 + else
  57 + _('Unknown')
  58 + end
  59 + _("File (%s)") % file_type
47 60 end
48 61  
49 62 # Define the css classes to style the page fragment with the file related
... ...
lib/noosfero.rb
... ... @@ -3,7 +3,7 @@ require &#39;fast_gettext&#39;
3 3  
4 4 module Noosfero
5 5 PROJECT = 'noosfero'
6   - VERSION = '0.46.1'
  6 + VERSION = '0.46.2'
7 7  
8 8 def self.pattern_for_controllers_in_directory(dir)
9 9 disjunction = controllers_in_directory(dir).join('|')
... ...
lib/noosfero/action_tracker_ext.rb 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +Rails.configuration.to_prepare do
  2 + ActionTracker::Record.module_eval do
  3 + extend CacheCounterHelper
  4 +
  5 + after_create do |record|
  6 + update_cache_counter(:activities_count, record.user, 1)
  7 + if record.target.kind_of?(Organization)
  8 + update_cache_counter(:activities_count, record.target, 1)
  9 + end
  10 + end
  11 +
  12 + after_destroy do |record|
  13 + if record.created_at >= ActionTracker::Record::RECENT_DELAY.days.ago
  14 + update_cache_counter(:activities_count, record.user, -1)
  15 + if record.target.kind_of?(Organization)
  16 + update_cache_counter(:activities_count, record.target, -1)
  17 + end
  18 + end
  19 + end
  20 + end
  21 +end
... ...
lib/noosfero/role_assignment_ext.rb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +Rails.configuration.to_prepare do
  2 + RoleAssignment.module_eval do
  3 + extend CacheCounterHelper
  4 +
  5 + after_create do |role_assignment|
  6 + accessor = role_assignment.accessor
  7 + resource = role_assignment.resource
  8 + if resource.kind_of?(Organization)
  9 + #FIXME This will only work as long as the role_assignment associations
  10 + #happen only between profiles, due to the polymorphic column type.
  11 + if resource.role_assignments.where(:accessor_id => accessor.id).count == 1
  12 + update_cache_counter(:members_count, resource, 1)
  13 + end
  14 + end
  15 + end
  16 +
  17 + after_destroy do |role_assignment|
  18 + accessor = role_assignment.accessor
  19 + resource = role_assignment.resource
  20 + if resource.kind_of?(Organization)
  21 + #FIXME This will only work as long as the role_assignment associations
  22 + #happen only between profiles, due to the polymorphic column type.
  23 + if resource.role_assignments.where(:accessor_id => accessor.id).count == 0
  24 + update_cache_counter(:members_count, resource, -1)
  25 + end
  26 + end
  27 + end
  28 + end
  29 +end
... ...
plugins/send_email/controllers/send_email_plugin_base_controller.rb
... ... @@ -3,7 +3,7 @@ module SendEmailPluginBaseController
3 3 if request.post?
4 4 @context_url = profile ? profile.url : {:host => environment.default_hostname, :controller => 'home'}
5 5 @mail = SendEmailPlugin::Mail.new(
6   - :from => environment.contact_email,
  6 + :from => environment.noreply_email,
7 7 :to => params[:to],
8 8 :message => params[:message],
9 9 :environment => environment,
... ...
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb
1 1 <h1> <%= _('Basket options') %> </h1>
2 2  
3 3 <% form_for(:settings, @settings, :url => {:action => 'edit'}, :html => {:method => 'post'}) do |f| %>
4   - <%= labelled_form_field(_('Enabled?'), f.check_box(:enabled)) %>
5   - <%= labelled_form_field(_('Delivery?'), f.check_box(:delivery)) %>
  4 + <%= labelled_form_field(_('Enable shopping basket'), f.check_box(:enabled)) %>
  5 + <%= labelled_form_field(_('Enable delivery fields on orders'), f.check_box(:delivery)) %>
6 6 <% display_delivery_settings = @settings.delivery ? 'auto' : 'none' %>
7 7 <fieldset id='delivery_settings' style="display: <%= display_delivery_settings %>"><legend><%=_('Delivery')%></legend>
8 8 <table>
... ... @@ -34,7 +34,7 @@
34 34 </table>
35 35  
36 36 <%= labelled_form_field(_("Order's minimum price for free delivery:"), f.text_field(:free_delivery_price)) %>
37   - <%= content_tag('small', _('Empty stands for no minimum price for free delivery.')) %>
  37 + <%= content_tag('small', _('Leave empty to always charge the delivery.')) %>
38 38 </fieldset>
39 39 <br style='clear: both'/>
40 40 <br style='clear: both'/>
... ...
plugins/spaminator/lib/spaminator_plugin/mailer.rb
... ... @@ -2,7 +2,7 @@ class SpaminatorPlugin::Mailer &lt; Noosfero::Plugin::MailerBase
2 2  
3 3 def inactive_person_notification(person)
4 4 recipients person.email
5   - from "#{person.environment.name} <#{person.environment.contact_email}>"
  5 + from "#{person.environment.name} <#{person.environment.noreply_email}>"
6 6 subject _("[%s] You must reactivate your account.") % person.environment.name
7 7 content_type 'text/html'
8 8 body :person => person,
... ...
plugins/spaminator/test/unit/spaminator_plugin/mailer_test.rb
... ... @@ -14,7 +14,7 @@ class SpaminatorPlugin::MailerTest &lt; ActiveSupport::TestCase
14 14 attr_accessor :environment, :settings
15 15  
16 16 should 'be able to send a inactive person notification message' do
17   - environment.contact_email = 'no-reply@noosfero.org'
  17 + environment.noreply_email = 'no-reply@noosfero.org'
18 18 environment.save
19 19  
20 20 person = create_user('spammer').person
... ...
plugins/tolerance_time/lib/tolerance_time_plugin/publication.rb
... ... @@ -5,8 +5,7 @@ class ToleranceTimePlugin::Publication &lt; Noosfero::Plugin::ActiveRecord
5 5  
6 6 class << self
7 7 def find_by_target(target)
8   - kind = target.kind_of?(Article) ? 'Article' : 'Comment'
9   - find_by_target_id_and_target_type(target.id, kind)
  8 + find_by_target_id_and_target_type(target.id, target.class.base_class.name)
10 9 end
11 10 end
12 11  
... ...
po/pt/noosfero.po
... ... @@ -2875,6 +2875,30 @@ msgstr &quot;Artigo de texto com linguagem de marcação Textile&quot;
2875 2875 msgid "Accessible alternative for visually impaired users."
2876 2876 msgstr "Alternativa acessível para usuários com deficiência visual."
2877 2877  
  2878 +#: app/models/layout_template.rb
  2879 +msgid "Left Bar"
  2880 +msgstr "Uma barra à esquerda"
  2881 +
  2882 +#: app/models/layout_template.rb
  2883 +msgid "2 Left Bars"
  2884 +msgstr "Duas barras à esquerda"
  2885 +
  2886 +#: app/models/layout_template.rb
  2887 +msgid "Left and Bottom Bar"
  2888 +msgstr "Uma barra à esquerda e outra ao final"
  2889 +
  2890 +#: app/models/layout_template.rb
  2891 +msgid "Right Bar"
  2892 +msgstr "Uma barra à direita"
  2893 +
  2894 +#: app/models/layout_template.rb
  2895 +msgid "Default"
  2896 +msgstr "Padrão"
  2897 +
  2898 +#: app/models/layout_template.rb
  2899 +msgid "No Sidebars"
  2900 +msgstr "Nenhuma barra lateral"
  2901 +
2878 2902 #: app/models/login_block.rb:4
2879 2903 msgid "Login/logout"
2880 2904 msgstr "Login/Sair"
... ... @@ -7219,8 +7243,8 @@ msgstr &quot;Funcionalidade&quot;
7219 7243  
7220 7244 #: app/views/features/index.rhtml:16
7221 7245 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:4
7222   -msgid "Enabled?"
7223   -msgstr "Habilitada?"
  7246 +msgid "Enable shopping basket"
  7247 +msgstr "Habilitar cesto de compras"
7224 7248  
7225 7249 #: app/views/features/index.rhtml:27
7226 7250 msgid "Configure features"
... ... @@ -12462,8 +12486,8 @@ msgid &quot;Basket options&quot;
12462 12486 msgstr "Opções do cesto"
12463 12487  
12464 12488 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:5
12465   -msgid "Delivery?"
12466   -msgstr "Entrega?"
  12489 +msgid "Enable delivery fields on orders"
  12490 +msgstr "Ativar campos de entrega para pedidos"
12467 12491  
12468 12492 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:10
12469 12493 msgid "Option"
... ... @@ -12480,12 +12504,12 @@ msgid &quot;ADD NEW OPTION&quot;
12480 12504 msgstr "ADCIONAR NOVA OPÇÂO"
12481 12505  
12482 12506 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:36
12483   -msgid "Free delivery price:"
12484   -msgstr "Preço de entrega grátis:"
  12507 +msgid "Order's minimum price for free delivery:"
  12508 +msgstr "Preço mínimo do pedido para entrega grátis:"
12485 12509  
12486 12510 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb:37
12487   -msgid "Empty stands for no free delivery price."
12488   -msgstr "Vazio significa sem preço de frete grátis."
  12511 +msgid "Leave empty to always charge the delivery."
  12512 +msgstr "Deixe vazio para sempre cobrar a entrega."
12489 12513  
12490 12514 #: plugins/shopping_cart/views/shopping_cart_plugin_myprofile/reports.html.erb:1
12491 12515 msgid "Purchase Reports"
... ...
public/designs/templates/leftbottom/config.yml
1   -name: "Left and Bottom bar"
  1 +name: "Left and Bottom Bar"
2 2 title: "Style 2 columns and a box at bottom of content"
3 3 description: "A theme with 2 columns and a box below the content"
4 4 number_of_boxes: 3
... ...
public/designs/templates/nosidebars/config.yml
1   -name: "No Side Bars"
  1 +name: "No Sidebars"
2 2 title: "No sidebars, only content"
3 3 description: "A template without sidebars, only content"
4 4 number_of_boxes: 1
... ...
test/functional/content_viewer_controller_test.rb
... ... @@ -741,16 +741,6 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
741 741 assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'}
742 742 end
743 743  
744   - should 'not allow html on title of the images' do
745   - login_as(profile.identifier)
746   - folder = fast_create(Gallery, :profile_id => profile.id)
747   - file = UploadedFile.create!(:title => '<b>my img title</b>', :profile => profile, :parent => folder, :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'))
748   -
749   - get :view_page, :profile => profile.identifier, :page => folder.explode_path
750   -
751   - assert_tag :tag => 'li', :attributes => {:title => 'my img title', :class => 'image-gallery-item'}, :child => {:tag => 'span', :content => 'my img title'}
752   - end
753   -
754 744 should 'allow publisher owner view private articles' do
755 745 c = Community.create!(:name => 'test_com')
756 746 u = create_user_with_permission('test_user', 'publish_content', c)
... ...
test/functional/invite_controller_test.rb
... ... @@ -230,7 +230,8 @@ class InviteControllerTest &lt; ActionController::TestCase
230 230  
231 231 contact_list = ContactList.create
232 232 post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
233   - assert_equal 'pt', Delayed::Job.first.payload_object.locale
  233 + job = Delayed::Job.where("handler LIKE '%InvitationJob%'").first
  234 + assert_equal 'pt', job.payload_object.locale
234 235 end
235 236  
236 237 private
... ...
test/functional/profile_controller_test.rb
... ... @@ -766,23 +766,28 @@ class ProfileControllerTest &lt; ActionController::TestCase
766 766 end
767 767  
768 768 should 'see all the activities in the current profile network' do
769   - p1= Person.first
  769 + p1= fast_create(Person)
770 770 p2= fast_create(Person)
771 771 assert !p1.is_a_friend?(p2)
  772 +
772 773 p3= fast_create(Person)
773 774 p3.add_friend(p1)
774 775 assert p3.is_a_friend?(p1)
775   - ActionTracker::Record.destroy_all
  776 +
  777 + ActionTracker::Record.delete_all
  778 +
  779 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
776 780 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
777 781 a1 = ActionTracker::Record.last
  782 +
778 783 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
779 784 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
780 785 a2 = ActionTracker::Record.last
  786 +
781 787 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
782 788 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
783 789 a3 = ActionTracker::Record.last
784 790  
785   -
786 791 @controller.stubs(:logged_in?).returns(true)
787 792 user = mock()
788 793 user.stubs(:person).returns(p3)
... ... @@ -792,24 +797,29 @@ class ProfileControllerTest &lt; ActionController::TestCase
792 797  
793 798 process_delayed_job_queue
794 799 get :index, :profile => p1.identifier
795   - assert_not_nil assigns(:network_activities)
796   - assert_equal [], [a1,a3] - assigns(:network_activities)
797   - assert_equal assigns(:network_activities) - [a1, a3], []
  800 +
  801 + assert_equivalent [a1,a3].map(&:id), assigns(:network_activities).map(&:id)
798 802 end
799 803  
800 804 should 'the network activity be visible only to profile followers' do
801   - p1= Person.first
  805 + p1= fast_create(Person)
802 806 p2= fast_create(Person)
803 807 assert !p1.is_a_friend?(p2)
  808 +
804 809 p3= fast_create(Person)
805 810 p3.add_friend(p1)
806 811 assert p3.is_a_friend?(p1)
807   - ActionTracker::Record.destroy_all
  812 +
  813 + ActionTracker::Record.delete_all
  814 +
  815 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
808 816 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
809 817 a1 = ActionTracker::Record.last
  818 +
810 819 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
811 820 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
812 821 a2 = ActionTracker::Record.last
  822 +
813 823 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
814 824 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
815 825 a3 = ActionTracker::Record.last
... ... @@ -819,8 +829,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
819 829 user.stubs(:person).returns(p2)
820 830 user.stubs(:login).returns('some')
821 831 @controller.stubs(:current_user).returns(user)
  832 +
822 833 get :index, :profile => p1.identifier
823   - assert_equal [], assigns(:network_activities)
  834 + assert assigns(:network_activities).blank?
824 835  
825 836 user = mock()
826 837 user.stubs(:person).returns(p3)
... ... @@ -828,9 +839,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
828 839 @controller.stubs(:current_user).returns(user)
829 840 Person.any_instance.stubs(:follows?).returns(true)
830 841 process_delayed_job_queue
  842 +
831 843 get :index, :profile => p3.identifier
832   - assert_equal [], [a1,a3] - assigns(:network_activities)
833   - assert_equal assigns(:network_activities) - [a1, a3], []
  844 + assert_equivalent [a1,a3], assigns(:network_activities)
834 845 end
835 846  
836 847 should 'the network activity be paginated' do
... ...
test/functional/search_controller_test.rb
... ... @@ -549,9 +549,9 @@ class SearchControllerTest &lt; ActionController::TestCase
549 549 c2 = create(Community, :name => 'Testing community 2')
550 550 c3 = create(Community, :name => 'Testing community 3')
551 551 ActionTracker::Record.delete_all
552   - fast_create(ActionTracker::Record, :target_id => c1, :user_type => 'Profile', :user_id => person, :created_at => Time.now)
553   - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now)
554   - fast_create(ActionTracker::Record, :target_id => c2, :user_type => 'Profile', :user_id => person, :created_at => Time.now)
  552 + ActionTracker::Record.create!(:target => c1, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
  553 + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
  554 + ActionTracker::Record.create!(:target => c2, :user => person, :created_at => Time.now, :verb => 'leave_scrap')
555 555 get :communities, :filter => 'more_active'
556 556 assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results]
557 557 end
... ...
test/test_helper.rb
... ... @@ -183,7 +183,7 @@ class ActiveSupport::TestCase
183 183 if reference.first == value
184 184 reference.shift
185 185 else
186   - assert false, "'#{value}' was found before it should be on: #{original.inspect}"
  186 + assert false, "'#{value.inspect}' was found before it should be on: #{original.inspect}"
187 187 end
188 188 end
189 189 end
... ...
test/unit/action_tracker_ext_test.rb 0 → 100644
... ... @@ -0,0 +1,64 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ActionTrackerExtTest < ActiveSupport::TestCase
  4 + should 'increase person activities_count on new activity' do
  5 + person = fast_create(Person)
  6 + assert_difference person, :activities_count, 1 do
  7 + ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile)
  8 + person.reload
  9 + end
  10 + end
  11 +
  12 + should 'decrease person activities_count on activity removal' do
  13 + person = fast_create(Person)
  14 + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile)
  15 + person.reload
  16 + assert_difference person, :activities_count, -1 do
  17 + record.destroy
  18 + person.reload
  19 + end
  20 + end
  21 +
  22 + should 'not decrease person activities_count on activity removal after the recent delay' do
  23 + person = fast_create(Person)
  24 + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => fast_create(Profile)
  25 + record.created_at = record.created_at - ActionTracker::Record::RECENT_DELAY.days - 1.day
  26 + record.save!
  27 + person.reload
  28 + assert_no_difference person, :activities_count do
  29 + record.destroy
  30 + person.reload
  31 + end
  32 + end
  33 +
  34 + should 'increase organization activities_count on new activity' do
  35 + person = fast_create(Person)
  36 + organization = fast_create(Organization)
  37 + assert_difference organization, :activities_count, 1 do
  38 + ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization
  39 + organization.reload
  40 + end
  41 + end
  42 +
  43 + should 'decrease organization activities_count on activity removal' do
  44 + person = fast_create(Person)
  45 + organization = fast_create(Organization)
  46 + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization
  47 + organization.reload
  48 + assert_difference organization, :activities_count, -1 do
  49 + record.destroy
  50 + organization.reload
  51 + end
  52 + end
  53 +
  54 + should 'not decrease organization activities_count on activity removal after the recent delay' do
  55 + person = fast_create(Person)
  56 + organization = fast_create(Organization)
  57 + record = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => organization, :created_at => (ActionTracker::Record::RECENT_DELAY + 1).days.ago
  58 + organization.reload
  59 + assert_no_difference organization, :activities_count do
  60 + record.destroy
  61 + organization.reload
  62 + end
  63 + end
  64 +end
... ...
test/unit/activities_counter_cache_job_test.rb 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ActivitiesCounterCacheJobTest < ActiveSupport::TestCase
  4 +
  5 + should 'correctly update the person activities counter cache' do
  6 + person = create_user('person').person
  7 + ActionTracker::Record.create!(:user => person, :verb => 'create_article')
  8 + ActionTracker::Record.create!(:user => person, :verb => 'create_article')
  9 + person.reload
  10 + assert_equal 2, person.activities_count
  11 +
  12 + person.activities_count = 0
  13 + person.save!
  14 + job = ActivitiesCounterCacheJob.new
  15 + job.perform
  16 + person.reload
  17 + assert_equal 2, person.activities_count
  18 + end
  19 +
  20 + should 'correctly update the organization activities counter cache' do
  21 + person = create_user('person').person
  22 + organization = Organization.create!(:name => 'Organization1', :identifier => 'organization1')
  23 + ActionTracker::Record.create!(:user => person, :verb => 'create_article', :target => organization)
  24 + ActionTracker::Record.create!(:user => person, :verb => 'create_article', :target => organization)
  25 + organization.reload
  26 + assert_equal 2, organization.activities_count
  27 +
  28 + organization.activities_count = 0
  29 + organization.save!
  30 + job = ActivitiesCounterCacheJob.new
  31 + job.perform
  32 + organization.reload
  33 + assert_equal 2, organization.activities_count
  34 + end
  35 +
  36 +end
... ...
test/unit/article_test.rb
... ... @@ -1630,10 +1630,10 @@ class ArticleTest &lt; ActiveSupport::TestCase
1630 1630  
1631 1631 should 'not allow all community members to edit by default' do
1632 1632 community = fast_create(Community)
1633   - admin = create_user('community-admin').person
1634   - member = create_user.person
1635   -
  1633 + admin = fast_create(Person)
  1634 + member = fast_create(Person)
1636 1635 community.add_admin(admin)
  1636 + community.reload
1637 1637 community.add_member(member)
1638 1638 a = Article.new(:profile => community)
1639 1639  
... ...
test/unit/community_test.rb
... ... @@ -213,8 +213,8 @@ class CommunityTest &lt; ActiveSupport::TestCase
213 213 community = fast_create(Community)
214 214 community.closed = true
215 215 community.save
216   -
217 216 community.add_member(fast_create(Person))
  217 + community.reload
218 218  
219 219 assert_difference AddMember, :count do
220 220 community.add_member(person)
... ...
test/unit/contact_sender_test.rb
... ... @@ -16,7 +16,7 @@ class ContactSenderTest &lt; ActiveSupport::TestCase
16 16 ent.contact_email = 'contact@invalid.com'
17 17 c = build(Contact, :dest => ent)
18 18 response = Contact::Sender.deliver_mail(c)
19   - assert_equal Environment.default.contact_email, response.from.to_s
  19 + assert_equal Environment.default.noreply_email.to_s, response.from.to_s
20 20 assert_equal "[#{ent.name}] #{c.subject}", response.subject
21 21 end
22 22  
... ... @@ -27,7 +27,7 @@ class ContactSenderTest &lt; ActiveSupport::TestCase
27 27 response = Contact::Sender.deliver_mail(c)
28 28 assert_includes response.to, c.dest.contact_email
29 29 end
30   -
  30 +
31 31 should 'deliver mail to admins of enterprise' do
32 32 admin = create_user('admin_test').person
33 33 ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :environment => Environment.default)
... ...
test/unit/contact_test.rb
... ... @@ -44,11 +44,14 @@ class ContactTest &lt; ActiveSupport::TestCase
44 44 assert !c.deliver
45 45 end
46 46  
47   - should 'use sender name and environment contact_email on from' do
  47 + should 'use sender name and environment noreply_email on from' do
48 48 ent = fast_create(Enterprise, :name => 'my enterprise', :identifier => 'myent')
  49 + env = ent.environment
  50 + env.noreply_email = 'noreply@sample.org'
  51 + env.save!
49 52 c = Contact.new(:name => 'john', :email => 'john@invalid.com', :subject => 'hi', :message => 'hi, all', :dest => ent)
50 53 email = c.deliver
51   - assert_equal "#{c.name} <#{ent.environment.contact_email}>", email['from'].to_s
  54 + assert_equal "#{c.name} <#{ent.environment.noreply_email}>", email['from'].to_s
52 55 end
53 56  
54 57 should 'add dest name on subject' do
... ...
test/unit/enterprise_test.rb
... ... @@ -99,6 +99,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
99 99 enterprise = fast_create(Enterprise)
100 100 member = fast_create(Person)
101 101 enterprise.add_member(member)
  102 + enterprise.reload
102 103  
103 104 person = fast_create(Person)
104 105 enterprise.add_member(person)
... ...
test/unit/environment_mailing_test.rb
... ... @@ -46,7 +46,7 @@ class EnvironmentMailingTest &lt; ActiveSupport::TestCase
46 46  
47 47 should 'display name and email on generate_from' do
48 48 mailing = EnvironmentMailing.new(:source => environment, :person => person_1)
49   - assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from
  49 + assert_equal "#{environment.name} <#{environment.noreply_email}>", mailing.generate_from
50 50 end
51 51  
52 52 should 'deliver mailing to each recipient after create' do
... ...
test/unit/file_presenter_test.rb
... ... @@ -58,4 +58,20 @@ class FilePresenterTest &lt; ActiveSupport::TestCase
58 58 end
59 59 end
60 60  
  61 + should 'pass kind_of? to the encapsulated file' do
  62 + f = FilePresenter.for(UploadedFile.new)
  63 + assert f.kind_of?(UploadedFile)
  64 + end
  65 +
  66 + should 'not crash with uploaded_file short description without content_type' do
  67 + f = FilePresenter.for(UploadedFile.new)
  68 + assert_nothing_raised do
  69 + f.short_description
  70 + end
  71 + end
  72 +
  73 + should 'show unknown type when file doesn\'t have a content_type' do
  74 + f = FilePresenter.for(UploadedFile.new)
  75 + assert_match /Unknown/, f.short_description
  76 + end
61 77 end
... ...
test/unit/mailing_test.rb
... ... @@ -74,7 +74,7 @@ class MailingTest &lt; ActiveSupport::TestCase
74 74 should 'display name and email on generate_from' do
75 75 person = Person['user_one']
76 76 mailing = Mailing.new(:source => environment, :person => person)
77   - assert_equal "#{environment.name} <#{environment.contact_email}>", mailing.generate_from
  77 + assert_equal "#{environment.name} <#{environment.noreply_email}>", mailing.generate_from
78 78 end
79 79  
80 80 should 'generate subject' do
... ...
test/unit/organization_mailing_test.rb
... ... @@ -42,7 +42,7 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase
42 42  
43 43 should 'display name and email on generate_from' do
44 44 mailing = OrganizationMailing.new(:source => community, :person => person)
45   - assert_equal "#{person.name} <#{community.environment.contact_email}>", mailing.generate_from
  45 + assert_equal "#{person.name} <#{community.environment.noreply_email}>", mailing.generate_from
46 46 end
47 47  
48 48 should 'generate subject' do
... ... @@ -62,18 +62,21 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase
62 62  
63 63 should 'deliver mailing to each member after create' do
64 64 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person)
  65 + community.reload
65 66 process_delayed_job_queue
66 67 assert_equal 2, ActionMailer::Base.deliveries.count
67 68 end
68 69  
69 70 should 'deliver mailing when there are many mailings created' do
70 71 50.times { OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) }
  72 + community.reload
71 73 process_delayed_job_queue
72 74 assert_equal 50*community.members_count, ActionMailer::Base.deliveries.count
73 75 end
74 76  
75 77 should 'create mailing sent to each recipient after delivering mailing' do
76 78 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person)
  79 + community.reload
77 80 assert_difference MailingSent, :count, 2 do
78 81 process_delayed_job_queue
79 82 end
... ...
test/unit/organization_test.rb
... ... @@ -302,18 +302,17 @@ class OrganizationTest &lt; ActiveSupport::TestCase
302 302 end
303 303  
304 304 should 'find more popular organizations' do
305   - Organization.delete_all
306 305 o1 = fast_create(Organization)
307 306 o2 = fast_create(Organization)
308 307  
309 308 p1 = fast_create(Person)
310 309 p2 = fast_create(Person)
311 310 o1.add_member(p1)
312   - assert_equal [o1,o2] , Organization.more_popular
  311 + assert_order [o1,o2] , Organization.more_popular
313 312  
314 313 o2.add_member(p1)
315 314 o2.add_member(p2)
316   - assert_equal [o2,o1] , Organization.more_popular
  315 + assert_order [o2,o1] , Organization.more_popular
317 316 end
318 317  
319 318 should 'list organizations that have no members in more popular list' do
... ... @@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase
331 330 person = fast_create(Person)
332 331 organization = fast_create(Organization)
333 332 organization.add_member(person)
  333 + organization.reload
334 334  
335 335 assert_equal "one member", organization.more_popular_label
336 336 end
... ... @@ -342,47 +342,30 @@ class OrganizationTest &lt; ActiveSupport::TestCase
342 342  
343 343 organization.add_member(person1)
344 344 organization.add_member(person2)
  345 + organization.reload
345 346 assert_equal "2 members", organization.more_popular_label
346 347  
347 348 person3 = fast_create(Person)
348 349 organization.add_member(person3)
  350 + organization.reload
349 351 assert_equal "3 members", organization.more_popular_label
350 352 end
351 353  
352 354 should 'find more active organizations' do
353 355 person = fast_create(Person)
354   - Organization.destroy_all
355 356 p1 = fast_create(Organization)
356 357 p2 = fast_create(Organization)
357 358 p3 = fast_create(Organization)
358 359  
359 360 ActionTracker::Record.destroy_all
360   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p1.id)
361   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p2.id)
362   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p2.id)
363   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id)
364   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id)
365   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => Time.now, :target_id => p3.id)
  361 + ActionTracker::Record.create!(:user => person, :target => p1, :verb => 'leave_scrap')
  362 + ActionTracker::Record.create!(:user => person, :target => p2, :verb => 'leave_scrap')
  363 + ActionTracker::Record.create!(:user => person, :target => p2, :verb => 'leave_scrap')
  364 + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap')
  365 + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap')
  366 + ActionTracker::Record.create!(:user => person, :target => p3, :verb => 'leave_scrap')
366 367  
367   - assert_equal [p3,p2,p1] , Organization.more_active
368   - end
369   -
370   - should 'more active profile take in consideration only actions created only in the recent delay interval' do
371   - ActionTracker::Record.destroy_all
372   - recent_delay = ActionTracker::Record::RECENT_DELAY.days.ago
373   -
374   - person = fast_create(Person)
375   - Organization.destroy_all
376   - p1 = fast_create(Organization)
377   - p2 = fast_create(Organization)
378   -
379   - ActionTracker::Record.destroy_all
380   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p1.id)
381   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p1.id)
382   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay, :target_id => p2.id)
383   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person, :created_at => recent_delay - 1.day, :target_id => p2.id)
384   -
385   - assert_equal [p1,p2] , Organization.more_active
  368 + assert_order [p3,p2,p1] , Organization.more_active
386 369 end
387 370  
388 371 should 'list profiles that have no actions in more active list' do
... ... @@ -422,4 +405,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase
422 405 assert !organization.visible
423 406 end
424 407  
  408 + should 'increase members_count on new membership' do
  409 + member = fast_create(Person)
  410 + organization = fast_create(Organization)
  411 + assert_difference organization, :members_count, 1 do
  412 + organization.add_member(member)
  413 + organization.reload
  414 + end
  415 + end
  416 +
  417 + should 'decrease members_count on membership removal' do
  418 + member = fast_create(Person)
  419 + organization = fast_create(Organization)
  420 + organization.add_member(member)
  421 + organization.reload
  422 + assert_difference organization, :members_count, -1 do
  423 + organization.remove_member(member)
  424 + organization.reload
  425 + end
  426 + end
  427 +
425 428 end
... ...
test/unit/person_test.rb
... ... @@ -404,15 +404,14 @@ class PersonTest &lt; ActiveSupport::TestCase
404 404  
405 405 should 'not allow simple member to view group pending tasks' do
406 406 community = fast_create(Community)
  407 + admin = fast_create(Person)
  408 + community.add_member(admin)
407 409 member = fast_create(Person)
  410 + community.reload
408 411 community.add_member(member)
409   -
410 412 community.tasks << Task.new
411 413  
412   - person = fast_create(Person)
413   - community.add_member(person)
414   -
415   - assert_not_includes Person.with_pending_tasks, person
  414 + assert_not_includes Person.with_pending_tasks, member
416 415 end
417 416  
418 417 should 'person has organization pending tasks' do
... ... @@ -642,16 +641,18 @@ class PersonTest &lt; ActiveSupport::TestCase
642 641 end
643 642  
644 643 should 'find more popular people' do
  644 + extend CacheCounterHelper
  645 +
645 646 Person.delete_all
646 647 p1 = fast_create(Person)
647 648 p2 = fast_create(Person)
648 649 p3 = fast_create(Person)
649 650  
650   - p1.add_friend(p2)
651   - p2.add_friend(p1)
652   - p2.add_friend(p3)
653   - assert_equal p2, Person.more_popular[0]
654   - assert_equal p1, Person.more_popular[1]
  651 + update_cache_counter(:friends_count, p1, 1)
  652 + update_cache_counter(:friends_count, p2, 2)
  653 + update_cache_counter(:friends_count, p3, 3)
  654 +
  655 + assert_order [p3, p2, p1], Person.more_popular
655 656 end
656 657  
657 658 should 'list people that have no friends in more popular list' do
... ... @@ -891,6 +892,7 @@ class PersonTest &lt; ActiveSupport::TestCase
891 892 p1 = fast_create(Person)
892 893 p2 = fast_create(Person)
893 894 p3 = fast_create(Person)
  895 + p4 = fast_create(Person)
894 896  
895 897 community.add_member(p1)
896 898 assert p1.is_member_of?(community)
... ... @@ -901,14 +903,15 @@ class PersonTest &lt; ActiveSupport::TestCase
901 903  
902 904 action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article')
903 905 action_tracker.target = community
  906 + action_tracker.user = p4
904 907 action_tracker.save!
905 908 ActionTrackerNotification.delete_all
906   - assert_difference(ActionTrackerNotification, :count, 3) do
  909 + assert_difference(ActionTrackerNotification, :count, 4) do
907 910 Person.notify_activity(action_tracker)
908 911 process_delayed_job_queue
909 912 end
910 913 ActionTrackerNotification.all.map{|a|a.profile}.map do |profile|
911   - assert [community,p1,p3].include?(profile)
  914 + assert [community,p1,p3,p4].include?(profile)
912 915 end
913 916 end
914 917  
... ... @@ -1011,9 +1014,9 @@ class PersonTest &lt; ActiveSupport::TestCase
1011 1014  
1012 1015 should 'the community specific notification created when a member joins community could not be propagated to members' do
1013 1016 ActionTracker::Record.delete_all
1014   - p1 = create_user('test_user').person
1015   - p2 = create_user('test_user').person
1016   - p3 = create_user('test_user').person
  1017 + p1 = create_user('p1').person
  1018 + p2 = create_user('p2').person
  1019 + p3 = create_user('p3').person
1017 1020 c = fast_create(Community, :name => "Foo")
1018 1021 c.add_member(p1)
1019 1022 process_delayed_job_queue
... ... @@ -1133,30 +1136,14 @@ class PersonTest &lt; ActiveSupport::TestCase
1133 1136 p3 = fast_create(Person)
1134 1137  
1135 1138 ActionTracker::Record.destroy_all
1136   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => Time.now)
1137   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => Time.now)
1138   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => Time.now)
1139   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now)
1140   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now)
1141   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p3, :created_at => Time.now)
  1139 + ActionTracker::Record.create!(:user => p1, :verb => 'leave_scrap')
  1140 + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap')
  1141 + ActionTracker::Record.create!(:user => p2, :verb => 'leave_scrap')
  1142 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
  1143 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
  1144 + ActionTracker::Record.create!(:user => p3, :verb => 'leave_scrap')
1142 1145  
1143   - assert_equal [p3,p2,p1] , Person.more_active
1144   - end
1145   -
1146   - should 'more active profile take in consideration only actions created only in the recent delay interval' do
1147   - Person.delete_all
1148   - ActionTracker::Record.destroy_all
1149   - recent_delay = ActionTracker::Record::RECENT_DELAY.days.ago
1150   -
1151   - p1 = fast_create(Person)
1152   - p2 = fast_create(Person)
1153   -
1154   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => recent_delay)
1155   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p1, :created_at => recent_delay)
1156   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => recent_delay)
1157   - fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => p2, :created_at => recent_delay - 1.day)
1158   -
1159   - assert_equal [p1,p2], Person.more_active
  1146 + assert_order [p3,p2,p1] , Person.more_active
1160 1147 end
1161 1148  
1162 1149 should 'list profiles that have no actions in more active list' do
... ... @@ -1363,7 +1350,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1363 1350 u = create_user('user'+i.to_s)
1364 1351 u.deactivate
1365 1352 }
1366   - assert_equal activated, Person.activated
  1353 + assert_equivalent activated, Person.activated
1367 1354 end
1368 1355  
1369 1356 should 'deactivated named_scope return persons who are deactivated users' do
... ... @@ -1379,7 +1366,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1379 1366 u = create_user('user'+i.to_s)
1380 1367 u.activate
1381 1368 }
1382   - assert_equal deactivated, Person.deactivated
  1369 + assert_equivalent deactivated, Person.deactivated
1383 1370 end
1384 1371  
1385 1372 should 'be able to retrieve memberships by role person has' do
... ... @@ -1446,4 +1433,30 @@ class PersonTest &lt; ActiveSupport::TestCase
1446 1433 assert 3, original_person.memberships.count
1447 1434 end
1448 1435  
  1436 + should 'increase friends_count on new friendship' do
  1437 + person = create_user('person').person
  1438 + friend = create_user('friend').person
  1439 + assert_difference person, :friends_count, 1 do
  1440 + assert_difference friend, :friends_count, 1 do
  1441 + person.add_friend(friend)
  1442 + friend.reload
  1443 + end
  1444 + person.reload
  1445 + end
  1446 + end
  1447 +
  1448 + should 'decrease friends_count on friendship removal' do
  1449 + person = create_user('person').person
  1450 + friend = create_user('friend').person
  1451 + person.add_friend(friend)
  1452 + friend.reload
  1453 + person.reload
  1454 + assert_difference person, :friends_count, -1 do
  1455 + assert_difference friend, :friends_count, -1 do
  1456 + person.remove_friend(friend)
  1457 + friend.reload
  1458 + end
  1459 + person.reload
  1460 + end
  1461 + end
1449 1462 end
... ...
test/unit/profile_test.rb
... ... @@ -1688,6 +1688,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1688 1688 person = fast_create(Person)
1689 1689 community = fast_create(Community)
1690 1690 community.add_member(person)
  1691 + community.reload
1691 1692  
1692 1693 assert_equal 1, community.members_count
1693 1694 end
... ... @@ -1823,11 +1824,12 @@ class ProfileTest &lt; ActiveSupport::TestCase
1823 1824 original_community.add_member(original_member)
1824 1825 community1.add_member(plugin1_member)
1825 1826 community2.add_member(plugin2_member)
  1827 + original_community.reload
1826 1828  
1827 1829 assert_includes original_community.members, original_member
1828 1830 assert_includes original_community.members, plugin1_member
1829 1831 assert_includes original_community.members, plugin2_member
1830   - assert 3, original_community.members.count
  1832 + assert 3, original_community.members_count
1831 1833 end
1832 1834  
1833 1835 private
... ...
test/unit/role_assignment_ext_test.rb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RoleAssignmentExtTest < ActiveSupport::TestCase
  4 + should 'increase organization members_count only on the first role_assignment' do
  5 + role1 = Role.create!(:name => 'role1')
  6 + role2 = Role.create!(:name => 'role2')
  7 + member = create_user('person').person
  8 + organization = Organization.create!(:name => 'Organization', :identifier => 'organization')
  9 + assert_difference organization, :members_count, 1 do
  10 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1)
  11 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2)
  12 + organization.reload
  13 + end
  14 + end
  15 +
  16 + should 'decrease organization members_count only on the last role_assignment' do
  17 + role1 = Role.create!(:name => 'role1')
  18 + role2 = Role.create!(:name => 'role2')
  19 + member = create_user('person').person
  20 + organization = Organization.create!(:name => 'Organization', :identifier => 'organization')
  21 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role1)
  22 + RoleAssignment.create!(:accessor => member, :resource => organization, :role => role2)
  23 + organization.reload
  24 + assert_difference organization, :members_count, -1 do
  25 + organization.role_assignments.destroy_all
  26 + organization.reload
  27 + end
  28 + end
  29 +end
... ...
test/unit/task_mailer_test.rb
... ... @@ -24,7 +24,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
24 24 requestor.expects(:name).returns('my name')
25 25  
26 26 environment = mock()
27   - environment.expects(:contact_email).returns('sender@example.com')
  27 + environment.expects(:noreply_email).returns('sender@example.com')
28 28 environment.expects(:default_hostname).returns('example.com')
29 29 environment.expects(:name).returns('example').at_least_once
30 30  
... ... @@ -47,7 +47,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
47 47 requestor.expects(:name).returns('my name')
48 48  
49 49 environment = mock()
50   - environment.expects(:contact_email).returns('sender@example.com')
  50 + environment.expects(:noreply_email).returns('sender@example.com')
51 51 environment.expects(:default_hostname).returns('example.com')
52 52 environment.expects(:name).returns('example').at_least_once
53 53  
... ... @@ -71,7 +71,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
71 71 requestor.expects(:name).returns('my name')
72 72  
73 73 environment = mock()
74   - environment.expects(:contact_email).returns('sender@example.com')
  74 + environment.expects(:noreply_email).returns('sender@example.com')
75 75 environment.expects(:default_hostname).returns('example.com')
76 76 environment.expects(:name).returns('example').at_least_once
77 77  
... ... @@ -105,7 +105,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
105 105 requestor.stubs(:public_profile_url).returns('requestor_path')
106 106  
107 107 environment = mock()
108   - environment.expects(:contact_email).returns('sender@example.com')
  108 + environment.expects(:noreply_email).returns('sender@example.com')
109 109 environment.expects(:default_hostname).returns('example.com')
110 110 environment.expects(:name).returns('example').at_least_once
111 111  
... ... @@ -124,11 +124,11 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
124 124 assert !ActionMailer::Base.deliveries.empty?
125 125 end
126 126  
127   - should 'use environment name and contact email' do
  127 + should 'use environment name and no-reply email' do
128 128 task = mock
129 129 environment = mock
130 130 environment.expects(:name).returns('My name')
131   - environment.expects(:contact_email).returns('email@example.com')
  131 + environment.expects(:noreply_email).returns('email@example.com')
132 132  
133 133 task.expects(:environment).returns(environment).at_least_once
134 134  
... ...
test/unit/theme_test.rb
... ... @@ -191,4 +191,22 @@ class ThemeTest &lt; ActiveSupport::TestCase
191 191 assert ! Theme.new('test').public
192 192 end
193 193  
  194 + should 'not crash with nil or invalid owner_type' do
  195 + profile = fast_create(Profile)
  196 + Theme.stubs(:system_themes_dir).returns(TMP_THEMES_DIR)
  197 +
  198 + t1 = Theme.new('t1').save
  199 + t1.send(:write_config)
  200 + t2 = Theme.new('t2', {:owner_type => nil}).save
  201 + t2.send(:write_config)
  202 + t3 = Theme.new('t3', {:owner_type => 'InvalidClass'}).save
  203 + t3.send(:write_config)
  204 +
  205 + assert_nothing_raised do
  206 + themes = Theme.approved_themes(profile)
  207 + assert_not_includes themes, t1
  208 + assert_not_includes themes, t2
  209 + assert_not_includes themes, t3
  210 + end
  211 + end
194 212 end
... ...
test/unit/uploaded_file_test.rb
... ... @@ -31,6 +31,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
31 31 assert_equal 'test.txt', file.name
32 32 end
33 33  
  34 + should 'not set filename on name if name is already set' do
  35 + file = UploadedFile.new
  36 + file.name = "Some name"
  37 + file.filename = 'test.txt'
  38 + assert_equal 'Some name', file.name
  39 + end
  40 +
34 41 should 'provide file content as data' do
35 42 file = UploadedFile.new
36 43 file.expects(:full_filename).returns('myfilename')
... ... @@ -119,24 +126,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
119 126 assert_equal 'my title', UploadedFile.new(:title => 'my title').title
120 127 end
121 128  
122   - should 'limit title to 140 characters' do
123   - upload = UploadedFile.new
124   -
125   - upload.title = '+' * 61; upload.valid?
126   - assert upload.errors[:title]
127   -
128   - upload.title = '+' * 60; upload.valid?
129   - assert !upload.errors[:title]
130   -
131   - end
132   -
133 129 should 'always provide a display title' do
134 130 upload = UploadedFile.new(:uploaded_data => fixture_file_upload('/files/test.txt', 'text/plain'))
135   - assert_equal 'test.txt', upload.display_title
  131 + assert_equal 'test.txt', upload.title
136 132 upload.title = 'My text file'
137   - assert_equal 'My text file', upload.display_title
  133 + assert_equal 'My text file', upload.title
138 134 upload.title = ''
139   - assert_equal 'test.txt', upload.display_title
  135 + assert_equal 'test.txt', upload.title
140 136 end
141 137  
142 138 should 'use name as title by default' do
... ... @@ -326,13 +322,15 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
326 322 end
327 323  
328 324 should 'group trackers activity of image\'s upload' do
  325 + ActionTracker::Record.delete_all
329 326 gallery = fast_create(Gallery, :profile_id => profile.id)
330   -
  327 + count = ActionTracker::Record.find_all_by_verb('upload_image').count
331 328 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile)
332   - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count
  329 + count += 1
  330 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
333 331  
334 332 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile)
335   - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count
  333 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
336 334 end
337 335  
338 336 {
... ...
vendor/plugins/action_tracker/lib/action_tracker_model.rb
1 1 module ActionTracker
2 2 class Record < ActiveRecord::Base
3   -
4 3 set_table_name 'action_tracker'
5 4  
6 5 belongs_to :user, :polymorphic => true
... ...
vendor/plugins/monkey_patches/rescue_delayed_job_crashes/init.rb
... ... @@ -5,8 +5,8 @@ Delayed::Worker.module_eval do
5 5 environment = Environment.default
6 6  
7 7 recipients NOOSFERO_CONF['exception_recipients']
8   - from environment.contact_email
9   - reply_to environment.contact_email
  8 + from environment.noreply_email
  9 + reply_to environment.noreply_email
10 10 subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}"
11 11 body render(:text => "
12 12 Job:
... ...