Commit 50f90482152b5eb3b7a7e603d875f9f03e1a321f

Authored by Joenio Costa
2 parents 08976954 040b05e2

Merge branch 'master' into AI2993-display_content_plugin_content

Showing 125 changed files with 2581 additions and 366 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 125 files displayed.

INSTALL.md
... ... @@ -23,7 +23,7 @@ You need to install some packages Noosfero depends on. On Debian GNU/Linux or De
23 23 # apt-get install ruby rake po4a libgettext-ruby-util libgettext-ruby1.8 \
24 24 libsqlite3-ruby rcov librmagick-ruby libredcloth-ruby libhpricot-ruby \
25 25 libwill-paginate-ruby iso-codes libfeedparser-ruby libdaemons-ruby thin \
26   - tango-icon-theme libnokogiri-ruby
  26 + tango-icon-theme
27 27  
28 28 On other systems, they may or may not be available through your regular package management system. Below are the links to their homepages.
29 29  
... ... @@ -41,7 +41,6 @@ On other systems, they may or may not be available through your regular package
41 41 * Thin: http://code.macournoyer.com/thin
42 42 * tango-icon-theme: http://tango.freedesktop.org/Tango_Icon_Library
43 43 * Hpricot: http://hpricot.com
44   -* Nokogiri: http://nokogiri.org/
45 44  
46 45 If you manage to install Noosfero successfully on other systems than Debian,
47 46 please feel free to contact the Noosfero development mailing with the
... ...
app/controllers/admin/environment_design_controller.rb
... ... @@ -3,6 +3,8 @@ class EnvironmentDesignController < BoxOrganizerController
3 3 protect 'edit_environment_design', :environment
4 4  
5 5 def available_blocks
  6 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  7 + # the Noosfero core soon, see ActionItem3045
6 8 @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ]
7 9 @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment)
8 10 end
... ...
app/controllers/admin/users_controller.rb
... ... @@ -7,7 +7,7 @@ class UsersController < AdminController
7 7 include UsersHelper
8 8  
9 9 def index
10   - @filter = params[:filter]
  10 + @filter = params[:filter] || 'all_users'
11 11 scope = environment.people.no_templates
12 12 if @filter == 'admin_users'
13 13 scope = scope.admins
... ... @@ -16,6 +16,7 @@ class UsersController < AdminController
16 16 elsif @filter == 'deactivated_users'
17 17 scope = scope.deactivated
18 18 end
  19 + scope = scope.order('name ASC')
19 20 @q = params[:q]
20 21 @collection = find_by_contents(:people, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
21 22 end
... ... @@ -44,6 +45,20 @@ class UsersController < AdminController
44 45 redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
45 46 end
46 47  
  48 +
  49 + def destroy_user
  50 + if request.post?
  51 + person = environment.people.find_by_id(params[:id])
  52 + if person && person.destroy
  53 + session[:notice] = _('The profile was deleted.')
  54 + else
  55 + session[:notice] = _('Could not remove profile')
  56 + end
  57 + end
  58 + redirect_to :action => :index, :q => params[:q], :filter => params[:filter]
  59 + end
  60 +
  61 +
47 62 def download
48 63 respond_to do |format|
49 64 format.html
... ...
app/controllers/application_controller.rb
... ... @@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base
21 21 include ApplicationHelper
22 22 layout :get_layout
23 23 def get_layout
  24 + return nil if request.format == :js
24 25 theme_layout = theme_option(:layout)
25 26 if theme_layout
26 27 theme_view_file('layouts/'+theme_layout) || theme_layout
... ...
app/controllers/box_organizer_controller.rb
... ... @@ -70,7 +70,7 @@ class BoxOrganizerController < ApplicationController
70 70 else
71 71 @center_block_types = (Box.acceptable_center_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => 1)
72 72 @side_block_types = (Box.acceptable_side_blocks & available_blocks) + plugins.dispatch(:extra_blocks, :type => boxes_holder.class, :position => [2,3])
73   - @boxes = boxes_holder.boxes
  73 + @boxes = boxes_holder.boxes.with_position
74 74 render :action => 'add_block', :layout => false
75 75 end
76 76 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -221,11 +221,10 @@ class CmsController < MyProfileController
221 221  
222 222 def update_categories
223 223 @object = params[:id] ? @profile.articles.find(params[:id]) : Article.new
  224 + @categories = @toplevel_categories = environment.top_level_categories
224 225 if params[:category_id]
225 226 @current_category = Category.find(params[:category_id])
226 227 @categories = @current_category.children
227   - else
228   - @categories = environment.top_level_categories.select{|i| !i.children.empty?}
229 228 end
230 229 render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false
231 230 end
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -55,11 +55,10 @@ class ProfileEditorController < MyProfileController
55 55  
56 56 def update_categories
57 57 @object = profile
  58 + @categories = @toplevel_categories = environment.top_level_categories
58 59 if params[:category_id]
59 60 @current_category = Category.find(params[:category_id])
60 61 @categories = @current_category.children
61   - else
62   - @categories = environment.top_level_categories.select{|i| !i.children.empty?}
63 62 end
64 63 render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false
65 64 end
... ...
app/controllers/my_profile/profile_members_controller.rb
... ... @@ -2,7 +2,7 @@ class ProfileMembersController < MyProfileController
2 2 protect 'manage_memberships', :profile
3 3  
4 4 def index
5   - @members = profile.members
  5 + @members = profile.members_by_name
6 6 @member_role = environment.roles.find_by_name('member')
7 7 end
8 8  
... ...
app/controllers/public/profile_controller.rb
... ... @@ -67,7 +67,7 @@ class ProfileController < PublicController
67 67  
68 68 def members
69 69 if is_cache_expired?(profile.members_cache_key(params))
70   - @members = profile.members.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
  70 + @members = profile.members_by_name.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage])
71 71 end
72 72 end
73 73  
... ... @@ -304,14 +304,6 @@ class ProfileController < PublicController
304 304 end
305 305 end
306 306  
307   - def profile_info
308   - begin
309   - @block = profile.blocks.find(params[:block_id])
310   - rescue
311   - render :text => _('Profile information could not be loaded')
312   - end
313   - end
314   -
315 307 def report_abuse
316 308 @abuse_report = AbuseReport.new
317 309 render :layout => false
... ...
app/controllers/themes_controller.rb
... ... @@ -12,7 +12,7 @@ class ThemesController < ApplicationController
12 12  
13 13 def index
14 14 @environment = environment
15   - @themes = environment.themes + Theme.approved_themes(target)
  15 + @themes = (environment.themes + Theme.approved_themes(target)).sort_by { |t| t.name }
16 16  
17 17 @current_theme = target.theme
18 18  
... ...
app/helpers/application_helper.rb
... ... @@ -608,49 +608,18 @@ module ApplicationHelper
608 608 end
609 609  
610 610 attr_reader :environment
  611 +
611 612 def select_categories(object_name, title=nil, title_size=4)
612 613 return nil if environment.enabled?(:disable_categories)
613 614 if title.nil?
614 615 title = _('Categories')
615 616 end
616 617  
617   - object = instance_variable_get("@#{object_name}")
618   -
619   - result = content_tag 'h'+title_size.to_s(), title
620   - result << javascript_tag( 'function open_close_cat( link ) {
621   - var div = link.parentNode.getElementsByTagName("div")[0];
622   - var end = function(){
623   - if ( div.style.display == "none" ) {
624   - this.link.className="button icon-button icon-down"
625   - } else {
626   - this.link.className="button icon-button icon-up-red"
627   - }
628   - }
629   - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } )
630   - }')
631   - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel|
632   - next unless object.accept_category?(toplevel)
633   - # FIXME
634   - ([toplevel] + toplevel.children_for_menu).each do |cat|
635   - if cat.top_level?
636   - result << '<div class="categorie_box">'.html_safe
637   - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' )
638   - result << content_tag('h5', toplevel.name)
639   - result << '<div style="display:none"><ul class="categories">'.html_safe
640   - else
641   - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}"
642   - result << content_tag('li', labelled_check_box(
643   - cat.full_name_without_leading(1, " &rarr; "),
644   - "#{object_name}[category_ids][]", cat.id,
645   - object.category_ids.include?(cat.id), :id => checkbox_id,
646   - :onchange => 'this.parentNode.className=(this.checked?"cat_checked":"")' ),
647   - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n"
648   - end
649   - end
650   - result << '</ul></div></div>'.html_safe
651   - end
  618 + @object = instance_variable_get("@#{object_name}")
  619 + @categories = environment.top_level_categories
652 620  
653   - content_tag('div', result)
  621 + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?}
  622 + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false
654 623 end
655 624  
656 625 def theme_option(opt = nil)
... ... @@ -1382,16 +1351,16 @@ module ApplicationHelper
1382 1351 end
1383 1352  
1384 1353 def convert_macro(html, source)
1385   - doc = Nokogiri::HTML(html)
  1354 + doc = Hpricot(html)
1386 1355 #TODO This way is more efficient but do not support macro inside of
1387 1356 # macro. You must parse them from the inside-out in order to enable
1388 1357 # that.
1389   - doc.css('.macro').each do |macro|
  1358 + doc.search('.macro').each do |macro|
1390 1359 macro_name = macro['data-macro']
1391 1360 result = @plugins.parse_macro(macro_name, macro, source)
1392   - macro.content = result.kind_of?(Proc) ? self.instance_eval(&result) : result
  1361 + macro.inner_html = result.kind_of?(Proc) ? self.instance_eval(&result) : result
1393 1362 end
1394   - CGI.unescapeHTML(doc.xpath('//body/*').to_s)
  1363 + doc.html
1395 1364 end
1396 1365  
1397 1366 def default_folder_for_image_upload(profile)
... ...
app/helpers/boxes_helper.rb
... ... @@ -39,7 +39,7 @@ module BoxesHelper
39 39 end
40 40  
41 41 def display_boxes(holder, main_content)
42   - boxes = holder.boxes.first(holder.boxes_limit)
  42 + boxes = holder.boxes.with_position.first(holder.boxes_limit)
43 43 content = boxes.reverse.map { |item| display_box(item, main_content) }.join("\n")
44 44 content = main_content if (content.blank?)
45 45  
... ...
app/helpers/categories_helper.rb
... ... @@ -48,4 +48,12 @@ module CategoriesHelper
48 48 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value)))
49 49 end
50 50  
  51 + #FIXME make this test
  52 + def selected_category_link(cat)
  53 + content_tag('div', button_to_function_without_text(:remove, _('Remove'), nil) {|page| page["selected-category-#{cat.id}"].remove} +
  54 + link_to_function(cat.full_name(' &rarr; '), nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove},
  55 + :class => 'selected-category'
  56 + )
  57 + end
  58 +
51 59 end
... ...
app/models/box.rb
... ... @@ -5,6 +5,8 @@ class Box &lt; ActiveRecord::Base
5 5  
6 6 include Noosfero::Plugin::HotSpot
7 7  
  8 + named_scope :with_position, :conditions => ['boxes.position > 0']
  9 +
8 10 def environment
9 11 owner ? (owner.kind_of?(Environment) ? owner : owner.environment) : nil
10 12 end
... ... @@ -24,6 +26,8 @@ class Box &lt; ActiveRecord::Base
24 26 CategoriesBlock,
25 27 CommunitiesBlock,
26 28 EnterprisesBlock,
  29 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  30 + # the Noosfero core soon, see ActionItem3045
27 31 EnvironmentStatisticsBlock,
28 32 FansBlock,
29 33 FavoriteEnterprisesBlock,
... ... @@ -50,6 +54,8 @@ class Box &lt; ActiveRecord::Base
50 54 CommunitiesBlock,
51 55 DisabledEnterpriseMessageBlock,
52 56 EnterprisesBlock,
  57 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  58 + # the Noosfero core soon, see ActionItem3045
53 59 EnvironmentStatisticsBlock,
54 60 FansBlock,
55 61 FavoriteEnterprisesBlock,
... ...
app/models/environment.rb
... ... @@ -161,6 +161,8 @@ class Environment &lt; ActiveRecord::Base
161 161  
162 162 # "left" area
163 163 env.boxes[1].blocks << LoginBlock.new
  164 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  165 + # the Noosfero core soon, see ActionItem3045
164 166 env.boxes[1].blocks << EnvironmentStatisticsBlock.new
165 167 env.boxes[1].blocks << RecentDocumentsBlock.new
166 168  
... ... @@ -186,7 +188,7 @@ class Environment &lt; ActiveRecord::Base
186 188 has_many :product_categories, :conditions => { :type => 'ProductCategory'}
187 189 has_many :regions
188 190  
189   - has_many :roles
  191 + has_many :roles, :dependent => :destroy
190 192  
191 193 has_many :qualifiers
192 194 has_many :certifiers
... ...
app/models/environment_statistics_block.rb
  1 +# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  2 +# the Noosfero core soon, see ActionItem3045
  3 +
1 4 class EnvironmentStatisticsBlock < Block
2 5  
3 6 def self.description
4   - _('Environment stastistics')
  7 + _('Environment stastistics (DEPRECATED)')
5 8 end
6 9  
7 10 def default_title
... ...
app/models/link_list_block.rb
... ... @@ -63,7 +63,7 @@ class LinkListBlock &lt; Block
63 63 def link_html(link)
64 64 klass = 'icon-' + link[:icon] if link[:icon]
65 65 sanitize_link(
66   - link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass)
  66 + link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass, :title => link[:title])
67 67 )
68 68 end
69 69  
... ...
app/models/profile.rb
... ... @@ -88,6 +88,10 @@ class Profile &lt; ActiveRecord::Base
88 88 ScopeTool.union *scopes
89 89 end
90 90  
  91 + def members_by_name
  92 + members.order(:name)
  93 + end
  94 +
91 95 def members_count
92 96 members.count
93 97 end
... ...
app/sweepers/profile_sweeper.rb
... ... @@ -8,6 +8,8 @@ class ProfileSweeper # &lt; ActiveRecord::Observer
8 8 end
9 9  
10 10 def after_create(profile)
  11 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  12 + # the Noosfero core soon, see ActionItem3045
11 13 expire_statistics_block_cache(profile)
12 14 end
13 15  
... ... @@ -29,6 +31,8 @@ protected
29 31 expire_blogs(profile) if profile.organization?
30 32 end
31 33  
  34 + # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from
  35 + # the Noosfero core soon, see ActionItem3045
32 36 def expire_statistics_block_cache(profile)
33 37 blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) }
34 38 BlockSweeper.expire_blocks(blocks)
... ...
app/views/blocks/location.html.erb
... ... @@ -3,7 +3,6 @@
3 3 <div class='the-localization-map'>
4 4 <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/>
5 5 </div>
6   -</div>
7 6 <% else %>
8 7 <i><%= _('This profile has no geographical position registered.') %></i>
9 8 <% end %>
... ...
app/views/blocks/profile_image.rhtml
... ... @@ -16,7 +16,7 @@
16 16  
17 17 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
18 18 <div class='admin-link'>
19   - <%= link_to _('Control panel'), :controller => 'profile_editor' %>
  19 + <%= link_to _('Control panel'), block.owner.admin_url %>
20 20 </div>
21 21 <% end %>
22 22  
... ...
app/views/blocks/profile_info.rhtml
... ... @@ -21,7 +21,7 @@
21 21 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) %></li>
22 22 <% end %>
23 23 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
24   - <li><%= link_to _('Control panel'), :controller => 'profile_editor' %></li>
  24 + <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
25 25 <% end %>
26 26 <% if profile.person? %>
27 27 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
... ... @@ -40,7 +40,7 @@
40 40 <% end %>
41 41  
42 42 <div class="profile-info-options">
43   - <%= render :file => view_for_profile_actions(@block.owner.class) %>
  43 + <%= render :file => view_for_profile_actions(block.owner.class) %>
44 44 </div>
45 45  
46 46 </div><!-- end class="vcard" -->
... ...
app/views/box_organizer/_link_list_block.rhtml
1 1 <strong><%= _('Links') %></strong>
2   -<div id='edit-link-list-block' style='width:450px'>
  2 +<div id='edit-link-list-block'>
3 3 <table id='links' class='noborder'>
4   - <tr><th><%= _('Icon') %></th><th><%= _('Name') %></th><th><%= _('Address') %></th><th><%= _('Target') %></th></tr>
  4 + <tr>
  5 + <th><%= _('Icon') %></th>
  6 + <th><%= _('Name') %></th>
  7 + <th><%= _('Address') %></th>
  8 + <th><%= _('Title') %></th>
  9 + <th><%= _('Target') %></th>
  10 + </tr>
5 11 <% for link in @block.links do %>
6   - <tr>
7   - <td>
8   - <%= icon_selector(link['icon']) %>
9   - </td>
10   - <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>
11   - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>
12   - <td>
13   - <%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %>
14   - </td>
15   - </tr>
  12 + <tr>
  13 + <td><%= icon_selector(link['icon']) %></td>
  14 + <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>
  15 + <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>
  16 + <td><%= text_field_tag 'block[links][][title]', link[:title], :class => 'link-title' %></td>
  17 + <td><%= select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, link[:target])) %></td>
  18 + </tr>
16 19 <% end %>
17 20 </table>
18 21 </div>
... ... @@ -22,8 +25,8 @@
22 25 content_tag('td', icon_selector('ok')) +
23 26 content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
24 27 content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'link-address'), :class => 'cel-address') +
25   - content_tag('td', select_tag('block[links][][target]',
26   -options_for_select(LinkListBlock::TARGET_OPTIONS, '_self')))
  28 + content_tag('td', text_field_tag('block[links][][title]', '', :class => 'link-title')) +
  29 + content_tag('td', select_tag('block[links][][target]', options_for_select(LinkListBlock::TARGET_OPTIONS, '_self')))
27 30 ) +
28 31 javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight")
29 32 end %>
... ...
app/views/content_viewer/view_page.rhtml
... ... @@ -40,14 +40,6 @@
40 40 </div>
41 41 <% end %>
42 42  
43   -<% if !@page.tags.empty? %>
44   - <div id="article-tags">
45   - <%= _("This article's tags:") %>
46   - <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
47   - </div>
48   -<% end %>
49   -
50   -
51 43 <%= render :partial => 'shared/disabled_enterprise' %>
52 44  
53 45 <% if NOOSFERO_CONF['addthis_enabled'] %>
... ... @@ -83,6 +75,13 @@
83 75 </div>
84 76 <% end %>
85 77  
  78 +<% if !@page.tags.empty? %>
  79 + <div id="article-tags">
  80 + <%= _("This article's tags:") %>
  81 + <%= @page.tags.map { |t| link_to(t, :controller => 'profile', :profile => @profile.identifier, :action => 'tags', :id => t.name ) }.join("\n") %>
  82 + </div>
  83 +<% end %>
  84 +
86 85 <%= display_source_info(@page) %>
87 86  
88 87 <div class="comments" id="comments_list">
... ...
app/views/features/_manage_community_fields.rhtml
1   -<h2><%= __('Manage community fields') %></h2>
2   -
3 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_community_fields'}) do |f| %>
4 2  
5 3 <table id='community_fields_conf'>
... ... @@ -9,21 +7,37 @@
9 7 <th><%= _('Required') %></th>
10 8 <th><%= _('Display on creation?') %></th>
11 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="community_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="community_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="community_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 26 <% @community_fields.each do |field| %>
13 27 <tr>
14 28 <td><label for="community_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 29  
16 30 <td>
17 31 <%= hidden_field_tag "community_fields[#{field}][active]", false %>
18   - <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "$('community_fields[#{field}][required]').disabled=$('community_fields[#{field}][signup]').disabled=!this.checked;" %>
  32 + <%= check_box_tag "community_fields[#{field}][active]", true, environment.custom_community_field(field, 'active'), :onclick => "active_action(this, 'community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
19 33 </td>
20 34 <td>
21 35 <%= hidden_field_tag "community_fields[#{field}][required]", false %>
22   - <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "if(this.checked) $('community_fields[#{field}][signup]').checked = true;" %>
  36 + <%= check_box_tag "community_fields[#{field}][required]", true, environment.custom_community_field(field, 'required'), :onclick => "required_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
23 37 </td>
24 38 <td>
25 39 <%= hidden_field_tag "community_fields[#{field}][signup]", false %>
26   - <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "if(!this.checked) $('community_fields[#{field}][required]').checked = false;" %>
  40 + <%= check_box_tag "community_fields[#{field}][signup]", true, environment.custom_community_field(field, 'signup'), :onclick => "signup_action('community_fields[#{field}][active]','community_fields[#{field}][required]', 'community_fields[#{field}][signup]')" %>
27 41 </td>
28 42  
29 43 </tr>
... ... @@ -31,18 +45,18 @@
31 45 </table>
32 46  
33 47 <script type='text/javascript'>
34   - var trs = $$('#community_fields_conf tr');
  48 + var trs = jQuery('#community_fields_conf tr');
35 49 var tr, td2;
36   - for ( var i=0; tr=trs[i]; i++ ) {
  50 + for ( var i=2; tr=trs[i]; i++ ) {
37 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38   - td2.getElementsByTagName('input')[0].onclick();
  52 + td2.getElementsByTagName('input')[1].onclick();
39 53 }
40 54 }
41 55 </script>
42 56  
43 57 <div>
44 58 <% button_bar do %>
45   - <%= submit_button('save', _('Save changes')) %>
  59 + <%= submit_button('save', _('Save changes'), :id=>"save_community_fields") %>
46 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 61 <% end %>
48 62 </div>
... ...
app/views/features/_manage_enterprise_fields.rhtml
1   -<h2><%= __('Manage enterprise fields') %></h2>
2   -
3 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_enterprise_fields'}) do |f| %>
4 2  
5 3 <table id='enterprise_fields_conf'>
... ... @@ -9,21 +7,37 @@
9 7 <th><%= _('Required') %></th>
10 8 <th><%= _('Display on registration?') %></th>
11 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="enterprise_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="enterprise_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="enterprise_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 26 <% @enterprise_fields.each do |field| %>
13 27 <tr>
14 28  
15 29 <td><label for="enterprise_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
16 30 <td>
17 31 <%= hidden_field_tag "enterprise_fields[#{field}][active]", false %>
18   - <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "$('enterprise_fields[#{field}][required]').disabled=$('enterprise_fields[#{field}][signup]').disabled=!this.checked;" %>
  32 + <%= check_box_tag "enterprise_fields[#{field}][active]", true, environment.custom_enterprise_field(field, 'active'), :onclick => "active_action(this, 'enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
19 33 </td>
20 34 <td>
21 35 <%= hidden_field_tag "enterprise_fields[#{field}][required]", false %>
22   - <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "if(this.checked) $('enterprise_fields[#{field}][signup]').checked = true;" %>
  36 + <%= check_box_tag "enterprise_fields[#{field}][required]", true, environment.custom_enterprise_field(field, 'required'), :onclick => "required_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
23 37 </td>
24 38 <td>
25 39 <%= hidden_field_tag "enterprise_fields[#{field}][signup]", false %>
26   - <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "if(!this.checked) $('enterprise_fields[#{field}][required]').checked = false;" %>
  40 + <%= check_box_tag "enterprise_fields[#{field}][signup]", true, environment.custom_enterprise_field(field, 'signup'), :onclick => "signup_action('enterprise_fields[#{field}][active]','enterprise_fields[#{field}][required]', 'enterprise_fields[#{field}][signup]')" %>
27 41 </td>
28 42  
29 43 </tr>
... ... @@ -31,18 +45,18 @@
31 45 </table>
32 46  
33 47 <script type='text/javascript'>
34   - var trs = $$('#enterprise_fields_conf tr');
  48 + var trs = jQuery('#enterprise_fields_conf tr');
35 49 var tr, td2;
36   - for ( var i=0; tr=trs[i]; i++ ) {
  50 + for ( var i=2; tr=trs[i]; i++ ) {
37 51 if ( td2 = tr.getElementsByTagName('td')[1] ) {
38   - td2.getElementsByTagName('input')[0].onclick();
  52 + td2.getElementsByTagName('input')[1].onclick();
39 53 }
40 54 }
41 55 </script>
42 56  
43 57 <div>
44 58 <% button_bar do %>
45   - <%= submit_button('save', _('Save changes')) %>
  59 + <%= submit_button('save', _('Save changes'), :id=>"save_enterprise_fields") %>
46 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
47 61 <% end %>
48 62 </div>
... ...
app/views/features/_manage_person_fields.rhtml
1   -<h2><%= _('Manage person fields') %></h2>
2   -
3 1 <% labelled_form_for(:environment, @environment, :url => {:action => 'manage_person_fields'}) do |f| %>
4 2  
5 3 <table id='person_fields_conf'>
... ... @@ -9,31 +7,48 @@
9 7 <th><%= _('Required') %></th>
10 8 <th><%= _('Display on signup?') %></th>
11 9 </tr>
  10 +
  11 + <tr class='manage-fields-batch-actions'>
  12 + <td>
  13 + <%= _("Check/Uncheck All")%>
  14 + </td>
  15 + <td>
  16 + <input type="checkbox" id="person_active" />
  17 + </td>
  18 + <td>
  19 + <input type="checkbox" id="person_required" />
  20 + </td>
  21 + <td>
  22 + <input type="checkbox" id="person_signup" />
  23 + </td>
  24 + </tr>
  25 +
12 26 <% @person_fields.each do |field| %>
13 27 <tr>
14 28 <td><label for="person_fields[<%= field %>][active]"><%= _(field.humanize) %></label></td>
15 29 <td>
16 30 <%= hidden_field_tag "person_fields[#{field}][active]", false %>
17   - <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "$('person_fields[#{field}][required]').disabled=$('person_fields[#{field}][signup]').disabled=!this.checked;" %>
  31 + <%= check_box_tag "person_fields[#{field}][active]", true, environment.custom_person_field(field, 'active'), :onclick => "active_action(this, 'person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
18 32 </td>
19 33 <td>
20 34 <%= hidden_field_tag "person_fields[#{field}][required]", false %>
21   - <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "if(this.checked) $('person_fields[#{field}][signup]').checked = true;" %>
  35 + <%= check_box_tag "person_fields[#{field}][required]", true, environment.custom_person_field(field, 'required'), :onclick => "required_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
22 36 </td>
23 37 <td>
24 38 <%= hidden_field_tag "person_fields[#{field}][signup]", false %>
25   - <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "if(!this.checked) $('person_fields[#{field}][required]').checked = false;" %>
  39 + <%= check_box_tag "person_fields[#{field}][signup]", true, environment.custom_person_field(field, 'signup'), :onclick => "signup_action('person_fields[#{field}][active]','person_fields[#{field}][required]', 'person_fields[#{field}][signup]')" %>
26 40 </td>
27 41 </tr>
28 42 <% end %>
29 43 </table>
30 44  
31 45 <script type='text/javascript'>// <!--
32   - var trs = $$('#person_fields_conf tr');
  46 + var trs = jQuery('#person_fields_conf tr');
  47 +
33 48 var tr, td2;
34   - for ( var i=0; tr=trs[i]; i++ ) {
  49 + for ( var i=2; tr=trs[i]; i++ ) {
35 50 if ( td2 = tr.getElementsByTagName('td')[1] ) {
36   - td2.getElementsByTagName('input')[0].onclick();
  51 + td2.getElementsByTagName('input')[1].onclick();
37 52 }
38 53 }
39 54 // -->
... ... @@ -41,7 +56,7 @@
41 56  
42 57 <div>
43 58 <% button_bar do %>
44   - <%= submit_button('save', _('Save changes')) %>
  59 + <%= submit_button('save', _('Save changes'), :id=>"save_person_fields") %>
45 60 <%= button :back, _('Back to admin panel'), :controller => 'admin_panel', :action => 'index' %>
46 61 <% end %>
47 62 </div>
... ...
app/views/features/manage_fields.rhtml
1   -<%= render :partial => 'manage_person_fields' %>
  1 +<h1><%= _('Manage fields displayed for profiles') %></h1>
2 2  
3   -<% if !environment.enabled?('disable_asset_enterprises') %>
4   - <%= render :partial => 'manage_enterprise_fields' %>
  3 +<% tabs = [] %>
  4 +<% tabs << {:title => _("Person's fields"), :id => 'person-fields',
  5 + :content => (render :partial => 'manage_person_fields')} %>
  6 +<% tabs << {:title => _("Community's fields"), :id => 'community-fields',
  7 + :content => (render :partial => 'manage_community_fields')} %>
  8 +<% unless environment.enabled?('disable_asset_enterprises') %>
  9 + <% tabs << {:title => _("Enterprise's fields"), :id => 'enterprise-fields',
  10 + :content => (render :partial => 'manage_enterprise_fields')} %>
5 11 <% end %>
6 12  
7   -<%= render :partial => 'manage_community_fields' %>
  13 +<%= render_tabs(tabs) %>
  14 +
  15 +<%= javascript_include_tag "manage-fields.js" %>
... ...
app/views/profile_members/_members_list.rhtml
1   -<% collection = @collection == :profile_admins ? profile.admins : profile.members %>
  1 +<% collection = @collection == :profile_admins ? profile.admins : profile.members_by_name %>
2 2 <% title = @title ? @title : _('Current members') %>
3 3 <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %>
4 4  
... ...
app/views/shared/_select_categories.rhtml
1   -<div id="category-ajax-selector">
  1 +<% extend CategoriesHelper %>
  2 +
2 3 <% if !@current_category.nil? %>
3   - <h3 class="box-title"><%= _('Current category:') %></h3>
4 4 <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %>
  5 + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %>
  6 + <%= button_to_remote_without_text(:back, _('Back'),
  7 + { :update => "select-categories",
  8 + :url => { :action => 'update_categories', :id => @object },
  9 + :loaded => visual_effect(:highlight, "select-categories")
  10 + },
  11 + :id => 'cancel-category-button') %>
5 12 <%
6 13 categories = [@current_category]
7 14 categories.push(@current_category) while @current_category = @current_category.parent
8 15 %>
9 16 <%= categories.compact.reverse.map{|i|
10   - link_to_remote(i.name,
  17 + link_to_remote(i.name,
11 18 :update => "select-categories",
12 19 :url => { :action => 'update_categories', :category_id => i.id, :id => @object },
13 20 :loaded => visual_effect(:highlight, "select-categories"),
14 21 :class => 'select-current-category-link')}.join(' &rarr; ')
15 22 %>
16   - <strong>
17   - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page|
18   - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name +
  23 + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page|
  24 + page.insert_html :bottom, 'selected-categories', content_tag('div',
19 25 hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) +
20   - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}")
  26 + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}")
  27 + page.replace_html 'select-categories', :partial => 'shared/select_subcategories',
  28 + :locals => {:object_name => object_name, :categories => @toplevel_categories}
21 29 end if multiple %>
22   - <%= button_to_remote_without_text(:cancel, _('Cancel'),
23   - { :update => "select-categories",
24   - :url => { :action => 'update_categories', :id => @object },
25   - :loaded => visual_effect(:highlight, "select-categories")
26   - },
27   - :id => 'cancel-category-button') %>
28   - </strong>
29   -<% else %>
30   - <h3 class="box-title"><%= _('Select a category:') %></h3>
31 30 <% end %>
32 31  
33   -<% if !@categories.empty? %>
34   - <h3><%= _('Categories:') %></h3>
35   - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %>
36   - <%= link_to_remote category.name,
37   - { :update => "select-categories",
38   - :url => { :action => "update_categories", :category_id => category.id, :id => @object},
39   - :loaded => visual_effect(:highlight, "select-categories")
40   - },
41   - :class => 'select-subcategory-link',
42   - :id => "select-category-#{category.id}-link"
43   - %>
44   - <% end %> &nbsp;
45   -<% end %>
  32 +<div class="toplevel-categories">
  33 + <%= render :partial => 'shared/select_subcategories', :locals => {:object_name => object_name, :categories => @categories} %>
46 34 </div>
... ...
app/views/shared/_select_categories_top.rhtml 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +<% categories_selected ||= nil %>
  2 +<% title ||= nil %>
  3 +
  4 +<% extend CategoriesHelper %>
  5 +
  6 +<%= content_tag "h#{title_size}", title, :class => "box-title" %>
  7 +
  8 +<%= hidden_field_tag "#{object_name}[category_ids][]", nil %>
  9 +
  10 +<div id="category-ajax-selector">
  11 +<% unless categories_selected.nil? %>
  12 +<div id="selected-categories">
  13 + <div class="label"><%= _('Selected categories:') %></div>
  14 + <% categories_selected.each do |cat| %>
  15 + <div id="selected-category-<%= cat.id %>">
  16 + <%= hidden_field_tag("#{object_name}[category_ids][]", cat.id) %>
  17 + <%= selected_category_link(cat) %>
  18 + </div>
  19 + <% end %>
  20 +</div>
  21 +<% end %>
  22 +<div id="select-categories">
  23 + <%= render :partial => 'shared/select_categories', :locals => {:object_name => object_name, :multiple => true, :categories_selected => categories_selected }, :layout => false %>
  24 +</div>
  25 +
  26 +</div>
... ...
app/views/shared/_select_subcategories.rhtml 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<% if !categories.nil? && !categories.empty? && !@object.nil? %>
  2 + <hr>
  3 + <div class="category-helper-label"><%= _('Click to select a category') %></div>
  4 +
  5 + <% categories.select{|i| @object.accept_category?(i)}.each do |category| %>
  6 +
  7 + <%= link_to_remote category.name,
  8 + { :update => "select-categories",
  9 + :url => { :action => "update_categories", :category_id => category.id, :id => @object},
  10 + :loaded => visual_effect(:highlight, "select-categories")
  11 + },
  12 + :class => 'select-subcategory-link',
  13 + :id => "select-category-#{category.id}-link"
  14 + %>
  15 + <% end %>
  16 +<% end %>
... ...
app/views/users/_users_list.rhtml
... ... @@ -19,16 +19,17 @@
19 19 <td class='actions'>
20 20 <div class="members-buttons-cell">
21 21 <% if p.is_admin? %>
22   - <%= button_without_text :'reset-admin-role', _('Reset admin role'), :action => 'reset_admin_role', :id => p, :q => @q, :filter => @filter %>
  22 + <%= button_without_text :'reset-admin-role', _('Reset admin role'), {:action => 'reset_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to reset this user as administrator?") %>
23 23 <% else %>
24   - <%= button_without_text :'set-admin-role', _('Set admin role'), :action => 'set_admin_role', :id => p, :q => @q, :filter => @filter %>
  24 + <%= button_without_text :'set-admin-role', _('Set admin role'), {:action => 'set_admin_role', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to set this user as administrator?") %>
25 25 <% end %>
26 26 <% if !p.user.activated? %>
27   - <%= button_without_text :'activate-user', _('Activate user'), :action => 'activate', :id => p, :q => @q, :filter => @filter %>
  27 + <%= button_without_text :'activate-user', _('Activate user'), {:action => 'activate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to activate this user?") %>
28 28 <% else %>
29   - <%= button_without_text :'deactivate-user', _('Deactivate user'), :action => 'deactivate', :id => p, :q => @q, :filter => @filter %>
  29 + <%= button_without_text :'deactivate-user', _('Deactivate user'), {:action => 'deactivate', :id => p, :q => @q}, :filter => @filter, :confirm => _("Do you want to deactivate this user?") %>
30 30 <% end %>
31   - </div>
  31 + <%= button_without_text :'delete', _('Remove'), {:action => :destroy_user, :id => p, :q => @q}, :method => :post, :filter => @filter, :confirm => _("Do you want to remove this user?") %>
  32 + </div>
32 33 </td>
33 34 </tr>
34 35 <% end %>
... ...
config/initializers/dependencies.rb
... ... @@ -8,4 +8,3 @@ require &#39;route_if&#39;
8 8  
9 9 # third-party libraries
10 10 require 'will_paginate'
11   -require 'nokogiri'
... ...
debian/changelog
  1 +noosfero (0.46.1) unstable; urgency=low
  2 +
  3 + * Bugfixes release
  4 +
  5 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 07 Mar 2014 10:33:11 +0000
  6 +
1 7 noosfero (0.46.0) unstable; urgency=low
2 8  
3 9 * New features release
... ...
debian/control
... ... @@ -41,7 +41,6 @@ Depends:
41 41 thin,
42 42 tango-icon-theme,
43 43 libhpricot-ruby,
44   - libnokogiri-ruby,
45 44 memcached,
46 45 debconf,
47 46 dbconfig-common,
... ...
features/manage_fields.feature 0 → 100644
... ... @@ -0,0 +1,76 @@
  1 +Feature: check all manage fields
  2 + As an administrator
  3 + I want to check and uncheck all person, enterprise and community's fields
  4 +
  5 + Background:
  6 + Given the following users
  7 + | login | name |
  8 + | mariasilva | Maria Silva |
  9 + And the following enterprises
  10 + | identifier | owner | name | contact_email | contact_phone | enabled |
  11 + | paper-street | mariasilva | Paper Street | marial.silva@workerbees.org | (288) 555-0153 | true |
  12 + And the following community
  13 + | identifier | name |
  14 + | mycommunity | My Community |
  15 + And I am logged in as admin
  16 + And I go to /admin/features/manage_fields
  17 +
  18 + @selenium
  19 + Scenario: check all active person fields
  20 + Given I follow "Person's fields"
  21 + And I check "person_active"
  22 + And I press "save_person_fields"
  23 + When I go to admin_user's control panel
  24 + And I follow "Edit Profile"
  25 + Then I should see "Custom area of study"
  26 +
  27 + @selenium
  28 + Scenario: check all active enterprise fields
  29 + Given I follow "Enterprise's fields"
  30 + And I check "enterprise_active"
  31 + And I press "save_enterprise_fields"
  32 + When I go to paper-street's control panel
  33 + And I follow "Enterprise Info and settings"
  34 + Then I should see "Historic and current context"
  35 +
  36 + @selenium
  37 + Scenario: check all active community fields
  38 + Given I follow "Community's fields"
  39 + And I check "community_active"
  40 + And I press "save_community_fields"
  41 + When I go to mycommunity's control panel
  42 + And I follow "Community Info and settings"
  43 + Then I should see "Economic activity"
  44 +
  45 + @selenium
  46 + Scenario: uncheck Check/Uncheck All active person field
  47 + Given I follow "Person's fields"
  48 + And I check "person_active"
  49 + And I press "save_person_fields"
  50 + And I uncheck "person_active"
  51 + And I press "save_person_fields"
  52 + And I follow "Control panel"
  53 + When I follow "Edit Profile"
  54 + Then I should not see "Custom area of study"
  55 +
  56 + @selenium
  57 + Scenario: uncheck Check/Uncheck All active community field
  58 + Given I follow "Community's fields"
  59 + And I check "community_active"
  60 + And I press "save_community_fields"
  61 + And I uncheck "community_active"
  62 + And I press "save_community_fields"
  63 + When I go to mycommunity's control panel
  64 + And I follow "Community Info and settings"
  65 + Then I should not see "Economic activity"
  66 +
  67 + @selenium
  68 + Scenario: uncheck Check/Uncheck All active enterprise field
  69 + Given I follow "Enterprise's fields"
  70 + And I check "enterprise_active"
  71 + And I press "save_enterprise_fields"
  72 + And I uncheck "enterprise_active"
  73 + And I press "save_enterprise_fields"
  74 + When I go to paper-street's control panel
  75 + And I follow "Enterprise Info and settings"
  76 + Then I should not see "Historic and current context"
... ...
features/manage_users.feature 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +Feature: manage users
  2 + As an environment administrator
  3 + I want to manage users
  4 + In order to remove, activate, deactivate users, and set admin roles.
  5 +
  6 +Background:
  7 + Given the following users
  8 + | login | name |
  9 + | joaosilva | Joao Silva |
  10 + | paulosantos | Paulo Santos |
  11 + Given I am logged in as admin
  12 + Given I go to /admin/users
  13 +
  14 + @selenium
  15 + Scenario: deactive user
  16 + When I follow "Deactivate user" within "tr[title='Joao Silva']"
  17 + And I confirm the "Do you want to deactivate this user?" dialog
  18 + Then I should see "Activate user" within "tr[title='Joao Silva']"
  19 +
  20 + @selenium
  21 + Scenario: activate user
  22 + Given I follow "Deactivate user" within "tr[title='Paulo Santos']"
  23 + Given I confirm the "Do you want to deactivate this user?" dialog
  24 + When I follow "Activate user" within "tr[title='Paulo Santos']"
  25 + And I confirm the "Do you want to activate this user?" dialog
  26 + Then I should see "Deactivate user" within "tr[title='Paulo Santos']"
  27 +
  28 + @selenium
  29 + Scenario: remove user
  30 + When I follow "Remove" within "tr[title='Joao Silva']"
  31 + And I confirm the "Do you want to remove this user?" dialog
  32 + And I go to /admin/users
  33 + Then I should not see "Joao Silva"
  34 +
  35 + @selenium
  36 + Scenario: admin user
  37 + When I follow "Set admin role" within "tr[title='Joao Silva']"
  38 + And I confirm the "Do you want to set this user as administrator?" dialog
  39 + Then I should see "Reset admin role" within "tr[title='Joao Silva']"
  40 +
  41 + @selenium
  42 + Scenario: unadmin user
  43 + Given I follow "Set admin role" within "tr[title='Paulo Santos']"
  44 + And I confirm the "Do you want to set this user as administrator?" dialog
  45 + When I follow "Reset admin role" within "tr[title='Paulo Santos']"
  46 + And I confirm the "Do you want to reset this user as administrator?" dialog
  47 + Then I should see "Set admin role" within "tr[title='Paulo Santos']"
... ...
lib/noosfero.rb
... ... @@ -3,7 +3,7 @@ require &#39;fast_gettext&#39;
3 3  
4 4 module Noosfero
5 5 PROJECT = 'noosfero'
6   - VERSION = '0.46.0'
  6 + VERSION = '0.46.1'
7 7  
8 8 def self.pattern_for_controllers_in_directory(dir)
9 9 disjunction = controllers_in_directory(dir).join('|')
... ...
lib/noosfero/core_ext.rb
1 1 require 'noosfero/core_ext/string'
2 2 require 'noosfero/core_ext/integer'
  3 +require 'noosfero/core_ext/array'
3 4 require 'noosfero/core_ext/object'
4 5 require 'noosfero/core_ext/active_record'
... ...
lib/noosfero/core_ext/array.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class Array
  2 +
  3 + def uniq_by
  4 + hash, array = {}, []
  5 + each { |i| hash[yield(i)] ||= (array << i) }
  6 + array
  7 + end
  8 +
  9 +end
... ...
lib/noosfero/plugin/macro.rb
... ... @@ -33,9 +33,9 @@ class Noosfero::Plugin::Macro
33 33 end
34 34  
35 35 def attributes(macro)
36   - macro.attributes.
  36 + macro.attributes.to_hash.
37 37 select {|key, value| key[0..10] == 'data-macro-'}.
38   - inject({}){|result, a| result.merge({a[0][11..-1] => a[1].value})}.
  38 + inject({}){|result, a| result.merge({a[0][11..-1] => a[1]})}.
39 39 with_indifferent_access
40 40 end
41 41  
... ...
lib/noosfero/plugin/routes.rb
... ... @@ -15,12 +15,16 @@ Dir.glob(File.join(Rails.root, plugins_root, &#39;*&#39;, &#39;controllers&#39;)) do |controller
15 15 controllers_by_folder.each do |folder, controllers|
16 16 controllers.each do |controller|
17 17 controller_name = controller.gsub("#{plugin_name}_plugin_",'')
18   - map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller
  18 + if %w[profile myprofile].include?(folder)
  19 + map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller, :profile => /#{Noosfero.identifier_format}/
  20 + else
  21 + map.connect "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}/:action/:id", :controller => controller
  22 + end
19 23 end
20 24 end
21 25  
22 26 map.connect 'plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin'
23   - map.connect 'profile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile'
24   - map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile'
  27 + map.connect 'profile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_profile', :profile => /#{Noosfero.identifier_format}/
  28 + map.connect 'myprofile/:profile/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_myprofile', :profile => /#{Noosfero.identifier_format}/
25 29 map.connect 'admin/plugin/' + plugin_name + '/:action/:id', :controller => plugin_name + '_plugin_admin'
26 30 end
... ...
plugins/comment_classification/README.md 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +README - Comment Classification Plugin
  2 +======================================
  3 +
  4 +This plugin creates the structure for classifying the comments. The
  5 +initial idea of this plugin is to support the management of public
  6 +consulting, but it can be used in different contexts.
  7 +For now, two kind of classification will be available:
  8 +
  9 + * Label: when creating a comment, the user identify the kind of it by
  10 +choosing the label of the comment. Example: "Suggestion",
  11 +"Disagreement"...
  12 + * Status: users with permission can include a Status for a comment.
  13 +Example: "Merged", "Unmerged"
  14 +
  15 +Dependency
  16 +==========
  17 +
  18 +This plugin was developed to help public consulting and needs the
  19 +CommentGroupPlugin enabled to be used.
... ...
plugins/comment_classification/controllers/admin/comment_classification_plugin_labels_controller.rb 0 → 100644
... ... @@ -0,0 +1,55 @@
  1 +class CommentClassificationPluginLabelsController < AdminController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  3 +
  4 + def index
  5 +# @labels = @environment.labels
  6 + @labels = CommentClassificationPlugin::Label.all
  7 + end
  8 +
  9 + def create
  10 + @label = CommentClassificationPlugin::Label.new(params[:label])
  11 + @colors = CommentClassificationPlugin::Label::COLORS
  12 + if request.post?
  13 + begin
  14 + @label.owner = environment
  15 + @label.save!
  16 + session[:notice] = _('Label created')
  17 + redirect_to :action => 'index'
  18 + rescue
  19 + session[:notice] = _('Label could not be created')
  20 + end
  21 + end
  22 + end
  23 +
  24 + def edit
  25 +# @labels = @environment.labels.find(params[:id])
  26 + @label = CommentClassificationPlugin::Label.find(params[:id])
  27 + @colors = CommentClassificationPlugin::Label::COLORS
  28 + if request.post?
  29 + begin
  30 + @label.update_attributes!(params[:label])
  31 + session[:notice] = _('Label updated')
  32 + redirect_to :action => :index
  33 + rescue
  34 + session[:notice] = _('Failed to edit label')
  35 + end
  36 + end
  37 + end
  38 +
  39 + def remove
  40 +# @label = environment.labels.find(params[:label])
  41 + @label = CommentClassificationPlugin::Label.find(params[:id])
  42 + if request.post?
  43 + begin
  44 + @label.destroy
  45 + session[:notice] = _('Label removed')
  46 + rescue
  47 + session[:notice] = _('Label could not be removed')
  48 + end
  49 + else
  50 + session[:notice] = _('Label could not be removed')
  51 + end
  52 + redirect_to :action => 'index'
  53 + end
  54 +
  55 +end
... ...
plugins/comment_classification/controllers/admin/comment_classification_plugin_status_controller.rb 0 → 100644
... ... @@ -0,0 +1,53 @@
  1 +class CommentClassificationPluginStatusController < AdminController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  3 +
  4 + def index
  5 +# @labels = @environment.labels
  6 + @status = CommentClassificationPlugin::Status.all
  7 + end
  8 +
  9 + def create
  10 + @status = CommentClassificationPlugin::Status.new(params[:status])
  11 + if request.post?
  12 + begin
  13 + @status.owner = environment
  14 + @status.save!
  15 + session[:notice] = _('Status created')
  16 + redirect_to :action => 'index'
  17 + rescue
  18 + session[:notice] = _('Status could not be created')
  19 + end
  20 + end
  21 + end
  22 +
  23 + def edit
  24 +# @labels = @environment.labels.find(params[:id])
  25 + @status = CommentClassificationPlugin::Status.find(params[:id])
  26 + if request.post?
  27 + begin
  28 + @status.update_attributes!(params[:status])
  29 + session[:notice] = _('Status updated')
  30 + redirect_to :action => :index
  31 + rescue
  32 + session[:notice] = _('Failed to edit status')
  33 + end
  34 + end
  35 + end
  36 +
  37 + def remove
  38 +# @label = environment.labels.find(params[:label])
  39 + @status = CommentClassificationPlugin::Status.find(params[:id])
  40 + if request.post?
  41 + begin
  42 + @status.destroy
  43 + session[:notice] = _('Status removed')
  44 + rescue
  45 + session[:notice] = _('Status could not be removed')
  46 + end
  47 + else
  48 + session[:notice] = _('Status could not be removed')
  49 + end
  50 + redirect_to :action => 'index'
  51 + end
  52 +
  53 +end
... ...
plugins/comment_classification/controllers/comment_classification_plugin_admin_controller.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +class CommentClassificationPluginAdminController < AdminController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def index
  5 + end
  6 +
  7 +end
... ...
plugins/comment_classification/controllers/comment_classification_plugin_myprofile_controller.rb 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +class CommentClassificationPluginMyprofileController < MyProfileController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + before_filter :organizations_only
  5 + protect 'moderate_comments', :profile
  6 +
  7 + def index
  8 + @comments = Comment.all
  9 + end
  10 +
  11 + def add_status
  12 + @comment = Comment.find(params[:id])
  13 + @statuses = CommentClassificationPlugin::Status.enabled
  14 + @status = CommentClassificationPlugin::CommentStatusUser.new(:profile => user, :comment => @comment)
  15 + if request.post? && params[:status]
  16 + @status.update_attributes(params[:status])
  17 + @status.save
  18 + end
  19 + end
  20 +
  21 + private
  22 +
  23 + def organizations_only
  24 + render_not_found if !profile.organization?
  25 + end
  26 +end
... ...
plugins/comment_classification/db/migrate/20130822043033_create_comments_labels.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class CreateCommentsLabels < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :comment_classification_plugin_labels do |t|
  4 + t.string :name
  5 + t.string :color
  6 + t.boolean :enabled, :default => true
  7 + t.references :owner, :polymorphic => true
  8 +
  9 + t.timestamps
  10 + end
  11 + end
  12 +
  13 + def self.down
  14 + drop_table :comment_classification_plugin_labels
  15 + end
  16 +end
... ...
plugins/comment_classification/db/migrate/20130822075623_create_comment_label_user.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class CreateCommentLabelUser < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :comment_classification_plugin_comment_label_user do |t|
  4 + t.references :profile
  5 + t.references :comment
  6 + t.references :label
  7 +
  8 + t.timestamps
  9 + end
  10 +
  11 + end
  12 +
  13 + def self.down
  14 + drop_table :comment_classification_plugin_comment_label_user
  15 + end
  16 +end
... ...
plugins/comment_classification/db/migrate/20130829130226_create_comment_status.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class CreateCommentStatus < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :comment_classification_plugin_statuses do |t|
  4 + t.string :name
  5 + t.boolean :enabled, :default => true
  6 + t.boolean :enable_reason, :default => true
  7 + t.references :owner, :polymorphic => true
  8 + t.timestamps
  9 + end
  10 +
  11 + end
  12 +
  13 + def self.down
  14 + drop_table :comment_classification_plugin_statuses
  15 + end
  16 +end
... ...
plugins/comment_classification/db/migrate/20130829144037_create_comment_status_user.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class CreateCommentStatusUser < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :comment_classification_plugin_comment_status_user do |t|
  4 + t.references :profile
  5 + t.references :comment
  6 + t.references :status
  7 + t.text :reason
  8 +
  9 + t.timestamps
  10 + end
  11 + end
  12 +
  13 + def self.down
  14 + drop_table :comment_classification_plugin_comment_status_user
  15 + end
  16 +end
... ...
plugins/comment_classification/features/labels.feature 0 → 100644
... ... @@ -0,0 +1,64 @@
  1 +Feature:
  2 + As a user
  3 + I want to add label for comments
  4 +
  5 +Background:
  6 + Given the following users
  7 + | login | name |
  8 + | joaosilva | Joao Silva |
  9 + | mariasilva | Maria Silva |
  10 + And the following communities
  11 + | identifier | name |
  12 + | sample-community | Sample Community |
  13 + And the following articles
  14 + | owner | name | body |
  15 + | sample-community | Article to comment | First post |
  16 + And CommentClassificationPlugin is enabled
  17 + And "Maria Silva" is a member of "Sample Community"
  18 + And "Joao Silva" is admin of "Sample Community"
  19 + And I am logged in as "joaosilva"
  20 +
  21 + @selenium
  22 + Scenario: dont display labels if admin did not configure status
  23 + Given I am on article "Article to comment"
  24 + And I follow "Post a comment"
  25 + Then I should not see "Label" within "#page-comment-form"
  26 +
  27 + Scenario: admin configure labels
  28 + Given I am logged in as "admin_user"
  29 + And I am on the environment control panel
  30 + And I follow "Plugins"
  31 + And I follow "Configuration"
  32 + And I follow "Manage Labels"
  33 + Then I should see "no label registered yet" within "#comment-classification-labels"
  34 + When I follow "Add a new label"
  35 + And I fill in "Name" with "Question"
  36 + And I check "Enable this label"
  37 + And I press "Save"
  38 + Then I should see "Question" within "#comment-classification-labels"
  39 +
  40 + @selenium
  41 + Scenario: save label for comment
  42 + Given the following labels
  43 + | owner | name | enabled |
  44 + | environment | Addition | true |
  45 + And I go to article "Article to comment"
  46 + And I follow "Post a comment"
  47 + And I fill in "Enter your comment" with "Hey ho, let's go!"
  48 + Then I select "Addition" from "comment_label_id"
  49 + And I press "Post comment"
  50 + Then I should see "Addition" within ".comment-details"
  51 +
  52 + @selenium
  53 + Scenario: users without permission should not edit the labels
  54 + Given the following labels
  55 + | owner | name | enabled |
  56 + | environment | Addition | true |
  57 + And I go to article "Article to comment"
  58 + And I follow "Post a comment"
  59 + Then I should see "Label" within "#page-comment-form"
  60 + And I should see "Addition" within "#comment_label_id"
  61 + When I am not logged in
  62 + And I am on article "Article to comment"
  63 + And I follow "Post a comment"
  64 + Then I should not see "Label" within "#page-comment-form"
... ...
plugins/comment_classification/features/status.feature 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 +Feature:
  2 + As a user
  3 + I want to add status for comments
  4 +
  5 +Background:
  6 + Given the following users
  7 + | login | name |
  8 + | joaosilva | Joao Silva |
  9 + | mariasilva | Maria Silva |
  10 + And the following communities
  11 + | identifier | name |
  12 + | sample-community | Sample Community |
  13 + And the following articles
  14 + | owner | name | body |
  15 + | sample-community | Article to comment | First post |
  16 + And the following comments
  17 + | article | author | body |
  18 + | Article to comment | mariasilva | great post! |
  19 + And CommentClassificationPlugin is enabled
  20 + And "Maria Silva" is a member of "Sample Community"
  21 + And "Joao Silva" is admin of "Sample Community"
  22 + And I am logged in as "joaosilva"
  23 +
  24 + Scenario: dont display to add status if not an organization
  25 + Given the following articles
  26 + | owner | name | body |
  27 + | joaosilva | Article on a person profile | First post |
  28 + And the following comments
  29 + | article | author | body |
  30 + | Article on a person profile | mariasilva | great post! |
  31 + Given I am on article "Article on a person profile"
  32 + Then I should see "great post!" within ".comment-details"
  33 + And I should not see "Status" within ".comment-details"
  34 +
  35 + Scenario: dont display to add status if admin did not configure status
  36 + Given I am on article "Article to comment"
  37 + Then I should see "great post!" within ".comment-details"
  38 + And I should not see "Status" within ".comment-details"
  39 +
  40 + Scenario: admin configure status
  41 + Given I am logged in as "admin_user"
  42 + And I am on the environment control panel
  43 + And I follow "Plugins"
  44 + And I follow "Configuration"
  45 + And I follow "Manage Status"
  46 + Then I should see "no status registered yet" within "#comment-classification-status"
  47 + When I follow "Add a new status"
  48 + And I fill in "Name" with "Merged"
  49 + And I check "Enable this status"
  50 + And I press "Save"
  51 + Then I should see "Merged" within "#comment-classification-status"
  52 +
  53 + Scenario: save status for comment
  54 + Given the following status
  55 + | owner | name | enabled |
  56 + | environment | Merged | true |
  57 + And I go to article "Article to comment"
  58 + And I follow "Status"
  59 + Then I select "Merged" from "status_status_id"
  60 + And I press "Save"
  61 + Then I should see "added the status Merged" within "#comment-classification-status-list"
  62 +
  63 + Scenario: dont display to add status if user not allowed
  64 + Given I am logged in as "mariasilva"
  65 + When I go to article "Article to comment"
  66 + Then I should see "great post!" within ".comment-details"
  67 + And I should not see "Status" within ".comment-details"
... ...
plugins/comment_classification/features/step_definitions/plugin_steps.rb 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +Given /^CommentClassificationPlugin is enabled$/ do
  2 + Given %{I am logged in as admin}
  3 + And %{I am on the environment control panel}
  4 + And %{I follow "Plugins"}
  5 + And %{I check "Comment Classification"}
  6 + And %{I press "Save changes"}
  7 + Environment.default.enabled_plugins.should include("CommentClassificationPlugin")
  8 +end
  9 +
  10 +Given /^the following labels$/ do |table|
  11 + table.hashes.map{|item| item.dup}.each do |item|
  12 + owner_type = item.delete('owner')
  13 + owner = owner_type == 'environment' ? Environment.default : Profile[owner_type]
  14 + CommentClassificationPlugin::Label.create!(item)
  15 + end
  16 +end
  17 +
  18 +Given /^the following status$/ do |table|
  19 + table.hashes.map{|item| item.dup}.each do |item|
  20 + owner_type = item.delete('owner')
  21 + owner = owner_type == 'environment' ? Environment.default : Profile[owner_type]
  22 + CommentClassificationPlugin::Status.create!(item)
  23 + end
  24 +end
... ...
plugins/comment_classification/lib/comment_classification_plugin.rb 0 → 100644
... ... @@ -0,0 +1,57 @@
  1 +require 'ext/environment'
  2 +require 'ext/comment'
  3 +
  4 +class CommentClassificationPlugin < Noosfero::Plugin
  5 +
  6 + def self.plugin_name
  7 + "Comment Classification"
  8 + end
  9 +
  10 + def self.plugin_description
  11 + _("A plugin that allow classification of comments.")
  12 + end
  13 +
  14 +#TODO Each organization can add its own status and labels
  15 +# def control_panel_buttons
  16 +# if context.profile.organization?
  17 +# { :title => _('Manage comment classification'), :icon => 'comment_classification', :url => {:controller => 'comment_classification_plugin_myprofile'} }
  18 +# end
  19 +# end
  20 +
  21 + def comment_form_extra_contents(args)
  22 + comment = args[:comment]
  23 + lambda {
  24 + render :file => 'comment/comments_labels_select.rhtml', :locals => {:comment => comment }
  25 + }
  26 + end
  27 +
  28 + def comment_extra_contents(args)
  29 + comment = args[:comment]
  30 + lambda {
  31 + render :file => 'comment/comment_extra.rhtml', :locals => {:comment => comment}
  32 + }
  33 + end
  34 +
  35 + def process_extra_comment_params(args)
  36 + comment = Comment.find args[0]
  37 + label_id = args[1][:comment_label_id]
  38 + if label_id.blank?
  39 + if !CommentClassificationPlugin::CommentLabelUser.find_by_comment_id(comment.id).nil?
  40 + CommentClassificationPlugin::CommentLabelUser.find_by_comment_id(comment.id).destroy
  41 + end
  42 + else
  43 + label = CommentClassificationPlugin::Label.find label_id
  44 + relation = CommentClassificationPlugin::CommentLabelUser.new(:profile => comment.author, :comment => comment, :label => label )
  45 + relation.save
  46 + end
  47 + end
  48 +
  49 + def js_files
  50 + 'comment_classification.js'
  51 + end
  52 +
  53 + def stylesheet?
  54 + true
  55 + end
  56 +
  57 +end
... ...
plugins/comment_classification/lib/comment_classification_plugin/comment_label_user.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class CommentClassificationPlugin::CommentLabelUser < Noosfero::Plugin::ActiveRecord
  2 + set_table_name :comment_classification_plugin_comment_label_user
  3 +
  4 + belongs_to :profile
  5 + belongs_to :comment
  6 + belongs_to :label, :class_name => 'CommentClassificationPlugin::Label'
  7 +
  8 + validates_presence_of :profile
  9 + validates_presence_of :comment
  10 + validates_presence_of :label
  11 +end
... ...
plugins/comment_classification/lib/comment_classification_plugin/comment_status_user.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class CommentClassificationPlugin::CommentStatusUser < Noosfero::Plugin::ActiveRecord
  2 + set_table_name :comment_classification_plugin_comment_status_user
  3 +
  4 + belongs_to :profile
  5 + belongs_to :comment
  6 + belongs_to :status, :class_name => 'CommentClassificationPlugin::Status'
  7 +
  8 + validates_presence_of :profile
  9 + validates_presence_of :comment
  10 + validates_presence_of :status
  11 +end
... ...
plugins/comment_classification/lib/comment_classification_plugin/label.rb 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +class CommentClassificationPlugin::Label < Noosfero::Plugin::ActiveRecord
  2 +
  3 + belongs_to :owner, :polymorphic => true
  4 +
  5 + validates_presence_of :name
  6 +
  7 + named_scope :enabled, :conditions => { :enabled => true }
  8 +
  9 + COLORS = ['red', 'green', 'yellow', 'gray', 'blue']
  10 +end
... ...
plugins/comment_classification/lib/comment_classification_plugin/status.rb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +class CommentClassificationPlugin::Status < Noosfero::Plugin::ActiveRecord
  2 +
  3 + belongs_to :owner, :polymorphic => true
  4 +
  5 + validates_presence_of :name
  6 +
  7 + named_scope :enabled, :conditions => { :enabled => true }
  8 +end
... ...
plugins/comment_classification/lib/ext/comment.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +require_dependency 'comment'
  2 +require 'comment_classification_plugin.rb'
  3 +require 'comment_classification_plugin/label.rb'
  4 +
  5 +class Comment
  6 +
  7 + has_one :comment_classification_plugin_comment_label_user, :class_name => 'CommentClassificationPlugin::CommentLabelUser'
  8 + has_one :label, :through => :comment_classification_plugin_comment_label_user, :foreign_key => 'label_id'
  9 +
  10 + has_many :comment_classification_plugin_comment_status_users, :class_name => 'CommentClassificationPlugin::CommentStatusUser'
  11 + has_many :statuses, :through => :comment_classification_plugin_comment_status_users, :foreign_key => 'status_id'
  12 +
  13 +end
... ...
plugins/comment_classification/lib/ext/environment.rb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +require_dependency 'environment'
  2 +
  3 +class Environment
  4 +
  5 + has_many :labels, :as => :owner, :class_name => 'CommentClassificationPlugin::Label'
  6 +
  7 +end
  8 +
... ...
plugins/comment_classification/public/images/comment-classification.png 0 → 100644

4.15 KB

plugins/comment_classification/public/style.css 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +.controller-profile_editor .control-panel a.control-panel-comment_classification {
  2 + background-image: url(images/comment-classification.png);
  3 +}
  4 +
  5 +#content .comment-classification-options .label-name {
  6 + font-style: italic;
  7 +}
  8 +
  9 +#content .comment-classification-options a.button {
  10 + background-color: transparent;
  11 + border: none;
  12 +}
... ...
plugins/comment_classification/views/comment/comment_extra.rhtml 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +<div class='comment-classification-options'>
  2 +
  3 + <% unless comment.label.nil? %>
  4 + <p class='label-name' style='color:<%= comment.label.color %>'>
  5 + <%= comment.label.name %>
  6 + </p>
  7 + <% end %>
  8 +
  9 + <% statuses = CommentClassificationPlugin::Status.enabled %>
  10 + <% if profile.organization? && user && user.has_permission?(:moderate_comments, profile) && !statuses.empty? %>
  11 + <div class='comment-classification-status'>
  12 + <%= link_to(_('Status'), :profile => profile.identifier, :controller => :comment_classification_plugin_myprofile, :action => :add_status, :id => comment.id)
  13 + %>
  14 + </div>
  15 + <% end %>
  16 +
  17 +</div>
... ...
plugins/comment_classification/views/comment/comments_labels_select.rhtml 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +<% labels = CommentClassificationPlugin::Label.enabled %>
  2 +<% if logged_in? && user.has_permission?(:moderate_comments, profile) && !labels.empty? %>
  3 + <%= labelled_form_field(_('Label'), select_tag('comment_label_id', options_for_select( [[_('[Select ...]'), nil]] + labels.map{|l|[l.name,l.id]}, @comment.label.nil? ? '' : @comment.label.id))) %>
  4 +<% end %>
... ...
plugins/comment_classification/views/comment_classification_plugin_admin/index.rhtml 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<h1><%= _('Comments classification options')%></h1>
  2 +
  3 +<ul>
  4 + <li><%= link_to _('Manage Labels'), :controller => 'comment_classification_plugin_labels' %></li>
  5 + <li><%= link_to _('Manage Status'), :controller => 'comment_classification_plugin_status' %></li>
  6 +</ul>
... ...
plugins/comment_classification/views/comment_classification_plugin_labels/_form.rhtml 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<%= error_messages_for :label %>
  2 +
  3 +<% form_for :label, @label do |f| %>
  4 + <%= required_fields_message %>
  5 +
  6 + <%= required labelled_form_field(_('Name'), f.text_field(:name)) %>
  7 + <%= labelled_form_field(_('Color'), f.select(:color, @colors.map{|s|[s.capitalize,s]})) %>
  8 + <%= labelled_form_field(f.check_box(:enabled) + _('Enable this label?'),'') %>
  9 +
  10 + <% button_bar do %>
  11 + <%= submit_button('save', _('Save'), :cancel => {:action => 'index'} ) %>
  12 + <% end %>
  13 +<% end %>
... ...
plugins/comment_classification/views/comment_classification_plugin_labels/create.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2> <%= _("Add a new label") %> </h2>
  2 +
  3 +<%= render :partial => 'form' %>
... ...
plugins/comment_classification/views/comment_classification_plugin_labels/edit.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2> <%= _("Editing label %s") % @label.name %> </h2>
  2 +
  3 +<%= render :partial => 'form' %>
... ...
plugins/comment_classification/views/comment_classification_plugin_labels/index.rhtml 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +<h1><%= _("Manage comments labels") %></h1>
  2 +
  3 +<div id='comment-classification-labels'>
  4 + <% if @labels.empty? %>
  5 + <%= _('(no label registered yet)') %>
  6 + <% else %>
  7 + <table>
  8 + <tr>
  9 + <th><%= _('Label') %></th>
  10 + <th><%= _('Color') %></th>
  11 + <th><%= _('Enabled') %></th>
  12 + <th><%= _('Actions') %></th>
  13 + </tr>
  14 + <% @labels.each do |label| %>
  15 + <tr>
  16 + <td><%= label.name %></td>
  17 + <td><%= label.color %></td>
  18 + <td><%= label.enabled %></td>
  19 + <td>
  20 + <%= button_without_text :edit, _('Edit'), {:action => 'edit', :id => label} %>
  21 + <%= button_without_text :delete, _('Remove'), {:action => 'destroy', :id => label}, :confirm => _('Are you sure you want to remove this label?') %>
  22 + </td>
  23 + </tr>
  24 + <% end %>
  25 + </table>
  26 + <% end %>
  27 +
  28 + <% button_bar do %>
  29 + <%= button(:add, _('Add a new label'), :action => 'create')%>
  30 + <%= button :back, _('Back to admin panel'), :controller => 'admin_panel' %>
  31 + <% end %>
  32 +</div>
... ...
plugins/comment_classification/views/comment_classification_plugin_myprofile/_status_form.html.erb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<%= error_messages_for :status %>
  2 +
  3 +<% form_for :status, @status do |f| %>
  4 + <%= required_fields_message %>
  5 +
  6 + <%= labelled_form_field(_('Status'), f.select(:status_id, @statuses.map{|s|[s.name,s.id]})) %>
  7 + <%= labelled_form_field(_('Reason:'), f.text_area(:reason, :rows => 5)) %>
  8 +
  9 + <% button_bar do %>
  10 + <%= submit_button('save', _('Save') ) %>
  11 + <% end %>
  12 +<% end %>
... ...
plugins/comment_classification/views/comment_classification_plugin_myprofile/add_status.html.erb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +<h1><%= _('Status for comment') %></h1>
  2 +
  3 +<div id='comment-classification-status-list'>
  4 + <% unless @comment.title.blank? %>
  5 + <div class='comment-title'><%= _("Title: %s") % @comment.title %></div>
  6 + <% end %>
  7 +
  8 + <b><%= _('Body:') %></b>
  9 + <p><%= @comment.body %></p>
  10 +
  11 + <h2> <%= _("History") %> </h2>
  12 +
  13 + <ul>
  14 + <% @comment.comment_classification_plugin_comment_status_users.each do |relation| %>
  15 + <li>
  16 + <%= _("<i>%{user}</i> added the status <i>%{status_name}</i> at <i>%{created_at}</i>.") % { :user => relation.profile.name, :status_name => relation.status.name, :created_at => time_ago_as_sentence(relation.created_at)} %>
  17 + <% unless relation.reason.blank? %>
  18 + <p><%= _("<i>Reason:</i> %s") % relation.reason %></p>
  19 + <% end %>
  20 + </li>
  21 + <% end %>
  22 + </ul>
  23 +
  24 + <h2> <%= _("Add a new status") %> </h2>
  25 +
  26 + <%= render :partial => 'status_form' %>
  27 +</div>
... ...
plugins/comment_classification/views/comment_classification_plugin_myprofile/index.html.erb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h1><%= _('Manage comment classification') %></h1>
  2 +
  3 +List all classifications
... ...
plugins/comment_classification/views/comment_classification_plugin_status/_form.rhtml 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<%= error_messages_for :status %>
  2 +
  3 +<% form_for :status, @status do |f| %>
  4 + <%= required_fields_message %>
  5 +
  6 + <%= required labelled_form_field(_('Name'), f.text_field(:name)) %>
  7 + <%= labelled_form_field(f.check_box(:enabled) + _('Enable this status?'),'') %>
  8 + <%#= labelled_form_field(f.check_box(:enable_reason) + _('This status allows reason?'),'') %>
  9 +
  10 + <% button_bar do %>
  11 + <%= submit_button('save', _('Save'), :cancel => {:action => 'index'} ) %>
  12 + <% end %>
  13 +<% end %>
... ...
plugins/comment_classification/views/comment_classification_plugin_status/create.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2> <%= _("Add a new status") %> </h2>
  2 +
  3 +<%= render :partial => 'form' %>
... ...
plugins/comment_classification/views/comment_classification_plugin_status/edit.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h2> <%= _("Editing status %s") % @status.name %> </h2>
  2 +
  3 +<%= render :partial => 'form' %>
... ...
plugins/comment_classification/views/comment_classification_plugin_status/index.rhtml 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +<h1> <%= _("Manage comments status") %></h1>
  2 +
  3 +<div id='comment-classification-status'>
  4 + <% if @status.empty? %>
  5 + <%= _('(no status registered yet)') %>
  6 + <% else %>
  7 + <table>
  8 + <tr>
  9 + <th><%= _('Status') %></th>
  10 + <th><%= _('Enabled') %></th>
  11 + <th><%= _('Reason enabled?') %></th>
  12 + <th><%= _('Actions') %></th>
  13 + </tr>
  14 + <% @status.each do |st| %>
  15 + <tr>
  16 + <td><%= st.name %></td>
  17 + <td><%= st.enabled %></td>
  18 + <td><%= st.enable_reason %></td>
  19 + <td>
  20 + <%= button_without_text :edit, _('Edit'), {:action => 'edit', :id => st} %>
  21 + <%= button_without_text :delete, _('Remove'), {:action => 'destroy', :id => st}, :confirm => _('Are you sure you want to remove this status?') %>
  22 + </td>
  23 + </tr>
  24 + <% end %>
  25 + </table>
  26 + <% end %>
  27 +
  28 + <% button_bar do %>
  29 + <%= button(:add, _('Add a new status'), :action => 'create')%>
  30 + <%= button :back, _('Back to admin panel'), :controller => 'admin_panel' %>
  31 + <% end %>
  32 +</div>
... ...
plugins/container_block/lib/container_block_plugin.rb
... ... @@ -16,4 +16,8 @@ class ContainerBlockPlugin &lt; Noosfero::Plugin
16 16 true
17 17 end
18 18  
  19 + def js_files
  20 + 'container_block.js'
  21 + end
  22 +
19 23 end
... ...
plugins/container_block/lib/container_block_plugin/container_block.rb
... ... @@ -7,6 +7,16 @@ class ContainerBlockPlugin::ContainerBlock &lt; Block
7 7 settings_items :container_box_id, :type => Integer, :default => nil
8 8 settings_items :children_settings, :type => Hash, :default => {}
9 9  
  10 + validate :no_cyclical_reference, :if => 'container_box_id.present?'
  11 +
  12 + def no_cyclical_reference
  13 + errors.add(:box_id, _('cyclical reference is not allowed.')) if box_id == container_box_id
  14 + end
  15 +
  16 + before_save do |b|
  17 + raise "cyclical reference is not allowed" if b.box_id == b.container_box_id && !b.container_box_id.blank?
  18 + end
  19 +
10 20 def self.description
11 21 _('Container')
12 22 end
... ... @@ -15,6 +25,10 @@ class ContainerBlockPlugin::ContainerBlock &lt; Block
15 25 _('This block acts as a container for another blocks')
16 26 end
17 27  
  28 + def cacheable?
  29 + false
  30 + end
  31 +
18 32 def layout_template
19 33 nil
20 34 end
... ... @@ -24,8 +38,9 @@ class ContainerBlockPlugin::ContainerBlock &lt; Block
24 38 end
25 39  
26 40 def create_box
27   - box = Box.create!(:owner => owner)
28   - settings[:container_box_id] = box.id
  41 + container_box = Box.create!(:owner => owner)
  42 + container_box.update_attribute(:position, nil)
  43 + settings[:container_box_id] = container_box.id
29 44 save!
30 45 end
31 46  
... ...
plugins/container_block/public/container_block.js 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +function enableMoveContainerChildren(container, box) {
  2 + var div = jQuery('#box-'+box+' > .block-outer > .block');
  3 + if(!div.is('.ui-resizable')) {
  4 + div.resizable({
  5 + handles: 'e, w',
  6 + containment: '#block-'+container+' .block-inner-2',
  7 + resize: function( event, ui ) {
  8 + ui.element.height('auto');
  9 + }
  10 + });
  11 + }
  12 +}
  13 +
  14 +function disableMoveContainerChildren(container, box) {
  15 + var div = jQuery('#box-'+box+' > .block-outer > .block');
  16 + if(div.is('.ui-resizable')) {
  17 + div.resizable('destroy');
  18 + }
  19 +}
  20 +
  21 +function containerChildrenWidth(container, box) {
  22 + widths = "";
  23 + jQuery('#box-'+box+' > .block-outer > .block').each(function(i) {
  24 + childId = jQuery(this).attr('id').match(/block-(\d+)/)[1];
  25 + widths+=childId+","+jQuery(this).width()+"|";
  26 + });
  27 + return "widths="+widths;
  28 +}
... ...
plugins/container_block/public/style.css
  1 +#box-organizer .container-block-plugin_container-block > .block-inner-1 > .block-inner-2 > .button-bar {
  2 + height: 22px;
  3 + padding-bottom: 0px;
  4 + width: auto;
  5 +}
  6 +
1 7 #content .boxes .container-block-plugin_container-block .container_block_child, .container-block-plugin_container-block .block-outer {
2 8 display: inline-block;
3 9 vertical-align: top;
... ... @@ -17,14 +23,10 @@
17 23 background-image: url(/designs/icons/default/Tango/16x16/actions/go-previous.png);
18 24 }
19 25  
20   -#content .boxes .container-block-plugin_container-block .block {
21   - outline-offset: -2px;
22   -}
23   -
24 26 #content .boxes .container-block-plugin_container-block .block .ui-resizable-handle {
25 27 width: 10px;
26 28 height: 28px;
27   - z-index: 0;
  29 + z-index: 1000;
28 30 }
29 31  
30 32 #content .boxes .container-block-plugin_container-block .block .ui-resizable-e {
... ... @@ -37,6 +39,21 @@
37 39 background-image: url(/plugins/container_block/images/handle_w.png);
38 40 }
39 41  
40   -.container-block-plugin_container-block .button-bar .icon-resize {
  42 +.container-block-plugin_container-block .container-block-button-bar .icon-resize {
41 43 background-image: url(/designs/icons/default/Tango/16x16/actions/view-fullscreen.png);
42 44 }
  45 +
  46 +#box-organizer .block .container-block-button-bar {
  47 + right: 0px;
  48 + bottom: 0px;
  49 + height: auto;
  50 +}
  51 +
  52 +#box-organizer .container-block-plugin_container-block:hover .block {
  53 + outline: 1px dashed black;
  54 + outline-offset: -1px;
  55 +}
  56 +
  57 +.container-block-plugin_container-block .block-target {
  58 + background: #afd;
  59 +}
... ...
plugins/container_block/test/functional/container_block_home_controller_test.rb
... ... @@ -31,6 +31,13 @@ class HomeControllerTest &lt; ActionController::TestCase
31 31 assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' }
32 32 end
33 33  
  34 + should 'display block title' do
  35 + @block.title = "Block Title"
  36 + @block.save!
  37 + get :index
  38 + assert_tag :div, :attributes => { :class => 'block container-block-plugin_container-block' }, :descendant => {:tag => 'h3', :attributes => { :class => "block-title"}, :content => @block.title }
  39 + end
  40 +
34 41 should 'display container children' do
35 42 c1 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child1 content')
36 43 c2 = RawHTMLBlock.create!(:box => @block.container_box, :html => 'child2 content')
... ...
plugins/container_block/test/unit/block_test.rb
... ... @@ -1,31 +0,0 @@
1   -require 'test_helper'
2   -
3   -class BlockTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @environment = fast_create(Environment)
7   - @box = Box.create!(:owner => @environment)
8   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
9   - end
10   -
11   - should 'return environment box if block owner is not a ContainerBlock' do
12   - block = Block.create!(:box => @box)
13   - assert_equal @box, block.box
14   - end
15   -
16   - should 'return container box if block owner is a ContainerBlock' do
17   - block = Block.create!(:box => @container.container_box)
18   - assert_equal @container.container_box, block.box
19   - end
20   -
21   - should 'return block owner if block onwer is not a ContainerBlock' do
22   - block = Block.create!(:box => @box)
23   - assert_equal @environment, block.owner
24   - end
25   -
26   - should 'return environment as owner if block onwer is a ContainerBlock' do
27   - block = Block.create!(:box => @container.container_box)
28   - assert_equal @environment, block.owner
29   - end
30   -
31   -end
plugins/container_block/test/unit/container_block_plugin/container_block_test.rb
... ... @@ -20,6 +20,11 @@ class ContainerBlockPlugin::ContainerBlockTest &lt; ActiveSupport::TestCase
20 20 assert @block.container_box_id
21 21 end
22 22  
  23 + should 'created box should have nil as position' do
  24 + @block.save!
  25 + assert_equal nil, @block.container_box.position
  26 + end
  27 +
23 28 should 'return created box' do
24 29 @block.save!
25 30 assert @block.container_box
... ... @@ -89,4 +94,27 @@ class ContainerBlockPlugin::ContainerBlockTest &lt; ActiveSupport::TestCase
89 94 end
90 95 end
91 96  
  97 + should 'not mess up with boxes positions when destroyed' do
  98 + env = fast_create(Environment)
  99 + box1 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 1)
  100 + box2 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 2)
  101 + box3 = fast_create(Box, :owner_id => env.id, :owner_type => 'Environment', :position => 3)
  102 + block = ContainerBlockPlugin::ContainerBlock.create!(:box => box1)
  103 + block.destroy
  104 + assert_equal [1, 2, 3], [box1.reload.position, box2.reload.position, box3.reload.position]
  105 + end
  106 +
  107 + should 'be able to change box' do
  108 + @block.save!
  109 + @block.box = Box.new(:owner => Environment.default)
  110 + @block.save!
  111 + end
  112 +
  113 + should 'not able to change box to be the same as container_box' do
  114 + @block.save!
  115 + @block.box = @block.container_box
  116 + @block.save
  117 + assert @block.errors.invalid?(:box_id)
  118 + end
  119 +
92 120 end
... ...
plugins/container_block/test/unit/environment_test.rb
... ... @@ -1,32 +0,0 @@
1   -require 'test_helper'
2   -
3   -class EnvironmentTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @environment = fast_create(Environment)
7   -
8   - @box = Box.create!(:owner => @environment)
9   - @block = Block.create!(:box => @box)
10   -
11   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
12   - end
13   -
14   - should 'return blocks as usual' do
15   - assert_equal [@block, @container], @environment.blocks
16   - end
17   -
18   - should 'return blocks with container children' do
19   - child = Block.create!(:box => @container.container_box)
20   - assert_equal [@block, @container, child], @environment.blocks
21   - end
22   -
23   - should 'return block with id at find method' do
24   - assert_equal @block, @environment.blocks.find(@block.id)
25   - end
26   -
27   - should 'return child block with id at find method' do
28   - child = Block.create!(:box => @container.container_box)
29   - assert_equal child, @environment.blocks.find(child.id)
30   - end
31   -
32   -end
plugins/container_block/test/unit/profile_test.rb
... ... @@ -1,32 +0,0 @@
1   -require 'test_helper'
2   -
3   -class ProfileTest < ActiveSupport::TestCase
4   -
5   - def setup
6   - @profile = fast_create(Profile)
7   -
8   - @box = Box.create!(:owner => @profile)
9   - @block = Block.create!(:box => @box)
10   -
11   - @container = ContainerBlockPlugin::ContainerBlock.create!(:box => @box)
12   - end
13   -
14   - should 'return blocks as usual' do
15   - assert_equal [@block, @container], @profile.blocks
16   - end
17   -
18   - should 'return blocks with container children' do
19   - child = Block.create!(:box => @container.container_box)
20   - assert_equal [@block, @container, child], @profile.blocks
21   - end
22   -
23   - should 'return block with id at find method' do
24   - assert_equal @block, @profile.blocks.find(@block.id)
25   - end
26   -
27   - should 'return child block with id at find method' do
28   - child = Block.create!(:box => @container.container_box)
29   - assert_equal child, @profile.blocks.find(child.id)
30   - end
31   -
32   -end
plugins/container_block/views/blocks/container.rhtml
1 1 <% edit_mode = @controller.send(:boxes_editor?) && @controller.send(:uses_design_blocks?) %>
2 2 <% box_decorator = edit_mode ? self : BoxesHelper::DontMoveBlocks %>
3 3  
  4 +<%= block_title(block.title) %>
4 5  
5 6 <div class="box" id="box-<%= block.container_box.id %>">
6 7 <%= display_box_content(block.container_box, nil) %>
... ... @@ -15,8 +16,18 @@
15 16 </style>
16 17  
17 18 <% if edit_mode %>
18   - <div class="button-bar">
19   - <a href="#" onclick="toggleMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>); return false;" class="button icon-resize" title=<%= _('Resize blocks').to_json %>></a>
  19 +
  20 + <script>
  21 + jQuery("#block-<%= block.id %>").hover(
  22 + function() {
  23 + enableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>);
  24 + }, function() {
  25 + disableMoveContainerChildren(<%= block.id %>, <%= block.container_box.id %>);
  26 + }
  27 + );
  28 + </script>
  29 +
  30 + <div class="container-block-button-bar button-bar">
20 31 <%= link_to_remote '', :url => { :controller => @controller.boxes_holder.kind_of?(Environment) ? 'container_block_plugin_admin' : 'container_block_plugin_myprofile', :action => 'saveWidths', :id => block.id },
21 32 :with => "containerChildrenWidth(#{block.id}, #{block.container_box.id})",
22 33 :html => {:class => "button icon-save container_block_save", :id => "container_block_save_#{block.id}", :title => _('Save') },
... ... @@ -24,37 +35,4 @@
24 35 :loaded => "close_loading();",
25 36 :complete => "display_notice(request.responseText);"%>
26 37 </div>
27   -
28   - <script>
29   - function toggleMoveContainerChildren(container, box) {
30   - var div = jQuery('#box-'+box+' > .block-outer > .block');
31   - var targetDiv = jQuery('#box-'+box+' .block-outer .block-target');
32   - if(div.is('.ui-resizable')) {
33   - targetDiv.show();
34   - div.find("a").die("click");
35   - div.resizable('destroy');
36   - } else {
37   - targetDiv.hide();
38   - div.find("a").live("click", function(e) {
39   - e.preventDefault();
40   - });
41   - div.resizable({
42   - handles: 'e, w',
43   - containment: '#block-'+container+' .block-inner-2',
44   - resize: function( event, ui ) {
45   - ui.element.height('auto');
46   - }
47   - });
48   - }
49   - }
50   -
51   - function containerChildrenWidth(container, box) {
52   - widths = "";
53   - jQuery('#box-'+box+' > .block-outer > .block').each(function(i) {
54   - childId = jQuery(this).attr('id').match(/block-(\d+)/)[1];
55   - widths+=childId+","+jQuery(this).width()+"|";
56   - });
57   - return "widths="+widths;
58   - }
59   - </script>
60 38 <% end %>
... ...
plugins/context_content/views/blocks/_more.rhtml
1 1 <% if contents.total_pages > 1 %>
2   - <%= link_to_remote(nil, :url => {:id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.previous_page, :article_id => article_id }, :html => {:class => "button icon-button icon-left #{contents.previous_page ? '':'disabled'}".strip}, :condition => "#{!contents.previous_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'left'});" )%>
3   - <%= link_to_remote(nil, :url => {:id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.next_page, :article_id => article_id }, :html => {:class => "button icon-button icon-right #{contents.next_page ? '':'disabled'}".strip}, :condition => "#{!contents.next_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'right'});" )%>
  2 + <%= link_to_remote(nil, :url => {:profile => block.owner.identifier, :id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.previous_page, :article_id => article_id }, :html => {:class => "button icon-button icon-left #{contents.previous_page ? '':'disabled'}".strip}, :condition => "#{!contents.previous_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'left'});" )%>
  3 + <%= link_to_remote(nil, :url => {:profile => block.owner.identifier, :id => block.id, :controller => 'context_content_plugin_profile', :action => 'view_content', :page => contents.next_page, :article_id => article_id }, :html => {:class => "button icon-button icon-right #{contents.next_page ? '':'disabled'}".strip}, :condition => "#{!contents.next_page.nil?}", :success => "jQuery('#context_content_#{block.id}').effect('slide', {direction: 'right'});" )%>
4 4 <% end %>
... ...
plugins/require_auth_to_comment/public/hide_comment_form.js
1 1 (function($) {
2 2 $(window).bind('userDataLoaded', function(event, data) {
3   - if (data.login || $('meta[name=profile.allow_unauthenticated_comments]').length > 0) {
  3 + if (data.login || $('meta[name="profile.allow_unauthenticated_comments"]').length > 0) {
4 4 $('.post-comment-button').livequery(function() {
5 5 $(this).show();
6 6 });
... ... @@ -8,7 +8,7 @@
8 8 $(this).show();
9 9 });
10 10 $('.comment-footer').livequery(function() {
11   - $(this).show();
  11 + $(this).show();
12 12 });
13 13 }
14 14 });
... ...
plugins/shopping_cart/views/shopping_cart_plugin_myprofile/edit.html.erb
... ... @@ -33,8 +33,8 @@
33 33 </tr>
34 34 </table>
35 35  
36   - <%= labelled_form_field(_('Free delivery price:'), f.text_field(:free_delivery_price)) %>
37   - <%= content_tag('small', _('Empty stands for no free delivery price.')) %>
  36 + <%= labelled_form_field(_("Order's minimum price for free delivery:"), f.text_field(:free_delivery_price)) %>
  37 + <%= content_tag('small', _('Empty stands for no minimum price for free delivery.')) %>
38 38 </fieldset>
39 39 <br style='clear: both'/>
40 40 <br style='clear: both'/>
... ...
plugins/statistics/README 0 → 100644
... ... @@ -0,0 +1,54 @@
  1 +README - Statistics (Statistics Plugin)
  2 +================================
  3 +
  4 +Statistics is a plugin to allow the user adds a block where you could see statistics of it's context.
  5 +
  6 +The Statistics block will be available for all layout columns of communities, peole, enterprises and environments.
  7 +
  8 +INSTALL
  9 +=======
  10 +
  11 +Enable Plugin
  12 +-------------
  13 +
  14 +Also, you need to enable Statistics Plugin at you Noosfero:
  15 +
  16 +cd <your_noosfero_dir>
  17 +./script/noosfero-plugins enable statistics
  18 +
  19 +Active Plugin
  20 +-------------
  21 +
  22 +As a Noosfero administrator user, go to administrator panel:
  23 +
  24 +- Click on "Enable/disable plugins" option
  25 +- Click on "Statistics Plugin" check-box
  26 +
  27 +Running Statistics tests
  28 +--------------------
  29 +
  30 +$ rake test:noosfero_plugins:statistics
  31 +
  32 +
  33 +Get Involved
  34 +============
  35 +
  36 +If you found any bug and/or want to collaborate, please send an e-mail to eduardo.edington@gmail.com
  37 +
  38 +LICENSE
  39 +=======
  40 +
  41 +Copyright (c) The Author developers.
  42 +
  43 +See Noosfero license.
  44 +
  45 +
  46 +AUTHORS
  47 +=======
  48 +
  49 + Eduardo Tourinho Edington (eduardo.edington at gmail.com)
  50 +
  51 +ACKNOWLEDGMENTS
  52 +===============
  53 +
  54 +The author has been supported by Serpro
... ...
plugins/statistics/lib/statistics_block.rb 0 → 100644
... ... @@ -0,0 +1,146 @@
  1 +class StatisticsBlock < Block
  2 +
  3 + settings_items :community_counter, :default => false
  4 + settings_items :user_counter, :default => true
  5 + settings_items :enterprise_counter, :default => false
  6 + settings_items :category_counter, :default => false
  7 + settings_items :tag_counter, :default => true
  8 + settings_items :comment_counter, :default => true
  9 + settings_items :hit_counter, :default => false
  10 + settings_items :templates_ids_counter, Hash, :default => {}
  11 +
  12 + USER_COUNTERS = [:community_counter, :user_counter, :enterprise_counter, :tag_counter, :comment_counter, :hit_counter]
  13 + COMMUNITY_COUNTERS = [:user_counter, :tag_counter, :comment_counter, :hit_counter]
  14 + ENTERPRISE_COUNTERS = [:user_counter, :tag_counter, :comment_counter, :hit_counter]
  15 +
  16 + def self.description
  17 + _('Statistics')
  18 + end
  19 +
  20 + def default_title
  21 + _('Statistics for %s') % owner.name
  22 + end
  23 +
  24 + def is_visible? counter
  25 + value = self.send(counter)
  26 + value == '1' || value == true
  27 + end
  28 +
  29 + def is_counter_available? counter
  30 + if owner.kind_of?(Environment)
  31 + true
  32 + elsif owner.kind_of?(Person)
  33 + USER_COUNTERS.include?(counter)
  34 + elsif owner.kind_of?(Community)
  35 + COMMUNITY_COUNTERS.include?(counter)
  36 + elsif owner.kind_of?(Enterprise)
  37 + ENTERPRISE_COUNTERS.include?(counter)
  38 + end
  39 +
  40 + end
  41 +
  42 + def help
  43 + _('This block presents some statistics about your context.')
  44 + end
  45 +
  46 + def timeout
  47 + 60.minutes
  48 + end
  49 +
  50 + def environment
  51 + if owner.kind_of?(Environment)
  52 + owner
  53 + elsif owner.kind_of?(Profile)
  54 + owner.environment
  55 + else
  56 + nil
  57 + end
  58 + end
  59 +
  60 + def templates
  61 + Community.templates(environment)
  62 + end
  63 +
  64 + def is_template_counter_active? template_id
  65 + self.templates_ids_counter[template_id.to_s].to_s == 'true'
  66 + end
  67 +
  68 + def template_counter_count(template_id)
  69 + owner.communities.visible.count(:conditions => {:template_id => template_id})
  70 + end
  71 +
  72 + def users
  73 + if owner.kind_of?(Environment)
  74 + owner.people.visible.count
  75 + elsif owner.kind_of?(Organization)
  76 + owner.members.visible.count
  77 + elsif owner.kind_of?(Person)
  78 + owner.friends.visible.count
  79 + else
  80 + 0
  81 + end
  82 + end
  83 +
  84 + def enterprises
  85 + if owner.kind_of?(Environment) || owner.kind_of?(Person)
  86 + owner.enterprises.visible.count
  87 + else
  88 + 0
  89 + end
  90 + end
  91 +
  92 + def communities
  93 + if owner.kind_of?(Environment) || owner.kind_of?(Person)
  94 + owner.communities.visible.count
  95 + else
  96 + 0
  97 + end
  98 + end
  99 +
  100 + def categories
  101 + if owner.kind_of?(Environment) then
  102 + owner.categories.count
  103 + else
  104 + 0
  105 + end
  106 + end
  107 +
  108 + def tags
  109 + if owner.kind_of?(Environment) then
  110 + owner.tag_counts.count
  111 + elsif owner.kind_of?(Profile) then
  112 + owner.article_tags.count
  113 + else
  114 + 0
  115 + end
  116 + end
  117 +
  118 + def comments
  119 + if owner.kind_of?(Environment) then
  120 + owner.profiles.joins(:articles).sum(:comments_count).to_i
  121 + elsif owner.kind_of?(Profile) then
  122 + owner.articles.sum(:comments_count)
  123 + else
  124 + 0
  125 + end
  126 + end
  127 +
  128 + def hits
  129 + if owner.kind_of?(Environment) then
  130 + owner.profiles.joins(:articles).sum(:hits).to_i
  131 + elsif owner.kind_of?(Profile) then
  132 + owner.articles.sum(:hits)
  133 + else
  134 + 0
  135 + end
  136 + end
  137 +
  138 + def content(args={})
  139 + block = self
  140 +
  141 + lambda do
  142 + render :file => 'statistics_block', :locals => { :block => block }
  143 + end
  144 + end
  145 +
  146 +end
... ...
plugins/statistics/lib/statistics_plugin.rb 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +require_dependency File.dirname(__FILE__) + '/statistics_block'
  2 +
  3 +class StatisticsPlugin < Noosfero::Plugin
  4 +
  5 + def self.plugin_name
  6 + "Statistics Plugin"
  7 + end
  8 +
  9 + def self.plugin_description
  10 + _("A plugin that adds a block where you can see statistics of it's context.")
  11 + end
  12 +
  13 + def self.extra_blocks
  14 + {
  15 + StatisticsBlock => {}
  16 + }
  17 + end
  18 +
  19 +end
... ...
plugins/statistics/test/functional/statistics_plugin_environment_design_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,161 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class EnvironmentDesignController; def rescue_action(e) raise e end; end
  5 +
  6 +class EnvironmentDesignControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = EnvironmentDesignController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 +
  13 + Environment.delete_all
  14 +
  15 + @environment = Environment.create(:name => 'testenv', :is_default => true)
  16 + @environment.enabled_plugins = ['StatisticsPlugin']
  17 + @environment.save!
  18 +
  19 + user = create_user('testinguser')
  20 + @environment.add_admin(user.person)
  21 +
  22 + StatisticsBlock.delete_all
  23 + @box1 = Box.create!(:owner => @environment)
  24 + @environment.boxes = [@box1]
  25 +
  26 + @block = StatisticsBlock.new
  27 + @block.box = @box1
  28 + @block.save!
  29 +
  30 + login_as(user.login)
  31 + end
  32 +
  33 + attr_accessor :block
  34 +
  35 + should 'be able to edit StatisticsBlock' do
  36 + get :edit, :id => @block.id
  37 + assert_tag :tag => 'input', :attributes => { :id => 'block_title' }
  38 + end
  39 +
  40 + should 'be able to save StatisticsBlock' do
  41 + get :edit, :id => @block.id
  42 + post :save, :id => @block.id, :block => {:title => 'Statistics' }
  43 + @block.reload
  44 + assert_equal 'Statistics', @block.title
  45 + end
  46 +
  47 + should 'be able to uncheck core counters' do
  48 + @block.user_counter = true
  49 + @block.community_counter = true
  50 + @block.enterprise_counter = true
  51 + @block.category_counter = true
  52 + @block.tag_counter = true
  53 + @block.comment_counter = true
  54 + @block.hit_counter = true
  55 + @block.save!
  56 + get :edit, :id => @block.id
  57 + post :save, :id => @block.id, :block => {:user_counter => '0', :community_counter => '0', :enterprise_counter => '0',
  58 + :category_counter => '0', :tag_counter => '0', :comment_counter => '0', :hit_counter => '0' }
  59 + @block.reload
  60 + any_checked = @block.is_visible?('user_counter') ||
  61 + @block.is_visible?('community_counter') ||
  62 + @block.is_visible?('enterprise_counter') ||
  63 + @block.is_visible?('category_counter') ||
  64 + @block.is_visible?('tag_counter') ||
  65 + @block.is_visible?('comment_counter') ||
  66 + @block.is_visible?('hit_counter')
  67 + assert_equal false, any_checked
  68 +
  69 + end
  70 +
  71 + should 'be able to check core counters' do
  72 + @block.user_counter = false
  73 + @block.community_counter = false
  74 + @block.enterprise_counter = false
  75 + @block.category_counter = false
  76 + @block.tag_counter = false
  77 + @block.comment_counter = false
  78 + @block.hit_counter = false
  79 + @block.save!
  80 + get :edit, :id => @block.id
  81 + post :save, :id => @block.id, :block => {:user_counter => '1', :community_counter => '1', :enterprise_counter => '1',
  82 + :category_counter => '1', :tag_counter => '1', :comment_counter => '1', :hit_counter => '1' }
  83 + @block.reload
  84 + all_checked = @block.is_visible?('user_counter') &&
  85 + @block.is_visible?('community_counter') &&
  86 + @block.is_visible?('enterprise_counter') &&
  87 + @block.is_visible?('category_counter') &&
  88 + @block.is_visible?('tag_counter') &&
  89 + @block.is_visible?('comment_counter') &&
  90 + @block.is_visible?('hit_counter')
  91 + assert all_checked
  92 +
  93 + end
  94 +
  95 + should 'be able to check template counters' do
  96 + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id)
  97 + @block.templates_ids_counter = {template.id.to_s => 'false'}
  98 + @block.save!
  99 + get :edit, :id => @block.id
  100 + post :save, :id => @block.id, :block => {:templates_ids_counter => {template.id.to_s => 'true'}}
  101 + @block.reload
  102 +
  103 + assert @block.is_template_counter_active?(template.id)
  104 + end
  105 +
  106 + should 'be able to uncheck template counters' do
  107 + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id)
  108 + @block.templates_ids_counter = {template.id.to_s => 'true'}
  109 + @block.save!
  110 + get :edit, :id => @block.id
  111 + post :save, :id => @block.id, :block => {:templates_ids_counter => {template.id.to_s => 'false'}}
  112 + @block.reload
  113 +
  114 + assert_equal false, @block.is_template_counter_active?(template.id)
  115 + end
  116 +
  117 + should 'input user counter be checked by default' do
  118 + get :edit, :id => @block.id
  119 +
  120 + assert_tag :input, :attributes => {:id => 'block_user_counter', :checked => 'checked'}
  121 + end
  122 +
  123 + should 'not input community counter be checked by default' do
  124 + get :edit, :id => @block.id
  125 +
  126 + assert_tag :input, :attributes => {:id => 'block_community_counter'}
  127 + assert_no_tag :input, :attributes => {:id => 'block_community_counter', :checked => 'checked'}
  128 + end
  129 +
  130 + should 'not input enterprise counter be checked by default' do
  131 + get :edit, :id => @block.id
  132 +
  133 + assert_tag :input, :attributes => {:id => 'block_enterprise_counter'}
  134 + assert_no_tag :input, :attributes => {:id => 'block_enterprise_counter', :checked => 'checked'}
  135 + end
  136 +
  137 + should 'not input category counter be checked by default' do
  138 + get :edit, :id => @block.id
  139 +
  140 + assert_tag :input, :attributes => {:id => 'block_category_counter'}
  141 + assert_no_tag :input, :attributes => {:id => 'block_category_counter', :checked => 'checked'}
  142 + end
  143 +
  144 + should 'input tag counter be checked by default' do
  145 + get :edit, :id => @block.id
  146 +
  147 + assert_tag :input, :attributes => {:id => 'block_tag_counter', :checked => 'checked'}
  148 + end
  149 +
  150 + should 'input comment counter be checked by default' do
  151 + get :edit, :id => @block.id
  152 +
  153 + assert_tag :input, :attributes => {:id => 'block_comment_counter', :checked => 'checked'}
  154 + end
  155 +
  156 + should 'input hit counter not be checked by default' do
  157 + get :edit, :id => @block.id
  158 +
  159 + assert_no_tag :input, :attributes => {:id => 'block_hit_counter', :checked => 'checked'}
  160 + end
  161 +end
... ...
plugins/statistics/test/functional/statistics_plugin_home_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,147 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class HomeController; def rescue_action(e) raise e end; end
  5 +
  6 +class HomeControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = HomeController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 +
  13 + Environment.delete_all
  14 +
  15 + @environment = Environment.create(:name => 'testenv', :is_default => true)
  16 + @environment.enabled_plugins = ['StatisticsPlugin']
  17 + @environment.save!
  18 +
  19 + user = create_user('testinguser')
  20 + @environment.add_admin(user.person)
  21 +
  22 + StatisticsBlock.delete_all
  23 + @box1 = Box.create!(:owner => @environment)
  24 + @environment.boxes = [@box1]
  25 +
  26 + @block = StatisticsBlock.new
  27 + @block.box = @box1
  28 + @block.save!
  29 +
  30 + login_as(user.login)
  31 + end
  32 +
  33 + attr_accessor :block
  34 +
  35 + should 'display statistics-block-data class in environment block edition' do
  36 + get :index
  37 +
  38 + assert_tag :div, :attributes => {:class => 'statistics-block-data'}
  39 + end
  40 +
  41 + should 'display users class in statistics-block-data block' do
  42 + get :index
  43 +
  44 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'users'} }
  45 + end
  46 +
  47 + should 'not display users class in statistics-block-data block' do
  48 + @block.user_counter = false
  49 + @block.save!
  50 + get :index
  51 +
  52 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'users'} }
  53 + end
  54 +
  55 + should 'display communities class in statistics-block-data block' do
  56 + @block.community_counter = true
  57 + @block.save!
  58 + get :index
  59 +
  60 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'communities'} }
  61 + end
  62 +
  63 + should 'not display communities class in statistics-block-data block' do
  64 + get :index
  65 +
  66 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'communities'} }
  67 + end
  68 +
  69 + should 'display enterprises class in statistics-block-data block' do
  70 + @block.enterprise_counter = true
  71 + @block.save!
  72 + get :index
  73 +
  74 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'enterprises'} }
  75 + end
  76 +
  77 + should 'not display enterprises class in statistics-block-data block' do
  78 + get :index
  79 +
  80 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'enterprises'} }
  81 + end
  82 +
  83 + should 'display categories class in statistics-block-data block' do
  84 + @block.category_counter = true
  85 + @block.save!
  86 + get :index
  87 +
  88 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'categories'} }
  89 + end
  90 +
  91 + should 'not display categories class in statistics-block-data block' do
  92 + get :index
  93 +
  94 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'categories'} }
  95 + end
  96 +
  97 + should 'display tags class in statistics-block-data block' do
  98 + get :index
  99 +
  100 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'tags'} }
  101 + end
  102 +
  103 + should 'not display tags class in statistics-block-data block' do
  104 + @block.tag_counter = false
  105 + @block.save!
  106 + get :index
  107 +
  108 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'tags'} }
  109 + end
  110 +
  111 + should 'display comments class in statistics-block-data block' do
  112 + get :index
  113 +
  114 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'comments'} }
  115 + end
  116 +
  117 + should 'not display comments class in statistics-block-data block' do
  118 + @block.comment_counter = false
  119 + @block.save!
  120 + get :index
  121 +
  122 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'comments'} }
  123 + end
  124 +
  125 + should 'display hits class in statistics-block-data block' do
  126 + @block.hit_counter = true
  127 + @block.save!
  128 + get :index
  129 +
  130 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'hits'} }
  131 + end
  132 +
  133 + should 'not display hits class in statistics-block-data block' do
  134 + get :index
  135 +
  136 + assert_no_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'hits'} }
  137 + end
  138 +
  139 + should 'display template name in class in statistics-block-data block' do
  140 + template = fast_create(Community, :name => 'Councils', :is_template => true, :environment_id => @environment.id)
  141 + @block.templates_ids_counter = {template.id.to_s => 'true'}
  142 + @block.save!
  143 + get :index
  144 +
  145 + assert_tag :tag => 'div', :attributes => {:class => 'statistics-block-data'}, :descendant => { :tag => 'li', :attributes => {:class => 'councils'} }
  146 + end
  147 +end
... ...
plugins/statistics/test/functional/statistics_plugin_profile_design_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,85 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +# Re-raise errors caught by the controller.
  4 +class ProfileDesignController; def rescue_action(e) raise e end; end
  5 +
  6 +class ProfileDesignControllerTest < ActionController::TestCase
  7 +
  8 + def setup
  9 + @controller = ProfileDesignController.new
  10 + @request = ActionController::TestRequest.new
  11 + @response = ActionController::TestResponse.new
  12 +
  13 + Environment.delete_all
  14 +
  15 + @environment = Environment.create(:name => 'testenv', :is_default => true)
  16 + @environment.enabled_plugins = ['StatisticsPlugin']
  17 + @environment.save!
  18 +
  19 + user = create_user('testinguser')
  20 + @person = user.person
  21 + @environment.add_admin(@person)
  22 +
  23 + StatisticsBlock.delete_all
  24 + @box1 = Box.create!(:owner => @person)
  25 + @environment.boxes = [@box1]
  26 +
  27 + @block = StatisticsBlock.new
  28 + @block.box = @box1
  29 + @block.save!
  30 +
  31 + login_as(user.login)
  32 + end
  33 +
  34 + attr_accessor :block
  35 +
  36 + should 'be able to edit StatisticsBlock' do
  37 + get :edit, :id => @block.id, :profile => @person.identifier
  38 + assert_tag :tag => 'input', :attributes => { :id => 'block_title' }
  39 + end
  40 +
  41 + should 'be able to save StatisticsBlock' do
  42 + get :edit, :id => @block.id, :profile => @person.identifier
  43 + post :save, :id => @block.id, :block => {:title => 'Statistics' }, :profile => @person.identifier
  44 + @block.reload
  45 + assert_equal 'Statistics', @block.title
  46 + end
  47 +
  48 + should 'be able to uncheck core counters' do
  49 + @block.user_counter = true
  50 + @block.tag_counter = true
  51 + @block.comment_counter = true
  52 + @block.hit_counter = true
  53 + @block.save!
  54 + get :edit, :id => @block.id, :profile => @person.identifier
  55 + post :save, :id => @block.id, :block => {:user_counter => '0', :tag_counter => '0', :comment_counter => '0', :hit_counter => '0' }, :profile => @person.identifier
  56 + @block.reload
  57 + any_checked = @block.is_visible?('user_counter') ||
  58 + @block.is_visible?('tag_counter') ||
  59 + @block.is_visible?('comment_counter') ||
  60 + @block.is_visible?('hit_counter')
  61 + assert_equal false, any_checked
  62 + end
  63 +
  64 + should 'be able to check core counters' do
  65 + @block.user_counter = false
  66 + @block.community_counter = false
  67 + @block.enterprise_counter = false
  68 + @block.category_counter = false
  69 + @block.tag_counter = false
  70 + @block.comment_counter = false
  71 + @block.hit_counter = false
  72 + @block.save!
  73 + get :edit, :id => @block.id, :profile => @person.identifier
  74 + post :save, :id => @block.id, :block => {:user_counter => '1',
  75 + :tag_counter => '1', :comment_counter => '1', :hit_counter => '1' }, :profile => @person.identifier
  76 + @block.reload
  77 + all_checked = @block.is_visible?('user_counter') &&
  78 + @block.is_visible?('tag_counter') &&
  79 + @block.is_visible?('comment_counter') &&
  80 + @block.is_visible?('hit_counter')
  81 + assert all_checked
  82 +
  83 + end
  84 +
  85 +end
... ...
plugins/statistics/test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
... ...
plugins/statistics/test/unit/statistics_block_test.rb 0 → 100644
... ... @@ -0,0 +1,336 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +class StatisticsBlockTest < ActiveSupport::TestCase
  3 +
  4 + ['user_counter', 'tag_counter', 'comment_counter'].map do |counter|
  5 + should "#{counter} be true by default" do
  6 + b = StatisticsBlock.new
  7 + assert b.is_visible?(counter)
  8 + end
  9 + end
  10 +
  11 + ['community_counter', 'enterprise_counter', 'category_counter', 'hit_counter'].map do |counter|
  12 + should "#{counter} be false by default" do
  13 + b = StatisticsBlock.new
  14 + assert !b.is_visible?(counter)
  15 + end
  16 + end
  17 +
  18 + should 'inherit from Block' do
  19 + assert_kind_of Block, StatisticsBlock.new
  20 + end
  21 +
  22 + should 'provide a default title' do
  23 + block = StatisticsBlock.new
  24 +
  25 + owner = mock
  26 + owner.expects(:name).returns('my environment')
  27 + block.expects(:owner).returns(owner)
  28 + assert_equal 'Statistics for my environment', block.title
  29 + end
  30 +
  31 + should 'describe itself' do
  32 + assert_not_equal StatisticsBlock.description, Block.description
  33 + end
  34 +
  35 + should 'is_visible? return true if setting is true' do
  36 + b = StatisticsBlock.new
  37 + b.community_counter = true
  38 + assert b.is_visible?('community_counter')
  39 + end
  40 +
  41 + should 'is_visible? return false if setting is false' do
  42 + b = StatisticsBlock.new
  43 + b.community_counter = false
  44 + assert !b.is_visible?('community_counter')
  45 + end
  46 +
  47 + should 'templates return the Community templates of the Environment' do
  48 + b = StatisticsBlock.new
  49 + e = fast_create(Environment)
  50 +
  51 + t1 = fast_create(Community, :is_template => true, :environment_id => e.id)
  52 + t2 = fast_create(Community, :is_template => true, :environment_id => e.id)
  53 + fast_create(Community, :is_template => false)
  54 +
  55 + b.expects(:owner).at_least_once.returns(e)
  56 +
  57 + t = b.templates
  58 + assert_equal [], [t1,t2] - t
  59 + assert_equal [], t - [t1,t2]
  60 + end
  61 +
  62 + should 'users return the amount of users of the Environment' do
  63 + b = StatisticsBlock.new
  64 + e = fast_create(Environment)
  65 +
  66 + fast_create(Person, :environment_id => e.id)
  67 + fast_create(Person, :environment_id => e.id)
  68 + fast_create(Person, :visible => false, :environment_id => e.id)
  69 +
  70 + b.expects(:owner).at_least_once.returns(e)
  71 +
  72 + assert_equal 2, b.users
  73 + end
  74 +
  75 + should 'users return the amount of members of the community' do
  76 + b = StatisticsBlock.new
  77 +
  78 + c1 = fast_create(Community)
  79 + c1.add_member(fast_create(Person))
  80 + c1.add_member(fast_create(Person))
  81 + c1.add_member(fast_create(Person))
  82 + c1.add_member(fast_create(Person, :visible => false))
  83 + c1.add_member(fast_create(Person, :visible => false))
  84 +
  85 + b.expects(:owner).at_least_once.returns(c1)
  86 + assert_equal 3, b.users
  87 + end
  88 +
  89 + should 'users return the amount of friends of the person' do
  90 + b = StatisticsBlock.new
  91 +
  92 + p1 = fast_create(Person)
  93 + p1.add_friend(fast_create(Person))
  94 + p1.add_friend(fast_create(Person))
  95 + p1.add_friend(fast_create(Person))
  96 + p1.add_friend(fast_create(Person, :visible => false))
  97 + p1.add_friend(fast_create(Person, :visible => false))
  98 +
  99 + b.expects(:owner).at_least_once.returns(p1)
  100 + assert_equal 3, b.users
  101 + end
  102 +
  103 + should 'communities return the amount of communities of the Environment' do
  104 + b = StatisticsBlock.new
  105 + e = fast_create(Environment)
  106 +
  107 + fast_create(Community, :environment_id => e.id)
  108 + fast_create(Community, :environment_id => e.id)
  109 + fast_create(Community, :visible => false, :environment_id => e.id)
  110 +
  111 + b.expects(:owner).at_least_once.returns(e)
  112 +
  113 + assert_equal 2, b.communities
  114 + end
  115 +
  116 + should 'enterprises return the amount of enterprises of the Environment' do
  117 + b = StatisticsBlock.new
  118 + e = fast_create(Environment)
  119 +
  120 + fast_create(Enterprise, :environment_id => e.id)
  121 + fast_create(Enterprise, :environment_id => e.id)
  122 + fast_create(Enterprise, :visible => false, :environment_id => e.id)
  123 +
  124 + b.expects(:owner).at_least_once.returns(e)
  125 +
  126 + assert_equal 2, b.enterprises
  127 + end
  128 +
  129 + should 'categories return the amount of categories of the Environment' do
  130 + b = StatisticsBlock.new
  131 + e = fast_create(Environment)
  132 +
  133 + fast_create(Category, :environment_id => e.id)
  134 + fast_create(Category, :environment_id => e.id)
  135 +
  136 + b.expects(:owner).at_least_once.returns(e)
  137 +
  138 + assert_equal 2, b.categories
  139 + end
  140 +
  141 + should 'tags return the amount of tags of the Environment' do
  142 + b = StatisticsBlock.new
  143 + e = fast_create(Environment)
  144 +
  145 + p1 = fast_create(Person, :environment_id => e.id)
  146 + a1 = fast_create(Article, :profile_id => p1.id)
  147 + t1 = fast_create(Tag, :name => 'T1')
  148 + t2 = fast_create(Tag, :name => 'T2')
  149 + a1.tags << t1
  150 + a1.tags << t2
  151 + a2 = fast_create(Article, :profile_id => p1.id)
  152 + t3 = fast_create(Tag, :name => 'T3')
  153 + t4 = fast_create(Tag, :name => 'T4')
  154 + a2.tags << t3
  155 + a2.tags << t4
  156 +
  157 + b.expects(:owner).at_least_once.returns(e)
  158 +
  159 + assert_equal 4, b.tags
  160 + end
  161 +
  162 + should 'tags return the amount of tags of the community' do
  163 + b = StatisticsBlock.new
  164 + e = fast_create(Environment)
  165 +
  166 + c1 = fast_create(Community, :environment_id => e.id)
  167 + a1 = fast_create(Article, :profile_id => c1.id)
  168 + t1 = fast_create(Tag, :name => 'T1')
  169 + t2 = fast_create(Tag, :name => 'T2')
  170 + a1.tags << t1
  171 + a1.tags << t2
  172 + a2 = fast_create(Article, :profile_id => c1.id)
  173 + t3 = fast_create(Tag, :name => 'T3')
  174 + t4 = fast_create(Tag, :name => 'T4')
  175 + a2.tags << t3
  176 + a2.tags << t4
  177 +
  178 + b.expects(:owner).at_least_once.returns(c1)
  179 +
  180 + assert_equal 4, b.tags
  181 + end
  182 +
  183 + should 'tags return the amount of tags of the profile (person)' do
  184 + b = StatisticsBlock.new
  185 + e = fast_create(Environment)
  186 +
  187 + p1 = fast_create(Person, :environment_id => e.id)
  188 + a1 = fast_create(Article, :profile_id => p1.id)
  189 + t1 = fast_create(Tag, :name => 'T1')
  190 + t2 = fast_create(Tag, :name => 'T2')
  191 + a1.tags << t1
  192 + a1.tags << t2
  193 + a2 = fast_create(Article, :profile_id => p1.id)
  194 + t3 = fast_create(Tag, :name => 'T3')
  195 + t4 = fast_create(Tag, :name => 'T4')
  196 + a2.tags << t3
  197 + a2.tags << t4
  198 +
  199 + b.expects(:owner).at_least_once.returns(p1)
  200 +
  201 + assert_equal 4, b.tags
  202 + end
  203 +
  204 + should 'comments return the amount of comments of the Environment' do
  205 + b = StatisticsBlock.new
  206 + e = fast_create(Environment)
  207 +
  208 + p1 = fast_create(Person, :environment_id => e.id)
  209 + a1 = fast_create(Article, :profile_id => p1.id)
  210 +
  211 + Comment.create!(:source => a1, :body => 'C1', :author_id => 1)
  212 + Comment.create!(:source => a1, :body => 'C2', :author_id => 1)
  213 +
  214 + a2 = fast_create(Article, :profile_id => p1.id)
  215 + Comment.create!(:source => a2, :body => 'C3', :author_id => 1)
  216 + Comment.create!(:source => a2, :body => 'C4', :author_id => 1)
  217 +
  218 + b.expects(:owner).at_least_once.returns(e)
  219 +
  220 + assert_equal 4, b.comments
  221 + end
  222 +
  223 + should 'comments return the amount of comments of the community' do
  224 + b = StatisticsBlock.new
  225 + e = Environment.default
  226 +
  227 + c1 = fast_create(Community, :environment_id => e.id)
  228 + a1 = fast_create(Article, :profile_id => c1.id)
  229 + Comment.create!(:source => a1, :body => 'C1', :author_id => 1)
  230 + Comment.create!(:source => a1, :body => 'C2', :author_id => 1)
  231 +
  232 + a2 = fast_create(Article, :profile_id => c1.id)
  233 + Comment.create!(:source => a2, :body => 'C3', :author_id => 1)
  234 + Comment.create!(:source => a2, :body => 'C4', :author_id => 1)
  235 +
  236 + b.expects(:owner).at_least_once.returns(c1)
  237 +
  238 + assert_equal 4, b.comments
  239 + end
  240 +
  241 + should 'comments return the amount of comments of the profile (person)' do
  242 + b = StatisticsBlock.new
  243 + e = fast_create(Environment)
  244 +
  245 + p1 = fast_create(Person, :environment_id => e.id)
  246 + a1 = fast_create(Article, :profile_id => p1.id)
  247 + Comment.create!(:source => a1, :body => 'C1', :author_id => 1)
  248 + Comment.create!(:source => a1, :body => 'C2', :author_id => 1)
  249 +
  250 + a2 = fast_create(Article, :profile_id => p1.id)
  251 + Comment.create!(:source => a1, :body => 'C3', :author_id => 1)
  252 + Comment.create!(:source => a1, :body => 'C4', :author_id => 1)
  253 +
  254 + b.expects(:owner).at_least_once.returns(p1)
  255 +
  256 + assert_equal 4, b.comments
  257 + end
  258 +
  259 + should 'hits return the amount of hits of the Environment' do
  260 + b = StatisticsBlock.new
  261 + e = fast_create(Environment)
  262 +
  263 + p1 = fast_create(Person, :environment_id => e.id)
  264 + a1 = fast_create(Article, :profile_id => p1.id, :hits => 2)
  265 + a2 = fast_create(Article, :profile_id => p1.id, :hits => 5)
  266 +
  267 + b.expects(:owner).at_least_once.returns(e)
  268 +
  269 + assert_equal 7, b.hits
  270 + end
  271 +
  272 + should 'hits return the amount of hits of the community' do
  273 + b = StatisticsBlock.new
  274 + e = fast_create(Environment)
  275 +
  276 + c1 = fast_create(Community, :environment_id => e.id)
  277 + a1 = fast_create(Article, :profile_id => c1.id, :hits => 2)
  278 + a2 = fast_create(Article, :profile_id => c1.id, :hits => 5)
  279 +
  280 + b.expects(:owner).at_least_once.returns(c1)
  281 +
  282 + assert_equal 7, b.hits
  283 + end
  284 +
  285 + should 'hits return the amount of hits of the profile (person)' do
  286 + b = StatisticsBlock.new
  287 + e = fast_create(Environment)
  288 +
  289 + p1 = fast_create(Person, :environment_id => e.id)
  290 + a1 = fast_create(Article, :profile_id => p1.id, :hits => 2)
  291 + a2 = fast_create(Article, :profile_id => p1.id, :hits => 5)
  292 +
  293 + b.expects(:owner).at_least_once.returns(p1)
  294 +
  295 + assert_equal 7, b.hits
  296 + end
  297 +
  298 + should 'is_counter_available? return true for all counters if owner is environment' do
  299 + b = StatisticsBlock.new
  300 + e = fast_create(Environment)
  301 +
  302 + b.expects(:owner).at_least_once.returns(e)
  303 +
  304 + assert b.is_counter_available?(:user_counter)
  305 + end
  306 +
  307 + should 'is_template_counter_active? return true if setting is true' do
  308 + b = StatisticsBlock.new
  309 + b.templates_ids_counter = {'1' => 'true'}
  310 + assert b.is_template_counter_active?(1)
  311 + end
  312 +
  313 + should 'is_template_counter_active? return false if setting is false' do
  314 + b = StatisticsBlock.new
  315 + b.templates_ids_counter = {'1' => 'false'}
  316 + assert !b.is_template_counter_active?(1)
  317 + end
  318 +
  319 + should 'template_counter_count return the amount of communities of the Environment using a template' do
  320 + b = StatisticsBlock.new
  321 + e = fast_create(Environment)
  322 +
  323 + t1 = fast_create(Community, :is_template => true, :environment_id => e.id)
  324 + t2 = fast_create(Community, :is_template => true, :environment_id => e.id)
  325 + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => true)
  326 + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => true)
  327 + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t1.id, :visible => false)
  328 +
  329 + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t2.id, :visible => true)
  330 + fast_create(Community, :is_template => false, :environment_id => e.id, :template_id => t2.id, :visible => false)
  331 +
  332 + b.expects(:owner).at_least_once.returns(e)
  333 +
  334 + assert_equal 2, b.template_counter_count(t1.id)
  335 + end
  336 +end
... ...
plugins/statistics/test/unit/statistics_plugin_test.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class StatisticsPluginTest < ActiveSupport::TestCase
  4 +
  5 + should "return StatisticsBlock in extra_mlocks class method" do
  6 + assert StatisticsPlugin.extra_blocks.keys.include?(StatisticsBlock)
  7 + end
  8 +
  9 +end
... ...