Commit 75524307b8962414354c692e19a677611fb4852c
Exists in
master
and in
23 other branches
Merging AI1826 with master
Conflicts: app/models/article.rb app/models/profile.rb app/models/uploaded_file.rb public/javascripts/application.js public/stylesheets/application.css test/unit/article_test.rb test/unit/category_finder_test.rb test/unit/enterprise_test.rb
Showing
86 changed files
with
1672 additions
and
772 deletions
Show diff stats
app/controllers/public/profile_controller.rb
| ... | ... | @@ -3,17 +3,15 @@ class ProfileController < PublicController |
| 3 | 3 | needs_profile |
| 4 | 4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] |
| 5 | 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 | 8 | helper TagsHelper |
| 9 | 9 | |
| 10 | 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 | 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 | 15 | end |
| 18 | 16 | @tags = profile.article_tags |
| 19 | 17 | unless profile.display_info_to?(user) |
| ... | ... | @@ -180,22 +178,33 @@ class ProfileController < PublicController |
| 180 | 178 | @scrap.receiver= receiver |
| 181 | 179 | @tab_action = params[:tab_action] |
| 182 | 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 | 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 | 199 | end |
| 191 | 200 | |
| 192 | 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 | 204 | end |
| 196 | 205 | |
| 197 | 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 | 208 | render :partial => 'profile_network_activities', :locals => {:network_activities => @activities} |
| 200 | 209 | end |
| 201 | 210 | |
| ... | ... | @@ -213,7 +222,11 @@ class ProfileController < PublicController |
| 213 | 222 | begin |
| 214 | 223 | raise if !can_edit_profile |
| 215 | 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 | 230 | render :text => _('Activity successfully removed.') |
| 218 | 231 | rescue |
| 219 | 232 | render :text => _('You could not remove this activity') |
| ... | ... | @@ -285,6 +298,16 @@ class ProfileController < PublicController |
| 285 | 298 | end |
| 286 | 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 | 311 | protected |
| 289 | 312 | |
| 290 | 313 | def check_access_to_profile | ... | ... |
app/helpers/application_helper.rb
| ... | ... | @@ -1218,15 +1218,12 @@ module ApplicationHelper |
| 1218 | 1218 | else _('1 minute') |
| 1219 | 1219 | end |
| 1220 | 1220 | |
| 1221 | - when 2..44 then _('%{distance} minutes') % { :distance => distance_in_minutes } | |
| 1222 | - when 45..89 then _('about 1 hour') | |
| 1223 | - when 90..1439 then _('about %{distance} hours') % { :distance => (distance_in_minutes.to_f / 60.0).round } | |
| 1224 | - when 1440..2879 then _('1 day') | |
| 1225 | - when 2880..43199 then _('%{distance} days') % { :distance => (distance_in_minutes / 1440).round } | |
| 1226 | - when 43200..86399 then _('about 1 month') | |
| 1227 | - when 86400..525599 then _('%{distance} months') % { :distance => (distance_in_minutes / 43200).round } | |
| 1228 | - when 525600..1051199 then _('about 1 year') | |
| 1229 | - else _('over %{distance} years') % { :distance => (distance_in_minutes / 525600).round } | |
| 1221 | + when 2..44 then _('%{distance} minutes ago') % { :distance => distance_in_minutes } | |
| 1222 | + when 45..89 then _('about 1 hour ago') | |
| 1223 | + when 90..1439 then _('about %{distance} hours ago') % { :distance => (distance_in_minutes.to_f / 60.0).round } | |
| 1224 | + when 1440..2879 then _('1 day ago') | |
| 1225 | + when 2880..10079 then _('%{distance} days ago') % { :distance => (distance_in_minutes / 1440).round } | |
| 1226 | + else show_time(from_time) | |
| 1230 | 1227 | end |
| 1231 | 1228 | end |
| 1232 | 1229 | ... | ... |
app/helpers/forum_helper.rb
| ... | ... | @@ -42,9 +42,9 @@ module ForumHelper |
| 42 | 42 | def last_topic_update(article) |
| 43 | 43 | info = article.info_from_last_update |
| 44 | 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 | 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 | 48 | end |
| 49 | 49 | end |
| 50 | 50 | ... | ... |
app/models/action_tracker_notification.rb
| ... | ... | @@ -3,6 +3,8 @@ class ActionTrackerNotification < ActiveRecord::Base |
| 3 | 3 | belongs_to :profile |
| 4 | 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 | 8 | validates_presence_of :profile_id, :action_tracker_id |
| 7 | 9 | validates_uniqueness_of :action_tracker_id, :scope => :profile_id |
| 8 | 10 | ... | ... |
app/models/article.rb
| ... | ... | @@ -8,9 +8,7 @@ class Article < ActiveRecord::Base |
| 8 | 8 | _('Content') |
| 9 | 9 | end |
| 10 | 10 | |
| 11 | - track_actions :create_article, :after_create, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target | |
| 12 | - 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 | |
| 13 | - track_actions :remove_article, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_target => :action_tracker_target | |
| 11 | + track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead, :first_image], :if => Proc.new { |a| a.is_trackable? && !a.image? } | |
| 14 | 12 | |
| 15 | 13 | # xss_terminate plugin can't sanitize array fields |
| 16 | 14 | before_save :sanitize_tag_list |
| ... | ... | @@ -23,7 +21,7 @@ class Article < ActiveRecord::Base |
| 23 | 21 | |
| 24 | 22 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
| 25 | 23 | |
| 26 | - has_many :comments, :dependent => :destroy, :order => 'created_at asc' | |
| 24 | + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' | |
| 27 | 25 | |
| 28 | 26 | has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ] |
| 29 | 27 | has_many :categories, :through => :article_categorizations |
| ... | ... | @@ -74,7 +72,7 @@ class Article < ActiveRecord::Base |
| 74 | 72 | validate :translation_must_have_language |
| 75 | 73 | |
| 76 | 74 | def is_trackable? |
| 77 | - self.published? && self.notifiable? && self.advertise? | |
| 75 | + self.published? && self.notifiable? && self.advertise? && self.profile.public_profile | |
| 78 | 76 | end |
| 79 | 77 | |
| 80 | 78 | def external_link=(link) |
| ... | ... | @@ -147,7 +145,7 @@ class Article < ActiveRecord::Base |
| 147 | 145 | before_update do |article| |
| 148 | 146 | article.advertise = true |
| 149 | 147 | end |
| 150 | - | |
| 148 | + | |
| 151 | 149 | # retrieves all articles belonging to the given +profile+ that are not |
| 152 | 150 | # sub-articles of any other article. |
| 153 | 151 | named_scope :top_level_for, lambda { |profile| |
| ... | ... | @@ -597,6 +595,21 @@ class Article < ActiveRecord::Base |
| 597 | 595 | _('Created at: ') |
| 598 | 596 | end |
| 599 | 597 | |
| 598 | + def activity | |
| 599 | + ActionTracker::Record.find_by_target_type_and_target_id 'Article', self.id | |
| 600 | + end | |
| 601 | + | |
| 602 | + def create_activity | |
| 603 | + if is_trackable? && !image? | |
| 604 | + save_action_for_verb 'create_article', [:name, :url, :lead, :first_image], Proc.new{}, :author | |
| 605 | + end | |
| 606 | + end | |
| 607 | + | |
| 608 | + def first_image | |
| 609 | + img = Hpricot(self.lead.to_s).search('img[@src]').first || Hpricot(self.body.to_s).search('img').first | |
| 610 | + img.nil? ? '' : img.attributes['src'] | |
| 611 | + end | |
| 612 | + | |
| 600 | 613 | private |
| 601 | 614 | |
| 602 | 615 | # FIXME: workaround for development env. | ... | ... |
app/models/comment.rb
| 1 | 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 | 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 | 9 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' |
| 8 | 10 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
| 9 | 11 | belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' |
| ... | ... | @@ -70,13 +72,25 @@ class Comment < ActiveRecord::Base |
| 70 | 72 | after_save :notify_article |
| 71 | 73 | after_destroy :notify_article |
| 72 | 74 | def notify_article |
| 73 | - article.comments_updated | |
| 75 | + article.comments_updated if article.kind_of?(Article) | |
| 74 | 76 | end |
| 75 | 77 | |
| 76 | 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 | 80 | Comment::Notifier.deliver_mail(comment) |
| 79 | 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 | 94 | end |
| 81 | 95 | |
| 82 | 96 | def replies | ... | ... |
app/models/community.rb
| ... | ... | @@ -87,4 +87,8 @@ class Community < Organization |
| 87 | 87 | {:title => __('Community Info and settings'), :icon => 'edit-profile-group'} |
| 88 | 88 | end |
| 89 | 89 | |
| 90 | + def activities | |
| 91 | + 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.target_id = #{self.id} UNION SELECT at.id, at.updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} at INNER JOIN articles a ON at.target_id = a.id WHERE a.profile_id = #{self.id} AND at.target_type = 'Article' ORDER BY updated_at DESC") | |
| 92 | + end | |
| 93 | + | |
| 90 | 94 | end | ... | ... |
app/models/enterprise.rb
| ... | ... | @@ -180,4 +180,8 @@ class Enterprise < Organization |
| 180 | 180 | true |
| 181 | 181 | end |
| 182 | 182 | |
| 183 | + def activities | |
| 184 | + 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") | |
| 185 | + end | |
| 186 | + | |
| 183 | 187 | end | ... | ... |
app/models/event.rb
app/models/external_feed.rb
| ... | ... | @@ -14,6 +14,7 @@ class ExternalFeed < ActiveRecord::Base |
| 14 | 14 | article = TinyMceArticle.new(:name => title, :profile => blog.profile, :body => content, :published_at => date, :source => link, :profile => blog.profile, :parent => blog) |
| 15 | 15 | unless blog.children.exists?(:slug => article.slug) |
| 16 | 16 | article.save! |
| 17 | + article.delay.create_activity | |
| 17 | 18 | end |
| 18 | 19 | end |
| 19 | 20 | ... | ... |
app/models/forum.rb
| ... | ... | @@ -28,4 +28,14 @@ class Forum < Folder |
| 28 | 28 | def self.icon_name(article = nil) |
| 29 | 29 | 'forum' |
| 30 | 30 | end |
| 31 | + | |
| 32 | + def notifiable? | |
| 33 | + true | |
| 34 | + end | |
| 35 | + | |
| 36 | + def first_paragraph | |
| 37 | + return '' if body.blank? | |
| 38 | + paragraphs = Hpricot(body).search('p') | |
| 39 | + paragraphs.empty? ? '' : paragraphs.first.to_html | |
| 40 | + end | |
| 31 | 41 | end | ... | ... |
app/models/image.rb
| ... | ... | @@ -13,7 +13,7 @@ class Image < ActiveRecord::Base |
| 13 | 13 | :thumbnails => { :big => '150x150', |
| 14 | 14 | :thumb => '100x100', |
| 15 | 15 | :portrait => '64x64', |
| 16 | - :minor => '50x50', | |
| 16 | + :minor => '50x50>', | |
| 17 | 17 | :icon => '20x20!' }, |
| 18 | 18 | :max_size => 5.megabytes # remember to update validate message below |
| 19 | 19 | ... | ... |
app/models/person.rb
| ... | ... | @@ -442,6 +442,10 @@ class Person < Profile |
| 442 | 442 | user.save! |
| 443 | 443 | end |
| 444 | 444 | |
| 445 | + def activities | |
| 446 | + 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") | |
| 447 | + end | |
| 448 | + | |
| 445 | 449 | protected |
| 446 | 450 | |
| 447 | 451 | def followed_by?(profile) | ... | ... |
app/models/profile.rb
| ... | ... | @@ -840,6 +840,11 @@ private :generate_url, :url_options |
| 840 | 840 | name |
| 841 | 841 | end |
| 842 | 842 | |
| 843 | + # Override in your subclasses | |
| 844 | + def activities | |
| 845 | + [] | |
| 846 | + end | |
| 847 | + | |
| 843 | 848 | private |
| 844 | 849 | def self.f_categories_label_proc(environment) |
| 845 | 850 | ids = environment.top_level_category_as_facet_ids | ... | ... |
app/models/scrap.rb
| ... | ... | @@ -12,6 +12,7 @@ class Scrap < ActiveRecord::Base |
| 12 | 12 | named_scope :not_replies, :conditions => {:scrap_id => nil} |
| 13 | 13 | |
| 14 | 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 | 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 | 18 | after_create do |scrap| | ... | ... |
app/models/uploaded_file.rb
| ... | ... | @@ -8,7 +8,7 @@ class UploadedFile < Article |
| 8 | 8 | _('File') |
| 9 | 9 | end |
| 10 | 10 | |
| 11 | - 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? } | |
| 11 | + 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 | |
| 12 | 12 | |
| 13 | 13 | include ShortFilename |
| 14 | 14 | |
| ... | ... | @@ -29,7 +29,7 @@ class UploadedFile < Article |
| 29 | 29 | end |
| 30 | 30 | |
| 31 | 31 | def thumbnail_path |
| 32 | - self.image? ? self.full_filename(:thumb).gsub(File.join(RAILS_ROOT, 'public'), '') : nil | |
| 32 | + self.image? ? self.full_filename(:display).gsub(File.join(RAILS_ROOT, 'public'), '') : nil | |
| 33 | 33 | end |
| 34 | 34 | |
| 35 | 35 | def display_title |
| ... | ... | @@ -144,4 +144,9 @@ class UploadedFile < Article |
| 144 | 144 | def uploaded_file? |
| 145 | 145 | true |
| 146 | 146 | end |
| 147 | + | |
| 148 | + def action_tracker_target | |
| 149 | + self | |
| 150 | + end | |
| 151 | + | |
| 147 | 152 | end | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +<%= render :partial => 'default_activity', :locals => { :activity => activity, :tab_action => tab_action } %> | ... | ... |
| ... | ... | @@ -0,0 +1,67 @@ |
| 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) %> | |
| 21 | + <% unless comment.title.blank? %> | |
| 22 | + <span class="comment-title"><%= comment.title %></span><br/> | |
| 23 | + <% end %> | |
| 24 | + <%= txt2html comment.body %> | |
| 25 | + </div> | |
| 26 | + <div class="profile-activity-time"> | |
| 27 | + <%= time_ago_as_sentence(comment.created_at) %> | |
| 28 | + </div> | |
| 29 | + </div> | |
| 30 | + | |
| 31 | + <% if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) %> | |
| 32 | + <% button_bar(:style => 'float: right; margin-top: 0px;') do %> | |
| 33 | + <%= 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?')) %> | |
| 34 | + <% end %> | |
| 35 | + <% end %> | |
| 36 | + <br style="clear: both;" /> | |
| 37 | + | |
| 38 | + <div class="comment_reply post_comment_box closed"> | |
| 39 | + <% if @comment && @comment.errors.any? && @comment.reply_of_id.to_i == comment.id %> | |
| 40 | + <%= error_messages_for :comment %> | |
| 41 | + <script type="text/javascript"> | |
| 42 | + jQuery(function() { | |
| 43 | + document.location.href = '#<%= comment.anchor %>'; | |
| 44 | + add_comment_reply_form('#comment-reply-to-<%= comment.id %>', <%= comment.id %>); | |
| 45 | + }); | |
| 46 | + </script> | |
| 47 | + <% end %> | |
| 48 | + <%= report_abuse(comment.author, :comment_link, comment) if comment.author %> | |
| 49 | + <%= link_to_function _('Reply'), | |
| 50 | + "var f = add_comment_reply_form(this, %s); f.find('input[name=comment[title]], textarea').val(''); return false" % comment.id, | |
| 51 | + :class => 'comment-footer comment-footer-link comment-footer-hide', | |
| 52 | + :id => 'comment-reply-to-' + comment.id.to_s | |
| 53 | + %> | |
| 54 | + </div> | |
| 55 | + | |
| 56 | + </div> | |
| 57 | + | |
| 58 | + <% unless comment.replies.blank? %> | |
| 59 | + <ul class="comment-replies"> | |
| 60 | + <% comment.replies.each do |reply| %> | |
| 61 | + <%= render :partial => 'comment', :locals => { :comment => reply } %> | |
| 62 | + <% end %> | |
| 63 | + </ul> | |
| 64 | + <% end %> | |
| 65 | + | |
| 66 | + </div> | |
| 67 | +</li> | ... | ... |
| ... | ... | @@ -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 | + <div class='article-name'><%= link_to(activity.params['name'], activity.params['url']) %></div> | |
| 11 | + <span title='<%= activity.target.class.short_description %>' class='profile-activity-icon icon-new icon-new<%= activity.target.class.icon_name %>'></span> | |
| 12 | + <%= image_tag(activity.params['first_image']) unless activity.params['first_image'].blank? %><%= strip_tags(truncate(activity.params['lead'], :length => 1000, :ommision => '...')).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 } %> | ... | ... |
| ... | ... | @@ -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 } %> | ... | ... |
| ... | ... | @@ -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/_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 | -<% 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 %> |
| ... | ... | @@ -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_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> | ... | ... |
| ... | ... | @@ -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> | ... | ... |
| ... | ... | @@ -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_as_thread %> | |
| 11 | +</ul> | |
| 12 | + | |
| 13 | +<%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %> | ... | ... |
app/views/profile/_profile_network.rhtml
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 | 4 | <% if network_activities.current_page < network_activities.total_pages %> |
| 32 | 5 | <div id='profile_network_activities_page_<%= network_activities.current_page %>'> |
| 33 | 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 | 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 | 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 | 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 | 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 | 26 | <% scrap.replies.map do |reply| %> |
| 19 | 27 | <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> |
| 20 | 28 | <% end %> |
| 21 | 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 | 31 | <hr /> |
| 50 | 32 | </li> | ... | ... |
| ... | ... | @@ -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 | 1 | <h3><%= _("%s's wall") % @profile.name %></h3> |
| 2 | 2 | <div id='leave_scrap'> |
| 3 | 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 | 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 | 7 | <% end %> |
| 8 | 8 | </div> |
| 9 | 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 | 12 | </ul> | ... | ... |
| ... | ... | @@ -0,0 +1 @@ |
| 1 | +NAO É PRA APARECER | ... | ... |
| ... | ... | @@ -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 | 17 | |
| 18 | 18 | <% if @profile.public? || (logged_in? && current_person.follows?(@profile)) %> |
| 19 | 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 | 46 | </table> |
| 22 | 47 | <% end %> | ... | ... |
app/views/tasks/_abuse_complaint_accept_details.rhtml
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | <% task.abuse_reports.each do |abuse_report| %> |
| 3 | 3 | <div> |
| 4 | 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 | 6 | <% if !abuse_report.content.blank? %> |
| 7 | 7 | <button class="display-abuse-report-details" data-report="<%=abuse_report.id%>"><%=_('View details')%></button> |
| 8 | 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 'noosfero/i18n' |
| 5 | 5 | ActionTrackerConfig.verbs = { |
| 6 | 6 | |
| 7 | 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 | 11 | :new_friendship => { |
| ... | ... | @@ -33,24 +22,11 @@ ActionTrackerConfig.verbs = { |
| 33 | 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 | 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 | 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 | 30 | :leave_scrap => { |
| 55 | 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 @@ |
| 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
db/migrate/20111228202739_remove_useless_tracked_actions.rb
0 → 100644
| ... | ... | @@ -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
db/migrate/20120228202739_adapt_create_articles_activity.rb
0 → 100644
| ... | ... | @@ -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 | ... | ... |
db/schema.rb
| ... | ... | @@ -29,6 +29,8 @@ ActiveRecord::Schema.define(:version => 20120411132751) do |
| 29 | 29 | t.string "verb" |
| 30 | 30 | t.datetime "created_at" |
| 31 | 31 | t.datetime "updated_at" |
| 32 | + t.integer "comments_count", :default => 0 | |
| 33 | + t.boolean "visible", :default => true | |
| 32 | 34 | end |
| 33 | 35 | |
| 34 | 36 | add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type" |
| ... | ... | @@ -200,7 +202,7 @@ ActiveRecord::Schema.define(:version => 20120411132751) do |
| 200 | 202 | create_table "comments", :force => true do |t| |
| 201 | 203 | t.string "title" |
| 202 | 204 | t.text "body" |
| 203 | - t.integer "article_id" | |
| 205 | + t.integer "source_id" | |
| 204 | 206 | t.integer "author_id" |
| 205 | 207 | t.string "name" |
| 206 | 208 | t.string "email" |
| ... | ... | @@ -208,6 +210,7 @@ ActiveRecord::Schema.define(:version => 20120411132751) do |
| 208 | 210 | t.integer "reply_of_id" |
| 209 | 211 | t.string "ip_address" |
| 210 | 212 | t.boolean "spam" |
| 213 | + t.string "source_type" | |
| 211 | 214 | end |
| 212 | 215 | |
| 213 | 216 | create_table "contact_lists", :force => true do |t| | ... | ... |
lib/notify_activity_to_profiles_job.rb
| 1 | 1 | class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id) |
| 2 | 2 | NOTIFY_ONLY_COMMUNITY = [ |
| 3 | - 'add_member_in_community', | |
| 4 | - 'remove_member_in_community', | |
| 3 | + 'add_member_in_community' | |
| 5 | 4 | ] |
| 6 | 5 | |
| 7 | 6 | NOT_NOTIFY_COMMUNITY = [ |
| 8 | - 'join_community', | |
| 9 | - 'leave_community', | |
| 7 | + 'join_community' | |
| 10 | 8 | ] |
| 11 | 9 | def perform |
| 12 | 10 | return unless ActionTracker::Record.exists?(tracked_action_id) |
| ... | ... | @@ -17,14 +15,23 @@ class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id) |
| 17 | 15 | return |
| 18 | 16 | end |
| 19 | 17 | |
| 18 | + # Notify the user | |
| 20 | 19 | ActionTrackerNotification.create(:profile_id => tracked_action.user.id, :action_tracker_id => tracked_action.id) |
| 21 | 20 | |
| 21 | + # Notify all friends | |
| 22 | 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})") |
| 23 | 23 | |
| 24 | 24 | if target.is_a?(Community) |
| 25 | - 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.id}") | |
| 26 | - | |
| 27 | 25 | ActionTrackerNotification.create(:profile_id => target.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb) |
| 26 | + | |
| 27 | + 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 profiles.id not in (select atn.profile_id from action_tracker_notifications as atn where atn.action_tracker_id = #{tracked_action.id}) and role_assignments.resource_type = 'Profile' and role_assignments.resource_id = #{target.id}") | |
| 28 | + end | |
| 29 | + | |
| 30 | + if target.is_a?(Article) && target.profile.is_a?(Community) | |
| 31 | + ActionTrackerNotification.create(:profile_id => target.profile.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb) | |
| 32 | + | |
| 33 | + 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 profiles.id not in (select atn.profile_id from action_tracker_notifications as atn where atn.action_tracker_id = #{tracked_action.id}) and role_assignments.resource_type = 'Profile' and role_assignments.resource_id = #{target.profile.id}") | |
| 28 | 34 | end |
| 35 | + | |
| 29 | 36 | end |
| 30 | 37 | end | ... | ... |
public/designs/icons/tango/style.css
| ... | ... | @@ -91,7 +91,7 @@ |
| 91 | 91 | .icon-lock { background-image: url(Tango/16x16/actions/lock.png) } |
| 92 | 92 | .icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat } |
| 93 | 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 | 95 | .icon-forum { background-image: url(Tango/16x16/apps/system-users.png) } |
| 96 | 96 | .icon-gallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } |
| 97 | 97 | .icon-newgallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | ... | ... |
public/designs/templates/default/stylesheets/style.css
public/designs/templates/leftbar/stylesheets/style.css
| ... | ... | @@ -23,3 +23,48 @@ |
| 23 | 23 | #profile-wall ul { |
| 24 | 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 .activity-gallery-images-count-1 span, | |
| 59 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img, | |
| 60 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a, | |
| 61 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span, | |
| 62 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img, | |
| 63 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a { | |
| 64 | + max-width: 540px; | |
| 65 | +} | |
| 66 | + | |
| 67 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a, | |
| 68 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a { | |
| 69 | + background-image: url(/images/gallery-image-activity-border-big-onecol.png); | |
| 70 | +} | ... | ... |
public/designs/templates/rightbar/stylesheets/style.css
| ... | ... | @@ -23,3 +23,43 @@ |
| 23 | 23 | #profile-wall ul { |
| 24 | 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 .activity-gallery-images-count-1 span, | |
| 59 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img, | |
| 60 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a, | |
| 61 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span, | |
| 62 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img, | |
| 63 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a { | |
| 64 | + max-width: 540px; | |
| 65 | +} | ... | ... |
1.73 KB
1.72 KB
477 Bytes
2.21 KB
1.32 KB
1.44 KB
1.01 KB
public/javascripts/application.js
| ... | ... | @@ -711,6 +711,41 @@ Array.min = function(array) { |
| 711 | 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 | +}); | |
| 748 | + | |
| 714 | 749 | /** |
| 715 | 750 | * @author Remy Sharp |
| 716 | 751 | * @url http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/ | ... | ... |
public/stylesheets/application.css
| ... | ... | @@ -240,6 +240,13 @@ td.field-name { |
| 240 | 240 | text-align: left; |
| 241 | 241 | vertical-align: top; |
| 242 | 242 | } |
| 243 | + | |
| 244 | +table.profile .ui-tabs .ui-tabs-panel { | |
| 245 | + border-left: 0; | |
| 246 | + border-right: 0; | |
| 247 | + border-bottom: 0; | |
| 248 | +} | |
| 249 | + | |
| 243 | 250 | table.profile th { |
| 244 | 251 | border-bottom: 2px solid #eeeeec; |
| 245 | 252 | padding: 10px 0px 0px 0px; |
| ... | ... | @@ -1034,6 +1041,11 @@ a.comment-picture { |
| 1034 | 1041 | .comment-logged-out .comment-text { |
| 1035 | 1042 | color: #888; |
| 1036 | 1043 | } |
| 1044 | + | |
| 1045 | +.comment-title { | |
| 1046 | + font-size: 12px; | |
| 1047 | + font-weight: bold; | |
| 1048 | +} | |
| 1037 | 1049 | .comment-created-at { |
| 1038 | 1050 | padding-right: 9px; |
| 1039 | 1051 | } |
| ... | ... | @@ -1205,7 +1217,9 @@ a.comment-picture { |
| 1205 | 1217 | -webkit-border-radius: 5px; |
| 1206 | 1218 | border-radius: 5px; |
| 1207 | 1219 | } |
| 1208 | -.comment-replies .article-comment-inner { | |
| 1220 | + | |
| 1221 | +.comment-replies .article-comment-inner, | |
| 1222 | +.scrap-replies { | |
| 1209 | 1223 | border: 1px solid #fff; |
| 1210 | 1224 | padding: 0; |
| 1211 | 1225 | -moz-border-radius: 4px; |
| ... | ... | @@ -4651,8 +4665,187 @@ h1#agenda-title { |
| 4651 | 4665 | } |
| 4652 | 4666 | #profile-activity li, #profile-network li, #profile-wall li { |
| 4653 | 4667 | display: block; |
| 4654 | - padding: 0; | |
| 4655 | - margin-bottom: 8px; | |
| 4668 | + padding: 3px; | |
| 4669 | + margin-bottom: 3px; | |
| 4670 | + background-color: #fff; | |
| 4671 | + border-bottom: 1px solid #e8e8e8; | |
| 4672 | + position: relative; | |
| 4673 | +} | |
| 4674 | + | |
| 4675 | +#profile-activity li, #profile-network li, #profile-wall li { | |
| 4676 | +} | |
| 4677 | + | |
| 4678 | +.profile-activity-lead img { | |
| 4679 | + width: 124px; | |
| 4680 | + float: left; | |
| 4681 | + margin-right: 5px; | |
| 4682 | +} | |
| 4683 | + | |
| 4684 | +.profile-activity-lead { | |
| 4685 | + width: 370px; | |
| 4686 | + display: inline-block; | |
| 4687 | + text-align: left; | |
| 4688 | + margin: 5px 0; | |
| 4689 | +} | |
| 4690 | + | |
| 4691 | +.profile-activity-lead .article-name { | |
| 4692 | + font-weight: bold; | |
| 4693 | + margin-bottom: 5px; | |
| 4694 | +} | |
| 4695 | + | |
| 4696 | +.profile-activity-article-forum .profile-activity-lead { | |
| 4697 | + height: 50px; | |
| 4698 | + width: 297px; | |
| 4699 | + padding-left: 60px; | |
| 4700 | + float: none; | |
| 4701 | + overflow: hidden; | |
| 4702 | + background: transparent url(/images/forum-activity-bg.png) left center no-repeat; | |
| 4703 | +} | |
| 4704 | + | |
| 4705 | +.profile-activity-article-forum .see-forum { | |
| 4706 | + text-align: right; | |
| 4707 | +} | |
| 4708 | + | |
| 4709 | +.profile-activity-article-forum .see-forum a { | |
| 4710 | + background: transparent url(/images/forum-activity-icon.png) left center no-repeat; | |
| 4711 | + padding-left: 30px; | |
| 4712 | + font-weight: bold; | |
| 4713 | + color: #dadada !important; | |
| 4714 | + text-decoration: none; | |
| 4715 | + font-size: 11px; | |
| 4716 | +} | |
| 4717 | + | |
| 4718 | +.profile-activity-article-forum .profile-activity-lead b { | |
| 4719 | + font-weight: normal; | |
| 4720 | +} | |
| 4721 | + | |
| 4722 | +#profile-activity li a, #profile-network li a, #profile-wall li a, | |
| 4723 | +#profile-wall .profile-wall-send-reply { | |
| 4724 | + color: #333; | |
| 4725 | +} | |
| 4726 | + | |
| 4727 | +#profile-activity li a, #profile-network li a, #profile-wall li a { | |
| 4728 | + font-weight: bold; | |
| 4729 | + text-decoration: none; | |
| 4730 | +} | |
| 4731 | + | |
| 4732 | +#profile-activity li a:hover, #profile-network li a:hover, #profile-wall li a:hover { | |
| 4733 | + text-decoration: underline; | |
| 4734 | +} | |
| 4735 | + | |
| 4736 | +.profile-activity-text { | |
| 4737 | + margin: 0; | |
| 4738 | + color: #000; | |
| 4739 | +} | |
| 4740 | + | |
| 4741 | +#profile-wall li.profile-activity-item.upload_image span, | |
| 4742 | +#profile-wall li.profile-activity-item.upload_image span a, | |
| 4743 | +#profile-network li.profile-activity-item.upload_image span, | |
| 4744 | +#profile-network li.profile-activity-item.upload_image span a { | |
| 4745 | + width: 110px; | |
| 4746 | + height: 100px; | |
| 4747 | + display: block; | |
| 4748 | + overflow: hidden; | |
| 4749 | + position: absolute; | |
| 4750 | +} | |
| 4751 | + | |
| 4752 | +#profile-wall li.profile-activity-item.upload_image span a img, | |
| 4753 | +#profile-network li.profile-activity-item.upload_image span a img { | |
| 4754 | + width: 110px; | |
| 4755 | + height: 100px; | |
| 4756 | +} | |
| 4757 | + | |
| 4758 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span, | |
| 4759 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a, | |
| 4760 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img, | |
| 4761 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span, | |
| 4762 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a img { | |
| 4763 | + width: auto; | |
| 4764 | + max-width: 383px; | |
| 4765 | + height: auto; | |
| 4766 | +} | |
| 4767 | + | |
| 4768 | +#profile-wall li.profile-activity-item.upload_image span img, | |
| 4769 | +#profile-network li.profile-activity-item.upload_image span img { | |
| 4770 | + display: block; | |
| 4771 | +} | |
| 4772 | + | |
| 4773 | +#profile-wall li.profile-activity-item.upload_image span, | |
| 4774 | +#profile-network li.profile-activity-item.upload_image span { | |
| 4775 | + position: relative; | |
| 4776 | + display: inline-block; | |
| 4777 | + margin: 5px 0px 0px 5px; | |
| 4778 | +} | |
| 4779 | + | |
| 4780 | +#profile-wall li.profile-activity-item.upload_image .profile-activity-text span, | |
| 4781 | +#profile-network li.profile-activity-item.upload_image .profile-activity-text span { | |
| 4782 | + border: 4px solid #D2D2D2; | |
| 4783 | + border-radius: 4px; | |
| 4784 | + -webkit-border-radius: 4px; | |
| 4785 | + -moz-border-radius: 4px; | |
| 4786 | +} | |
| 4787 | + | |
| 4788 | +#profile-wall li.profile-activity-item.upload_image span a, | |
| 4789 | +#profile-network li.profile-activity-item.upload_image span a { | |
| 4790 | + text-indent: -5000em; | |
| 4791 | +} | |
| 4792 | + | |
| 4793 | +#profile-wall li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a, | |
| 4794 | +#profile-network li.profile-activity-item.upload_image .activity-gallery-images-count-1 span a { | |
| 4795 | + position: relative; | |
| 4796 | +} | |
| 4797 | + | |
| 4798 | +#profile-wall li.profile-activity-item.upload_image .article-comment span, | |
| 4799 | +#profile-wall li.profile-activity-item.upload_image .profile-wall-actions span, | |
| 4800 | +#profile-network li.profile-activity-item.upload_image .article-comment span, | |
| 4801 | +#profile-network li.profile-activity-item.upload_image .profile-wall-actions span { | |
| 4802 | + display: inline; | |
| 4803 | + position: static; | |
| 4804 | + margin: 0; | |
| 4805 | + float: none; | |
| 4806 | + width: auto; | |
| 4807 | + height: auto; | |
| 4808 | + font-weight: normal; | |
| 4809 | +} | |
| 4810 | + | |
| 4811 | +#profile-wall li.profile-activity-item ul.profile-wall-activities-comments, | |
| 4812 | +#profile-network li.profile-activity-item ul.profile-wall-activities-comments { | |
| 4813 | + margin-top: 0; | |
| 4814 | +} | |
| 4815 | + | |
| 4816 | +#profile-wall li.profile-activity-item.upload_image .profile-activity-text, | |
| 4817 | +#profile-network li.profile-activity-item.upload_image .profile-activity-text, | |
| 4818 | +#profile-network li.profile-activity-item ul.profile-wall-activities-comments { | |
| 4819 | + padding-left: 50px; | |
| 4820 | +} | |
| 4821 | + | |
| 4822 | +#profile-wall li.profile-activity-item.join_community .profile-activity-text a img, | |
| 4823 | +#profile-wall li.profile-activity-item.new_friendship .profile-activity-text a img, | |
| 4824 | +#profile-network li.profile-activity-item.join_community .profile-activity-text a img, | |
| 4825 | +#profile-network li.profile-activity-item.new_friendship .profile-activity-text a img { | |
| 4826 | + margin: 5px 5px 0 0; | |
| 4827 | + padding: 1px; | |
| 4828 | + border: 1px solid #ccc; | |
| 4829 | +} | |
| 4830 | + | |
| 4831 | +#profile-wall li.profile-activity-item.create_article, | |
| 4832 | +#profile-netowrk li.profile-activity-item.create_article { | |
| 4833 | + position: relative; | |
| 4834 | +} | |
| 4835 | + | |
| 4836 | +.profile-activity-icon { | |
| 4837 | + width: 16px; | |
| 4838 | + height: 16px; | |
| 4839 | + display: inline-block; | |
| 4840 | + position: absolute; | |
| 4841 | + top: 0px; | |
| 4842 | + right: 0px; | |
| 4843 | +} | |
| 4844 | + | |
| 4845 | +#profile-activity .profile-wall-scrap-replies li, | |
| 4846 | +#profile-network .profile-wall-scrap-replies li, | |
| 4847 | +#profile-wall .profile-wall-scrap-replies li { | |
| 4848 | + border-bottom: none; | |
| 4656 | 4849 | } |
| 4657 | 4850 | #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { |
| 4658 | 4851 | float: left; |
| ... | ... | @@ -4664,12 +4857,12 @@ h1#agenda-title { |
| 4664 | 4857 | } |
| 4665 | 4858 | #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { |
| 4666 | 4859 | float: left; |
| 4667 | - min-height: 60px; | |
| 4860 | + Xmin-height: 60px; | |
| 4668 | 4861 | margin: 0; |
| 4669 | 4862 | padding: 0; |
| 4670 | 4863 | border: 1px solid #ccc; |
| 4671 | 4864 | overflow: hidden; |
| 4672 | - background-color: #fff; | |
| 4865 | + Xbackground-color: #fff; | |
| 4673 | 4866 | position: relative; |
| 4674 | 4867 | } |
| 4675 | 4868 | #profile-wall .profile-wall-description { |
| ... | ... | @@ -4678,7 +4871,10 @@ h1#agenda-title { |
| 4678 | 4871 | #profile-activity .profile-activity-description .icon-delete span, #profile-network .profile-network-description .icon-delete span, #profile-wall .profile-wall-description .icon-delete span { |
| 4679 | 4872 | display: none; |
| 4680 | 4873 | } |
| 4681 | -#profile-activity .profile-activity-description .icon-delete, #profile-network .profile-network-description .icon-delete, #profile-wall .profile-wall-description .icon-delete { | |
| 4874 | + | |
| 4875 | +#profile-activity .profile-activity-description .icon-delete, | |
| 4876 | +#profile-network .profile-activity-description .icon-delete, | |
| 4877 | +#profile-wall .profile-wall-description .icon-delete { | |
| 4682 | 4878 | position: absolute; |
| 4683 | 4879 | top: 4px; |
| 4684 | 4880 | right: 4px; |
| ... | ... | @@ -4688,21 +4884,55 @@ h1#agenda-title { |
| 4688 | 4884 | -webkit-border-radius: 3px; |
| 4689 | 4885 | -moz-border-radius: 3px; |
| 4690 | 4886 | } |
| 4691 | -#profile-activity .profile-activity-text, #profile-network .profile-network-text, #profile-wall .profile-wall-text { | |
| 4887 | + | |
| 4888 | +#profile-activity .profile-activity-text, | |
| 4889 | +#profile-network .profile-activity-text, | |
| 4890 | +#profile-wall .profile-wall-text { | |
| 4692 | 4891 | font-size: 13px; |
| 4693 | - margin: 5px; | |
| 4892 | + margin: 2px 5px; | |
| 4694 | 4893 | } |
| 4695 | 4894 | #profile-wall .profile-wall-text { |
| 4696 | 4895 | padding-top: 0; |
| 4697 | 4896 | } |
| 4698 | -#profile-activity .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { | |
| 4897 | + | |
| 4898 | +.profile-activities .profile-activity-time, | |
| 4899 | +#profile-network .profile-activity-time, | |
| 4900 | +#profile-wall .profile-wall-time { | |
| 4699 | 4901 | font-size: 11px; |
| 4700 | 4902 | margin: 5px; |
| 4701 | 4903 | color: #babdb6; |
| 4904 | + text-align: right; | |
| 4905 | +} | |
| 4906 | + | |
| 4907 | +#profile-wall .profile-wall-send-reply, | |
| 4908 | +.profile-activities .profile-activity-time, | |
| 4909 | +#profile-network .profile-activity-time, | |
| 4910 | +#profile-wall .profile-wall-time, | |
| 4911 | +.profile-wall-actions a { | |
| 4912 | + display: block; | |
| 4913 | + float: right; | |
| 4914 | + font-size: 10px; | |
| 4915 | + margin: 2px 0 3px 10px; | |
| 4916 | + color: #ccc; | |
| 4917 | + padding: 0; | |
| 4918 | +} | |
| 4919 | + | |
| 4920 | +#profile-wall li .profile-wall-actions a, | |
| 4921 | +#profile-activity li .profile-wall-actions a, | |
| 4922 | +#profile-network li .profile-wall-actions a, | |
| 4923 | +#profile-wall .profile-wall-send-reply a { | |
| 4924 | + text-decoration: none; | |
| 4925 | + color: #333; | |
| 4926 | + font-weight: normal; | |
| 4927 | +} | |
| 4928 | + | |
| 4929 | +#profile-wall li .profile-wall-actions a:hover, | |
| 4930 | +#profile-network li .profile-wall-actions a:hover, | |
| 4931 | +#profile-wall .profile-wall-send-reply a:hover { | |
| 4932 | + text-decoration: underline; | |
| 4702 | 4933 | } |
| 4703 | 4934 | #profile-activity hr, #profile-network hr, #profile-wall hr { |
| 4704 | - clear: both; | |
| 4705 | - border: 0; | |
| 4935 | + display: none; | |
| 4706 | 4936 | } |
| 4707 | 4937 | #profile-activity .profile-activity-send-message, #profile-network .profile-network-send-message, #profile-wall .profile-wall-send-message { |
| 4708 | 4938 | font-size: 10px; |
| ... | ... | @@ -4762,9 +4992,13 @@ h1#agenda-title { |
| 4762 | 4992 | } |
| 4763 | 4993 | .profile-wall-sender, .profile-wall-time, .profile-wall-description, .profile-activity-sender, .profile-activity-time, .profile-activity-description, .profile-network-sender, .profile-network-time, .profile-network-description { |
| 4764 | 4994 | padding-left: 5px; |
| 4995 | + margin: 5px; | |
| 4765 | 4996 | } |
| 4766 | -.profile-network-sender, .profile-wall-sender { | |
| 4767 | - margin: 2px 0; | |
| 4997 | + | |
| 4998 | +.profile-network-sender, | |
| 4999 | +.profile-activity-sender, | |
| 5000 | +.profile-wall-sender { | |
| 5001 | + margin: 0; | |
| 4768 | 5002 | } |
| 4769 | 5003 | #profile-activity .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { |
| 4770 | 5004 | margin: 0; |
| ... | ... | @@ -4775,7 +5009,16 @@ h1#agenda-title { |
| 4775 | 5009 | padding: 2px; |
| 4776 | 5010 | overflow: hidden; |
| 4777 | 5011 | } |
| 4778 | -.profile-network-message, .profile-wall-message { | |
| 5012 | + | |
| 5013 | +#profile-network li textarea:focus, | |
| 5014 | +#profile-wall li textarea:focus { | |
| 5015 | + background-position: left center; | |
| 5016 | + background-repeat: no-repeat; | |
| 5017 | + text-indent: 28px; | |
| 5018 | +} | |
| 5019 | + | |
| 5020 | +.profile-network-message, | |
| 5021 | +.profile-wall-message { | |
| 4779 | 5022 | margin: 0; |
| 4780 | 5023 | } |
| 4781 | 5024 | .limited-text-area p { |
| ... | ... | @@ -4801,19 +5044,24 @@ h1#agenda-title { |
| 4801 | 5044 | overflow: hidden; |
| 4802 | 5045 | } |
| 4803 | 5046 | .profile-send-reply { |
| 4804 | - background-color: #eee; | |
| 4805 | - border: 1px solid #aaa; | |
| 4806 | - padding: 2px; | |
| 4807 | - padding-left: 20px; | |
| 4808 | - background-repeat: no-repeat; | |
| 4809 | - background-position: 2px center; | |
| 5047 | + xbackground-color: #eee; | |
| 5048 | + xborder: 1px solid #aaa; | |
| 5049 | + xpadding: 2px; | |
| 5050 | + xpadding-left: 20px; | |
| 5051 | + xbackground-repeat: no-repeat; | |
| 5052 | + xbackground-position: 2px center; | |
| 4810 | 5053 | color: #aaa; |
| 4811 | - text-decoration: none; | |
| 4812 | - margin-left: 8px; | |
| 5054 | + Xtext-decoration: none; | |
| 5055 | + Xmargin-left: 8px; | |
| 4813 | 5056 | } |
| 4814 | 5057 | #content .profile-send-reply:hover { |
| 4815 | 5058 | text-decoration: none; |
| 4816 | 5059 | } |
| 5060 | + | |
| 5061 | +#profile-wall .profile-wall-actions { | |
| 5062 | + text-align: right; | |
| 5063 | +} | |
| 5064 | + | |
| 4817 | 5065 | #profile-wall .profile-wall-scrap-replies .profile-wall-description { |
| 4818 | 5066 | background: transparent; |
| 4819 | 5067 | } |
| ... | ... | @@ -4826,6 +5074,105 @@ h1#agenda-title { |
| 4826 | 5074 | .limited-text-area div.fieldWithErrors { |
| 4827 | 5075 | background: transparent; |
| 4828 | 5076 | } |
| 5077 | + | |
| 5078 | +#profile-wall ul.profile-wall-activities-comments, | |
| 5079 | +#profile-network ul.profile-wall-activities-comments { | |
| 5080 | + margin-top: 35px; | |
| 5081 | + padding-left: 50px; | |
| 5082 | + width: auto; | |
| 5083 | +} | |
| 5084 | + | |
| 5085 | +#profile-wall ul.profile-wall-activities-comments ul, | |
| 5086 | +#profile-network ul.profile-wall-activities-comments ul { | |
| 5087 | + padding-left: 0px; | |
| 5088 | +} | |
| 5089 | + | |
| 5090 | +#profile-wall .profile-wall-activities-comments li, | |
| 5091 | +#profile-network .profile-wall-activities-comments li { | |
| 5092 | + background: #f0f0f1; | |
| 5093 | + border-bottom: 1px solid #d2d2d2 !important; | |
| 5094 | + border-top: 1px solid #fff; | |
| 5095 | + margin-bottom: 0; | |
| 5096 | +} | |
| 5097 | + | |
| 5098 | +#profile-wall .profile-wall-activities-comments img, | |
| 5099 | +#profile-network .profile-wall-activities-comments img { | |
| 5100 | + max-width: 50px; | |
| 5101 | + max-height: 50px; | |
| 5102 | +} | |
| 5103 | + | |
| 5104 | +#profile-wall .profile-wall-activities-comments .comment_reply, | |
| 5105 | +#profile-wall .profile-wall-activities-comments h4, | |
| 5106 | +#profile-network .profile-wall-activities-comments .comment_reply, | |
| 5107 | +#profile-network .profile-wall-activities-comments h4 { | |
| 5108 | + display: none; | |
| 5109 | +} | |
| 5110 | + | |
| 5111 | +#profile-wall .profile-wall-activities-comments .comment-picture, | |
| 5112 | +#profile-network .profile-wall-activities-comments .comment-picture { | |
| 5113 | + width: 50px; | |
| 5114 | + text-align: center; | |
| 5115 | +} | |
| 5116 | + | |
| 5117 | +#profile-wall .profile-wall-activities-comments .comment-text p, | |
| 5118 | +#profile-network .profile-wall-activities-comments .comment-text p { | |
| 5119 | + margin: 0; | |
| 5120 | +} | |
| 5121 | + | |
| 5122 | +#profile-wall .profile-wall-activities-comments .profile-activity-time, | |
| 5123 | +#profile-network .profile-wall-activities-comments .profile-activity-time { | |
| 5124 | + clear: both; | |
| 5125 | +} | |
| 5126 | + | |
| 5127 | +#profile-wall .profile-wall-activities-comments .comment-details, | |
| 5128 | +#profile-network .profile-wall-activities-comments .comment-details { | |
| 5129 | + padding: 0; | |
| 5130 | +} | |
| 5131 | + | |
| 5132 | +#profile-wall .profile-wall-activities-comments .article-comment .button-bar, | |
| 5133 | +#profile-network .profile-wall-activities-comments .article-comment .button-bar { | |
| 5134 | + float: right; | |
| 5135 | + padding: 0; | |
| 5136 | + text-align: right; | |
| 5137 | + position: static; | |
| 5138 | + clear: none; | |
| 5139 | + display: none; | |
| 5140 | +} | |
| 5141 | + | |
| 5142 | +#profile-wall .profile-wall-activities-comments .article-comment:hover .button-bar, | |
| 5143 | +#profile-network .profile-wall-activities-comments .article-comment:hover .button-bar { | |
| 5144 | + display: block; | |
| 5145 | +} | |
| 5146 | + | |
| 5147 | +#profile-wall .profile-wall-activities-comments .article-comment .button-bar a.button, | |
| 5148 | +#profile-network .profile-wall-activities-comments .article-comment .button-bar a.button { | |
| 5149 | + background: transparent; | |
| 5150 | + border: 0; | |
| 5151 | + height: auto; | |
| 5152 | + line-height: auto; | |
| 5153 | + color: #333; | |
| 5154 | + text-decoration: none; | |
| 5155 | + font-size: 10px; | |
| 5156 | + padding: 0; | |
| 5157 | + margin: 0; | |
| 5158 | + display: inline; | |
| 5159 | + position: static; | |
| 5160 | + float: none; | |
| 5161 | + font-weight: normal; | |
| 5162 | +} | |
| 5163 | + | |
| 5164 | +#profile-wall .profile-wall-activities-comments .article-comment .button-bar a.button:hover, | |
| 5165 | +#profile-network .profile-wall-activities-comments .article-comment .button-bar a.button:hover { | |
| 5166 | + text-decoration: underline; | |
| 5167 | +} | |
| 5168 | + | |
| 5169 | +#profile-wall .profile-wall-activities-comments .article-comment .button-bar .button span, | |
| 5170 | +#profile-network .profile-wall-activities-comments .article-comment .button-bar .button span { | |
| 5171 | + display: inline; | |
| 5172 | + position: static; | |
| 5173 | + display: inline; | |
| 5174 | +} | |
| 5175 | + | |
| 4829 | 5176 | /* friends online {{{ */ |
| 4830 | 5177 | |
| 4831 | 5178 | #chat-online-users { |
| ... | ... | @@ -4948,15 +5295,36 @@ h1#agenda-title { |
| 4948 | 5295 | margin-left: 0; |
| 4949 | 5296 | } |
| 4950 | 5297 | #profile-wall .comment-balloon-content { |
| 4951 | - padding: 3px 0 3px 15px; | |
| 5298 | + padding: 3px 0px; | |
| 4952 | 5299 | } |
| 4953 | 5300 | .profile-wall-reply { |
| 4954 | 5301 | margin: 0; |
| 4955 | 5302 | } |
| 5303 | + | |
| 5304 | +.profile-wall-reply-form { | |
| 5305 | + display: block; | |
| 5306 | + background: #f0f0f1; | |
| 5307 | + border-bottom: 1px solid #d2d2d2; | |
| 5308 | + border-top: 1px solid #fff; | |
| 5309 | + margin-left: 50px; | |
| 5310 | + padding: 0 5px; | |
| 5311 | +} | |
| 5312 | + | |
| 5313 | +.scrap-replies .profile-wall-reply-form { | |
| 5314 | + margin-left: 0px; | |
| 5315 | +} | |
| 5316 | + | |
| 4956 | 5317 | .profile-wall-scrap-replies { |
| 4957 | 5318 | float: right; |
| 4958 | 5319 | margin-right: 2px; |
| 4959 | 5320 | } |
| 5321 | + | |
| 5322 | +.view-all-comments { | |
| 5323 | + clear: both; | |
| 5324 | + margin-left: 50px; | |
| 5325 | + padding-left: 20px; | |
| 5326 | +} | |
| 5327 | + | |
| 4960 | 5328 | /* Profile activity relative dimensions */ |
| 4961 | 5329 | |
| 4962 | 5330 | #leave_scrap { |
| ... | ... | @@ -4965,15 +5333,37 @@ h1#agenda-title { |
| 4965 | 5333 | #leave_scrap textarea { |
| 4966 | 5334 | width: 98%; |
| 4967 | 5335 | } |
| 4968 | -#profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { | |
| 4969 | - width: 19%; | |
| 5336 | + | |
| 5337 | +.profile-activities .profile-activity-image, | |
| 5338 | +#profile-network .profile-activity-image, | |
| 5339 | +#profile-wall .profile-wall-image { | |
| 5340 | + width: 50px; | |
| 5341 | + margin: 5px; | |
| 5342 | + float: left; | |
| 4970 | 5343 | } |
| 4971 | -#profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { | |
| 4972 | - width: 80%; | |
| 5344 | + | |
| 5345 | +#profile-activity .profile-activity-description, | |
| 5346 | +#profile-network .profile-activity-description, | |
| 5347 | +#profile-wall .profile-wall-description { | |
| 4973 | 5348 | word-wrap: break-word; |
| 4974 | 5349 | } |
| 4975 | -#profile-wall .profile-wall-scrap-replies textarea, #profile-network textarea, #profile-wall textarea { | |
| 4976 | - width: 99%; | |
| 5350 | + | |
| 5351 | +#profile-wall textarea { | |
| 5352 | + width: 375px; | |
| 5353 | +} | |
| 5354 | + | |
| 5355 | +#profile-wall li textarea { | |
| 5356 | + width: 388px; | |
| 5357 | +} | |
| 5358 | + | |
| 5359 | +#profile-wall .profile-wall-scrap-replies textarea, | |
| 5360 | +#profile-network textarea, #profile-wall textarea, | |
| 5361 | +#profile-wall li .profile-wall-reply-form textarea { | |
| 5362 | + width: 98%; | |
| 5363 | +} | |
| 5364 | + | |
| 5365 | +#profile-wall #leave_scrap textarea { | |
| 5366 | + width: 442px; | |
| 4977 | 5367 | } |
| 4978 | 5368 | .profile-wall-scrap-replies { |
| 4979 | 5369 | width: 100%; | ... | ... |
test/factories.rb
| ... | ... | @@ -374,7 +374,7 @@ module Noosfero::Factory |
| 374 | 374 | ############################################### |
| 375 | 375 | |
| 376 | 376 | def defaults_for_scrap(params = {}) |
| 377 | - { :content => 'soment content ', :sender_id => 1, :receiver_id => 1, :created_at => DateTime.now }.merge(params) | |
| 377 | + { :content => 'some content ', :sender_id => 1, :receiver_id => 1, :created_at => DateTime.now }.merge(params) | |
| 378 | 378 | end |
| 379 | 379 | |
| 380 | 380 | ############################################### |
| ... | ... | @@ -442,7 +442,7 @@ module Noosfero::Factory |
| 442 | 442 | |
| 443 | 443 | def defaults_for_comment(params = {}) |
| 444 | 444 | name = "comment_#{rand(1000)}" |
| 445 | - { :title => name, :body => "my own comment", :article_id => 1 }.merge(params) | |
| 445 | + { :title => name, :body => "my own comment", :source_id => 1 }.merge(params) | |
| 446 | 446 | end |
| 447 | 447 | |
| 448 | 448 | ############################################### | ... | ... |
test/functional/profile_controller_test.rb
| ... | ... | @@ -714,25 +714,23 @@ class ProfileControllerTest < ActionController::TestCase |
| 714 | 714 | assert_no_tag :tag => 'p', :content => 'A scrap' |
| 715 | 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 | 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 | 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 | 731 | login_as(profile.identifier) |
| 733 | 732 | get :index, :profile => p1.identifier |
| 734 | - assert_not_nil assigns(:activities) | |
| 735 | - assert_equal [a1], assigns(:activities) | |
| 733 | + assert_nil assigns(:activities) | |
| 736 | 734 | end |
| 737 | 735 | |
| 738 | 736 | should 'see the activities_items paginated' do |
| ... | ... | @@ -744,26 +742,27 @@ class ProfileControllerTest < ActionController::TestCase |
| 744 | 742 | assert_equal 30, assigns(:activities).count |
| 745 | 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 | 746 | p2= fast_create(Person) |
| 750 | - assert !p1.is_a_friend?(p2) | |
| 747 | + assert !profile.is_a_friend?(p2) | |
| 751 | 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 | 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 | 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 | 762 | login_as(profile.identifier) |
| 764 | - get :index, :profile => p1.identifier | |
| 763 | + get :index, :profile => p3.identifier | |
| 765 | 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 | 766 | end |
| 768 | 767 | |
| 769 | 768 | should 'see all the activities in the current profile network' do |
| ... | ... | @@ -931,13 +930,29 @@ class ProfileControllerTest < ActionController::TestCase |
| 931 | 930 | assert_template 'index' |
| 932 | 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 | 942 | get :index, :profile => p1.identifier |
| 937 | - assert_equal [], assigns(:wall_items) | |
| 943 | + assert_nil assigns(:activities) | |
| 938 | 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 | 956 | p1 = ActionTracker::Record.current_user_from_model |
| 942 | 957 | p2 = fast_create(Person) |
| 943 | 958 | p3 = fast_create(Person) |
| ... | ... | @@ -952,10 +967,10 @@ class ProfileControllerTest < ActionController::TestCase |
| 952 | 967 | @controller.stubs(:current_user).returns(user) |
| 953 | 968 | Person.any_instance.stubs(:follows?).returns(true) |
| 954 | 969 | get :index, :profile => p1.identifier |
| 955 | - assert_equal [s2,s3], assigns(:wall_items) | |
| 970 | + assert_equal [s2,s3], assigns(:activities) | |
| 956 | 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 | 974 | c = fast_create(Community) |
| 960 | 975 | p1 = fast_create(Person) |
| 961 | 976 | p2 = fast_create(Person) |
| ... | ... | @@ -971,12 +986,12 @@ class ProfileControllerTest < ActionController::TestCase |
| 971 | 986 | @controller.stubs(:current_user).returns(user) |
| 972 | 987 | Person.any_instance.stubs(:follows?).returns(true) |
| 973 | 988 | get :index, :profile => c.identifier |
| 974 | - assert_equal [s2,s3], assigns(:wall_items) | |
| 989 | + assert_equal [s2,s3], assigns(:activities) | |
| 975 | 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 | 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 | 996 | @controller.stubs(:logged_in?).returns(true) |
| 982 | 997 | user = mock() |
| ... | ... | @@ -986,10 +1001,10 @@ class ProfileControllerTest < ActionController::TestCase |
| 986 | 1001 | Person.any_instance.stubs(:follows?).returns(true) |
| 987 | 1002 | assert_equal 40, p1.scraps_received.not_replies.count |
| 988 | 1003 | get :index, :profile => p1.identifier |
| 989 | - assert_equal 30, assigns(:wall_items).count | |
| 1004 | + assert_equal 30, assigns(:activities).count | |
| 990 | 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 | 1008 | p1 = Person.first |
| 994 | 1009 | c = fast_create(Community) |
| 995 | 1010 | 40.times{fast_create(Scrap, :receiver_id => c.id)} |
| ... | ... | @@ -1002,7 +1017,7 @@ class ProfileControllerTest < ActionController::TestCase |
| 1002 | 1017 | Person.any_instance.stubs(:follows?).returns(true) |
| 1003 | 1018 | assert_equal 40, c.scraps_received.not_replies.count |
| 1004 | 1019 | get :index, :profile => c.identifier |
| 1005 | - assert_equal 30, assigns(:wall_items).count | |
| 1020 | + assert_equal 30, assigns(:activities).count | |
| 1006 | 1021 | end |
| 1007 | 1022 | |
| 1008 | 1023 | should "the owner of activity could remove it" do |
| ... | ... | @@ -1072,17 +1087,17 @@ class ProfileControllerTest < ActionController::TestCase |
| 1072 | 1087 | end |
| 1073 | 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 | 1091 | login_as(profile.identifier) |
| 1077 | 1092 | person = fast_create(Person) |
| 1078 | 1093 | at = fast_create(ActionTracker::Record, :user_id => person.id) |
| 1079 | 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 | 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 | 1101 | end |
| 1087 | 1102 | |
| 1088 | 1103 | should "not show the scrap button on network activity if the user is himself" do |
| ... | ... | @@ -1093,16 +1108,16 @@ class ProfileControllerTest < ActionController::TestCase |
| 1093 | 1108 | assert_no_tag :tag => 'p', :attributes => {:class => 'profile-network-send-message'} |
| 1094 | 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 | 1112 | login_as(profile.identifier) |
| 1098 | 1113 | person = fast_create(Person) |
| 1099 | 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 | 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 | 1121 | end |
| 1107 | 1122 | |
| 1108 | 1123 | should "not show the scrap button on wall activity if the user is himself" do |
| ... | ... | @@ -1158,7 +1173,7 @@ class ProfileControllerTest < ActionController::TestCase |
| 1158 | 1173 | assert_equal 40, profile.tracked_actions.count |
| 1159 | 1174 | get :view_more_activities, :profile => profile.identifier, :page => 2 |
| 1160 | 1175 | assert_response :success |
| 1161 | - assert_template '_profile_activities' | |
| 1176 | + assert_template '_profile_activities_list' | |
| 1162 | 1177 | assert_equal 10, assigns(:activities).count |
| 1163 | 1178 | end |
| 1164 | 1179 | |
| ... | ... | @@ -1247,4 +1262,70 @@ class ProfileControllerTest < ActionController::TestCase |
| 1247 | 1262 | post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'} |
| 1248 | 1263 | end |
| 1249 | 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 | 1331 | end | ... | ... |
test/unit/action_tracker_notification_test.rb
| ... | ... | @@ -76,4 +76,28 @@ class ActionTrackerNotificationTest < ActiveSupport::TestCase |
| 76 | 76 | assert_equal [last_notification], at.action_tracker_notifications |
| 77 | 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 | 103 | end | ... | ... |
test/unit/approve_article_test.rb
| ... | ... | @@ -251,7 +251,7 @@ class ApproveArticleTest < ActiveSupport::TestCase |
| 251 | 251 | assert_equal 1, ActionTracker::Record.count |
| 252 | 252 | end |
| 253 | 253 | |
| 254 | - should 'notify with different trackers activity create with different targets' do | |
| 254 | + should 'not group trackers activity of article\'s creation' do | |
| 255 | 255 | ActionTracker::Record.delete_all |
| 256 | 256 | |
| 257 | 257 | article = fast_create(TextileArticle) |
| ... | ... | @@ -261,28 +261,15 @@ class ApproveArticleTest < ActiveSupport::TestCase |
| 261 | 261 | article = fast_create(TextileArticle) |
| 262 | 262 | a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => community, :requestor => profile) |
| 263 | 263 | a.finish |
| 264 | - assert_equal 1, ActionTracker::Record.count | |
| 265 | 264 | |
| 266 | 265 | article = fast_create(TextileArticle) |
| 267 | 266 | other_community = fast_create(Community) |
| 268 | 267 | a = ApproveArticle.create!(:name => 'another bar', :article => article, :target => other_community, :requestor => profile) |
| 269 | 268 | a.finish |
| 270 | - assert_equal 2, ActionTracker::Record.count | |
| 271 | - end | |
| 272 | - | |
| 273 | - should 'notify activity on update' do | |
| 274 | - ActionTracker::Record.delete_all | |
| 275 | - a = ApproveArticle.create!(:name => 'bar', :article => article, :target => community, :requestor => profile) | |
| 276 | - a.finish | |
| 277 | - assert_equal 1, ActionTracker::Record.count | |
| 278 | - | |
| 279 | - published = article.class.last | |
| 280 | - published.name = 'foo' | |
| 281 | - published.save! | |
| 282 | - assert_equal 2, ActionTracker::Record.count | |
| 269 | + assert_equal 3, ActionTracker::Record.count | |
| 283 | 270 | end |
| 284 | 271 | |
| 285 | - should 'notify with different trackers activity update with different targets' do | |
| 272 | + should 'not create trackers activity when updating articles' do | |
| 286 | 273 | ActionTracker::Record.delete_all |
| 287 | 274 | article1 = fast_create(TextileArticle) |
| 288 | 275 | a = ApproveArticle.create!(:name => 'bar', :article => article1, :target => community, :requestor => profile) |
| ... | ... | @@ -294,16 +281,16 @@ class ApproveArticleTest < ActiveSupport::TestCase |
| 294 | 281 | a.finish |
| 295 | 282 | assert_equal 2, ActionTracker::Record.count |
| 296 | 283 | |
| 297 | - published = article1.class.last | |
| 298 | - published.name = 'foo';published.save! | |
| 299 | - assert_equal 3, ActionTracker::Record.count | |
| 300 | - | |
| 301 | - published = article2.class.last | |
| 302 | - published.name = 'another foo';published.save! | |
| 303 | - assert_equal 4, ActionTracker::Record.count | |
| 284 | + assert_no_difference ActionTracker::Record, :count do | |
| 285 | + published = article1.class.last | |
| 286 | + published.name = 'foo';published.save! | |
| 287 | + | |
| 288 | + published = article2.class.last | |
| 289 | + published.name = 'another foo';published.save! | |
| 290 | + end | |
| 304 | 291 | end |
| 305 | 292 | |
| 306 | - should "the tracker action target be defined as Community by custom_target method on articles'creation in communities" do | |
| 293 | + should "the tracker action target be defined as the article on articles'creation in communities" do | |
| 307 | 294 | ActionTracker::Record.delete_all |
| 308 | 295 | person = fast_create(Person) |
| 309 | 296 | community.add_member(person) |
| ... | ... | @@ -311,17 +298,21 @@ class ApproveArticleTest < ActiveSupport::TestCase |
| 311 | 298 | a = ApproveArticle.create!(:article => article, :target => community, :requestor => profile) |
| 312 | 299 | a.finish |
| 313 | 300 | |
| 314 | - assert_equal Community, ActionTracker::Record.last.target.class | |
| 301 | + approved_article = community.articles.find_by_name(article.name) | |
| 302 | + | |
| 303 | + assert_equal approved_article, ActionTracker::Record.last.target | |
| 315 | 304 | end |
| 316 | 305 | |
| 317 | - should "the tracker action target be defined as person by custom_target method on articles'creation in profile" do | |
| 306 | + should "the tracker action target be defined as the article on articles'creation in profile" do | |
| 318 | 307 | ActionTracker::Record.delete_all |
| 319 | 308 | person = fast_create(Person) |
| 320 | 309 | |
| 321 | 310 | a = ApproveArticle.create!(:article => article, :target => person, :requestor => profile) |
| 322 | 311 | a.finish |
| 323 | 312 | |
| 324 | - assert_equal Person, ActionTracker::Record.last.target.class | |
| 313 | + approved_article = person.articles.find_by_name(article.name) | |
| 314 | + | |
| 315 | + assert_equal approved_article, ActionTracker::Record.last.target | |
| 325 | 316 | end |
| 326 | 317 | |
| 327 | 318 | should "have the same is_trackable method as original article" do | ... | ... |
test/unit/article_test.rb
| ... | ... | @@ -322,15 +322,16 @@ class ArticleTest < ActiveSupport::TestCase |
| 322 | 322 | |
| 323 | 323 | should 'list most commented articles' do |
| 324 | 324 | Article.delete_all |
| 325 | + (1..4).each do |n| | |
| 326 | + create(TextileArticle, :name => "art #{n}", :profile_id => profile.id) | |
| 327 | + end | |
| 328 | + first_article = profile.articles.first | |
| 329 | + 2.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => first_article).save! } | |
| 325 | 330 | |
| 326 | - person = create_user('testuser').person | |
| 327 | - articles = (1..4).map {|n| a = person.articles.build(:name => "art #{n}"); a.save!; a } | |
| 328 | - | |
| 329 | - 2.times { articles[0].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } | |
| 330 | - 4.times { articles[1].comments.build(:title => 'test', :body => 'asdsad', :author => person).save! } | |
| 331 | - | |
| 331 | + last_article = profile.articles.last | |
| 332 | + 4.times { Comment.create(:title => 'test', :body => 'asdsad', :author => profile, :source => last_article).save! } | |
| 332 | 333 | # should respect the order (more commented comes first) |
| 333 | - assert_equal [articles[1], articles[0]], person.articles.most_commented(2) | |
| 334 | + assert_equal [last_article, first_article], profile.articles.most_commented(2) | |
| 334 | 335 | end |
| 335 | 336 | |
| 336 | 337 | should 'identify itself as a non-folder' do |
| ... | ... | @@ -365,8 +366,8 @@ class ArticleTest < ActiveSupport::TestCase |
| 365 | 366 | should 'index comments title together with article' do |
| 366 | 367 | TestSolr.enable |
| 367 | 368 | owner = create_user('testuser').person |
| 368 | - art = owner.articles.build(:name => 'ytest'); art.save! | |
| 369 | - c1 = art.comments.build(:title => 'a nice comment', :body => 'anything', :author => owner); c1.save! | |
| 369 | + art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest') | |
| 370 | + c1 = Comment.create(:title => 'a nice comment', :body => 'anything', :author => owner, :source => art ); c1.save! | |
| 370 | 371 | |
| 371 | 372 | assert_includes Article.find_by_contents('nice')[:results], art |
| 372 | 373 | end |
| ... | ... | @@ -374,8 +375,8 @@ class ArticleTest < ActiveSupport::TestCase |
| 374 | 375 | should 'index comments body together with article' do |
| 375 | 376 | TestSolr.enable |
| 376 | 377 | owner = create_user('testuser').person |
| 377 | - art = owner.articles.build(:name => 'ytest'); art.save! | |
| 378 | - c1 = art.comments.build(:title => 'test comment', :body => 'anything', :author => owner); c1.save! | |
| 378 | + art = fast_create(TinyMceArticle, :profile_id => owner.id, :name => 'ytest') | |
| 379 | + c1 = Comment.create(:title => 'test comment', :body => 'anything', :author => owner, :source => art); c1.save! | |
| 379 | 380 | |
| 380 | 381 | assert_includes Article.find_by_contents('anything')[:results], art |
| 381 | 382 | end |
| ... | ... | @@ -953,79 +954,34 @@ class ArticleTest < ActiveSupport::TestCase |
| 953 | 954 | end |
| 954 | 955 | |
| 955 | 956 | should 'track action when a published article is created outside a community' do |
| 956 | - article = TinyMceArticle.create! :name => 'Tracked Article', :profile_id => profile.id | |
| 957 | - assert article.published? | |
| 958 | - assert_kind_of Person, article.profile | |
| 959 | - ta = ActionTracker::Record.last | |
| 960 | - assert_equal 'Tracked Article', ta.get_name.last | |
| 961 | - assert_equal article.url, ta.get_url.last | |
| 962 | - assert_kind_of Person, ta.user | |
| 963 | - ta.created_at = Time.now.ago(26.hours); ta.save! | |
| 964 | - article = TinyMceArticle.create! :name => 'Another Tracked Article', :profile_id => profile.id | |
| 965 | - ta = ActionTracker::Record.last | |
| 966 | - assert_equal ['Another Tracked Article'], ta.get_name | |
| 967 | - assert_equal [article.url], ta.get_url | |
| 957 | + article = create(TinyMceArticle, :profile_id => profile.id) | |
| 958 | + ta = article.activity | |
| 959 | + assert_equal article.name, ta.get_name | |
| 960 | + assert_equal article.url, ta.get_url | |
| 968 | 961 | end |
| 969 | 962 | |
| 970 | 963 | should 'track action when a published article is created in a community' do |
| 971 | 964 | community = fast_create(Community) |
| 972 | - p1 = ActionTracker::Record.current_user_from_model | |
| 965 | + p1 = fast_create(Person) | |
| 973 | 966 | p2 = fast_create(Person) |
| 974 | 967 | p3 = fast_create(Person) |
| 975 | 968 | community.add_member(p1) |
| 976 | 969 | community.add_member(p2) |
| 977 | - assert p1.is_member_of?(community) | |
| 978 | - assert p2.is_member_of?(community) | |
| 979 | - assert !p3.is_member_of?(community) | |
| 980 | - Article.destroy_all | |
| 981 | - ActionTracker::Record.destroy_all | |
| 982 | - article = TinyMceArticle.create! :name => 'Tracked Article', :profile_id => community.id | |
| 983 | - assert article.published? | |
| 984 | - assert_kind_of Community, article.profile | |
| 985 | - ta = ActionTracker::Record.last | |
| 986 | - assert_equal 'Tracked Article', ta.get_name.last | |
| 987 | - assert_equal article.url, ta.get_url.last | |
| 988 | - assert_kind_of Person, ta.user | |
| 970 | + UserStampSweeper.any_instance.expects(:current_user).returns(p1).at_least_once | |
| 971 | + | |
| 972 | + article = create(TinyMceArticle, :profile_id => community.id) | |
| 973 | + activity = article.activity | |
| 974 | + | |
| 989 | 975 | process_delayed_job_queue |
| 990 | - assert_equal 3, ActionTrackerNotification.count | |
| 991 | - ActionTrackerNotification.all.map{|a|a.profile}.map do |profile| | |
| 992 | - assert [p1,p2,community].include?(profile) | |
| 993 | - end | |
| 976 | + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(activity.id).count | |
| 977 | + assert_equivalent [p1,p2,community], ActionTrackerNotification.find_all_by_action_tracker_id(activity.id).map(&:profile) | |
| 994 | 978 | end |
| 995 | 979 | |
| 996 | - should 'track action when a published article is updated' do | |
| 997 | - a = TinyMceArticle.create! :name => 'a', :profile_id => profile.id | |
| 998 | - a.update_attributes! :name => 'b' | |
| 999 | - ta = ActionTracker::Record.last | |
| 1000 | - assert_equal ['b'], ta.get_name | |
| 1001 | - assert_equal [a.reload.url], ta.get_url | |
| 1002 | - a.update_attributes! :name => 'c' | |
| 1003 | - ta = ActionTracker::Record.last | |
| 1004 | - assert_equal ['b','c'], ta.get_name | |
| 1005 | - assert_equal [a.url,a.reload.url], ta.get_url | |
| 1006 | - a.update_attributes! :body => 'test' | |
| 1007 | - ta = ActionTracker::Record.last | |
| 1008 | - assert_equal ['b','c','c'], ta.get_name | |
| 1009 | - assert_equal [a.url,a.reload.url,a.reload.url], ta.get_url | |
| 1010 | - a.update_attributes! :hits => 50 | |
| 1011 | - ta = ActionTracker::Record.last | |
| 1012 | - assert_equal ['b','c','c'], ta.get_name | |
| 1013 | - assert_equal [a.url,a.reload.url,a.reload.url], ta.get_url | |
| 1014 | - end | |
| 1015 | - | |
| 1016 | - should 'track action when a published article is removed' do | |
| 1017 | - a = TinyMceArticle.create! :name => 'a', :profile_id => profile.id | |
| 1018 | - a.destroy | |
| 1019 | - ta = ActionTracker::Record.last | |
| 1020 | - assert_equal ['a'], ta.get_name | |
| 1021 | - a = TinyMceArticle.create! :name => 'b', :profile_id => profile.id | |
| 1022 | - a.destroy | |
| 1023 | - ta = ActionTracker::Record.last | |
| 1024 | - assert_equal ['a','b'], ta.get_name | |
| 1025 | - a = TinyMceArticle.create! :name => 'c', :profile_id => profile.id, :published => false | |
| 1026 | - a.destroy | |
| 1027 | - ta = ActionTracker::Record.last | |
| 1028 | - assert_equal ['a','b'], ta.get_name | |
| 980 | + should 'not track action when a published article is removed' do | |
| 981 | + a = create(TinyMceArticle, :profile_id => profile.id) | |
| 982 | + assert_no_difference ActionTracker::Record, :count do | |
| 983 | + a.destroy | |
| 984 | + end | |
| 1029 | 985 | end |
| 1030 | 986 | |
| 1031 | 987 | should 'notifiable is false by default' do |
| ... | ... | @@ -1054,6 +1010,15 @@ class ArticleTest < ActiveSupport::TestCase |
| 1054 | 1010 | assert_equal 0, ActionTracker::Record.count |
| 1055 | 1011 | end |
| 1056 | 1012 | |
| 1013 | + should 'create activity' do | |
| 1014 | + a = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true | |
| 1015 | + a.activity.destroy | |
| 1016 | + assert_nil a.activity | |
| 1017 | + | |
| 1018 | + a.create_activity | |
| 1019 | + assert_not_nil a.activity | |
| 1020 | + end | |
| 1021 | + | |
| 1057 | 1022 | should "the action_tracker_target method be defined" do |
| 1058 | 1023 | assert Article.method_defined?(:action_tracker_target) |
| 1059 | 1024 | end |
| ... | ... | @@ -1090,141 +1055,64 @@ class ArticleTest < ActiveSupport::TestCase |
| 1090 | 1055 | assert_equal false, a.is_trackable? |
| 1091 | 1056 | end |
| 1092 | 1057 | |
| 1093 | - should 'not create more than one notification track action to community when update more than one artile' do | |
| 1094 | - community = fast_create(Community) | |
| 1095 | - p1 = Person.first || fast_create(Person) | |
| 1096 | - community.add_member(p1) | |
| 1097 | - assert p1.is_member_of?(community) | |
| 1098 | - Article.destroy_all | |
| 1099 | - ActionTracker::Record.destroy_all | |
| 1100 | - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => community.id | |
| 1101 | - assert article.published? | |
| 1102 | - assert_kind_of Community, article.profile | |
| 1103 | - assert_equal 1, ActionTracker::Record.count | |
| 1104 | - ta = ActionTracker::Record.last | |
| 1105 | - assert_equal 'Tracked Article 1', ta.get_name.last | |
| 1106 | - assert_equal article.url, ta.get_url.last | |
| 1107 | - assert p1, ta.user | |
| 1108 | - assert community, ta.target | |
| 1109 | - process_delayed_job_queue | |
| 1110 | - assert_equal 2, ActionTrackerNotification.count | |
| 1111 | - | |
| 1112 | - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id | |
| 1113 | - assert article.published? | |
| 1114 | - assert_kind_of Community, article.profile | |
| 1115 | - assert_equal 1, ActionTracker::Record.count | |
| 1116 | - ta = ActionTracker::Record.last | |
| 1117 | - assert_equal 'Tracked Article 2', ta.get_name.last | |
| 1118 | - assert_equal article.url, ta.get_url.last | |
| 1119 | - assert_equal p1, ta.user | |
| 1120 | - assert_equal community, ta.target | |
| 1121 | - process_delayed_job_queue | |
| 1122 | - assert_equal 2, ActionTrackerNotification.count | |
| 1058 | + should "not be trackable if article is inside a private community" do | |
| 1059 | + private_community = fast_create(Community, :public_profile => false) | |
| 1060 | + a = fast_create(TinyMceArticle, :profile_id => private_community.id) | |
| 1061 | + assert_equal false, a.is_trackable? | |
| 1123 | 1062 | end |
| 1124 | 1063 | |
| 1125 | - should 'create the notification to the member when one member has the notification and the other no' do | |
| 1064 | + should 'create the notification to organization and all organization members' do | |
| 1126 | 1065 | community = fast_create(Community) |
| 1127 | - p1 = Person.first || fast_create(Person) | |
| 1128 | - community.add_member(p1) | |
| 1129 | - assert p1.is_member_of?(community) | |
| 1130 | - Article.destroy_all | |
| 1131 | - ActionTracker::Record.destroy_all | |
| 1066 | + member_1 = Person.first | |
| 1067 | + community.add_member(member_1) | |
| 1068 | + | |
| 1132 | 1069 | article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => community.id |
| 1133 | - assert article.published? | |
| 1134 | - assert_kind_of Community, article.profile | |
| 1135 | - assert_equal 1, ActionTracker::Record.count | |
| 1136 | - ta = ActionTracker::Record.first | |
| 1137 | - assert_equal 'Tracked Article 1', ta.get_name.last | |
| 1138 | - assert_equal article.url, ta.get_url.last | |
| 1139 | - assert p1, ta.user | |
| 1140 | - assert community, ta.target | |
| 1141 | - process_delayed_job_queue | |
| 1142 | - assert_equal 2, ActionTrackerNotification.count | |
| 1070 | + first_activity = article.activity | |
| 1071 | + assert_equal [first_activity], ActionTracker::Record.find_all_by_verb('create_article') | |
| 1143 | 1072 | |
| 1144 | - p2 = fast_create(Person) | |
| 1145 | - community.add_member(p2) | |
| 1146 | 1073 | process_delayed_job_queue |
| 1147 | - assert_equal 5, ActionTrackerNotification.count | |
| 1148 | - | |
| 1149 | - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id | |
| 1150 | - assert article.published? | |
| 1151 | - assert_kind_of Community, article.profile | |
| 1152 | - assert_equal 3, ActionTracker::Record.count | |
| 1153 | - ta = ActionTracker::Record.first | |
| 1154 | - assert_equal 'Tracked Article 2', ta.get_name.last | |
| 1155 | - assert_equal article.url, ta.get_url.last | |
| 1156 | - assert_equal p1, ta.user | |
| 1157 | - assert_equal community, ta.target | |
| 1074 | + assert_equal 2, ActionTrackerNotification.find_all_by_action_tracker_id(first_activity.id).count | |
| 1075 | + | |
| 1076 | + member_2 = fast_create(Person) | |
| 1077 | + community.add_member(member_2) | |
| 1078 | + | |
| 1079 | + article2 = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => community.id | |
| 1080 | + second_activity = article2.activity | |
| 1081 | + assert_equivalent [first_activity, second_activity], ActionTracker::Record.find_all_by_verb('create_article') | |
| 1082 | + | |
| 1158 | 1083 | process_delayed_job_queue |
| 1159 | - assert_equal 6, ActionTrackerNotification.count | |
| 1084 | + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(second_activity.id).count | |
| 1160 | 1085 | end |
| 1161 | 1086 | |
| 1162 | - should 'not create more than one notification track action to friends when update more than one artile' do | |
| 1163 | - p1 = Person.first || fast_create(Person) | |
| 1087 | + should 'create notifications to friends when creating an article' do | |
| 1164 | 1088 | friend = fast_create(Person) |
| 1165 | - p1.add_friend(friend) | |
| 1089 | + profile.add_friend(friend) | |
| 1166 | 1090 | Article.destroy_all |
| 1167 | 1091 | ActionTracker::Record.destroy_all |
| 1168 | 1092 | ActionTrackerNotification.destroy_all |
| 1169 | - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => p1.id | |
| 1170 | - assert article.published? | |
| 1171 | - assert_kind_of Person, article.profile | |
| 1172 | - assert_equal 1, ActionTracker::Record.count | |
| 1173 | - ta = ActionTracker::Record.last | |
| 1174 | - assert_equal 'Tracked Article 1', ta.get_name.last | |
| 1175 | - assert_equal article.url, ta.get_url.last | |
| 1176 | - assert p1, ta.user | |
| 1177 | - assert p1, ta.target | |
| 1178 | - process_delayed_job_queue | |
| 1179 | - assert_equal 2, ActionTrackerNotification.count | |
| 1180 | - | |
| 1181 | - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => p1.id | |
| 1182 | - assert article.published? | |
| 1183 | - assert_kind_of Person, article.profile | |
| 1184 | - assert_equal 1, ActionTracker::Record.count | |
| 1185 | - ta = ActionTracker::Record.last | |
| 1186 | - assert_equal 'Tracked Article 2', ta.get_name.last | |
| 1187 | - assert_equal article.url, ta.get_url.last | |
| 1188 | - assert_equal p1, ta.user | |
| 1189 | - assert_equal p1, ta.target | |
| 1093 | + UserStampSweeper.any_instance.expects(:current_user).returns(profile).at_least_once | |
| 1094 | + article = create(TinyMceArticle, :profile_id => profile.id) | |
| 1095 | + | |
| 1190 | 1096 | process_delayed_job_queue |
| 1191 | - assert_equal 2, ActionTrackerNotification.count | |
| 1097 | + assert_equal friend, ActionTrackerNotification.last.profile | |
| 1192 | 1098 | end |
| 1193 | 1099 | |
| 1194 | 1100 | should 'create the notification to the friend when one friend has the notification and the other no' do |
| 1195 | - p1 = Person.first || fast_create(Person) | |
| 1196 | 1101 | f1 = fast_create(Person) |
| 1197 | - p1.add_friend(f1) | |
| 1198 | - Article.destroy_all | |
| 1199 | - ActionTracker::Record.destroy_all | |
| 1200 | - ActionTrackerNotification.destroy_all | |
| 1201 | - article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => p1.id | |
| 1202 | - assert article.published? | |
| 1203 | - assert_kind_of Person, article.profile | |
| 1204 | - assert_equal 1, ActionTracker::Record.count | |
| 1205 | - ta = ActionTracker::Record.first | |
| 1206 | - assert_equal 'Tracked Article 1', ta.get_name.last | |
| 1207 | - assert_equal article.url, ta.get_url.last | |
| 1208 | - assert p1, ta.user | |
| 1209 | - assert p1, ta.target | |
| 1102 | + profile.add_friend(f1) | |
| 1103 | + | |
| 1104 | + UserStampSweeper.any_instance.expects(:current_user).returns(profile).at_least_once | |
| 1105 | + article = TinyMceArticle.create! :name => 'Tracked Article 1', :profile_id => profile.id | |
| 1106 | + assert_equal 1, ActionTracker::Record.find_all_by_verb('create_article').count | |
| 1210 | 1107 | process_delayed_job_queue |
| 1211 | - assert_equal 2, ActionTrackerNotification.count | |
| 1108 | + assert_equal 2, ActionTrackerNotification.find_all_by_action_tracker_id(article.activity.id).count | |
| 1212 | 1109 | |
| 1213 | 1110 | f2 = fast_create(Person) |
| 1214 | - p1.add_friend(f2) | |
| 1215 | - process_delayed_job_queue | |
| 1216 | - assert_equal 5, ActionTrackerNotification.count | |
| 1217 | - article = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => p1.id | |
| 1218 | - assert article.published? | |
| 1219 | - assert_kind_of Person, article.profile | |
| 1220 | - assert_equal 2, ActionTracker::Record.count | |
| 1221 | - ta = ActionTracker::Record.first | |
| 1222 | - assert_equal 'Tracked Article 2', ta.get_name.last | |
| 1223 | - assert_equal article.url, ta.get_url.last | |
| 1224 | - assert_equal p1, ta.user | |
| 1225 | - assert_equal p1, ta.target | |
| 1111 | + profile.add_friend(f2) | |
| 1112 | + article2 = TinyMceArticle.create! :name => 'Tracked Article 2', :profile_id => profile.id | |
| 1113 | + assert_equal 2, ActionTracker::Record.find_all_by_verb('create_article').count | |
| 1226 | 1114 | process_delayed_job_queue |
| 1227 | - assert_equal 6, ActionTrackerNotification.count | |
| 1115 | + assert_equal 3, ActionTrackerNotification.find_all_by_action_tracker_id(article2.activity.id).count | |
| 1228 | 1116 | end |
| 1229 | 1117 | |
| 1230 | 1118 | should 'found articles with published date between a range' do |
| ... | ... | @@ -1582,7 +1470,7 @@ class ArticleTest < ActiveSupport::TestCase |
| 1582 | 1470 | domain = Environment.default.domains.first || Domain.new(:name => 'localhost') |
| 1583 | 1471 | article = Article.new(:body => "An article with invalid src in img tag <img src='path with spaces.png' />", :profile => @profile) |
| 1584 | 1472 | assert_nothing_raised URI::InvalidURIError do |
| 1585 | - assert_equal ["http://#{domain.name}/path%20with%20spaces.png"], article.body_images_paths | |
| 1473 | + assert_equal ["http://#{profile.environment.default_hostname}/path%20with%20spaces.png"], article.body_images_paths | |
| 1586 | 1474 | end |
| 1587 | 1475 | end |
| 1588 | 1476 | |
| ... | ... | @@ -1814,4 +1702,24 @@ class ArticleTest < ActiveSupport::TestCase |
| 1814 | 1702 | assert !a.allow_edit?(nil) |
| 1815 | 1703 | end |
| 1816 | 1704 | |
| 1705 | + should 'get first image from lead' do | |
| 1706 | + a = fast_create(Article, :body => '<p>Foo</p><p><img src="bar.png" />Bar<img src="foo.png" /></p>', | |
| 1707 | + :abstract => '<p>Lead</p><p><img src="leadbar.png" />Bar<img src="leadfoo.png" /></p>') | |
| 1708 | + assert_equal 'leadbar.png', a.first_image | |
| 1709 | + end | |
| 1710 | + | |
| 1711 | + should 'get first image from body' do | |
| 1712 | + a = fast_create(Article, :body => '<p>Foo</p><p><img src="bar.png" />Bar<img src="foo.png" /></p>') | |
| 1713 | + assert_equal 'bar.png', a.first_image | |
| 1714 | + end | |
| 1715 | + | |
| 1716 | + should 'not get first image from anywhere' do | |
| 1717 | + a = fast_create(Article, :body => '<p>Foo</p><p>Bar</p>') | |
| 1718 | + assert_equal '', a.first_image | |
| 1719 | + end | |
| 1720 | + | |
| 1721 | + should 'store first image in tracked action' do | |
| 1722 | + a = TinyMceArticle.create! :name => 'Tracked Article', :body => '<p>Foo<img src="foo.png" />Bar</p>', :profile_id => profile.id | |
| 1723 | + assert_equal 'foo.png', ActionTracker::Record.last.get_first_image | |
| 1724 | + end | |
| 1817 | 1725 | end | ... | ... |
test/unit/category_test.rb
| ... | ... | @@ -311,10 +311,10 @@ class CategoryTest < ActiveSupport::TestCase |
| 311 | 311 | a2 = person.articles.build(:name => 'art2', :category_ids => [c.id]); a2.save! |
| 312 | 312 | a3 = person.articles.build(:name => 'art3', :category_ids => [c.id]); a3.save! |
| 313 | 313 | |
| 314 | - a1.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! | |
| 315 | - 5.times { a2.comments.build(:title => 'test', :body => 'asdsa', :author => person).save! } | |
| 314 | + Comment.create(:title => 'test', :body => 'asdsa', :author => person, :source => a1) | |
| 315 | + 5.times { Comment.create(:title => 'test', :body => 'asdsa', :author => person, :source => a2) } | |
| 316 | 316 | |
| 317 | - 10.times { a3.comments.build(:title => 'test', :body => 'kajsdsa', :author => person).save! } | |
| 317 | + 10.times { Comment.create(:title => 'test', :body => 'kajsdsa', :author => person, :source => a3) } | |
| 318 | 318 | |
| 319 | 319 | assert_equal [a3, a2], c.most_commented_articles(2) |
| 320 | 320 | end | ... | ... |
test/unit/comment_notifier_test.rb
| ... | ... | @@ -12,26 +12,26 @@ class CommentNotifierTest < ActiveSupport::TestCase |
| 12 | 12 | @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true) |
| 13 | 13 | end |
| 14 | 14 | |
| 15 | - should 'deliver mail after make aarticle commment' do | |
| 15 | + should 'deliver mail after make an article comment' do | |
| 16 | 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 | 18 | end |
| 19 | 19 | end |
| 20 | 20 | |
| 21 | 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 | 23 | sent = ActionMailer::Base.deliveries.first |
| 24 | 24 | assert_equal [@profile.email], sent.to |
| 25 | 25 | end |
| 26 | 26 | |
| 27 | 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 | 29 | sent = ActionMailer::Base.deliveries.first |
| 30 | 30 | assert_match /user_comment_test/, sent.body |
| 31 | 31 | end |
| 32 | 32 | |
| 33 | 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 | 35 | sent = ActionMailer::Base.deliveries.first |
| 36 | 36 | assert_match /flatline/, sent.body |
| 37 | 37 | assert_match /flatline@invalid.com/, sent.body |
| ... | ... | @@ -45,13 +45,13 @@ class CommentNotifierTest < ActiveSupport::TestCase |
| 45 | 45 | end |
| 46 | 46 | |
| 47 | 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 | 49 | sent = ActionMailer::Base.deliveries.first |
| 50 | 50 | assert_match /comment title/, sent.body |
| 51 | 51 | end |
| 52 | 52 | |
| 53 | 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 | 55 | sent = ActionMailer::Base.deliveries.first |
| 56 | 56 | assert_match /comment body/, sent.body |
| 57 | 57 | end | ... | ... |
test/unit/comment_test.rb
| ... | ... | @@ -13,13 +13,13 @@ class CommentTest < ActiveSupport::TestCase |
| 13 | 13 | assert_mandatory(Comment.new, :body) |
| 14 | 14 | end |
| 15 | 15 | |
| 16 | - should 'belong to an article' do | |
| 16 | + should 'have a polymorphic relationship with source' do | |
| 17 | 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 | 20 | end |
| 21 | 21 | assert_nothing_raised do |
| 22 | - c.article = Article.new | |
| 22 | + c.source = ActionTracker::Record.new | |
| 23 | 23 | end |
| 24 | 24 | end |
| 25 | 25 | |
| ... | ... | @@ -65,12 +65,33 @@ class CommentTest < ActiveSupport::TestCase |
| 65 | 65 | |
| 66 | 66 | should 'update counter cache in article' do |
| 67 | 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 | 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 | 95 | end |
| 75 | 96 | |
| 76 | 97 | should 'provide author name for authenticated authors' do |
| ... | ... | @@ -217,30 +238,10 @@ class CommentTest < ActiveSupport::TestCase |
| 217 | 238 | assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist." |
| 218 | 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 | 241 | should 'have the action_tracker_target defined' do |
| 233 | 242 | assert Comment.method_defined?(:action_tracker_target) |
| 234 | 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 | 245 | should "get children of a comment" do |
| 245 | 246 | c = fast_create(Comment) |
| 246 | 247 | c1 = fast_create(Comment, :reply_of_id => c.id) |
| ... | ... | @@ -307,11 +308,11 @@ class CommentTest < ActiveSupport::TestCase |
| 307 | 308 | |
| 308 | 309 | should "return comments as a thread" do |
| 309 | 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 | 316 | result = a.comments.as_thread |
| 316 | 317 | assert_equal c0.id, result[0].id |
| 317 | 318 | assert_equal [c1.id, c3.id], result[0].replies.map(&:id) |
| ... | ... | @@ -320,6 +321,22 @@ class CommentTest < ActiveSupport::TestCase |
| 320 | 321 | assert result[1].replies.empty? |
| 321 | 322 | end |
| 322 | 323 | |
| 324 | + should "return activities comments as a thread" do | |
| 325 | + person = fast_create(Person) | |
| 326 | + a = TextileArticle.create!(:profile => person, :name => 'My article', :body => 'Article body') | |
| 327 | + c0 = Comment.create!(:source => a, :body => 'My comment', :author => person) | |
| 328 | + c1 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person) | |
| 329 | + c2 = Comment.create!(:reply_of_id => c1.id, :source => a, :body => 'bla', :author => person) | |
| 330 | + c3 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person) | |
| 331 | + c4 = Comment.create!(:source => a, :body => 'My comment', :author => person) | |
| 332 | + result = a.activity.comments_as_thread | |
| 333 | + assert_equal c0, result[0] | |
| 334 | + assert_equal [c1, c3], result[0].replies | |
| 335 | + assert_equal [c2], result[0].replies[0].replies | |
| 336 | + assert_equal c4, result[1] | |
| 337 | + assert result[1].replies.empty? | |
| 338 | + end | |
| 339 | + | |
| 323 | 340 | should 'provide author url for authenticated user' do |
| 324 | 341 | author = Person.new |
| 325 | 342 | author.expects(:url).returns('http://blabla.net/author') |
| ... | ... | @@ -338,4 +355,27 @@ class CommentTest < ActiveSupport::TestCase |
| 338 | 355 | assert c.rejected? |
| 339 | 356 | end |
| 340 | 357 | |
| 358 | + should 'update article activity when add a comment' do | |
| 359 | + profile = create_user('testuser').person | |
| 360 | + article = create(TinyMceArticle, :profile => profile) | |
| 361 | + action = article.activity | |
| 362 | + time = action.updated_at | |
| 363 | + | |
| 364 | + Time.stubs(:now).returns(time + 1.day) | |
| 365 | + | |
| 366 | + comment = create(Comment, :source => article, :author => profile) | |
| 367 | + assert_equal time + 1.day, article.activity.updated_at | |
| 368 | + end | |
| 369 | + | |
| 370 | + should 'create a new activity when add a comment and the activity was removed' do | |
| 371 | + profile = create_user('testuser').person | |
| 372 | + article = create(TinyMceArticle, :profile => profile) | |
| 373 | + article.activity.destroy | |
| 374 | + | |
| 375 | + assert_nil article.activity | |
| 376 | + | |
| 377 | + comment = create(Comment, :source => article, :author => profile) | |
| 378 | + assert_not_nil article.activity | |
| 379 | + end | |
| 380 | + | |
| 341 | 381 | end | ... | ... |
test/unit/community_test.rb
| ... | ... | @@ -274,22 +274,19 @@ class CommunityTest < ActiveSupport::TestCase |
| 274 | 274 | end |
| 275 | 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 | 278 | ActionTrackerNotification.delete_all |
| 279 | 279 | p1 = Person.first |
| 280 | 280 | community = fast_create(Community) |
| 281 | 281 | p2 = fast_create(Person) |
| 282 | 282 | p3 = fast_create(Person) |
| 283 | 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 | 290 | end |
| 294 | 291 | |
| 295 | 292 | should "see get all received scraps" do |
| ... | ... | @@ -341,4 +338,35 @@ class CommunityTest < ActiveSupport::TestCase |
| 341 | 338 | assert_equal false, community.receives_scrap_notification? |
| 342 | 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 | 372 | end | ... | ... |
test/unit/enterprise_test.rb
| ... | ... | @@ -470,4 +470,36 @@ class EnterpriseTest < ActiveSupport::TestCase |
| 470 | 470 | ent.save! |
| 471 | 471 | end |
| 472 | 472 | |
| 473 | + should 'return scraps as activities' do | |
| 474 | + person = fast_create(Person) | |
| 475 | + enterprise = fast_create(Enterprise) | |
| 476 | + | |
| 477 | + | |
| 478 | + activity = ActionTracker::Record.last | |
| 479 | + scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => enterprise, :content => 'A scrap')) | |
| 480 | + | |
| 481 | + assert_equal [scrap], enterprise.activities.map { |a| a.klass.constantize.find(a.id) } | |
| 482 | + end | |
| 483 | + | |
| 484 | + should 'return tracked_actions of community as activities' do | |
| 485 | + person = fast_create(Person) | |
| 486 | + enterprise = fast_create(Enterprise) | |
| 487 | + | |
| 488 | + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once | |
| 489 | + article = create(TinyMceArticle, :profile => enterprise, :name => 'An article about free software') | |
| 490 | + | |
| 491 | + assert_equal [article.activity], enterprise.activities.map { |a| a.klass.constantize.find(a.id) } | |
| 492 | + end | |
| 493 | + | |
| 494 | + should 'not return tracked_actions of other community as activities' do | |
| 495 | + person = fast_create(Person) | |
| 496 | + enterprise = fast_create(Enterprise) | |
| 497 | + enterprise2 = fast_create(Enterprise) | |
| 498 | + | |
| 499 | + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once | |
| 500 | + article = create(TinyMceArticle, :profile => enterprise2, :name => 'Another article about free software') | |
| 501 | + | |
| 502 | + assert_not_includes enterprise.activities.map { |a| a.klass.constantize.find(a.id) }, article.activity | |
| 503 | + end | |
| 504 | + | |
| 473 | 505 | end | ... | ... |
test/unit/event_test.rb
test/unit/forum_helper_test.rb
| ... | ... | @@ -65,7 +65,7 @@ class ForumHelperTest < ActiveSupport::TestCase |
| 65 | 65 | some_post.comments << Comment.new(:name => 'John', :email => 'lenon@example.com', :title => 'test', :body => 'test') |
| 66 | 66 | c = Comment.last |
| 67 | 67 | out = last_topic_update(some_post) |
| 68 | - assert_match "#{c.created_at.to_s} ago by John", out | |
| 68 | + assert_match "#{c.created_at.to_s} by John", out | |
| 69 | 69 | assert_match 'John', out |
| 70 | 70 | |
| 71 | 71 | assert_match(/#{Regexp.escape(c.created_at.to_s)} ago by John/m, last_topic_update(some_post)) | ... | ... |
test/unit/forum_test.rb
| ... | ... | @@ -28,21 +28,21 @@ class ForumTest < ActiveSupport::TestCase |
| 28 | 28 | |
| 29 | 29 | should 'create rss feed automatically' do |
| 30 | 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 | 32 | assert_kind_of RssFeed, b.feed |
| 33 | 33 | end |
| 34 | 34 | |
| 35 | 35 | should 'save feed options' do |
| 36 | 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 | 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 | 40 | end |
| 41 | 41 | |
| 42 | 42 | should 'save feed options after create forum' do |
| 43 | 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 | 46 | end |
| 47 | 47 | |
| 48 | 48 | should 'list 5 posts per page by default' do |
| ... | ... | @@ -52,16 +52,15 @@ class ForumTest < ActiveSupport::TestCase |
| 52 | 52 | |
| 53 | 53 | should 'update posts per page setting' do |
| 54 | 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 | 56 | forum.posts_per_page = 7 |
| 58 | 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 | 59 | end |
| 61 | 60 | |
| 62 | 61 | should 'has posts' do |
| 63 | 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 | 64 | post = fast_create(TextileArticle, :name => 'First post', :profile_id => p.id, :parent_id => forum.id) |
| 66 | 65 | forum.children << post |
| 67 | 66 | assert_includes forum.posts, post |
| ... | ... | @@ -69,7 +68,7 @@ class ForumTest < ActiveSupport::TestCase |
| 69 | 68 | |
| 70 | 69 | should 'not includes rss feed in posts' do |
| 71 | 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 | 72 | assert_includes forum.children, forum.feed |
| 74 | 73 | assert_not_includes forum.posts, forum.feed |
| 75 | 74 | end |
| ... | ... | @@ -89,13 +88,13 @@ class ForumTest < ActiveSupport::TestCase |
| 89 | 88 | p = create_user('testuser').person |
| 90 | 89 | fast_create(Forum, :name => 'Forum test', :profile_id => p.id) |
| 91 | 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 | 92 | end |
| 94 | 93 | end |
| 95 | 94 | |
| 96 | 95 | should 'not update slug from name for existing forum' do |
| 97 | 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 | 98 | assert_equal 'forum-test', forum.slug |
| 100 | 99 | forum.name = 'Changed name' |
| 101 | 100 | assert_not_equal 'changed-name', forum.slug |
| ... | ... | @@ -110,4 +109,28 @@ class ForumTest < ActiveSupport::TestCase |
| 110 | 109 | assert !folder.accept_uploads? |
| 111 | 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 | 136 | end | ... | ... |
test/unit/notify_activity_to_profiles_job_test.rb
| ... | ... | @@ -24,28 +24,6 @@ class NotifyActivityToProfilesJobTest < ActiveSupport::TestCase |
| 24 | 24 | end |
| 25 | 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 | 27 | should 'notify just the users and his friends tracking user actions' do |
| 50 | 28 | person = fast_create(Person) |
| 51 | 29 | community = fast_create(Community) |
| ... | ... | @@ -132,36 +110,14 @@ class NotifyActivityToProfilesJobTest < ActiveSupport::TestCase |
| 132 | 110 | end |
| 133 | 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 | 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 | 115 | assert_equal [], notify_community_verbs - NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY |
| 160 | 116 | assert_equal [], NotifyActivityToProfilesJob::NOTIFY_ONLY_COMMUNITY - notify_community_verbs |
| 161 | 117 | end |
| 162 | 118 | |
| 163 | 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 | 121 | assert_equal [], not_notify_community_verbs - NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY |
| 166 | 122 | assert_equal [], NotifyActivityToProfilesJob::NOT_NOTIFY_COMMUNITY - not_notify_community_verbs |
| 167 | 123 | end | ... | ... |
test/unit/person_test.rb
| ... | ... | @@ -1013,65 +1013,14 @@ class PersonTest < ActiveSupport::TestCase |
| 1013 | 1013 | assert has_add_member_notification |
| 1014 | 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 | 1017 | p = create_user('test_user').person |
| 1018 | 1018 | c = fast_create(Community, :name => "Foo") |
| 1019 | 1019 | c.add_member(p) |
| 1020 | 1020 | c.add_moderator(p) |
| 1021 | 1021 | ActionTracker::Record.delete_all |
| 1022 | 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 | 1024 | end |
| 1076 | 1025 | |
| 1077 | 1026 | should 'get all friends online' do |
| ... | ... | @@ -1243,4 +1192,32 @@ class PersonTest < ActiveSupport::TestCase |
| 1243 | 1192 | assert !person.visible |
| 1244 | 1193 | assert_not_equal password, person.user.password |
| 1245 | 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_equivalent [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) } | |
| 1222 | + end | |
| 1246 | 1223 | end | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -1648,7 +1648,7 @@ class ProfileTest < ActiveSupport::TestCase |
| 1648 | 1648 | |
| 1649 | 1649 | should 'have forum' do |
| 1650 | 1650 | p = fast_create(Profile) |
| 1651 | - p.articles << Forum.new(:profile => p, :name => 'forum_feed_test') | |
| 1651 | + p.articles << Forum.new(:profile => p, :name => 'forum_feed_test', :body => 'Forum test') | |
| 1652 | 1652 | assert p.has_forum? |
| 1653 | 1653 | end |
| 1654 | 1654 | |
| ... | ... | @@ -1664,9 +1664,9 @@ class ProfileTest < ActiveSupport::TestCase |
| 1664 | 1664 | |
| 1665 | 1665 | should 'get first forum when has multiple forums' do |
| 1666 | 1666 | p = fast_create(Profile) |
| 1667 | - p.forums << Forum.new(:profile => p, :name => 'Forum one') | |
| 1668 | - p.forums << Forum.new(:profile => p, :name => 'Forum two') | |
| 1669 | - p.forums << Forum.new(:profile => p, :name => 'Forum three') | |
| 1667 | + p.forums << Forum.new(:profile => p, :name => 'Forum one', :body => 'Forum test') | |
| 1668 | + p.forums << Forum.new(:profile => p, :name => 'Forum two', :body => 'Forum test') | |
| 1669 | + p.forums << Forum.new(:profile => p, :name => 'Forum three', :body => 'Forum test') | |
| 1670 | 1670 | assert_equal 'Forum one', p.forum.name |
| 1671 | 1671 | assert_equal 3, p.forums.count |
| 1672 | 1672 | end |
| ... | ... | @@ -1731,6 +1731,7 @@ class ProfileTest < ActiveSupport::TestCase |
| 1731 | 1731 | assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage) |
| 1732 | 1732 | end |
| 1733 | 1733 | |
| 1734 | + | |
| 1734 | 1735 | should 'find profiles with image' do |
| 1735 | 1736 | env = fast_create(Environment) |
| 1736 | 1737 | 2.times do |n| |
| ... | ... | @@ -1791,6 +1792,11 @@ class ProfileTest < ActiveSupport::TestCase |
| 1791 | 1792 | end |
| 1792 | 1793 | end |
| 1793 | 1794 | |
| 1795 | + should 'return empty array as activities' do | |
| 1796 | + profile = Profile.new | |
| 1797 | + assert_equal [], profile.activities | |
| 1798 | + end | |
| 1799 | + | |
| 1794 | 1800 | private |
| 1795 | 1801 | |
| 1796 | 1802 | def assert_invalid_identifier(id) | ... | ... |
test/unit/textile_article_test.rb
| ... | ... | @@ -38,80 +38,72 @@ class TextileArticleTest < ActiveSupport::TestCase |
| 38 | 38 | assert_equal 1, ActionTracker::Record.count |
| 39 | 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 | 42 | ActionTracker::Record.delete_all |
| 43 | 43 | profile = fast_create(Profile) |
| 44 | 44 | TextileArticle.create! :name => 'bar', :profile_id => profile.id, :published => true |
| 45 | 45 | TextileArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true |
| 46 | - assert_equal 1, ActionTracker::Record.count | |
| 47 | 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 | 48 | end |
| 50 | 49 | |
| 51 | - should 'notify activity on update' do | |
| 50 | + should 'not update activity on update of an article' do | |
| 52 | 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 | 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 | 64 | ActionTracker::Record.delete_all |
| 62 | 65 | a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true |
| 63 | 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 | 71 | end |
| 72 | 72 | |
| 73 | - should 'notify activity on destroy' do | |
| 73 | + should 'not notify activity on destroy' do | |
| 74 | 74 | ActionTracker::Record.delete_all |
| 75 | 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 | 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 | 82 | ActionTracker::Record.delete_all |
| 83 | 83 | a1 = TextileArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true |
| 84 | 84 | a2 = TextileArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true |
| 85 | 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 | 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 | 93 | ActionTracker::Record.delete_all |
| 94 | 94 | community = fast_create(Community) |
| 95 | 95 | p1 = Person.first |
| 96 | 96 | community.add_member(p1) |
| 97 | 97 | assert p1.is_member_of?(community) |
| 98 | 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 | 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 | 103 | ActionTracker::Record.delete_all |
| 108 | 104 | person = Person.first |
| 109 | 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 | 107 | end |
| 116 | 108 | |
| 117 | 109 | should 'not notify activity if the article is not advertise' do |
| ... | ... | @@ -129,7 +121,7 @@ class TextileArticleTest < ActiveSupport::TestCase |
| 129 | 121 | end |
| 130 | 122 | |
| 131 | 123 | should "the common trackable conditions return the correct value" do |
| 132 | - a = TextileArticle.new | |
| 124 | + a = TextileArticle.new(:profile => profile) | |
| 133 | 125 | a.published = a.advertise = true |
| 134 | 126 | assert_equal true, a.published? |
| 135 | 127 | assert_equal true, a.notifiable? | ... | ... |
test/unit/tiny_mce_article_test.rb
| ... | ... | @@ -135,80 +135,64 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
| 135 | 135 | assert_equal 1, ActionTracker::Record.count |
| 136 | 136 | end |
| 137 | 137 | |
| 138 | - should 'notify with different trackers activity create with different targets' do | |
| 138 | + should 'not group trackers activity of article\'s creation' do | |
| 139 | 139 | ActionTracker::Record.delete_all |
| 140 | 140 | profile = fast_create(Profile) |
| 141 | 141 | TinyMceArticle.create! :name => 'bar', :profile_id => profile.id, :published => true |
| 142 | 142 | TinyMceArticle.create! :name => 'another bar', :profile_id => profile.id, :published => true |
| 143 | - assert_equal 1, ActionTracker::Record.count | |
| 144 | - TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true | |
| 145 | 143 | assert_equal 2, ActionTracker::Record.count |
| 144 | + TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true | |
| 145 | + assert_equal 3, ActionTracker::Record.count | |
| 146 | 146 | end |
| 147 | 147 | |
| 148 | - should 'notify activity on update' do | |
| 148 | + should 'not update activity on update of an article' do | |
| 149 | 149 | ActionTracker::Record.delete_all |
| 150 | - a = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true | |
| 151 | - assert_equal 1, ActionTracker::Record.count | |
| 152 | - a.name = 'foo' | |
| 153 | - a.save! | |
| 154 | - assert_equal 2, ActionTracker::Record.count | |
| 150 | + profile = fast_create(Profile) | |
| 151 | + article = create(TinyMceArticle, :profile_id => profile.id) | |
| 152 | + time = article.activity.updated_at | |
| 153 | + Time.stubs(:now).returns(time + 1.day) | |
| 154 | + assert_no_difference ActionTracker::Record, :count do | |
| 155 | + article.name = 'foo' | |
| 156 | + article.save! | |
| 157 | + end | |
| 158 | + assert_equal time, article.activity.updated_at | |
| 155 | 159 | end |
| 156 | 160 | |
| 157 | - should 'notify with different trackers activity update with different targets' do | |
| 161 | + should 'not create trackers activity when updating articles' do | |
| 158 | 162 | ActionTracker::Record.delete_all |
| 159 | 163 | a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true |
| 160 | 164 | a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true |
| 161 | - assert_equal 2, ActionTracker::Record.count | |
| 162 | - a1.name = 'foo' | |
| 163 | - a1.save! | |
| 164 | - assert_equal 3, ActionTracker::Record.count | |
| 165 | - a2.name = 'another foo' | |
| 166 | - a2.save! | |
| 167 | - assert_equal 4, ActionTracker::Record.count | |
| 165 | + assert_no_difference ActionTracker::Record, :count do | |
| 166 | + a1.name = 'foo';a1.save! | |
| 167 | + a2.name = 'another foo';a2.save! | |
| 168 | + end | |
| 168 | 169 | end |
| 169 | 170 | |
| 170 | - should 'notify activity on destroy' do | |
| 171 | - ActionTracker::Record.delete_all | |
| 172 | - a = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true | |
| 173 | - assert_equal 1, ActionTracker::Record.count | |
| 174 | - a.destroy | |
| 175 | - assert_equal 2, ActionTracker::Record.count | |
| 176 | - end | |
| 177 | - | |
| 178 | - should 'notify different activities when destroy articles with diferrents targets' do | |
| 171 | + should 'not notify when an article is destroyed' do | |
| 179 | 172 | ActionTracker::Record.delete_all |
| 180 | 173 | a1 = TinyMceArticle.create! :name => 'bar', :profile_id => fast_create(Profile).id, :published => true |
| 181 | 174 | a2 = TinyMceArticle.create! :name => 'another bar', :profile_id => fast_create(Profile).id, :published => true |
| 182 | - assert_equal 2, ActionTracker::Record.count | |
| 183 | - a1.destroy | |
| 184 | - assert_equal 3, ActionTracker::Record.count | |
| 185 | - a2.destroy | |
| 186 | - assert_equal 4, ActionTracker::Record.count | |
| 175 | + assert_no_difference ActionTracker::Record, :count do | |
| 176 | + a1.destroy | |
| 177 | + a2.destroy | |
| 178 | +end | |
| 187 | 179 | end |
| 188 | 180 | |
| 189 | - should "the tracker action target be defined as Community by custom_target method on articles'creation in communities" do | |
| 181 | + should "the tracker action target be defined as the article on articles'creation in communities" do | |
| 190 | 182 | ActionTracker::Record.delete_all |
| 191 | 183 | community = fast_create(Community) |
| 192 | 184 | p1 = Person.first |
| 193 | 185 | community.add_member(p1) |
| 194 | 186 | assert p1.is_member_of?(community) |
| 195 | 187 | article = TinyMceArticle.create! :name => 'test', :profile_id => community.id |
| 196 | - assert_equal true, article.published? | |
| 197 | - assert_equal true, article.notifiable? | |
| 198 | - assert_equal false, article.image? | |
| 199 | - assert_equal Community, article.profile.class | |
| 200 | - assert_equal Community, ActionTracker::Record.last.target.class | |
| 188 | + assert_equal article, ActionTracker::Record.last.target | |
| 201 | 189 | end |
| 202 | 190 | |
| 203 | - should "the tracker action target be defined as person by custom_target method on articles'creation in profile" do | |
| 191 | + should "the tracker action target be defined as the article on articles'creation in profile" do | |
| 204 | 192 | ActionTracker::Record.delete_all |
| 205 | 193 | person = Person.first |
| 206 | 194 | article = TinyMceArticle.create! :name => 'test', :profile_id => person.id |
| 207 | - assert_equal true, article.published? | |
| 208 | - assert_equal true, article.notifiable? | |
| 209 | - assert_equal false, article.image? | |
| 210 | - assert_equal Person, article.profile.class | |
| 211 | - assert_equal person, ActionTracker::Record.last.target | |
| 195 | + assert_equal article, ActionTracker::Record.last.target | |
| 212 | 196 | end |
| 213 | 197 | |
| 214 | 198 | should 'not notify activity if the article is not advertise' do |
| ... | ... | @@ -226,7 +210,7 @@ class TinyMceArticleTest < ActiveSupport::TestCase |
| 226 | 210 | end |
| 227 | 211 | |
| 228 | 212 | should "the common trackable conditions return the correct value" do |
| 229 | - a = TinyMceArticle.new | |
| 213 | + a = TinyMceArticle.new(:profile => profile) | |
| 230 | 214 | a.published = a.advertise = true |
| 231 | 215 | assert_equal true, a.published? |
| 232 | 216 | assert_equal true, a.notifiable? | ... | ... |
test/unit/uploaded_file_test.rb
| ... | ... | @@ -231,10 +231,10 @@ class UploadedFileTest < ActiveSupport::TestCase |
| 231 | 231 | should 'return a thumbnail for images' do |
| 232 | 232 | f = UploadedFile.new |
| 233 | 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 | 235 | assert_equal '/images/0000/0005/x.png', f.thumbnail_path |
| 236 | 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 | 238 | f.expects(:image?).returns(false) |
| 239 | 239 | assert_nil f.thumbnail_path |
| 240 | 240 | end |
| ... | ... | @@ -330,4 +330,11 @@ class UploadedFileTest < ActiveSupport::TestCase |
| 330 | 330 | assert_equal 'hello_world.php.txt', file.filename |
| 331 | 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 | 340 | end | ... | ... |
vendor/plugins/access_control/lib/role_assignment.rb
| ... | ... | @@ -9,10 +9,6 @@ class RoleAssignment < ActiveRecord::Base |
| 9 | 9 | |
| 10 | 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 | 12 | def has_permission?(perm, res) |
| 17 | 13 | return false unless role.has_permission?(perm.to_s) && (resource || is_global) |
| 18 | 14 | return true if is_global | ... | ... |
vendor/plugins/action_tracker/lib/action_tracker_model.rb
| ... | ... | @@ -0,0 +1,23 @@ |
| 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 | + def comments_as_thread | |
| 13 | + result = {} | |
| 14 | + root = [] | |
| 15 | + self.comments.each do |c| | |
| 16 | + c.replies = [] | |
| 17 | + result[c.id] ||= c | |
| 18 | + c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c | |
| 19 | + end | |
| 20 | + root | |
| 21 | + end | |
| 22 | + | |
| 23 | +end | ... | ... |
vendor/plugins/active_record_counter_cache_on_polymorphic_association/init.rb
0 → 100644
| ... | ... | @@ -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 | ... | ... |