Commit 3e5d8c7699ccc3da51f7bb1f0b277d5fb90b8bfc

Authored by Victor Costa
2 parents b77d88ab ce9e80c8

Merge branch 'serpro-context' into stable

Conflicts:
	app/models/profile.rb
	app/views/profile_editor/edit.html.erb
.gitmodules
... ... @@ -16,3 +16,6 @@
16 16 [submodule "plugins/proposals_discussion"]
17 17 path = plugins/proposals_discussion
18 18 url = git@gitlab.com:noosfero-plugins/proposals_discussion.git
  19 +[submodule "plugins/site_tour"]
  20 + path = plugins/site_tour
  21 + url = git@gitlab.com:noosfero-plugins/site_tour.git
... ...
app/models/profile.rb
... ... @@ -3,7 +3,7 @@
3 3 # which by default is the one returned by Environment:default.
4 4 class Profile < ActiveRecord::Base
5 5  
6   - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :custom_fields
  6 + attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :custom_fields
7 7  
8 8 # use for internationalizable human type names in search facets
9 9 # reimplement on subclasses
... ... @@ -116,16 +116,6 @@ class Profile &lt; ActiveRecord::Base
116 116 scope :templates, {:conditions => {:is_template => true}}
117 117 scope :no_templates, {:conditions => {:is_template => false}}
118 118  
119   - #FIXME make this test
120   - scope :newer_than, lambda { |reference_id|
121   - {:conditions => ["profiles.id > #{reference_id}"]}
122   - }
123   -
124   - #FIXME make this test
125   - scope :older_than, lambda { |reference_id|
126   - {:conditions => ["profiles.id < #{reference_id}"]}
127   - }
128   -
129 119 def members
130 120 scopes = plugins.dispatch_scopes(:organization_members, self)
131 121 scopes << Person.members_of(self)
... ... @@ -703,32 +693,6 @@ private :generate_url, :url_options
703 693 end
704 694 end
705 695  
706   - # Adds many people to profile by id's or email's
707   - def add_members(people_ids)
708   -
709   - unless people_ids.nil? && people_ids.empty?
710   - people = []
711   -
712   - if people_ids.first =~ /\@/
713   - people = User.where(email: people_ids)
714   - else
715   - people = Person.where(id: people_ids)
716   - end
717   -
718   - people.each do |profile|
719   - person = profile
720   -
721   - if profile.is_a? User
722   - person = profile.person
723   - end
724   -
725   - unless person.is_member_of?(self)
726   - add_member person
727   - end
728   - end
729   - end
730   - end
731   -
732 696 def remove_member(person)
733 697 self.disaffiliate(person, Profile::Roles.all_roles(environment.id))
734 698 end
... ... @@ -975,13 +939,6 @@ private :generate_url, :url_options
975 939 image.public_filename(:icon) if image.present?
976 940 end
977 941  
978   - #FIXME make this test
979   - def profile_custom_image(size = :icon)
980   - image_path = profile_custom_icon if size == :icon
981   - image_path ||= image.public_filename(size) if image.present?
982   - image_path
983   - end
984   -
985 942 def jid(options = {})
986 943 domain = options[:domain] || environment.default_hostname
987 944 "#{identifier}@#{domain}"
... ...
app/views/favorite_enterprises/index.html.erb
... ... @@ -9,7 +9,7 @@
9 9 enterprise.identifier, :class => 'profile-link' %>
10 10 <%# profile_image_link enterprise, :portrait, 'div' %>
11 11 <div class="controll">
12   - <%= button(:delete, _('remove'), { :action => 'remove', :id => enterprise.id },:title => _('remove')) %>
  12 + <%= button_without_text(:delete, _('remove'), { :action => 'remove', :id => enterprise.id },:title => _('remove')) %>
13 13 </div><!-- end class="controll" -->
14 14 </li>
15 15 <% end %>
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -6,6 +6,10 @@
6 6 <!--<meta http-equiv="refresh" content="1"/>-->
7 7 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
8 8  
  9 + <% unless defined? MetadataPlugin and environment.enabled_plugins.include? 'MetadataPlugin' %>
  10 + <meta name="description" content="<%= @environment.name %>" />
  11 + <% end %>
  12 +
9 13 <!-- site root -->
10 14 <meta property="noosfero:root" content="<%= Noosfero.root %>"/>
11 15  
... ...
app/views/profile_editor/edit.html.erb
... ... @@ -33,14 +33,14 @@
33 33 <%= labelled_radio_button _('Private &mdash; show my contents only to friends'), 'profile_data[public_profile]', false, !@profile.public_profile? %>
34 34 </div>
35 35 <% else %>
36   - <div style="border-bottom: 1px solid #e0e0e0; padding-bottom: 7px; margin-bottom: 7px;">
37   - <%= labelled_check_box _('Hidden &mdash; this group will be visible only by members'), 'profile_data[visible]', false, !@profile.visible %>
  36 + <div>
  37 + <%= labelled_check_box _("Secret &mdash; hide the community and all its contents for non members and other people can't join this community unless they are invited to."), 'profile_data[secret]', true, profile.secret, :class => "profile-secret-box" %>
38 38 </div>
39 39 <div>
40   - <%= labelled_radio_button _('Public &mdash; show content of this group to all internet users'), 'profile_data[public_profile]', true, @profile.public_profile? %>
  40 + <%= labelled_radio_button _('Public &mdash; show content of this group to all internet users'), 'profile_data[public_profile]', true, @profile.public_profile?, :class => "public-community-button" %>
41 41 </div>
42 42 <div>
43   - <%= labelled_radio_button _('Private &mdash; show content of this group only to members'), 'profile_data[public_profile]', false, !@profile.public_profile? %>
  43 + <%= labelled_radio_button _('Private &mdash; show content of this group only to members'), 'profile_data[public_profile]', false, !@profile.public_profile?, :class => "private-community-button" %>
44 44 </div>
45 45 <% end %>
46 46  
... ... @@ -89,3 +89,5 @@
89 89 <% end %>
90 90 <% end %>
91 91 <% end %>
  92 +
  93 +<%= javascript_include_tag 'profile_editor' %>
... ...
db/migrate/20150223180806_add_secret_to_profile.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class AddSecretToProfile < ActiveRecord::Migration
  2 + def change
  3 + add_column :profiles, :secret, :boolean, :default => false
  4 + end
  5 +end
... ...
db/schema.rb
... ... @@ -11,7 +11,7 @@
11 11 #
12 12 # It's strongly recommended to check this file into your version control system.
13 13  
14   -ActiveRecord::Schema.define(:version => 20150122165042) do
  14 +ActiveRecord::Schema.define(:version => 20150223180806) do
15 15  
16 16 create_table "abuse_reports", :force => true do |t|
17 17 t.integer "reporter_id"
... ... @@ -535,6 +535,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150122165042) do
535 535 t.integer "welcome_page_id"
536 536 t.boolean "allow_members_to_invite", :default => true
537 537 t.boolean "invite_friends_only", :default => false
  538 + t.boolean "secret", :default => false
538 539 end
539 540  
540 541 add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count"
... ...
features/secret_community.feature 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +Feature: Use a secret community
  2 + As a community administrator
  3 + I want to manage the community privacy
  4 +
  5 + Background:
  6 + Given the following users
  7 + | login | name |
  8 + | jose | Jose Wilker |
  9 + | maria | Maria Carminha |
  10 + And the following community
  11 + | identifier | name |
  12 + | mycommunity | My Community |
  13 + And "Jose Wilker" is admin of "My Community"
  14 + And I am logged in as "jose"
  15 + And I go to mycommunity's control panel
  16 + And I follow "Community Info and settings"
  17 + And I check "Secret"
  18 + And I press "Save"
  19 + And I follow "Logout"
  20 +
  21 + @selenium
  22 + Scenario: Hide privacity options when secret is checked
  23 + Given I am logged in as "jose"
  24 + And I go to mycommunity's control panel
  25 + And I follow "Community Info and settings"
  26 + Then I should not see "Public — show content of this group to all internet users"
  27 + And I should not see "Private — show content of this group only to members"
  28 + And I uncheck "Secret"
  29 + Then I should see "Public — show content of this group to all internet users"
  30 + Then I should see "Private — show content of this group only to members"
  31 +
  32 + @selenium
  33 + Scenario: Non members shouldn't see secret communit's content
  34 + Given I am logged in as "maria"
  35 + And I go to mycommunity's homepage
  36 + And I should see "Access denied"
  37 + And I follow "Communities"
  38 + Then I should not see "My Community"
  39 +
  40 + Scenario: A member should see the secret community's content
  41 + Given I am logged in as "maria"
  42 + And "Maria Carminha" is a member of "My Community"
  43 + And I go to maria's control panel
  44 + And I follow "Manage my groups"
  45 + And I follow "My Community"
  46 + Then I should see "My Community"
  47 +
  48 + @selenium
  49 + Scenario: public article on a secret profile should not be displayed
  50 + Given I am logged in as "jose"
  51 + And I go to mycommunity's control panel
  52 + And I follow "Manage Content"
  53 + And I follow "New content"
  54 + And I follow "Text article with visual editor"
  55 + And I fill in "Title" with "My public article"
  56 + And I choose "Public"
  57 + And I press "Save and continue"
  58 + When I am logged in as "maria"
  59 + And I go to /mycommunity/my-public-article
  60 + Then I should not see "My public article"
... ...
plugins/breadcrumbs/lib/breadcrumbs_plugin/content_breadcrumbs_block.rb
... ... @@ -2,8 +2,9 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
2 2  
3 3 settings_items :show_cms_action, :type => :boolean, :default => true
4 4 settings_items :show_profile, :type => :boolean, :default => true
  5 + settings_items :show_section_name, :type => :boolean, :default => true
5 6  
6   - attr_accessible :show_cms_action, :show_profile
  7 + attr_accessible :show_cms_action, :show_profile, :show_section_name
7 8  
8 9 def self.description
9 10 _("<p>Display a breadcrumb of the current content navigation.</p><p>You could choose if the breadcrumb is going to appear in the cms editing or not.</p> <p>There is either the option of display the profile location in the breadcrumb path.</p>")
... ... @@ -48,7 +49,18 @@ class BreadcrumbsPlugin::ContentBreadcrumbsBlock &lt; Block
48 49 proc do
49 50 trail = block.trail(@page, @profile, params)
50 51 if !trail.empty?
51   - trail.map { |t| link_to(t[:name], t[:url], :class => 'item') }.join(content_tag('span', ' > ', :class => 'separator'))
  52 + separator = content_tag('span', ' > ', :class => 'separator')
  53 +
  54 + breadcrumb = trail.map do |t|
  55 + link_to(t[:name], t[:url], :class => 'item')
  56 + end.join(separator)
  57 +
  58 + if block.show_section_name
  59 + section_name = block.show_profile ? trail.second[:name] : trail.first[:name]
  60 + breadcrumb << content_tag('div', section_name, :class => 'section-name')
  61 + end
  62 +
  63 + breadcrumb
52 64 else
53 65 ''
54 66 end
... ...
plugins/breadcrumbs/test/functional/profile_design_controller_test.rb
... ... @@ -41,4 +41,9 @@ class ProfileDesignControllerTest &lt; ActionController::TestCase
41 41 assert !@block.show_cms_action
42 42 end
43 43  
  44 + should 'be able save breadcrumbs block with show_section_name option' do
  45 + get :edit, :id => @block.id, :profile => @profile.identifier
  46 + post :save, :id => @block.id, :profile => @profile.identifier, :block => {:title => 'breadcrumbs', :show_cms_action => false, :show_profile => true, :show_section_name => true }
  47 + assert @block.show_section_name
  48 + end
44 49 end
... ...
plugins/breadcrumbs/views/box_organizer/breadcrumbs_plugin/_content_breadcrumbs_block.html.erb
1 1 <div id='edit-breadcrumbs-block'>
2 2 <%= labelled_form_field check_box(:block, :show_cms_action) + _('Show cms action'), '' %>
3 3 <%= labelled_form_field check_box(:block, :show_profile) + _('Show profile'), '' %>
  4 + <%= labelled_form_field check_box(:block, :show_section_name) + _('Show section name'), '' %>
4 5 </div>
... ...
plugins/metadata/lib/ext/environment.rb
... ... @@ -2,6 +2,10 @@ require_dependency &#39;environment&#39;
2 2  
3 3 class Environment
4 4  
  5 + metadata_spec tags: {
  6 + description: proc{ |e, plugin| e.name },
  7 + }
  8 +
5 9 metadata_spec namespace: :og, tags: {
6 10 type: 'website',
7 11 title: proc{ |e, plugin| e.name },
... ...
plugins/pg_search/db/migrate/20130320010063_create_indexes_for_search.rb
1 1 class CreateIndexesForSearch < ActiveRecord::Migration
  2 + SEARCHABLES = %w[ article comment qualifier national_region certifier profile license scrap category ]
  3 + KLASSES = SEARCHABLES.map {|searchable| searchable.camelize.constantize }
2 4 def self.up
3   - searchables = %w[ article comment qualifier national_region certifier profile license scrap category ]
4   - klasses = searchables.map {|searchable| searchable.camelize.constantize }
5   - klasses.each do |klass|
  5 + KLASSES.each do |klass|
6 6 fields = klass.pg_search_plugin_fields
7 7 execute "create index pg_search_plugin_#{klass.name.singularize.downcase} on #{klass.table_name} using gin(to_tsvector('simple', #{fields}))"
8 8 end
9 9 end
10 10  
11 11 def self.down
12   - klasses.each do |klass|
  12 + KLASSES.each do |klass|
13 13 execute "drop index pg_search_plugin_#{klass.name.singularize.downcase}"
14 14 end
15 15 end
... ...
plugins/site_tour 0 → 160000
... ... @@ -0,0 +1 @@
  1 +Subproject commit e6925e5450f49bc7d89414c0f20876351933cebd
... ...
public/javascripts/application.js
... ... @@ -1074,7 +1074,7 @@ jQuery(document).ready(function(){
1074 1074 function apply_zoom_to_images(zoom_text) {
1075 1075 jQuery(function($) {
1076 1076 $(window).load( function() {
1077   - $('#article .article-body img').each( function(index) {
  1077 + $('#article .article-body img:not(.disable-zoom)').each( function(index) {
1078 1078 var original = original_image_dimensions($(this).attr('src'));
1079 1079 if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1080 1080 $(this).wrap('<div class="zoomable-image" />');
... ...
public/javascripts/profile_editor.js 0 → 100644
... ... @@ -0,0 +1,26 @@
  1 +(function($){
  2 + 'use strict';
  3 +
  4 + function show_or_hide_privacy_radio_buttons(hide_options) {
  5 + var public_community = $(".public-community-button").parent();
  6 + var private_community = $(".private-community-button").parent();
  7 + if (hide_options) {
  8 + $(".private-community-button").selected();
  9 + public_community.hide();
  10 + private_community.hide();
  11 +
  12 + } else {
  13 + public_community.show();
  14 + private_community.show();
  15 + }
  16 + }
  17 +
  18 + $(document).ready(function(){
  19 + var profile_secret = $(".profile-secret-box");
  20 + show_or_hide_privacy_radio_buttons(profile_secret.is(":checked"));
  21 + profile_secret.change(function(){
  22 + show_or_hide_privacy_radio_buttons(this.checked);
  23 + });
  24 +
  25 + });
  26 +})(jQuery);
... ...
test/unit/profile_test.rb
... ... @@ -443,6 +443,24 @@ class ProfileTest &lt; ActiveSupport::TestCase
443 443 assert_not_includes result, p2
444 444 end
445 445  
  446 + should 'be able to find the public profiles but not secret ones' do
  447 + p1 = create(Profile, :public_profile => true)
  448 + p2 = create(Profile, :public_profile => true, :secret => true)
  449 +
  450 + result = Profile.public
  451 + assert_includes result, p1
  452 + assert_not_includes result, p2
  453 + end
  454 +
  455 + should 'be able to find visible profiles but not secret ones' do
  456 + p1 = create(Profile, :visible => true)
  457 + p2 = create(Profile, :visible => true, :secret => true)
  458 +
  459 + result = Profile.visible
  460 + assert_includes result, p1
  461 + assert_not_includes result, p2
  462 + end
  463 +
446 464 should 'have public content by default' do
447 465 assert_equal true, Profile.new.public_content
448 466 end
... ... @@ -485,7 +503,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
485 503 should 'categorize in the entire category hierarchy' do
486 504 c1 = fast_create(Category)
487 505 c2 = fast_create(Category, :parent_id => c1.id)
488   - c3 = fast_create(Category, :parent_id => c2.id)
  506 + c3 = fast_create(Category, :parent_id => c2.id)
489 507  
490 508 profile = create_user('testuser').person
491 509 profile.add_category(c3)
... ... @@ -1006,7 +1024,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1006 1024  
1007 1025 should 'copy header when applying template' do
1008 1026 template = fast_create(Profile)
1009   - template[:custom_header] = '{name}'
  1027 + template[:custom_header] = '{name}'
1010 1028 template.save!
1011 1029  
1012 1030 p = create(Profile, :name => 'test prof')
... ... @@ -1260,7 +1278,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1260 1278 task2 = Task.create!(:requestor => person, :target => another)
1261 1279  
1262 1280 person.stubs(:is_admin?).with(other).returns(true)
1263   - Environment.find(:all).select{|i| i != other }.each do |env|
  1281 + Environment.find(:all).select{|i| i != other }.each do |env|
1264 1282 person.stubs(:is_admin?).with(env).returns(false)
1265 1283 end
1266 1284  
... ... @@ -1729,7 +1747,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1729 1747 assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage)
1730 1748 end
1731 1749  
1732   -
  1750 +
1733 1751 should 'find profiles with image' do
1734 1752 env = fast_create(Environment)
1735 1753 2.times do |n|
... ...