Commit 858648c1ccfefe0e6c441b312777a4df48c02a9b

Authored by Ábner Oliveira
2 parents c22f58b9 8c9632f9
Exists in staging and in 1 other branch production

Merge branch 'master' into staging

Showing 60 changed files with 486 additions and 130 deletions   Show diff stats
app/api/entities.rb
@@ -121,6 +121,10 @@ module Api @@ -121,6 +121,10 @@ module Api
121 expose :type 121 expose :type
122 expose :custom_header 122 expose :custom_header
123 expose :custom_footer 123 expose :custom_footer
  124 + expose :permissions do |profile, options|
  125 + Entities.permissions_for_entity(profile, options[:current_person],
  126 + :allow_post_content?, :allow_edit?, :allow_destroy?)
  127 + end
124 end 128 end
125 129
126 class UserBasic < Entity 130 class UserBasic < Entity
@@ -202,12 +206,21 @@ module Api @@ -202,12 +206,21 @@ module Api
202 expose :accept_comments?, as: :accept_comments 206 expose :accept_comments?, as: :accept_comments
203 end 207 end
204 208
  209 + def self.permissions_for_entity(entity, current_person, *method_names)
  210 + method_names.map { |method| entity.send(method, current_person) ? method.to_s.gsub(/\?/,'') : nil }.compact
  211 + end
  212 +
205 class Article < ArticleBase 213 class Article < ArticleBase
206 root 'articles', 'article' 214 root 'articles', 'article'
207 expose :parent, :using => ArticleBase 215 expose :parent, :using => ArticleBase
208 expose :children, :using => ArticleBase do |article, options| 216 expose :children, :using => ArticleBase do |article, options|
209 article.children.published.limit(V1::Articles::MAX_PER_PAGE) 217 article.children.published.limit(V1::Articles::MAX_PER_PAGE)
210 end 218 end
  219 + expose :permissions do |article, options|
  220 + Entities.permissions_for_entity(article, options[:current_person],
  221 + :allow_edit?, :allow_post_content?, :allow_delete?, :allow_create?,
  222 + :allow_publish_content?)
  223 + end
211 end 224 end
212 225
213 class User < Entity 226 class User < Entity
app/api/helpers.rb
@@ -132,7 +132,7 @@ module Api @@ -132,7 +132,7 @@ module Api
132 132
133 def present_article(asset) 133 def present_article(asset)
134 article = find_article(asset.articles, params[:id]) 134 article = find_article(asset.articles, params[:id])
135 - present_partial article, :with => Entities::Article, :params => params 135 + present_partial article, with: Entities::Article, params: params, current_person: current_person
136 end 136 end
137 137
138 def present_articles_for_asset(asset, method = 'articles') 138 def present_articles_for_asset(asset, method = 'articles')
@@ -141,7 +141,7 @@ module Api @@ -141,7 +141,7 @@ module Api
141 end 141 end
142 142
143 def present_articles(articles) 143 def present_articles(articles)
144 - present_partial paginate(articles), :with => Entities::Article, :params => params 144 + present_partial paginate(articles), :with => Entities::Article, :params => params, current_person: current_person
145 end 145 end
146 146
147 def find_articles(asset, method = 'articles') 147 def find_articles(asset, method = 'articles')
app/api/v1/activities.rb
1 module Api 1 module Api
2 module V1 2 module V1
3 class Activities < Grape::API 3 class Activities < Grape::API
4 - before { authenticate! }  
5 4
6 resource :profiles do 5 resource :profiles do
7 6
@@ -9,7 +8,7 @@ module Api @@ -9,7 +8,7 @@ module Api
9 profile = Profile.find_by id: params[:id] 8 profile = Profile.find_by id: params[:id]
10 9
11 not_found! if profile.blank? || profile.secret || !profile.visible 10 not_found! if profile.blank? || profile.secret || !profile.visible
12 - forbidden! if !profile.secret && profile.visible && !profile.display_private_info_to?(current_person) 11 + forbidden! if !profile.display_private_info_to?(current_person)
13 12
14 activities = profile.activities.map(&:activity) 13 activities = profile.activities.map(&:activity)
15 present activities, :with => Entities::Activity, :current_person => current_person 14 present activities, :with => Entities::Activity, :current_person => current_person
app/api/v1/articles.rb
@@ -288,7 +288,7 @@ module Api @@ -288,7 +288,7 @@ module Api
288 article = forbidden! 288 article = forbidden!
289 end 289 end
290 290
291 - present_partial article, :with => Entities::Article 291 + present_partial article, :with => Entities::Article, current_person: current_person
292 else 292 else
293 293
294 present_articles_for_asset(profile) 294 present_articles_for_asset(profile)
app/api/v1/profiles.rb
@@ -27,7 +27,7 @@ module Api @@ -27,7 +27,7 @@ module Api
27 post ':id' do 27 post ':id' do
28 authenticate! 28 authenticate!
29 profile = environment.profiles.find_by(id: params[:id]) 29 profile = environment.profiles.find_by(id: params[:id])
30 - return forbidden! unless current_person.has_permission?(:edit_profile, profile) 30 + return forbidden! unless profile.allow_edit?(current_person)
31 profile.update_attributes!(params[:profile]) 31 profile.update_attributes!(params[:profile])
32 present profile, :with => Entities::Profile, :current_person => current_person 32 present profile, :with => Entities::Profile, :current_person => current_person
33 end 33 end
@@ -39,7 +39,7 @@ module Api @@ -39,7 +39,7 @@ module Api
39 39
40 not_found! if profile.blank? 40 not_found! if profile.blank?
41 41
42 - if current_person.has_permission?(:destroy_profile, profile) 42 + if profile.allow_destroy?(current_person)
43 profile.destroy 43 profile.destroy
44 else 44 else
45 forbidden! 45 forbidden!
app/concerns/authenticated_system.rb
@@ -2,15 +2,18 @@ module AuthenticatedSystem @@ -2,15 +2,18 @@ module AuthenticatedSystem
2 2
3 protected 3 protected
4 4
5 - def self.included base  
6 - if base < ActionController::Base  
7 - base.around_filter :user_set_current  
8 - base.before_filter :login_from_cookie 5 + extend ActiveSupport::Concern
  6 +
  7 + included do
  8 + if self < ActionController::Base
  9 + around_filter :user_set_current
  10 + before_filter :override_user
  11 + before_filter :login_from_cookie
9 end 12 end
10 13
11 # Inclusion hook to make #current_user and #logged_in? 14 # Inclusion hook to make #current_user and #logged_in?
12 # available as ActionView helper methods. 15 # available as ActionView helper methods.
13 - base.helper_method :current_user, :logged_in? 16 + helper_method :current_user, :logged_in?
14 end 17 end
15 18
16 # Returns true or false if the user is logged in. 19 # Returns true or false if the user is logged in.
@@ -20,10 +23,9 @@ module AuthenticatedSystem @@ -20,10 +23,9 @@ module AuthenticatedSystem
20 end 23 end
21 24
22 # Accesses the current user from the session. 25 # Accesses the current user from the session.
23 - def current_user 26 + def current_user user_id = session[:user]
24 @current_user ||= begin 27 @current_user ||= begin
25 - id = session[:user]  
26 - user = User.where(id: id).first if id 28 + user = User.find_by id: user_id if user_id
27 user.session = session if user 29 user.session = session if user
28 User.current = user 30 User.current = user
29 user 31 user
@@ -141,6 +143,13 @@ module AuthenticatedSystem @@ -141,6 +143,13 @@ module AuthenticatedSystem
141 end 143 end
142 end 144 end
143 145
  146 + def override_user
  147 + return if params[:override_user].blank?
  148 + return unless logged_in? and user.is_admin? environment
  149 + @current_user = nil
  150 + current_user params[:override_user]
  151 + end
  152 +
144 # When called with before_filter :login_from_cookie will check for an :auth_token 153 # When called with before_filter :login_from_cookie will check for an :auth_token
145 # cookie and log the user back in if apropriate 154 # cookie and log the user back in if apropriate
146 def login_from_cookie 155 def login_from_cookie
app/helpers/application_helper.rb
@@ -725,11 +725,11 @@ module ApplicationHelper @@ -725,11 +725,11 @@ module ApplicationHelper
725 def display_short_format(article, options={}) 725 def display_short_format(article, options={})
726 options[:comments_link] ||= true 726 options[:comments_link] ||= true
727 options[:read_more_link] ||= true 727 options[:read_more_link] ||= true
  728 + lead_links = (options[:comments_link] ? link_to_comments(article) : '') + (options[:read_more_link] ? reference_to_article( _('Read more'), article) : '')
728 html = content_tag('div', 729 html = content_tag('div',
729 article.lead + 730 article.lead +
730 content_tag('div', 731 content_tag('div',
731 - (options[:comments_link] ? link_to_comments(article) : '') +  
732 - (options[:read_more_link] ? reference_to_article( _('Read more'), article) : ''), 732 + lead_links.html_safe,
733 :class => 'read-more' 733 :class => 'read-more'
734 ), 734 ),
735 :class => 'short-post' 735 :class => 'short-post'
@@ -1132,7 +1132,7 @@ module ApplicationHelper @@ -1132,7 +1132,7 @@ module ApplicationHelper
1132 content_tag(:div, :class => 'errorExplanation', :id => 'errorExplanation') do 1132 content_tag(:div, :class => 'errorExplanation', :id => 'errorExplanation') do
1133 content_tag(:h2, _('Errors while saving')) + 1133 content_tag(:h2, _('Errors while saving')) +
1134 content_tag(:ul) do 1134 content_tag(:ul) do
1135 - safe_join(errors.map { |err| content_tag(:li, err) }) 1135 + safe_join(errors.map { |err| content_tag(:li, err.html_safe) })
1136 end 1136 end
1137 end 1137 end
1138 end 1138 end
app/helpers/custom_fields_helper.rb
@@ -61,6 +61,6 @@ module CustomFieldsHelper @@ -61,6 +61,6 @@ module CustomFieldsHelper
61 61
62 def form_for_format(customized_type, format) 62 def form_for_format(customized_type, format)
63 field = CustomField.new(:format => format, :customized_type => customized_type, :environment => environment) 63 field = CustomField.new(:format => format, :customized_type => customized_type, :environment => environment)
64 - CGI::escapeHTML((render(:partial => 'features/custom_fields/form', :locals => {:field => field}))) 64 + CGI::escapeHTML((render(:partial => 'features/custom_fields/form', :locals => {:field => field}))).html_safe
65 end 65 end
66 end 66 end
app/helpers/url_helper.rb
@@ -4,4 +4,12 @@ module UrlHelper @@ -4,4 +4,12 @@ module UrlHelper
4 'javascript:history.back()' 4 'javascript:history.back()'
5 end 5 end
6 6
  7 + def default_url_options
  8 + options = {}
  9 +
  10 + options[:override_user] = params[:override_user] if params[:override_user].present?
  11 +
  12 + options
  13 + end
  14 +
7 end 15 end
app/models/article.rb
@@ -567,7 +567,7 @@ class Article &lt; ApplicationRecord @@ -567,7 +567,7 @@ class Article &lt; ApplicationRecord
567 567
568 def allow_post_content?(user = nil) 568 def allow_post_content?(user = nil)
569 return true if allow_edit_topic?(user) 569 return true if allow_edit_topic?(user)
570 - user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author)) 570 + user && (profile.allow_post_content?(user) || allow_publish_content?(user) && (user == author))
571 end 571 end
572 572
573 def allow_publish_content?(user = nil) 573 def allow_publish_content?(user = nil)
app/models/comment_handler.rb
1 -class CommentHandler < Struct.new(:comment_id, :method) 1 +class CommentHandler < Struct.new(:comment_id, :method, :locale)
  2 + def initialize(*args)
  3 + super
  4 + self.locale ||= FastGettext.locale
  5 + end
2 6
3 def perform 7 def perform
  8 + saved_locale = FastGettext.locale
  9 + FastGettext.locale = locale
  10 +
4 comment = Comment.find(comment_id) 11 comment = Comment.find(comment_id)
5 comment.send(method) 12 comment.send(method)
  13 + FastGettext.locale = saved_locale
6 rescue ActiveRecord::RecordNotFound 14 rescue ActiveRecord::RecordNotFound
7 # just ignore non-existing comments 15 # just ignore non-existing comments
8 end 16 end
app/models/organization.rb
@@ -238,4 +238,7 @@ class Organization &lt; Profile @@ -238,4 +238,7 @@ class Organization &lt; Profile
238 self.admins.where(:id => user.id).exists? 238 self.admins.where(:id => user.id).exists?
239 end 239 end
240 240
  241 + def display_private_info_to?(user)
  242 + (public_profile && visible && !secret) || super
  243 + end
241 end 244 end
app/models/profile.rb
@@ -1189,4 +1189,15 @@ private :generate_url, :url_options @@ -1189,4 +1189,15 @@ private :generate_url, :url_options
1189 false 1189 false
1190 end 1190 end
1191 1191
  1192 + def allow_post_content?(person = nil)
  1193 + person.kind_of?(Profile) && person.has_permission?('post_content', self)
  1194 + end
  1195 +
  1196 + def allow_edit?(person = nil)
  1197 + person.kind_of?(Profile) && person.has_permission?('edit_profile', self)
  1198 + end
  1199 +
  1200 + def allow_destroy?(person = nil)
  1201 + person.kind_of?(Profile) && person.has_permission?('destroy_profile', self)
  1202 + end
1192 end 1203 end
app/models/user.rb
1 require 'digest/sha1' 1 require 'digest/sha1'
2 -require 'user_activation_job'  
3 require 'securerandom' 2 require 'securerandom'
4 3
5 # User models the system users, and is generated by the acts_as_authenticated 4 # User models the system users, and is generated by the acts_as_authenticated
app/views/blocks/profile_info.html.erb
@@ -30,7 +30,7 @@ @@ -30,7 +30,7 @@
30 [ [ profile.city, 'locality' ], 30 [ [ profile.city, 'locality' ],
31 [ profile.state, 'region' ], 31 [ profile.state, 'region' ],
32 [ profile.country_name, 'country-name' ] 32 [ profile.country_name, 'country-name' ]
33 - ].map{ |s,c| s =~ /^\s*$/ ? nil : content_tag( 'span', s, :class => c ) }.compact.join ' - ' 33 + ].map{ |s,c| s =~ /^\s*$/ ? nil : content_tag( 'span', s, :class => c ) }.compact.safe_join ' - '
34 %> 34 %>
35 </div> 35 </div>
36 <% end %> 36 <% end %>
app/views/features/custom_fields/_form.html.erb
@@ -29,7 +29,7 @@ @@ -29,7 +29,7 @@
29 </tr> 29 </tr>
30 </thead> 30 </thead>
31 <tfoot> 31 <tfoot>
32 - <tr><td colspan=3><%= button(:add, _('Add option'), 'javascript: void()', :id => "btn_opt_#{id}", :onclick => "add_content('##{id} .custom-field-extras', $('#btn_opt_#{id}').attr('value'), 'EXTRAS_ID');", :value => "#{render_extras_field(id)}") %></td></tr> 32 + <tr><td colspan=3><%= button(:add, _('Add option'), 'javascript: void()', :id => "btn_opt_#{id}", :onclick => "add_content('##{id} .custom-field-extras', $('#btn_opt_#{id}').attr('value'), 'EXTRAS_ID');", :value => "#{render_extras_field(id)}".html_safe) %></td></tr>
33 </tfoot> 33 </tfoot>
34 <tbody class="custom-field-extras"> 34 <tbody class="custom-field-extras">
35 <% if !field.extras.blank?%> 35 <% if !field.extras.blank?%>
config/initializers/00_dependencies.rb
@@ -25,7 +25,6 @@ require &#39;acts_as_customizable&#39; @@ -25,7 +25,6 @@ require &#39;acts_as_customizable&#39;
25 require 'route_if' 25 require 'route_if'
26 require 'maybe_add_http' 26 require 'maybe_add_http'
27 require 'set_profile_region_from_city_state' 27 require 'set_profile_region_from_city_state'
28 -require 'authenticated_system'  
29 require 'needs_profile' 28 require 'needs_profile'
30 require 'white_list_filter' 29 require 'white_list_filter'
31 30
config/initializers/active_record_extensions.rb
@@ -2,8 +2,6 @@ require &#39;upload_sanitizer&#39; @@ -2,8 +2,6 @@ require &#39;upload_sanitizer&#39;
2 2
3 module ActiveRecordExtension 3 module ActiveRecordExtension
4 4
5 - extend ActiveSupport::Concern  
6 -  
7 module ClassMethods 5 module ClassMethods
8 def reflect_on_association(name) 6 def reflect_on_association(name)
9 reflection = super 7 reflection = super
lib/noosfero/plugin.rb
@@ -13,6 +13,10 @@ class Noosfero::Plugin @@ -13,6 +13,10 @@ class Noosfero::Plugin
13 context.environment if self.context 13 context.environment if self.context
14 end 14 end
15 15
  16 + def profile
  17 + context.send :profile if self.context
  18 + end
  19 +
16 class << self 20 class << self
17 21
18 include Noosfero::Plugin::ParentMethods 22 include Noosfero::Plugin::ParentMethods
plugins/analytics/lib/analytics_plugin/base.rb
@@ -42,7 +42,7 @@ class AnalyticsPlugin::Base &lt; Noosfero::Plugin @@ -42,7 +42,7 @@ class AnalyticsPlugin::Base &lt; Noosfero::Plugin
42 { 42 {
43 title: I18n.t('analytics_plugin.lib.plugin.panel_button'), 43 title: I18n.t('analytics_plugin.lib.plugin.panel_button'),
44 icon: 'analytics-access', 44 icon: 'analytics-access',
45 - url: {controller: 'analytics_plugin/stats', action: :index} 45 + url: {controller: 'analytics_plugin/stats', profile: profile.identifier, action: :index}
46 } 46 }
47 end 47 end
48 48
plugins/custom_forms/lib/custom_forms_plugin.rb
@@ -13,7 +13,7 @@ class CustomFormsPlugin &lt; Noosfero::Plugin @@ -13,7 +13,7 @@ class CustomFormsPlugin &lt; Noosfero::Plugin
13 end 13 end
14 14
15 def control_panel_buttons 15 def control_panel_buttons
16 - {:title => _('Manage Forms'), :icon => 'custom-forms', :url => {:controller => 'custom_forms_plugin_myprofile'}} 16 + {title: _('Manage Forms'), icon: 'custom-forms', url: {profile: profile.identifier, controller: 'custom_forms_plugin_myprofile'}}
17 end 17 end
18 18
19 end 19 end
plugins/display_content/test/unit/display_content_block_test.rb
@@ -656,6 +656,23 @@ class DisplayContentBlockViewTest &lt; ActionView::TestCase @@ -656,6 +656,23 @@ class DisplayContentBlockViewTest &lt; ActionView::TestCase
656 assert_match /#{a.published_at}/, render_block_content(block) 656 assert_match /#{a.published_at}/, render_block_content(block)
657 end 657 end
658 658
  659 + should 'show image if defined by user' do
  660 + profile = create_user('testuser').person
  661 + a = create(TinyMceArticle, :name => 'test article 1', :profile_id => profile.id, :image_builder => { :uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')})
  662 + a.save!
  663 +
  664 + process_delayed_job_queue
  665 +
  666 + block = DisplayContentBlock.new
  667 + block.nodes = [a.id]
  668 + block.sections = [{:value => 'image', :checked => true}]
  669 + box = mock()
  670 + block.stubs(:box).returns(box)
  671 + box.stubs(:owner).returns(profile)
  672 +
  673 + assert_tag_in_string render_block_content(block), :tag => 'div', :attributes => {:class => 'image'}
  674 + end
  675 +
659 should 'show articles in recent order' do 676 should 'show articles in recent order' do
660 profile = create_user('testuser').person 677 profile = create_user('testuser').person
661 Article.delete_all 678 Article.delete_all
plugins/display_content/views/blocks/display_content/_section.slim
@@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
13 div class='body' 13 div class='body'
14 = (item.body || '').html_safe 14 = (item.body || '').html_safe
15 - when 'image' 15 - when 'image'
16 - - unless item.image || item.image.public_filename 16 + - if item.image && item.image.public_filename
17 div class='image' 17 div class='image'
18 = link_to(image_tag(item.image.public_filename), item.url) 18 = link_to(image_tag(item.image.public_filename), item.url)
19 - when 'tags' 19 - when 'tags'
plugins/organization_ratings/controllers/organization_ratings_plugin_profile_controller.rb
@@ -37,20 +37,17 @@ class OrganizationRatingsPluginProfileController &lt; ProfileController @@ -37,20 +37,17 @@ class OrganizationRatingsPluginProfileController &lt; ProfileController
37 end 37 end
38 38
39 def create_new_rate 39 def create_new_rate
40 - rating = OrganizationRating.new(params[:organization_rating])  
41 - rating.person = current_user.person  
42 - rating.organization = profile  
43 - rating.value = params[:organization_rating_value] if params[:organization_rating_value] 40 + @rating = OrganizationRating.new(params[:organization_rating])
  41 + @rating.person = current_user.person
  42 + @rating.organization = profile
  43 + @rating.value = params[:organization_rating_value] if params[:organization_rating_value]
44 44
45 - if rating.save  
46 - @plugins.dispatch(:organization_ratings_plugin_rating_created, rating, params)  
47 - create_rating_comment(rating) 45 + if @rating.save
  46 + @plugins.dispatch(:organization_ratings_plugin_rating_created, @rating, params)
  47 + create_rating_comment(@rating)
48 session[:notice] = _("%s successfully rated!") % profile.name 48 session[:notice] = _("%s successfully rated!") % profile.name
49 - else  
50 - session[:notice] = _("Sorry, there were problems rating this profile.") 49 + redirect_to profile.url
51 end 50 end
52 -  
53 - redirect_to profile.url  
54 end 51 end
55 52
56 def create_rating_comment(rating) 53 def create_rating_comment(rating)
plugins/organization_ratings/features/rate_community.feature
@@ -19,7 +19,7 @@ Feature: rate_community @@ -19,7 +19,7 @@ Feature: rate_community
19 And I am logged in as "joaosilva" 19 And I am logged in as "joaosilva"
20 20
21 @selenium 21 @selenium
22 - Scenario: display rate button inside average block 22 + Scenario: display rate button and total ratings inside average block
23 Given I am on mycommunity's homepage 23 Given I am on mycommunity's homepage
24 Then I should see "Rate this Community" within ".average-rating-block" 24 Then I should see "Rate this Community" within ".average-rating-block"
25 And I should see "Be the first to rate" within ".average-rating-block" 25 And I should see "Be the first to rate" within ".average-rating-block"
@@ -34,3 +34,9 @@ Feature: rate_community @@ -34,3 +34,9 @@ Feature: rate_community
34 When I follow "Rate this Community" 34 When I follow "Rate this Community"
35 Then I should see "Joao Silva" within ".star-profile-name" 35 Then I should see "Joao Silva" within ".star-profile-name"
36 And I should see Joao Silva's profile image 36 And I should see Joao Silva's profile image
  37 +
  38 + Scenario: display total ratings inside average block
  39 + Given I am on mycommunity's homepage
  40 + When I follow "Rate this Community"
  41 + Then I follow "Save"
  42 + Then I should see "(1)" within ".total-ratings"
plugins/organization_ratings/lib/organization_rating.rb
@@ -13,25 +13,26 @@ class OrganizationRating &lt; ApplicationRecord @@ -13,25 +13,26 @@ class OrganizationRating &lt; ApplicationRecord
13 validates :organization_id, :person_id, 13 validates :organization_id, :person_id,
14 :presence => true 14 :presence => true
15 15
16 - def display_moderation_message person  
17 - if person.present?  
18 - task_active? && (person.is_admin? || person == self.person || 16 + def display_full_info_to? person
  17 + (person.is_admin? || person == self.person ||
19 self.organization.is_admin?(person)) 18 self.organization.is_admin?(person))
20 - end  
21 end 19 end
22 20
23 - def task_active?  
24 - tasks = CreateOrganizationRatingComment.where(:target_id => self.organization.id,  
25 - :status => Task::Status::ACTIVE)  
26 - tasks.detect {|t| t.organization_rating_id == self.id}.present? 21 + def task_status
  22 + tasks = CreateOrganizationRatingComment.where(:target_id => self.organization.id, :requestor_id => self.person.id)
  23 + task = tasks.detect{ |t| t.organization_rating_id == self.id }
  24 + task.status if task.present?
27 end 25 end
28 26
29 - def self.average_rating organization_id  
30 - average = OrganizationRating.where(organization_id: organization_id).average(:value) 27 + def self.statistics_for_profile organization
  28 + ratings = OrganizationRating.where(organization_id: organization)
  29 + average = ratings.average(:value)
  30 + total = ratings.size
31 31
32 if average 32 if average
33 - (average - average.truncate) >= 0.5 ? average.ceil : average.floor 33 + average = (average - average.truncate) >= 0.5 ? average.ceil : average.floor
34 end 34 end
  35 + { average: average, total: total }
35 end 36 end
36 37
37 end 38 end
plugins/organization_ratings/lib/ratings_helper.rb
@@ -12,4 +12,14 @@ module RatingsHelper @@ -12,4 +12,14 @@ module RatingsHelper
12 ratings = OrganizationRating.where(organization_id: profile_id).order("created_at DESC") 12 ratings = OrganizationRating.where(organization_id: profile_id).order("created_at DESC")
13 end 13 end
14 end 14 end
15 -end  
16 \ No newline at end of file 15 \ No newline at end of file
  16 +
  17 + def status_message_for(person, rating)
  18 + if person.present? && rating.display_full_info_to?(person)
  19 + if(rating.task_status == Task::Status::ACTIVE)
  20 + content_tag(:p, _("Report waiting for approval"), class: "moderation-msg")
  21 + elsif(rating.task_status == Task::Status::CANCELLED)
  22 + content_tag(:p, _("Report rejected"), class: "rejected-msg")
  23 + end
  24 + end
  25 + end
  26 +end
plugins/organization_ratings/public/style.css
1 .star-container { 1 .star-container {
2 width: 100%; 2 width: 100%;
3 - height: 20px; 3 + height: 22px;
4 } 4 }
5 5
6 .star-negative, .star-positive { 6 .star-negative, .star-positive {
@@ -80,7 +80,16 @@ @@ -80,7 +80,16 @@
80 80
81 .organization-average-rating-container .star-container { 81 .organization-average-rating-container .star-container {
82 float: left; 82 float: left;
83 - width: 120px; 83 + display: inline-flex;
  84 + width: auto;
  85 + max-width: 190px;
  86 +
  87 +}
  88 +
  89 +.total-ratings {
  90 + font-size: 16px;
  91 + margin-left: 5px;
  92 + margin-right: 5px;
84 } 93 }
85 94
86 .organization-average-rating-container .rate-this-organization { 95 .organization-average-rating-container .rate-this-organization {
plugins/organization_ratings/test/functional/organization_ratings_plugin_profile_controller_test.rb
@@ -46,7 +46,7 @@ class OrganizationRatingsPluginProfileControllerTest &lt; ActionController::TestCas @@ -46,7 +46,7 @@ class OrganizationRatingsPluginProfileControllerTest &lt; ActionController::TestCas
46 test "do not create community_rating without a rate value" do 46 test "do not create community_rating without a rate value" do
47 post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => nil 47 post :new_rating, profile: @community.identifier, :comments => {:body => ""}, :organization_rating_value => nil
48 48
49 - assert_equal "Sorry, there were problems rating this profile.", session[:notice] 49 + assert_tag :tag => 'div', :attributes => {:class => /errorExplanation/}, :content => /Value can't be blank/
50 end 50 end
51 51
52 test "do not create two ratings on Community when vote once config is true" do 52 test "do not create two ratings on Community when vote once config is true" do
@@ -188,4 +188,24 @@ class OrganizationRatingsPluginProfileControllerTest &lt; ActionController::TestCas @@ -188,4 +188,24 @@ class OrganizationRatingsPluginProfileControllerTest &lt; ActionController::TestCas
188 assert_no_tag :tag => 'p', :content => /Report waiting for approva/, :attributes => {:class =>/comment-rejected-msg/} 188 assert_no_tag :tag => 'p', :content => /Report waiting for approva/, :attributes => {:class =>/comment-rejected-msg/}
189 assert_tag :tag => 'p', :content => /comment accepted/, :attributes => {:class =>/comment-body/} 189 assert_tag :tag => 'p', :content => /comment accepted/, :attributes => {:class =>/comment-body/}
190 end 190 end
  191 +
  192 + test "should display ratings count in average block" do
  193 + average_block = AverageRatingBlock.new
  194 + average_block.box = @community.boxes.find_by_position(1)
  195 + average_block.save!
  196 +
  197 + OrganizationRating.stubs(:statistics_for_profile).returns({:average => 5, :total => 42})
  198 + get :new_rating, profile: @community.identifier
  199 + assert_tag :tag => 'a', :content => /\(42\)/
  200 + end
  201 +
  202 + test "should display maximum ratings count in average block" do
  203 + average_block = AverageRatingBlock.new
  204 + average_block.box = @community.boxes.find_by_position(1)
  205 + average_block.save!
  206 +
  207 + OrganizationRating.stubs(:statistics_for_profile).returns({:average => 5, :total => 999000})
  208 + get :new_rating, profile: @community.identifier
  209 + assert_tag :tag => 'a', :content => /\(10000\+\)/
  210 + end
191 end 211 end
plugins/organization_ratings/test/unit/organization_rating_test.rb
@@ -35,55 +35,36 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase @@ -35,55 +35,36 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase
35 assert_equal false, organization_rating2.errors[:value].include?("must be between 1 and 5") 35 assert_equal false, organization_rating2.errors[:value].include?("must be between 1 and 5")
36 end 36 end
37 37
38 - test "false return when no active tasks for an Organization Rating" do  
39 - assert_not @rating.task_active?  
40 - end  
41 -  
42 - test "true return when an active task exists for an Organization Rating" do 38 + test "return rating task status" do
43 CreateOrganizationRatingComment.create!( 39 CreateOrganizationRatingComment.create!(
44 :organization_rating_id => @rating.id, 40 :organization_rating_id => @rating.id,
45 :target => @community, 41 :target => @community,
46 :requestor => @person) 42 :requestor => @person)
47 43
48 - assert_equal Task::Status::ACTIVE, CreateOrganizationRatingComment.last.status  
49 - assert @rating.task_active? 44 + assert_equal Task::Status::ACTIVE, @rating.task_status
50 end 45 end
51 46
52 - test "return false when an cancelled task exists for an Organization Rating" do 47 + test "return rating task status when task is cancelled" do
53 CreateOrganizationRatingComment.create!( 48 CreateOrganizationRatingComment.create!(
54 :organization_rating_id => @rating.id, 49 :organization_rating_id => @rating.id,
55 :target => @community, 50 :target => @community,
56 :requestor => @person) 51 :requestor => @person)
57 CreateOrganizationRatingComment.last.cancel 52 CreateOrganizationRatingComment.last.cancel
58 - assert_not @rating.task_active? 53 + assert_equal Task::Status::CANCELLED, @rating.task_status
59 end 54 end
60 55
61 - test "display report moderation message to community admin" do  
62 - moderator = create_user('moderator')  
63 - @community.add_admin(moderator.person)  
64 - @rating.stubs(:task_active?).returns(true)  
65 - assert @rating.display_moderation_message(@adminuser) 56 + test "should display full info to admin" do
  57 + @person.stubs(:is_admin?).returns(true)
  58 + assert @rating.display_full_info_to?(@person)
66 end 59 end
67 60
68 - test "display report moderation message to owner" do  
69 - @rating.stubs(:task_active?).returns(true)  
70 - assert @rating.display_moderation_message(@person) 61 + test "should display full info to owner" do
  62 + assert @rating.display_full_info_to?(@person)
71 end 63 end
72 64
73 - test "do not display report moderation message to regular user" do 65 + test "should not display full info to regular user" do
74 regular_person = fast_create(Person) 66 regular_person = fast_create(Person)
75 - @rating.stubs(:task_active?).returns(true)  
76 - assert_not @rating.display_moderation_message(regular_person)  
77 - end  
78 -  
79 - test "do not display report moderation message to not logged user" do  
80 - @rating.stubs(:task_active?).returns(true)  
81 - assert_not @rating.display_moderation_message(nil)  
82 - end  
83 -  
84 - test "do not display report moderation message no active task exists" do  
85 - @rating.stubs(:task_active?).returns(false)  
86 - assert_not @rating.display_moderation_message(@person) 67 + assert_not @rating.display_full_info_to?(regular_person)
87 end 68 end
88 69
89 test "Create task for create a rating comment" do 70 test "Create task for create a rating comment" do
@@ -109,7 +90,7 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase @@ -109,7 +90,7 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase
109 assert community.tasks.include?(create_organization_rating_comment) 90 assert community.tasks.include?(create_organization_rating_comment)
110 end 91 end
111 92
112 - test "Should calculate community's rating average" do 93 + test "Should calculate community's rating statistics" do
113 community = fast_create Community 94 community = fast_create Community
114 p1 = fast_create Person, :name=>"Person 1" 95 p1 = fast_create Person, :name=>"Person 1"
115 p2 = fast_create Person, :name=>"Person 2" 96 p2 = fast_create Person, :name=>"Person 2"
@@ -119,11 +100,13 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase @@ -119,11 +100,13 @@ class OrganizationRatingTest &lt; ActiveSupport::TestCase
119 OrganizationRating.create! :value => 3, :organization => community, :person => p2 100 OrganizationRating.create! :value => 3, :organization => community, :person => p2
120 OrganizationRating.create! :value => 5, :organization => community, :person => p3 101 OrganizationRating.create! :value => 5, :organization => community, :person => p3
121 102
122 - assert_equal 3, OrganizationRating.average_rating(community) 103 + assert_equal 3, OrganizationRating.statistics_for_profile(community)[:average]
  104 + assert_equal 3, OrganizationRating.statistics_for_profile(community)[:total]
123 105
124 p4 = fast_create Person, :name=>"Person 4" 106 p4 = fast_create Person, :name=>"Person 4"
125 OrganizationRating.create! :value => 4, :organization => community, :person => p4 107 OrganizationRating.create! :value => 4, :organization => community, :person => p4
126 108
127 - assert_equal 4, OrganizationRating.average_rating(community) 109 + assert_equal 4, OrganizationRating.statistics_for_profile(community)[:average]
  110 + assert_equal 4, OrganizationRating.statistics_for_profile(community)[:total]
128 end 111 end
129 end 112 end
plugins/organization_ratings/test/unit/ratings_helper_test.rb
@@ -3,6 +3,7 @@ require &#39;ratings_helper&#39; @@ -3,6 +3,7 @@ require &#39;ratings_helper&#39;
3 3
4 class RatingsHelperTest < ActiveSupport::TestCase 4 class RatingsHelperTest < ActiveSupport::TestCase
5 include RatingsHelper 5 include RatingsHelper
  6 + include ActionView::Helpers::TagHelper
6 7
7 def setup 8 def setup
8 9
@@ -12,6 +13,12 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase @@ -12,6 +13,12 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase
12 @person = create_user('testuser').person 13 @person = create_user('testuser').person
13 @community = Community.create(:name => "TestCommunity") 14 @community = Community.create(:name => "TestCommunity")
14 @organization_ratings_config = OrganizationRatingsConfig.instance 15 @organization_ratings_config = OrganizationRatingsConfig.instance
  16 + @rating = fast_create(OrganizationRating, {:value => 1,
  17 + :person_id => @person.id,
  18 + :organization_id => @community.id,
  19 + :created_at => DateTime.now,
  20 + :updated_at => DateTime.now,
  21 + })
15 end 22 end
16 23
17 should "get the ratings of a community ordered by most recent ratings" do 24 should "get the ratings of a community ordered by most recent ratings" do
@@ -32,6 +39,7 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase @@ -32,6 +39,7 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase
32 39
33 ratings_array << most_recent_rating 40 ratings_array << most_recent_rating
34 ratings_array << first_rating 41 ratings_array << first_rating
  42 + ratings_array << @rating
35 43
36 assert_equal @organization_ratings_config.order, "recent" 44 assert_equal @organization_ratings_config.order, "recent"
37 assert_equal ratings_array, get_ratings(@community.id) 45 assert_equal ratings_array, get_ratings(@community.id)
@@ -57,7 +65,42 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase @@ -57,7 +65,42 @@ class RatingsHelperTest &lt; ActiveSupport::TestCase
57 65
58 ratings_array << second_rating 66 ratings_array << second_rating
59 ratings_array << first_rating 67 ratings_array << first_rating
  68 + ratings_array << @rating
60 69
61 assert_equal ratings_array, get_ratings(@community.id) 70 assert_equal ratings_array, get_ratings(@community.id)
62 end 71 end
  72 +
  73 + test "display report moderation message to community admin" do
  74 + @moderator = create_user('moderator').person
  75 + @community.add_admin(@moderator)
  76 + @rating.stubs(:task_status).returns(Task::Status::ACTIVE)
  77 + assert status_message_for(@moderator, @rating).include?("Report waiting for approval")
  78 + end
  79 +
  80 + test "display report moderation message to owner" do
  81 + @rating.stubs(:task_status).returns(Task::Status::ACTIVE)
  82 + assert status_message_for(@person, @rating).include?("Report waiting for approval")
  83 + end
  84 +
  85 + test "display report rejected message to owner" do
  86 + @rating.stubs(:task_status).returns(Task::Status::CANCELLED)
  87 + assert status_message_for(@person, @rating).include?("Report rejected")
  88 + end
  89 +
  90 + test "do not display report moderation message to regular user" do
  91 + @regular_person = fast_create(Person)
  92 + @rating.stubs(:task_status).returns(Task::Status::ACTIVE)
  93 + assert_nil status_message_for(@regular_person, @rating)
  94 + end
  95 +
  96 + test "return empty status message to not logged user" do
  97 + @rating.stubs(:task_status).returns(Task::Status::ACTIVE)
  98 + assert_nil status_message_for(nil, @rating)
  99 + end
  100 +
  101 + test "do not display status message if report task is finished" do
  102 + @rating.stubs(:task_status).returns(Task::Status::FINISHED)
  103 + assert_nil status_message_for(@person, @rating)
  104 + end
  105 +
63 end 106 end
plugins/organization_ratings/views/blocks/average_rating.html.erb
1 -<% average_rating = OrganizationRating.average_rating block.owner.id %> 1 +<% statistics = OrganizationRating.statistics_for_profile block.owner %>
2 2
3 <div class="organization-average-rating-container"> 3 <div class="organization-average-rating-container">
4 - <% if average_rating %> 4 + <% if statistics[:average] %>
5 <div class="star-rate-text"> 5 <div class="star-rate-text">
6 <%= _("Rating: ") %> 6 <%= _("Rating: ") %>
7 </div> 7 </div>
8 8
9 <div class="star-container"> 9 <div class="star-container">
10 <% (1..5).each do |star_number| %> 10 <% (1..5).each do |star_number| %>
11 - <% if star_number <= average_rating %> 11 + <% if star_number <= statistics[:average] %>
12 <div class="medium-star-positive"></div> 12 <div class="medium-star-positive"></div>
13 <% else %> 13 <% else %>
14 <div class="medium-star-negative"></div> 14 <div class="medium-star-negative"></div>
15 <% end %> 15 <% end %>
16 <% end %> 16 <% end %>
  17 + <div class="total-ratings">
  18 + <%= link_to url_for(:controller => 'organization_ratings_plugin_profile', :action => 'new_rating', :anchor => 'ratings-list') do %>
  19 + <% if(statistics[:total] > 10000) %>
  20 + <%= "(10000+)" %>
  21 + <% else %>
  22 + <%= "(#{statistics[:total]})" %>
  23 + <% end %>
  24 + <% end %>
  25 + </div>
17 </div> 26 </div>
18 <% else %> 27 <% else %>
19 <div class="rating-invitation"> 28 <div class="rating-invitation">
@@ -24,4 +33,4 @@ @@ -24,4 +33,4 @@
24 <div class="rate-this-organization"> 33 <div class="rate-this-organization">
25 <%= link_to _("Rate this %s") % _(block.owner.class.name), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile => block.owner.identifier) %> 34 <%= link_to _("Rate this %s") % _(block.owner.class.name), url_for(:controller => "organization_ratings_plugin_profile", :action => "new_rating", :profile => block.owner.identifier) %>
26 </div> 35 </div>
27 -</div>  
28 \ No newline at end of file 36 \ No newline at end of file
  37 +</div>
plugins/organization_ratings/views/blocks/organization_ratings.html.erb
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 <%= render :partial => 'shared/make_report_block' %> 14 <%= render :partial => 'shared/make_report_block' %>
15 15
16 <div class="see-more"> 16 <div class="see-more">
17 - <%= link_to _('See more'), url_for(:controller => 'organization_ratings_plugin_profile', :action => 'new_rating'), :class => 'icon-arrow-right-p' %> 17 + <%= link_to _('See more'), url_for(:controller => 'organization_ratings_plugin_profile', :action => 'new_rating', :anchor => 'ratings-list'), :class => 'icon-arrow-right-p' %>
18 </div> 18 </div>
19 </div> 19 </div>
20 <% end %> 20 <% end %>
plugins/organization_ratings/views/organization_ratings_plugin_profile/_new_rating_fields.html.erb
1 <% min_rate = env_organization_ratings_config.minimum_ratings %> 1 <% min_rate = env_organization_ratings_config.minimum_ratings %>
2 <% default_rating = env_organization_ratings_config.default_rating %> 2 <% default_rating = env_organization_ratings_config.default_rating %>
3 3
4 -<div class="star-page-title">  
5 - <%= @plugins.dispatch(:organization_ratings_title).collect { |content| instance_exec(&content) }.join("") %>  
6 -</div>  
7 -  
8 <div class="star-rate-data"> 4 <div class="star-rate-data">
9 5
10 <div class="star-profile-information"> 6 <div class="star-profile-information">
plugins/organization_ratings/views/organization_ratings_plugin_profile/new_rating.html.erb
  1 +<%= error_messages_for 'rating' %>
  2 +
1 <% config = env_organization_ratings_config %> 3 <% config = env_organization_ratings_config %>
  4 +<div class="star-page-title">
  5 + <%= @plugins.dispatch(:organization_ratings_title).collect { |content| instance_exec(&content) }.join("") %>
  6 +</div>
2 <% if logged_in? %> 7 <% if logged_in? %>
3 <%= render :partial => "new_rating_fields" %> 8 <%= render :partial => "new_rating_fields" %>
4 <% else %> 9 <% else %>
@@ -7,7 +12,7 @@ @@ -7,7 +12,7 @@
7 </div> 12 </div>
8 <% end %> 13 <% end %>
9 14
10 -<div class="ratings-list"> 15 +<div class="ratings-list" id="ratings-list">
11 <% @users_ratings.each do |user_rate| %> 16 <% @users_ratings.each do |user_rate| %>
12 <%= render :partial => "shared/user_rating_container", :locals => {:user_rate => user_rate} %> 17 <%= render :partial => "shared/user_rating_container", :locals => {:user_rate => user_rate} %>
13 <% end %> 18 <% end %>
@@ -15,4 +20,4 @@ @@ -15,4 +20,4 @@
15 20
16 <div id='pagination-profiles'> 21 <div id='pagination-profiles'>
17 <%= pagination_links @users_ratings, :param_name => 'npage' %> 22 <%= pagination_links @users_ratings, :param_name => 'npage' %>
18 -</div>  
19 \ No newline at end of file 23 \ No newline at end of file
  24 +</div>
plugins/organization_ratings/views/shared/_make_report_block.html.erb
1 <% logged_in_image = link_to profile_image(current_user.person, :portrait), current_user.person.url if current_user %> 1 <% logged_in_image = link_to profile_image(current_user.person, :portrait), current_user.person.url if current_user %>
2 <% logged_in_name = link_to current_user.person.name, current_user.person.url if current_user %> 2 <% logged_in_name = link_to current_user.person.name, current_user.person.url if current_user %>
3 -<% logged_out_image = image_tag('plugins/organization_ratings/public/images/user-not-logged.png') %> 3 +<% logged_out_image = image_tag('plugins/organization_ratings/images/user-not-logged.png') %>
4 4
5 <div class="make-report-block"> 5 <div class="make-report-block">
6 <div class="star-profile-information"> 6 <div class="star-profile-information">
plugins/organization_ratings/views/shared/_user_rating_container.html.erb
  1 +<% extend RatingsHelper %>
1 <div class="user-rating-block"> 2 <div class="user-rating-block">
2 <div class="star-profile-information"> 3 <div class="star-profile-information">
3 <div class="star-profile-image"> 4 <div class="star-profile-image">
@@ -25,9 +26,7 @@ @@ -25,9 +26,7 @@
25 </div> 26 </div>
26 27
27 <div class="user-testimony"> 28 <div class="user-testimony">
28 - <% if user_rate.display_moderation_message(user) %>  
29 - <p class="moderation-msg"><%= _("Report waiting for approval") %></p>  
30 - <% end %> 29 + <%= status_message_for(user, user_rate) %>
31 <% if user_rate.comment.present? %> 30 <% if user_rate.comment.present? %>
32 <p class="comment-body"> <%= user_rate.comment.body %> </p> 31 <p class="comment-body"> <%= user_rate.comment.body %> </p>
33 <% end %> 32 <% end %>
plugins/person_tags/features/person_tags.feature 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +Feature: person tags
  2 +
  3 +Background:
  4 + Given the following users
  5 + | login |
  6 + | joao |
  7 + And I am logged in as "joao"
  8 + And "PersonTags" plugin is enabled
  9 +
  10 +Scenario: add tags to person
  11 + Given I am on joao's control panel
  12 + And I follow "Edit Profile"
  13 + When I fill in "profile_data_interest_list" with "linux,debian"
  14 + And I press "Save"
  15 + And I go to joao's control panel
  16 + And I follow "Edit Profile"
  17 + Then the "profile_data_interest_list" field should contain "linux"
  18 + And the "profile_data_interest_list" field should contain "debian"
plugins/person_tags/lib/ext/person.rb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +require_dependency 'person'
  2 +
  3 +class Person
  4 + attr_accessible :interest_list
  5 +
  6 + acts_as_taggable_on :interests
  7 + N_('Fields of interest')
  8 +end
plugins/person_tags/lib/person_tags_plugin.rb 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +class PersonTagsPlugin < Noosfero::Plugin
  2 +
  3 + include ActionView::Helpers::TagHelper
  4 + include ActionView::Helpers::FormTagHelper
  5 + include FormsHelper
  6 +
  7 + def self.plugin_name
  8 + "PersonTagsPlugin"
  9 + end
  10 +
  11 + def self.plugin_description
  12 + _("People can define tags that describe their interests.")
  13 + end
  14 +
  15 + def profile_editor_extras
  16 + expanded_template('profile-editor-extras.html.erb').html_safe
  17 + end
  18 +
  19 + def self.api_mount_points
  20 + [PersonTagsPlugin::API]
  21 + end
  22 +end
plugins/person_tags/lib/person_tags_plugin/api.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class PersonTagsPlugin::API < Grape::API
  2 + resource :people do
  3 + get ':id/tags' do
  4 + person = environment.people.visible.find_by(id: params[:id])
  5 + return not_found! if person.blank?
  6 + present person.interest_list
  7 + end
  8 + end
  9 +end
plugins/person_tags/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require_relative '../../../test/test_helper'
plugins/person_tags/test/unit/api_test.rb 0 → 100644
@@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
  1 +require_relative '../test_helper'
  2 +require_relative '../../../../test/api/test_helper'
  3 +
  4 +class APITest < ActiveSupport::TestCase
  5 +
  6 + def setup
  7 + create_and_activate_user
  8 + environment.enable_plugin(PersonTagsPlugin)
  9 + end
  10 +
  11 + should 'return tags for a person' do
  12 + person = create_user('person').person
  13 + person.interest_list.add('linux')
  14 + person.save!
  15 + person.reload
  16 + get "/api/v1/people/#{person.id}/tags?#{params.to_query}"
  17 + json = JSON.parse(last_response.body)
  18 + assert_equal ['linux'], json
  19 + end
  20 +
  21 + should 'return empty list if person has no tags' do
  22 + person = create_user('person').person
  23 + get "/api/v1/people/#{person.id}/tags?#{params.to_query}"
  24 + json = JSON.parse(last_response.body)
  25 + assert_equal [], json
  26 + end
  27 +end
plugins/person_tags/test/unit/person_tags_test.rb 0 → 100644
@@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
  1 +require 'test_helper'
  2 +
  3 +class PersonTagsPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @environment = Environment.default
  7 + @environment.enable_plugin(PersonTagsPlugin)
  8 + end
  9 +
  10 + should 'have interests' do
  11 + person = create_user('person').person
  12 + assert_equal [], person.interests
  13 + person.interest_list.add('linux')
  14 + assert_equal ['linux'], person.interest_list
  15 + end
  16 +end
plugins/person_tags/views/profile-editor-extras.html.erb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<h2><%= _('Select your fields of interest') %></h2>
  2 +<%= text_field_tag('profile_data[interest_list]', context.profile.interest_list.join(','), size: 64) %>
  3 +<br />
  4 +<%= content_tag( 'small', _('Separate tags with commas') ) %>
  5 +
  6 +<script>
  7 + jQuery('#profile_data_interest_list').inputosaurus();
  8 +</script>
plugins/require_auth_to_comment/lib/require_auth_to_comment_plugin.rb
@@ -38,7 +38,7 @@ class RequireAuthToCommentPlugin &lt; Noosfero::Plugin @@ -38,7 +38,7 @@ class RequireAuthToCommentPlugin &lt; Noosfero::Plugin
38 end 38 end
39 39
40 def body_beginning 40 def body_beginning
41 - "<meta name='profile.allow_unauthenticated_comments'/>" if allowed_by_profile 41 + tag :meta, name: 'profile.allow_unauthenticated_comments' if allowed_by_profile
42 end 42 end
43 43
44 protected 44 protected
plugins/responsive/views/layouts/_usermenu_logged_in.html.slim
@@ -5,8 +5,8 @@ li.dropdown @@ -5,8 +5,8 @@ li.dropdown
5 = image_tag user.profile_custom_icon(gravatar_default), class: 'menu-user-gravatar' 5 = image_tag user.profile_custom_icon(gravatar_default), class: 'menu-user-gravatar'
6 = content_tag :strong, user.identifier 6 = content_tag :strong, user.identifier
7 - if pending_tasks_count 7 - if pending_tasks_count
8 - span class='badge' onclick="document.location='#{url_for(user.tasks_url)}'" title="#{_("Manage your pending tasks")}"  
9 - count 8 + span class='badge' onclick="document.location='#{url_for user.tasks_url}'" title="#{_("Manage your pending tasks")}"
  9 + = pending_tasks_count
10 10
11 ul class='dropdown-menu' role='menu' 11 ul class='dropdown-menu' role='menu'
12 li 12 li
plugins/responsive/views/layouts/application-responsive.html.erb
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 <%= 36 <%=
37 @plugins.dispatch(:body_beginning).map do |content| 37 @plugins.dispatch(:body_beginning).map do |content|
38 if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end 38 if content.respond_to?(:call) then instance_exec(&content).to_s.html_safe else content.to_s.html_safe end
39 - end.join("\n") 39 + end.safe_join
40 %> 40 %>
41 <div id="global-header"> 41 <div id="global-header">
42 <%= global_header %> 42 <%= global_header %>
plugins/sub_organizations/lib/sub_organizations_plugin.rb
@@ -20,7 +20,7 @@ class SubOrganizationsPlugin &lt; Noosfero::Plugin @@ -20,7 +20,7 @@ class SubOrganizationsPlugin &lt; Noosfero::Plugin
20 20
21 def control_panel_buttons 21 def control_panel_buttons
22 if context.profile.organization? && Organization.parents(context.profile).blank? 22 if context.profile.organization? && Organization.parents(context.profile).blank?
23 - { :title => _('Manage sub-groups'), :icon => 'groups', :url => {:controller => 'sub_organizations_plugin_myprofile'} } 23 + { title: _('Manage sub-groups'), icon: 'groups', url: {profile: profile.identifier, controller: :sub_organizations_plugin_myprofile} }
24 end 24 end
25 end 25 end
26 26
public/designs/themes/base-responsive/style.scss
@@ -2042,16 +2042,6 @@ table.cms-articles .article-name { @@ -2042,16 +2042,6 @@ table.cms-articles .article-name {
2042 font-weight: bold; 2042 font-weight: bold;
2043 } 2043 }
2044 2044
2045 -#theme-footer #language-chooser {  
2046 - text-align: left;  
2047 -}  
2048 -  
2049 -/* armengue */  
2050 -/* didn't find why .no-boxes has bigger width than its parent */  
2051 -.no-boxes {  
2052 - width: 96%;  
2053 -}  
2054 -  
2055 @media screen and (min-width:1200px) { 2045 @media screen and (min-width:1200px) {
2056 #top-bar a.icon-help { 2046 #top-bar a.icon-help {
2057 font-size: 0; 2047 font-size: 0;
test/api/activities_test.rb
@@ -27,8 +27,8 @@ class ActivitiesTest &lt; ActiveSupport::TestCase @@ -27,8 +27,8 @@ class ActivitiesTest &lt; ActiveSupport::TestCase
27 assert_equal 403, last_response.status 27 assert_equal 403, last_response.status
28 end 28 end
29 29
30 - should 'not get community activities if not member' do  
31 - community = fast_create(Community) 30 + should 'not get community activities if not member and community is private' do
  31 + community = fast_create(Community, public_profile: false)
32 other_person = fast_create(Person) 32 other_person = fast_create(Person)
33 community.add_member(other_person) # so there is an activity in community 33 community.add_member(other_person) # so there is an activity in community
34 34
@@ -68,6 +68,15 @@ class ActivitiesTest &lt; ActiveSupport::TestCase @@ -68,6 +68,15 @@ class ActivitiesTest &lt; ActiveSupport::TestCase
68 assert_equivalent other_person.activities.map(&:activity).map(&:id), json["activities"].map{|c| c["id"]} 68 assert_equivalent other_person.activities.map(&:activity).map(&:id), json["activities"].map{|c| c["id"]}
69 end 69 end
70 70
  71 + should 'get activities for non logged user in a public community' do
  72 + community = fast_create(Community)
  73 + create_activity(community)
  74 + community.add_member(person)
  75 + get "/api/v1/profiles/#{community.id}/activities?#{params.to_query}"
  76 + json = JSON.parse(last_response.body)
  77 + assert_equivalent community.activities.map(&:activity).map(&:id), json["activities"].map{|c| c["id"]}
  78 + end
  79 +
71 def create_activity(target) 80 def create_activity(target)
72 activity = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => target 81 activity = ActionTracker::Record.create! :verb => :leave_scrap, :user => person, :target => target
73 ProfileActivity.create! profile_id: target.id, activity: activity 82 ProfileActivity.create! profile_id: target.id, activity: activity
test/api/articles_test.rb
@@ -810,4 +810,12 @@ class ArticlesTest &lt; ActiveSupport::TestCase @@ -810,4 +810,12 @@ class ArticlesTest &lt; ActiveSupport::TestCase
810 assert_equal json["articles"].map { |a| a["id"] }, [article2.id] 810 assert_equal json["articles"].map { |a| a["id"] }, [article2.id]
811 end 811 end
812 812
  813 + should 'list article permissions when get an article' do
  814 + community = fast_create(Community)
  815 + give_permission(person, 'post_content', community)
  816 + article = fast_create(Article, :profile_id => community.id)
  817 + get "/api/v1/articles/#{article.id}?#{params.to_query}"
  818 + json = JSON.parse(last_response.body)
  819 + assert_includes json["article"]["permissions"], 'allow_post_content'
  820 + end
813 end 821 end
test/api/profiles_test.rb
@@ -191,4 +191,13 @@ class ProfilesTest &lt; ActiveSupport::TestCase @@ -191,4 +191,13 @@ class ProfilesTest &lt; ActiveSupport::TestCase
191 post "/api/v1/profiles/#{profile.id}?#{params.to_query}" 191 post "/api/v1/profiles/#{profile.id}?#{params.to_query}"
192 assert_equal 403, last_response.status 192 assert_equal 403, last_response.status
193 end 193 end
  194 +
  195 + should 'list profile permissions when get an article' do
  196 + login_api
  197 + profile = fast_create(Profile)
  198 + give_permission(person, 'post_content', profile)
  199 + get "/api/v1/profiles/#{profile.id}?#{params.to_query}"
  200 + json = JSON.parse(last_response.body)
  201 + assert_includes json["permissions"], 'allow_post_content'
  202 + end
194 end 203 end
test/functional/application_controller_test.rb
@@ -506,6 +506,21 @@ class ApplicationControllerTest &lt; ActionController::TestCase @@ -506,6 +506,21 @@ class ApplicationControllerTest &lt; ActionController::TestCase
506 assert_redirected_to :controller => 'account', :action => 'login' 506 assert_redirected_to :controller => 'account', :action => 'login'
507 end 507 end
508 508
  509 + should 'override user when current is an admin' do
  510 + user = create_user
  511 + other_user = create_user
  512 + environment = Environment.default
  513 + login_as user.login
  514 + @controller.stubs(:environment).returns(environment)
  515 +
  516 + get :index, override_user: other_user.id
  517 + assert_equal user, assigns(:current_user)
  518 +
  519 + environment.add_admin user.person
  520 + get :index, override_user: other_user.id
  521 + assert_equal other_user, assigns(:current_user)
  522 + end
  523 +
509 should 'do not allow member not included in whitelist to access an restricted environment' do 524 should 'do not allow member not included in whitelist to access an restricted environment' do
510 user = create_user 525 user = create_user
511 e = Environment.default 526 e = Environment.default
test/integration/safe_strings_test.rb
@@ -175,4 +175,15 @@ class SafeStringsTest &lt; ActionDispatch::IntegrationTest @@ -175,4 +175,15 @@ class SafeStringsTest &lt; ActionDispatch::IntegrationTest
175 assert_select '.icon-selector .icon-edit' 175 assert_select '.icon-selector .icon-edit'
176 end 176 end
177 177
  178 + should 'not escape read more link to article on display short format' do
  179 + profile = fast_create Profile
  180 + blog = fast_create Blog, :name => 'Blog', :profile_id => profile.id
  181 + fast_create(TinyMceArticle, :name => "Post Test", :profile_id => profile.id, :parent_id => blog.id, :accept_comments => false, :body => '<p>Lorem ipsum dolor sit amet</p>')
  182 + blog.update_attribute(:visualization_format, 'short')
  183 +
  184 + get "/#{profile.identifier}/blog"
  185 + assert_tag :tag => 'div', :attributes => {:class => 'read-more'}, :child => {:tag => 'a', :content => 'Read more'}
  186 + end
  187 +
  188 +
178 end 189 end
test/test_helper.rb
@@ -8,7 +8,7 @@ require &#39;rails/test_help&#39; @@ -8,7 +8,7 @@ require &#39;rails/test_help&#39;
8 8
9 require 'mocha' 9 require 'mocha'
10 require 'mocha/mini_test' 10 require 'mocha/mini_test'
11 - 11 +require "minitest/spec"
12 require "minitest/reporters" 12 require "minitest/reporters"
13 Minitest::Reporters.use! Minitest::Reporters::ProgressReporter.new, ENV, Minitest.backtrace_filter 13 Minitest::Reporters.use! Minitest::Reporters::ProgressReporter.new, ENV, Minitest.backtrace_filter
14 14
@@ -52,19 +52,13 @@ class ActiveSupport::TestCase @@ -52,19 +52,13 @@ class ActiveSupport::TestCase
52 # then set this back to true. 52 # then set this back to true.
53 self.use_instantiated_fixtures = false 53 self.use_instantiated_fixtures = false
54 54
55 - # Add more helper methods to be used by all tests here... 55 + extend Test::Should
56 56
57 - # for fixture_file_upload  
58 include ActionDispatch::TestProcess 57 include ActionDispatch::TestProcess
59 -  
60 include Noosfero::Factory 58 include Noosfero::Factory
61 -  
62 include AuthenticatedTestHelper 59 include AuthenticatedTestHelper
63 -  
64 include PerformanceHelper 60 include PerformanceHelper
65 61
66 - extend Test::Should  
67 -  
68 fixtures :environments, :roles 62 fixtures :environments, :roles
69 63
70 def self.all_fixtures 64 def self.all_fixtures
test/unit/comment_handler_test.rb
@@ -21,4 +21,14 @@ class CommentHandlerTest &lt; ActiveSupport::TestCase @@ -21,4 +21,14 @@ class CommentHandlerTest &lt; ActiveSupport::TestCase
21 handler.perform 21 handler.perform
22 end 22 end
23 23
  24 + should 'save locale from creation context and not change current locale' do
  25 + FastGettext.stubs(:locale).returns("pt")
  26 + handler = CommentHandler.new(5, :whatever_method)
  27 +
  28 + FastGettext.stubs(:locale).returns("en")
  29 + assert_equal "pt", handler.locale
  30 +
  31 + handler.perform
  32 + assert_equal "en", FastGettext.locale
  33 + end
24 end 34 end
test/unit/organization_test.rb
@@ -567,4 +567,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase @@ -567,4 +567,24 @@ class OrganizationTest &lt; ActiveSupport::TestCase
567 assert_not_includes person_orgs, o7 567 assert_not_includes person_orgs, o7
568 assert_includes env_admin_orgs, o7 568 assert_includes env_admin_orgs, o7
569 end 569 end
  570 +
  571 + should 'return true at display_private_info_to? when profile is public and user is nil' do
  572 + organization = fast_create(Organization, public_profile: true)
  573 + assert organization.display_private_info_to?(nil)
  574 + end
  575 +
  576 + should 'return false at display_private_info_to? when profile is public and secret' do
  577 + organization = fast_create(Organization, public_profile: true, secret: true)
  578 + assert !organization.display_private_info_to?(nil)
  579 + end
  580 +
  581 + should 'return false at display_private_info_to? when profile is public and not visible' do
  582 + organization = fast_create(Organization, public_profile: true, visible: false)
  583 + assert !organization.display_private_info_to?(nil)
  584 + end
  585 +
  586 + should 'return false at display_private_info_to? when profile is private and user is nil' do
  587 + organization = fast_create(Organization, public_profile: false)
  588 + assert !organization.display_private_info_to?(nil)
  589 + end
570 end 590 end
test/unit/profile_test.rb
@@ -2204,4 +2204,24 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -2204,4 +2204,24 @@ class ProfileTest &lt; ActiveSupport::TestCase
2204 assert_not_includes profiles, p3 2204 assert_not_includes profiles, p3
2205 assert_not_includes profiles, p4 2205 assert_not_includes profiles, p4
2206 end 2206 end
  2207 +
  2208 + ['post_content', 'edit_profile', 'destroy_profile'].each do |permission|
  2209 + should "return true in #{permission} when user has this permission" do
  2210 + profile = fast_create(Profile)
  2211 + person = fast_create(Person)
  2212 + give_permission(person, permission, profile)
  2213 + assert profile.send("allow_#{permission.gsub(/_profile/,'')}?", person)
  2214 + end
  2215 +
  2216 + should "return false in #{permission} when user doesn't have this permission" do
  2217 + profile = fast_create(Profile)
  2218 + person = fast_create(Person)
  2219 + assert !profile.send("allow_#{permission.gsub(/_profile/,'')}?", person)
  2220 + end
  2221 +
  2222 + should "return false in #{permission} when user is nil" do
  2223 + profile = fast_create(Profile)
  2224 + assert !profile.send("allow_#{permission.gsub(/_profile/,'')}?", nil)
  2225 + end
  2226 + end
2207 end 2227 end
test/unit/url_helper_test.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +require 'test_helper'
  2 +
  3 +class UrlHelperTest < ActionView::TestCase
  4 +
  5 + include UrlHelper
  6 +
  7 + def setup
  8 + end
  9 +
  10 + should 'preserve override_user if present' do
  11 + params[:override_user] = 1
  12 + assert_equal default_url_options[:override_user], params[:override_user]
  13 + end
  14 +
  15 +end