Commit 084b93c03109b872336bb4476d1a18051b7bee15

Authored by Leandro Nunes dos Santos
2 parents 0d7f7927 4eb56579

Merge branch 'next_colivre' into ActionItem2892

Showing 41 changed files with 1657 additions and 113 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
... ... @@ -144,10 +144,15 @@ class CmsController < MyProfileController
144 144  
145 145 post_only :set_home_page
146 146 def set_home_page
147   - @article = profile.articles.find(params[:id])
148   - profile.home_page = @article
149   - profile.save(false)
150   - session[:notice] = _('"%s" configured as home page.') % @article.name
  147 + article = params[:id].nil? ? nil : profile.articles.find(params[:id])
  148 + profile.update_attribute(:home_page, article)
  149 +
  150 + if article.nil?
  151 + session[:notice] = _('Homepage reseted.')
  152 + else
  153 + session[:notice] = _('"%s" configured as homepage.') % article.name
  154 + end
  155 +
151 156 redirect_to (request.referer || profile.url)
152 157 end
153 158  
... ...
app/controllers/public/profile_controller.rb
... ... @@ -206,10 +206,50 @@ class ProfileController < PublicController
206 206 end
207 207  
208 208 def view_more_network_activities
209   - @activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page])
  209 + @activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page])
210 210 render :partial => 'profile_network_activities', :locals => {:network_activities => @activities}
211 211 end
212 212  
  213 + def more_comments
  214 + activity = ActionTracker::Record.find(:first, :conditions => {:id => params[:activity], :user_id => @profile})
  215 + comments_count = activity.comments.count
  216 + comment_page = (params[:comment_page] || 1).to_i
  217 + comments_per_page = 5
  218 + no_more_pages = comments_count <= comment_page * comments_per_page
  219 +
  220 + render :update do |page|
  221 + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
  222 + :partial => 'comment', :collection => activity.comments.paginate(:per_page => comments_per_page, :page => comment_page)
  223 +
  224 + if no_more_pages
  225 + page.remove 'profile-wall-activities-comments-more-'+params[:activity]
  226 + else
  227 + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
  228 + :partial => 'more_comments', :locals => {:activity => activity, :comment_page => comment_page}
  229 + end
  230 + end
  231 + end
  232 +
  233 + def more_replies
  234 + activity = Scrap.find(:first, :conditions => {:id => params[:activity], :receiver_id => @profile, :scrap_id => nil})
  235 + comments_count = activity.replies.count
  236 + comment_page = (params[:comment_page] || 1).to_i
  237 + comments_per_page = 5
  238 + no_more_pages = comments_count <= comment_page * comments_per_page
  239 +
  240 + render :update do |page|
  241 + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
  242 + :partial => 'profile_scrap', :collection => activity.replies.paginate(:per_page => comments_per_page, :page => comment_page), :as => :scrap
  243 +
  244 + if no_more_pages
  245 + page.remove 'profile-wall-activities-comments-more-'+params[:activity]
  246 + else
  247 + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
  248 + :partial => 'more_replies', :locals => {:activity => activity, :comment_page => comment_page}
  249 + end
  250 + end
  251 + end
  252 +
213 253 def remove_scrap
214 254 begin
215 255 scrap = current_user.person.scraps(params[:scrap_id])
... ... @@ -343,6 +383,7 @@ class ProfileController &lt; PublicController
343 383 end
344 384 end
345 385  
  386 +
346 387 protected
347 388  
348 389 def check_access_to_profile
... ... @@ -393,4 +434,5 @@ class ProfileController &lt; PublicController
393 434 def relations_to_include
394 435 [:image, :domains, :preferred_domain, :environment]
395 436 end
  437 +
396 438 end
... ...
app/helpers/application_helper.rb
... ... @@ -1424,8 +1424,8 @@ module ApplicationHelper
1424 1424 end
1425 1425  
1426 1426 def filter_html(html, source)
1427   - if @plugins && source.has_macro?
1428   - html = convert_macro(html, source)
  1427 + if @plugins && source && source.has_macro?
  1428 + html = convert_macro(html, source) unless @plugins.enabled_macros.blank?
1429 1429 #TODO This parse should be done through the macro infra, but since there
1430 1430 # are old things that do not support it we are keeping this hot spot.
1431 1431 html = @plugins.pipeline(:parse_content, html, source).first
... ...
app/views/cms/view.rhtml
... ... @@ -2,6 +2,18 @@
2 2 <%= _('Content management') %>
3 3 </h1>
4 4  
  5 +<% if !environment.enabled?('cant_change_homepage') && !remove_content_button(:home) %>
  6 + <div class="cms-homepage">
  7 + <%= _('Profile homepage:') %>
  8 + <% if profile.home_page %>
  9 + <%= link_to_article(profile.home_page) %>
  10 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  11 + <% else %>
  12 + <span class="cms-homepage-default"><%= _('Profile Information') %></span>
  13 + <% end %>
  14 + </div>
  15 +<% end %>
  16 +
5 17 <% button_bar(:style => 'margin-bottom: 1em;') do %>
6 18 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
7 19  
... ... @@ -56,7 +68,11 @@
56 68 <%= button_without_text :eyes, _('Public view'), article.view_url %>
57 69 <%= display_spread_button(profile, article) unless article.folder? || remove_content_button(:spread)%>
58 70 <% if !environment.enabled?('cant_change_homepage') && !remove_content_button(:home) %>
59   - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  71 + <% if profile.home_page != article %>
  72 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  73 + <% else %>
  74 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  75 + <% end %>
60 76 <% end %>
61 77 <%= display_delete_button(article) if !remove_content_button(:delete) %>
62 78 </td>
... ...
app/views/profile/_more_comments.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<div class='view-more-comments'>
  2 + <%= link_to(_('More'), :profile => @profile.identifier, :controller => 'profile', :action => 'more_comments', :activity => activity, :comment_page => (comment_page + 1)) %>
  3 +</div>
... ...
app/views/profile/_more_replies.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<div class='view-more-replies'>
  2 + <%= link_to(_('More'), :profile => @profile.identifier, :controller => 'profile', :action => 'more_replies', :activity => activity, :comment_page => (comment_page + 1)) %>
  3 +</div>
... ...
app/views/profile/_profile_activities_list.rhtml
... ... @@ -4,7 +4,7 @@
4 4 <% if activity.kind_of?(ActionTracker::Record) %>
5 5 <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %>
6 6 <% else %>
7   - <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %>
  7 + <%= render :partial => 'profile_scraps', :locals => { :activity => activity, :scrap => activity } %>
8 8 <% end %>
9 9 <% end %>
10 10 <% end %>
... ...
app/views/profile/_profile_comments.rhtml
1 1 <hr />
2 2  
3   -<% if activity.comments_count > 2 %>
  3 +<ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments" >
  4 +</ul>
  5 +<% if activity.comments_count > 0 %>
  6 +<div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments" >
4 7 <div class='view-all-comments icon-chat'>
5   - <%= link_to(_("View all %s comments") % activity.comments_count, '#') %>
  8 + <%= link_to(n_('View comment', "View all %s comments", activity.comments_count) % activity.comments_count, :profile => profile.identifier, :controller => 'profile', :action => 'more_comments', :activity => activity, :comment_page => (1)) %>
6 9 </div>
  10 +</div>
7 11 <% 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 12 <%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %>
... ...
app/views/profile/_profile_scrap.rhtml
... ... @@ -16,13 +16,7 @@
16 16 </div>
17 17 </div>
18 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>
23   - <% end %>
24   -
25   - <ul class="profile-wall-activities-comments scrap-replies" style="width: auto; <%= 'display:none;' if (scrap.replies.count > 2) %>" >
  19 + <ul class="profile-wall-activities-comments scrap-replies" style="width: auto;" >
26 20 <% scrap.replies.map do |reply| %>
27 21 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %>
28 22 <% end %>
... ...
app/views/profile/_profile_scraps.rhtml
1   -NÃO DEVE APARECER
  1 +<li class='profile-activity-item' id='profile-activity-item-<%= scrap.id %>'>
  2 + <div class='profile-activity-image'>
  3 + <%= link_to(profile_image(scrap.sender, :minor), scrap.sender.url) %>
  4 + </div>
  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>
  14 + <% end %>
  15 + <%= link_to_function(_('Remove'), 'remove_item_wall(this, %s, %s, %s); return false ;' % ["'.profile-activity-item'", url_for(:profile => params[:profile], :action => :remove_scrap, :scrap_id => scrap.id, :view => params[:view]).to_json, _('Are you sure you want to remove this scrap and all its replies?').to_json]) if logged_in? && user.can_control_scrap?(scrap) %>
  16 + </div>
  17 + </div>
  18 +
  19 +
  20 + <ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments scrap-replies" style="width: auto;" >
  21 + </ul>
  22 +
  23 + <% if scrap.replies.count > 0 %>
  24 + <div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments">
  25 + <div class='view-all-comments icon-chat'>
  26 + <%= link_to(n_('View comment', "View all %s comments", scrap.replies.count) % scrap.replies.count, :profile => profile.identifier, :controller => 'profile', :action => 'more_replies', :activity => activity, :comment_page => (1)) %>
  27 + </div>
  28 + </div>
  29 + <% end %>
  30 + <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
  31 + <hr />
  32 +</li>
... ...
plugins/comment_group/controllers/profile/comment_group_plugin_profile_controller.rb
1 1 class CommentGroupPluginProfileController < ProfileController
2   - append_view_path File.join(File.dirname(__FILE__) + '/../views')
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
3 3  
4 4 def view_comments
5   - article_id = params[:article_id]
6   - group_id = params[:group_id]
  5 + @article_id = params[:article_id]
  6 + @group_id = params[:group_id]
7 7  
8   - article = profile.articles.find(article_id)
9   - comments = article.group_comments.without_spam.in_group(group_id)
10   - render :update do |page|
11   - page.replace_html "comments_list_group_#{group_id}", :partial => 'comment/comment.rhtml', :collection => comments
12   - page.replace_html "comment-count-#{group_id}", comments.count
13   - end
  8 + article = profile.articles.find(@article_id)
  9 + @group_comment_page = (params[:group_comment_page] || 1).to_i
  10 +
  11 + @comments = article.comments.without_spam.in_group(@group_id)
  12 + @comments_count = @comments.count
  13 + @comments = @comments.without_reply.paginate(:per_page => per_page, :page => @group_comment_page )
  14 +
  15 + @no_more_pages = @comments_count <= @group_comment_page * per_page
  16 + end
  17 +
  18 + def per_page
  19 + 3
14 20 end
15 21  
16 22 end
... ...
plugins/comment_group/lib/comment_group_plugin.rb
... ... @@ -24,6 +24,11 @@ class CommentGroupPlugin &lt; Noosfero::Plugin
24 24 'comment_group_macro.js'
25 25 end
26 26  
  27 + def stylesheet?
  28 + true
  29 + end
  30 +
  31 +
27 32 end
28 33  
29 34 require_dependency 'comment_group_plugin/macros/allow_comment'
... ...
plugins/comment_group/lib/comment_group_plugin/macros/allow_comment.rb
... ... @@ -11,7 +11,6 @@ class CommentGroupPlugin::AllowComment &lt; Noosfero::Plugin::Macro
11 11 :css_files => 'comment_group.css' }
12 12 end
13 13  
14   - #FIXME Make this test
15 14 def parse(params, inner_html, source)
16 15 group_id = params[:group_id].to_i
17 16 article = source
... ...
plugins/comment_group/lib/ext/article.rb
... ... @@ -2,13 +2,10 @@ require_dependency &#39;article&#39;
2 2  
3 3 class Article
4 4  
5   - #FIXME make this test
6 5 has_many :group_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'group_id IS NOT NULL']
7 6  
8   - #FIXME make this test
9 7 validate :not_empty_group_comments_removed
10 8  
11   - #FIXME make this test
12 9 def not_empty_group_comments_removed
13 10 if body
14 11 groups_with_comments = group_comments.collect {|comment| comment.group_id}.uniq
... ...
plugins/comment_group/public/style.css 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +div.article-comments-list-more{
  2 + width: 100%;
  3 + height: 30px;
  4 + text-align: center;
  5 + font-size: 20px;
  6 + margin-bottom: 5px;
  7 +}
... ...
plugins/comment_group/test/functional/comment_group_plugin_profile_controller_test.rb
1   -require File.dirname(__FILE__) + '/../../../../test/test_helper'
  1 +require File.dirname(__FILE__) + '/../test_helper'
2 2 require File.dirname(__FILE__) + '/../../controllers/profile/comment_group_plugin_profile_controller'
3 3  
4 4 # Re-raise errors caught by the controller.
... ... @@ -21,18 +21,52 @@ class CommentGroupPluginProfileControllerTest &lt; ActionController::TestCase
21 21 should 'be able to show group comments' do
22 22 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
23 23 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
24   - assert_template 'comment/_comment.rhtml'
  24 + assert_template 'comment_group_plugin_profile/view_comments.rjs'
25 25 assert_match /comments_list_group_0/, @response.body
26 26 assert_match /\"comment-count-0\", \"1\"/, @response.body
27 27 end
28 28  
29 29 should 'do not show global comments' do
30   - comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :group_id => nil)
31   - comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  30 + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :group_id => nil)
  31 + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
32 32 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
33   - assert_template 'comment/_comment.rhtml'
  33 + assert_template 'comment_group_plugin_profile/view_comments.rjs'
34 34 assert_match /comments_list_group_0/, @response.body
35 35 assert_match /\"comment-count-0\", \"1\"/, @response.body
36 36 end
37 37  
  38 + should 'show first page comments only' do
  39 + comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'secondpage', :group_id => 0)
  40 + comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 1', :group_id => 0)
  41 + comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 2', :group_id => 0)
  42 + comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 3', :group_id => 0)
  43 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  44 + assert_match /firstpage 1/, @response.body
  45 + assert_match /firstpage 2/, @response.body
  46 + assert_match /firstpage 3/, @response.body
  47 + assert_no_match /secondpage/, @response.body
  48 + end
  49 +
  50 + should 'show link to display more comments' do
  51 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  52 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  53 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  54 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'secondpage', :body => 'secondpage', :group_id => 0)
  55 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  56 + assert_match /group_comment_page=2/, @response.body
  57 + end
  58 +
  59 + should 'do not show link to display more comments if do not have more pages' do
  60 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  61 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  62 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  63 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  64 + assert_no_match /group_comment_page/, @response.body
  65 + end
  66 +
  67 + should 'do not show link to display more comments if do not have any comments' do
  68 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  69 + assert_no_match /group_comment_page/, @response.body
  70 + end
  71 +
38 72 end
... ...
plugins/comment_group/test/functional/comment_group_plugin_public_controller_test.rb
1   -require File.dirname(__FILE__) + '/../../../../test/test_helper'
  1 +require File.dirname(__FILE__) + '/../test_helper'
2 2 require File.dirname(__FILE__) + '/../../controllers/public/comment_group_plugin_public_controller'
3 3  
4 4 # Re-raise errors caught by the controller.
... ...
plugins/comment_group/test/functional/content_viewer_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ContentViewerController
  4 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  5 + def rescue_action(e)
  6 + raise e
  7 + end
  8 +end
  9 +
  10 +class ContentViewerControllerTest < ActionController::TestCase
  11 +
  12 + def setup
  13 + @profile = fast_create(Community)
  14 + @page = fast_create(Article, :profile_id => @profile.id, :body => "<div class=\"macro\" data-macro-group_id=\"1\" data-macro='comment_group_plugin/allow_comment' ></div>")
  15 + @environment = Environment.default
  16 + @environment.enable_plugin(CommentGroupPlugin)
  17 + end
  18 +
  19 + attr_reader :page
  20 +
  21 + should 'parse article body and render comment group view' do
  22 + comment1 = fast_create(Comment, :group_id => 1, :source_id => page.id)
  23 + get :view_page, @page.url
  24 + assert_tag 'div', :attributes => {:class => 'comment_group_1'}
  25 + assert_tag 'div', :attributes => {:id => 'comments_group_count_1'}
  26 + end
  27 +
  28 +end
... ...
plugins/comment_group/test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
... ...
plugins/comment_group/test/unit/allow_comment_test.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class AllowCommentTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @macro = CommentGroupPlugin::AllowComment.new
  7 + end
  8 +
  9 + attr_reader :macro
  10 +
  11 + should 'have a configuration' do
  12 + assert CommentGroupPlugin::AllowComment.configuration
  13 + end
  14 +
  15 + should 'parse contents to include comment group view' do
  16 + profile = fast_create(Community)
  17 + article = fast_create(Article, :profile_id => profile.id)
  18 + comment = fast_create(Comment, :group_id => 1, :source_id => article.id)
  19 + inner_html = 'inner'
  20 + content = macro.parse({:group_id => comment.group_id}, inner_html, article)
  21 +
  22 + expects(:render).with({:partial => 'plugins/comment_group/views/comment_group.rhtml', :locals => {:group_id => comment.group_id, :article_id => article.id, :inner_html => inner_html, :count => 1, :profile_identifier => profile.identifier} })
  23 + instance_eval(&content)
  24 + end
  25 +
  26 +end
... ...
plugins/comment_group/test/unit/article_test.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ArticleTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + profile = fast_create(Community)
  7 + @article = fast_create(Article, :profile_id => profile.id)
  8 + end
  9 +
  10 + attr_reader :article
  11 +
  12 + should 'return group comments from article' do
  13 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  14 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  15 + assert_equal [comment1], article.group_comments
  16 + end
  17 +
  18 + should 'do not allow a exclusion of a group comment macro if this group has comments' do
  19 + article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=2></div>")
  20 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  21 + assert !article.save
  22 + assert_equal 'Not empty group comment cannot be removed', article.errors[:base]
  23 + end
  24 +
  25 + should 'allow save if comment group macro is not removed for group with comments' do
  26 + article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=1></div>")
  27 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  28 + assert article.save
  29 + end
  30 +
  31 +end
... ...
plugins/comment_group/test/unit/comment_group_plugin_test.rb
1   -require File.dirname(__FILE__) + '/../../../../test/test_helper'
  1 +require File.dirname(__FILE__) + '/../test_helper'
2 2  
3 3 class CommentGroupPluginTest < ActiveSupport::TestCase
4 4  
5   - include Noosfero::Plugin::HotSpot
6   -
7 5 def setup
8 6 @environment = Environment.default
  7 + @plugin = CommentGroupPlugin.new
  8 + end
  9 +
  10 + attr_reader :environment, :plugin
  11 +
  12 + should 'have a name' do
  13 + assert_not_equal Noosfero::Plugin.plugin_name, CommentGroupPlugin::plugin_name
  14 + end
  15 +
  16 + should 'describe yourself' do
  17 + assert_not_equal Noosfero::Plugin.plugin_description, CommentGroupPlugin::plugin_description
  18 + end
  19 +
  20 + should 'have a js file' do
  21 + assert !plugin.js_files.blank?
9 22 end
10 23  
11   - attr_reader :environment
  24 + should 'have stylesheet' do
  25 + assert plugin.stylesheet?
  26 + end
  27 +
  28 + should 'have extra contents for comment form' do
  29 + comment = fast_create(Comment, :group_id => 1)
  30 + content = plugin.comment_form_extra_contents({:comment => comment})
  31 + expects(:hidden_field_tag).with('comment[group_id]', comment.group_id).once
  32 + instance_eval(&content)
  33 + end
  34 +
  35 + should 'do not have extra contents for comments without group' do
  36 + comment = fast_create(Comment, :group_id => nil)
  37 + content = plugin.comment_form_extra_contents({:comment => comment})
  38 + assert_equal nil, instance_eval(&content)
  39 + end
  40 +
  41 + should 'call without_group for scope passed as parameter to unavailable_comments' do
  42 + article = fast_create(Article)
  43 + article.expects(:without_group).once
  44 + plugin.unavailable_comments(article)
  45 + end
12 46  
13 47 #FIXME Obsolete test
14 48 #
... ...
plugins/comment_group/test/unit/comment_test.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CommentTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + profile = fast_create(Community)
  7 + @article = fast_create(Article, :profile_id => profile.id)
  8 + end
  9 +
  10 + attr_reader :article
  11 +
  12 + should 'return comments that belongs to a specified group' do
  13 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  14 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  15 + comment3 = fast_create(Comment, :group_id => 2, :source_id => article.id)
  16 + assert_equal [comment1], article.comments.in_group(1)
  17 + end
  18 +
  19 + should 'return comments that do not belongs to any group' do
  20 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  21 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  22 + comment3 = fast_create(Comment, :group_id => 2, :source_id => article.id)
  23 + assert_equal [comment2], article.comments.without_group
  24 + end
  25 +
  26 +end
... ...
plugins/comment_group/views/_comment_group.rhtml
... ... @@ -20,7 +20,13 @@
20 20 <div class="comment-group-loading-<%= group_id %>"/>
21 21  
22 22 <div class="comments_list_toggle_group_<%= group_id %>" style="display:none">
23   - <div class="article-comments-list" id="comments_list_group_<%= group_id %>"></div>
24   - <div id="page-comment-form-<%= group_id %>" class='post_comment_box closed'><%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :group_id => group_id}%></div>
  23 + <div class="article-comments-list" id="comments_list_group_<%= group_id %>">
  24 + </div>
  25 + <div class ="article-comments-list-more" id="comments_list_group_<%= group_id %>_more">
  26 + </div>
  27 + <div id="page-comment-form-<%= group_id %>" class='post_comment_box closed'>
  28 + <%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :group_id => group_id}%>
  29 + </div>
  30 +
25 31 </div>
26 32 </div>
... ...
plugins/comment_group/views/comment_group_plugin_profile/view_comments.rjs 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +if @group_comment_page == 1
  2 + page.replace_html "comments_list_group_#{@group_id}", :partial => 'comment/comment.rhtml', :collection => @comments
  3 +else
  4 + page.insert_html :bottom, "comments_list_group_#{@group_id}", :partial => 'comment/comment.rhtml', :collection => @comments
  5 +end
  6 +page.replace_html "comment-count-#{@group_id}", @comments_count
  7 +
  8 +if @no_more_pages
  9 + page.replace_html "comments_list_group_#{@group_id}_more", ""
  10 +else
  11 + page.replace_html "comments_list_group_#{@group_id}_more", link_to_remote(_('More'), :url => { :profile => profile.identifier, :controller => 'comment_group_plugin_profile', :action => 'view_comments', :group_id => @group_id, :article_id => @article_id, :group_comment_page => @group_comment_page + 1}, :loaded => visual_effect(:highlight, "comments_list_group_#{@group_id}"), :method => :post, :complete => "loadCompleted(#{@group_id})")
  12 +end
... ...
plugins/community_track/lib/community_track_plugin/step.rb
... ... @@ -7,7 +7,7 @@ class CommunityTrackPlugin::Step &lt; Folder
7 7 acts_as_list :scope => :parent
8 8  
9 9 def belong_to_track
10   - errors.add(:parent, "Step not allowed at this parent.") if !parent.kind_of?(CommunityTrackPlugin::Track)
  10 + errors.add(:parent, _("Step not allowed at this parent.")) unless parent.kind_of?(CommunityTrackPlugin::Track)
11 11 end
12 12  
13 13 validate :belong_to_track
... ...
plugins/community_track/lib/community_track_plugin/track.rb
... ... @@ -49,8 +49,8 @@ class CommunityTrackPlugin::Track &lt; Folder
49 49 "community-track-plugin-track"
50 50 end
51 51  
52   - #FIXME make this test
53 52 def first_paragraph
  53 + return '' if body.blank?
54 54 paragraphs = Hpricot(body).search('p')
55 55 paragraphs.empty? ? '' : paragraphs.first.to_html
56 56 end
... ...
plugins/community_track/public/icons/calendar.png 0 → 100644

604 Bytes

plugins/community_track/public/style.css
... ... @@ -193,3 +193,9 @@
193 193 .community-track textarea {
194 194 width: 100%;
195 195 }
  196 +
  197 +.formfield input#datepicker-from-date,
  198 +.formfield input#datepicker-to-date {
  199 + width: 115px;
  200 + background: url(/plugins/community_track/icons/calendar.png) right center no-repeat;
  201 +}
... ...
plugins/community_track/test/unit/community_track_plugin/track_test.rb
... ... @@ -110,4 +110,18 @@ class TrackTest &lt; ActiveSupport::TestCase
110 110 assert_equal [hidden_step], @track.hidden_steps
111 111 end
112 112  
  113 + should 'get first paragraph' do
  114 + @track.body = '<p>First</p><p>Second</p>'
  115 + assert_equal '<p>First</p>', @track.first_paragraph
  116 + end
  117 +
  118 + should 'provide first_paragraph even if body was not given' do
  119 + assert_equal '', @track.first_paragraph
  120 + end
  121 +
  122 + should 'provide first_paragraph even if body is nil' do
  123 + @track.body = nil
  124 + assert_equal '', @track.first_paragraph
  125 + end
  126 +
113 127 end
... ...
plugins/community_track/views/cms/community_track_plugin/_step.rhtml
... ... @@ -4,8 +4,14 @@
4 4  
5 5 <div>
6 6 <%= required f.text_field('name', :size => '64', :maxlength => 150) %>
7   - <%= labelled_form_field(_('Start date'), pick_date(:article, :start_date)) %>
8   - <%= labelled_form_field(_('End date'), pick_date(:article, :end_date)) %>
  7 + <%= labelled_form_field(_('Period'), (
  8 + date_range_field('article[start_date]', 'article[end_date]', @article.start_date, @article.end_date,
  9 + '%Y-%m-%d',
  10 + { :change_month => true, :change_year => true,
  11 + :date_format => 'yy-mm-dd' },
  12 + { :size => 14 })
  13 + )) %>
  14 +
9 15 </div>
10 16  
11 17 <%= labelled_form_field check_box(:article, :hidden) + _('Hidden Step'), '' %>
... ...
public/designs/icons/tango/mod/16x16/actions/go-home-not.png 0 → 100644

1.02 KB

public/designs/icons/tango/mod/scalable/actions/go-home-not.svg 0 → 100644
... ... @@ -0,0 +1,1112 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<svg
  3 + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
  4 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  5 + xmlns:cc="http://creativecommons.org/ns#"
  6 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  7 + xmlns:svg="http://www.w3.org/2000/svg"
  8 + xmlns="http://www.w3.org/2000/svg"
  9 + xmlns:xlink="http://www.w3.org/1999/xlink"
  10 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  11 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  12 + width="48"
  13 + height="48"
  14 + overflow="visible"
  15 + enable-background="new 0 0 128 129.396"
  16 + xml:space="preserve"
  17 + id="svg2"
  18 + sodipodi:version="0.32"
  19 + inkscape:version="0.48.1 r9760"
  20 + sodipodi:docname="go-home-not.svg"
  21 + version="1.0"
  22 + inkscape:export-filename="/home/85902810515/projetos/noosfero/public/designs/icons/tango/mod/16x16/actions/go-home-not.png"
  23 + inkscape:export-xdpi="30.01"
  24 + inkscape:export-ydpi="30.01"
  25 + inkscape:output_extension="org.inkscape.output.svg.inkscape"
  26 + style="display:inline;overflow:visible"><metadata
  27 + id="metadata367"><rdf:RDF><cc:Work
  28 + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
  29 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license
  30 + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /><dc:title></dc:title><dc:creator><cc:Agent><dc:title>Jakub Steiner</dc:title></cc:Agent></dc:creator><dc:source>http://jimmac.musichall.cz</dc:source><dc:subject><rdf:Bag><rdf:li>home</rdf:li><rdf:li>return</rdf:li><rdf:li>go</rdf:li><rdf:li>default</rdf:li><rdf:li>user</rdf:li><rdf:li>directory</rdf:li></rdf:Bag></dc:subject><dc:contributor><cc:Agent><dc:title>Tuomas Kuosmanen</dc:title></cc:Agent></dc:contributor></cc:Work><cc:License
  31 + rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits
  32 + rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
  33 + rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits
  34 + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF></metadata><defs
  35 + id="defs365"><linearGradient
  36 + id="linearGradient4711"><stop
  37 + style="stop-color:#f87171;stop-opacity:1;"
  38 + offset="0"
  39 + id="stop4713" /><stop
  40 + style="stop-color:#fb1f22;stop-opacity:1;"
  41 + offset="1"
  42 + id="stop4715" /></linearGradient><linearGradient
  43 + id="linearGradient4700"><stop
  44 + style="stop-color:#b20000;stop-opacity:1;"
  45 + offset="0"
  46 + id="stop4702" /><stop
  47 + style="stop-color:#db0000;stop-opacity:1;"
  48 + offset="1"
  49 + id="stop4704" /></linearGradient><linearGradient
  50 + id="linearGradient4694"
  51 + osb:paint="solid"><stop
  52 + style="stop-color:#2042e2;stop-opacity:1;"
  53 + offset="0"
  54 + id="stop4696" /></linearGradient><inkscape:perspective
  55 + sodipodi:type="inkscape:persp3d"
  56 + inkscape:vp_x="0 : 24 : 1"
  57 + inkscape:vp_y="0 : 1000 : 0"
  58 + inkscape:vp_z="48 : 24 : 1"
  59 + inkscape:persp3d-origin="24 : 16 : 1"
  60 + id="perspective92" /><radialGradient
  61 + inkscape:collect="always"
  62 + xlink:href="#linearGradient5060"
  63 + id="radialGradient5031"
  64 + gradientUnits="userSpaceOnUse"
  65 + gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
  66 + cx="605.71429"
  67 + cy="486.64789"
  68 + fx="605.71429"
  69 + fy="486.64789"
  70 + r="117.14286" /><linearGradient
  71 + inkscape:collect="always"
  72 + id="linearGradient5060"><stop
  73 + style="stop-color:black;stop-opacity:1;"
  74 + offset="0"
  75 + id="stop5062" /><stop
  76 + style="stop-color:black;stop-opacity:0;"
  77 + offset="1"
  78 + id="stop5064" /></linearGradient><radialGradient
  79 + inkscape:collect="always"
  80 + xlink:href="#linearGradient5060"
  81 + id="radialGradient5029"
  82 + gradientUnits="userSpaceOnUse"
  83 + gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
  84 + cx="605.71429"
  85 + cy="486.64789"
  86 + fx="605.71429"
  87 + fy="486.64789"
  88 + r="117.14286" /><linearGradient
  89 + id="linearGradient5048"><stop
  90 + style="stop-color:black;stop-opacity:0;"
  91 + offset="0"
  92 + id="stop5050" /><stop
  93 + id="stop5056"
  94 + offset="0.5"
  95 + style="stop-color:black;stop-opacity:1;" /><stop
  96 + style="stop-color:black;stop-opacity:0;"
  97 + offset="1"
  98 + id="stop5052" /></linearGradient><linearGradient
  99 + inkscape:collect="always"
  100 + xlink:href="#linearGradient5048"
  101 + id="linearGradient5027"
  102 + gradientUnits="userSpaceOnUse"
  103 + gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
  104 + x1="302.85715"
  105 + y1="366.64789"
  106 + x2="302.85715"
  107 + y2="609.50507" /><linearGradient
  108 + id="linearGradient2406"><stop
  109 + style="stop-color:#7c7e79;stop-opacity:1;"
  110 + offset="0"
  111 + id="stop2408" /><stop
  112 + id="stop2414"
  113 + offset="0.1724138"
  114 + style="stop-color:#848681;stop-opacity:1;" /><stop
  115 + style="stop-color:#898c86;stop-opacity:1;"
  116 + offset="1"
  117 + id="stop2410" /></linearGradient><linearGradient
  118 + inkscape:collect="always"
  119 + id="linearGradient2390"><stop
  120 + style="stop-color:#919191;stop-opacity:1;"
  121 + offset="0"
  122 + id="stop2392" /><stop
  123 + style="stop-color:#919191;stop-opacity:0;"
  124 + offset="1"
  125 + id="stop2394" /></linearGradient><linearGradient
  126 + inkscape:collect="always"
  127 + id="linearGradient2378"><stop
  128 + style="stop-color:#575757;stop-opacity:1;"
  129 + offset="0"
  130 + id="stop2380" /><stop
  131 + style="stop-color:#575757;stop-opacity:0;"
  132 + offset="1"
  133 + id="stop2382" /></linearGradient><linearGradient
  134 + inkscape:collect="always"
  135 + id="linearGradient2368"><stop
  136 + style="stop-color:#ffffff;stop-opacity:1;"
  137 + offset="0"
  138 + id="stop2370" /><stop
  139 + style="stop-color:#ffffff;stop-opacity:0;"
  140 + offset="1"
  141 + id="stop2372" /></linearGradient><linearGradient
  142 + inkscape:collect="always"
  143 + id="linearGradient2349"><stop
  144 + style="stop-color:#000000;stop-opacity:1;"
  145 + offset="0"
  146 + id="stop2351" /><stop
  147 + style="stop-color:#000000;stop-opacity:0;"
  148 + offset="1"
  149 + id="stop2353" /></linearGradient><linearGradient
  150 + id="linearGradient2341"><stop
  151 + id="stop2343"
  152 + offset="0"
  153 + style="stop-color:#000000;stop-opacity:1;" /><stop
  154 + id="stop2345"
  155 + offset="1"
  156 + style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient
  157 + id="linearGradient2329"><stop
  158 + style="stop-color:#000000;stop-opacity:0.18556701;"
  159 + offset="0"
  160 + id="stop2331" /><stop
  161 + style="stop-color:#ffffff;stop-opacity:1;"
  162 + offset="1"
  163 + id="stop2333" /></linearGradient><linearGradient
  164 + inkscape:collect="always"
  165 + id="linearGradient2319"><stop
  166 + style="stop-color:#000000;stop-opacity:1;"
  167 + offset="0"
  168 + id="stop2321" /><stop
  169 + style="stop-color:#000000;stop-opacity:0;"
  170 + offset="1"
  171 + id="stop2323" /></linearGradient><linearGradient
  172 + id="linearGradient2307"><stop
  173 + style="stop-color:#edd400;stop-opacity:1;"
  174 + offset="0"
  175 + id="stop2309" /><stop
  176 + style="stop-color:#998800;stop-opacity:1;"
  177 + offset="1"
  178 + id="stop2311" /></linearGradient><linearGradient
  179 + inkscape:collect="always"
  180 + id="linearGradient2299"><stop
  181 + style="stop-color:#ffffff;stop-opacity:1;"
  182 + offset="0"
  183 + id="stop2301" /><stop
  184 + style="stop-color:#ffffff;stop-opacity:0;"
  185 + offset="1"
  186 + id="stop2303" /></linearGradient><linearGradient
  187 + id="XMLID_2_"
  188 + gradientUnits="userSpaceOnUse"
  189 + x1="80.223602"
  190 + y1="117.5205"
  191 + x2="48.046001"
  192 + y2="59.7995"
  193 + gradientTransform="matrix(0.314683,0,0,0.314683,4.128264,3.742874)">
  194 + <stop
  195 + offset="0"
  196 + style="stop-color:#CCCCCC"
  197 + id="stop17" />
  198 + <stop
  199 + offset="0.9831"
  200 + style="stop-color:#FFFFFF"
  201 + id="stop19" />
  202 + <midPointStop
  203 + offset="0"
  204 + style="stop-color:#CCCCCC"
  205 + id="midPointStop48" />
  206 + <midPointStop
  207 + offset="0.5"
  208 + style="stop-color:#CCCCCC"
  209 + id="midPointStop50" />
  210 + <midPointStop
  211 + offset="0.9831"
  212 + style="stop-color:#FFFFFF"
  213 + id="midPointStop52" />
  214 + </linearGradient><linearGradient
  215 + inkscape:collect="always"
  216 + xlink:href="#XMLID_2_"
  217 + id="linearGradient1514"
  218 + gradientUnits="userSpaceOnUse"
  219 + gradientTransform="matrix(0.336922,0,0,0.166888,17.98288,15.46151)"
  220 + x1="52.006104"
  221 + y1="166.1331"
  222 + x2="14.049017"
  223 + y2="-42.218513" /><linearGradient
  224 + id="XMLID_39_"
  225 + gradientUnits="userSpaceOnUse"
  226 + x1="64.387703"
  227 + y1="65.124001"
  228 + x2="64.387703"
  229 + y2="35.569"
  230 + gradientTransform="matrix(0.354101,0,0,0.354101,1.638679,-0.08364921)">
  231 + <stop
  232 + offset="0"
  233 + style="stop-color:#FFFFFF"
  234 + id="stop336" />
  235 + <stop
  236 + offset="0.8539"
  237 + style="stop-color:#FF6200"
  238 + id="stop338" />
  239 + <stop
  240 + offset="1"
  241 + style="stop-color:#F25D00"
  242 + id="stop340" />
  243 + <midPointStop
  244 + offset="0"
  245 + style="stop-color:#FFFFFF"
  246 + id="midPointStop335" />
  247 + <midPointStop
  248 + offset="0.5"
  249 + style="stop-color:#FFFFFF"
  250 + id="midPointStop337" />
  251 + <midPointStop
  252 + offset="0.8539"
  253 + style="stop-color:#FF6200"
  254 + id="midPointStop339" />
  255 + <midPointStop
  256 + offset="0.5"
  257 + style="stop-color:#FF6200"
  258 + id="midPointStop341" />
  259 + <midPointStop
  260 + offset="1"
  261 + style="stop-color:#F25D00"
  262 + id="midPointStop343" />
  263 + </linearGradient><radialGradient
  264 + inkscape:collect="always"
  265 + xlink:href="#linearGradient2299"
  266 + id="radialGradient2305"
  267 + cx="7.5326638"
  268 + cy="24.202574"
  269 + fx="7.5326638"
  270 + fy="24.202574"
  271 + r="8.2452126"
  272 + gradientTransform="matrix(4.100086,0,0,4.201322,-25.41506,-78.53967)"
  273 + gradientUnits="userSpaceOnUse" /><radialGradient
  274 + inkscape:collect="always"
  275 + xlink:href="#linearGradient2307"
  276 + id="radialGradient2313"
  277 + cx="19.985598"
  278 + cy="36.77816"
  279 + fx="19.985598"
  280 + fy="36.77816"
  281 + r="1.0821035"
  282 + gradientTransform="matrix(1.125263,0,0,0.982744,-3.428678,0.565787)"
  283 + gradientUnits="userSpaceOnUse" /><radialGradient
  284 + inkscape:collect="always"
  285 + xlink:href="#linearGradient2319"
  286 + id="radialGradient2325"
  287 + cx="20.443665"
  288 + cy="37.425831"
  289 + fx="20.443665"
  290 + fy="37.425831"
  291 + r="1.0821035"
  292 + gradientTransform="matrix(1.125263,0,0,0.982744,-3.428678,0.731106)"
  293 + gradientUnits="userSpaceOnUse" /><linearGradient
  294 + inkscape:collect="always"
  295 + xlink:href="#linearGradient2329"
  296 + id="linearGradient2335"
  297 + x1="17.602522"
  298 + y1="26.057423"
  299 + x2="17.682528"
  300 + y2="32.654099"
  301 + gradientUnits="userSpaceOnUse"
  302 + gradientTransform="matrix(0.898789,0,0,1.071914,0.478025,-2.080838)" /><radialGradient
  303 + inkscape:collect="always"
  304 + xlink:href="#linearGradient2341"
  305 + id="radialGradient2339"
  306 + gradientUnits="userSpaceOnUse"
  307 + gradientTransform="matrix(4.100086,0,0,-4.201322,-5.198109,105.3535)"
  308 + cx="11.68129"
  309 + cy="19.554111"
  310 + fx="11.68129"
  311 + fy="19.554111"
  312 + r="8.2452126" /><radialGradient
  313 + inkscape:collect="always"
  314 + xlink:href="#linearGradient2349"
  315 + id="radialGradient2355"
  316 + cx="24.023088"
  317 + cy="40.56913"
  318 + fx="24.023088"
  319 + fy="40.56913"
  320 + r="16.28684"
  321 + gradientTransform="matrix(1,0,0,0.43125,0,23.07369)"
  322 + gradientUnits="userSpaceOnUse" /><radialGradient
  323 + inkscape:collect="always"
  324 + xlink:href="#linearGradient2368"
  325 + id="radialGradient2374"
  326 + cx="29.913452"
  327 + cy="30.442923"
  328 + fx="29.913452"
  329 + fy="30.442923"
  330 + r="4.001883"
  331 + gradientTransform="matrix(3.751495,0,0,3.147818,-82.00907,-65.70704)"
  332 + gradientUnits="userSpaceOnUse" /><radialGradient
  333 + inkscape:collect="always"
  334 + xlink:href="#linearGradient2378"
  335 + id="radialGradient2384"
  336 + cx="24.195112"
  337 + cy="10.577631"
  338 + fx="24.195112"
  339 + fy="10.577631"
  340 + r="15.242914"
  341 + gradientTransform="matrix(1.125263,-3.585417e-8,4.269819e-8,1.340059,-3.006704,1.355395)"
  342 + gradientUnits="userSpaceOnUse" /><linearGradient
  343 + inkscape:collect="always"
  344 + xlink:href="#linearGradient2390"
  345 + id="linearGradient2396"
  346 + x1="30.603519"
  347 + y1="37.337803"
  348 + x2="30.603519"
  349 + y2="36.112415"
  350 + gradientUnits="userSpaceOnUse"
  351 + gradientTransform="matrix(1.263867,0,0,0.859794,-6.499556,8.390924)" /><linearGradient
  352 + inkscape:collect="always"
  353 + xlink:href="#linearGradient2406"
  354 + id="linearGradient2412"
  355 + x1="17.850183"
  356 + y1="28.939463"
  357 + x2="19.040216"
  358 + y2="41.03223"
  359 + gradientUnits="userSpaceOnUse"
  360 + gradientTransform="matrix(0.888785,0,0,1.08932,2.41099,-1.524336)" /><radialGradient
  361 + inkscape:collect="always"
  362 + xlink:href="#linearGradient9647"
  363 + id="radialGradient2239"
  364 + cx="24.30225"
  365 + cy="33.30225"
  366 + fx="24.30225"
  367 + fy="33.30225"
  368 + r="12.30225"
  369 + gradientUnits="userSpaceOnUse"
  370 + gradientTransform="matrix(1.693981,0,0,1.693981,-16.86529,-25.11111)" /><linearGradient
  371 + id="linearGradient9647"><stop
  372 + style="stop-color:#ffffff;stop-opacity:1;"
  373 + offset="0"
  374 + id="stop9649" /><stop
  375 + style="stop-color:#dbdbdb;stop-opacity:1;"
  376 + offset="1"
  377 + id="stop9651" /></linearGradient><linearGradient
  378 + inkscape:collect="always"
  379 + xlink:href="#linearGradient2256"
  380 + id="linearGradient2262"
  381 + x1="21.75"
  382 + y1="15.80225"
  383 + x2="24.30225"
  384 + y2="35.05225"
  385 + gradientUnits="userSpaceOnUse"
  386 + gradientTransform="translate(0,-2)" /><linearGradient
  387 + id="linearGradient2256"><stop
  388 + style="stop-color:#ff0202;stop-opacity:1;"
  389 + offset="0"
  390 + id="stop2258" /><stop
  391 + style="stop-color:#ff9b9b;stop-opacity:1;"
  392 + offset="1"
  393 + id="stop2260" /></linearGradient><radialGradient
  394 + r="12.30225"
  395 + fy="33.30225"
  396 + fx="24.30225"
  397 + cy="33.30225"
  398 + cx="24.30225"
  399 + gradientTransform="matrix(1.693981,0,0,1.693981,-5.6354248,-11.964506)"
  400 + gradientUnits="userSpaceOnUse"
  401 + id="radialGradient3047"
  402 + xlink:href="#linearGradient9647"
  403 + inkscape:collect="always" /><linearGradient
  404 + y2="35.05225"
  405 + x2="24.30225"
  406 + y1="15.80225"
  407 + x1="21.75"
  408 + gradientTransform="translate(11.229865,11.146604)"
  409 + gradientUnits="userSpaceOnUse"
  410 + id="linearGradient3049"
  411 + xlink:href="#linearGradient2256"
  412 + inkscape:collect="always" /><radialGradient
  413 + inkscape:collect="always"
  414 + xlink:href="#linearGradient21644"
  415 + id="radialGradient21650"
  416 + cx="25.125"
  417 + cy="36.75"
  418 + fx="25.125"
  419 + fy="36.75"
  420 + r="15.75"
  421 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  422 + gradientUnits="userSpaceOnUse" /><linearGradient
  423 + inkscape:collect="always"
  424 + id="linearGradient21644"><stop
  425 + style="stop-color:#000000;stop-opacity:1;"
  426 + offset="0"
  427 + id="stop21646" /><stop
  428 + style="stop-color:#000000;stop-opacity:0;"
  429 + offset="1"
  430 + id="stop21648" /></linearGradient><linearGradient
  431 + inkscape:collect="always"
  432 + xlink:href="#linearGradient4981"
  433 + id="linearGradient4987"
  434 + x1="23.995985"
  435 + y1="20.105337"
  436 + x2="41.047836"
  437 + y2="37.959785"
  438 + gradientUnits="userSpaceOnUse"
  439 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  440 + id="linearGradient4981"><stop
  441 + style="stop-color:#cc0000;stop-opacity:1;"
  442 + offset="0"
  443 + id="stop4983" /><stop
  444 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  445 + offset="1.0000000"
  446 + id="stop4985" /></linearGradient><linearGradient
  447 + inkscape:collect="always"
  448 + xlink:href="#linearGradient11780"
  449 + id="linearGradient2057"
  450 + x1="15.737001"
  451 + y1="12.5036"
  452 + x2="53.570126"
  453 + y2="47.374317"
  454 + gradientUnits="userSpaceOnUse"
  455 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  456 + id="linearGradient11780"><stop
  457 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  458 + offset="0.0000000"
  459 + id="stop11782" /><stop
  460 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  461 + offset="1.0000000"
  462 + id="stop11784" /></linearGradient><radialGradient
  463 + inkscape:collect="always"
  464 + xlink:href="#linearGradient2248"
  465 + id="radialGradient2254"
  466 + cx="16.75"
  467 + cy="10.666344"
  468 + fx="16.75"
  469 + fy="10.666344"
  470 + r="21.25"
  471 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  472 + gradientUnits="userSpaceOnUse" /><linearGradient
  473 + inkscape:collect="always"
  474 + id="linearGradient2248"><stop
  475 + style="stop-color:#ffffff;stop-opacity:1;"
  476 + offset="0"
  477 + id="stop2250" /><stop
  478 + style="stop-color:#ffffff;stop-opacity:0;"
  479 + offset="1"
  480 + id="stop2252" /></linearGradient><radialGradient
  481 + inkscape:collect="always"
  482 + xlink:href="#linearGradient9647-3"
  483 + id="radialGradient2239-7"
  484 + cx="24.30225"
  485 + cy="33.30225"
  486 + fx="24.30225"
  487 + fy="33.30225"
  488 + r="12.30225"
  489 + gradientUnits="userSpaceOnUse"
  490 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)" /><linearGradient
  491 + id="linearGradient9647-3"><stop
  492 + style="stop-color:#ffffff;stop-opacity:1;"
  493 + offset="0"
  494 + id="stop9649-3" /><stop
  495 + style="stop-color:#dbdbdb;stop-opacity:1;"
  496 + offset="1"
  497 + id="stop9651-2" /></linearGradient><linearGradient
  498 + inkscape:collect="always"
  499 + xlink:href="#linearGradient2256-0"
  500 + id="linearGradient2262-5"
  501 + x1="21.75"
  502 + y1="15.80225"
  503 + x2="24.30225"
  504 + y2="35.05225"
  505 + gradientUnits="userSpaceOnUse"
  506 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  507 + id="linearGradient2256-0"><stop
  508 + style="stop-color:#ff0202;stop-opacity:1;"
  509 + offset="0"
  510 + id="stop2258-2" /><stop
  511 + style="stop-color:#ff9b9b;stop-opacity:1;"
  512 + offset="1"
  513 + id="stop2260-8" /></linearGradient><radialGradient
  514 + r="15.75"
  515 + fy="36.75"
  516 + fx="25.125"
  517 + cy="36.75"
  518 + cx="25.125"
  519 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  520 + gradientUnits="userSpaceOnUse"
  521 + id="radialGradient3090"
  522 + xlink:href="#linearGradient21644"
  523 + inkscape:collect="always" /><radialGradient
  524 + inkscape:collect="always"
  525 + xlink:href="#linearGradient21644"
  526 + id="radialGradient3205"
  527 + gradientUnits="userSpaceOnUse"
  528 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  529 + cx="25.125"
  530 + cy="36.75"
  531 + fx="25.125"
  532 + fy="36.75"
  533 + r="15.75" /><linearGradient
  534 + inkscape:collect="always"
  535 + xlink:href="#linearGradient4981"
  536 + id="linearGradient3207"
  537 + gradientUnits="userSpaceOnUse"
  538 + gradientTransform="translate(23.026616,19.550612)"
  539 + x1="23.995985"
  540 + y1="20.105337"
  541 + x2="41.047836"
  542 + y2="37.959785" /><linearGradient
  543 + inkscape:collect="always"
  544 + xlink:href="#linearGradient11780"
  545 + id="linearGradient3209"
  546 + gradientUnits="userSpaceOnUse"
  547 + gradientTransform="translate(23.026616,19.550612)"
  548 + x1="15.737001"
  549 + y1="12.5036"
  550 + x2="53.570126"
  551 + y2="47.374317" /><radialGradient
  552 + inkscape:collect="always"
  553 + xlink:href="#linearGradient2248"
  554 + id="radialGradient3211"
  555 + gradientUnits="userSpaceOnUse"
  556 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  557 + cx="16.75"
  558 + cy="10.666344"
  559 + fx="16.75"
  560 + fy="10.666344"
  561 + r="21.25" /><radialGradient
  562 + inkscape:collect="always"
  563 + xlink:href="#linearGradient9647-3"
  564 + id="radialGradient3213"
  565 + gradientUnits="userSpaceOnUse"
  566 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  567 + cx="24.30225"
  568 + cy="33.30225"
  569 + fx="24.30225"
  570 + fy="33.30225"
  571 + r="12.30225" /><linearGradient
  572 + inkscape:collect="always"
  573 + xlink:href="#linearGradient2256-0"
  574 + id="linearGradient3215"
  575 + gradientUnits="userSpaceOnUse"
  576 + gradientTransform="translate(23.026616,19.550612)"
  577 + x1="21.75"
  578 + y1="15.80225"
  579 + x2="24.30225"
  580 + y2="35.05225" /><radialGradient
  581 + inkscape:collect="always"
  582 + xlink:href="#linearGradient21644"
  583 + id="radialGradient3218"
  584 + gradientUnits="userSpaceOnUse"
  585 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  586 + cx="25.125"
  587 + cy="36.75"
  588 + fx="25.125"
  589 + fy="36.75"
  590 + r="15.75" /><linearGradient
  591 + inkscape:collect="always"
  592 + xlink:href="#linearGradient4981"
  593 + id="linearGradient3221"
  594 + gradientUnits="userSpaceOnUse"
  595 + gradientTransform="translate(23.026616,19.550612)"
  596 + x1="23.995985"
  597 + y1="20.105337"
  598 + x2="41.047836"
  599 + y2="37.959785" /><linearGradient
  600 + inkscape:collect="always"
  601 + xlink:href="#linearGradient11780"
  602 + id="linearGradient3224"
  603 + gradientUnits="userSpaceOnUse"
  604 + gradientTransform="translate(23.026616,19.550612)"
  605 + x1="15.737001"
  606 + y1="12.5036"
  607 + x2="53.570126"
  608 + y2="47.374317" /><radialGradient
  609 + inkscape:collect="always"
  610 + xlink:href="#linearGradient2248"
  611 + id="radialGradient3227"
  612 + gradientUnits="userSpaceOnUse"
  613 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  614 + cx="16.75"
  615 + cy="10.666344"
  616 + fx="16.75"
  617 + fy="10.666344"
  618 + r="21.25" /><radialGradient
  619 + inkscape:collect="always"
  620 + xlink:href="#linearGradient9647-3"
  621 + id="radialGradient3230"
  622 + gradientUnits="userSpaceOnUse"
  623 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  624 + cx="24.30225"
  625 + cy="33.30225"
  626 + fx="24.30225"
  627 + fy="33.30225"
  628 + r="12.30225" /><linearGradient
  629 + inkscape:collect="always"
  630 + xlink:href="#linearGradient2256-0"
  631 + id="linearGradient3232"
  632 + gradientUnits="userSpaceOnUse"
  633 + gradientTransform="translate(23.026616,19.550612)"
  634 + x1="21.75"
  635 + y1="15.80225"
  636 + x2="24.30225"
  637 + y2="35.05225" /><radialGradient
  638 + inkscape:collect="always"
  639 + xlink:href="#linearGradient21644-3"
  640 + id="radialGradient3218-2"
  641 + gradientUnits="userSpaceOnUse"
  642 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  643 + cx="25.125"
  644 + cy="36.75"
  645 + fx="25.125"
  646 + fy="36.75"
  647 + r="15.75" /><linearGradient
  648 + inkscape:collect="always"
  649 + id="linearGradient21644-3"><stop
  650 + style="stop-color:#000000;stop-opacity:1;"
  651 + offset="0"
  652 + id="stop21646-9" /><stop
  653 + style="stop-color:#000000;stop-opacity:0;"
  654 + offset="1"
  655 + id="stop21648-9" /></linearGradient><linearGradient
  656 + inkscape:collect="always"
  657 + xlink:href="#linearGradient4981-1"
  658 + id="linearGradient3221-9"
  659 + gradientUnits="userSpaceOnUse"
  660 + gradientTransform="translate(23.026616,19.550612)"
  661 + x1="23.995985"
  662 + y1="20.105337"
  663 + x2="41.047836"
  664 + y2="37.959785" /><linearGradient
  665 + id="linearGradient4981-1"><stop
  666 + style="stop-color:#cc0000;stop-opacity:1;"
  667 + offset="0"
  668 + id="stop4983-4" /><stop
  669 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  670 + offset="1.0000000"
  671 + id="stop4985-7" /></linearGradient><linearGradient
  672 + inkscape:collect="always"
  673 + xlink:href="#linearGradient11780-3"
  674 + id="linearGradient3224-7"
  675 + gradientUnits="userSpaceOnUse"
  676 + gradientTransform="translate(23.026616,19.550612)"
  677 + x1="15.737001"
  678 + y1="12.5036"
  679 + x2="53.570126"
  680 + y2="47.374317" /><linearGradient
  681 + id="linearGradient11780-3"><stop
  682 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  683 + offset="0.0000000"
  684 + id="stop11782-9" /><stop
  685 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  686 + offset="1.0000000"
  687 + id="stop11784-6" /></linearGradient><radialGradient
  688 + inkscape:collect="always"
  689 + xlink:href="#linearGradient2248-9"
  690 + id="radialGradient3227-6"
  691 + gradientUnits="userSpaceOnUse"
  692 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  693 + cx="16.75"
  694 + cy="10.666344"
  695 + fx="16.75"
  696 + fy="10.666344"
  697 + r="21.25" /><linearGradient
  698 + inkscape:collect="always"
  699 + id="linearGradient2248-9"><stop
  700 + style="stop-color:#ffffff;stop-opacity:1;"
  701 + offset="0"
  702 + id="stop2250-3" /><stop
  703 + style="stop-color:#ffffff;stop-opacity:0;"
  704 + offset="1"
  705 + id="stop2252-5" /></linearGradient><radialGradient
  706 + inkscape:collect="always"
  707 + xlink:href="#linearGradient9647-3-4"
  708 + id="radialGradient3230-9"
  709 + gradientUnits="userSpaceOnUse"
  710 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  711 + cx="24.30225"
  712 + cy="33.30225"
  713 + fx="24.30225"
  714 + fy="33.30225"
  715 + r="12.30225" /><linearGradient
  716 + id="linearGradient9647-3-4"><stop
  717 + style="stop-color:#ffffff;stop-opacity:1;"
  718 + offset="0"
  719 + id="stop9649-3-2" /><stop
  720 + style="stop-color:#dbdbdb;stop-opacity:1;"
  721 + offset="1"
  722 + id="stop9651-2-0" /></linearGradient><linearGradient
  723 + inkscape:collect="always"
  724 + xlink:href="#linearGradient2256-0-0"
  725 + id="linearGradient3232-1"
  726 + gradientUnits="userSpaceOnUse"
  727 + gradientTransform="translate(23.026616,19.550612)"
  728 + x1="21.75"
  729 + y1="15.80225"
  730 + x2="24.30225"
  731 + y2="35.05225" /><linearGradient
  732 + id="linearGradient2256-0-0"><stop
  733 + style="stop-color:#ff0202;stop-opacity:1;"
  734 + offset="0"
  735 + id="stop2258-2-7" /><stop
  736 + style="stop-color:#ff9b9b;stop-opacity:1;"
  737 + offset="1"
  738 + id="stop2260-8-0" /></linearGradient><radialGradient
  739 + r="12.30225"
  740 + fy="33.30225"
  741 + fx="24.30225"
  742 + cy="33.30225"
  743 + cx="24.30225"
  744 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  745 + gradientUnits="userSpaceOnUse"
  746 + id="radialGradient3276"
  747 + xlink:href="#linearGradient9647-3-4"
  748 + inkscape:collect="always" /><linearGradient
  749 + y2="35.05225"
  750 + x2="24.30225"
  751 + y1="15.80225"
  752 + x1="21.75"
  753 + gradientTransform="translate(23.026616,19.550612)"
  754 + gradientUnits="userSpaceOnUse"
  755 + id="linearGradient3278"
  756 + xlink:href="#linearGradient2256-0-0"
  757 + inkscape:collect="always" /><radialGradient
  758 + inkscape:collect="always"
  759 + xlink:href="#linearGradient21644-3-0"
  760 + id="radialGradient3218-2-4"
  761 + gradientUnits="userSpaceOnUse"
  762 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  763 + cx="25.125"
  764 + cy="36.75"
  765 + fx="25.125"
  766 + fy="36.75"
  767 + r="15.75" /><linearGradient
  768 + id="linearGradient21644-3-0"><stop
  769 + style="stop-color:#000000;stop-opacity:1;"
  770 + offset="0"
  771 + id="stop21646-9-1" /><stop
  772 + style="stop-color:#000000;stop-opacity:0;"
  773 + offset="1"
  774 + id="stop21648-9-8" /></linearGradient><linearGradient
  775 + inkscape:collect="always"
  776 + xlink:href="#linearGradient4981-1-6"
  777 + id="linearGradient3221-9-6"
  778 + gradientUnits="userSpaceOnUse"
  779 + gradientTransform="translate(23.026616,19.550612)"
  780 + x1="23.995985"
  781 + y1="20.105337"
  782 + x2="41.047836"
  783 + y2="37.959785" /><linearGradient
  784 + id="linearGradient4981-1-6"><stop
  785 + style="stop-color:#cc0000;stop-opacity:1;"
  786 + offset="0"
  787 + id="stop4983-4-0" /><stop
  788 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  789 + offset="1.0000000"
  790 + id="stop4985-7-7" /></linearGradient><linearGradient
  791 + inkscape:collect="always"
  792 + xlink:href="#linearGradient11780-3-5"
  793 + id="linearGradient3224-7-4"
  794 + gradientUnits="userSpaceOnUse"
  795 + gradientTransform="translate(23.026616,19.550612)"
  796 + x1="15.737001"
  797 + y1="12.5036"
  798 + x2="53.570126"
  799 + y2="47.374317" /><linearGradient
  800 + id="linearGradient11780-3-5"><stop
  801 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  802 + offset="0.0000000"
  803 + id="stop11782-9-4" /><stop
  804 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  805 + offset="1.0000000"
  806 + id="stop11784-6-8" /></linearGradient><radialGradient
  807 + inkscape:collect="always"
  808 + xlink:href="#linearGradient2248-9-9"
  809 + id="radialGradient3227-6-4"
  810 + gradientUnits="userSpaceOnUse"
  811 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  812 + cx="16.75"
  813 + cy="10.666344"
  814 + fx="16.75"
  815 + fy="10.666344"
  816 + r="21.25" /><linearGradient
  817 + inkscape:collect="always"
  818 + id="linearGradient2248-9-9"><stop
  819 + style="stop-color:#ffffff;stop-opacity:1;"
  820 + offset="0"
  821 + id="stop2250-3-5" /><stop
  822 + style="stop-color:#ffffff;stop-opacity:0;"
  823 + offset="1"
  824 + id="stop2252-5-3" /></linearGradient><radialGradient
  825 + r="12.30225"
  826 + fy="33.30225"
  827 + fx="24.30225"
  828 + cy="33.30225"
  829 + cx="24.30225"
  830 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  831 + gradientUnits="userSpaceOnUse"
  832 + id="radialGradient3276-7"
  833 + xlink:href="#linearGradient9647-3-4-6"
  834 + inkscape:collect="always" /><linearGradient
  835 + id="linearGradient9647-3-4-6"><stop
  836 + style="stop-color:#ffffff;stop-opacity:1;"
  837 + offset="0"
  838 + id="stop9649-3-2-7" /><stop
  839 + style="stop-color:#dbdbdb;stop-opacity:1;"
  840 + offset="1"
  841 + id="stop9651-2-0-1" /></linearGradient><linearGradient
  842 + y2="35.05225"
  843 + x2="24.30225"
  844 + y1="15.80225"
  845 + x1="21.75"
  846 + gradientTransform="translate(23.026616,19.550612)"
  847 + gradientUnits="userSpaceOnUse"
  848 + id="linearGradient3278-2"
  849 + xlink:href="#linearGradient2256-0-0-1"
  850 + inkscape:collect="always" /><linearGradient
  851 + id="linearGradient2256-0-0-1"><stop
  852 + style="stop-color:#ff0202;stop-opacity:1;"
  853 + offset="0"
  854 + id="stop2258-2-7-8" /><stop
  855 + style="stop-color:#ff9b9b;stop-opacity:1;"
  856 + offset="1"
  857 + id="stop2260-8-0-4" /></linearGradient><radialGradient
  858 + r="12.30225"
  859 + fy="33.30225"
  860 + fx="24.30225"
  861 + cy="33.30225"
  862 + cx="24.30225"
  863 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  864 + gradientUnits="userSpaceOnUse"
  865 + id="radialGradient3812"
  866 + xlink:href="#linearGradient9647-3-4-6"
  867 + inkscape:collect="always" /><linearGradient
  868 + y2="35.05225"
  869 + x2="24.30225"
  870 + y1="15.80225"
  871 + x1="21.75"
  872 + gradientTransform="translate(23.026616,19.550612)"
  873 + gradientUnits="userSpaceOnUse"
  874 + id="linearGradient3814"
  875 + xlink:href="#linearGradient2256-0-0-1"
  876 + inkscape:collect="always" /><radialGradient
  877 + inkscape:collect="always"
  878 + xlink:href="#linearGradient9647-3-4-6"
  879 + id="radialGradient3886"
  880 + gradientUnits="userSpaceOnUse"
  881 + gradientTransform="matrix(0.85754753,0,0,0.85754753,16.064712,11.20392)"
  882 + cx="24.30225"
  883 + cy="33.30225"
  884 + fx="24.30225"
  885 + fy="33.30225"
  886 + r="12.30225" /><linearGradient
  887 + inkscape:collect="always"
  888 + xlink:href="#linearGradient2256-0-0-1"
  889 + id="linearGradient3888"
  890 + gradientUnits="userSpaceOnUse"
  891 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  892 + x1="21.75"
  893 + y1="15.80225"
  894 + x2="24.30225"
  895 + y2="35.05225" /><radialGradient
  896 + inkscape:collect="always"
  897 + xlink:href="#linearGradient2248-9-9"
  898 + id="radialGradient3891"
  899 + gradientUnits="userSpaceOnUse"
  900 + gradientTransform="matrix(2.1094827,0,0,1.5765366,-2.293898,12.776643)"
  901 + cx="16.75"
  902 + cy="10.666344"
  903 + fx="16.75"
  904 + fy="10.666344"
  905 + r="21.25" /><linearGradient
  906 + inkscape:collect="always"
  907 + xlink:href="#linearGradient11780-3-5"
  908 + id="linearGradient3894"
  909 + gradientUnits="userSpaceOnUse"
  910 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  911 + x1="15.737001"
  912 + y1="12.5036"
  913 + x2="53.570126"
  914 + y2="47.374317" /><linearGradient
  915 + inkscape:collect="always"
  916 + xlink:href="#linearGradient4981-1-6"
  917 + id="linearGradient3897"
  918 + gradientUnits="userSpaceOnUse"
  919 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  920 + x1="23.995985"
  921 + y1="20.105337"
  922 + x2="41.047836"
  923 + y2="37.959785" /><radialGradient
  924 + inkscape:collect="always"
  925 + xlink:href="#linearGradient21644-3-0"
  926 + id="radialGradient3900"
  927 + gradientUnits="userSpaceOnUse"
  928 + gradientTransform="matrix(0.75877044,0,0,0.21650012,17.801926,37.031146)"
  929 + cx="25.125"
  930 + cy="36.75"
  931 + fx="25.125"
  932 + fy="36.75"
  933 + r="15.75" /><linearGradient
  934 + inkscape:collect="always"
  935 + xlink:href="#linearGradient4700"
  936 + id="linearGradient4706"
  937 + x1="42"
  938 + y1="40.46875"
  939 + x2="30.3125"
  940 + y2="29.09375"
  941 + gradientUnits="userSpaceOnUse" /><linearGradient
  942 + inkscape:collect="always"
  943 + xlink:href="#linearGradient4711"
  944 + id="linearGradient4717"
  945 + x1="29.3125"
  946 + y1="28.25"
  947 + x2="44.125"
  948 + y2="42.5625"
  949 + gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
  950 + inkscape:cy="18.229536"
  951 + inkscape:cx="35.718843"
  952 + inkscape:zoom="8"
  953 + inkscape:window-height="827"
  954 + inkscape:window-width="1440"
  955 + inkscape:pageshadow="2"
  956 + inkscape:pageopacity="0.0"
  957 + borderopacity="0.21568627"
  958 + bordercolor="#666666"
  959 + pagecolor="#ffffff"
  960 + id="base"
  961 + inkscape:showpageshadow="false"
  962 + inkscape:window-x="0"
  963 + inkscape:window-y="0"
  964 + inkscape:current-layer="layer3"
  965 + fill="#555753"
  966 + showgrid="false"
  967 + stroke="#a40000"
  968 + showguides="true"
  969 + inkscape:guide-bbox="true"
  970 + inkscape:window-maximized="1" />
  971 +
  972 +<g
  973 + inkscape:groupmode="layer"
  974 + id="layer1"
  975 + inkscape:label="Home"
  976 + style="display:inline"
  977 + sodipodi:insensitive="true"><g
  978 + style="display:inline;overflow:visible"
  979 + id="g3710"><g
  980 + transform="matrix(0.02158196,0,0,0.01859457,43.12251,41.63767)"
  981 + id="g5022"
  982 + style="display:inline"><rect
  983 + style="opacity:0.40206185;color:#000000;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  984 + id="rect4173"
  985 + width="1339.6335"
  986 + height="478.35718"
  987 + x="-1559.2523"
  988 + y="-150.69685" /><path
  989 + inkscape:connector-curvature="0"
  990 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  991 + d="m -219.61876,-150.68038 c 0,0 0,478.33079 0,478.33079 142.874166,0.90045 345.40022,-107.16966 345.40014,-239.196175 0,-132.026537 -159.436816,-239.134595 -345.40014,-239.134615 z"
  992 + id="path5058"
  993 + sodipodi:nodetypes="cccc" /><path
  994 + inkscape:connector-curvature="0"
  995 + sodipodi:nodetypes="cccc"
  996 + id="path5018"
  997 + d="m -1559.2523,-150.68038 c 0,0 0,478.33079 0,478.33079 -142.8742,0.90045 -345.4002,-107.16966 -345.4002,-239.196175 0,-132.026537 159.4368,-239.134595 345.4002,-239.134615 z"
  998 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /></g><path
  999 + inkscape:connector-curvature="0"
  1000 + sodipodi:nodetypes="ccccccccc"
  1001 + id="rect1512"
  1002 + d="m 21.619576,8.1833733 5.957459,0 c 0.839732,0 13.886475,15.4353277 13.886475,16.3406587 l -0.443521,18.496745 c 0,0.905333 -0.67603,1.634177 -1.515762,1.634177 l -31.4572774,0 c -0.8397329,0 -1.5157625,-0.728844 -1.5157625,-1.634177 l 0.056478,-18.496745 c 0,-0.905331 14.1921789,-16.3406587 15.0319109,-16.3406587 z"
  1003 + style="color:#000000;fill:url(#linearGradient1514);fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1004 + inkscape:connector-curvature="0"
  1005 + d="m 46.963575,45.735573 -45.3248988,0 0,-45.32489746 45.3248988,0 0,45.32489746 z"
  1006 + id="path5"
  1007 + style="fill:none" /><path
  1008 + inkscape:connector-curvature="0"
  1009 + sodipodi:nodetypes="ccccc"
  1010 + clip-rule="evenodd"
  1011 + d="m 23,29 -0.04574,15.090942 -11.842791,0 L 11,29 23,29 z"
  1012 + id="path2327"
  1013 + style="fill:url(#linearGradient2335);fill-opacity:1;fill-rule:evenodd" /><path
  1014 + inkscape:connector-curvature="0"
  1015 + style="opacity:0.3125;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
  1016 + d="m 21.780459,9.405584 5.559097,0 c 0.783582,0 13.000869,14.399588 13.000869,15.244172 l -0.347158,18.212311 c 0,0.459259 -0.143737,0.653465 -0.512375,0.653465 l -31.3872026,0.01428 c -0.3686377,0 -0.5839636,-0.07992 -0.5839636,-0.45355 L 7.7250676,24.649756 c 0,-0.844584 13.2718124,-15.244172 14.0553914,-15.244172 z"
  1017 + id="path2357"
  1018 + sodipodi:nodetypes="ccccccccc" /><path
  1019 + inkscape:connector-curvature="0"
  1020 + sodipodi:nodetypes="ccccccc"
  1021 + style="opacity:0.2;fill:url(#radialGradient2384);fill-opacity:1;fill-rule:evenodd"
  1022 + id="path23"
  1023 + d="M 7.2075295,27.943053 7.1532728,30.538247 25.521437,17.358993 40.807832,28.513421 40.879142,28.201707 24.508686,12.297576 7.2075295,27.943053 z"
  1024 + clip-rule="evenodd" /><path
  1025 + inkscape:connector-curvature="0"
  1026 + sodipodi:nodetypes="ccccc"
  1027 + style="fill:url(#linearGradient2412);fill-opacity:1;fill-rule:evenodd"
  1028 + id="path188"
  1029 + d="m 22,30 0,14.090942 -9.811029,0 L 12,30 22,30 z"
  1030 + clip-rule="evenodd" /><path
  1031 + inkscape:connector-curvature="0"
  1032 + clip-rule="evenodd"
  1033 + d="m 19.576856,36.44767 c 0.67279,0 1.216616,0.474605 1.216616,1.058507 0,0.589811 -0.543826,1.068355 -1.216616,1.068355 -0.672272,0 -1.218686,-0.478544 -1.218686,-1.068355 5.15e-4,-0.583902 0.546414,-1.058507 1.218686,-1.058507 z"
  1034 + id="path2315"
  1035 + style="opacity:0.40909089;fill:url(#radialGradient2325);fill-opacity:1;fill-rule:evenodd" /><path
  1036 + inkscape:connector-curvature="0"
  1037 + style="fill:url(#radialGradient2313);fill-opacity:1;fill-rule:evenodd"
  1038 + id="path217"
  1039 + d="m 19.462314,35.932229 c 0.672789,0 1.216615,0.474605 1.216615,1.058507 0,0.589809 -0.543826,1.068353 -1.216615,1.068353 -0.672273,0 -1.218687,-0.478544 -1.218687,-1.068353 5.15e-4,-0.583902 0.546414,-1.058507 1.218687,-1.058507 z"
  1040 + clip-rule="evenodd" /><path
  1041 + inkscape:connector-curvature="0"
  1042 + sodipodi:nodetypes="ccccccccccccc"
  1043 + style="fill:url(#XMLID_39_)"
  1044 + id="path342"
  1045 + d="m 24.447748,11.559337 18.92706,17.169868 0.494679,0.391991 0.403676,-0.171385 -0.37287,-0.761673 L 43.622679,27.964702 24.447748,12.392396 5.0582327,28.135731 4.8206309,28.279851 4.603921,28.986637 5.0373408,29.115885 5.4218948,28.807462 24.447748,11.559337 z" /><path
  1046 + inkscape:connector-curvature="0"
  1047 + sodipodi:nodetypes="cccccccccc"
  1048 + d="M 24.330168,2.2713382 2.4484294,20.372675 1.8237005,27.538603 3.8236367,29.602926 c 0,0 20.4073813,-17.157285 20.6240933,-17.327963 L 44.08027,29.818223 45.978694,27.494226 44.362903,20.382852 24.44773,2.1668788 24.330168,2.2713382 z"
  1049 + id="path362"
  1050 + style="fill:#ef2929;stroke:#a40000" /><path
  1051 + inkscape:connector-curvature="0"
  1052 + sodipodi:nodetypes="ccccc"
  1053 + id="path1536"
  1054 + d="M 2.8413446,20.613129 2.5497894,27.236494 24.369219,8.980075 24.298891,3.0867443 2.8413446,20.613129 z"
  1055 + style="opacity:0.40909089;color:#000000;fill:url(#radialGradient2305);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1056 + inkscape:connector-curvature="0"
  1057 + style="opacity:0.13636367;color:#000000;fill:url(#radialGradient2339);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  1058 + d="M 24.483763,8.7509884 24.583223,2.9098867 43.912186,20.56184 45.403998,27.062652 24.483763,8.7509884 z"
  1059 + id="path2337"
  1060 + sodipodi:nodetypes="ccccc" /><path
  1061 + inkscape:connector-curvature="0"
  1062 + sodipodi:nodetypes="ccccccccc"
  1063 + id="rect2361"
  1064 + d="m 27.102228,27.719824 9.039995,0 c 0.770595,0 1.390967,0.62037 1.390967,1.390967 l -0.008,9.079221 c 0,0.770596 -0.596322,1.265969 -1.366918,1.265969 l -9.056083,0 c -0.770597,0 -1.390967,-0.620373 -1.390967,-1.390969 l 0,-8.954221 c 0,-0.770597 0.62037,-1.390967 1.390967,-1.390967 z"
  1065 + style="opacity:0.31818183;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.99999934;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><rect
  1066 + ry="0.38128215"
  1067 + rx="0.38128215"
  1068 + y="28.514256"
  1069 + x="26.507767"
  1070 + height="9.9624557"
  1071 + width="10.001333"
  1072 + id="rect3263"
  1073 + style="color:#000000;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1074 + inkscape:connector-curvature="0"
  1075 + sodipodi:nodetypes="ccccc"
  1076 + id="rect2363"
  1077 + d="m 27.107118,34.408261 c 3.617983,0.331177 5.527724,-1.445704 8.868152,-1.55274 L 36,29.00603 27.088388,29 l 0.01873,5.408261 z"
  1078 + style="opacity:0.39772728;color:#000000;fill:url(#radialGradient2374);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999958;marker:none;visibility:visible;display:inline;overflow:visible" /></g></g><g
  1079 + inkscape:groupmode="layer"
  1080 + id="layer3"
  1081 + inkscape:label="Cancel"
  1082 + style="display:inline"
  1083 + sodipodi:insensitive="true"><path
  1084 + inkscape:connector-curvature="0"
  1085 + id="path21642-1"
  1086 + d="m 47.662816,44.987526 c -0.120652,1.646851 -3.213412,2.606775 -5.88153,3.03684 -4.362088,0.658404 -9.413,0.503003 -13.246573,-0.867841 -2.049624,-0.673315 -3.29125,-2.200566 -1.810314,-3.341428 2.178762,-1.659613 6.251742,-2.183438 9.862965,-2.236334 3.69133,-0.006 7.82464,0.471868 10.226986,2.081485 0.520681,0.38489 0.853108,0.849828 0.848466,1.327278 z"
  1087 + style="opacity:0.63068183;color:#000000;fill:url(#radialGradient3900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /><rect
  1088 + style="fill:url(#linearGradient4706);fill-opacity:1;fill-rule:nonzero;stroke:#850000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
  1089 + id="rect4692"
  1090 + width="21.625"
  1091 + height="21.9375"
  1092 + x="25.9375"
  1093 + y="24.0625"
  1094 + rx="0.38128215"
  1095 + ry="0.38128215" /><rect
  1096 + style="fill:none;stroke:url(#linearGradient4717);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;overflow:visible"
  1097 + id="rect4709"
  1098 + width="20.875"
  1099 + height="21"
  1100 + x="26.3125"
  1101 + y="24.5625"
  1102 + rx="0.38128215"
  1103 + ry="0.38128215" /><path
  1104 + style="fill:#cc2e2e;fill-opacity:0.89138579;stroke:none;display:inline;overflow:visible"
  1105 + d="m 26.4375,24.8125 20.625,0.125 L 47,39.4375 C 41.4375,36.625 39.859375,37.3125 37.195313,37.765625 35.025662,38.134656 32.65625,40.125 26.5,39.625 z"
  1106 + id="rect4720"
  1107 + inkscape:connector-curvature="0"
  1108 + sodipodi:nodetypes="cccscc" /><path
  1109 + inkscape:connector-curvature="0"
  1110 + id="path2787-5"
  1111 + d="m 33.090545,29.231406 c -0.720061,0.72006 -1.440121,1.44012 -2.160181,2.160181 1.271499,1.271499 2.542997,2.542997 3.814496,3.814497 -1.271499,1.271499 -2.542997,2.542997 -3.814496,3.814496 0.72006,0.720061 1.44012,1.440121 2.160181,2.160182 1.271499,-1.271499 2.542997,-2.542999 3.814496,-3.814498 1.271499,1.271499 2.542998,2.542999 3.814497,3.814498 0.72006,-0.720061 1.440121,-1.440121 2.160181,-2.160182 -1.271499,-1.271499 -2.542998,-2.542997 -3.814497,-3.814496 1.271499,-1.2715 2.542998,-2.542998 3.814497,-3.814497 -0.72006,-0.720061 -1.440121,-1.440121 -2.160181,-2.160181 -1.271499,1.271499 -2.542998,2.542998 -3.814497,3.814497 -1.271499,-1.271499 -2.542997,-2.542998 -3.814496,-3.814497 z"
  1112 + style="fill:url(#radialGradient3886);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3888);stroke-width:0.50623184;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;overflow:visible" /></g></svg>
0 1113 \ No newline at end of file
... ...
public/designs/icons/tango/style.css
1 1 /******************SMALL ICONS********************/
2 2 .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) }
3   -.icon-home { background-image: url(Tango/16x16/actions/go-home.png) }
  3 +.icon-home { background-image: url(Tango/16x16/actions/go-home.png) }
  4 +.icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) }
4 5 .icon-new,
5 6 .icon-suggest { background-image: url(Tango/16x16/actions/filenew.png) }
6 7 .icon-close { background-image: url(Tango/16x16/actions/gtk-cancel.png) }
... ...
public/javascripts/application.js
... ... @@ -853,6 +853,12 @@ Array.min = function(array) {
853 853 return Math.min.apply(Math, array);
854 854 };
855 855  
  856 +function hideAndGetUrl(link) {
  857 + link.hide();
  858 + url = jQuery(link).attr('href');
  859 + jQuery.get(url);
  860 +}
  861 +
856 862 jQuery(function($){
857 863 $('.submit-with-keypress').live('keydown', function(e) {
858 864 field = this;
... ... @@ -875,12 +881,21 @@ jQuery(function($){
875 881 }
876 882 });
877 883  
878   - $('.view-all-comments').live('click', function(e) {
879   - var link = this;
880   - $(link).parent().find('.profile-wall-activities-comments').show();
881   - $(link).hide();
  884 + $('#content').delegate( '.view-all-comments a', 'click', function(e) {
  885 + hideAndGetUrl(this);
882 886 return false;
  887 + });
  888 +
  889 + $('#content').delegate('.view-more-replies a', 'click', function(e) {
  890 + hideAndGetUrl(this);
  891 + return false;
883 892 });
  893 +
  894 + $('#content').delegate('.view-more-comments a', 'click', function(e) {
  895 + hideAndGetUrl(this);
  896 + return false;
  897 + });
  898 +
884 899 $('.focus-on-comment').live('click', function(e) {
885 900 var link = this;
886 901 $(link).parents('.profile-activity-item').find('textarea').focus();
... ...
public/stylesheets/application.css
... ... @@ -3137,7 +3137,7 @@ table.cms-articles a.icon {
3137 3137 text-overflow: ellipsis;
3138 3138 }
3139 3139  
3140   -table.cms-articles a.icon, table.cms-articles a.icon-parent-folder {
  3140 +table.cms-articles a.icon, table.cms-articles a.icon-parent-folder, .cms-homepage a.icon {
3141 3141 padding: 0px 0px 3px 20px;
3142 3142 background-repeat: no-repeat;
3143 3143 }
... ... @@ -3156,6 +3156,14 @@ table.cms-articles .icon:hover {
3156 3156 border-right: 1px solid #ccc;
3157 3157 }
3158 3158  
  3159 +.cms-homepage a.icon {
  3160 + border: none;
  3161 +}
  3162 +
  3163 +.cms-homepage a:hover {
  3164 + background-color: transparent;
  3165 +}
  3166 +
3159 3167 .select-article-type {
3160 3168 padding: 5px 20px;
3161 3169 width: 455px;
... ... @@ -5705,6 +5713,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5705 5713 padding-left: 20px;
5706 5714 }
5707 5715  
  5716 +.view-more-comments, .view-more-replies {
  5717 + text-align: center;
  5718 +}
  5719 +
5708 5720 /* Profile activity relative dimensions */
5709 5721  
5710 5722 #leave_scrap {
... ...
test/functional/cms_controller_test.rb
... ... @@ -109,6 +109,18 @@ class CmsControllerTest &lt; ActionController::TestCase
109 109 assert_no_tag :tag => 'a', :content => 'Use as homepage', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/set_home_page/#{folder.id}" }
110 110 end
111 111  
  112 + should 'display the profile homepage if can change homepage' do
  113 + env = Environment.default; env.disable('cant_change_homepage')
  114 + get :index, :profile => profile.identifier
  115 + assert_tag :tag => 'div', :content => /Profile homepage/, :attributes => { :class => "cms-homepage"}
  116 + end
  117 +
  118 + should 'not display the profile homepage if cannot change homepage' do
  119 + env = Environment.default; env.enable('cant_change_homepage')
  120 + get :index, :profile => profile.identifier
  121 + assert_no_tag :tag => 'div', :content => /Profile homepage/, :attributes => { :class => "cms-homepage"}
  122 + end
  123 +
112 124 should 'be able to set home page' do
113 125 a = profile.articles.build(:name => 'my new home page')
114 126 a.save!
... ... @@ -119,6 +131,7 @@ class CmsControllerTest &lt; ActionController::TestCase
119 131  
120 132 profile.reload
121 133 assert_equal a, profile.home_page
  134 + assert_match /configured/, session[:notice]
122 135 end
123 136  
124 137 should 'be able to set home page even when profile description is invalid' do
... ... @@ -154,6 +167,37 @@ class CmsControllerTest &lt; ActionController::TestCase
154 167 assert_redirected_to profile.url
155 168 end
156 169  
  170 + should 'be able to reset home page' do
  171 + a = profile.articles.build(:name => 'my new home page')
  172 + a.save!
  173 +
  174 + profile.home_page = a
  175 + profile.save!
  176 +
  177 + post :set_home_page, :profile => profile.identifier, :id => nil
  178 +
  179 + profile.reload
  180 + assert_equal nil, profile.home_page
  181 + assert_match /reseted/, session[:notice]
  182 + end
  183 +
  184 + should 'display default home page' do
  185 + profile.home_page = nil
  186 + profile.save!
  187 + get :index, :profile => profile.identifier
  188 + assert_tag :tag => 'div', :attributes => { :class => "cms-homepage" }, :descendant => { :tag => "span", :content => /Profile Information/ }
  189 + end
  190 +
  191 + should 'display article as home page' do
  192 + a = profile.articles.build(:name => 'my new home page')
  193 + a.save!
  194 + profile.home_page = a
  195 + profile.save!
  196 + Article.stubs(:short_description).returns('short description')
  197 + get :index, :profile => profile.identifier
  198 + assert_tag :tag => 'div', :attributes => { :class => "cms-homepage" }, :descendant => { :tag => "a", :content => /my new home page/ }
  199 + end
  200 +
157 201 should 'set last_changed_by when creating article' do
158 202 login_as(profile.identifier)
159 203  
... ...
test/functional/profile_controller_test.rb
... ... @@ -734,7 +734,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
734 734 end
735 735  
736 736 should 'see the activities_items paginated' do
737   - p1= Person.first
  737 + p1 = create_user('some').person
738 738 ActionTracker::Record.destroy_all
739 739 40.times{Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))}
740 740 login_as(p1.identifier)
... ... @@ -1170,6 +1170,58 @@ class ProfileControllerTest &lt; ActionController::TestCase
1170 1170 assert_redirected_to :controller => 'account', :action => 'login'
1171 1171 end
1172 1172  
  1173 + should "not index display activities comments" do
  1174 + login_as(profile.identifier)
  1175 + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software')
  1176 + ActionTracker::Record.destroy_all
  1177 + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image})
  1178 + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)}
  1179 + article.reload
  1180 + get :index, :profile => profile.identifier
  1181 + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments'}, :children => {:count => 0 }
  1182 + end
  1183 +
  1184 + should "view more comments paginated" do
  1185 + login_as(profile.identifier)
  1186 + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software')
  1187 + ActionTracker::Record.destroy_all
  1188 + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image})
  1189 + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)}
  1190 + article.reload
  1191 + assert_equal 20, article.comments.count
  1192 + get :more_comments, :activity => activity.id, :comment_page => 2
  1193 + assert_response :success
  1194 + assert_template '_comment'
  1195 + assert_select_rjs :insert_html do
  1196 + assert_select 'li', 5 # 5 comments per page
  1197 + end
  1198 + end
  1199 +
  1200 + should "not index display scraps replies" do
  1201 + login_as(profile.identifier)
  1202 + Scrap.destroy_all
  1203 + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id)
  1204 + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)}
  1205 + profile.reload
  1206 + get :index, :profile => profile.identifier
  1207 + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments scrap-replies'}, :children => {:count => 0 }
  1208 + end
  1209 +
  1210 + should "view more replies paginated" do
  1211 + login_as(profile.identifier)
  1212 + Scrap.destroy_all
  1213 + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id)
  1214 + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)}
  1215 + profile.reload
  1216 + assert_equal 20, scrap.replies.count
  1217 + get :more_replies, :activity => scrap.id, :comment_page => 2
  1218 + assert_response :success
  1219 + assert_template '_profile_scrap'
  1220 + assert_select_rjs :insert_html do
  1221 + assert_select 'li', 5 # 5 replies per page
  1222 + end
  1223 + end
  1224 +
1173 1225 should 'render empty response for not logged in users in check_membership' do
1174 1226 get :check_membership
1175 1227 assert_equal '', @response.body
... ... @@ -1331,30 +1383,6 @@ class ProfileControllerTest &lt; ActionController::TestCase
1331 1383 assert_equal "Comment successfully added.", assigns(:message)
1332 1384 end
1333 1385  
1334   - should 'display comment in wall if user was removed' do
1335   - UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
1336   - article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
1337   - to_be_removed = create_user('removed_user').person
1338   - comment = Comment.create!(:author => to_be_removed, :title => 'Test Comment', :body => 'My author does not exist =(', :source_id => article.id, :source_type => 'Article')
1339   - to_be_removed.destroy
1340   -
1341   - login_as(profile.identifier)
1342   - get :index, :profile => profile.identifier
1343   -
1344   - assert_tag :tag => 'span', :content => '(removed user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-removed'}
1345   - end
1346   -
1347   - should 'display comment in wall from non logged users' do
1348   - UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
1349   - article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
1350   - comment = Comment.create!(:name => 'outside user', :email => 'outside@localhost.localdomain', :title => 'Test Comment', :body => 'My author does not exist =(', :source_id => article.id, :source_type => 'Article')
1351   -
1352   - login_as(profile.identifier)
1353   - get :index, :profile => profile.identifier
1354   -
1355   - assert_tag :tag => 'span', :content => '(unauthenticated user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-unknown'}
1356   - end
1357   -
1358 1386 should 'add locale on mailing' do
1359 1387 community = fast_create(Community)
1360 1388 create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community)
... ...
test/unit/application_helper_test.rb
... ... @@ -814,6 +814,32 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
814 814 assert_no_match /Test1/, parsed_html
815 815 end
816 816  
  817 + should 'not convert macro if source is nil' do
  818 + profile = create_user('testuser').person
  819 + article = fast_create(Article, :profile_id => profile.id)
  820 + class Plugin1 < Noosfero::Plugin; end
  821 +
  822 + environment = Environment.default
  823 + environment.enable_plugin(Plugin1)
  824 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  825 +
  826 + expects(:convert_macro).never
  827 + filter_html(article.body, nil)
  828 + end
  829 +
  830 + should 'not convert macro if there is no macro plugin active' do
  831 + profile = create_user('testuser').person
  832 + article = fast_create(Article, :profile_id => profile.id)
  833 + class Plugin1 < Noosfero::Plugin; end
  834 +
  835 + environment = Environment.default
  836 + environment.enable_plugin(Plugin1)
  837 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  838 +
  839 + expects(:convert_macro).never
  840 + filter_html(article.body, article)
  841 + end
  842 +
817 843 protected
818 844 include NoosferoTestHelper
819 845  
... ...
test/unit/comment_test.rb
... ... @@ -285,22 +285,6 @@ class CommentTest &lt; ActiveSupport::TestCase
285 285 assert_equal [c1,c3], c.reload.children
286 286 end
287 287  
288   - should "return activities comments as a thread" do
289   - person = fast_create(Person)
290   - a = TextileArticle.create!(:profile => person, :name => 'My article', :body => 'Article body')
291   - c0 = Comment.create!(:source => a, :body => 'My comment', :author => person)
292   - c1 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person)
293   - c2 = Comment.create!(:reply_of_id => c1.id, :source => a, :body => 'bla', :author => person)
294   - c3 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person)
295   - c4 = Comment.create!(:source => a, :body => 'My comment', :author => person)
296   - result = a.activity.comments_as_thread
297   - assert_equal c0, result[0]
298   - assert_equal [c1, c3], result[0].replies
299   - assert_equal [c2], result[0].replies[0].replies
300   - assert_equal c4, result[1]
301   - assert result[1].replies.empty?
302   - end
303   -
304 288 should 'provide author url for authenticated user' do
305 289 author = Person.new
306 290 author.expects(:url).returns('http://blabla.net/author')
... ...
vendor/plugins/action_tracker_has_comments/init.rb
... ... @@ -3,22 +3,13 @@
3 3 Rails.configuration.to_prepare do
4 4 ActionTracker::Record.module_eval do
5 5  
6   - 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 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy,
  7 + :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC',
  8 + :counter_sql => 'SELECT COUNT(*) FROM comments WHERE #{conditions_for_comments}'
7 9  
8 10 def conditions_for_comments
9 11 type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])
10   - "source_type = '#{type}' AND source_id = '#{id}'"
11   - end
12   -
13   - def comments_as_thread
14   - result = {}
15   - root = []
16   - self.comments.each do |c|
17   - c.replies = []
18   - result[c.id] ||= c
19   - c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c
20   - end
21   - root
  12 + "source_type = '#{type}' AND source_id = '#{id}' AND reply_of_id IS NULL"
22 13 end
23 14  
24 15 end
... ...