Commit d5d9e7da9ac12964930897882ea047961855ae02

Authored by Rodrigo Souto
2 parents be1a989b 8bef50d2

Merge branch 'search-optimizations' into stable

Showing 35 changed files with 461 additions and 129 deletions   Show diff stats
app/helpers/cache_counter_helper.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -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/models/friendship.rb
1 class Friendship < ActiveRecord::Base 1 class Friendship < ActiveRecord::Base
2 track_actions :new_friendship, :after_create, :keep_params => ["friend.name", "friend.url", "friend.profile_custom_icon"], :custom_user => :person 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 belongs_to :person, :foreign_key => :person_id 6 belongs_to :person, :foreign_key => :person_id
5 belongs_to :friend, :class_name => 'Person', :foreign_key => 'friend_id' 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 end 18 end
app/models/organization.rb
@@ -26,18 +26,7 @@ class Organization &lt; Profile @@ -26,18 +26,7 @@ class Organization &lt; Profile
26 26
27 has_many :mailings, :class_name => 'OrganizationMailing', :foreign_key => :source_id, :as => 'source' 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 def validation_methodology 31 def validation_methodology
43 self.validation_info ? self.validation_info.validation_methodology : nil 32 self.validation_info ? self.validation_info.validation_methodology : nil
app/models/person.rb
@@ -66,18 +66,7 @@ class Person &lt; Profile @@ -66,18 +66,7 @@ class Person &lt; Profile
66 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' 66 has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
67 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' 67 has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions'
68 68
69 - named_scope :more_popular,  
70 - :select => "#{Profile.qualified_column_names}, count(friend_id) as total",  
71 - :group => Profile.qualified_column_names,  
72 - :joins => "LEFT OUTER JOIN friendships on profiles.id = friendships.person_id",  
73 - :order => "total DESC"  
74 -  
75 - named_scope :more_active,  
76 - :select => "#{Profile.qualified_column_names}, count(action_tracker.id) as total",  
77 - :joins => "LEFT OUTER JOIN action_tracker ON profiles.id = action_tracker.user_id",  
78 - :group => Profile.qualified_column_names,  
79 - :order => 'total DESC',  
80 - :conditions => ['action_tracker.created_at >= ? OR action_tracker.id IS NULL', ActionTracker::Record::RECENT_DELAY.days.ago] 69 + named_scope :more_popular, :order => 'friends_count DESC'
81 70
82 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*' 71 named_scope :abusers, :joins => :abuse_complaints, :conditions => ['tasks.status = 3'], :select => 'DISTINCT profiles.*'
83 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.*" 72 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
@@ -87,10 +87,6 @@ class Profile &lt; ActiveRecord::Base @@ -87,10 +87,6 @@ class Profile &lt; ActiveRecord::Base
87 scopes.size == 1 ? scopes.first : Person.or_scope(scopes) 87 scopes.size == 1 ? scopes.first : Person.or_scope(scopes)
88 end 88 end
89 89
90 - def members_count  
91 - members.count  
92 - end  
93 -  
94 class << self 90 class << self
95 def count_with_distinct(*args) 91 def count_with_distinct(*args)
96 options = args.last || {} 92 options = args.last || {}
@@ -113,10 +109,11 @@ class Profile &lt; ActiveRecord::Base @@ -113,10 +109,11 @@ class Profile &lt; ActiveRecord::Base
113 109
114 named_scope :visible, :conditions => { :visible => true } 110 named_scope :visible, :conditions => { :visible => true }
115 named_scope :public, :conditions => { :visible => true, :public_profile => true } 111 named_scope :public, :conditions => { :visible => true, :public_profile => true }
116 - # Subclasses must override these methods 112 +
  113 + # Subclasses must override this method
117 named_scope :more_popular 114 named_scope :more_popular
118 - named_scope :more_active  
119 115
  116 + named_scope :more_active, :order => 'activities_count DESC'
120 named_scope :more_recent, :order => "created_at DESC" 117 named_scope :more_recent, :order => "created_at DESC"
121 118
122 acts_as_trackable :dependent => :destroy 119 acts_as_trackable :dependent => :destroy
@@ -611,10 +608,10 @@ private :generate_url, :url_options @@ -611,10 +608,10 @@ private :generate_url, :url_options
611 # Adds a person as member of this Profile. 608 # Adds a person as member of this Profile.
612 def add_member(person) 609 def add_member(person)
613 if self.has_members? 610 if self.has_members?
614 - if self.closed? && members_count > 0 611 + if self.closed? && members.count > 0
615 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) 612 AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person)
616 else 613 else
617 - self.affiliate(person, Profile::Roles.admin(environment.id)) if members_count == 0 614 + self.affiliate(person, Profile::Roles.admin(environment.id)) if members.count == 0
618 self.affiliate(person, Profile::Roles.member(environment.id)) 615 self.affiliate(person, Profile::Roles.member(environment.id))
619 end 616 end
620 else 617 else
config/initializers/activities_counter_cache.rb 0 → 100644
@@ -0,0 +1,4 @@ @@ -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 Delayed::Worker.backend = :active_record 1 Delayed::Worker.backend = :active_record
2 Delayed::Worker.max_attempts = 2 2 Delayed::Worker.max_attempts = 2
3 -Delayed::Worker.max_run_time = 10.minutes 3 +
  4 +class Delayed::Worker
  5 + def handle_failed_job_with_loggin(job, error)
  6 + handle_failed_job_without_loggin(job,error)
  7 + Delayed::Worker.logger.error(error.message)
  8 + Delayed::Worker.logger.error(error.backtrace.join("\n"))
  9 + end
  10 + alias_method_chain :handle_failed_job, :loggin
  11 +end
config/initializers/noosfero_extensions.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +require 'noosfero/role_assignment_ext'
  2 +require 'noosfero/action_tracker_ext'
db/migrate/20140312132212_add_indexes_for_article_search.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 # 9 #
10 # It's strongly recommended to check this file into your version control system. 10 # It's strongly recommended to check this file into your version control system.
11 11
12 -ActiveRecord::Schema.define(:version => 20140108132730) do 12 +ActiveRecord::Schema.define(:version => 20140314200103) do
13 13
14 create_table "abuse_reports", :force => true do |t| 14 create_table "abuse_reports", :force => true do |t|
15 t.integer "reporter_id" 15 t.integer "reporter_id"
@@ -140,6 +140,9 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -140,6 +140,9 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
140 t.integer "position" 140 t.integer "position"
141 end 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 add_index "articles", ["name"], :name => "index_articles_on_name" 146 add_index "articles", ["name"], :name => "index_articles_on_name"
144 add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id" 147 add_index "articles", ["parent_id"], :name => "index_articles_on_parent_id"
145 add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id" 148 add_index "articles", ["profile_id"], :name => "index_articles_on_profile_id"
@@ -429,6 +432,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -429,6 +432,7 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
429 t.integer "image_id" 432 t.integer "image_id"
430 end 433 end
431 434
  435 + add_index "products", ["created_at"], :name => "index_products_on_created_at"
432 add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id" 436 add_index "products", ["enterprise_id"], :name => "index_products_on_enterprise_id"
433 add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id" 437 add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id"
434 438
@@ -465,10 +469,17 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do @@ -465,10 +469,17 @@ ActiveRecord::Schema.define(:version =&gt; 20140108132730) do
465 t.boolean "is_template", :default => false 469 t.boolean "is_template", :default => false
466 t.integer "template_id" 470 t.integer "template_id"
467 t.string "redirection_after_login" 471 t.string "redirection_after_login"
  472 + t.integer "friends_count", :default => 0, :null => false
  473 + t.integer "members_count", :default => 0, :null => false
  474 + t.integer "activities_count", :default => 0, :null => false
468 end 475 end
469 476
  477 + add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count"
  478 + add_index "profiles", ["created_at"], :name => "index_profiles_on_created_at"
470 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" 479 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
  480 + add_index "profiles", ["friends_count"], :name => "index_profiles_on_friends_count"
471 add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" 481 add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier"
  482 + add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count"
472 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" 483 add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id"
473 484
474 create_table "qualifier_certifiers", :force => true do |t| 485 create_table "qualifier_certifiers", :force => true do |t|
lib/activities_counter_cache_job.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -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/noosfero/action_tracker_ext.rb 0 → 100644
@@ -0,0 +1,21 @@ @@ -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 @@ @@ -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
test/functional/invite_controller_test.rb
@@ -230,7 +230,8 @@ class InviteControllerTest &lt; ActionController::TestCase @@ -230,7 +230,8 @@ class InviteControllerTest &lt; ActionController::TestCase
230 230
231 contact_list = ContactList.create 231 contact_list = ContactList.create
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 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 end 235 end
235 236
236 private 237 private
test/functional/profile_controller_test.rb
@@ -766,23 +766,28 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -766,23 +766,28 @@ class ProfileControllerTest &lt; ActionController::TestCase
766 end 766 end
767 767
768 should 'see all the activities in the current profile network' do 768 should 'see all the activities in the current profile network' do
769 - p1= Person.first 769 + p1= fast_create(Person)
770 p2= fast_create(Person) 770 p2= fast_create(Person)
771 assert !p1.is_a_friend?(p2) 771 assert !p1.is_a_friend?(p2)
  772 +
772 p3= fast_create(Person) 773 p3= fast_create(Person)
773 p3.add_friend(p1) 774 p3.add_friend(p1)
774 assert p3.is_a_friend?(p1) 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 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 780 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
777 a1 = ActionTracker::Record.last 781 a1 = ActionTracker::Record.last
  782 +
778 UserStampSweeper.any_instance.stubs(:current_user).returns(p2) 783 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
779 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) 784 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
780 a2 = ActionTracker::Record.last 785 a2 = ActionTracker::Record.last
  786 +
781 UserStampSweeper.any_instance.stubs(:current_user).returns(p3) 787 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
782 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) 788 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
783 a3 = ActionTracker::Record.last 789 a3 = ActionTracker::Record.last
784 790
785 -  
786 @controller.stubs(:logged_in?).returns(true) 791 @controller.stubs(:logged_in?).returns(true)
787 user = mock() 792 user = mock()
788 user.stubs(:person).returns(p3) 793 user.stubs(:person).returns(p3)
@@ -792,24 +797,29 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -792,24 +797,29 @@ class ProfileControllerTest &lt; ActionController::TestCase
792 797
793 process_delayed_job_queue 798 process_delayed_job_queue
794 get :index, :profile => p1.identifier 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 end 802 end
799 803
800 should 'the network activity be visible only to profile followers' do 804 should 'the network activity be visible only to profile followers' do
801 - p1= Person.first 805 + p1= fast_create(Person)
802 p2= fast_create(Person) 806 p2= fast_create(Person)
803 assert !p1.is_a_friend?(p2) 807 assert !p1.is_a_friend?(p2)
  808 +
804 p3= fast_create(Person) 809 p3= fast_create(Person)
805 p3.add_friend(p1) 810 p3.add_friend(p1)
806 assert p3.is_a_friend?(p1) 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 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 816 Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
809 a1 = ActionTracker::Record.last 817 a1 = ActionTracker::Record.last
  818 +
810 UserStampSweeper.any_instance.stubs(:current_user).returns(p2) 819 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
811 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) 820 Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
812 a2 = ActionTracker::Record.last 821 a2 = ActionTracker::Record.last
  822 +
813 UserStampSweeper.any_instance.stubs(:current_user).returns(p3) 823 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
814 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) 824 Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
815 a3 = ActionTracker::Record.last 825 a3 = ActionTracker::Record.last
@@ -819,8 +829,9 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -819,8 +829,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
819 user.stubs(:person).returns(p2) 829 user.stubs(:person).returns(p2)
820 user.stubs(:login).returns('some') 830 user.stubs(:login).returns('some')
821 @controller.stubs(:current_user).returns(user) 831 @controller.stubs(:current_user).returns(user)
  832 +
822 get :index, :profile => p1.identifier 833 get :index, :profile => p1.identifier
823 - assert_equal [], assigns(:network_activities) 834 + assert assigns(:network_activities).blank?
824 835
825 user = mock() 836 user = mock()
826 user.stubs(:person).returns(p3) 837 user.stubs(:person).returns(p3)
@@ -828,9 +839,9 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -828,9 +839,9 @@ class ProfileControllerTest &lt; ActionController::TestCase
828 @controller.stubs(:current_user).returns(user) 839 @controller.stubs(:current_user).returns(user)
829 Person.any_instance.stubs(:follows?).returns(true) 840 Person.any_instance.stubs(:follows?).returns(true)
830 process_delayed_job_queue 841 process_delayed_job_queue
  842 +
831 get :index, :profile => p3.identifier 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 end 845 end
835 846
836 should 'the network activity be paginated' do 847 should 'the network activity be paginated' do
test/functional/search_controller_test.rb
@@ -549,9 +549,9 @@ class SearchControllerTest &lt; ActionController::TestCase @@ -549,9 +549,9 @@ class SearchControllerTest &lt; ActionController::TestCase
549 c2 = create(Community, :name => 'Testing community 2') 549 c2 = create(Community, :name => 'Testing community 2')
550 c3 = create(Community, :name => 'Testing community 3') 550 c3 = create(Community, :name => 'Testing community 3')
551 ActionTracker::Record.delete_all 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 get :communities, :filter => 'more_active' 555 get :communities, :filter => 'more_active'
556 assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results] 556 assert_equal [c2,c1,c3] , assigns(:searches)[:communities][:results]
557 end 557 end
test/test_helper.rb
@@ -183,7 +183,7 @@ class ActiveSupport::TestCase @@ -183,7 +183,7 @@ class ActiveSupport::TestCase
183 if reference.first == value 183 if reference.first == value
184 reference.shift 184 reference.shift
185 else 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 end 187 end
188 end 188 end
189 end 189 end
test/unit/action_tracker_ext_test.rb 0 → 100644
@@ -0,0 +1,64 @@ @@ -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 @@ @@ -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
@@ -1625,10 +1625,10 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1625,10 +1625,10 @@ class ArticleTest &lt; ActiveSupport::TestCase
1625 1625
1626 should 'not allow all community members to edit by default' do 1626 should 'not allow all community members to edit by default' do
1627 community = fast_create(Community) 1627 community = fast_create(Community)
1628 - admin = create_user('community-admin').person  
1629 - member = create_user.person  
1630 - 1628 + admin = fast_create(Person)
  1629 + member = fast_create(Person)
1631 community.add_admin(admin) 1630 community.add_admin(admin)
  1631 + community.reload
1632 community.add_member(member) 1632 community.add_member(member)
1633 a = Article.new(:profile => community) 1633 a = Article.new(:profile => community)
1634 1634
test/unit/community_test.rb
@@ -213,8 +213,8 @@ class CommunityTest &lt; ActiveSupport::TestCase @@ -213,8 +213,8 @@ class CommunityTest &lt; ActiveSupport::TestCase
213 community = fast_create(Community) 213 community = fast_create(Community)
214 community.closed = true 214 community.closed = true
215 community.save 215 community.save
216 -  
217 community.add_member(fast_create(Person)) 216 community.add_member(fast_create(Person))
  217 + community.reload
218 218
219 assert_difference AddMember, :count do 219 assert_difference AddMember, :count do
220 community.add_member(person) 220 community.add_member(person)
test/unit/enterprise_test.rb
@@ -99,6 +99,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase @@ -99,6 +99,7 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
99 enterprise = fast_create(Enterprise) 99 enterprise = fast_create(Enterprise)
100 member = fast_create(Person) 100 member = fast_create(Person)
101 enterprise.add_member(member) 101 enterprise.add_member(member)
  102 + enterprise.reload
102 103
103 person = fast_create(Person) 104 person = fast_create(Person)
104 enterprise.add_member(person) 105 enterprise.add_member(person)
test/unit/organization_mailing_test.rb
@@ -62,18 +62,21 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase @@ -62,18 +62,21 @@ class OrganizationMailingTest &lt; ActiveSupport::TestCase
62 62
63 should 'deliver mailing to each member after create' do 63 should 'deliver mailing to each member after create' do
64 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) 64 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person)
  65 + community.reload
65 process_delayed_job_queue 66 process_delayed_job_queue
66 assert_equal 2, ActionMailer::Base.deliveries.count 67 assert_equal 2, ActionMailer::Base.deliveries.count
67 end 68 end
68 69
69 should 'deliver mailing when there are many mailings created' do 70 should 'deliver mailing when there are many mailings created' do
70 50.times { OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) } 71 50.times { OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) }
  72 + community.reload
71 process_delayed_job_queue 73 process_delayed_job_queue
72 assert_equal 50*community.members_count, ActionMailer::Base.deliveries.count 74 assert_equal 50*community.members_count, ActionMailer::Base.deliveries.count
73 end 75 end
74 76
75 should 'create mailing sent to each recipient after delivering mailing' do 77 should 'create mailing sent to each recipient after delivering mailing' do
76 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person) 78 mailing = OrganizationMailing.create(:source => community, :subject => 'Hello', :body => 'We have some news', :person => person)
  79 + community.reload
77 assert_difference MailingSent, :count, 2 do 80 assert_difference MailingSent, :count, 2 do
78 process_delayed_job_queue 81 process_delayed_job_queue
79 end 82 end
test/unit/organization_test.rb
@@ -302,18 +302,17 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -302,18 +302,17 @@ class OrganizationTest &lt; ActiveSupport::TestCase
302 end 302 end
303 303
304 should 'find more popular organizations' do 304 should 'find more popular organizations' do
305 - Organization.delete_all  
306 o1 = fast_create(Organization) 305 o1 = fast_create(Organization)
307 o2 = fast_create(Organization) 306 o2 = fast_create(Organization)
308 307
309 p1 = fast_create(Person) 308 p1 = fast_create(Person)
310 p2 = fast_create(Person) 309 p2 = fast_create(Person)
311 o1.add_member(p1) 310 o1.add_member(p1)
312 - assert_equal [o1,o2] , Organization.more_popular 311 + assert_order [o1,o2] , Organization.more_popular
313 312
314 o2.add_member(p1) 313 o2.add_member(p1)
315 o2.add_member(p2) 314 o2.add_member(p2)
316 - assert_equal [o2,o1] , Organization.more_popular 315 + assert_order [o2,o1] , Organization.more_popular
317 end 316 end
318 317
319 should 'list organizations that have no members in more popular list' do 318 should 'list organizations that have no members in more popular list' do
@@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -331,6 +330,7 @@ class OrganizationTest &lt; ActiveSupport::TestCase
331 person = fast_create(Person) 330 person = fast_create(Person)
332 organization = fast_create(Organization) 331 organization = fast_create(Organization)
333 organization.add_member(person) 332 organization.add_member(person)
  333 + organization.reload
334 334
335 assert_equal "one member", organization.more_popular_label 335 assert_equal "one member", organization.more_popular_label
336 end 336 end
@@ -342,47 +342,30 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -342,47 +342,30 @@ class OrganizationTest &lt; ActiveSupport::TestCase
342 342
343 organization.add_member(person1) 343 organization.add_member(person1)
344 organization.add_member(person2) 344 organization.add_member(person2)
  345 + organization.reload
345 assert_equal "2 members", organization.more_popular_label 346 assert_equal "2 members", organization.more_popular_label
346 347
347 person3 = fast_create(Person) 348 person3 = fast_create(Person)
348 organization.add_member(person3) 349 organization.add_member(person3)
  350 + organization.reload
349 assert_equal "3 members", organization.more_popular_label 351 assert_equal "3 members", organization.more_popular_label
350 end 352 end
351 353
352 should 'find more active organizations' do 354 should 'find more active organizations' do
353 person = fast_create(Person) 355 person = fast_create(Person)
354 - Organization.destroy_all  
355 p1 = fast_create(Organization) 356 p1 = fast_create(Organization)
356 p2 = fast_create(Organization) 357 p2 = fast_create(Organization)
357 p3 = fast_create(Organization) 358 p3 = fast_create(Organization)
358 359
359 ActionTracker::Record.destroy_all 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 end 369 end
387 370
388 should 'list profiles that have no actions in more active list' do 371 should 'list profiles that have no actions in more active list' do
@@ -422,4 +405,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -422,4 +405,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase
422 assert !organization.visible 405 assert !organization.visible
423 end 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 end 428 end
test/unit/person_test.rb
@@ -404,15 +404,14 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -404,15 +404,14 @@ class PersonTest &lt; ActiveSupport::TestCase
404 404
405 should 'not allow simple member to view group pending tasks' do 405 should 'not allow simple member to view group pending tasks' do
406 community = fast_create(Community) 406 community = fast_create(Community)
  407 + admin = fast_create(Person)
  408 + community.add_member(admin)
407 member = fast_create(Person) 409 member = fast_create(Person)
  410 + community.reload
408 community.add_member(member) 411 community.add_member(member)
409 -  
410 community.tasks << Task.new 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 end 415 end
417 416
418 should 'person has organization pending tasks' do 417 should 'person has organization pending tasks' do
@@ -642,16 +641,18 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -642,16 +641,18 @@ class PersonTest &lt; ActiveSupport::TestCase
642 end 641 end
643 642
644 should 'find more popular people' do 643 should 'find more popular people' do
  644 + extend CacheCounterHelper
  645 +
645 Person.delete_all 646 Person.delete_all
646 p1 = fast_create(Person) 647 p1 = fast_create(Person)
647 p2 = fast_create(Person) 648 p2 = fast_create(Person)
648 p3 = fast_create(Person) 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 end 656 end
656 657
657 should 'list people that have no friends in more popular list' do 658 should 'list people that have no friends in more popular list' do
@@ -891,6 +892,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -891,6 +892,7 @@ class PersonTest &lt; ActiveSupport::TestCase
891 p1 = fast_create(Person) 892 p1 = fast_create(Person)
892 p2 = fast_create(Person) 893 p2 = fast_create(Person)
893 p3 = fast_create(Person) 894 p3 = fast_create(Person)
  895 + p4 = fast_create(Person)
894 896
895 community.add_member(p1) 897 community.add_member(p1)
896 assert p1.is_member_of?(community) 898 assert p1.is_member_of?(community)
@@ -901,14 +903,15 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -901,14 +903,15 @@ class PersonTest &lt; ActiveSupport::TestCase
901 903
902 action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article') 904 action_tracker = fast_create(ActionTracker::Record, :verb => 'create_article')
903 action_tracker.target = community 905 action_tracker.target = community
  906 + action_tracker.user = p4
904 action_tracker.save! 907 action_tracker.save!
905 ActionTrackerNotification.delete_all 908 ActionTrackerNotification.delete_all
906 - assert_difference(ActionTrackerNotification, :count, 3) do 909 + assert_difference(ActionTrackerNotification, :count, 4) do
907 Person.notify_activity(action_tracker) 910 Person.notify_activity(action_tracker)
908 process_delayed_job_queue 911 process_delayed_job_queue
909 end 912 end
910 ActionTrackerNotification.all.map{|a|a.profile}.map do |profile| 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 end 915 end
913 end 916 end
914 917
@@ -1011,9 +1014,9 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1011,9 +1014,9 @@ class PersonTest &lt; ActiveSupport::TestCase
1011 1014
1012 should 'the community specific notification created when a member joins community could not be propagated to members' do 1015 should 'the community specific notification created when a member joins community could not be propagated to members' do
1013 ActionTracker::Record.delete_all 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 c = fast_create(Community, :name => "Foo") 1020 c = fast_create(Community, :name => "Foo")
1018 c.add_member(p1) 1021 c.add_member(p1)
1019 process_delayed_job_queue 1022 process_delayed_job_queue
@@ -1133,30 +1136,14 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1133,30 +1136,14 @@ class PersonTest &lt; ActiveSupport::TestCase
1133 p3 = fast_create(Person) 1136 p3 = fast_create(Person)
1134 1137
1135 ActionTracker::Record.destroy_all 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)  
1142 -  
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 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')
1150 1145
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 end 1147 end
1161 1148
1162 should 'list profiles that have no actions in more active list' do 1149 should 'list profiles that have no actions in more active list' do
@@ -1363,7 +1350,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1363,7 +1350,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1363 u = create_user('user'+i.to_s) 1350 u = create_user('user'+i.to_s)
1364 u.deactivate 1351 u.deactivate
1365 } 1352 }
1366 - assert_equal activated, Person.activated 1353 + assert_equivalent activated, Person.activated
1367 end 1354 end
1368 1355
1369 should 'deactivated named_scope return persons who are deactivated users' do 1356 should 'deactivated named_scope return persons who are deactivated users' do
@@ -1379,7 +1366,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1379,7 +1366,7 @@ class PersonTest &lt; ActiveSupport::TestCase
1379 u = create_user('user'+i.to_s) 1366 u = create_user('user'+i.to_s)
1380 u.activate 1367 u.activate
1381 } 1368 }
1382 - assert_equal deactivated, Person.deactivated 1369 + assert_equivalent deactivated, Person.deactivated
1383 end 1370 end
1384 1371
1385 should 'be able to retrieve memberships by role person has' do 1372 should 'be able to retrieve memberships by role person has' do
@@ -1413,4 +1400,31 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1413,4 +1400,31 @@ class PersonTest &lt; ActiveSupport::TestCase
1413 person.reload 1400 person.reload
1414 assert_equal person.activities, [] 1401 assert_equal person.activities, []
1415 end 1402 end
  1403 +
  1404 + should 'increase friends_count on new friendship' do
  1405 + person = create_user('person').person
  1406 + friend = create_user('friend').person
  1407 + assert_difference person, :friends_count, 1 do
  1408 + assert_difference friend, :friends_count, 1 do
  1409 + person.add_friend(friend)
  1410 + friend.reload
  1411 + end
  1412 + person.reload
  1413 + end
  1414 + end
  1415 +
  1416 + should 'decrease friends_count on friendship removal' do
  1417 + person = create_user('person').person
  1418 + friend = create_user('friend').person
  1419 + person.add_friend(friend)
  1420 + friend.reload
  1421 + person.reload
  1422 + assert_difference person, :friends_count, -1 do
  1423 + assert_difference friend, :friends_count, -1 do
  1424 + person.remove_friend(friend)
  1425 + friend.reload
  1426 + end
  1427 + person.reload
  1428 + end
  1429 + end
1416 end 1430 end
test/unit/profile_test.rb
@@ -1688,6 +1688,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1688,6 +1688,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1688 person = fast_create(Person) 1688 person = fast_create(Person)
1689 community = fast_create(Community) 1689 community = fast_create(Community)
1690 community.add_member(person) 1690 community.add_member(person)
  1691 + community.reload
1691 1692
1692 assert_equal 1, community.members_count 1693 assert_equal 1, community.members_count
1693 end 1694 end
@@ -1801,11 +1802,12 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1801,11 +1802,12 @@ class ProfileTest &lt; ActiveSupport::TestCase
1801 original_community.add_member(original_member) 1802 original_community.add_member(original_member)
1802 community1.add_member(plugin1_member) 1803 community1.add_member(plugin1_member)
1803 community2.add_member(plugin2_member) 1804 community2.add_member(plugin2_member)
  1805 + original_community.reload
1804 1806
1805 assert_includes original_community.members, original_member 1807 assert_includes original_community.members, original_member
1806 assert_includes original_community.members, plugin1_member 1808 assert_includes original_community.members, plugin1_member
1807 assert_includes original_community.members, plugin2_member 1809 assert_includes original_community.members, plugin2_member
1808 - assert 3, original_community.members.count 1810 + assert 3, original_community.members_count
1809 end 1811 end
1810 1812
1811 private 1813 private
test/unit/role_assignment_ext_test.rb 0 → 100644
@@ -0,0 +1,29 @@ @@ -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/uploaded_file_test.rb
@@ -316,12 +316,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -316,12 +316,13 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
316 316
317 should 'group trackers activity of image\'s upload' do 317 should 'group trackers activity of image\'s upload' do
318 gallery = fast_create(Gallery, :profile_id => profile.id) 318 gallery = fast_create(Gallery, :profile_id => profile.id)
319 - 319 + count = ActionTracker::Record.find_all_by_verb('upload_image').count
320 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile) 320 image1 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => gallery, :profile => profile)
321 - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count 321 + count += 1
  322 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
322 323
323 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile) 324 image2 = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/other-pic.jpg', 'image/jpg'), :parent => gallery, :profile => profile)
324 - assert_equal 1, ActionTracker::Record.find_all_by_verb('upload_image').count 325 + assert_equal count, ActionTracker::Record.find_all_by_verb('upload_image').count
325 end 326 end
326 327
327 { 328 {
vendor/plugins/action_tracker/lib/action_tracker_model.rb
1 module ActionTracker 1 module ActionTracker
2 class Record < ActiveRecord::Base 2 class Record < ActiveRecord::Base
3 -  
4 set_table_name 'action_tracker' 3 set_table_name 'action_tracker'
5 4
6 belongs_to :user, :polymorphic => true 5 belongs_to :user, :polymorphic => true