Commit 858648c1ccfefe0e6c441b312777a4df48c02a9b
Exists in
staging
and in
1 other branch
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 < ApplicationRecord | @@ -567,7 +567,7 @@ class Article < 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 < Profile | @@ -238,4 +238,7 @@ class Organization < 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
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 'acts_as_customizable' | @@ -25,7 +25,6 @@ require 'acts_as_customizable' | ||
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 'upload_sanitizer' | @@ -2,8 +2,6 @@ require 'upload_sanitizer' | ||
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 < Noosfero::Plugin | @@ -42,7 +42,7 @@ class AnalyticsPlugin::Base < 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 < Noosfero::Plugin | @@ -13,7 +13,7 @@ class CustomFormsPlugin < 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 < ActionView::TestCase | @@ -656,6 +656,23 @@ class DisplayContentBlockViewTest < 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 < ProfileController | @@ -37,20 +37,17 @@ class OrganizationRatingsPluginProfileController < 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 < ApplicationRecord | @@ -13,25 +13,26 @@ class OrganizationRating < 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 < ActionController::TestCas | @@ -46,7 +46,7 @@ class OrganizationRatingsPluginProfileControllerTest < 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 < ActionController::TestCas | @@ -188,4 +188,24 @@ class OrganizationRatingsPluginProfileControllerTest < 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 < ActiveSupport::TestCase | @@ -35,55 +35,36 @@ class OrganizationRatingTest < 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 < ActiveSupport::TestCase | @@ -109,7 +90,7 @@ class OrganizationRatingTest < 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 < ActiveSupport::TestCase | @@ -119,11 +100,13 @@ class OrganizationRatingTest < 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 'ratings_helper' | @@ -3,6 +3,7 @@ require 'ratings_helper' | ||
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 < ActiveSupport::TestCase | @@ -12,6 +13,12 @@ class RatingsHelperTest < 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 < ActiveSupport::TestCase | @@ -32,6 +39,7 @@ class RatingsHelperTest < 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 < ActiveSupport::TestCase | @@ -57,7 +65,42 @@ class RatingsHelperTest < 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 %> |
@@ -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" |
@@ -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 |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +require_relative '../../../test/test_helper' |
@@ -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 |
@@ -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 < Noosfero::Plugin | @@ -38,7 +38,7 @@ class RequireAuthToCommentPlugin < 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 < Noosfero::Plugin | @@ -20,7 +20,7 @@ class SubOrganizationsPlugin < 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 < ActiveSupport::TestCase | @@ -27,8 +27,8 @@ class ActivitiesTest < 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 < ActiveSupport::TestCase | @@ -68,6 +68,15 @@ class ActivitiesTest < 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 < ActiveSupport::TestCase | @@ -810,4 +810,12 @@ class ArticlesTest < 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 < ActiveSupport::TestCase | @@ -191,4 +191,13 @@ class ProfilesTest < 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 < ActionController::TestCase | @@ -506,6 +506,21 @@ class ApplicationControllerTest < 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 < ActionDispatch::IntegrationTest | @@ -175,4 +175,15 @@ class SafeStringsTest < 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 'rails/test_help' | @@ -8,7 +8,7 @@ require 'rails/test_help' | ||
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 < ActiveSupport::TestCase | @@ -21,4 +21,14 @@ class CommentHandlerTest < 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 < ActiveSupport::TestCase | @@ -567,4 +567,24 @@ class OrganizationTest < 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 < ActiveSupport::TestCase | @@ -2204,4 +2204,24 @@ class ProfileTest < 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 |
@@ -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 |