Commit cb35a9eb295f8c940328c7b666cd10f0ae86cda6

Authored by Daniela Feitosa
2 parents 93103d85 c40d3969

Merge branch '0.37-rc2' into AI1826

Conflicts:
	test/unit/article_test.rb
Showing 86 changed files with 1631 additions and 771 deletions   Show diff stats
app/controllers/public/profile_controller.rb
@@ -3,17 +3,15 @@ class ProfileController < PublicController @@ -3,17 +3,15 @@ class ProfileController < PublicController
3 needs_profile 3 needs_profile
4 before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] 4 before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add]
5 before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse] 5 before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse]
6 - before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_scraps, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report] 6 + before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity]
7 7
8 helper TagsHelper 8 helper TagsHelper
9 9
10 def index 10 def index
11 - @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page])  
12 - @wall_items = []  
13 - @network_activities = !@profile.is_a?(Person) ? @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) : [] 11 + @network_activities = !@profile.is_a?(Person) ? @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page]) : []
14 if logged_in? && current_person.follows?(@profile) 12 if logged_in? && current_person.follows?(@profile)
15 - @network_activities = @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) if @network_activities.empty?  
16 - @wall_items = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) 13 + @network_activities = @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page]) if @network_activities.empty?
  14 + @activities = @profile.activities.paginate(:per_page => 15, :page => params[:page])
17 end 15 end
18 @tags = profile.article_tags 16 @tags = profile.article_tags
19 unless profile.display_info_to?(user) 17 unless profile.display_info_to?(user)
@@ -180,22 +178,33 @@ class ProfileController < PublicController @@ -180,22 +178,33 @@ class ProfileController < PublicController
180 @scrap.receiver= receiver 178 @scrap.receiver= receiver
181 @tab_action = params[:tab_action] 179 @tab_action = params[:tab_action]
182 @message = @scrap.save ? _("Message successfully sent.") : _("You can't leave an empty message.") 180 @message = @scrap.save ? _("Message successfully sent.") : _("You can't leave an empty message.")
183 - @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil?  
184 - render :partial => 'leave_scrap' 181 + activities = @profile.activities.paginate(:per_page => 15, :page => params[:page]) if params[:not_load_scraps].nil?
  182 + render :partial => 'profile_activities_list', :locals => {:activities => activities}
185 end 183 end
186 184
187 - def view_more_scraps  
188 - @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page])  
189 - render :partial => 'profile_scraps', :locals => {:scraps => @scraps} 185 + def leave_comment_on_activity
  186 + @comment = Comment.new(params[:comment])
  187 + @comment.author = user
  188 + @activity = ActionTracker::Record.find(params[:source_id])
  189 + @comment.source_type, @comment.source_id = (@activity.target_type == 'Article' ? ['Article', @activity.target_id] : [@activity.class.to_s, @activity.id])
  190 + @tab_action = params[:tab_action]
  191 + @message = @comment.save ? _("Comment successfully added.") : _("You can't leave an empty comment.")
  192 + if @tab_action == 'wall'
  193 + activities = @profile.activities.paginate(:per_page => 15, :page => params[:page]) if params[:not_load_scraps].nil?
  194 + render :partial => 'profile_activities_list', :locals => {:activities => activities}
  195 + else
  196 + network_activities = @profile.tracked_notifications.visible.paginate(:per_page => 15, :page => params[:page])
  197 + render :partial => 'profile_network_activities', :locals => {:network_activities => network_activities}
  198 + end
190 end 199 end
191 200
192 def view_more_activities 201 def view_more_activities
193 - @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page])  
194 - render :partial => 'profile_activities', :locals => {:activities => @activities} 202 + @activities = @profile.activities.paginate(:per_page => 10, :page => params[:page])
  203 + render :partial => 'profile_activities_list', :locals => {:activities => @activities}
195 end 204 end
196 205
197 def view_more_network_activities 206 def view_more_network_activities
198 - @activities = @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) 207 + @activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page])
199 render :partial => 'profile_network_activities', :locals => {:network_activities => @activities} 208 render :partial => 'profile_network_activities', :locals => {:network_activities => @activities}
200 end 209 end
201 210
@@ -213,7 +222,11 @@ class ProfileController < PublicController @@ -213,7 +222,11 @@ class ProfileController < PublicController
213 begin 222 begin
214 raise if !can_edit_profile 223 raise if !can_edit_profile
215 activity = ActionTracker::Record.find(params[:activity_id]) 224 activity = ActionTracker::Record.find(params[:activity_id])
216 - activity.destroy 225 + if params[:only_hide]
  226 + activity.update_attribute(:visible, false)
  227 + else
  228 + activity.destroy
  229 + end
217 render :text => _('Activity successfully removed.') 230 render :text => _('Activity successfully removed.')
218 rescue 231 rescue
219 render :text => _('You could not remove this activity') 232 render :text => _('You could not remove this activity')
@@ -285,6 +298,16 @@ class ProfileController < PublicController @@ -285,6 +298,16 @@ class ProfileController < PublicController
285 end 298 end
286 end 299 end
287 300
  301 + def remove_comment
  302 + #FIXME Check whether these permissions are enough
  303 + @comment = Comment.find(params[:comment_id])
  304 + if (user == @comment.author || user == profile || user.has_permission?(:moderate_comments, profile))
  305 + @comment.destroy
  306 + session[:notice] = _('Comment successfully deleted')
  307 + end
  308 + redirect_to :action => :index
  309 + end
  310 +
288 protected 311 protected
289 312
290 def check_access_to_profile 313 def check_access_to_profile
app/helpers/application_helper.rb
@@ -1217,15 +1217,12 @@ module ApplicationHelper @@ -1217,15 +1217,12 @@ module ApplicationHelper
1217 else _('1 minute') 1217 else _('1 minute')
1218 end 1218 end
1219 1219
1220 - when 2..44 then _('%{distance} minutes') % { :distance => distance_in_minutes }  
1221 - when 45..89 then _('about 1 hour')  
1222 - when 90..1439 then _('about %{distance} hours') % { :distance => (distance_in_minutes.to_f / 60.0).round }  
1223 - when 1440..2879 then _('1 day')  
1224 - when 2880..43199 then _('%{distance} days') % { :distance => (distance_in_minutes / 1440).round }  
1225 - when 43200..86399 then _('about 1 month')  
1226 - when 86400..525599 then _('%{distance} months') % { :distance => (distance_in_minutes / 43200).round }  
1227 - when 525600..1051199 then _('about 1 year')  
1228 - else _('over %{distance} years') % { :distance => (distance_in_minutes / 525600).round } 1220 + when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes }
  1221 + when 45..89 then _('about 1 hour ago')
  1222 + when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round }
  1223 + when 1440..2879 then _('1 day ago')
  1224 + when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round }
  1225 + else show_time(from_time)
1229 end 1226 end
1230 end 1227 end
1231 1228
app/helpers/forum_helper.rb
@@ -42,9 +42,9 @@ module ForumHelper @@ -42,9 +42,9 @@ module ForumHelper
42 def last_topic_update(article) 42 def last_topic_update(article)
43 info = article.info_from_last_update 43 info = article.info_from_last_update
44 if info[:author_url] 44 if info[:author_url]
45 - time_ago_as_sentence(info[:date]) + ' ' + _('ago') + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url]) 45 + time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + link_to(info[:author_name], info[:author_url])
46 else 46 else
47 - time_ago_as_sentence(info[:date]) + ' ' + _('ago') + ' ' + _('by') + ' ' + info[:author_name] 47 + time_ago_as_sentence(info[:date]) + ' ' + _('by') + ' ' + info[:author_name]
48 end 48 end
49 end 49 end
50 50
app/models/action_tracker_notification.rb
@@ -3,6 +3,8 @@ class ActionTrackerNotification < ActiveRecord::Base @@ -3,6 +3,8 @@ class ActionTrackerNotification < ActiveRecord::Base
3 belongs_to :profile 3 belongs_to :profile
4 belongs_to :action_tracker, :class_name => 'ActionTracker::Record', :foreign_key => 'action_tracker_id' 4 belongs_to :action_tracker, :class_name => 'ActionTracker::Record', :foreign_key => 'action_tracker_id'
5 5
  6 + has_many :comments, :through => :action_tracker, :class_name => 'Comment', :foreign_key => 'source_id'
  7 +
6 validates_presence_of :profile_id, :action_tracker_id 8 validates_presence_of :profile_id, :action_tracker_id
7 validates_uniqueness_of :action_tracker_id, :scope => :profile_id 9 validates_uniqueness_of :action_tracker_id, :scope => :profile_id
8 10
app/models/article.rb
@@ -2,9 +2,7 @@ require 'hpricot' @@ -2,9 +2,7 @@ require 'hpricot'
2 2
3 class Article < ActiveRecord::Base 3 class Article < ActiveRecord::Base
4 4
5 - track_actions :create_article, :after_create, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target  
6 - track_actions :update_article, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && (a.body_changed? || a.name_changed?) }, :custom_target => :action_tracker_target  
7 - track_actions :remove_article, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_target => :action_tracker_target 5 + track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead, :first_image], :if => Proc.new { |a| a.is_trackable? && !a.image? }
8 6
9 # xss_terminate plugin can't sanitize array fields 7 # xss_terminate plugin can't sanitize array fields
10 before_save :sanitize_tag_list 8 before_save :sanitize_tag_list
@@ -17,7 +15,7 @@ class Article &lt; ActiveRecord::Base @@ -17,7 +15,7 @@ class Article &lt; ActiveRecord::Base
17 15
18 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' 16 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
19 17
20 - has_many :comments, :dependent => :destroy, :order => 'created_at asc' 18 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc'
21 19
22 has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ] 20 has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ]
23 has_many :categories, :through => :article_categorizations 21 has_many :categories, :through => :article_categorizations
@@ -65,7 +63,7 @@ class Article &lt; ActiveRecord::Base @@ -65,7 +63,7 @@ class Article &lt; ActiveRecord::Base
65 validate :translation_must_have_language 63 validate :translation_must_have_language
66 64
67 def is_trackable? 65 def is_trackable?
68 - self.published? && self.notifiable? && self.advertise? 66 + self.published? && self.notifiable? && self.advertise? && self.profile.public_profile
69 end 67 end
70 68
71 def external_link=(link) 69 def external_link=(link)
@@ -135,7 +133,7 @@ class Article &lt; ActiveRecord::Base @@ -135,7 +133,7 @@ class Article &lt; ActiveRecord::Base
135 before_update do |article| 133 before_update do |article|
136 article.advertise = true 134 article.advertise = true
137 end 135 end
138 - 136 +
139 # retrieves all articles belonging to the given +profile+ that are not 137 # retrieves all articles belonging to the given +profile+ that are not
140 # sub-articles of any other article. 138 # sub-articles of any other article.
141 named_scope :top_level_for, lambda { |profile| 139 named_scope :top_level_for, lambda { |profile|
@@ -571,6 +569,21 @@ class Article &lt; ActiveRecord::Base @@ -571,6 +569,21 @@ class Article &lt; ActiveRecord::Base
571 _('Created at: ') 569 _('Created at: ')
572 end 570 end
573 571
  572 + def activity
  573 + ActionTracker::Record.find_by_target_type_and_target_id 'Article', self.id
  574 + end
  575 +
  576 + def create_activity
  577 + if is_trackable? && !image?
  578 + save_action_for_verb 'create_article', [:name, :url, :lead, :first_image], Proc.new{}, :author
  579 + end
  580 + end
  581 +
  582 + def first_image
  583 + img = Hpricot(self.lead.to_s).search('img[@src]').first || Hpricot(self.body.to_s).search('img').first
  584 + img.nil? ? '' : img.attributes['src']
  585 + end
  586 +
574 private 587 private
575 588
576 def sanitize_tag_list 589 def sanitize_tag_list
app/models/comment.rb
1 class Comment < ActiveRecord::Base 1 class Comment < ActiveRecord::Base
2 2
3 - track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target  
4 -  
5 validates_presence_of :body 3 validates_presence_of :body
6 - belongs_to :article, :counter_cache => true 4 +
  5 + belongs_to :source, :counter_cache => true, :polymorphic => true
  6 + alias :article :source
  7 + alias :article= :source=
  8 +
7 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' 9 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id'
8 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy 10 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy
9 belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' 11 belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id'
@@ -70,13 +72,25 @@ class Comment &lt; ActiveRecord::Base @@ -70,13 +72,25 @@ class Comment &lt; ActiveRecord::Base
70 after_save :notify_article 72 after_save :notify_article
71 after_destroy :notify_article 73 after_destroy :notify_article
72 def notify_article 74 def notify_article
73 - article.comments_updated 75 + article.comments_updated if article.kind_of?(Article)
74 end 76 end
75 77
76 after_create do |comment| 78 after_create do |comment|
77 - if comment.article.notify_comments? && !comment.article.profile.notification_emails.empty? 79 + if comment.source.kind_of?(Article) && comment.article.notify_comments? && !comment.article.profile.notification_emails.empty?
78 Comment::Notifier.deliver_mail(comment) 80 Comment::Notifier.deliver_mail(comment)
79 end 81 end
  82 +
  83 + if comment.source.kind_of?(Article)
  84 + comment.article.create_activity if comment.article.activity.nil?
  85 + if comment.article.activity
  86 + comment.article.activity.increment!(:comments_count)
  87 + comment.article.activity.update_attribute(:visible, true)
  88 + end
  89 + end
  90 + end
  91 +
  92 + after_destroy do |comment|
  93 + comment.article.activity.decrement!(:comments_count) if comment.source.kind_of?(Article) && comment.article.activity
80 end 94 end
81 95
82 def replies 96 def replies
app/models/community.rb
@@ -79,4 +79,8 @@ class Community &lt; Organization @@ -79,4 +79,8 @@ class Community &lt; Organization
79 {:title => __('Community Info and settings'), :icon => 'edit-profile-group'} 79 {:title => __('Community Info and settings'), :icon => 'edit-profile-group'}
80 end 80 end
81 81
  82 + def activities
  83 + Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY action_tracker.updated_at DESC")
  84 + end
  85 +
82 end 86 end
app/models/enterprise.rb
@@ -181,4 +181,8 @@ class Enterprise &lt; Organization @@ -181,4 +181,8 @@ class Enterprise &lt; Organization
181 true 181 true
182 end 182 end
183 183
  184 + def activities
  185 + Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY action_tracker.updated_at DESC")
  186 + end
  187 +
184 end 188 end
app/models/event.rb
@@ -120,6 +120,10 @@ class Event &lt; Article @@ -120,6 +120,10 @@ class Event &lt; Article
120 true 120 true
121 end 121 end
122 122
  123 + def notifiable?
  124 + true
  125 + end
  126 +
123 include Noosfero::TranslatableContent 127 include Noosfero::TranslatableContent
124 include MaybeAddHttp 128 include MaybeAddHttp
125 129
app/models/external_feed.rb
@@ -14,6 +14,7 @@ class ExternalFeed &lt; ActiveRecord::Base @@ -14,6 +14,7 @@ class ExternalFeed &lt; ActiveRecord::Base
14 article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog) 14 article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog)
15 unless blog.children.exists?(:slug => article.slug) 15 unless blog.children.exists?(:slug => article.slug)
16 article.save! 16 article.save!
  17 + article.delay.create_activity
17 end 18 end
18 end 19 end
19 20
app/models/forum.rb
@@ -24,4 +24,14 @@ class Forum &lt; Folder @@ -24,4 +24,14 @@ class Forum &lt; Folder
24 def self.icon_name(article = nil) 24 def self.icon_name(article = nil)
25 'forum' 25 'forum'
26 end 26 end
  27 +
  28 + def notifiable?
  29 + true
  30 + end
  31 +
  32 + def first_paragraph
  33 + return '' if body.blank?
  34 + paragraphs = Hpricot(body).search('p')
  35 + paragraphs.empty? ? '' : paragraphs.first.to_html
  36 + end
27 end 37 end
app/models/person.rb
@@ -435,6 +435,10 @@ class Person &lt; Profile @@ -435,6 +435,10 @@ class Person &lt; Profile
435 user.save! 435 user.save!
436 end 436 end
437 437
  438 + def activities
  439 + Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.user_id = #{self.id} ORDER BY updated_at DESC")
  440 + end
  441 +
438 protected 442 protected
439 443
440 def followed_by?(profile) 444 def followed_by?(profile)
app/models/profile.rb
@@ -822,6 +822,10 @@ private :generate_url, :url_options @@ -822,6 +822,10 @@ private :generate_url, :url_options
822 name 822 name
823 end 823 end
824 824
  825 + # Override in your subclasses
  826 + def activities
  827 + []
  828 + end
825 protected 829 protected
826 830
827 def followed_by?(person) 831 def followed_by?(person)
app/models/scrap.rb
@@ -12,6 +12,7 @@ class Scrap &lt; ActiveRecord::Base @@ -12,6 +12,7 @@ class Scrap &lt; ActiveRecord::Base
12 named_scope :not_replies, :conditions => {:scrap_id => nil} 12 named_scope :not_replies, :conditions => {:scrap_id => nil}
13 13
14 track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.receiver != s.sender}, :custom_target => :action_tracker_target 14 track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.receiver != s.sender}, :custom_target => :action_tracker_target
  15 +
15 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.receiver == s.sender} 16 track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.receiver == s.sender}
16 17
17 after_create do |scrap| 18 after_create do |scrap|
app/models/uploaded_file.rb
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 # of the file itself is kept. (FIXME?) 4 # of the file itself is kept. (FIXME?)
5 class UploadedFile < Article 5 class UploadedFile < Article
6 6
7 - track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? } 7 + track_actions :upload_image, :after_create, :keep_params => ["view_url", "thumbnail_path", "parent.url", "parent.name"], :if => Proc.new { |a| a.published? && a.image? && !a.parent.nil? && a.parent.gallery? }, :custom_target => :action_tracker_target
8 8
9 include ShortFilename 9 include ShortFilename
10 10
@@ -25,7 +25,7 @@ class UploadedFile &lt; Article @@ -25,7 +25,7 @@ class UploadedFile &lt; Article
25 end 25 end
26 26
27 def thumbnail_path 27 def thumbnail_path
28 - self.image? ? self.full_filename(:thumb).gsub(File.join(RAILS_ROOT, 'public'), '') : nil 28 + self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil
29 end 29 end
30 30
31 def display_title 31 def display_title
@@ -140,4 +140,9 @@ class UploadedFile &lt; Article @@ -140,4 +140,9 @@ class UploadedFile &lt; Article
140 def uploaded_file? 140 def uploaded_file?
141 true 141 true
142 end 142 end
  143 +
  144 + def action_tracker_target
  145 + self
  146 + end
  147 +
143 end 148 end
app/views/profile/_add_member_in_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => { :activity => activity, :tab_action => tab_action } %>
app/views/profile/_comment.rhtml 0 → 100644
@@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
  1 +<% Comment %>
  2 +<% Profile %>
  3 +<% Person %>
  4 +
  5 +<li class="article-comment" style='border-bottom:none;'>
  6 + <div class="article-comment-inner">
  7 +
  8 + <div class="comment-content comment-logged-in">
  9 +
  10 + <% if comment.author %>
  11 + <%= link_to image_tag(profile_icon(comment.author, :minor)),
  12 + Person.find(comment.author_id).url,
  13 + :class => 'comment-picture',
  14 + :title => comment.author_name
  15 + %>
  16 + <% end %>
  17 +
  18 + <div class="comment-details">
  19 + <div class="comment-text">
  20 + <%= link_to(comment.author_name, comment.author.url) %> <%= txt2html comment.body %>
  21 + </div>
  22 + <div class="profile-activity-time">
  23 + <%= time_ago_as_sentence(comment.created_at) %>
  24 + </div>
  25 + </div>
  26 +
  27 + <% if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) %>
  28 + <% button_bar(:style => 'float: right; margin-top: 0px;') do %>
  29 + <%= icon_button(:delete, _('Remove'), { :action => :remove_comment, :comment_id => comment.id }, :method => :get, :confirm => _('Are you sure you want to remove this comment and all its replies?')) %>
  30 + <% end %>
  31 + <% end %>
  32 + <br style="clear: both;" />
  33 +
  34 + <div class="comment_reply post_comment_box closed">
  35 + <% if @comment && @comment.errors.any? && @comment.reply_of_id.to_i == comment.id %>
  36 + <%= error_messages_for :comment %>
  37 + <script type="text/javascript">
  38 + jQuery(function() {
  39 + document.location.href = '#<%= comment.anchor %>';
  40 + add_comment_reply_form('#comment-reply-to-<%= comment.id %>', <%= comment.id %>);
  41 + });
  42 + </script>
  43 + <% end %>
  44 + <%= report_abuse(comment.author, :comment_link, comment) if comment.author %>
  45 + <%= link_to_function _('Reply'),
  46 + "var f = add_comment_reply_form(this, %s); f.find('input[name=comment[title]], textarea').val(''); return false" % comment.id,
  47 + :class => 'comment-footer comment-footer-link comment-footer-hide',
  48 + :id => 'comment-reply-to-' + comment.id.to_s
  49 + %>
  50 + </div>
  51 +
  52 + </div>
  53 +
  54 + <% unless comment.replies.blank? %>
  55 + <ul class="comment-replies">
  56 + <% comment.replies.each do |reply| %>
  57 + <%= render :partial => 'comment', :locals => { :comment => reply } %>
  58 + <% end %>
  59 + </ul>
  60 + <% end %>
  61 +
  62 + </div>
  63 +</li>
app/views/profile/_create_article.rhtml 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +<div class='profile-activity-image'>
  2 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  3 +</div>
  4 +<div class='profile-activity-description profile-activity-article-<%= activity.target.class.icon_name %>'>
  5 + <p class='profile-activity-text'>
  6 + <%= link_to activity.user.short_name(20), activity.user.url %>
  7 + <%= _("on community %s") % link_to(activity.target.profile.short_name(20), activity.target.profile.url) if activity.target.profile.is_a?(Community) %>
  8 + </p>
  9 + <div class='profile-activity-lead'>
  10 + <b><%= link_to(activity.params['name'], activity.params['url']) %></b>
  11 + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span><br />
  12 + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(activity.params['lead']).gsub(/(\xA0|\xC2|\s)+/, ' ').gsub(/^\s+/, '') %> <small><%= link_to(_('See more'), activity.params['url']) unless activity.get_lead.blank? %></small>
  13 + </div>
  14 + <%= content_tag(:p, link_to(_('See complete forum'), activity.get_url), :class => 'see-forum') if activity.target.is_a?(Forum) %>
  15 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p>
  16 + <div class='profile-wall-actions'>
  17 + <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
  18 + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id, :only_hide => true}, :confirm => _('Are you sure?'), :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  19 + </div>
  20 +</div>
  21 +
  22 +<%= render :partial => 'profile_comments', :locals => { :activity => activity, :tab_action => tab_action } %>
app/views/profile/_default_activity.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<div class='profile-activity-image'>
  2 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  3 +</div>
  4 +<div class='profile-activity-description'>
  5 + <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
  6 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p>
  7 + <div class='profile-wall-actions'>
  8 + <%= link_to s_('profile|Comment'), '#', { :class => 'focus-on-comment'} %>
  9 + <%= link_to_remote(content_tag(:span, _('Remove')), :confirm => _('Are you sure?'), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  10 + </div>
  11 +</div>
  12 +
  13 +<%= render :partial => 'profile_comments', :locals => { :activity => activity, :tab_action => tab_action } %>
app/views/profile/_join_community.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_add_member_in_community.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/profile/_leave_comment_on_activity.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +NÃO É PRA APARECER
app/views/profile/_leave_scrap.rhtml
1 -<%= @message %>  
2 -<% unless @scraps.nil? %>  
3 - <%= render :partial => 'profile_scraps', :locals => {:scraps => @scraps} %>  
4 -<% end %> 1 +<div class='profile-activity-image'>
  2 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  3 +</div>
  4 +<div class='profile-activity-description'>
  5 + <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
  6 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p>
  7 + <div class='profile-wall-actions'>
  8 + <%= link_to_remote(content_tag(:span, _('Remove')), :confirm => _('Are you sure?'), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  9 + </div>
  10 +</div>
  11 +
  12 +<br/>
app/views/profile/_leave_scrap_to_self.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_leave_scrap.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/profile/_new_friendship.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_add_member_in_community.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/profile/_profile.rhtml
1 -<tr>  
2 - <td colspan='2'> 1 +NÃO DEVE APARECER
3 2
4 - <% plugins_tabs = @plugins.dispatch(:profile_tabs).  
5 - map { |tab| {:title => tab[:title], :id => tab[:id], :content => instance_eval(&tab[:content]), :start => tab[:title]} }%>  
6 -  
7 - <% tabs = plugins_tabs.select { |tab| tab[:start] } %>  
8 -  
9 - <% if logged_in? && current_person.follows?(@profile) %>  
10 - <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %>  
11 - <% end %>  
12 -  
13 - <% if @profile.organization? %>  
14 - <% tabs << {:title => _('What\'s new'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %>  
15 - <% tabs << {:title => _('Profile'), :id => 'organization-profile', :content => (render :partial => 'organization_profile')} %>  
16 - <% elsif @profile.person? %>  
17 - <% if logged_in? && current_person.follows?(@profile) %>  
18 - <% tabs << {:title => _('Network'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %>  
19 - <% end %>  
20 -  
21 - <% tabs << {:title => _('Activity'), :id => 'profile-activity', :content => (render :partial => 'profile_activity')} %>  
22 - <% tabs << {:title => _('Profile'), :id => 'person-profile', :content => (render :partial => 'person_profile')} %>  
23 - <% end %>  
24 -  
25 - <% tabs += plugins_tabs.select { |tab| !tab[:start] } %>  
26 -  
27 - <%= render_tabs(tabs) %>  
28 -  
29 - </td>  
30 -</tr>  
app/views/profile/_profile_activities.rhtml
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -<% activities.each do |activity| %>  
2 - <li class='profile-activity-item <%= activity.verb %>' id='profile-activity-item-<%= activity.id %>'>  
3 - <div class='profile-activity-image'>  
4 - <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>  
5 - </div>  
6 - <div class='profile-activity-description'>  
7 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p>  
8 - <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>  
9 - <%= button_to_remote(:delete, content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if can_edit_profile %>  
10 - </div>  
11 - <hr />  
12 - </li>  
13 -<% end %>  
14 -<% if activities.current_page < activities.total_pages %>  
15 - <div id='profile_activities_page_<%= activities.current_page %>'>  
16 - <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_activities', :page => (activities.current_page + 1)}, :update => "profile_activities_page_#{activities.current_page}" %>  
17 - </div>  
18 -<% end %>  
app/views/profile/_profile_activities_list.rhtml 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +<% unless activities.nil? %>
  2 + <% activities.each do |a| %>
  3 + <% activity = a.klass.constantize.find(a.id) %>
  4 + <% if activity.kind_of?(ActionTracker::Record) %>
  5 + <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %>
  6 + <% else %>
  7 + <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %>
  8 + <% end %>
  9 + <% end %>
  10 +<% end %>
  11 +
  12 +<% if activities.current_page < activities.total_pages %>
  13 + <div id='profile_activities_page_<%= activities.current_page %>'>
  14 + <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_activities', :page => (activities.current_page + 1)}, :update => "profile_activities_page_#{activities.current_page}" %>
  15 + </div>
  16 +<% end %>
app/views/profile/_profile_activities_scraps.rhtml 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +NÂO DEVE APARECER!!
  2 +
app/views/profile/_profile_activity.rhtml
1 -<div id='profile-activity'>  
2 - <h3><%= _("%s's activity") % @profile.name %></h3>  
3 - <ul>  
4 - <%= render :partial => 'profile_activities', :locals => {:activities => @activities} %>  
5 - </ul>  
6 -</div> 1 +<li class='profile-activity-item <%= activity.verb %>' id='profile-activity-item-<%= activity.id %>'>
  2 + <%= render :partial => activity.verb, :locals => { :activity => activity, :tab_action => tab_action }%>
  3 + <hr />
  4 +</li>
app/views/profile/_profile_comment_form.rhtml 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +<div id='profile-wall-reply-<%= activity.id%>'>
  2 + <div id='profile-wall-reply-form-<%= activity.id%>'>
  3 + <p class='profile-wall-reply'>
  4 + <% update_area = tab_action == 'wall' ? 'profile_activities' : 'network-activities' %>
  5 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_comment_on_activity', :tab_action => tab_action}, :html => { :class => 'profile-wall-reply-form', 'data-update' => update_area } do %>
  6 + <%= text_area :comment, :body, {:id => "reply_content_#{activity.id}",
  7 + :cols => 50,
  8 + :rows => 1,
  9 + :class => 'submit-with-keypress',
  10 + :title => _('Leave your comment'),
  11 + :onfocus => ('if(this.value==this.title){this.value="";this.style.color="#000"};this.style.backgroundImage="url(' + profile_icon(current_person, :icon, false) + ')"' if logged_in?),
  12 + :onblur => ('if(this.value==""){this.value=this.title;this.style.color="#ccc"};this.style.backgroundImage="none"' if logged_in?),
  13 + :value => _('Leave your comment'),
  14 + :style => 'color: #ccc' } %>
  15 + <%= hidden_field_tag :source_id, activity.id, :id => "activity_id_#{activity.id}" %>
  16 + <% end %>
  17 + </p>
  18 + </div>
  19 + <div id='profile-wall-message-response-<%=activity.id%>' class='profile-wall-message-response'></div>
  20 +</div>
app/views/profile/_profile_comments.rhtml 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +<hr />
  2 +
  3 +<% if activity.comments_count > 2 %>
  4 + <div class='view-all-comments icon-chat'>
  5 + <%= link_to(_("View all %s comments") % activity.comments_count, '#') %>
  6 + </div>
  7 +<% end %>
  8 +
  9 +<ul class="profile-wall-activities-comments" style="<%= 'display:none;' if (activity.comments_count > 2) %>" >
  10 + <%= render :partial => 'comment', :collection => activity.comments %>
  11 +</ul>
  12 +
  13 +<%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %>
app/views/profile/_profile_network.rhtml
1 <h3><%= _("%s's network activity") % @profile.name %></h3> 1 <h3><%= _("%s's network activity") % @profile.name %></h3>
2 -<ul> 2 +<ul id='network-activities' class='profile-activities'>
3 <%= render :partial => 'profile_network_activities', :locals => {:network_activities => @network_activities} %> 3 <%= render :partial => 'profile_network_activities', :locals => {:network_activities => @network_activities} %>
4 </ul> 4 </ul>
app/views/profile/_profile_network_activities.rhtml
1 - <% network_activities.each do |activity| %>  
2 - <li class='profile-network-item <%= activity.verb %>' id='profile-network-item-<%= activity.id %>'>  
3 - <div class='profile-network-image'>  
4 - <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>  
5 - <% if logged_in? && current_person.follows?(activity.user) && current_person != activity.user %>  
6 - <p class='profile-network-send-message'><%= link_to_function _('Scrap'), "hide_and_show(['#profile-network-message-response-#{activity.id}'],['#profile-network-message-#{activity.id}', '#profile-network-form-#{activity.id}']);$('content_#{activity.id}').value='';return false", :class => "profile-send-message", :title => _("Send a message to %s") % activity.user.name %></p>  
7 - <% end %>  
8 - </div>  
9 - <div class='profile-network-description'>  
10 - <p class='profile-network-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p>  
11 - <p class='profile-network-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>  
12 - <%= button_to_remote(:delete, content_tag(:span, _('Remove')), :url =>{:action => 'remove_notification', :activity_id => activity.id}, :update => "profile-network-item-#{activity.id}") if can_edit_profile %>  
13 - <p class='profile-network-where'><%= _('In community %s') % link_to(activity.target.name, activity.target.url) if !profile.is_a?(Community) && activity.target.is_a?(Community) %></p>  
14 - </div>  
15 - <div id='profile-network-message-<%= activity.id%>' style='display:none;'>  
16 - <div id='profile-network-form-<%= activity.id%>' style='display:none;'>  
17 - <p class='profile-network-message'>  
18 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :not_load_scraps => true}, :update => "profile-network-message-response-#{activity.id}", :success =>"hide_and_show(['#profile-network-form-#{activity.id}'],['#profile-network-message-response-#{activity.id}'])" do %>  
19 - <%= limited_text_area :scrap, :content, 420, "content_#{activity.id}", :cols => 50, :rows => 2 %>  
20 - <%= hidden_field_tag 'receiver_id', activity.user.id %>  
21 - <%= submit_button :add, _('Leave a message') %>  
22 - <%= button_to_function :cancel, _('Cancel'), "hide_and_show(['#profile-network-message-#{activity.id}'],[]);return false" %>  
23 - <% end %>  
24 - </p>  
25 - </div>  
26 - <div id='profile-network-message-response-<%=activity.id%>' class='profile-network-message-response'></div>  
27 - </div>  
28 - <hr />  
29 - </li>  
30 - <% end %> 1 +<% network_activities.each do |activity| %>
  2 + <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'network' } if activity.visible? %>
  3 +<% end %>
31 <% if network_activities.current_page < network_activities.total_pages %> 4 <% if network_activities.current_page < network_activities.total_pages %>
32 <div id='profile_network_activities_page_<%= network_activities.current_page %>'> 5 <div id='profile_network_activities_page_<%= network_activities.current_page %>'>
33 <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_network_activities', :page => (network_activities.current_page + 1)}, :update => "profile_network_activities_page_#{network_activities.current_page}" %> 6 <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_network_activities', :page => (network_activities.current_page + 1)}, :update => "profile_network_activities_page_#{network_activities.current_page}" %>
app/views/profile/_profile_scrap.rhtml
1 -<li class='profile-wall-item' id='profile-wall-item-<%= scrap.id %>'>  
2 - <div class='profile-wall-image'> 1 +<li class='profile-activity-item' id='profile-activity-item-<%= scrap.id %>'>
  2 + <div class='profile-activity-image'>
3 <%= link_to(profile_image(scrap.sender, :minor), scrap.sender.url) %> 3 <%= link_to(profile_image(scrap.sender, :minor), scrap.sender.url) %>
4 - <% if logged_in? && current_person.follows?(scrap.sender) && current_person != scrap.sender %>  
5 - <p class='profile-wall-send-message'><%= link_to_function _('Scrap'), "hide_and_show(['#profile-wall-message-response-#{scrap.id}'],['#profile-wall-message-#{scrap.id}', '#profile-wall-form-#{scrap.id}']);$('content_#{scrap.id}').value='';return false", :class => "profile-send-message", :title => _("Send a message to %s") % scrap.sender.name %></p>  
6 - <% end %>  
7 </div> 4 </div>
8 - <% comment_balloon :class => 'profile-wall-description' do %>  
9 - <p class='profile-wall-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>  
10 - <p class='profile-wall-time'><%= time_ago_as_sentence(scrap.created_at) + ' ' + _('ago') %></p>  
11 - <p class='profile-wall-text'><%= txt2html scrap.content %></p>  
12 - <%= button_to_remote(:delete, content_tag(:span, _('Remove')), :url =>{:action => 'remove_scrap', :scrap_id => scrap.id}, :update => "profile-wall-item-#{scrap.id}") if logged_in? && user.can_control_scrap?(scrap) %>  
13 - <% if logged_in? && current_person.follows?(scrap.sender) && scrap.root.nil? %>  
14 - <p class='profile-wall-send-reply'><%= link_to_function _('Reply'), "hide_and_show(['#profile-wall-reply-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('scrap_id_#{scrap.id}').value='#{scrap.id}';return false", :class => "profile-send-reply icon-reply" %></p> 5 + <div class='profile-activity-description'>
  6 + <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
  7 + <p class='profile-activity-text'><%= txt2html scrap.content %></p>
  8 + <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p>
  9 + <div class='profile-wall-actions'>
  10 + <% if logged_in? && current_person.follows?(scrap.sender) %>
  11 + <span class='profile-activity-send-reply'>
  12 + <%= link_to_function s_('profile|Comment'), "hide_and_show(['#profile-wall-message-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('reply_content_#{scrap.id}').focus();return false", :class => "profile-send-reply" %>
  13 + </span>
15 <% end %> 14 <% end %>
  15 + <%= link_to_remote(content_tag(:span, _('Remove')), :confirm => _('Are you sure?'), :url =>{:action => 'remove_scrap', :scrap_id => scrap.id}, :update => "profile-activity-item-#{scrap.id}") if logged_in? && user.can_control_scrap?(scrap) %>
  16 + </div>
  17 + </div>
  18 +
  19 + <% if scrap.replies.count > 2 %>
  20 + <div class='view-all-comments icon-chat'>
  21 + <%= link_to(_("View all %s comments") % scrap.replies.count, '#') %>
  22 + </div>
16 <% end %> 23 <% end %>
17 - <ul class="profile-wall-scrap-replies"> 24 +
  25 + <ul class="profile-wall-activities-comments scrap-replies" style="width: auto; <%= 'display:none;' if (scrap.replies.count > 2) %>" >
18 <% scrap.replies.map do |reply| %> 26 <% scrap.replies.map do |reply| %>
19 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> 27 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %>
20 <% end %> 28 <% end %>
21 </ul> 29 </ul>
22 - <div id='profile-wall-message-<%= scrap.id%>' style='display:none;'>  
23 - <div id='profile-wall-form-<%= scrap.id%>' style='display:none;'>  
24 - <p class='profile-wall-message'>  
25 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :not_load_scraps => true}, :update => "profile-wall-message-response-#{scrap.id}", :success =>"hide_and_show(['#profile-wall-form-#{scrap.id}'],['#profile-wall-message-response-#{scrap.id}'])" do %>  
26 - <%= limited_text_area :scrap, :content, 420, "content_#{scrap.id}", :cols => 50, :rows => 2 %>  
27 - <%= hidden_field_tag 'receiver_id', scrap.sender.id %>  
28 - <%= submit_button :add, _('Leave a scrap') %>  
29 - <%= button_to_function :cancel, _('Cancel'), "hide_and_show(['#profile-wall-message-#{scrap.id}'],[]);return false" %>  
30 - <% end %>  
31 - </p>  
32 - </div>  
33 - <div id='profile-wall-message-response-<%=scrap.id%>' class='profile-wall-message-response'></div>  
34 - </div>  
35 - <div id='profile-wall-reply-<%= scrap.id%>' style='display:none;'>  
36 - <div id='profile-wall-reply-form-<%= scrap.id%>' style='display:none;'>  
37 - <p class='profile-wall-reply'>  
38 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap'}, :update => "profile_scraps", :success =>"hide_and_show(['#profile-wall-reply-form-#{scrap.id}'],['#profile-wall-reply-response-#{scrap.id}'])" do %>  
39 - <%= limited_text_area :scrap, :content, 420, "reply_content_#{scrap.id}", :cols => 50, :rows => 2 %>  
40 - <%= hidden_field :scrap, :scrap_id, :id => "scrap_id_#{scrap.id}" %>  
41 - <%= hidden_field_tag 'receiver_id', scrap.sender.id %>  
42 - <%= submit_button :add, _('Leave a scrap') %>  
43 - <%= button_to_function :cancel, _('Cancel'), "hide_and_show(['#profile-wall-reply-#{scrap.id}'],[]);return false" %>  
44 - <% end %>  
45 - </p>  
46 - </div>  
47 - <div id='profile-wall-message-response-<%=scrap.id%>' class='profile-wall-message-response'></div>  
48 - </div> 30 + <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
49 <hr /> 31 <hr />
50 </li> 32 </li>
app/views/profile/_profile_scrap_reply_form.rhtml 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +<div id='profile-wall-reply-<%= scrap.id%>' style='display:none'>
  2 + <div id='profile-wall-reply-form-<%= scrap.id%>' style='display:none'>
  3 + <p class='profile-wall-reply'>
  4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap'}, :update => "profile_activities", :html => { :class => 'profile-wall-reply-form'} do %>
  5 + <%= text_area :scrap, :content, { :id => "reply_content_#{scrap.id}",
  6 + :cols => 50,
  7 + :rows => 1,
  8 + :class => 'submit-with-keypress',
  9 + :title => _('Leave your comment'),
  10 + :onfocus => ('if(this.value==this.title){this.value="";this.style.color="#000"};this.style.backgroundImage="url(' + profile_icon(current_person, :icon, false) + ')"' if logged_in?),
  11 + :onblur => ('if(this.value==""){this.value=this.title;this.style.color="#ccc"};this.style.backgroundImage="none"' if logged_in?),
  12 + :value => _('Leave your comment')
  13 + } %>
  14 + <%= hidden_field_tag 'scrap[scrap_id]', scrap.id %>
  15 + <%= hidden_field_tag 'receiver_id', scrap.sender.id %>
  16 + <% end %>
  17 + </p>
  18 + </div>
  19 + <div id='profile-wall-message-response-<%=scrap.id%>' class='profile-wall-message-response'></div>
  20 +</div>
app/views/profile/_profile_scraps.rhtml
1 -<% scraps.map do |scrap| %>  
2 - <%= render :partial => 'profile_scrap', :locals => {:scrap => scrap} %>  
3 -<% end %>  
4 -<% if scraps.current_page < scraps.total_pages %>  
5 - <div id='profile_scraps_page_<%= scraps.current_page %>'>  
6 - <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_scraps', :page => (scraps.current_page + 1)}, :update => "profile_scraps_page_#{scraps.current_page}" %>  
7 - </div>  
8 -<% end %> 1 +NÃO DEVE APARECER
app/views/profile/_profile_wall.rhtml
1 <h3><%= _("%s's wall") % @profile.name %></h3> 1 <h3><%= _("%s's wall") % @profile.name %></h3>
2 <div id='leave_scrap'> 2 <div id='leave_scrap'>
3 <%= flash[:error] %> 3 <%= flash[:error] %>
4 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_scraps', :success => "$('leave_scrap_content').value=''" do %> 4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''" do %>
5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %> 5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %>
6 - <%= submit_button :scrap, _('Leave a scrap') %> 6 + <%= submit_button :new, _('Share') %>
7 <% end %> 7 <% end %>
8 </div> 8 </div>
9 <div id='leave_scrap_response'></div> 9 <div id='leave_scrap_response'></div>
10 -<ul id='profile_scraps'>  
11 - <%= render :partial => 'profile_scraps', :locals => {:scraps => @wall_items} %> 10 +<ul id='profile_activities' class='profile-activities'>
  11 + <%= render :partial => 'profile_activities_list', :locals => {:activities => @activities} %>
12 </ul> 12 </ul>
app/views/profile/_update_article.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +NAO É PRA APARECER
app/views/profile/_upload_image.rhtml 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +<div class="activity-gallery-images-count-<%= activity.get_view_url.size %>">
  2 + <div class='profile-activity-image'>
  3 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  4 + </div>
  5 + <div class='profile-activity-description'>
  6 + <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
  7 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) %></p>
  8 + <div class='profile-wall-actions'>
  9 + <%= link_to(s_('profile|Comment'), '#', { :class => 'focus-on-comment'}) unless activity.get_view_url.size == 1 %>
  10 + <%= link_to_remote(content_tag(:span, _('Remove')), :confirm => _('Are you sure?'), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  11 + </div>
  12 + </div>
  13 +</div>
  14 +<div title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-newgallery'></div>
  15 +
  16 +<% if activity.get_view_url.size == 1 %>
  17 + <%= render :partial => 'profile_comments', :locals => { :activity => activity, :tab_action => tab_action } %>
  18 +<% end %>
  19 +
  20 +<br/>
app/views/profile/index.rhtml
@@ -17,6 +17,31 @@ @@ -17,6 +17,31 @@
17 17
18 <% if @profile.public? || (logged_in? && current_person.follows?(@profile)) %> 18 <% if @profile.public? || (logged_in? && current_person.follows?(@profile)) %>
19 <table class='profile'> 19 <table class='profile'>
20 - <%= render :partial => 'profile' %> 20 + <tr>
  21 + <td colspan='2'>
  22 + <% plugins_tabs = @plugins.dispatch(:profile_tabs).
  23 + map { |tab| {:title => tab[:title], :id => tab[:id], :content => instance_eval(&tab[:content]), :start => tab[:title]} }%>
  24 +
  25 + <% tabs = plugins_tabs.select { |tab| tab[:start] } %>
  26 +
  27 + <% if @profile.organization? %>
  28 + <% tabs << {:title => _('Profile'), :id => 'organization-profile', :content => (render :partial => 'organization_profile')} %>
  29 + <% if logged_in? && current_person.follows?(@profile) %>
  30 + <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %>
  31 + <% end %>
  32 + <% tabs << {:title => _('What\'s new'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %>
  33 + <% elsif @profile.person? %>
  34 + <% tabs << {:title => _('Profile'), :id => 'person-profile', :content => (render :partial => 'person_profile')} %>
  35 + <% if logged_in? && current_person.follows?(@profile) %>
  36 + <% tabs << {:title => _('Wall'), :id => 'profile-wall', :content => (render :partial => 'profile_wall')} %>
  37 + <% tabs << {:title => _('Network'), :id => 'profile-network', :content => (render :partial => 'profile_network')} %>
  38 + <% end %>
  39 + <% end %>
  40 +
  41 + <% tabs += plugins_tabs.select { |tab| !tab[:start] } %>
  42 +
  43 + <%= render_tabs(tabs) %>
  44 + </td>
  45 + </tr>
21 </table> 46 </table>
22 <% end %> 47 <% end %>
app/views/tasks/_abuse_complaint_accept_details.rhtml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <% task.abuse_reports.each do |abuse_report| %> 2 <% task.abuse_reports.each do |abuse_report| %>
3 <div> 3 <div>
4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br /> 4 <strong style="word-wrap: break-word; display: block; padding-right: 40px">"<%= abuse_report.reason %>"</strong> <br />
5 - <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_as_sentence(abuse_report.created_at) + ' ' + _('ago')}%></i> <br /> 5 + <i><%= _('Reported by %{reporter} %{time}.') % {:reporter => abuse_report.reporter.name, :time => time_ago_as_sentence(abuse_report.created_at) }%></i> <br />
6 <% if !abuse_report.content.blank? %> 6 <% if !abuse_report.content.blank? %>
7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button> 7 <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button>
8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details"> 8 <div style='display: none' id=<%= 'abuse-report-details-'+abuse_report.id.to_s %> class="abuse-report-details">
config/initializers/action_tracker.rb
@@ -5,18 +5,7 @@ require &#39;noosfero/i18n&#39; @@ -5,18 +5,7 @@ require &#39;noosfero/i18n&#39;
5 ActionTrackerConfig.verbs = { 5 ActionTrackerConfig.verbs = {
6 6
7 :create_article => { 7 :create_article => {
8 - :description => lambda { n_('published 1 article: %{title}', 'published %{num} articles: %{title}', get_name.size) % { :num => get_name.size, :title => '{{ta.collect_group_with_index(:name){ |n,i| link_to(truncate(n), ta.get_url[i]) }.to_sentence(:connector => "%s")}}' % _("and") } },  
9 - :type => :groupable  
10 - },  
11 -  
12 - :update_article => {  
13 - :description => lambda { n_('updated 1 article: %{title}', 'updated %{num} articles: %{title}', get_name.uniq.size) % { :num => get_name.uniq.size, :title => '{{ta.collect_group_with_index(:name){ |n,i| link_to(truncate(n), ta.get_url[i]) }.uniq.to_sentence(:connector => "%s")}}' % _("and") } },  
14 - :type => :groupable  
15 - },  
16 -  
17 - :remove_article => {  
18 - :description => lambda { n_('removed 1 article: %{title}', 'removed %{num} articles: %{title}', get_name.size) % { :num => get_name.size, :title => '{{ta.get_name.collect{ |n| truncate(n) }.to_sentence(:connector => "%s")}}' % _("and") } },  
19 - :type => :groupable 8 + :description => lambda { _('published an article: %{title}') % { :title => '{{link_to(truncate(ta.get_name), ta.get_url)}}' } }
20 }, 9 },
21 10
22 :new_friendship => { 11 :new_friendship => {
@@ -33,24 +22,11 @@ ActionTrackerConfig.verbs = { @@ -33,24 +22,11 @@ ActionTrackerConfig.verbs = {
33 :description => lambda { _('has joined the community.') }, 22 :description => lambda { _('has joined the community.') },
34 }, 23 },
35 24
36 - :remove_member_in_community => {  
37 - :description => lambda { _('has left the community.') },  
38 - },  
39 -  
40 - :leave_community => {  
41 - :description => lambda { n_('has left 1 community:<br />%{name}', 'has left %{num} communities:<br />%{name}', get_resource_name.size) % { :num => get_resource_name.size, :name => '{{ta.collect_group_with_index(:resource_name){ |n,i| link_to(image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")), ta.get_resource_url[i], :title => n)}.join}}' } },  
42 - :type => :groupable  
43 - },  
44 -  
45 :upload_image => { 25 :upload_image => {
46 - :description => lambda { n_('uploaded 1 image:<br />%{thumbnails}<br />%{details}', 'uploaded %{num} images:<br />%{thumbnails}<br />%{details}', get_view_url.size) % { :num => get_view_url.size, :thumbnails => '{{ta.collect_group_with_index(:thumbnail_path){ |t,i| content_tag(:span, link_to(image_tag(t), ta.get_view_url[i]))}.last(3).join}}', :details => '{{unique_with_count(ta.collect_group_with_index(:parent_name){ |n,i| link_to(n, ta.get_parent_url[i])}, "%s").join("<br />")}}' % _("in the gallery") } }, 26 + :description => lambda { n_('uploaded 1 image<br />%{thumbnails}<br style="clear: both;" />', 'uploaded %{num} images<br />%{thumbnails}<br style="clear: both;" />', get_view_url.size) % { :num => get_view_url.size, :thumbnails => '{{ta.collect_group_with_index(:thumbnail_path){ |t,i| content_tag(:span, link_to(image_tag(t), ta.get_view_url[i]))}.last(3).join}}' } },
47 :type => :groupable 27 :type => :groupable
48 }, 28 },
49 29
50 - :leave_comment => {  
51 - :description => lambda { _('has left a comment entitled "%{title}" on the article %{article}: <br /> "%{comment}" (%{read})') % { :title => "{{truncate(ta.get_title)}}", :article => "{{link_to(truncate(ta.get_article_title), ta.get_article_url)}}", :comment => "{{truncate(ta.get_body, 50)}}", :read => '{{link_to("%s", ta.get_url)}}' % _("read") } }  
52 - },  
53 -  
54 :leave_scrap => { 30 :leave_scrap => {
55 :description => lambda { _('sent a message to %{receiver}: <br /> "%{message}"') % { :receiver => "{{link_to(ta.get_receiver_name, ta.get_receiver_url)}}", :message => "{{auto_link_urls(ta.get_content)}}" } } 31 :description => lambda { _('sent a message to %{receiver}: <br /> "%{message}"') % { :receiver => "{{link_to(ta.get_receiver_name, ta.get_receiver_url)}}", :message => "{{auto_link_urls(ta.get_content)}}" } }
56 }, 32 },
db/migrate/20111211204445_add_polymorphism_on_comment.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class AddPolymorphismOnComment < ActiveRecord::Migration
  2 + def self.up
  3 + rename_column :comments, :article_id, :source_id
  4 + add_column :comments, :source_type, :string
  5 + execute("update comments set source_type = 'Article'")
  6 + end
  7 +
  8 + def self.down
  9 + remove_column :comments, :source_type
  10 + rename_column :comments, :source_id, :article_id
  11 + end
  12 +end
db/migrate/20111211233957_add_comment_count_to_action_tracker.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddCommentCountToActionTracker < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :action_tracker, :comments_count, :integer, :default => 0
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :action_tracker, :comments_count, :integer
  8 + end
  9 +end
db/migrate/20111228202739_remove_useless_tracked_actions.rb 0 → 100644
@@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
  1 +class RemoveUselessTrackedActions < ActiveRecord::Migration
  2 + def self.up
  3 + select_all("SELECT id FROM action_tracker").each do |tracker|
  4 + verbs = ['update_article', 'remove_article', 'leave_comment', 'leave_community', 'remove_member_in_community']
  5 + activity = ActionTracker::Record.find_by_id(tracker['id'])
  6 + if activity
  7 + if (activity.updated_at.to_time < Time.now.months_ago(3)) || verbs.include?(activity.verb)
  8 + activity.destroy
  9 + end
  10 + end
  11 + end
  12 + end
  13 +
  14 + def self.down
  15 + say "this migration can't be reverted"
  16 + end
  17 +end
db/migrate/20120228154642_add_visibility_to_action_tracker.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddVisibilityToActionTracker < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :action_tracker, :visible, :boolean, :default => true
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :action_tracker, :visible, :boolean
  8 + end
  9 +end
db/migrate/20120228202739_adapt_create_articles_activity.rb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +class AdaptCreateArticlesActivity < ActiveRecord::Migration
  2 +
  3 + # Removing 'create_article' activities that grouped articles.
  4 + # Creating new activities only to recent articles (not grouping)
  5 + def self.up
  6 + select_all("SELECT id FROM action_tracker WHERE verb = 'create_article'").each do |tracker|
  7 + activity = ActionTracker::Record.find_by_id(tracker['id'])
  8 + if activity
  9 + activity.destroy
  10 + end
  11 + end
  12 +
  13 + select_all("SELECT id FROM articles").each do |art|
  14 + article = Article.find(art['id'])
  15 + if article && article.created_at >= 8.days.ago && article.author && article.author.kind_of?(Person)
  16 + article.create_activity
  17 + end
  18 + end
  19 + end
  20 +
  21 + def self.down
  22 + say "this migration can't be reverted"
  23 + end
  24 +end
@@ -29,6 +29,8 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -29,6 +29,8 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
29 t.string "verb" 29 t.string "verb"
30 t.datetime "created_at" 30 t.datetime "created_at"
31 t.datetime "updated_at" 31 t.datetime "updated_at"
  32 + t.integer "comments_count", :default => 0
  33 + t.boolean "visible", :default => true
32 end 34 end
33 35
34 add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type" 36 add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type"
@@ -198,7 +200,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -198,7 +200,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
198 create_table "comments", :force => true do |t| 200 create_table "comments", :force => true do |t|
199 t.string "title" 201 t.string "title"
200 t.text "body" 202 t.text "body"
201 - t.integer "article_id" 203 + t.integer "source_id"
202 t.integer "author_id" 204 t.integer "author_id"
203 t.string "name" 205 t.string "name"
204 t.string "email" 206 t.string "email"
@@ -206,6 +208,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -206,6 +208,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
206 t.integer "reply_of_id" 208 t.integer "reply_of_id"
207 t.string "ip_address" 209 t.string "ip_address"
208 t.boolean "spam" 210 t.boolean "spam"
  211 + t.string "source_type"
209 end 212 end
210 213
211 create_table "contact_lists", :force => true do |t| 214 create_table "contact_lists", :force => true do |t|
lib/notify_activity_to_profiles_job.rb
1 class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id) 1 class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id)
2 NOTIFY_ONLY_COMMUNITY = [ 2 NOTIFY_ONLY_COMMUNITY = [
3 - 'add_member_in_community',  
4 - 'remove_member_in_community', 3 + 'add_member_in_community'
5 ] 4 ]
6 5
7 NOT_NOTIFY_COMMUNITY = [ 6 NOT_NOTIFY_COMMUNITY = [
8 - 'join_community',  
9 - 'leave_community', 7 + 'join_community'
10 ] 8 ]
11 def perform 9 def perform
12 return unless ActionTracker::Record.exists?(tracked_action_id) 10 return unless ActionTracker::Record.exists?(tracked_action_id)
@@ -19,6 +17,7 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id) @@ -19,6 +17,7 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id)
19 17
20 ActionTrackerNotification.create(:profile_id => tracked_action.user.id, :action_tracker_id => tracked_action.id) 18 ActionTrackerNotification.create(:profile_id => tracked_action.user.id, :action_tracker_id => tracked_action.id)
21 19
  20 + #Notify all friends
22 ActionTrackerNotification.connection.execute("insert into action_tracker_notifications(profile_id, action_tracker_id) select f.friend_id, #{tracked_action.id} from friendships as f where person_id=#{tracked_action.user.id} and f.friend_id not in (select atn.profile_id from action_tracker_notifications as atn where atn.action_tracker_id = #{tracked_action.id})") 21 ActionTrackerNotification.connection.execute("insert into action_tracker_notifications(profile_id, action_tracker_id) select f.friend_id, #{tracked_action.id} from friendships as f where person_id=#{tracked_action.user.id} and f.friend_id not in (select atn.profile_id from action_tracker_notifications as atn where atn.action_tracker_id = #{tracked_action.id})")
23 22
24 if target.is_a?(Community) 23 if target.is_a?(Community)
@@ -26,5 +25,12 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id) @@ -26,5 +25,12 @@ class NotifyActivityToProfilesJob &lt; Struct.new(:tracked_action_id)
26 25
27 ActionTrackerNotification.create(:profile_id => target.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb) 26 ActionTrackerNotification.create(:profile_id => target.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb)
28 end 27 end
  28 +
  29 + if target.is_a?(Article) && target.profile.is_a?(Community)
  30 + ActionTrackerNotification.connection.execute("insert into action_tracker_notifications(profile_id, action_tracker_id) select distinct profiles.id, #{tracked_action.id} from role_assignments, profiles where profiles.type = 'Person' and profiles.id = role_assignments.accessor_id and profiles.id != #{tracked_action.user.id} and role_assignments.resource_type = 'Profile' and role_assignments.resource_id = #{target.profile.id}")
  31 +
  32 + ActionTrackerNotification.create(:profile_id => target.profile.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb)
  33 + end
  34 +
29 end 35 end
30 end 36 end
public/designs/icons/tango/style.css
@@ -91,7 +91,7 @@ @@ -91,7 +91,7 @@
91 .icon-lock { background-image: url(Tango/16x16/actions/lock.png) } 91 .icon-lock { background-image: url(Tango/16x16/actions/lock.png) }
92 .icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat } 92 .icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat }
93 .icon-reply { background-image: url(Tango/16x16/actions/mail-reply-sender.png) } 93 .icon-reply { background-image: url(Tango/16x16/actions/mail-reply-sender.png) }
94 -.icon-newforum { background-image: url(Tango/16x16/apps/system-users.png) } 94 +.icon-newforum { background-image: url(Tango/16x16/apps/internet-group-chat.png) }
95 .icon-forum { background-image: url(Tango/16x16/apps/system-users.png) } 95 .icon-forum { background-image: url(Tango/16x16/apps/system-users.png) }
96 .icon-gallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } 96 .icon-gallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) }
97 .icon-newgallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } 97 .icon-newgallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) }
public/designs/templates/default/stylesheets/style.css
@@ -24,3 +24,9 @@ @@ -24,3 +24,9 @@
24 #profile-wall ul { 24 #profile-wall ul {
25 width: 460px; 25 width: 460px;
26 } 26 }
  27 +#profile-activity ul.comment-replies,
  28 +#profile-network ul.comment-replies,
  29 +#profile-wall ul.comment-replies {
  30 + width: auto;
  31 +}
  32 +
public/designs/templates/leftbar/stylesheets/style.css
@@ -23,3 +23,54 @@ @@ -23,3 +23,54 @@
23 #profile-wall ul { 23 #profile-wall ul {
24 width: 620px; 24 width: 620px;
25 } 25 }
  26 +
  27 +.profile-activity-lead {
  28 + width: 534px;
  29 +}
  30 +
  31 +#profile-wall textarea {
  32 + width: 534px;
  33 +}
  34 +
  35 +#profile-wall #leave_scrap textarea {
  36 + width: 640px;
  37 +}
  38 +
  39 +#profile-wall li textarea {
  40 + width: 548px;
  41 +}
  42 +
  43 +.profile-activity-article-forum .profile-activity-lead {
  44 + background: url(/images/forum-activity-bg-onecol.png);
  45 + width: 489px;
  46 +}
  47 +
  48 +#profile-wall li.profile-activity-item.upload_image span,
  49 +#profile-wall li.profile-activity-item.upload_image span img,
  50 +#profile-wall li.profile-activity-item.upload_image span a,
  51 +#profile-network li.profile-activity-item.upload_image span,
  52 +#profile-network li.profile-activity-item.upload_image span img,
  53 +#profile-network li.profile-activity-item.upload_image span a {
  54 + width: 178px;
  55 + height: 144px;
  56 +}
  57 +
  58 +#profile-wall li.profile-activity-item.upload_image span a,
  59 +#profile-network li.profile-activity-item.upload_image span a {
  60 + background-image: url(/images/gallery-image-activity-border-onecol.png);
  61 +}
  62 +
  63 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  64 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span img,
  65 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  66 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  67 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span img,
  68 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a {
  69 + width: 549px;
  70 + height: 254px;
  71 +}
  72 +
  73 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  74 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a {
  75 + background-image: url(/images/gallery-image-activity-border-big-onecol.png);
  76 +}
public/designs/templates/rightbar/stylesheets/style.css
@@ -23,3 +23,54 @@ @@ -23,3 +23,54 @@
23 #profile-wall ul { 23 #profile-wall ul {
24 width: 620px; 24 width: 620px;
25 } 25 }
  26 +
  27 +.profile-activity-lead {
  28 + width: 534px;
  29 +}
  30 +
  31 +#profile-wall textarea {
  32 + width: 534px;
  33 +}
  34 +
  35 +#profile-wall #leave_scrap textarea {
  36 + width: 640px;
  37 +}
  38 +
  39 +#profile-wall li textarea {
  40 + width: 548px;
  41 +}
  42 +
  43 +.profile-activity-article-forum .profile-activity-lead {
  44 + background: url(/images/forum-activity-bg-onecol.png);
  45 + width: 489px;
  46 +}
  47 +
  48 +#profile-wall li.profile-activity-item.upload_image span,
  49 +#profile-wall li.profile-activity-item.upload_image span img,
  50 +#profile-wall li.profile-activity-item.upload_image span a,
  51 +#profile-network li.profile-activity-item.upload_image span,
  52 +#profile-network li.profile-activity-item.upload_image span img,
  53 +#profile-network li.profile-activity-item.upload_image span a {
  54 + width: 178px;
  55 + height: 144px;
  56 +}
  57 +
  58 +#profile-wall li.profile-activity-item.upload_image span a,
  59 +#profile-network li.profile-activity-item.upload_image span a {
  60 + background-image: url(/images/gallery-image-activity-border-onecol.png);
  61 +}
  62 +
  63 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  64 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span img,
  65 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  66 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  67 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span img,
  68 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a {
  69 + width: 549px;
  70 + height: 254px;
  71 +}
  72 +
  73 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  74 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a {
  75 + background-image: url(/images/gallery-image-activity-border-big-onecol.png);
  76 +}
public/images/forum-activity-bg-onecol.png 0 → 100644

1.73 KB

public/images/forum-activity-bg.png 0 → 100644

1.72 KB

public/images/forum-activity-icon.png 0 → 100644

477 Bytes

public/images/gallery-image-activity-border-big-onecol.png 0 → 100644

2.21 KB

public/images/gallery-image-activity-border-big.png 0 → 100644

1.32 KB

public/images/gallery-image-activity-border-onecol.png 0 → 100644

1.44 KB

public/images/gallery-image-activity-border.png 0 → 100644

1.01 KB

public/javascripts/application.js
@@ -711,3 +711,37 @@ Array.min = function(array) { @@ -711,3 +711,37 @@ Array.min = function(array) {
711 return Math.min.apply(Math, array); 711 return Math.min.apply(Math, array);
712 }; 712 };
713 713
  714 +jQuery(function($){
  715 + $('.submit-with-keypress').live('keydown', function(e) {
  716 + field = this;
  717 + if (e.keyCode == 13) {
  718 + e.preventDefault();
  719 + var form = $(field).closest("form");
  720 + $.ajax({
  721 + url: form.attr("action"),
  722 + data: form.serialize(),
  723 + beforeSend: function() {
  724 + loading_for_button($(field));
  725 + },
  726 + success: function(data) {
  727 + var update = form.attr('data-update');
  728 + $('#'+update).html(data);
  729 + $(field).val($(field).attr('title'));
  730 + }
  731 + });
  732 + return false;
  733 + }
  734 + });
  735 +
  736 + $('.view-all-comments').live('click', function(e) {
  737 + var link = this;
  738 + $(link).parent().find('.profile-wall-activities-comments').show();
  739 + $(link).hide();
  740 + return false;
  741 + });
  742 + $('.focus-on-comment').live('click', function(e) {
  743 + var link = this;
  744 + $(link).parents('.profile-activity-item').find('textarea').focus();
  745 + return false;
  746 + });
  747 +});
public/stylesheets/application.css
@@ -268,6 +268,12 @@ td.field-name { @@ -268,6 +268,12 @@ td.field-name {
268 vertical-align: top; 268 vertical-align: top;
269 } 269 }
270 270
  271 +table.profile .ui-tabs .ui-tabs-panel {
  272 + border-left: 0;
  273 + border-right: 0;
  274 + border-bottom: 0;
  275 +}
  276 +
271 table.profile th { 277 table.profile th {
272 border-bottom: 2px solid #eeeeec; 278 border-bottom: 2px solid #eeeeec;
273 padding: 10px 0px 0px 0px; 279 padding: 10px 0px 0px 0px;
@@ -1429,7 +1435,8 @@ a.comment-picture { @@ -1429,7 +1435,8 @@ a.comment-picture {
1429 border-radius: 5px; 1435 border-radius: 5px;
1430 } 1436 }
1431 1437
1432 -.comment-replies .article-comment-inner { 1438 +.comment-replies .article-comment-inner,
  1439 +.scrap-replies {
1433 border: 1px solid #fff; 1440 border: 1px solid #fff;
1434 padding: 0; 1441 padding: 0;
1435 -moz-border-radius: 4px; 1442 -moz-border-radius: 4px;
@@ -5883,8 +5890,183 @@ h1#agenda-title { @@ -5883,8 +5890,183 @@ h1#agenda-title {
5883 5890
5884 #profile-activity li, #profile-network li, #profile-wall li { 5891 #profile-activity li, #profile-network li, #profile-wall li {
5885 display: block; 5892 display: block;
5886 - padding: 0;  
5887 - margin-bottom: 8px; 5893 + padding: 3px;
  5894 + margin-bottom: 3px;
  5895 + background-color: #fff;
  5896 + border-bottom: 1px solid #e8e8e8;
  5897 + position: relative;
  5898 +}
  5899 +
  5900 +#profile-activity li, #profile-network li, #profile-wall li {
  5901 +}
  5902 +
  5903 +.profile-activity-lead img {
  5904 + width: 124px;
  5905 + float: left;
  5906 + margin-right: 5px;
  5907 +}
  5908 +
  5909 +.profile-activity-lead {
  5910 + width: 370px;
  5911 + display: inline-block;
  5912 + text-align: left;
  5913 + margin: 5px 0;
  5914 +}
  5915 +
  5916 +.profile-activity-article-forum .profile-activity-lead {
  5917 + height: 50px;
  5918 + width: 297px;
  5919 + padding-left: 60px;
  5920 + float: none;
  5921 + overflow: hidden;
  5922 + background: transparent url(/images/forum-activity-bg.png) left center no-repeat;
  5923 +}
  5924 +
  5925 +.profile-activity-article-forum .see-forum {
  5926 + text-align: right;
  5927 +}
  5928 +
  5929 +.profile-activity-article-forum .see-forum a {
  5930 + background: transparent url(/images/forum-activity-icon.png) left center no-repeat;
  5931 + padding-left: 30px;
  5932 + font-weight: bold;
  5933 + color: #dadada !important;
  5934 + text-decoration: none;
  5935 + font-size: 11px;
  5936 +}
  5937 +
  5938 +.profile-activity-article-forum .profile-activity-lead b {
  5939 + font-weight: normal;
  5940 +}
  5941 +
  5942 +#profile-activity li a, #profile-network li a, #profile-wall li a,
  5943 +#profile-wall .profile-wall-send-reply {
  5944 + color: #333;
  5945 +}
  5946 +
  5947 +#profile-activity li a, #profile-network li a, #profile-wall li a {
  5948 + font-weight: bold;
  5949 + text-decoration: none;
  5950 +}
  5951 +
  5952 +#profile-activity li a:hover, #profile-network li a:hover, #profile-wall li a:hover {
  5953 + text-decoration: underline;
  5954 +}
  5955 +
  5956 +.profile-activity-text {
  5957 + margin: 0;
  5958 + color: #000;
  5959 +}
  5960 +
  5961 +#profile-wall li.profile-activity-item.upload_image span,
  5962 +#profile-wall li.profile-activity-item.upload_image span a,
  5963 +#profile-network li.profile-activity-item.upload_image span,
  5964 +#profile-network li.profile-activity-item.upload_image span a {
  5965 + width: 110px;
  5966 + height: 100px;
  5967 + display: block;
  5968 + overflow: hidden;
  5969 + position: absolute;
  5970 +}
  5971 +
  5972 +#profile-wall li.profile-activity-item.upload_image span a img,
  5973 +#profile-network li.profile-activity-item.upload_image span a img {
  5974 + width: 110px;
  5975 + height: 100px;
  5976 +}
  5977 +
  5978 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  5979 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  5980 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img,
  5981 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span,
  5982 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img {
  5983 + width: 383px;
  5984 + height: auto;
  5985 +}
  5986 +
  5987 +#profile-wall li.profile-activity-item.upload_image span img,
  5988 +#profile-network li.profile-activity-item.upload_image span img {
  5989 + display: block;
  5990 +}
  5991 +
  5992 +#profile-wall li.profile-activity-item.upload_image span,
  5993 +#profile-network li.profile-activity-item.upload_image span {
  5994 + position: relative;
  5995 + display: inline-block;
  5996 + margin: 5px 0px 0px 5px;
  5997 +}
  5998 +
  5999 +#profile-wall li.profile-activity-item.upload_image .profile-activity-text span,
  6000 +#profile-network li.profile-activity-item.upload_image .profile-activity-text span {
  6001 + border: 4px solid #D2D2D2;
  6002 + border-radius: 4px;
  6003 + -webkit-border-radius: 4px;
  6004 + -moz-border-radius: 4px;
  6005 +}
  6006 +
  6007 +#profile-wall li.profile-activity-item.upload_image span a,
  6008 +#profile-network li.profile-activity-item.upload_image span a {
  6009 + Xbackground: transparent url(/images/gallery-image-activity-border.png) center center no-repeat;
  6010 + text-indent: -5000em;
  6011 +}
  6012 +
  6013 +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a,
  6014 +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a {
  6015 + Xbackground-image: url(/images/gallery-image-activity-border-big.png);
  6016 + position: relative;
  6017 +}
  6018 +
  6019 +#profile-wall li.profile-activity-item.upload_image .article-comment span,
  6020 +#profile-wall li.profile-activity-item.upload_image .profile-wall-actions span,
  6021 +#profile-network li.profile-activity-item.upload_image .article-comment span,
  6022 +#profile-network li.profile-activity-item.upload_image .profile-wall-actions span {
  6023 + display: inline;
  6024 + position: static;
  6025 + margin: 0;
  6026 + float: none;
  6027 + width: auto;
  6028 + height: auto;
  6029 + font-weight: normal;
  6030 +}
  6031 +
  6032 +#profile-wall li.profile-activity-item ul.profile-wall-activities-comments,
  6033 +#profile-network li.profile-activity-item ul.profile-wall-activities-comments {
  6034 + margin-top: 0;
  6035 +}
  6036 +
  6037 +#profile-wall li.profile-activity-item.upload_image .profile-activity-text,
  6038 +#profile-network li.profile-activity-item.upload_image .profile-activity-text,
  6039 +#profile-network li.profile-activity-item ul.profile-wall-activities-comments {
  6040 + padding-left: 50px;
  6041 +}
  6042 +
  6043 +#profile-wall li.profile-activity-item.join_community .profile-activity-text a img,
  6044 +#profile-wall li.profile-activity-item.new_friendship .profile-activity-text a img,
  6045 +#profile-network li.profile-activity-item.join_community .profile-activity-text a img,
  6046 +#profile-network li.profile-activity-item.new_friendship .profile-activity-text a img {
  6047 + margin: 5px 5px 0 0;
  6048 + padding: 1px;
  6049 + border: 1px solid #ccc;
  6050 +}
  6051 +
  6052 +#profile-wall li.profile-activity-item.create_article,
  6053 +#profile-netowrk li.profile-activity-item.create_article {
  6054 + position: relative;
  6055 +}
  6056 +
  6057 +.profile-activity-icon {
  6058 + width: 16px;
  6059 + height: 16px;
  6060 + display: inline-block;
  6061 + position: absolute;
  6062 + top: 0px;
  6063 + right: 0px;
  6064 +}
  6065 +
  6066 +#profile-activity .profile-wall-scrap-replies li,
  6067 +#profile-network .profile-wall-scrap-replies li,
  6068 +#profile-wall .profile-wall-scrap-replies li {
  6069 + border-bottom: none;
5888 } 6070 }
5889 6071
5890 #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { 6072 #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image {
@@ -5898,12 +6080,12 @@ h1#agenda-title { @@ -5898,12 +6080,12 @@ h1#agenda-title {
5898 6080
5899 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { 6081 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description {
5900 float: left; 6082 float: left;
5901 - min-height: 60px; 6083 + Xmin-height: 60px;
5902 margin: 0; 6084 margin: 0;
5903 padding: 0; 6085 padding: 0;
5904 border: 1px solid #ccc; 6086 border: 1px solid #ccc;
5905 overflow: hidden; 6087 overflow: hidden;
5906 - background-color: #fff; 6088 + Xbackground-color: #fff;
5907 position: relative; 6089 position: relative;
5908 } 6090 }
5909 6091
@@ -5918,7 +6100,7 @@ h1#agenda-title { @@ -5918,7 +6100,7 @@ h1#agenda-title {
5918 } 6100 }
5919 6101
5920 #profile-activity .profile-activity-description .icon-delete, 6102 #profile-activity .profile-activity-description .icon-delete,
5921 -#profile-network .profile-network-description .icon-delete, 6103 +#profile-network .profile-activity-description .icon-delete,
5922 #profile-wall .profile-wall-description .icon-delete { 6104 #profile-wall .profile-wall-description .icon-delete {
5923 position: absolute; 6105 position: absolute;
5924 top: 4px; 6106 top: 4px;
@@ -5930,24 +6112,56 @@ h1#agenda-title { @@ -5930,24 +6112,56 @@ h1#agenda-title {
5930 -moz-border-radius: 3px; 6112 -moz-border-radius: 3px;
5931 } 6113 }
5932 6114
5933 -#profile-activity .profile-activity-text, #profile-network .profile-network-text, #profile-wall .profile-wall-text { 6115 +#profile-activity .profile-activity-text,
  6116 +#profile-network .profile-activity-text,
  6117 +#profile-wall .profile-wall-text {
5934 font-size: 13px; 6118 font-size: 13px;
5935 - margin: 5px; 6119 + margin: 2px 5px;
5936 } 6120 }
5937 6121
5938 #profile-wall .profile-wall-text { 6122 #profile-wall .profile-wall-text {
5939 padding-top: 0; 6123 padding-top: 0;
5940 } 6124 }
5941 6125
5942 -#profile-activity .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { 6126 +.profile-activities .profile-activity-time,
  6127 +#profile-network .profile-activity-time,
  6128 +#profile-wall .profile-wall-time {
5943 font-size: 11px; 6129 font-size: 11px;
5944 margin: 5px; 6130 margin: 5px;
5945 color: #babdb6; 6131 color: #babdb6;
  6132 + text-align: right;
  6133 +}
  6134 +
  6135 +#profile-wall .profile-wall-send-reply,
  6136 +.profile-activities .profile-activity-time,
  6137 +#profile-network .profile-activity-time,
  6138 +#profile-wall .profile-wall-time,
  6139 +.profile-wall-actions a {
  6140 + display: block;
  6141 + float: right;
  6142 + font-size: 10px;
  6143 + margin: 2px 0 3px 10px;
  6144 + color: #ccc;
  6145 + padding: 0;
  6146 +}
  6147 +
  6148 +#profile-wall li .profile-wall-actions a,
  6149 +#profile-activity li .profile-wall-actions a,
  6150 +#profile-network li .profile-wall-actions a,
  6151 +#profile-wall .profile-wall-send-reply a {
  6152 + text-decoration: none;
  6153 + color: #333;
  6154 + font-weight: normal;
  6155 +}
  6156 +
  6157 +#profile-wall li .profile-wall-actions a:hover,
  6158 +#profile-network li .profile-wall-actions a:hover,
  6159 +#profile-wall .profile-wall-send-reply a:hover {
  6160 + text-decoration: underline;
5946 } 6161 }
5947 6162
5948 #profile-activity hr, #profile-network hr, #profile-wall hr { 6163 #profile-activity hr, #profile-network hr, #profile-wall hr {
5949 - clear: both;  
5950 - border: 0; 6164 + display: none;
5951 } 6165 }
5952 6166
5953 #profile-activity .profile-activity-send-message, #profile-network .profile-network-send-message, #profile-wall .profile-wall-send-message { 6167 #profile-activity .profile-activity-send-message, #profile-network .profile-network-send-message, #profile-wall .profile-wall-send-message {
@@ -6029,11 +6243,13 @@ h1#agenda-title { @@ -6029,11 +6243,13 @@ h1#agenda-title {
6029 .profile-network-time, 6243 .profile-network-time,
6030 .profile-network-description { 6244 .profile-network-description {
6031 padding-left: 5px; 6245 padding-left: 5px;
  6246 + margin: 5px;
6032 } 6247 }
6033 6248
6034 .profile-network-sender, 6249 .profile-network-sender,
  6250 +.profile-activity-sender,
6035 .profile-wall-sender { 6251 .profile-wall-sender {
6036 - margin: 2px 0; 6252 + margin: 0;
6037 } 6253 }
6038 6254
6039 #profile-activity .profile-activity-time, 6255 #profile-activity .profile-activity-time,
@@ -6050,6 +6266,13 @@ h1#agenda-title { @@ -6050,6 +6266,13 @@ h1#agenda-title {
6050 overflow: hidden; 6266 overflow: hidden;
6051 } 6267 }
6052 6268
  6269 +#profile-network li textarea:focus,
  6270 +#profile-wall li textarea:focus {
  6271 + background-position: left center;
  6272 + background-repeat: no-repeat;
  6273 + text-indent: 28px;
  6274 +}
  6275 +
6053 .profile-network-message, 6276 .profile-network-message,
6054 .profile-wall-message { 6277 .profile-wall-message {
6055 margin: 0; 6278 margin: 0;
@@ -6084,21 +6307,25 @@ h1#agenda-title { @@ -6084,21 +6307,25 @@ h1#agenda-title {
6084 } 6307 }
6085 6308
6086 .profile-send-reply { 6309 .profile-send-reply {
6087 - background-color: #eee;  
6088 - border: 1px solid #aaa;  
6089 - padding: 2px;  
6090 - padding-left: 20px;  
6091 - background-repeat: no-repeat;  
6092 - background-position: 2px center; 6310 + xbackground-color: #eee;
  6311 + xborder: 1px solid #aaa;
  6312 + xpadding: 2px;
  6313 + xpadding-left: 20px;
  6314 + xbackground-repeat: no-repeat;
  6315 + xbackground-position: 2px center;
6093 color: #aaa; 6316 color: #aaa;
6094 - text-decoration: none;  
6095 - margin-left: 8px; 6317 + Xtext-decoration: none;
  6318 + Xmargin-left: 8px;
6096 } 6319 }
6097 6320
6098 #content .profile-send-reply:hover { 6321 #content .profile-send-reply:hover {
6099 text-decoration: none; 6322 text-decoration: none;
6100 } 6323 }
6101 6324
  6325 +#profile-wall .profile-wall-actions {
  6326 + text-align: right;
  6327 +}
  6328 +
6102 #profile-wall .profile-wall-scrap-replies .profile-wall-description { 6329 #profile-wall .profile-wall-scrap-replies .profile-wall-description {
6103 background: transparent; 6330 background: transparent;
6104 } 6331 }
@@ -6116,6 +6343,104 @@ h1#agenda-title { @@ -6116,6 +6343,104 @@ h1#agenda-title {
6116 background: transparent; 6343 background: transparent;
6117 } 6344 }
6118 6345
  6346 +#profile-wall ul.profile-wall-activities-comments,
  6347 +#profile-network ul.profile-wall-activities-comments {
  6348 + margin-top: 35px;
  6349 + padding-left: 50px;
  6350 + width: auto;
  6351 +}
  6352 +
  6353 +#profile-wall ul.profile-wall-activities-comments ul,
  6354 +#profile-network ul.profile-wall-activities-comments ul {
  6355 + padding-left: 0px;
  6356 +}
  6357 +
  6358 +#profile-wall .profile-wall-activities-comments li,
  6359 +#profile-network .profile-wall-activities-comments li {
  6360 + background: #f0f0f1;
  6361 + border-bottom: 1px solid #d2d2d2 !important;
  6362 + border-top: 1px solid #fff;
  6363 + margin-bottom: 0;
  6364 +}
  6365 +
  6366 +#profile-wall .profile-wall-activities-comments img,
  6367 +#profile-network .profile-wall-activities-comments img {
  6368 + width: 33px;
  6369 + height: 33px;
  6370 +}
  6371 +
  6372 +#profile-wall .profile-wall-activities-comments .comment_reply,
  6373 +#profile-wall .profile-wall-activities-comments h4,
  6374 +#profile-network .profile-wall-activities-comments .comment_reply,
  6375 +#profile-network .profile-wall-activities-comments h4 {
  6376 + display: none;
  6377 +}
  6378 +
  6379 +#profile-wall .profile-wall-activities-comments .comment-picture,
  6380 +#profile-network .profile-wall-activities-comments .comment-picture {
  6381 + width: 33px;
  6382 + margin-right: 10px;
  6383 +}
  6384 +
  6385 +#profile-wall .profile-wall-activities-comments .comment-text p,
  6386 +#profile-network .profile-wall-activities-comments .comment-text p {
  6387 + margin: 0;
  6388 +}
  6389 +
  6390 +#profile-wall .profile-wall-activities-comments .profile-activity-time,
  6391 +#profile-network .profile-wall-activities-comments .profile-activity-time {
  6392 + clear: both;
  6393 +}
  6394 +
  6395 +#profile-wall .profile-wall-activities-comments .comment-details,
  6396 +#profile-network .profile-wall-activities-comments .comment-details {
  6397 + padding: 0;
  6398 +}
  6399 +
  6400 +#profile-wall .profile-wall-activities-comments .article-comment .button-bar,
  6401 +#profile-network .profile-wall-activities-comments .article-comment .button-bar {
  6402 + float: right;
  6403 + padding: 0;
  6404 + text-align: right;
  6405 + position: static;
  6406 + clear: none;
  6407 + display: none;
  6408 +}
  6409 +
  6410 +#profile-wall .profile-wall-activities-comments .article-comment:hover .button-bar,
  6411 +#profile-network .profile-wall-activities-comments .article-comment:hover .button-bar {
  6412 + display: block;
  6413 +}
  6414 +
  6415 +#profile-wall .profile-wall-activities-comments .article-comment .button-bar a.button,
  6416 +#profile-network .profile-wall-activities-comments .article-comment .button-bar a.button {
  6417 + background: transparent;
  6418 + border: 0;
  6419 + height: auto;
  6420 + line-height: auto;
  6421 + color: #333;
  6422 + text-decoration: none;
  6423 + font-size: 10px;
  6424 + padding: 0;
  6425 + margin: 0;
  6426 + display: inline;
  6427 + position: static;
  6428 + float: none;
  6429 + font-weight: normal;
  6430 +}
  6431 +
  6432 +#profile-wall .profile-wall-activities-comments .article-comment .button-bar a.button:hover,
  6433 +#profile-network .profile-wall-activities-comments .article-comment .button-bar a.button:hover {
  6434 + text-decoration: underline;
  6435 +}
  6436 +
  6437 +#profile-wall .profile-wall-activities-comments .article-comment .button-bar .button span,
  6438 +#profile-network .profile-wall-activities-comments .article-comment .button-bar .button span {
  6439 + display: inline;
  6440 + position: static;
  6441 + display: inline;
  6442 +}
  6443 +
6119 /* friends online {{{ */ 6444 /* friends online {{{ */
6120 6445
6121 #chat-online-users { 6446 #chat-online-users {
@@ -6245,18 +6570,37 @@ h1#agenda-title { @@ -6245,18 +6570,37 @@ h1#agenda-title {
6245 } 6570 }
6246 6571
6247 #profile-wall .comment-balloon-content { 6572 #profile-wall .comment-balloon-content {
6248 - padding: 3px 0 3px 15px; 6573 + padding: 3px 0px;
6249 } 6574 }
6250 6575
6251 .profile-wall-reply { 6576 .profile-wall-reply {
6252 margin: 0; 6577 margin: 0;
6253 } 6578 }
6254 6579
  6580 +.profile-wall-reply-form {
  6581 + display: block;
  6582 + background: #f0f0f1;
  6583 + border-bottom: 1px solid #d2d2d2;
  6584 + border-top: 1px solid #fff;
  6585 + margin-left: 50px;
  6586 + padding: 0 5px;
  6587 +}
  6588 +
  6589 +.scrap-replies .profile-wall-reply-form {
  6590 + margin-left: 0px;
  6591 +}
  6592 +
6255 .profile-wall-scrap-replies { 6593 .profile-wall-scrap-replies {
6256 float: right; 6594 float: right;
6257 margin-right: 2px; 6595 margin-right: 2px;
6258 } 6596 }
6259 6597
  6598 +.view-all-comments {
  6599 + clear: both;
  6600 + margin-left: 50px;
  6601 + padding-left: 20px;
  6602 +}
  6603 +
6260 /* Profile activity relative dimensions */ 6604 /* Profile activity relative dimensions */
6261 6605
6262 #leave_scrap { 6606 #leave_scrap {
@@ -6267,18 +6611,36 @@ h1#agenda-title { @@ -6267,18 +6611,36 @@ h1#agenda-title {
6267 width: 98%; 6611 width: 98%;
6268 } 6612 }
6269 6613
6270 -#profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image {  
6271 - width: 19%; 6614 +.profile-activities .profile-activity-image,
  6615 +#profile-network .profile-activity-image,
  6616 +#profile-wall .profile-wall-image {
  6617 + width: 50px;
  6618 + margin: 5px;
  6619 + float: left;
6272 } 6620 }
6273 6621
6274 -#profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description {  
6275 - width: 80%; 6622 +#profile-activity .profile-activity-description,
  6623 +#profile-network .profile-activity-description,
  6624 +#profile-wall .profile-wall-description {
6276 word-wrap: break-word; 6625 word-wrap: break-word;
6277 } 6626 }
6278 6627
  6628 +#profile-wall textarea {
  6629 + width: 375px;
  6630 +}
  6631 +
  6632 +#profile-wall li textarea {
  6633 + width: 388px;
  6634 +}
  6635 +
6279 #profile-wall .profile-wall-scrap-replies textarea, 6636 #profile-wall .profile-wall-scrap-replies textarea,
6280 -#profile-network textarea, #profile-wall textarea {  
6281 - width: 99%; 6637 +#profile-network textarea, #profile-wall textarea,
  6638 +#profile-wall li .profile-wall-reply-form textarea {
  6639 + width: 98%;
  6640 +}
  6641 +
  6642 +#profile-wall #leave_scrap textarea {
  6643 + width: 442px;
6282 } 6644 }
6283 6645
6284 .profile-wall-scrap-replies { 6646 .profile-wall-scrap-replies {
test/factories.rb
@@ -372,7 +372,7 @@ module Noosfero::Factory @@ -372,7 +372,7 @@ module Noosfero::Factory
372 ############################################### 372 ###############################################
373 373
374 def defaults_for_scrap(params = {}) 374 def defaults_for_scrap(params = {})
375 - { :content => 'soment content ', :sender_id => 1, :receiver_id => 1, :created_at => DateTime.now }.merge(params) 375 + { :content => 'some content ', :sender_id => 1, :receiver_id => 1, :created_at => DateTime.now }.merge(params)
376 end 376 end
377 377
378 ############################################### 378 ###############################################
@@ -440,7 +440,7 @@ module Noosfero::Factory @@ -440,7 +440,7 @@ module Noosfero::Factory
440 440
441 def defaults_for_comment(params = {}) 441 def defaults_for_comment(params = {})
442 name = "comment_#{rand(1000)}" 442 name = "comment_#{rand(1000)}"
443 - { :title => name, :body => "my own comment", :article_id => 1 }.merge(params) 443 + { :title => name, :body => "my own comment", :source_id => 1 }.merge(params)
444 end 444 end
445 445
446 ############################################### 446 ###############################################
test/functional/profile_controller_test.rb
@@ -714,25 +714,23 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -714,25 +714,23 @@ class ProfileControllerTest &lt; ActionController::TestCase
714 assert_no_tag :tag => 'p', :content => 'A scrap' 714 assert_no_tag :tag => 'p', :content => 'A scrap'
715 end 715 end
716 716
717 - should 'see all activities of the current profile' do  
718 - p1= Person.first 717 + should 'not display activities of the current profile when he is not followed by the viewer' do
  718 + p1= fast_create(Person)
719 p2= fast_create(Person) 719 p2= fast_create(Person)
720 - assert !p1.is_a_friend?(p2)  
721 - p3= fast_create(Person)  
722 - assert !p1.is_a_friend?(p3)  
723 - ActionTracker::Record.destroy_all  
724 - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))  
725 - a1 = ActionTracker::Record.last 720 +
  721 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
  722 + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p2))
  723 +
726 UserStampSweeper.any_instance.stubs(:current_user).returns(p2) 724 UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
727 - Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))  
728 - a2 = ActionTracker::Record.last  
729 - UserStampSweeper.any_instance.stubs(:current_user).returns(p3)  
730 - Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))  
731 - a3 = ActionTracker::Record.last 725 + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p1))
  726 +
  727 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
  728 + TinyMceArticle.create!(:profile => p1, :name => 'An article about free software')
  729 + a1 = ActionTracker::Record.last
  730 +
732 login_as(profile.identifier) 731 login_as(profile.identifier)
733 get :index, :profile => p1.identifier 732 get :index, :profile => p1.identifier
734 - assert_not_nil assigns(:activities)  
735 - assert_equal [a1], assigns(:activities) 733 + assert_nil assigns(:activities)
736 end 734 end
737 735
738 should 'see the activities_items paginated' do 736 should 'see the activities_items paginated' do
@@ -744,26 +742,27 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -744,26 +742,27 @@ class ProfileControllerTest &lt; ActionController::TestCase
744 assert_equal 30, assigns(:activities).count 742 assert_equal 30, assigns(:activities).count
745 end 743 end
746 744
747 - should 'see not see the friends activities in the current profile activity' do  
748 - p1= Person.first 745 + should 'not see the friends activities in the current profile' do
749 p2= fast_create(Person) 746 p2= fast_create(Person)
750 - assert !p1.is_a_friend?(p2) 747 + assert !profile.is_a_friend?(p2)
751 p3= fast_create(Person) 748 p3= fast_create(Person)
752 - p1.add_friend(p3)  
753 - assert p1.is_a_friend?(p3) 749 + p3.add_friend(profile)
  750 + assert p3.is_a_friend?(profile)
754 ActionTracker::Record.destroy_all 751 ActionTracker::Record.destroy_all
755 - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))  
756 - a1 = ActionTracker::Record.last  
757 - UserStampSweeper.any_instance.stubs(:current_user).returns(p2)  
758 - Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))  
759 - a2 = ActionTracker::Record.last 752 +
  753 + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
  754 + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => profile))
  755 +
760 UserStampSweeper.any_instance.stubs(:current_user).returns(p3) 756 UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
761 - Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))  
762 - a3 = ActionTracker::Record.last 757 + article1 = TinyMceArticle.create!(:profile => p3, :name => 'An article about free software')
  758 +
  759 + UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
  760 + article2 = TinyMceArticle.create!(:profile => p2, :name => 'Another article about free software')
  761 +
763 login_as(profile.identifier) 762 login_as(profile.identifier)
764 - get :index, :profile => p1.identifier 763 + get :index, :profile => p3.identifier
765 assert_not_nil assigns(:activities) 764 assert_not_nil assigns(:activities)
766 - assert_equal [a1], assigns(:activities) 765 + assert_equivalent [scrap1, article1.activity], assigns(:activities).map { |a| a.klass.constantize.find(a.id) }
767 end 766 end
768 767
769 should 'see all the activities in the current profile network' do 768 should 'see all the activities in the current profile network' do
@@ -931,13 +930,29 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -931,13 +930,29 @@ class ProfileControllerTest &lt; ActionController::TestCase
931 assert_template 'index' 930 assert_template 'index'
932 end 931 end
933 932
934 - should 'have wall_itens defined' do  
935 - p1= ActionTracker::Record.current_user_from_model 933 + should 'not have activities defined if not logged in' do
  934 + p1= fast_create(Person)
  935 + get :index, :profile => p1.identifier
  936 + assert_nil assigns(:actvities)
  937 + end
  938 +
  939 + should 'not have activities defined if logged in but is not following profile' do
  940 + login_as(profile.identifier)
  941 + p1= fast_create(Person)
936 get :index, :profile => p1.identifier 942 get :index, :profile => p1.identifier
937 - assert_equal [], assigns(:wall_items) 943 + assert_nil assigns(:activities)
938 end 944 end
939 945
940 - should 'the wall_itens be the received scraps in people profile' do 946 + should 'have activities defined if logged in and is following profile' do
  947 + login_as(profile.identifier)
  948 + p1= fast_create(Person)
  949 + p1.add_friend(profile)
  950 + ActionTracker::Record.destroy_all
  951 + get :index, :profile => p1.identifier
  952 + assert_equal [], assigns(:activities)
  953 + end
  954 +
  955 + should 'the activities be the received scraps in people profile' do
941 p1 = ActionTracker::Record.current_user_from_model 956 p1 = ActionTracker::Record.current_user_from_model
942 p2 = fast_create(Person) 957 p2 = fast_create(Person)
943 p3 = fast_create(Person) 958 p3 = fast_create(Person)
@@ -952,10 +967,10 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -952,10 +967,10 @@ class ProfileControllerTest &lt; ActionController::TestCase
952 @controller.stubs(:current_user).returns(user) 967 @controller.stubs(:current_user).returns(user)
953 Person.any_instance.stubs(:follows?).returns(true) 968 Person.any_instance.stubs(:follows?).returns(true)
954 get :index, :profile => p1.identifier 969 get :index, :profile => p1.identifier
955 - assert_equal [s2,s3], assigns(:wall_items) 970 + assert_equal [s2,s3], assigns(:activities)
956 end 971 end
957 972
958 - should 'the wall_itens be the received scraps in community profile' do 973 + should 'the activities be the received scraps in community profile' do
959 c = fast_create(Community) 974 c = fast_create(Community)
960 p1 = fast_create(Person) 975 p1 = fast_create(Person)
961 p2 = fast_create(Person) 976 p2 = fast_create(Person)
@@ -971,12 +986,12 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -971,12 +986,12 @@ class ProfileControllerTest &lt; ActionController::TestCase
971 @controller.stubs(:current_user).returns(user) 986 @controller.stubs(:current_user).returns(user)
972 Person.any_instance.stubs(:follows?).returns(true) 987 Person.any_instance.stubs(:follows?).returns(true)
973 get :index, :profile => c.identifier 988 get :index, :profile => c.identifier
974 - assert_equal [s2,s3], assigns(:wall_items) 989 + assert_equal [s2,s3], assigns(:activities)
975 end 990 end
976 991
977 - should 'the wall_itens be paginated in people profiles' do 992 + should 'the activities be paginated in people profiles' do
978 p1 = Person.first 993 p1 = Person.first
979 - 40.times{fast_create(Scrap, :sender_id => p1.id)} 994 + 40.times{fast_create(Scrap, :sender_id => p1.id, :created_at => Time.now)}
980 995
981 @controller.stubs(:logged_in?).returns(true) 996 @controller.stubs(:logged_in?).returns(true)
982 user = mock() 997 user = mock()
@@ -986,10 +1001,10 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -986,10 +1001,10 @@ class ProfileControllerTest &lt; ActionController::TestCase
986 Person.any_instance.stubs(:follows?).returns(true) 1001 Person.any_instance.stubs(:follows?).returns(true)
987 assert_equal 40, p1.scraps_received.not_replies.count 1002 assert_equal 40, p1.scraps_received.not_replies.count
988 get :index, :profile => p1.identifier 1003 get :index, :profile => p1.identifier
989 - assert_equal 30, assigns(:wall_items).count 1004 + assert_equal 30, assigns(:activities).count
990 end 1005 end
991 1006
992 - should 'the wall_itens be paginated in community profiles' do 1007 + should 'the activities be paginated in community profiles' do
993 p1 = Person.first 1008 p1 = Person.first
994 c = fast_create(Community) 1009 c = fast_create(Community)
995 40.times{fast_create(Scrap, :receiver_id => c.id)} 1010 40.times{fast_create(Scrap, :receiver_id => c.id)}
@@ -1002,7 +1017,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1002,7 +1017,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1002 Person.any_instance.stubs(:follows?).returns(true) 1017 Person.any_instance.stubs(:follows?).returns(true)
1003 assert_equal 40, c.scraps_received.not_replies.count 1018 assert_equal 40, c.scraps_received.not_replies.count
1004 get :index, :profile => c.identifier 1019 get :index, :profile => c.identifier
1005 - assert_equal 30, assigns(:wall_items).count 1020 + assert_equal 30, assigns(:activities).count
1006 end 1021 end
1007 1022
1008 should "the owner of activity could remove it" do 1023 should "the owner of activity could remove it" do
@@ -1072,17 +1087,17 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1072,17 +1087,17 @@ class ProfileControllerTest &lt; ActionController::TestCase
1072 end 1087 end
1073 end 1088 end
1074 1089
1075 - should "not show the scrap button on network activity if the user don't follow the user" do 1090 + should "not show the network activity if the viewer don't follow the profile" do
1076 login_as(profile.identifier) 1091 login_as(profile.identifier)
1077 person = fast_create(Person) 1092 person = fast_create(Person)
1078 at = fast_create(ActionTracker::Record, :user_id => person.id) 1093 at = fast_create(ActionTracker::Record, :user_id => person.id)
1079 atn = fast_create(ActionTrackerNotification, :profile_id => profile.id, :action_tracker_id => at.id) 1094 atn = fast_create(ActionTrackerNotification, :profile_id => profile.id, :action_tracker_id => at.id)
1080 - get :index, :profile => profile.identifier  
1081 - assert_no_tag :tag => 'p', :attributes => {:class => 'profile-network-send-message'} 1095 + get :index, :profile => person.identifier
  1096 + assert_no_tag :tag => 'div', :attributes => {:id => 'profile-network'}
1082 1097
1083 person.add_friend(profile) 1098 person.add_friend(profile)
1084 - get :index, :profile => profile.identifier  
1085 - assert_tag :tag => 'p', :attributes => {:class => 'profile-network-send-message'} 1099 + get :index, :profile => person.identifier
  1100 + assert_tag :tag => 'div', :attributes => {:id => 'profile-network'}
1086 end 1101 end
1087 1102
1088 should "not show the scrap button on network activity if the user is himself" do 1103 should "not show the scrap button on network activity if the user is himself" do
@@ -1093,16 +1108,16 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1093,16 +1108,16 @@ class ProfileControllerTest &lt; ActionController::TestCase
1093 assert_no_tag :tag => 'p', :attributes => {:class => 'profile-network-send-message'} 1108 assert_no_tag :tag => 'p', :attributes => {:class => 'profile-network-send-message'}
1094 end 1109 end
1095 1110
1096 - should "not show the scrap button on wall activity if the user don't follow the user" do 1111 + should "not show the scrap area on wall if the user don't follow the user" do
1097 login_as(profile.identifier) 1112 login_as(profile.identifier)
1098 person = fast_create(Person) 1113 person = fast_create(Person)
1099 scrap = fast_create(Scrap, :sender_id => person.id, :receiver_id => profile.id) 1114 scrap = fast_create(Scrap, :sender_id => person.id, :receiver_id => profile.id)
1100 - get :index, :profile => profile.identifier  
1101 - assert_no_tag :tag => 'p', :attributes => {:class => 'profile-wall-send-message'} 1115 + get :index, :profile => person.identifier
  1116 + assert_no_tag :tag => 'div', :attributes => {:id => 'leave_scrap'}, :descendant => { :tag => 'input', :attributes => {:value => 'Share'} }
1102 1117
1103 person.add_friend(profile) 1118 person.add_friend(profile)
1104 - get :index, :profile => profile.identifier  
1105 - assert_tag :tag => 'p', :attributes => {:class => 'profile-wall-send-message'} 1119 + get :index, :profile => person.identifier
  1120 + assert_tag :tag => 'div', :attributes => {:id => 'leave_scrap'}, :descendant => { :tag => 'input', :attributes => {:value => 'Share'} }
1106 end 1121 end
1107 1122
1108 should "not show the scrap button on wall activity if the user is himself" do 1123 should "not show the scrap button on wall activity if the user is himself" do
@@ -1158,7 +1173,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1158,7 +1173,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1158 assert_equal 40, profile.tracked_actions.count 1173 assert_equal 40, profile.tracked_actions.count
1159 get :view_more_activities, :profile => profile.identifier, :page => 2 1174 get :view_more_activities, :profile => profile.identifier, :page => 2
1160 assert_response :success 1175 assert_response :success
1161 - assert_template '_profile_activities' 1176 + assert_template '_profile_activities_list'
1162 assert_equal 10, assigns(:activities).count 1177 assert_equal 10, assigns(:activities).count
1163 end 1178 end
1164 1179
@@ -1247,4 +1262,70 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1247,4 +1262,70 @@ class ProfileControllerTest &lt; ActionController::TestCase
1247 post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'} 1262 post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'}
1248 end 1263 end
1249 end 1264 end
  1265 +
  1266 + should 'display activities and scraps together' do
  1267 + another_person = fast_create(Person)
  1268 + Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  1269 +
  1270 + UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
  1271 + ActionTracker::Record.destroy_all
  1272 + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1273 +
  1274 + login_as(profile.identifier)
  1275 + get :index, :profile => profile.identifier
  1276 +
  1277 + assert_tag :tag => 'p', :content => 'A scrap', :attributes => { :class => 'profile-activity-text'}
  1278 + assert_tag :tag => 'div', :attributes => { :class => 'profile-activity-lead' }, :descendant => { :tag => 'a', :content => 'An article about free software' }
  1279 + end
  1280 +
  1281 + should 'have scraps and activities on activities' do
  1282 + another_person = fast_create(Person)
  1283 + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  1284 +
  1285 + UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
  1286 + ActionTracker::Record.destroy_all
  1287 + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1288 + activity = ActionTracker::Record.last
  1289 +
  1290 + login_as(profile.identifier)
  1291 + get :index, :profile => profile.identifier
  1292 +
  1293 + assert_equivalent [scrap,activity], assigns(:activities).map {|a| a.klass.constantize.find(a.id)}
  1294 + end
  1295 +
  1296 + should "be logged in to leave comment on an activity" do
  1297 + article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1298 + activity = ActionTracker::Record.last
  1299 + count = activity.comments.count
  1300 +
  1301 + post :leave_comment_on_activity, :profile => profile.identifier, :comment => {:body => 'something', :source_id => activity.id}
  1302 + assert_equal count, activity.comments.count
  1303 + assert_redirected_to :controller => 'account', :action => 'login'
  1304 + end
  1305 +
  1306 + should "leave a comment in own activity" do
  1307 + login_as(profile.identifier)
  1308 + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1309 + activity = ActionTracker::Record.last
  1310 + count = activity.comments.count
  1311 +
  1312 + assert_equal 0, count
  1313 + post :leave_comment_on_activity, :profile => profile.identifier, :comment => {:body => 'something'}, :source_id => activity.id
  1314 + assert_equal count + 1, ActionTracker::Record.find(activity.id).comments_count
  1315 + assert_response :success
  1316 + assert_equal "Comment successfully added.", assigns(:message)
  1317 + end
  1318 +
  1319 + should "leave a comment on another profile's activity" do
  1320 + login_as(profile.identifier)
  1321 + another_person = fast_create(Person)
  1322 + TinyMceArticle.create!(:profile => another_person, :name => 'An article about free software')
  1323 + activity = ActionTracker::Record.last
  1324 + count = activity.comments.count
  1325 + assert_equal 0, count
  1326 + post :leave_comment_on_activity, :profile => another_person.identifier, :comment => {:body => 'something'}, :source_id => activity.id
  1327 + assert_equal count + 1, ActionTracker::Record.find(activity.id).comments_count
  1328 + assert_response :success
  1329 + assert_equal "Comment successfully added.", assigns(:message)
  1330 + end
1250 end 1331 end
test/unit/action_tracker_notification_test.rb
@@ -76,4 +76,28 @@ class ActionTrackerNotificationTest &lt; ActiveSupport::TestCase @@ -76,4 +76,28 @@ class ActionTrackerNotificationTest &lt; ActiveSupport::TestCase
76 assert_equal [last_notification], at.action_tracker_notifications 76 assert_equal [last_notification], at.action_tracker_notifications
77 end 77 end
78 78
  79 + should "have comments through action_tracker" do
  80 + person = fast_create(Person)
  81 + community = fast_create(Community)
  82 + community.add_member(person)
  83 + activity = ActionTracker::Record.last
  84 + process_delayed_job_queue
  85 + notification = ActionTrackerNotification.last
  86 +
  87 + comment = create(Comment, :source => activity, :author => person)
  88 +
  89 + assert_equal activity.comments, notification.comments
  90 + end
  91 +
  92 + should "have comments through article action_tracker" do
  93 + person = fast_create(Person)
  94 + article = create(TextileArticle, :profile_id => person.id)
  95 + process_delayed_job_queue
  96 + notification = ActionTrackerNotification.last
  97 +
  98 + comment = create(Comment, :source => article, :author => person)
  99 +
  100 + assert_equal article.activity.comments, notification.comments
  101 + end
  102 +
79 end 103 end
test/unit/approve_article_test.rb
@@ -250,7 +250,7 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase @@ -250,7 +250,7 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
250 assert_equal 1, ActionTracker::Record.count 250 assert_equal 1, ActionTracker::Record.count
251 end 251 end
252 252
253 - should 'notify with different trackers activity create with different targets' do 253 + should 'not group trackers activity of article\'s creation' do
254 ActionTracker::Record.delete_all 254 ActionTracker::Record.delete_all
255 255
256 article = fast_create(TextileArticle) 256 article = fast_create(TextileArticle)
@@ -260,28 +260,15 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase @@ -260,28 +260,15 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
260 article = fast_create(TextileArticle) 260 article = fast_create(TextileArticle)
261 a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => community, :requestor => profile) 261 a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => community, :requestor => profile)
262 a.finish 262 a.finish
263 - assert_equal 1, ActionTracker::Record.count  
264 263
265 article = fast_create(TextileArticle) 264 article = fast_create(TextileArticle)
266 other_community = fast_create(Community) 265 other_community = fast_create(Community)
267 a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => other_community, :requestor => profile) 266 a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => other_community, :requestor => profile)
268 a.finish 267 a.finish
269 - assert_equal 2, ActionTracker::Record.count  
270 - end  
271 -  
272 - should 'notify activity on update' do  
273 - ActionTracker::Record.delete_all  
274 - a = ApproveArticle.create!(:name => 'bar', :article => article, :target => community, :requestor => profile)  
275 - a.finish  
276 - assert_equal 1, ActionTracker::Record.count  
277 -  
278 - published = article.class.last  
279 - published.name = 'foo'  
280 - published.save!  
281 - assert_equal 2, ActionTracker::Record.count 268 + assert_equal 3, ActionTracker::Record.count
282 end 269 end
283 270
284 - should 'notify with different trackers activity update with different targets' do 271 + should 'not create trackers activity when updating articles' do
285 ActionTracker::Record.delete_all 272 ActionTracker::Record.delete_all
286 article1 = fast_create(TextileArticle) 273 article1 = fast_create(TextileArticle)
287 a = ApproveArticle.create!(:name => 'bar', :article => article1, :target => community, :requestor => profile) 274 a = ApproveArticle.create!(:name => 'bar', :article => article1, :target => community, :requestor => profile)
@@ -293,16 +280,16 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase @@ -293,16 +280,16 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
293 a.finish 280 a.finish
294 assert_equal 2, ActionTracker::Record.count 281 assert_equal 2, ActionTracker::Record.count
295 282
296 - published = article1.class.last  
297 - published.name = 'foo';published.save!  
298 - assert_equal 3, ActionTracker::Record.count  
299 -  
300 - published = article2.class.last  
301 - published.name = 'another foo';published.save!  
302 - assert_equal 4, ActionTracker::Record.count 283 + assert_no_difference ActionTracker::Record, :count do
  284 + published = article1.class.last
  285 + published.name = 'foo';published.save!
  286 +
  287 + published = article2.class.last
  288 + published.name = 'another foo';published.save!
  289 + end
303 end 290 end
304 291
305 - should "the tracker action target be defined as Community by custom_target method on articles'creation in communities" do 292 + should "the tracker action target be defined as the article on articles'creation in communities" do
306 ActionTracker::Record.delete_all 293 ActionTracker::Record.delete_all
307 person = fast_create(Person) 294 person = fast_create(Person)
308 community.add_member(person) 295 community.add_member(person)
@@ -310,17 +297,21 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase @@ -310,17 +297,21 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
310 a = ApproveArticle.create!(:article => article, :target => community, :requestor => profile) 297 a = ApproveArticle.create!(:article => article, :target => community, :requestor => profile)
311 a.finish 298 a.finish
312 299
313 - assert_equal Community, ActionTracker::Record.last.target.class 300 + approved_article = community.articles.find_by_name(article.name)
  301 +
  302 + assert_equal approved_article, ActionTracker::Record.last.target
314 end 303 end
315 304
316 - should "the tracker action target be defined as person by custom_target method on articles'creation in profile" do 305 + should "the tracker action target be defined as the article on articles'creation in profile" do
317 ActionTracker::Record.delete_all 306 ActionTracker::Record.delete_all
318 person = fast_create(Person) 307 person = fast_create(Person)
319 308
320 a = ApproveArticle.create!(:article => article, :target => person, :requestor => profile) 309 a = ApproveArticle.create!(:article => article, :target => person, :requestor => profile)
321 a.finish 310 a.finish
322 311
323 - assert_equal Person, ActionTracker::Record.last.target.class 312 + approved_article = person.articles.find_by_name(article.name)
  313 +
  314 + assert_equal approved_article, ActionTracker::Record.last.target
324 end 315 end
325 316
326 should "have the same is_trackable method as original article" do 317 should "have the same is_trackable method as original article" do
test/unit/article_test.rb
@@ -320,15 +320,16 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -320,15 +320,16 @@ class ArticleTest &lt; ActiveSupport::TestCase
320 320
321 should 'list most commented articles' do 321 should 'list most commented articles' do
322 Article.delete_all 322 Article.delete_all
  323 + (1..4).each do |n|
  324 + create(TextileArticle, :name => "art #{n}", :profile_id => profile.id)
  325 + end
  326 + first_article = profile.articles.first
  327 + 2.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => first_article).save! }
323 328
324 - person = create_user('testuser').person  
325 - articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}"); a.save!; a }  
326 -  
327 - 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! }  
328 - 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! }  
329 - 329 + last_article = profile.articles.last
  330 + 4.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => last_article).save! }
330 # should respect the order (more commented comes first) 331 # should respect the order (more commented comes first)
331 - assert_equal [articles[1], articles[0]], person.articles.most_commented(2) 332 + assert_equal [last_article, first_article], profile.articles.most_commented(2)
332 end 333 end
333 334
334 should 'identify itself as a non-folder' do 335 should 'identify itself as a non-folder' do
@@ -362,16 +363,16 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -362,16 +363,16 @@ class ArticleTest &lt; ActiveSupport::TestCase
362 363
363 should 'index comments title together with article' do 364 should 'index comments title together with article' do
364 owner = create_user('testuser').person 365 owner = create_user('testuser').person
365 - art = owner.articles.build(:name => 'ytest'); art.save!  
366 - c1 = art.comments.build(:title => 'a nice comment', :body => 'anything', :author => owner); c1.save! 366 + art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest')
  367 + c1 = Comment.create(:title => 'a nice comment', :body => 'anything', :author => owner, :source => art ); c1.save!
367 368
368 assert_includes Article.find_by_contents('nice'), art 369 assert_includes Article.find_by_contents('nice'), art
369 end 370 end
370 371
371 should 'index comments body together with article' do 372 should 'index comments body together with article' do
372 owner = create_user('testuser').person 373 owner = create_user('testuser').person
373 - art = owner.articles.build(:name => 'ytest'); art.save!  
374 - c1 = art.comments.build(:title => 'test comment', :body => 'anything', :author => owner); c1.save! 374 + art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest')
  375 + c1 = Comment.create(:title => 'test comment', :body => 'anything', :author => owner, :source => art); c1.save!
375 376
376 assert_includes Article.find_by_contents('anything'), art 377 assert_includes Article.find_by_contents('anything'), art
377 end 378 end
@@ -934,79 +935,34 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -934,79 +935,34 @@ class ArticleTest &lt; ActiveSupport::TestCase
934 end 935 end
935 936
936 should 'track action when a published article is created outside a community' do 937 should 'track action when a published article is created outside a community' do
937 - article = TinyMceArticle.create! :name => 'Tracked Article', :profile_id => profile.id  
938 - assert article.published?  
939 - assert_kind_of Person, article.profile  
940 - ta = ActionTracker::Record.last  
941 - assert_equal 'Tracked Article', ta.get_name.last  
942 - assert_equal article.url, ta.get_url.last  
943 - assert_kind_of Person, ta.user  
944 - ta.created_at = Time.now.ago(26.hours); ta.save!  
945 - article = TinyMceArticle.create! :name => 'Another Tracked Article', :profile_id => profile.id  
946 - ta = ActionTracker::Record.last  
947 - assert_equal ['Another Tracked Article'], ta.get_name  
948 - assert_equal [article.url], ta.get_url 938 + article = create(TinyMceArticle, :profile_id => profile.id)
  939 + ta = article.activity
  940 + assert_equal article.name, ta.get_name
  941 + assert_equal article.url, ta.get_url
949 end 942 end
950 943
951 should 'track action when a published article is created in a community' do 944 should 'track action when a published article is created in a community' do
952 community = fast_create(Community) 945 community = fast_create(Community)
953 - p1 = ActionTracker::Record.current_user_from_model 946 + p1 = fast_create(Person)
954 p2 = fast_create(Person) 947 p2 = fast_create(Person)
955 p3 = fast_create(Person) 948 p3 = fast_create(Person)
956 community.add_member(p1) 949 community.add_member(p1)
957 community.add_member(p2) 950 community.add_member(p2)
958 - assert p1.is_member_of?(community)  
959 - assert p2.is_member_of?(community)  
960 - assert !p3.is_member_of?(community)  
961 - Article.destroy_all  
962 - ActionTracker::Record.destroy_all  
963 - article = TinyMceArticle.create! :name => 'Tracked Article', :profile_id => community.id  
964 - assert article.published?  
965 - assert_kind_of Community, article.profile  
966 - ta = ActionTracker::Record.last  
967 - assert_equal 'Tracked Article', ta.get_name.last  
968 - assert_equal article.url, ta.get_url.last  
969 - assert_kind_of Person, ta.user 951 + UserStampSweeper.any_instance.expects(:current_user).returns(p1).at_least_once
  952 +
  953 + article = create(TinyMceArticle, :profile_id => community.id)
  954 + activity = article.activity
  955 +
970 process_delayed_job_queue 956 process_delayed_job_queue
971 - assert_equal 3, ActionTrackerNotification.count  
972 - ActionTrackerNotification.all.map{|a|a.profile}.map do |profile|  
973 - assert [p1,p2,community].include?(profile)  
974 - end 957 + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(activity.id).count
  958 + assert_equivalent [p1,p2,community], ActionTrackerNotification.find_all_by_action_tracker_id(activity.id).map(&:profile)
975 end 959 end
976 960
977 - should 'track action when a published article is updated' do  
978 - a = TinyMceArticle.create! :name => 'a', :profile_id => profile.id  
979 - a.update_attributes! :name => 'b'  
980 - ta = ActionTracker::Record.last  
981 - assert_equal ['b'], ta.get_name  
982 - assert_equal [a.reload.url], ta.get_url  
983 - a.update_attributes! :name => 'c'  
984 - ta = ActionTracker::Record.last  
985 - assert_equal ['b','c'], ta.get_name  
986 - assert_equal [a.url,a.reload.url], ta.get_url  
987 - a.update_attributes! :body => 'test'  
988 - ta = ActionTracker::Record.last  
989 - assert_equal ['b','c','c'], ta.get_name  
990 - assert_equal [a.url,a.reload.url,a.reload.url], ta.get_url  
991 - a.update_attributes! :hits => 50  
992 - ta = ActionTracker::Record.last  
993 - assert_equal ['b','c','c'], ta.get_name  
994 - assert_equal [a.url,a.reload.url,a.reload.url], ta.get_url  
995 - end  
996 -  
997 - should 'track action when a published article is removed' do  
998 - a = TinyMceArticle.create! :name => 'a', :profile_id => profile.id  
999 - a.destroy  
1000 - ta = ActionTracker::Record.last  
1001 - assert_equal ['a'], ta.get_name  
1002 - a = TinyMceArticle.create! :name => 'b', :profile_id => profile.id  
1003 - a.destroy  
1004 - ta = ActionTracker::Record.last  
1005 - assert_equal ['a','b'], ta.get_name  
1006 - a = TinyMceArticle.create! :name => 'c', :profile_id => profile.id, :published => false  
1007 - a.destroy  
1008 - ta = ActionTracker::Record.last  
1009 - assert_equal ['a','b'], ta.get_name 961 + should 'not track action when a published article is removed' do
  962 + a = create(TinyMceArticle, :profile_id => profile.id)
  963 + assert_no_difference ActionTracker::Record, :count do
  964 + a.destroy
  965 + end
1010 end 966 end
1011 967
1012 should 'notifiable is false by default' do 968 should 'notifiable is false by default' do
@@ -1035,6 +991,15 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1035,6 +991,15 @@ class ArticleTest &lt; ActiveSupport::TestCase
1035 assert_equal 0, ActionTracker::Record.count 991 assert_equal 0, ActionTracker::Record.count
1036 end 992 end
1037 993
  994 + should 'create activity' do
  995 + a = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
  996 + a.activity.destroy
  997 + assert_nil a.activity
  998 +
  999 + a.create_activity
  1000 + assert_not_nil a.activity
  1001 + end
  1002 +
1038 should "the action_tracker_target method be defined" do 1003 should "the action_tracker_target method be defined" do
1039 assert Article.method_defined?(:action_tracker_target) 1004 assert Article.method_defined?(:action_tracker_target)
1040 end 1005 end
@@ -1071,141 +1036,64 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1071,141 +1036,64 @@ class ArticleTest &lt; ActiveSupport::TestCase
1071 assert_equal false, a.is_trackable? 1036 assert_equal false, a.is_trackable?
1072 end 1037 end
1073 1038
1074 - should 'not create more than one notification track action to community when update more than one artile' do  
1075 - community = fast_create(Community)  
1076 - p1 = Person.first || fast_create(Person)  
1077 - community.add_member(p1)  
1078 - assert p1.is_member_of?(community)  
1079 - Article.destroy_all  
1080 - ActionTracker::Record.destroy_all  
1081 - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => community.id  
1082 - assert article.published?  
1083 - assert_kind_of Community, article.profile  
1084 - assert_equal 1, ActionTracker::Record.count  
1085 - ta = ActionTracker::Record.last  
1086 - assert_equal 'Tracked Article 1', ta.get_name.last  
1087 - assert_equal article.url, ta.get_url.last  
1088 - assert p1, ta.user  
1089 - assert community, ta.target  
1090 - process_delayed_job_queue  
1091 - assert_equal 2, ActionTrackerNotification.count  
1092 -  
1093 - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id  
1094 - assert article.published?  
1095 - assert_kind_of Community, article.profile  
1096 - assert_equal 1, ActionTracker::Record.count  
1097 - ta = ActionTracker::Record.last  
1098 - assert_equal 'Tracked Article 2', ta.get_name.last  
1099 - assert_equal article.url, ta.get_url.last  
1100 - assert_equal p1, ta.user  
1101 - assert_equal community, ta.target  
1102 - process_delayed_job_queue  
1103 - assert_equal 2, ActionTrackerNotification.count 1039 + should "not be trackable if article is inside a private community" do
  1040 + private_community = fast_create(Community, :public_profile => false)
  1041 + a = fast_create(TinyMceArticle, :profile_id => private_community.id)
  1042 + assert_equal false, a.is_trackable?
1104 end 1043 end
1105 1044
1106 - should 'create the notification to the member when one member has the notification and the other no' do 1045 + should 'create the notification to organization and all organization members' do
1107 community = fast_create(Community) 1046 community = fast_create(Community)
1108 - p1 = Person.first || fast_create(Person)  
1109 - community.add_member(p1)  
1110 - assert p1.is_member_of?(community)  
1111 - Article.destroy_all  
1112 - ActionTracker::Record.destroy_all 1047 + member_1 = Person.first
  1048 + community.add_member(member_1)
  1049 +
1113 article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => community.id 1050 article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => community.id
1114 - assert article.published?  
1115 - assert_kind_of Community, article.profile  
1116 - assert_equal 1, ActionTracker::Record.count  
1117 - ta = ActionTracker::Record.first  
1118 - assert_equal 'Tracked Article 1', ta.get_name.last  
1119 - assert_equal article.url, ta.get_url.last  
1120 - assert p1, ta.user  
1121 - assert community, ta.target  
1122 - process_delayed_job_queue  
1123 - assert_equal 2, ActionTrackerNotification.count 1051 + first_activity = article.activity
  1052 + assert_equal [first_activity], ActionTracker::Record.find_all_by_verb('create_article')
1124 1053
1125 - p2 = fast_create(Person)  
1126 - community.add_member(p2)  
1127 process_delayed_job_queue 1054 process_delayed_job_queue
1128 - assert_equal 5, ActionTrackerNotification.count  
1129 -  
1130 - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id  
1131 - assert article.published?  
1132 - assert_kind_of Community, article.profile  
1133 - assert_equal 3, ActionTracker::Record.count  
1134 - ta = ActionTracker::Record.first  
1135 - assert_equal 'Tracked Article 2', ta.get_name.last  
1136 - assert_equal article.url, ta.get_url.last  
1137 - assert_equal p1, ta.user  
1138 - assert_equal community, ta.target 1055 + assert_equal 2, ActionTrackerNotification.find_all_by_action_tracker_id(first_activity.id).count
  1056 +
  1057 + member_2 = fast_create(Person)
  1058 + community.add_member(member_2)
  1059 +
  1060 + article2 = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id
  1061 + second_activity = article2.activity
  1062 + assert_equivalent [first_activity, second_activity], ActionTracker::Record.find_all_by_verb('create_article')
  1063 +
1139 process_delayed_job_queue 1064 process_delayed_job_queue
1140 - assert_equal 6, ActionTrackerNotification.count 1065 + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(second_activity.id).count
1141 end 1066 end
1142 1067
1143 - should 'not create more than one notification track action to friends when update more than one artile' do  
1144 - p1 = Person.first || fast_create(Person) 1068 + should 'create notifications to friends when creating an article' do
1145 friend = fast_create(Person) 1069 friend = fast_create(Person)
1146 - p1.add_friend(friend) 1070 + profile.add_friend(friend)
1147 Article.destroy_all 1071 Article.destroy_all
1148 ActionTracker::Record.destroy_all 1072 ActionTracker::Record.destroy_all
1149 ActionTrackerNotification.destroy_all 1073 ActionTrackerNotification.destroy_all
1150 - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => p1.id  
1151 - assert article.published?  
1152 - assert_kind_of Person, article.profile  
1153 - assert_equal 1, ActionTracker::Record.count  
1154 - ta = ActionTracker::Record.last  
1155 - assert_equal 'Tracked Article 1', ta.get_name.last  
1156 - assert_equal article.url, ta.get_url.last  
1157 - assert p1, ta.user  
1158 - assert p1, ta.target  
1159 - process_delayed_job_queue  
1160 - assert_equal 2, ActionTrackerNotification.count  
1161 -  
1162 - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => p1.id  
1163 - assert article.published?  
1164 - assert_kind_of Person, article.profile  
1165 - assert_equal 1, ActionTracker::Record.count  
1166 - ta = ActionTracker::Record.last  
1167 - assert_equal 'Tracked Article 2', ta.get_name.last  
1168 - assert_equal article.url, ta.get_url.last  
1169 - assert_equal p1, ta.user  
1170 - assert_equal p1, ta.target 1074 + UserStampSweeper.any_instance.expects(:current_user).returns(profile).at_least_once
  1075 + article = create(TinyMceArticle, :profile_id => profile.id)
  1076 +
1171 process_delayed_job_queue 1077 process_delayed_job_queue
1172 - assert_equal 2, ActionTrackerNotification.count 1078 + assert_equal friend, ActionTrackerNotification.last.profile
1173 end 1079 end
1174 1080
1175 should 'create the notification to the friend when one friend has the notification and the other no' do 1081 should 'create the notification to the friend when one friend has the notification and the other no' do
1176 - p1 = Person.first || fast_create(Person)  
1177 f1 = fast_create(Person) 1082 f1 = fast_create(Person)
1178 - p1.add_friend(f1)  
1179 - Article.destroy_all  
1180 - ActionTracker::Record.destroy_all  
1181 - ActionTrackerNotification.destroy_all  
1182 - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => p1.id  
1183 - assert article.published?  
1184 - assert_kind_of Person, article.profile  
1185 - assert_equal 1, ActionTracker::Record.count  
1186 - ta = ActionTracker::Record.first  
1187 - assert_equal 'Tracked Article 1', ta.get_name.last  
1188 - assert_equal article.url, ta.get_url.last  
1189 - assert p1, ta.user  
1190 - assert p1, ta.target 1083 + profile.add_friend(f1)
  1084 +
  1085 + UserStampSweeper.any_instance.expects(:current_user).returns(profile).at_least_once
  1086 + article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => profile.id
  1087 + assert_equal 1, ActionTracker::Record.find_all_by_verb('create_article').count
1191 process_delayed_job_queue 1088 process_delayed_job_queue
1192 - assert_equal 2, ActionTrackerNotification.count 1089 + assert_equal 2, ActionTrackerNotification.find_all_by_action_tracker_id(article.activity.id).count
1193 1090
1194 f2 = fast_create(Person) 1091 f2 = fast_create(Person)
1195 - p1.add_friend(f2)  
1196 - process_delayed_job_queue  
1197 - assert_equal 5, ActionTrackerNotification.count  
1198 - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => p1.id  
1199 - assert article.published?  
1200 - assert_kind_of Person, article.profile  
1201 - assert_equal 2, ActionTracker::Record.count  
1202 - ta = ActionTracker::Record.first  
1203 - assert_equal 'Tracked Article 2', ta.get_name.last  
1204 - assert_equal article.url, ta.get_url.last  
1205 - assert_equal p1, ta.user  
1206 - assert_equal p1, ta.target 1092 + profile.add_friend(f2)
  1093 + article2 = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => profile.id
  1094 + assert_equal 2, ActionTracker::Record.find_all_by_verb('create_article').count
1207 process_delayed_job_queue 1095 process_delayed_job_queue
1208 - assert_equal 6, ActionTrackerNotification.count 1096 + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(article2.activity.id).count
1209 end 1097 end
1210 1098
1211 should 'found articles with published date between a range' do 1099 should 'found articles with published date between a range' do
@@ -1560,7 +1448,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1560,7 +1448,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1560 should 'survive to a invalid src attribute while looking for images in body' do 1448 should 'survive to a invalid src attribute while looking for images in body' do
1561 article = Article.new(:body => "An article with invalid src in img tag <img src='path with spaces.png' />", :profile => @profile) 1449 article = Article.new(:body => "An article with invalid src in img tag <img src='path with spaces.png' />", :profile => @profile)
1562 assert_nothing_raised URI::InvalidURIError do 1450 assert_nothing_raised URI::InvalidURIError do
1563 - assert_equal ['http://localhost/path%20with%20spaces.png'], article.body_images_paths 1451 + assert_equal ["http://#{profile.environment.default_hostname}/path%20with%20spaces.png"], article.body_images_paths
1564 end 1452 end
1565 end 1453 end
1566 1454
@@ -1671,4 +1559,24 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1671,4 +1559,24 @@ class ArticleTest &lt; ActiveSupport::TestCase
1671 assert !a.allow_edit?(nil) 1559 assert !a.allow_edit?(nil)
1672 end 1560 end
1673 1561
  1562 + should 'get first image from lead' do
  1563 + a = fast_create(Article, :body => '<p>Foo</p><p><img src="bar.png" />Bar<img src="foo.png" /></p>',
  1564 + :abstract => '<p>Lead</p><p><img src="leadbar.png" />Bar<img src="leadfoo.png" /></p>')
  1565 + assert_equal 'leadbar.png', a.first_image
  1566 + end
  1567 +
  1568 + should 'get first image from body' do
  1569 + a = fast_create(Article, :body => '<p>Foo</p><p><img src="bar.png" />Bar<img src="foo.png" /></p>')
  1570 + assert_equal 'bar.png', a.first_image
  1571 + end
  1572 +
  1573 + should 'not get first image from anywhere' do
  1574 + a = fast_create(Article, :body => '<p>Foo</p><p>Bar</p>')
  1575 + assert_equal '', a.first_image
  1576 + end
  1577 +
  1578 + should 'store first image in tracked action' do
  1579 + a = TinyMceArticle.create! :name => 'Tracked Article', :body => '<p>Foo<img src="foo.png" />Bar</p>', :profile_id => profile.id
  1580 + assert_equal 'foo.png', ActionTracker::Record.last.get_first_image
  1581 + end
1674 end 1582 end
test/unit/category_finder_test.rb
@@ -188,17 +188,20 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase @@ -188,17 +188,20 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
188 end 188 end
189 189
190 should 'return most commented articles' do 190 should 'return most commented articles' do
  191 + person = create_user('testuser').person
191 Article.delete_all 192 Article.delete_all
192 193
193 - person = create_user('testuser').person  
194 - articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}", :category_ids => [@category.id]); a.save!; a } 194 + (1..4).map {|n| create(TextileArticle, :profile_id => person.id, :name => "art #{n}", :category_ids => [@category.id]) }
  195 +
  196 + first_article = person.articles.first
  197 + 2.times { Comment.create(:title => 'test', :body => 'asdsad', :author => person, :source => first_article) }
195 198
196 - 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! }  
197 - 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } 199 + last_article = person.articles.last
  200 + 4.times { Comment.create(:title => 'test', :body => 'asdsad', :author => person, :source => last_article) }
198 201
199 result = @finder.most_commented_articles(2) 202 result = @finder.most_commented_articles(2)
200 # should respect the order (more commented comes first) 203 # should respect the order (more commented comes first)
201 - assert_equal [articles[1], articles[0]], result 204 + assert_equal [last_article, first_article], result
202 assert_respond_to result, :total_entries 205 assert_respond_to result, :total_entries
203 end 206 end
204 207
test/unit/category_test.rb
@@ -260,13 +260,14 @@ class CategoryTest &lt; ActiveSupport::TestCase @@ -260,13 +260,14 @@ class CategoryTest &lt; ActiveSupport::TestCase
260 a2 = person.articles.build(:name => 'art2', :category_ids => [c.id]); a2.save! 260 a2 = person.articles.build(:name => 'art2', :category_ids => [c.id]); a2.save!
261 a3 = person.articles.build(:name => 'art3', :category_ids => [c.id]); a3.save! 261 a3 = person.articles.build(:name => 'art3', :category_ids => [c.id]); a3.save!
262 262
263 - a1.comments.build(:title => 'test', :body => 'asdsa', :author => person).save!  
264 - 5.times { a2.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! } 263 + Comment.create(:title => 'test', :body => 'asdsa', :author => person, :source => a1)
  264 + 5.times { Comment.create(:title => 'test', :body => 'asdsa', :author => person, :source => a2) }
265 265
266 - 10.times { a3.comments.build(:title => 'test', :body => 'kajsdsa', :author => person).save! } 266 + 10.times { Comment.create(:title => 'test', :body => 'kajsdsa', :author => person, :source => a3) }
267 267
268 assert_equal [a3, a2], c.most_commented_articles(2) 268 assert_equal [a3, a2], c.most_commented_articles(2)
269 end 269 end
  270 +
270 should 'have comments' do 271 should 'have comments' do
271 c = @env.categories.build(:name => 'my category'); c.save! 272 c = @env.categories.build(:name => 'my category'); c.save!
272 person = create_user('testuser').person 273 person = create_user('testuser').person
test/unit/comment_notifier_test.rb
@@ -12,26 +12,26 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase @@ -12,26 +12,26 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
12 @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true) 12 @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true)
13 end 13 end
14 14
15 - should 'deliver mail after make aarticle commment' do 15 + should 'deliver mail after make an article comment' do
16 assert_difference ActionMailer::Base.deliveries, :size do 16 assert_difference ActionMailer::Base.deliveries, :size do
17 - @article.comments << Comment.new(:author => @profile, :title => 'test comment', :body => 'you suck!') 17 + Comment.create(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article )
18 end 18 end
19 end 19 end
20 20
21 should 'deliver mail to owner of article' do 21 should 'deliver mail to owner of article' do
22 - @article.comments << Comment.new(:author => @profile, :title => 'test comment', :body => 'you suck!') 22 + Comment.create(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article )
23 sent = ActionMailer::Base.deliveries.first 23 sent = ActionMailer::Base.deliveries.first
24 assert_equal [@profile.email], sent.to 24 assert_equal [@profile.email], sent.to
25 end 25 end
26 26
27 should 'display author name in delivered mail' do 27 should 'display author name in delivered mail' do
28 - @article.comments << Comment.new(:author => @profile, :title => 'test comment', :body => 'you suck!') 28 + Comment.create(:author => @profile, :title => 'test comment', :body => 'you suck!', :source => @article)
29 sent = ActionMailer::Base.deliveries.first 29 sent = ActionMailer::Base.deliveries.first
30 assert_match /user_comment_test/, sent.body 30 assert_match /user_comment_test/, sent.body
31 end 31 end
32 32
33 should 'display unauthenticated author name and email in delivered mail' do 33 should 'display unauthenticated author name and email in delivered mail' do
34 - @article.comments << Comment.new(:name => 'flatline', :email => 'flatline@invalid.com', :title => 'test comment', :body => 'you suck!') 34 + Comment.create(:name => 'flatline', :email => 'flatline@invalid.com', :title => 'test comment', :body => 'you suck!', :source => @article )
35 sent = ActionMailer::Base.deliveries.first 35 sent = ActionMailer::Base.deliveries.first
36 assert_match /flatline/, sent.body 36 assert_match /flatline/, sent.body
37 assert_match /flatline@invalid.com/, sent.body 37 assert_match /flatline@invalid.com/, sent.body
@@ -45,13 +45,13 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase @@ -45,13 +45,13 @@ class CommentNotifierTest &lt; ActiveSupport::TestCase
45 end 45 end
46 46
47 should 'include comment title in the e-mail' do 47 should 'include comment title in the e-mail' do
48 - @article.comments << Comment.new(:author => @profile, :title => 'comment title', :body => 'comment title') 48 + Comment.create(:author => @profile, :title => 'comment title', :body => 'comment body', :source => @article)
49 sent = ActionMailer::Base.deliveries.first 49 sent = ActionMailer::Base.deliveries.first
50 assert_match /comment title/, sent.body 50 assert_match /comment title/, sent.body
51 end 51 end
52 52
53 should 'include comment text in the e-mail' do 53 should 'include comment text in the e-mail' do
54 - @article.comments << Comment.new(:author => @profile, :title => 'comment title', :body => 'comment body') 54 + Comment.create(:author => @profile, :title => 'comment title', :body => 'comment body', :source => @article)
55 sent = ActionMailer::Base.deliveries.first 55 sent = ActionMailer::Base.deliveries.first
56 assert_match /comment body/, sent.body 56 assert_match /comment body/, sent.body
57 end 57 end
test/unit/comment_test.rb
@@ -13,13 +13,13 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -13,13 +13,13 @@ class CommentTest &lt; ActiveSupport::TestCase
13 assert_mandatory(Comment.new, :body) 13 assert_mandatory(Comment.new, :body)
14 end 14 end
15 15
16 - should 'belong to an article' do 16 + should 'have a polymorphic relationship with source' do
17 c = Comment.new 17 c = Comment.new
18 - assert_raise ActiveRecord::AssociationTypeMismatch do  
19 - c.article = 1 18 + assert_nothing_raised do
  19 + c.source = Article.new
20 end 20 end
21 assert_nothing_raised do 21 assert_nothing_raised do
22 - c.article = Article.new 22 + c.source = ActionTracker::Record.new
23 end 23 end
24 end 24 end
25 25
@@ -65,12 +65,33 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -65,12 +65,33 @@ class CommentTest &lt; ActiveSupport::TestCase
65 65
66 should 'update counter cache in article' do 66 should 'update counter cache in article' do
67 owner = create_user('testuser').person 67 owner = create_user('testuser').person
68 - art = owner.articles.build(:name => 'ytest'); art.save!  
69 - 68 + art = create(TextileArticle, :profile_id => owner.id)
70 cc = art.comments_count 69 cc = art.comments_count
71 - art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save!  
72 - art.reload  
73 - assert_equal cc + 1, art.comments_count 70 +
  71 + comment = create(Comment, :source => art, :author_id => owner.id)
  72 + assert_equal cc + 1, Article.find(art.id).comments_count
  73 + end
  74 +
  75 + should 'update counter cache in article activity' do
  76 + owner = create_user('testuser').person
  77 + article = create(TextileArticle, :profile_id => owner.id)
  78 +
  79 + action = article.activity
  80 + cc = action.comments_count
  81 + comment = create(Comment, :source => action, :author_id => owner.id)
  82 + assert_equal cc + 1, ActionTracker::Record.find(action.id).comments_count
  83 + end
  84 +
  85 + should 'update counter cache in general activity when add a comment' do
  86 + person = fast_create(Person)
  87 + community = fast_create(Community)
  88 +
  89 + activity = ActionTracker::Record.create :user => person, :target => community, :verb => 'add_member_in_community'
  90 +
  91 + cc = activity.comments_count
  92 +
  93 + comment = create(Comment, :source => activity, :author_id => person.id)
  94 + assert_equal cc + 1, ActionTracker::Record.find(activity.id).comments_count
74 end 95 end
75 96
76 should 'provide author name for authenticated authors' do 97 should 'provide author name for authenticated authors' do
@@ -217,30 +238,10 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -217,30 +238,10 @@ class CommentTest &lt; ActiveSupport::TestCase
217 assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist." 238 assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist."
218 end 239 end
219 240
220 - should 'track action when comment is created' do  
221 - owner = create_user('testuser').person  
222 - article = owner.articles.create!(:name => 'test', :body => '...')  
223 - comment = article.comments.create!(:article => article, :name => 'foo', :title => 'bar', :body => 'my comment', :email => 'cracker@test.org')  
224 - ta = ActionTracker::Record.last  
225 - assert_equal 'bar', ta.get_title  
226 - assert_equal 'my comment', ta.get_body  
227 - assert_equal 'test', ta.get_article_title  
228 - assert_equal article.url, ta.get_article_url  
229 - assert_equal comment.url, ta.get_url  
230 - end  
231 -  
232 should 'have the action_tracker_target defined' do 241 should 'have the action_tracker_target defined' do
233 assert Comment.method_defined?(:action_tracker_target) 242 assert Comment.method_defined?(:action_tracker_target)
234 end 243 end
235 244
236 - should "have the action_tracker_target be the articles's profile" do  
237 - owner = create_user('testuser').person  
238 - article = owner.articles.create!(:name => 'test', :body => '...')  
239 - comment = article.comments.create!(:article => article, :name => 'foo', :title => 'bar', :body => 'my comment', :email => 'cracker@test.org')  
240 - ta = ActionTracker::Record.last  
241 - assert_equal owner, ta.target  
242 - end  
243 -  
244 should "get children of a comment" do 245 should "get children of a comment" do
245 c = fast_create(Comment) 246 c = fast_create(Comment)
246 c1 = fast_create(Comment, :reply_of_id => c.id) 247 c1 = fast_create(Comment, :reply_of_id => c.id)
@@ -307,11 +308,11 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -307,11 +308,11 @@ class CommentTest &lt; ActiveSupport::TestCase
307 308
308 should "return comments as a thread" do 309 should "return comments as a thread" do
309 a = fast_create(Article) 310 a = fast_create(Article)
310 - c0 = fast_create(Comment, :article_id => a.id)  
311 - c1 = fast_create(Comment, :reply_of_id => c0.id, :article_id => a.id)  
312 - c2 = fast_create(Comment, :reply_of_id => c1.id, :article_id => a.id)  
313 - c3 = fast_create(Comment, :reply_of_id => c0.id, :article_id => a.id)  
314 - c4 = fast_create(Comment, :article_id => a.id) 311 + c0 = fast_create(Comment, :source_id => a.id)
  312 + c1 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id)
  313 + c2 = fast_create(Comment, :reply_of_id => c1.id, :source_id => a.id)
  314 + c3 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id)
  315 + c4 = fast_create(Comment, :source_id => a.id)
315 result = a.comments.as_thread 316 result = a.comments.as_thread
316 assert_equal c0.id, result[0].id 317 assert_equal c0.id, result[0].id
317 assert_equal [c1.id, c3.id], result[0].replies.map(&:id) 318 assert_equal [c1.id, c3.id], result[0].replies.map(&:id)
@@ -338,4 +339,27 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -338,4 +339,27 @@ class CommentTest &lt; ActiveSupport::TestCase
338 assert c.rejected? 339 assert c.rejected?
339 end 340 end
340 341
  342 + should 'update article activity when add a comment' do
  343 + profile = create_user('testuser').person
  344 + article = create(TinyMceArticle, :profile => profile)
  345 + action = article.activity
  346 + time = action.updated_at
  347 +
  348 + Time.stubs(:now).returns(time + 1.day)
  349 +
  350 + comment = create(Comment, :source => article, :author => profile)
  351 + assert_equal time + 1.day, article.activity.updated_at
  352 + end
  353 +
  354 + should 'create a new activity when add a comment and the activity was removed' do
  355 + profile = create_user('testuser').person
  356 + article = create(TinyMceArticle, :profile => profile)
  357 + article.activity.destroy
  358 +
  359 + assert_nil article.activity
  360 +
  361 + comment = create(Comment, :source => article, :author => profile)
  362 + assert_not_nil article.activity
  363 + end
  364 +
341 end 365 end
test/unit/community_test.rb
@@ -274,22 +274,19 @@ class CommunityTest &lt; ActiveSupport::TestCase @@ -274,22 +274,19 @@ class CommunityTest &lt; ActiveSupport::TestCase
274 end 274 end
275 end 275 end
276 276
277 - should "be created an tracked action to the community when an community's article is commented" do 277 + should "update the action of article creation when an community's article is commented" do
278 ActionTrackerNotification.delete_all 278 ActionTrackerNotification.delete_all
279 p1 = Person.first 279 p1 = Person.first
280 community = fast_create(Community) 280 community = fast_create(Community)
281 p2 = fast_create(Person) 281 p2 = fast_create(Person)
282 p3 = fast_create(Person) 282 p3 = fast_create(Person)
283 community.add_member(p3) 283 community.add_member(p3)
284 - article = fast_create(Article, :profile_id => community.id)  
285 - ActionTracker::Record.destroy_all  
286 - assert_difference(ActionTrackerNotification, :count, 3) do  
287 - Comment.create!(:article_id => article.id, :title => 'some', :body => 'some', :author_id => p2.id)  
288 - process_delayed_job_queue  
289 - end  
290 - ActionTrackerNotification.all.map{|a|a.profile}.map do |profile|  
291 - assert [community,p1,p3].include?(profile)  
292 - end 284 + article = create(TextileArticle, :profile_id => community.id)
  285 + time = article.activity.updated_at
  286 + Time.stubs(:now).returns(time + 1.day)
  287 + Comment.create!(:source_id => article.id, :title => 'some', :body => 'some', :author_id => p2.id)
  288 + process_delayed_job_queue
  289 + assert_equal time, article.activity.updated_at
293 end 290 end
294 291
295 should "see get all received scraps" do 292 should "see get all received scraps" do
@@ -341,4 +338,35 @@ class CommunityTest &lt; ActiveSupport::TestCase @@ -341,4 +338,35 @@ class CommunityTest &lt; ActiveSupport::TestCase
341 assert_equal false, community.receives_scrap_notification? 338 assert_equal false, community.receives_scrap_notification?
342 end 339 end
343 340
  341 + should 'return scraps as activities' do
  342 + person = fast_create(Person)
  343 + community = fast_create(Community)
  344 +
  345 + scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => community, :content => 'A scrap'))
  346 + activity = ActionTracker::Record.last
  347 +
  348 + assert_equal [activity,scrap], community.activities.map { |a| a.klass.constantize.find(a.id) }
  349 + end
  350 +
  351 + should 'return tracked_actions of community as activities' do
  352 + person = fast_create(Person)
  353 + community = fast_create(Community)
  354 +
  355 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  356 + article = create(TinyMceArticle, :profile => community, :name => 'An article about free software')
  357 +
  358 + assert_equal [article.activity], community.activities.map { |a| a.klass.constantize.find(a.id) }
  359 + end
  360 +
  361 + should 'not return tracked_actions of other community as activities' do
  362 + person = fast_create(Person)
  363 + community = fast_create(Community)
  364 + community2 = fast_create(Community)
  365 +
  366 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  367 + article = create(TinyMceArticle, :profile => community2, :name => 'Another article about free software')
  368 +
  369 + assert_not_includes community.activities.map { |a| a.klass.constantize.find(a.id) }, article.activity
  370 + end
  371 +
344 end 372 end
test/unit/enterprise_test.rb
@@ -450,4 +450,37 @@ class EnterpriseTest &lt; ActiveSupport::TestCase @@ -450,4 +450,37 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
450 e = fast_create(Enterprise) 450 e = fast_create(Enterprise)
451 assert_respond_to e, :production_costs 451 assert_respond_to e, :production_costs
452 end 452 end
  453 +
  454 + should 'return scraps as activities' do
  455 + person = fast_create(Person)
  456 + enterprise = fast_create(Enterprise)
  457 +
  458 +
  459 + activity = ActionTracker::Record.last
  460 + scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => enterprise, :content => 'A scrap'))
  461 +
  462 + assert_equal [scrap], enterprise.activities.map { |a| a.klass.constantize.find(a.id) }
  463 + end
  464 +
  465 + should 'return tracked_actions of community as activities' do
  466 + person = fast_create(Person)
  467 + enterprise = fast_create(Enterprise)
  468 +
  469 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  470 + article = create(TinyMceArticle, :profile => enterprise, :name => 'An article about free software')
  471 +
  472 + assert_equal [article.activity], enterprise.activities.map { |a| a.klass.constantize.find(a.id) }
  473 + end
  474 +
  475 + should 'not return tracked_actions of other community as activities' do
  476 + person = fast_create(Person)
  477 + enterprise = fast_create(Enterprise)
  478 + enterprise2 = fast_create(Enterprise)
  479 +
  480 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  481 + article = create(TinyMceArticle, :profile => enterprise2, :name => 'Another article about free software')
  482 +
  483 + assert_not_includes enterprise.activities.map { |a| a.klass.constantize.find(a.id) }, article.activity
  484 + end
  485 +
453 end 486 end
test/unit/event_test.rb
@@ -274,4 +274,7 @@ class EventTest &lt; ActiveSupport::TestCase @@ -274,4 +274,7 @@ class EventTest &lt; ActiveSupport::TestCase
274 assert Event.new.tiny_mce? 274 assert Event.new.tiny_mce?
275 end 275 end
276 276
  277 + should 'be notifiable' do
  278 + assert Event.new.notifiable?
  279 + end
277 end 280 end
test/unit/forum_helper_test.rb
@@ -63,7 +63,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase @@ -63,7 +63,7 @@ class ForumHelperTest &lt; ActiveSupport::TestCase
63 some_post.comments << Comment.new(:name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test') 63 some_post.comments << Comment.new(:name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test')
64 c = Comment.last 64 c = Comment.last
65 out = last_topic_update(some_post) 65 out = last_topic_update(some_post)
66 - assert_match "#{c.created_at.to_s} ago by John", out 66 + assert_match "#{c.created_at.to_s} by John", out
67 assert_match 'John', out 67 assert_match 'John', out
68 end 68 end
69 69
test/unit/forum_test.rb
@@ -28,21 +28,21 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -28,21 +28,21 @@ class ForumTest &lt; ActiveSupport::TestCase
28 28
29 should 'create rss feed automatically' do 29 should 'create rss feed automatically' do
30 p = create_user('testuser').person 30 p = create_user('testuser').person
31 - b = create(Forum, :profile_id => p.id, :name => 'forum_feed_test') 31 + b = create(Forum, :profile_id => p.id, :name => 'forum_feed_test', :body => 'Forum')
32 assert_kind_of RssFeed, b.feed 32 assert_kind_of RssFeed, b.feed
33 end 33 end
34 34
35 should 'save feed options' do 35 should 'save feed options' do
36 p = create_user('testuser').person 36 p = create_user('testuser').person
37 - p.articles << Forum.new(:profile => p, :name => 'forum_feed_test') 37 + p.articles << forum = Forum.new(:profile => p, :name => 'forum_feed_test', :body => 'Forum test')
38 p.forum.feed = { :limit => 7 } 38 p.forum.feed = { :limit => 7 }
39 - assert_equal 7, p.forum.feed.limit 39 + assert_equal 7, Forum.find(forum.id).feed.limit
40 end 40 end
41 41
42 should 'save feed options after create forum' do 42 should 'save feed options after create forum' do
43 p = create_user('testuser').person 43 p = create_user('testuser').person
44 - p.articles << Forum.new(:profile => p, :name => 'forum_feed_test', :feed => { :limit => 7 })  
45 - assert_equal 7, p.forum.feed.limit 44 + p.articles << forum = Forum.new(:profile => p, :name => 'forum_feed_test', :body => 'Forum test', :feed => { :limit => 7 })
  45 + assert_equal 7, Forum.find(forum.id).feed.limit
46 end 46 end
47 47
48 should 'list 5 posts per page by default' do 48 should 'list 5 posts per page by default' do
@@ -52,16 +52,15 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -52,16 +52,15 @@ class ForumTest &lt; ActiveSupport::TestCase
52 52
53 should 'update posts per page setting' do 53 should 'update posts per page setting' do
54 p = create_user('testuser').person 54 p = create_user('testuser').person
55 - p.articles << Forum.new(:profile => p, :name => 'Forum test')  
56 - forum = p.forum 55 + p.articles << forum = Forum.new(:profile => p, :name => 'Forum test', :body => 'Forum test')
57 forum.posts_per_page = 7 56 forum.posts_per_page = 7
58 assert forum.save! 57 assert forum.save!
59 - assert_equal 7, p.forum.posts_per_page 58 + assert_equal 7, Forum.find(forum.id).posts_per_page
60 end 59 end
61 60
62 should 'has posts' do 61 should 'has posts' do
63 p = create_user('testuser').person 62 p = create_user('testuser').person
64 - forum = fast_create(Forum, :profile_id => p.id, :name => 'Forum test') 63 + p.articles << forum = Forum.new(:profile => p, :name => 'Forum test', :body => 'Forum test')
65 post = fast_create(TextileArticle, :name => 'First post', :profile_id => p.id, :parent_id => forum.id) 64 post = fast_create(TextileArticle, :name => 'First post', :profile_id => p.id, :parent_id => forum.id)
66 forum.children << post 65 forum.children << post
67 assert_includes forum.posts, post 66 assert_includes forum.posts, post
@@ -69,7 +68,7 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -69,7 +68,7 @@ class ForumTest &lt; ActiveSupport::TestCase
69 68
70 should 'not includes rss feed in posts' do 69 should 'not includes rss feed in posts' do
71 p = create_user('testuser').person 70 p = create_user('testuser').person
72 - forum = create(Forum, :profile_id => p.id, :name => 'Forum test') 71 + forum = create(Forum, :profile_id => p.id, :name => 'Forum test', :body => 'Forum')
73 assert_includes forum.children, forum.feed 72 assert_includes forum.children, forum.feed
74 assert_not_includes forum.posts, forum.feed 73 assert_not_includes forum.posts, forum.feed
75 end 74 end
@@ -89,13 +88,13 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -89,13 +88,13 @@ class ForumTest &lt; ActiveSupport::TestCase
89 p = create_user('testuser').person 88 p = create_user('testuser').person
90 fast_create(Forum, :name => 'Forum test', :profile_id => p.id) 89 fast_create(Forum, :name => 'Forum test', :profile_id => p.id)
91 assert_nothing_raised ActiveRecord::RecordInvalid do 90 assert_nothing_raised ActiveRecord::RecordInvalid do
92 - Forum.create!(:name => 'Another Forum', :profile => p) 91 + Forum.create!(:name => 'Another Forum', :profile => p, :body => 'Forum test')
93 end 92 end
94 end 93 end
95 94
96 should 'not update slug from name for existing forum' do 95 should 'not update slug from name for existing forum' do
97 p = create_user('testuser').person 96 p = create_user('testuser').person
98 - forum = Forum.create!(:name => 'Forum test', :profile => p) 97 + forum = Forum.create(:name => 'Forum test', :profile_id => p.id, :body => 'Forum')
99 assert_equal 'forum-test', forum.slug 98 assert_equal 'forum-test', forum.slug
100 forum.name = 'Changed name' 99 forum.name = 'Changed name'
101 assert_not_equal 'changed-name', forum.slug 100 assert_not_equal 'changed-name', forum.slug
@@ -110,4 +109,28 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -110,4 +109,28 @@ class ForumTest &lt; ActiveSupport::TestCase
110 assert !folder.accept_uploads? 109 assert !folder.accept_uploads?
111 end 110 end
112 111
  112 + should 'be notifiable' do
  113 + assert Forum.new.notifiable?
  114 + end
  115 +
  116 + should 'get first paragraph' do
  117 + f = fast_create(Forum, :body => '<p>First</p><p>Second</p>')
  118 + assert_equal '<p>First</p>', f.first_paragraph
  119 + end
  120 +
  121 + should 'not get first paragraph' do
  122 + f = fast_create(Forum, :body => 'Nothing to do here')
  123 + assert_equal '', f.first_paragraph
  124 + end
  125 +
  126 + should 'provide first_paragraph even if body was not given' do
  127 + f = fast_create(Forum)
  128 + assert_equal '', f.first_paragraph
  129 + end
  130 +
  131 + should 'provide first_paragraph even if body is nil' do
  132 + f = fast_create(Forum, :body => nil)
  133 + assert_equal '', f.first_paragraph
  134 + end
  135 +
113 end 136 end
test/unit/notify_activity_to_profiles_job_test.rb
@@ -24,28 +24,6 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -24,28 +24,6 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
24 end 24 end
25 end 25 end
26 26
27 - should 'notify just the community in tracker with remove_member_in_community verb' do  
28 - person = fast_create(Person)  
29 - community = fast_create(Community)  
30 - action_tracker = fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person.id, :target_type => 'Profile', :target_id => community.id, :verb => 'remove_member_in_community')  
31 - assert NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)  
32 - p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)  
33 - fast_create(Friendship, :person_id => person.id, :friend_id => p1.id)  
34 - fast_create(Friendship, :person_id => person.id, :friend_id => p2.id)  
35 - fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id)  
36 - fast_create(RoleAssignment, :accessor_id => m2.id, :role_id => 3, :resource_id => community.id)  
37 - ActionTrackerNotification.delete_all  
38 - job = NotifyActivityToProfilesJob.new(action_tracker.id)  
39 - job.perform  
40 - process_delayed_job_queue  
41 -  
42 - assert_equal 1, ActionTrackerNotification.count  
43 - [community].each do |profile|  
44 - notification = ActionTrackerNotification.find_by_profile_id profile.id  
45 - assert_equal action_tracker, notification.action_tracker  
46 - end  
47 - end  
48 -  
49 should 'notify just the users and his friends tracking user actions' do 27 should 'notify just the users and his friends tracking user actions' do
50 person = fast_create(Person) 28 person = fast_create(Person)
51 community = fast_create(Community) 29 community = fast_create(Community)
@@ -132,36 +110,14 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase @@ -132,36 +110,14 @@ class NotifyActivityToProfilesJobTest &lt; ActiveSupport::TestCase
132 end 110 end
133 end 111 end
134 112
135 - should 'not notify the community tracking leave_community verb' do  
136 - person = fast_create(Person)  
137 - community = fast_create(Community)  
138 - action_tracker = fast_create(ActionTracker::Record, :user_type => 'Profile', :user_id => person.id, :target_type => 'Profile', :target_id => community.id, :verb => 'leave_community')  
139 - assert !NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY.include?(action_tracker.verb)  
140 - p1, p2, m1, m2 = fast_create(Person), fast_create(Person), fast_create(Person), fast_create(Person)  
141 - fast_create(Friendship, :person_id => person.id, :friend_id => p1.id)  
142 - fast_create(Friendship, :person_id => person.id, :friend_id => p2.id)  
143 - fast_create(RoleAssignment, :accessor_id => m1.id, :role_id => 3, :resource_id => community.id)  
144 - fast_create(RoleAssignment, :accessor_id => m2.id, :role_id => 3, :resource_id => community.id)  
145 - ActionTrackerNotification.delete_all  
146 - job = NotifyActivityToProfilesJob.new(action_tracker.id)  
147 - job.perform  
148 - process_delayed_job_queue  
149 -  
150 - assert_equal 5, ActionTrackerNotification.count  
151 - [person, p1, p2, m1, m2].each do |profile|  
152 - notification = ActionTrackerNotification.find_by_profile_id profile.id  
153 - assert_equal action_tracker, notification.action_tracker  
154 - end  
155 - end  
156 -  
157 should "the NOTIFY_ONLY_COMMUNITY constant has all the verbs tested" do 113 should "the NOTIFY_ONLY_COMMUNITY constant has all the verbs tested" do
158 - notify_community_verbs = ['add_member_in_community', 'remove_member_in_community'] 114 + notify_community_verbs = ['add_member_in_community']
159 assert_equal [], notify_community_verbs - NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY 115 assert_equal [], notify_community_verbs - NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY
160 assert_equal [], NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY - notify_community_verbs 116 assert_equal [], NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY - notify_community_verbs
161 end 117 end
162 118
163 should "the NOT_NOTIFY_COMMUNITY constant has all the verbs tested" do 119 should "the NOT_NOTIFY_COMMUNITY constant has all the verbs tested" do
164 - not_notify_community_verbs = ['join_community', 'leave_community'] 120 + not_notify_community_verbs = ['join_community']
165 assert_equal [], not_notify_community_verbs - NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY 121 assert_equal [], not_notify_community_verbs - NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY
166 assert_equal [], NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY - not_notify_community_verbs 122 assert_equal [], NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY - not_notify_community_verbs
167 end 123 end
test/unit/person_test.rb
@@ -1013,65 +1013,14 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1013,65 +1013,14 @@ class PersonTest &lt; ActiveSupport::TestCase
1013 assert has_add_member_notification 1013 assert has_add_member_notification
1014 end 1014 end
1015 1015
1016 - should 'track only one action when a person leaves a community' do 1016 + should 'not track when a person leaves a community' do
1017 p = create_user('test_user').person 1017 p = create_user('test_user').person
1018 c = fast_create(Community, :name => "Foo") 1018 c = fast_create(Community, :name => "Foo")
1019 c.add_member(p) 1019 c.add_member(p)
1020 c.add_moderator(p) 1020 c.add_moderator(p)
1021 ActionTracker::Record.delete_all 1021 ActionTracker::Record.delete_all
1022 c.remove_member(p) 1022 c.remove_member(p)
1023 - assert_equal ["Foo"], ActionTracker::Record.last(:conditions => {:verb => 'leave_community'}).get_resource_name  
1024 - end  
1025 -  
1026 - should 'the tracker target be Community when a person leaves a community' do  
1027 - ActionTracker::Record.delete_all  
1028 - p = create_user('test_user').person  
1029 - c = fast_create(Community, :name => "Foo")  
1030 - c.add_member(p)  
1031 - c.add_moderator(p)  
1032 - ActionTracker::Record.delete_all  
1033 - c.remove_member(p)  
1034 - assert_kind_of Community, ActionTracker::Record.last(:conditions => {:verb => 'leave_community'}).target  
1035 - end  
1036 -  
1037 - should 'the community be notified specifically when a person leaves a community' do  
1038 - ActionTracker::Record.delete_all  
1039 - p = create_user('test_user').person  
1040 - c = fast_create(Community, :name => "Foo")  
1041 - c.add_member(p)  
1042 - c.add_moderator(p)  
1043 - ActionTracker::Record.delete_all  
1044 - c.remove_member(p)  
1045 - assert_not_nil ActionTracker::Record.last(:conditions => {:verb => 'remove_member_in_community'})  
1046 - end  
1047 -  
1048 - should 'the community specific notification created when a member leaves community could not be propagated to members' do  
1049 - ActionTracker::Record.delete_all  
1050 - p1 = Person.first  
1051 - p2 = create_user('test_user').person  
1052 - p3 = create_user('test_user').person  
1053 - c = fast_create(Community, :name => "Foo")  
1054 - process_delayed_job_queue  
1055 - Delayed::Job.delete_all  
1056 - c.add_member(p1)  
1057 - c.add_member(p3)  
1058 - c.add_moderator(p1)  
1059 - c.add_moderator(p3)  
1060 - ActionTracker::Record.delete_all  
1061 - c.remove_member(p1)  
1062 - process_delayed_job_queue  
1063 - c.remove_member(p3)  
1064 - process_delayed_job_queue  
1065 - assert_equal 4, ActionTracker::Record.count  
1066 - assert_equal 5, ActionTrackerNotification.count  
1067 - has_remove_member_notification = false  
1068 - ActionTrackerNotification.all.map do |notification|  
1069 - if notification.action_tracker.verb == 'remove_member_in_community'  
1070 - has_remove_member_notification = true  
1071 - assert_equal c, notification.profile  
1072 - end  
1073 - end  
1074 - assert has_remove_member_notification 1023 + assert_equal [], ActionTracker::Record.all
1075 end 1024 end
1076 1025
1077 should 'get all friends online' do 1026 should 'get all friends online' do
@@ -1243,4 +1192,32 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1243,4 +1192,32 @@ class PersonTest &lt; ActiveSupport::TestCase
1243 assert !person.visible 1192 assert !person.visible
1244 assert_not_equal password, person.user.password 1193 assert_not_equal password, person.user.password
1245 end 1194 end
  1195 +
  1196 + should 'return tracked_actions and scraps as activities' do
  1197 + person = fast_create(Person)
  1198 + another_person = fast_create(Person)
  1199 +
  1200 + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => person, :content => 'A scrap'))
  1201 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  1202 + article = TinyMceArticle.create!(:profile => person, :name => 'An article about free software')
  1203 +
  1204 + assert_equivalent [scrap,article.activity], person.activities.map { |a| a.klass.constantize.find(a.id) }
  1205 + end
  1206 +
  1207 + should 'not return tracked_actions and scraps from others as activities' do
  1208 + person = fast_create(Person)
  1209 + another_person = fast_create(Person)
  1210 +
  1211 + person_scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => person, :content => 'A scrap from person'))
  1212 + another_person_scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => another_person, :content => 'A scrap from another person'))
  1213 +
  1214 + TinyMceArticle.create!(:profile => another_person, :name => 'An article about free software from another person')
  1215 + another_person_activity = ActionTracker::Record.last
  1216 +
  1217 + UserStampSweeper.any_instance.stubs(:current_user).returns(person)
  1218 + TinyMceArticle.create!(:profile => person, :name => 'An article about free software')
  1219 + person_activity = ActionTracker::Record.last
  1220 +
  1221 + assert_equal [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) }
  1222 + end
1246 end 1223 end
test/unit/profile_test.rb
@@ -1623,7 +1623,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1623,7 +1623,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1623 1623
1624 should 'have forum' do 1624 should 'have forum' do
1625 p = fast_create(Profile) 1625 p = fast_create(Profile)
1626 - p.articles << Forum.new(:profile => p, :name => 'forum_feed_test') 1626 + p.articles << Forum.new(:profile => p, :name => 'forum_feed_test', :body => 'Forum test')
1627 assert p.has_forum? 1627 assert p.has_forum?
1628 end 1628 end
1629 1629
@@ -1639,9 +1639,9 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1639,9 +1639,9 @@ class ProfileTest &lt; ActiveSupport::TestCase
1639 1639
1640 should 'get first forum when has multiple forums' do 1640 should 'get first forum when has multiple forums' do
1641 p = fast_create(Profile) 1641 p = fast_create(Profile)
1642 - p.forums << Forum.new(:profile => p, :name => 'Forum one')  
1643 - p.forums << Forum.new(:profile => p, :name => 'Forum two')  
1644 - p.forums << Forum.new(:profile => p, :name => 'Forum three') 1642 + p.forums << Forum.new(:profile => p, :name => 'Forum one', :body => 'Forum test')
  1643 + p.forums << Forum.new(:profile => p, :name => 'Forum two', :body => 'Forum test')
  1644 + p.forums << Forum.new(:profile => p, :name => 'Forum three', :body => 'Forum test')
1645 assert_equal 'Forum one', p.forum.name 1645 assert_equal 'Forum one', p.forum.name
1646 assert_equal 3, p.forums.count 1646 assert_equal 3, p.forums.count
1647 end 1647 end
@@ -1704,6 +1704,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1704,6 +1704,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1704 assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage) 1704 assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage)
1705 end 1705 end
1706 1706
  1707 +
1707 should 'find profiles with image' do 1708 should 'find profiles with image' do
1708 env = fast_create(Environment) 1709 env = fast_create(Environment)
1709 2.times do |n| 1710 2.times do |n|
@@ -1764,6 +1765,11 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1764,6 +1765,11 @@ class ProfileTest &lt; ActiveSupport::TestCase
1764 end 1765 end
1765 end 1766 end
1766 1767
  1768 + should 'return empty array as activities' do
  1769 + profile = Profile.new
  1770 + assert_equal [], profile.activities
  1771 + end
  1772 +
1767 private 1773 private
1768 1774
1769 def assert_invalid_identifier(id) 1775 def assert_invalid_identifier(id)
test/unit/textile_article_test.rb
@@ -38,80 +38,72 @@ class TextileArticleTest &lt; ActiveSupport::TestCase @@ -38,80 +38,72 @@ class TextileArticleTest &lt; ActiveSupport::TestCase
38 assert_equal 1, ActionTracker::Record.count 38 assert_equal 1, ActionTracker::Record.count
39 end 39 end
40 40
41 - should 'notify with different trackers activity create with different targets' do 41 + should 'not group trackers activity of article\'s creation' do
42 ActionTracker::Record.delete_all 42 ActionTracker::Record.delete_all
43 profile = fast_create(Profile) 43 profile = fast_create(Profile)
44 TextileArticle.create! :name => 'bar', :profile_id => profile.id, :published => true 44 TextileArticle.create! :name => 'bar', :profile_id => profile.id, :published => true
45 TextileArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true 45 TextileArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true
46 - assert_equal 1, ActionTracker::Record.count  
47 TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true 46 TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
48 - assert_equal 2, ActionTracker::Record.count 47 + assert_equal 3, ActionTracker::Record.count
49 end 48 end
50 49
51 - should 'notify activity on update' do 50 + should 'not update activity on update of an article' do
52 ActionTracker::Record.delete_all 51 ActionTracker::Record.delete_all
53 - a = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true  
54 - assert_equal 1, ActionTracker::Record.count  
55 - a.name = 'foo'  
56 - a.save!  
57 - assert_equal 2, ActionTracker::Record.count 52 + profile = fast_create(Profile)
  53 + article = create(TextileArticle, :profile_id => profile.id)
  54 + time = article.activity.updated_at
  55 + Time.stubs(:now).returns(time + 1.day)
  56 + assert_no_difference ActionTracker::Record, :count do
  57 + article.name = 'foo'
  58 + article.save!
  59 + end
  60 + assert_equal time, article.activity.updated_at
58 end 61 end
59 62
60 - should 'notify with different trackers activity update with different targets' do 63 + should 'not create trackers activity when updating articles' do
61 ActionTracker::Record.delete_all 64 ActionTracker::Record.delete_all
62 a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true 65 a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
63 a2 = TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true 66 a2 = TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
64 - assert_equal 2, ActionTracker::Record.count  
65 - a1.name = 'foo'  
66 - a1.save!  
67 - assert_equal 3, ActionTracker::Record.count  
68 - a2.name = 'another foo'  
69 - a2.save!  
70 - assert_equal 4, ActionTracker::Record.count 67 + assert_no_difference ActionTracker::Record, :count do
  68 + a1.name = 'foo';a1.save!
  69 + a2.name = 'another foo';a2.save!
  70 + end
71 end 71 end
72 72
73 - should 'notify activity on destroy' do 73 + should 'not notify activity on destroy' do
74 ActionTracker::Record.delete_all 74 ActionTracker::Record.delete_all
75 a = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true 75 a = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
76 - assert_equal 1, ActionTracker::Record.count  
77 - a.destroy  
78 - assert_equal 2, ActionTracker::Record.count 76 + assert_no_difference ActionTracker::Record, :count do
  77 + a.destroy
  78 + end
79 end 79 end
80 80
81 - should 'notify different activities when destroy articles with diferrents targets' do 81 + should 'not notify when an article is destroyed' do
82 ActionTracker::Record.delete_all 82 ActionTracker::Record.delete_all
83 a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true 83 a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
84 a2 = TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true 84 a2 = TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
85 assert_equal 2, ActionTracker::Record.count 85 assert_equal 2, ActionTracker::Record.count
86 - a1.destroy  
87 - assert_equal 3, ActionTracker::Record.count  
88 - a2.destroy  
89 - assert_equal 4, ActionTracker::Record.count 86 + assert_no_difference ActionTracker::Record, :count do
  87 + a1.destroy
  88 + a2.destroy
  89 + end
90 end 90 end
91 91
92 - should "the tracker action target be defined as Community by custom_target method on articles'creation in communities" do 92 + should "the tracker action target be defined as the article on articles'creation in communities" do
93 ActionTracker::Record.delete_all 93 ActionTracker::Record.delete_all
94 community = fast_create(Community) 94 community = fast_create(Community)
95 p1 = Person.first 95 p1 = Person.first
96 community.add_member(p1) 96 community.add_member(p1)
97 assert p1.is_member_of?(community) 97 assert p1.is_member_of?(community)
98 article = TextileArticle.create! :name => 'test', :profile_id => community.id 98 article = TextileArticle.create! :name => 'test', :profile_id => community.id
99 - assert_equal true, article.published?  
100 - assert_equal true, article.notifiable?  
101 - assert_equal false, article.image?  
102 - assert_equal Community, article.profile.class  
103 - assert_equal Community, ActionTracker::Record.last.target.class 99 + assert_equal article, ActionTracker::Record.last.target
104 end 100 end
105 101
106 - should "the tracker action target be defined as person by custom_target method on articles'creation in profile" do 102 + should "the tracker action target be defined as the article on articles'creation in profile" do
107 ActionTracker::Record.delete_all 103 ActionTracker::Record.delete_all
108 person = Person.first 104 person = Person.first
109 article = TextileArticle.create! :name => 'test', :profile_id => person.id 105 article = TextileArticle.create! :name => 'test', :profile_id => person.id
110 - assert_equal true, article.published?  
111 - assert_equal true, article.notifiable?  
112 - assert_equal false, article.image?  
113 - assert_equal Person, article.profile.class  
114 - assert_equal person, ActionTracker::Record.last.target 106 + assert_equal article, ActionTracker::Record.last.target
115 end 107 end
116 108
117 should 'not notify activity if the article is not advertise' do 109 should 'not notify activity if the article is not advertise' do
test/unit/tiny_mce_article_test.rb
@@ -134,80 +134,64 @@ class TinyMceArticleTest &lt; ActiveSupport::TestCase @@ -134,80 +134,64 @@ class TinyMceArticleTest &lt; ActiveSupport::TestCase
134 assert_equal 1, ActionTracker::Record.count 134 assert_equal 1, ActionTracker::Record.count
135 end 135 end
136 136
137 - should 'notify with different trackers activity create with different targets' do 137 + should 'not group trackers activity of article\'s creation' do
138 ActionTracker::Record.delete_all 138 ActionTracker::Record.delete_all
139 profile = fast_create(Profile) 139 profile = fast_create(Profile)
140 TinyMceArticle.create! :name => 'bar', :profile_id => profile.id, :published => true 140 TinyMceArticle.create! :name => 'bar', :profile_id => profile.id, :published => true
141 TinyMceArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true 141 TinyMceArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true
142 - assert_equal 1, ActionTracker::Record.count  
143 - TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true  
144 assert_equal 2, ActionTracker::Record.count 142 assert_equal 2, ActionTracker::Record.count
  143 + TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
  144 + assert_equal 3, ActionTracker::Record.count
145 end 145 end
146 146
147 - should 'notify activity on update' do 147 + should 'not update activity on update of an article' do
148 ActionTracker::Record.delete_all 148 ActionTracker::Record.delete_all
149 - a = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true  
150 - assert_equal 1, ActionTracker::Record.count  
151 - a.name = 'foo'  
152 - a.save!  
153 - assert_equal 2, ActionTracker::Record.count 149 + profile = fast_create(Profile)
  150 + article = create(TinyMceArticle, :profile_id => profile.id)
  151 + time = article.activity.updated_at
  152 + Time.stubs(:now).returns(time + 1.day)
  153 + assert_no_difference ActionTracker::Record, :count do
  154 + article.name = 'foo'
  155 + article.save!
  156 + end
  157 + assert_equal time, article.activity.updated_at
154 end 158 end
155 159
156 - should 'notify with different trackers activity update with different targets' do 160 + should 'not create trackers activity when updating articles' do
157 ActionTracker::Record.delete_all 161 ActionTracker::Record.delete_all
158 a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true 162 a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
159 a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true 163 a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
160 - assert_equal 2, ActionTracker::Record.count  
161 - a1.name = 'foo'  
162 - a1.save!  
163 - assert_equal 3, ActionTracker::Record.count  
164 - a2.name = 'another foo'  
165 - a2.save!  
166 - assert_equal 4, ActionTracker::Record.count 164 + assert_no_difference ActionTracker::Record, :count do
  165 + a1.name = 'foo';a1.save!
  166 + a2.name = 'another foo';a2.save!
  167 + end
167 end 168 end
168 169
169 - should 'notify activity on destroy' do  
170 - ActionTracker::Record.delete_all  
171 - a = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true  
172 - assert_equal 1, ActionTracker::Record.count  
173 - a.destroy  
174 - assert_equal 2, ActionTracker::Record.count  
175 - end  
176 -  
177 - should 'notify different activities when destroy articles with diferrents targets' do 170 + should 'not notify when an article is destroyed' do
178 ActionTracker::Record.delete_all 171 ActionTracker::Record.delete_all
179 a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true 172 a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true
180 a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true 173 a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true
181 - assert_equal 2, ActionTracker::Record.count  
182 - a1.destroy  
183 - assert_equal 3, ActionTracker::Record.count  
184 - a2.destroy  
185 - assert_equal 4, ActionTracker::Record.count 174 + assert_no_difference ActionTracker::Record, :count do
  175 + a1.destroy
  176 + a2.destroy
  177 +end
186 end 178 end
187 179
188 - should "the tracker action target be defined as Community by custom_target method on articles'creation in communities" do 180 + should "the tracker action target be defined as the article on articles'creation in communities" do
189 ActionTracker::Record.delete_all 181 ActionTracker::Record.delete_all
190 community = fast_create(Community) 182 community = fast_create(Community)
191 p1 = Person.first 183 p1 = Person.first
192 community.add_member(p1) 184 community.add_member(p1)
193 assert p1.is_member_of?(community) 185 assert p1.is_member_of?(community)
194 article = TinyMceArticle.create! :name => 'test', :profile_id => community.id 186 article = TinyMceArticle.create! :name => 'test', :profile_id => community.id
195 - assert_equal true, article.published?  
196 - assert_equal true, article.notifiable?  
197 - assert_equal false, article.image?  
198 - assert_equal Community, article.profile.class  
199 - assert_equal Community, ActionTracker::Record.last.target.class 187 + assert_equal article, ActionTracker::Record.last.target
200 end 188 end
201 189
202 - should "the tracker action target be defined as person by custom_target method on articles'creation in profile" do 190 + should "the tracker action target be defined as the article on articles'creation in profile" do
203 ActionTracker::Record.delete_all 191 ActionTracker::Record.delete_all
204 person = Person.first 192 person = Person.first
205 article = TinyMceArticle.create! :name => 'test', :profile_id => person.id 193 article = TinyMceArticle.create! :name => 'test', :profile_id => person.id
206 - assert_equal true, article.published?  
207 - assert_equal true, article.notifiable?  
208 - assert_equal false, article.image?  
209 - assert_equal Person, article.profile.class  
210 - assert_equal person, ActionTracker::Record.last.target 194 + assert_equal article, ActionTracker::Record.last.target
211 end 195 end
212 196
213 should 'not notify activity if the article is not advertise' do 197 should 'not notify activity if the article is not advertise' do
test/unit/uploaded_file_test.rb
@@ -231,10 +231,10 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -231,10 +231,10 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
231 should 'return a thumbnail for images' do 231 should 'return a thumbnail for images' do
232 f = UploadedFile.new 232 f = UploadedFile.new
233 f.expects(:image?).returns(true) 233 f.expects(:image?).returns(true)
234 - f.expects(:full_filename).with(:thumb).returns(File.join(RAILS_ROOT, 'public', 'images', '0000', '0005', 'x.png')) 234 + f.expects(:full_filename).with(:display).returns(File.join(RAILS_ROOT, 'public', 'images', '0000', '0005', 'x.png'))
235 assert_equal '/images/0000/0005/x.png', f.thumbnail_path 235 assert_equal '/images/0000/0005/x.png', f.thumbnail_path
236 f = UploadedFile.new 236 f = UploadedFile.new
237 - f.stubs(:full_filename).with(:thumb).returns(File.join(RAILS_ROOT, 'public', 'images', '0000', '0005', 'x.png')) 237 + f.stubs(:full_filename).with(:display).returns(File.join(RAILS_ROOT, 'public', 'images', '0000', '0005', 'x.png'))
238 f.expects(:image?).returns(false) 238 f.expects(:image?).returns(false)
239 assert_nil f.thumbnail_path 239 assert_nil f.thumbnail_path
240 end 240 end
@@ -330,4 +330,11 @@ class UploadedFileTest &lt; ActiveSupport::TestCase @@ -330,4 +330,11 @@ class UploadedFileTest &lt; ActiveSupport::TestCase
330 assert_equal 'hello_world.php.txt', file.filename 330 assert_equal 'hello_world.php.txt', file.filename
331 end 331 end
332 332
  333 + should 'use itself as target for action tracker' do
  334 + p = fast_create(Gallery, :profile_id => @profile.id)
  335 + f = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png'), :parent => p, :profile => @profile)
  336 + ta = f.activity
  337 + assert_equal f, ta.target
  338 + end
  339 +
333 end 340 end
vendor/plugins/access_control/lib/role_assignment.rb
@@ -7,12 +7,8 @@ class RoleAssignment &lt; ActiveRecord::Base @@ -7,12 +7,8 @@ class RoleAssignment &lt; ActiveRecord::Base
7 7
8 track_actions :join_community, :after_create, :keep_params => ["resource.name", "resource.url", "resource.profile_custom_icon"], :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_user => :accessor, :custom_target => :resource 8 track_actions :join_community, :after_create, :keep_params => ["resource.name", "resource.url", "resource.profile_custom_icon"], :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_user => :accessor, :custom_target => :resource
9 9
10 - track_actions :add_member_in_community, :after_create, :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_user => :accessor, :custom_target => :resource 10 +# track_actions :add_member_in_community, :after_create, :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_user => :accessor, :custom_target => :resource
11 11
12 - track_actions :leave_community, :before_destroy, :keep_params => ["resource.name", "resource.url", "resource.profile_custom_icon"], :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_user => :accessor, :custom_target => :resource  
13 -  
14 - track_actions :remove_member_in_community, :before_destroy, :if => Proc.new { |x| x.resource.is_a?(Community) && x.accessor.role_assignments.count(:conditions => { :resource_id => x.resource.id, :resource_type => 'Profile' }) == 1 }, :custom_target => :resource, :custom_user => :accessor  
15 -  
16 def has_permission?(perm, res) 12 def has_permission?(perm, res)
17 return false unless role.has_permission?(perm.to_s) && (resource || is_global) 13 return false unless role.has_permission?(perm.to_s) && (resource || is_global)
18 return true if is_global 14 return true if is_global
vendor/plugins/action_tracker/lib/action_tracker_model.rb
@@ -24,6 +24,7 @@ module ActionTracker @@ -24,6 +24,7 @@ module ActionTracker
24 RECENT_DELAY = 30 24 RECENT_DELAY = 30
25 25
26 named_scope :recent, :conditions => ['created_at >= ?', RECENT_DELAY.days.ago] 26 named_scope :recent, :conditions => ['created_at >= ?', RECENT_DELAY.days.ago]
  27 + named_scope :visible, :conditions => { :visible => true }
27 28
28 def self.current_user_from_model 29 def self.current_user_from_model
29 u = new 30 u = new
vendor/plugins/action_tracker_has_comments/init.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +# monkey patch to add comments on action_tracker
  2 +
  3 +ActionTracker::Record.module_eval do
  4 +
  5 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}'
  6 +
  7 + def conditions_for_comments
  8 + type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])
  9 + "source_type = '#{type}' AND source_id = '#{id}'"
  10 + end
  11 +
  12 +end
vendor/plugins/active_record_counter_cache_on_polymorphic_association/init.rb 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +# monkey patch to fix ActiveRecord bug
  2 +#
  3 +# https://rails.lighthouseapp.com/projects/8994/tickets/2452-counter_cache-not-updated-when-an-item-updates-its-polymorphic-owner
  4 +
  5 +#ActiveRecord::Associations.module_eval do
  6 +#
  7 +# def replace(record)
  8 +#
  9 +# counter_cache_name = @reflection.counter_cache_column
  10 +#
  11 +# if record.nil?
  12 +# if counter_cache_name && !@owner.new_record?
  13 +# record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
  14 +# end
  15 +#
  16 +# @target = @owner[@reflection.primary_key_name] = @owner[@reflection.options[:foreign_type]] = nil
  17 +# else
  18 +# @target = (AssociationProxy === record ? record.target : record)
  19 +#
  20 +# if counter_cache_name && !@owner.new_record?
  21 +# record.class.base_class.increment_counter(counter_cache_name, record.id)
  22 +# record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
  23 +# end
  24 +#
  25 +# @owner[@reflection.primary_key_name] = record.id
  26 +# @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
  27 +#
  28 +#
  29 +# @updated = true
  30 +# end
  31 +#
  32 +# loaded
  33 +# record
  34 +# end
  35 +#
  36 +#end