Commit f31c657e98f20ac22457d6de4feb9d000e00aeab
1 parent
0d1b2d3f
Exists in
master
and in
28 other branches
AI1826
Showing
38 changed files
with
480 additions
and
138 deletions
Show diff stats
app/controllers/public/profile_controller.rb
... | ... | @@ -14,6 +14,7 @@ class ProfileController < PublicController |
14 | 14 | if logged_in? && current_person.follows?(@profile) |
15 | 15 | @network_activities = @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) if @network_activities.empty? |
16 | 16 | @wall_items = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) |
17 | + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) | |
17 | 18 | end |
18 | 19 | @tags = profile.article_tags |
19 | 20 | unless profile.display_info_to?(user) |
... | ... | @@ -180,18 +181,29 @@ class ProfileController < PublicController |
180 | 181 | @scrap.receiver= receiver |
181 | 182 | @tab_action = params[:tab_action] |
182 | 183 | @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 | + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil? | |
184 | 185 | render :partial => 'leave_scrap' |
185 | 186 | end |
186 | 187 | |
188 | + def leave_comment_on_activity | |
189 | + @comment = Comment.new(params[:comment]) | |
190 | + @comment.author = user #'if logged_in? | |
191 | + @comment.source = ActionTracker::Record.find(params[:comment][:source_id]) | |
192 | + @tab_action = params[:tab_action] | |
193 | + @message = @comment.save ? _("Comment successfully added.") : _("You can't leave an empty comment.") | |
194 | + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil? | |
195 | + render :partial => 'leave_comment_on_activity' | |
196 | + end | |
197 | + | |
187 | 198 | def view_more_scraps |
188 | 199 | @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) |
189 | 200 | render :partial => 'profile_scraps', :locals => {:scraps => @scraps} |
190 | 201 | end |
191 | 202 | |
192 | 203 | def view_more_activities |
193 | - @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page]) | |
194 | - render :partial => 'profile_activities', :locals => {:activities => @activities} | |
204 | +# @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page]) | |
205 | + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) | |
206 | + render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} | |
195 | 207 | end |
196 | 208 | |
197 | 209 | def view_more_network_activities | ... | ... |
app/models/action_tracker_notification.rb
... | ... | @@ -3,9 +3,12 @@ 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 | |
9 | 11 | end |
10 | 12 | |
11 | 13 | ActionTracker::Record.has_many :action_tracker_notifications, :class_name => 'ActionTrackerNotification', :foreign_key => 'action_tracker_id', :dependent => :destroy |
14 | +ActionTracker::Record.has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' | ... | ... |
app/models/article.rb
... | ... | @@ -2,9 +2,7 @@ require 'hpricot' |
2 | 2 | |
3 | 3 | class Article < ActiveRecord::Base |
4 | 4 | |
5 | - track_actions :create_article, :after_create, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target | |
6 | - track_actions :update_article, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && (a.body_changed? || a.name_changed?) }, :custom_target => :action_tracker_target | |
7 | - track_actions :remove_article, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_target => :action_tracker_target | |
5 | + track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target | |
8 | 6 | |
9 | 7 | # xss_terminate plugin can't sanitize array fields |
10 | 8 | before_save :sanitize_tag_list |
... | ... | @@ -17,7 +15,7 @@ class Article < ActiveRecord::Base |
17 | 15 | |
18 | 16 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
19 | 17 | |
20 | - has_many :comments, :dependent => :destroy, :order => 'created_at asc' | |
18 | + has_many :comments, :dependent => :destroy, :order => 'created_at asc', :as => :source | |
21 | 19 | |
22 | 20 | has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ] |
23 | 21 | has_many :categories, :through => :article_categorizations |
... | ... | @@ -134,7 +132,11 @@ class Article < ActiveRecord::Base |
134 | 132 | before_update do |article| |
135 | 133 | article.advertise = true |
136 | 134 | end |
137 | - | |
135 | + | |
136 | + after_update do |article| | |
137 | + #update article's activity | |
138 | + end | |
139 | + | |
138 | 140 | # retrieves all articles belonging to the given +profile+ that are not |
139 | 141 | # sub-articles of any other article. |
140 | 142 | named_scope :top_level_for, lambda { |profile| | ... | ... |
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 | |
3 | +# track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target | |
4 | 4 | |
5 | 5 | validates_presence_of :body |
6 | - belongs_to :article, :counter_cache => true | |
6 | + | |
7 | + belongs_to :source, :foreign_key => :source_id, :counter_cache => true, :polymorphic => true | |
8 | + alias :article :source | |
9 | + alias :article= :source= | |
10 | + | |
7 | 11 | belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' |
8 | 12 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
9 | 13 | belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' |
... | ... | @@ -70,11 +74,11 @@ class Comment < ActiveRecord::Base |
70 | 74 | after_save :notify_article |
71 | 75 | after_destroy :notify_article |
72 | 76 | def notify_article |
73 | - article.comments_updated | |
77 | + article.comments_updated if article.kind_of?(Article) | |
74 | 78 | end |
75 | 79 | |
76 | 80 | after_create do |comment| |
77 | - if comment.article.notify_comments? && !comment.article.profile.notification_emails.empty? | |
81 | + if comment.source.kind_of?(Article) && comment.article.notify_comments? && !comment.article.profile.notification_emails.empty? | |
78 | 82 | Comment::Notifier.deliver_mail(comment) |
79 | 83 | end |
80 | 84 | end | ... | ... |
app/models/person.rb
... | ... | @@ -421,6 +421,10 @@ class Person < Profile |
421 | 421 | user.save! |
422 | 422 | end |
423 | 423 | |
424 | + def activities | |
425 | + 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") | |
426 | + end | |
427 | + | |
424 | 428 | protected |
425 | 429 | |
426 | 430 | def followed_by?(profile) | ... | ... |
app/models/profile.rb
app/models/scrap.rb
... | ... | @@ -11,8 +11,9 @@ class Scrap < ActiveRecord::Base |
11 | 11 | |
12 | 12 | named_scope :not_replies, :conditions => {:scrap_id => nil} |
13 | 13 | |
14 | - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.receiver != s.sender}, :custom_target => :action_tracker_target | |
15 | - track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.receiver == s.sender} | |
14 | +######### COMO OS AMIGOS VÃO SABER Q O AMIGO RECEBEU COMENTÁRIO? ACHO QUE TEM QUE TER AÇÃO | |
15 | +# 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 | |
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| |
18 | 19 | scrap.root.update_attribute('updated_at', DateTime.now) unless scrap.root.nil? | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => {:activity => activity} %> | ... | ... |
... | ... | @@ -0,0 +1,61 @@ |
1 | +<li class="article-comment" style='border-bottom:none;'> | |
2 | + <div class="article-comment-inner"> | |
3 | + | |
4 | + <div class="comment-content comment-logged-in"> | |
5 | + | |
6 | + <%# if comment.author %> | |
7 | + <%= link_to image_tag(profile_icon(comment.author, :minor)) + | |
8 | + content_tag('span', comment.author_name, :class => 'comment-info'), | |
9 | + comment.author.url, | |
10 | + :class => 'comment-picture', | |
11 | + :title => comment.author_name | |
12 | + %> | |
13 | + <%# end %> | |
14 | + | |
15 | + <div class="comment-details"> | |
16 | + <h4><%= comment.title %></h4> | |
17 | + <div class="comment-text"> | |
18 | + <p/> | |
19 | + <%= txt2html comment.body %> | |
20 | + </div> | |
21 | + <div class="profile-activity-time"> | |
22 | + <%= show_time(comment.created_at) %> | |
23 | + </div> | |
24 | + </div> | |
25 | + | |
26 | + <%# if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) %> | |
27 | + <% button_bar(:style => 'float: right; margin-top: 0px;') do %> | |
28 | + <%= icon_button(:delete, _('Remove this comment and all its replies'), { :profile => params[:profile], :remove_comment => comment.id, :view => params[:view] }, :method => :post, :confirm => _('Are you sure you want to remove this comment and all its replies?')) %> | |
29 | + <% end %> | |
30 | + <%# end %> | |
31 | + | |
32 | + <div class="comment_reply post_comment_box closed"> | |
33 | + <% if @comment && @comment.errors.any? && @comment.reply_of_id.to_i == comment.id %> | |
34 | + <%= error_messages_for :comment %> | |
35 | + <script type="text/javascript"> | |
36 | + jQuery(function() { | |
37 | + document.location.href = '#<%= comment.anchor %>'; | |
38 | + add_comment_reply_form('#comment-reply-to-<%= comment.id %>', <%= comment.id %>); | |
39 | + }); | |
40 | + </script> | |
41 | + <% end %> | |
42 | + <%= report_abuse(comment.author, :comment_link, comment) if comment.author %> | |
43 | + <%= link_to_function _('Reply'), | |
44 | + "var f = add_comment_reply_form(this, %s); f.find('input[name=comment[title]], textarea').val(''); return false" % comment.id, | |
45 | + :class => 'comment-footer comment-footer-link comment-footer-hide', | |
46 | + :id => 'comment-reply-to-' + comment.id.to_s | |
47 | + %> | |
48 | + </div> | |
49 | + | |
50 | + </div> | |
51 | + | |
52 | + <% unless comment.replies.blank? %> | |
53 | + <ul class="comment-replies"> | |
54 | + <% comment.replies.each do |reply| %> | |
55 | + <%= render :partial => 'comment', :locals => { :comment => reply } %> | |
56 | + <% end %> | |
57 | + </ul> | |
58 | + <% end %> | |
59 | + | |
60 | + </div> | |
61 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
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-text'><%= activity.params['lead'] %></p> | |
7 | + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p> | |
8 | + <div class='profile-wall-actions'> | |
9 | + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %> | |
10 | + </div> | |
11 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
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) + ' ' + _('ago') %></p> | |
7 | + <div class='profile-wall-actions'> | |
8 | + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %> | |
9 | + </div> | |
10 | +</div> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => {:activity => activity} %> | ... | ... |
app/views/profile/_leave_scrap.rhtml
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => {:activity => activity} %> | ... | ... |
app/views/profile/_profile_activities.rhtml
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) %> | |
1 | +<li class='profile-activity-item <%= activity.verb %>' id='profile-activity-item-<%= activity.id %>'> | |
2 | + <%= render :partial => activity.verb, :locals => { :activity => activity }%> | |
3 | + <hr /> | |
4 | + | |
5 | + <%# if logged_in? && current_person.follows?(activity.sender) && activity.root.nil? %> | |
6 | + <span class='profile-wall-send-reply'><%= link_to_function _('Comment'), "hide_and_show(['#profile-wall-reply-response-#{activity.id}'],['#profile-wall-reply-#{activity.id}', '#profile-wall-reply-form-#{activity.id}']);$('reply_content_#{activity.id}').value='';$('activity_id_#{activity.id}').value='#{activity.id}';return false", :class => "profile-send-reply" %></span> | |
7 | + <%# end %> | |
8 | + | |
9 | + <ul class="profile-wall-activities-comments" style='padding-left: 50px;width:auto'> | |
10 | + <%= render :partial => 'comment', :collection => activity.comments %> | |
11 | + </ul> | |
12 | + | |
13 | + <div id='profile-wall-reply-<%= activity.id%>' style='display:none;width:auto;'> | |
14 | + <div id='profile-wall-reply-form-<%= activity.id%>' style='display:none;'> | |
15 | + <p class='profile-wall-reply'> | |
16 | + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_comment_on_activity'}, :update => "profile_activities", :success =>"hide_and_show(['#profile-wall-reply-form-#{activity.id}'],['#profile-wall-reply-response-#{activity.id}'])" do %> | |
17 | + <%= limited_text_area :comment, :body, 420, "reply_content_#{activity.id}", :cols => 50, :rows => 2 %> | |
18 | + <%= hidden_field :comment, :source_id, :id => "activity_id_#{activity.id}" %> | |
19 | + <%= hidden_field :comment, :author_id, :value => user.id %> | |
20 | + <%= submit_button :add, _('Leave a comment') %> | |
21 | + <%= button_to_function :cancel, _('Cancel'), "hide_and_show(['#profile-wall-reply-#{activity.id}'],[]);return false" %> | |
22 | + <% end %> | |
23 | + </p> | |
5 | 24 | </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}" %> | |
25 | + <div id='profile-wall-message-response-<%=activity.id%>' class='profile-wall-message-response'></div> | |
17 | 26 | </div> |
18 | -<% end %> | |
27 | + | |
28 | +</li> | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +<% activities.each do |a| %> | |
2 | + <% activity = a.klass.constantize.find(a.id) %> | |
3 | + <% if activity.kind_of?(ActionTracker::Record) && @profile.person? %> | |
4 | + <%= render :partial => 'profile_activities', :locals => {:activity => activity} %> | |
5 | + <% else %> | |
6 | + <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %> | |
7 | + <% end %> | |
8 | +<% end %> | ... | ... |
app/views/profile/_profile_activity.rhtml
1 | 1 | <div id='profile-activity'> |
2 | 2 | <h3><%= _("%s's activity") % @profile.name %></h3> |
3 | 3 | <ul> |
4 | - <%= render :partial => 'profile_activities', :locals => {:activities => @activities} %> | |
4 | + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %> | |
5 | 5 | </ul> |
6 | 6 | </div> | ... | ... |
app/views/profile/_profile_scrap.rhtml
... | ... | @@ -7,13 +7,15 @@ |
7 | 7 | </div> |
8 | 8 | <% comment_balloon :class => 'profile-wall-description' do %> |
9 | 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 | 10 | <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) %> | |
11 | + <p class='profile-wall-time'><%= time_ago_as_sentence(scrap.created_at) + ' ' + _('ago') %></p> | |
12 | + <div class='profile-wall-actions'> | |
13 | 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> | |
14 | + <span class='profile-wall-send-reply'><%= link_to_function _('Comment'), "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" %></span> | |
15 | 15 | <% end %> |
16 | + <%= link_to_remote(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) %> | |
16 | 17 | <% end %> |
18 | + </div> | |
17 | 19 | <ul class="profile-wall-scrap-replies"> |
18 | 20 | <% scrap.replies.map do |reply| %> |
19 | 21 | <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> |
... | ... | @@ -35,7 +37,7 @@ |
35 | 37 | <div id='profile-wall-reply-<%= scrap.id%>' style='display:none;'> |
36 | 38 | <div id='profile-wall-reply-form-<%= scrap.id%>' style='display:none;'> |
37 | 39 | <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 %> | |
40 | + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap'}, :update => "profile_activities", :success =>"hide_and_show(['#profile-wall-reply-form-#{scrap.id}'],['#profile-wall-reply-response-#{scrap.id}'])" do %> | |
39 | 41 | <%= limited_text_area :scrap, :content, 420, "reply_content_#{scrap.id}", :cols => 50, :rows => 2 %> |
40 | 42 | <%= hidden_field :scrap, :scrap_id, :id => "scrap_id_#{scrap.id}" %> |
41 | 43 | <%= hidden_field_tag 'receiver_id', scrap.sender.id %> | ... | ... |
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 | 6 | <%= submit_button :scrap, _('Leave a scrap') %> |
7 | 7 | <% end %> |
8 | 8 | </div> |
9 | 9 | <div id='leave_scrap_response'></div> |
10 | +<ul id='profile_activities'> | |
11 | + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %> | |
12 | +</ul> | |
13 | + | |
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 %> | |
19 | + | |
20 | +<!-- | |
10 | 21 | <ul id='profile_scraps'> |
11 | - <%= render :partial => 'profile_scraps', :locals => {:scraps => @wall_items} %> | |
22 | + <%#= render :partial => 'profile_scraps', :locals => {:scraps => @wall_items} %> | |
12 | 23 | </ul> |
24 | + | |
25 | +<% if @profile.person? %> | |
26 | + <%#= render :partial => 'profile_activity' %> | |
27 | +<% end %> | |
28 | +--> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => {:activity => activity} %> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= render :partial => 'default_activity', :locals => {:activity => activity} %> | ... | ... |
config/initializers/action_tracker.rb
... | ... | @@ -5,13 +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 | |
8 | + :description => lambda { _('published an article: %{title}') % { :title => '{{link_to(truncate(ta.get_name), ta.get_url)}}' } } | |
15 | 9 | }, |
16 | 10 | |
17 | 11 | :remove_article => { | ... | ... |
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
... | ... | @@ -0,0 +1,9 @@ |
1 | +class AddCommentCountToActionTracker < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + add_column :action_tracker, :comments_count, :integer, :default => 0 | |
4 | + end | |
5 | + | |
6 | + def self.down | |
7 | + remove_column :action_tracker, :comments_count, :integer, :default => 0 | |
8 | + end | |
9 | +end | ... | ... |
db/schema.rb
... | ... | @@ -29,6 +29,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) 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 | |
32 | 33 | end |
33 | 34 | |
34 | 35 | add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type" |
... | ... | @@ -198,7 +199,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
198 | 199 | create_table "comments", :force => true do |t| |
199 | 200 | t.string "title" |
200 | 201 | t.text "body" |
201 | - t.integer "article_id" | |
202 | + t.integer "source_id" | |
202 | 203 | t.integer "author_id" |
203 | 204 | t.string "name" |
204 | 205 | t.string "email" |
... | ... | @@ -206,6 +207,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
206 | 207 | t.integer "reply_of_id" |
207 | 208 | t.string "ip_address" |
208 | 209 | t.boolean "spam" |
210 | + t.string "source_type" | |
209 | 211 | end |
210 | 212 | |
211 | 213 | create_table "contact_lists", :force => true do |t| |
... | ... | @@ -252,6 +254,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
252 | 254 | t.datetime "created_at" |
253 | 255 | t.datetime "updated_at" |
254 | 256 | t.integer "reports_lower_bound", :default => 0, :null => false |
257 | + t.text "send_email_plugin_allow_to" | |
255 | 258 | end |
256 | 259 | |
257 | 260 | create_table "external_feeds", :force => true do |t| |
... | ... | @@ -384,7 +387,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
384 | 387 | t.string "type" |
385 | 388 | t.string "identifier" |
386 | 389 | t.integer "environment_id" |
387 | - t.boolean "active", :default => true | |
390 | + t.boolean "active", :default => true | |
388 | 391 | t.string "address" |
389 | 392 | t.string "contact_phone" |
390 | 393 | t.integer "home_page_id" |
... | ... | @@ -395,19 +398,24 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
395 | 398 | t.float "lat" |
396 | 399 | t.float "lng" |
397 | 400 | t.integer "geocode_precision" |
398 | - t.boolean "enabled", :default => true | |
399 | - t.string "nickname", :limit => 16 | |
401 | + t.boolean "enabled", :default => true | |
402 | + t.string "nickname", :limit => 16 | |
400 | 403 | t.text "custom_header" |
401 | 404 | t.text "custom_footer" |
402 | 405 | t.string "theme" |
403 | - t.boolean "public_profile", :default => true | |
406 | + t.boolean "public_profile", :default => true | |
404 | 407 | t.date "birth_date" |
405 | 408 | t.integer "preferred_domain_id" |
406 | 409 | t.datetime "updated_at" |
407 | - t.boolean "visible", :default => true | |
410 | + t.boolean "visible", :default => true | |
408 | 411 | t.integer "image_id" |
409 | - t.boolean "validated", :default => true | |
412 | + t.boolean "validated", :default => true | |
410 | 413 | t.string "cnpj" |
414 | + t.boolean "shopping_cart", :default => true | |
415 | + t.boolean "shopping_cart_delivery", :default => false | |
416 | + t.decimal "shopping_cart_delivery_price", :default => 0.0 | |
417 | + t.integer "bsc_id" | |
418 | + t.string "company_name" | |
411 | 419 | end |
412 | 420 | |
413 | 421 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" |
... | ... | @@ -496,6 +504,7 @@ ActiveRecord::Schema.define(:version => 20120307200651) do |
496 | 504 | t.datetime "created_at" |
497 | 505 | t.string "target_type" |
498 | 506 | t.integer "image_id" |
507 | + t.integer "bsc_id" | |
499 | 508 | end |
500 | 509 | |
501 | 510 | create_table "thumbnails", :force => true do |t| | ... | ... |
public/designs/themes/base/style.css
... | ... | @@ -1053,53 +1053,53 @@ hr.pre-posts, hr.sep-posts { |
1053 | 1053 | |
1054 | 1054 | .comment-wrapper-1 { |
1055 | 1055 | margin-left: 60px; |
1056 | - background: url(imgs/comment-bg-N.png) 0% 0% repeat-x; | |
1056 | + Xbackground: url(imgs/comment-bg-N.png) 0% 0% repeat-x; | |
1057 | 1057 | } |
1058 | 1058 | .comment-wrapper-2 { |
1059 | - background: url(imgs/comment-bg-S.png) 0% 100% repeat-x; | |
1059 | + Xbackground: url(imgs/comment-bg-S.png) 0% 100% repeat-x; | |
1060 | 1060 | } |
1061 | 1061 | .comment-wrapper-3 { |
1062 | - background: url(imgs/comment-bg-L.png) 100% 0% repeat-y; | |
1062 | + Xbackground: url(imgs/comment-bg-L.png) 100% 0% repeat-y; | |
1063 | 1063 | } |
1064 | 1064 | .comment-wrapper-4 { |
1065 | - background: url(imgs/comment-bg-O.png) 0% 0% repeat-y; | |
1065 | + Xbackground: url(imgs/comment-bg-O.png) 0% 0% repeat-y; | |
1066 | 1066 | } |
1067 | 1067 | .comment-wrapper-5 { |
1068 | - background: url(imgs/comment-bg-SL.png) 100% 100% no-repeat; | |
1068 | + Xbackground: url(imgs/comment-bg-SL.png) 100% 100% no-repeat; | |
1069 | 1069 | } |
1070 | 1070 | .comment-wrapper-6 { |
1071 | - background: url(imgs/comment-bg-SO.png) 0% 100% no-repeat; | |
1071 | + Xbackground: url(imgs/comment-bg-SO.png) 0% 100% no-repeat; | |
1072 | 1072 | } |
1073 | 1073 | .comment-wrapper-7 { |
1074 | - background: url(imgs/comment-bg-NL.png) 100% 0% no-repeat; | |
1074 | + Xbackground: url(imgs/comment-bg-NL.png) 100% 0% no-repeat; | |
1075 | 1075 | } |
1076 | 1076 | .comment-wrapper-8 { |
1077 | - background: url(imgs/comment-bg-NO.png) 0% 0% no-repeat; | |
1077 | + Xbackground: url(imgs/comment-bg-NO.png) 0% 0% no-repeat; | |
1078 | 1078 | } |
1079 | 1079 | |
1080 | 1080 | .comment-from-owner .comment-wrapper-1 { |
1081 | - background: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x; | |
1081 | + Xbackground: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x; | |
1082 | 1082 | } |
1083 | 1083 | .comment-from-owner .comment-wrapper-2 { |
1084 | - background: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x; | |
1084 | + Xbackground: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x; | |
1085 | 1085 | } |
1086 | 1086 | .comment-from-owner .comment-wrapper-3 { |
1087 | - background: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y; | |
1087 | + Xbackground: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y; | |
1088 | 1088 | } |
1089 | 1089 | .comment-from-owner .comment-wrapper-4 { |
1090 | - background: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y; | |
1090 | + Xbackground: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y; | |
1091 | 1091 | } |
1092 | 1092 | .comment-from-owner .comment-wrapper-5 { |
1093 | - background: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat; | |
1093 | + Xbackground: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat; | |
1094 | 1094 | } |
1095 | 1095 | .comment-from-owner .comment-wrapper-6 { |
1096 | - background: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat; | |
1096 | + Xbackground: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat; | |
1097 | 1097 | } |
1098 | 1098 | .comment-from-owner .comment-wrapper-7 { |
1099 | - background: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat; | |
1099 | + Xbackground: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat; | |
1100 | 1100 | } |
1101 | 1101 | .comment-from-owner .comment-wrapper-8 { |
1102 | - background: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat; | |
1102 | + Xbackground: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat; | |
1103 | 1103 | } |
1104 | 1104 | |
1105 | 1105 | .comment-created-at { | ... | ... |
public/stylesheets/application.css
... | ... | @@ -1314,7 +1314,7 @@ a.comment-picture { |
1314 | 1314 | } |
1315 | 1315 | |
1316 | 1316 | .comment-balloon-content { |
1317 | - margin-left: 15px; | |
1317 | + Xmargin-left: 15px; | |
1318 | 1318 | } |
1319 | 1319 | |
1320 | 1320 | /* * * Comment Replies * * */ |
... | ... | @@ -5883,7 +5883,15 @@ h1#agenda-title { |
5883 | 5883 | #profile-activity li, #profile-network li, #profile-wall li { |
5884 | 5884 | display: block; |
5885 | 5885 | padding: 0; |
5886 | - margin-bottom: 8px; | |
5886 | + Xmargin-bottom: 8px; | |
5887 | + background-color: #E8E8E8; | |
5888 | + border-bottom: 5px double #f2f2f2; | |
5889 | +} | |
5890 | + | |
5891 | +#profile-activity .profile-wall-scrap-replies li, | |
5892 | +#profile-network .profile-wall-scrap-replies li, | |
5893 | +#profile-wall .profile-wall-scrap-replies li { | |
5894 | + border-bottom: none; | |
5887 | 5895 | } |
5888 | 5896 | |
5889 | 5897 | #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { |
... | ... | @@ -5897,12 +5905,12 @@ h1#agenda-title { |
5897 | 5905 | |
5898 | 5906 | #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { |
5899 | 5907 | float: left; |
5900 | - min-height: 60px; | |
5908 | + Xmin-height: 60px; | |
5901 | 5909 | margin: 0; |
5902 | 5910 | padding: 0; |
5903 | 5911 | border: 1px solid #ccc; |
5904 | 5912 | overflow: hidden; |
5905 | - background-color: #fff; | |
5913 | + Xbackground-color: #fff; | |
5906 | 5914 | position: relative; |
5907 | 5915 | } |
5908 | 5916 | |
... | ... | @@ -5931,17 +5939,18 @@ h1#agenda-title { |
5931 | 5939 | |
5932 | 5940 | #profile-activity .profile-activity-text, #profile-network .profile-network-text, #profile-wall .profile-wall-text { |
5933 | 5941 | font-size: 13px; |
5934 | - margin: 5px; | |
5942 | + margin: 2px 5px; | |
5935 | 5943 | } |
5936 | 5944 | |
5937 | 5945 | #profile-wall .profile-wall-text { |
5938 | 5946 | padding-top: 0; |
5939 | 5947 | } |
5940 | 5948 | |
5941 | -#profile-activity .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { | |
5949 | +#profile_activities .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { | |
5942 | 5950 | font-size: 11px; |
5943 | 5951 | margin: 5px; |
5944 | 5952 | color: #babdb6; |
5953 | + text-align: right; | |
5945 | 5954 | } |
5946 | 5955 | |
5947 | 5956 | #profile-activity hr, #profile-network hr, #profile-wall hr { |
... | ... | @@ -6083,21 +6092,30 @@ h1#agenda-title { |
6083 | 6092 | } |
6084 | 6093 | |
6085 | 6094 | .profile-send-reply { |
6086 | - background-color: #eee; | |
6087 | - border: 1px solid #aaa; | |
6088 | - padding: 2px; | |
6089 | - padding-left: 20px; | |
6090 | - background-repeat: no-repeat; | |
6091 | - background-position: 2px center; | |
6095 | + xbackground-color: #eee; | |
6096 | + xborder: 1px solid #aaa; | |
6097 | + xpadding: 2px; | |
6098 | + xpadding-left: 20px; | |
6099 | + xbackground-repeat: no-repeat; | |
6100 | + xbackground-position: 2px center; | |
6092 | 6101 | color: #aaa; |
6093 | - text-decoration: none; | |
6094 | - margin-left: 8px; | |
6102 | + Xtext-decoration: none; | |
6103 | + Xmargin-left: 8px; | |
6095 | 6104 | } |
6096 | 6105 | |
6097 | 6106 | #content .profile-send-reply:hover { |
6098 | 6107 | text-decoration: none; |
6099 | 6108 | } |
6100 | 6109 | |
6110 | +#profile-wall .profile-wall-actions { | |
6111 | + text-align: right; | |
6112 | +} | |
6113 | + | |
6114 | +#profile-wall .profile-wall-send-reply { | |
6115 | + display: inline-block; | |
6116 | + | |
6117 | +} | |
6118 | + | |
6101 | 6119 | #profile-wall .profile-wall-scrap-replies .profile-wall-description { |
6102 | 6120 | background: transparent; |
6103 | 6121 | } |
... | ... | @@ -6244,7 +6262,7 @@ h1#agenda-title { |
6244 | 6262 | } |
6245 | 6263 | |
6246 | 6264 | #profile-wall .comment-balloon-content { |
6247 | - padding: 3px 0 3px 15px; | |
6265 | + padding: 3px 0px; | |
6248 | 6266 | } |
6249 | 6267 | |
6250 | 6268 | .profile-wall-reply { |
... | ... | @@ -6266,8 +6284,9 @@ h1#agenda-title { |
6266 | 6284 | width: 98%; |
6267 | 6285 | } |
6268 | 6286 | |
6269 | -#profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { | |
6270 | - width: 19%; | |
6287 | +#profile_activities .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { | |
6288 | + width: 50px; | |
6289 | + margin: 5px; | |
6271 | 6290 | } |
6272 | 6291 | |
6273 | 6292 | #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { | ... | ... |
test/factories.rb
... | ... | @@ -438,7 +438,7 @@ module Noosfero::Factory |
438 | 438 | |
439 | 439 | def defaults_for_comment(params = {}) |
440 | 440 | name = "comment_#{rand(1000)}" |
441 | - { :title => name, :body => "my own comment", :article_id => 1 }.merge(params) | |
441 | + { :title => name, :body => "my own comment", :source_id => 1 }.merge(params) | |
442 | 442 | end |
443 | 443 | |
444 | 444 | ############################################### | ... | ... |
test/functional/profile_controller_test.rb
... | ... | @@ -714,21 +714,27 @@ 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 | |
717 | + should 'see only actions of the current profile when he is not followed by the viewer' do | |
718 | 718 | p1= Person.first |
719 | 719 | p2= fast_create(Person) |
720 | - assert !p1.is_a_friend?(p2) | |
721 | 720 | p3= fast_create(Person) |
722 | - assert !p1.is_a_friend?(p3) | |
721 | + | |
722 | +# UserStampSweeper.any_instance.stubs(:current_user).returns(p1) | |
723 | 723 | ActionTracker::Record.destroy_all |
724 | - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) | |
724 | + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) | |
725 | + | |
726 | +# UserStampSweeper.any_instance.stubs(:current_user).returns(p2) | |
727 | + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) | |
728 | +# a2 = ActionTracker::Record.last | |
729 | + | |
730 | +# UserStampSweeper.any_instance.stubs(:current_user).returns(p3) | |
731 | + scrap3 = Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) | |
732 | +# a3 = ActionTracker::Record.last | |
733 | + | |
734 | + UserStampSweeper.any_instance.stubs(:current_user).returns(p1) | |
735 | + TinyMceArticle.create!(:profile => p1, :name => 'An article about free software') | |
725 | 736 | a1 = ActionTracker::Record.last |
726 | - 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 | |
737 | + | |
732 | 738 | login_as(profile.identifier) |
733 | 739 | get :index, :profile => p1.identifier |
734 | 740 | assert_not_nil assigns(:activities) |
... | ... | @@ -744,7 +750,7 @@ class ProfileControllerTest < ActionController::TestCase |
744 | 750 | assert_equal 30, assigns(:activities).count |
745 | 751 | end |
746 | 752 | |
747 | - should 'see not see the friends activities in the current profile activity' do | |
753 | + should 'not see the friends actions and scraps in the current profile activity' do | |
748 | 754 | p1= Person.first |
749 | 755 | p2= fast_create(Person) |
750 | 756 | assert !p1.is_a_friend?(p2) |
... | ... | @@ -752,18 +758,23 @@ class ProfileControllerTest < ActionController::TestCase |
752 | 758 | p1.add_friend(p3) |
753 | 759 | assert p1.is_a_friend?(p3) |
754 | 760 | ActionTracker::Record.destroy_all |
755 | - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) | |
761 | + | |
762 | + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) | |
763 | + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) | |
764 | + scrap3 = Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) | |
765 | + | |
766 | + UserStampSweeper.any_instance.stubs(:current_user).returns(p3) | |
767 | + TinyMceArticle.create!(:profile => p3, :name => 'An article about free software') | |
756 | 768 | a1 = ActionTracker::Record.last |
757 | - UserStampSweeper.any_instance.stubs(:current_user).returns(p2) | |
758 | - Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) | |
769 | + | |
770 | + UserStampSweeper.any_instance.stubs(:current_user).returns(p1) | |
771 | + TinyMceArticle.create!(:profile => p1, :name => 'Another article about free software') | |
759 | 772 | a2 = ActionTracker::Record.last |
760 | - UserStampSweeper.any_instance.stubs(:current_user).returns(p3) | |
761 | - Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1)) | |
762 | - a3 = ActionTracker::Record.last | |
773 | + | |
763 | 774 | login_as(profile.identifier) |
764 | 775 | get :index, :profile => p1.identifier |
765 | 776 | assert_not_nil assigns(:activities) |
766 | - assert_equal [a1], assigns(:activities) | |
777 | + assert_equal [a2], assigns(:activities) | |
767 | 778 | end |
768 | 779 | |
769 | 780 | should 'see all the activities in the current profile network' do |
... | ... | @@ -976,7 +987,7 @@ class ProfileControllerTest < ActionController::TestCase |
976 | 987 | |
977 | 988 | should 'the wall_itens be paginated in people profiles' do |
978 | 989 | p1 = Person.first |
979 | - 40.times{fast_create(Scrap, :sender_id => p1.id)} | |
990 | + 40.times{fast_create(Scrap, :sender_id => p1.id, :created_at => Time.now)} | |
980 | 991 | |
981 | 992 | @controller.stubs(:logged_in?).returns(true) |
982 | 993 | user = mock() |
... | ... | @@ -1158,7 +1169,7 @@ class ProfileControllerTest < ActionController::TestCase |
1158 | 1169 | assert_equal 40, profile.tracked_actions.count |
1159 | 1170 | get :view_more_activities, :profile => profile.identifier, :page => 2 |
1160 | 1171 | assert_response :success |
1161 | - assert_template '_profile_activities' | |
1172 | + assert_template '_profile_bla' | |
1162 | 1173 | assert_equal 10, assigns(:activities).count |
1163 | 1174 | end |
1164 | 1175 | |
... | ... | @@ -1247,4 +1258,34 @@ class ProfileControllerTest < ActionController::TestCase |
1247 | 1258 | post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'} |
1248 | 1259 | end |
1249 | 1260 | end |
1261 | + | |
1262 | + should 'display activities and scraps together' do | |
1263 | + another_person = fast_create(Person) | |
1264 | + Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap')) | |
1265 | + | |
1266 | + UserStampSweeper.any_instance.stubs(:current_user).returns(profile) | |
1267 | + ActionTracker::Record.destroy_all | |
1268 | + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') | |
1269 | + | |
1270 | + login_as(profile.identifier) | |
1271 | + get :index, :profile => profile.identifier | |
1272 | + | |
1273 | + assert_tag :tag => 'div', :attributes => { :id => 'profile-wall' }, :descendant => { :tag => 'p', :content => 'A scrap' } | |
1274 | + assert_tag :tag => 'div', :attributes => { :id => 'profile-wall' }, :descendant => { :tag => 'a', :content => 'An article about free software' } | |
1275 | + end | |
1276 | + | |
1277 | + should 'have scraps and activities on activities' do | |
1278 | + another_person = fast_create(Person) | |
1279 | + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap')) | |
1280 | + | |
1281 | + UserStampSweeper.any_instance.stubs(:current_user).returns(profile) | |
1282 | + ActionTracker::Record.destroy_all | |
1283 | + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software') | |
1284 | + activity = ActionTracker::Record.last | |
1285 | + | |
1286 | + login_as(profile.identifier) | |
1287 | + get :index, :profile => profile.identifier | |
1288 | + | |
1289 | + assert_equivalent [scrap,activity], assigns(:activities).map {|a| a.klass.constantize.find(a.id)} | |
1290 | + end | |
1250 | 1291 | end | ... | ... |
test/unit/action_tracker_notification_test.rb
... | ... | @@ -76,4 +76,12 @@ 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 | + action = fast_create(ActionTracker::Record) | |
81 | + notification = fast_create(ActionTrackerNotification, :action_tracker_id => action.id, :profile_id => 1) | |
82 | + | |
83 | + comment = fast_create(Comment, :source_id => action.id) | |
84 | + assert_equal action.comments, notification.comments | |
85 | + end | |
86 | + | |
79 | 87 | end | ... | ... |
test/unit/article_test.rb
... | ... | @@ -1009,6 +1009,28 @@ class ArticleTest < ActiveSupport::TestCase |
1009 | 1009 | assert_equal ['a','b'], ta.get_name |
1010 | 1010 | end |
1011 | 1011 | |
1012 | + should 'update action when article is updated' do | |
1013 | + article = create(TinyMceArticle, :profile => profile) | |
1014 | + action = ActionTracker::Record.last | |
1015 | + time = action.updated_at | |
1016 | + | |
1017 | + Time.stubs(:now).returns(time + 1.day) | |
1018 | + article.name = 'New name' | |
1019 | + article.save | |
1020 | + assert_not_equal time, ActionTracker::Record.last.updated_at | |
1021 | + end | |
1022 | + | |
1023 | + should 'update action when comment is created' do | |
1024 | + article = create(TinyMceArticle, :profile => profile) | |
1025 | + action = ActionTracker::Record.last | |
1026 | + time = action.updated_at | |
1027 | + | |
1028 | + Time.stubs(:now).returns(time + 1.day) | |
1029 | + | |
1030 | + article.comments << Comment.create(:name => 'Guest', :email => 'guest@example.com', :title => 'test comment', :body => 'hello!') | |
1031 | + assert_not_equal time, ActionTracker::Record.last.updated_at | |
1032 | + end | |
1033 | + | |
1012 | 1034 | should 'notifiable is false by default' do |
1013 | 1035 | a = fast_create(Article) |
1014 | 1036 | assert !a.notifiable? |
... | ... | @@ -1638,4 +1660,23 @@ class ArticleTest < ActiveSupport::TestCase |
1638 | 1660 | assert_equal [c1,c2,c5], Article.text_articles |
1639 | 1661 | end |
1640 | 1662 | |
1663 | + should 'filter articles by date of creation' do | |
1664 | + from = Date.today - 2.days | |
1665 | + to = Date.today - 1.day | |
1666 | + article1 = fast_create(Article, :created_at => from - 1.day) | |
1667 | + article2 = fast_create(Article, :created_at => from + 6.hours) | |
1668 | + article3 = fast_create(Article, :created_at => to + 1.day) | |
1669 | + | |
1670 | + assert_not_includes Article.created_between(from, nil), article1 | |
1671 | + assert_includes Article.created_between(from, nil), article2 | |
1672 | + assert_includes Article.created_between(from, nil), article3 | |
1673 | + | |
1674 | + assert_includes Article.created_between(nil, to), article1 | |
1675 | + assert_includes Article.created_between(nil, to), article2 | |
1676 | + assert_not_includes Article.created_between(nil, to), article3 | |
1677 | + | |
1678 | + assert_not_includes Article.created_between(from, to), article1 | |
1679 | + assert_includes Article.created_between(from, to), article2 | |
1680 | + assert_not_includes Article.created_between(from, to), article3 | |
1681 | + end | |
1641 | 1682 | 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 | |
... | ... | @@ -69,8 +69,9 @@ class CommentTest < ActiveSupport::TestCase |
69 | 69 | |
70 | 70 | cc = art.comments_count |
71 | 71 | art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save! |
72 | - art.reload | |
73 | - assert_equal cc + 1, art.comments_count | |
72 | + art = Article.find(art.id) | |
73 | + | |
74 | + assert_equal cc + 1, Article.find(art.id).comments_count | |
74 | 75 | end |
75 | 76 | |
76 | 77 | should 'provide author name for authenticated authors' do |
... | ... | @@ -217,30 +218,10 @@ class CommentTest < ActiveSupport::TestCase |
217 | 218 | assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist." |
218 | 219 | end |
219 | 220 | |
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 | 221 | should 'have the action_tracker_target defined' do |
233 | 222 | assert Comment.method_defined?(:action_tracker_target) |
234 | 223 | end |
235 | 224 | |
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 | 225 | should "get children of a comment" do |
245 | 226 | c = fast_create(Comment) |
246 | 227 | c1 = fast_create(Comment, :reply_of_id => c.id) |
... | ... | @@ -307,11 +288,11 @@ class CommentTest < ActiveSupport::TestCase |
307 | 288 | |
308 | 289 | should "return comments as a thread" do |
309 | 290 | 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) | |
291 | + c0 = fast_create(Comment, :source_id => a.id) | |
292 | + c1 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id) | |
293 | + c2 = fast_create(Comment, :reply_of_id => c1.id, :source_id => a.id) | |
294 | + c3 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id) | |
295 | + c4 = fast_create(Comment, :source_id => a.id) | |
315 | 296 | result = a.comments.as_thread |
316 | 297 | assert_equal c0.id, result[0].id |
317 | 298 | assert_equal [c1.id, c3.id], result[0].replies.map(&:id) | ... | ... |
test/unit/community_test.rb
test/unit/enterprise_test.rb
test/unit/person_test.rb
... | ... | @@ -1243,4 +1243,34 @@ class PersonTest < ActiveSupport::TestCase |
1243 | 1243 | assert !person.visible |
1244 | 1244 | assert_not_equal password, person.user.password |
1245 | 1245 | end |
1246 | + | |
1247 | + should 'return tracked_actions and scraps as activities' do | |
1248 | + person = fast_create(Person) | |
1249 | + another_person = fast_create(Person) | |
1250 | + | |
1251 | + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => person, :content => 'A scrap')) | |
1252 | + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once | |
1253 | + TinyMceArticle.create!(:profile => person, :name => 'An article about free software') | |
1254 | + activity = ActionTracker::Record.last | |
1255 | + | |
1256 | + assert_equal 'An article about free software', activity.get_name.last | |
1257 | + assert_equal [scrap,activity], person.activities.map { |a| a.klass.constantize.find(a.id) } | |
1258 | + end | |
1259 | + | |
1260 | + should 'not return tracked_actions and scraps from others as activities' do | |
1261 | + person = fast_create(Person) | |
1262 | + another_person = fast_create(Person) | |
1263 | + | |
1264 | + person_scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => person, :content => 'A scrap from person')) | |
1265 | + another_person_scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => another_person, :content => 'A scrap from another person')) | |
1266 | + | |
1267 | + TinyMceArticle.create!(:profile => another_person, :name => 'An article about free software from another person') | |
1268 | + another_person_activity = ActionTracker::Record.last | |
1269 | + | |
1270 | + UserStampSweeper.any_instance.stubs(:current_user).returns(person) | |
1271 | + TinyMceArticle.create!(:profile => person, :name => 'An article about free software') | |
1272 | + person_activity = ActionTracker::Record.last | |
1273 | + | |
1274 | + assert_equal [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) } | |
1275 | + end | |
1246 | 1276 | end | ... | ... |
test/unit/profile_test.rb
... | ... | @@ -1704,6 +1704,7 @@ class ProfileTest < ActiveSupport::TestCase |
1704 | 1704 | assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage) |
1705 | 1705 | end |
1706 | 1706 | |
1707 | + | |
1707 | 1708 | should 'find profiles with image' do |
1708 | 1709 | env = fast_create(Environment) |
1709 | 1710 | 2.times do |n| |
... | ... | @@ -1762,10 +1763,15 @@ class ProfileTest < ActiveSupport::TestCase |
1762 | 1763 | assert_raise NoMethodError do |
1763 | 1764 | Profile::Roles.invalid_role(env.id) |
1764 | 1765 | end |
1766 | + | |
1767 | + should 'return empty array as activities' do | |
1768 | + profile = Profile.new | |
1769 | + assert_equal [], profile.activities | |
1765 | 1770 | end |
1766 | 1771 | |
1767 | 1772 | private |
1768 | 1773 | |
1774 | + | |
1769 | 1775 | def assert_invalid_identifier(id) |
1770 | 1776 | profile = Profile.new(:identifier => id) |
1771 | 1777 | assert !profile.valid? | ... | ... |
vendor/plugins/active_record_counter_cache_on_polymorphic_association/init.rb
0 → 100644
... | ... | @@ -0,0 +1,32 @@ |
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::ClassMethods.module_eval do | |
6 | + | |
7 | + def replace(record) | |
8 | + counter_cache_name = @reflection.counter_cache_column | |
9 | + if record.nil? | |
10 | + if counter_cache_name && !@owner.new_record? | |
11 | + record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name] | |
12 | + end | |
13 | + @target = @owner[@reflection.primary_key_name] = @owner[@reflection.options[:foreign_type]] = nil | |
14 | + else | |
15 | + @target = (AssociationProxy === record ? record.target : record) | |
16 | + | |
17 | + if counter_cache_name && !@owner.new_record? | |
18 | + record.class.base_class.increment_counter(counter_cache_name, record.id) | |
19 | + record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name] | |
20 | + end | |
21 | + | |
22 | + @owner[@reflection.primary_key_name] = record.id | |
23 | + @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s | |
24 | + | |
25 | + @updated = true | |
26 | + end | |
27 | + | |
28 | + loaded | |
29 | + record | |
30 | + end | |
31 | + | |
32 | +end | ... | ... |