Commit 7a8c628278b97de5e019a31467c24924126515ae

Authored by Evandro Junior
2 parents 256e490d 99b738b5

Merge branch 'master' of gitlab.com:noosfero/noosfero

Showing 94 changed files with 1352 additions and 426 deletions   Show diff stats
INSTALL.chat.md
1 -XMPP/Chat Setup  
2 -=============== 1 +Automatic XMPP/Chat Setup
  2 +=========================
  3 +
  4 +Since Noosfero 1.2, the XMPP/Chat can be installed via `noosfero-chat` Debian
  5 +package. So you don't need to follow the manual instructions here if you
  6 +already have it installed on your system.
  7 +
  8 +But if you are going to install the `noosfero-chat` package on a system that
  9 +already has `noosfero` older 1.2 installed then you need to check if apache's
  10 +configuration file `/etc/apache2/sites-available/noosfero` has this line below:
  11 +
  12 + Include /usr/share/noosfero/util/chat/apache/xmpp.conf
  13 +
  14 +Manual XMPP/Chat Setup
  15 +======================
3 16
4 The samples of config file to configure a XMPP/BOSH server with ejabberd, 17 The samples of config file to configure a XMPP/BOSH server with ejabberd,
5 postgresql and apache2 can be found at util/chat directory. 18 postgresql and apache2 can be found at util/chat directory.
@@ -8,7 +21,7 @@ This setup supposes that you are using Noosfero installed via Debian package @@ -8,7 +21,7 @@ This setup supposes that you are using Noosfero installed via Debian package
8 in a production environment. 21 in a production environment.
9 22
10 Steps 23 Steps
11 -===== 24 +-----
12 25
13 This is a step-by-step guide to get a XMPP service working, in a Debian system. 26 This is a step-by-step guide to get a XMPP service working, in a Debian system.
14 27
@@ -144,15 +157,8 @@ You should see a page with a message like that: @@ -144,15 +157,8 @@ You should see a page with a message like that:
144 157
145 ## 9. Test chat session 158 ## 9. Test chat session
146 159
147 -Open Noosfero console and execute:  
148 -  
149 ->> environment = Environment.default  
150 ->> user = Person['guest']  
151 ->> password = user.user.crypted_password  
152 ->> login = user.jid  
153 ->> RubyBOSH.initialize_session(login, password, "http://#{environment.default_hostname}/http-bind", :wait => 30, :hold => 1, :window => 5  
154 -  
155 -If you have luck, should see something like that: 160 +Run `./script/noosfero-test-chat-session`. If you have luck, should see
  161 +something like that:
156 162
157 Ruby-BOSH - SEND 163 Ruby-BOSH - SEND
158 <body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/> 164 <body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/>
app/controllers/admin/admin_panel_controller.rb
@@ -71,22 +71,4 @@ class AdminPanelController &lt; AdminController @@ -71,22 +71,4 @@ class AdminPanelController &lt; AdminController
71 end 71 end
72 end 72 end
73 end 73 end
74 -  
75 - def manage_organizations_status  
76 - scope = environment.organizations  
77 - @filter = params[:filter] || 'any'  
78 - @title = "Organization profiles"  
79 - @title = @title+" - "+@filter if @filter != 'any'  
80 -  
81 - if @filter == 'enabled'  
82 - scope = scope.visible  
83 - elsif @filter == 'disabled'  
84 - scope = scope.disabled  
85 - end  
86 -  
87 - scope = scope.order('name ASC')  
88 -  
89 - @q = params[:q]  
90 - @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => 10, :page => params[:npage]})[:results]  
91 - end  
92 end 74 end
app/controllers/admin/organizations_controller.rb 0 → 100644
@@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
  1 +class OrganizationsController < AdminController
  2 +
  3 + protect 'manage_environment_organizations', :environment
  4 +
  5 + def index
  6 + @filter = params[:filter] || 'any'
  7 + @title = _('Organization profiles')
  8 + @type = params[:type] || "any"
  9 + @types_filter = [[_('All'), 'any'], [_('Community'), 'Community'], [_('Enterprise'), 'Enterprise']]
  10 + @types_filter = @types_filter | @plugins.dispatch(:organization_types_filter_options)
  11 +
  12 + scope = @plugins.dispatch_first(:filter_manage_organization_scope, @type)
  13 + if scope.blank?
  14 + scope = environment.organizations
  15 + scope = scope.where(:type => @type) if @type != 'any'
  16 + end
  17 +
  18 + if @filter == 'enabled'
  19 + scope = scope.visible
  20 + elsif @filter == 'disabled'
  21 + scope = scope.disabled
  22 + end
  23 +
  24 + scope = scope.order('name ASC')
  25 +
  26 + @q = params[:q]
  27 + @collection = find_by_contents(:organizations, environment, scope, @q, {:per_page => per_page, :page => params[:npage]})[:results]
  28 + end
  29 +
  30 + def activate
  31 + organization = environment.organizations.find(params[:id])
  32 + if organization.enable
  33 + render :text => (_('%s enabled') % organization.name).to_json
  34 + else
  35 + render :text => (_('%s could not be enabled') % organization.name).to_json
  36 + end
  37 + end
  38 +
  39 + def deactivate
  40 + organization = environment.organizations.find(params[:id])
  41 + if organization.disable
  42 + render :text => (_('%s disabled') % organization.name).to_json
  43 + else
  44 + render :text => (_('%s could not be disable') % organization.name).to_json
  45 + end
  46 + end
  47 +
  48 + def destroy
  49 + if request.post?
  50 + organization = environment.organizations.find(params[:id])
  51 + if organization && organization.destroy
  52 + render :text => (_('%s removed') % organization.name).to_json
  53 + else
  54 + render :text => (_('%s could not be removed') % organization.name).to_json
  55 + end
  56 + else
  57 + render :nothing => true
  58 + end
  59 + end
  60 +
  61 + private
  62 +
  63 + def per_page
  64 + 10
  65 + end
  66 +end
app/controllers/my_profile/cms_controller.rb
@@ -143,7 +143,14 @@ class CmsController &lt; MyProfileController @@ -143,7 +143,14 @@ class CmsController &lt; MyProfileController
143 klass = @type.constantize 143 klass = @type.constantize
144 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {} 144 article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
145 article_data.merge!(params[:article]) if params[:article] 145 article_data.merge!(params[:article]) if params[:article]
146 - @article = klass.new(article_data) 146 + article_data.merge!(:profile => profile) if profile
  147 +
  148 + @article = if params[:clone]
  149 + current_article = profile.articles.find(params[:id])
  150 + current_article.copy_without_save
  151 + else
  152 + klass.new(article_data)
  153 + end
147 154
148 parent = check_parent(params[:parent_id]) 155 parent = check_parent(params[:parent_id])
149 if parent 156 if parent
@@ -220,7 +227,7 @@ class CmsController &lt; MyProfileController @@ -220,7 +227,7 @@ class CmsController &lt; MyProfileController
220 if @errors.any? 227 if @errors.any?
221 render :action => 'upload_files', :parent_id => @parent_id 228 render :action => 'upload_files', :parent_id => @parent_id
222 else 229 else
223 - session[:notice] = _('File(s) successfully uploaded') 230 + session[:notice] = _('File(s) successfully uploaded')
224 if @back_to 231 if @back_to
225 redirect_to @back_to 232 redirect_to @back_to
226 elsif @parent 233 elsif @parent
app/controllers/my_profile/tasks_controller.rb
1 class TasksController < MyProfileController 1 class TasksController < MyProfileController
2 2
3 protect 'perform_task', :profile 3 protect 'perform_task', :profile
4 - 4 +
5 def index 5 def index
6 - @filter = params[:filter_type].blank? ? nil : params[:filter_type] 6 + @filter_type = params[:filter_type].presence
  7 + @filter_text = params[:filter_text].presence
7 @task_types = Task.pending_types_for(profile) 8 @task_types = Task.pending_types_for(profile)
8 - @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) 9 + @tasks = Task.pending_all(profile, @filter_type, @filter_text).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
9 @failed = params ? params[:failed] : {} 10 @failed = params ? params[:failed] : {}
10 end 11 end
11 12
app/controllers/public/content_viewer_controller.rb
@@ -13,7 +13,7 @@ class ContentViewerController &lt; ApplicationController @@ -13,7 +13,7 @@ class ContentViewerController &lt; ApplicationController
13 @version = params[:version].to_i 13 @version = params[:version].to_i
14 14
15 if path.blank? 15 if path.blank?
16 - @page = profile.home_page 16 + @page = profile.home_page
17 return if redirected_to_profile_index 17 return if redirected_to_profile_index
18 else 18 else
19 @page = profile.articles.find_by_path(path) 19 @page = profile.articles.find_by_path(path)
@@ -121,21 +121,23 @@ class ContentViewerController &lt; ApplicationController @@ -121,21 +121,23 @@ class ContentViewerController &lt; ApplicationController
121 helper_method :pass_without_comment_captcha? 121 helper_method :pass_without_comment_captcha?
122 122
123 def allow_access_to_page(path) 123 def allow_access_to_page(path)
124 - allowed = true  
125 if @page.nil? # page not found, give error 124 if @page.nil? # page not found, give error
126 render_not_found(path) 125 render_not_found(path)
127 - allowed = false  
128 - elsif !@page.display_to?(user)  
129 - if !profile.public? 126 + return false
  127 + end
  128 +
  129 + unless @page.display_to?(user)
  130 + if !profile.visible? || profile.secret? || (user && user.follows?(profile))
  131 + render_access_denied
  132 + else #!profile.public?
130 private_profile_partial_parameters 133 private_profile_partial_parameters
131 render :template => 'profile/_private_profile', :status => 403, :formats => [:html] 134 render :template => 'profile/_private_profile', :status => 403, :formats => [:html]
132 - allowed = false  
133 - else #if !profile.visible?  
134 - render_access_denied  
135 - allowed = false  
136 end 135 end
  136 +
  137 + return false
137 end 138 end
138 - allowed 139 +
  140 + return true
139 end 141 end
140 142
141 def user_is_a_bot? 143 def user_is_a_bot?
@@ -180,7 +182,7 @@ class ContentViewerController &lt; ApplicationController @@ -180,7 +182,7 @@ class ContentViewerController &lt; ApplicationController
180 if @page.forum? && @page.has_terms_of_use && terms_accepted == "true" 182 if @page.forum? && @page.has_terms_of_use && terms_accepted == "true"
181 @page.add_agreed_user(user) 183 @page.add_agreed_user(user)
182 end 184 end
183 - end 185 + end
184 186
185 def is_a_forum_topic? (page) 187 def is_a_forum_topic? (page)
186 return (!@page.parent.nil? && @page.parent.forum?) 188 return (!@page.parent.nil? && @page.parent.forum?)
app/controllers/public_controller.rb
@@ -3,7 +3,7 @@ class PublicController &lt; ApplicationController @@ -3,7 +3,7 @@ class PublicController &lt; ApplicationController
3 3
4 def allow_access_to_page 4 def allow_access_to_page
5 unless profile.display_info_to?(user) 5 unless profile.display_info_to?(user)
6 - if profile.visible? 6 + if profile.visible? && !profile.secret
7 private_profile 7 private_profile
8 else 8 else
9 invisible_profile 9 invisible_profile
app/helpers/application_helper.rb
@@ -931,6 +931,19 @@ module ApplicationHelper @@ -931,6 +931,19 @@ module ApplicationHelper
931 article_helper.cms_label_for_edit 931 article_helper.cms_label_for_edit
932 end 932 end
933 933
  934 + def label_for_clone_article(article)
  935 + translated_types = {
  936 + Folder => _('Folder'),
  937 + Blog => _('Blog'),
  938 + Event => _('Event'),
  939 + Forum => _('Forum')
  940 + }
  941 +
  942 + translated_type = translated_types[article.class] || _('Article')
  943 +
  944 + _('Clone %s') % translated_type
  945 + end
  946 +
934 def add_rss_feed_to_head(title, url) 947 def add_rss_feed_to_head(title, url)
935 content_for :feeds do 948 content_for :feeds do
936 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url)) 949 tag(:link, :rel => 'alternate', :type => 'application/rss+xml', :title => title, :href => url_for(url))
@@ -1498,4 +1511,26 @@ module ApplicationHelper @@ -1498,4 +1511,26 @@ module ApplicationHelper
1498 text_field(object_name, method, options.merge(:class => 'colorpicker_field')) 1511 text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
1499 end 1512 end
1500 1513
  1514 + def fullscreen_buttons(itemId)
  1515 + content="
  1516 + <script>fullscreenPageLoad('#{itemId}')</script>
  1517 + "
  1518 + content+=content_tag('a', content_tag('span',_("Full screen")),
  1519 + { :id=>"fullscreen-btn",
  1520 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1521 + :class=>"button with-text icon-fullscreen",
  1522 + :href=>"#",
  1523 + :title=>_("Go to full screen mode")
  1524 + })
  1525 +
  1526 + content+=content_tag('a', content_tag('span',_("Exit full screen")),
  1527 + { :style=>"display: none;",
  1528 + :id=>"exit-fullscreen-btn",
  1529 + :onClick=>"toggle_fullwidth('#{itemId}')",
  1530 + :class=>"button with-text icon-fullscreen",
  1531 + :href=>"#",
  1532 + :title=>_("Exit full screen mode")
  1533 + })
  1534 + end
  1535 +
1501 end 1536 end
app/helpers/article_helper.rb
@@ -12,6 +12,7 @@ module ArticleHelper @@ -12,6 +12,7 @@ module ArticleHelper
12 @article = article 12 @article = article
13 13
14 visibility_options(@article, tokenized_children) + 14 visibility_options(@article, tokenized_children) +
  15 + topic_creation(@article) +
15 content_tag('h4', _('Options')) + 16 content_tag('h4', _('Options')) +
16 content_tag('div', 17 content_tag('div',
17 (article.profile.has_members? ? 18 (article.profile.has_members? ?
@@ -55,14 +56,7 @@ module ArticleHelper @@ -55,14 +56,7 @@ module ArticleHelper
55 'div', 56 'div',
56 check_box(:article, :display_versions) + 57 check_box(:article, :display_versions) +
57 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions') 58 content_tag('label', _('I want this article to display a link to older versions'), :for => 'article_display_versions')
58 - ) : '') +  
59 -  
60 - (article.forum? && article.profile.community? ?  
61 - content_tag(  
62 - 'div',  
63 - check_box(:article, :allows_members_to_create_topics) +  
64 - content_tag('label', _('Allow members to create topics'), :for => 'article_allows_members_to_create_topics')  
65 - ) : '') 59 + ) : '')
66 ) 60 )
67 end 61 end
68 62
@@ -81,6 +75,22 @@ module ArticleHelper @@ -81,6 +75,22 @@ module ArticleHelper
81 ) 75 )
82 end 76 end
83 77
  78 + def topic_creation(article)
  79 + return '' unless article.forum?
  80 +
  81 + general_options = Forum::TopicCreation.general_options(article)
  82 + slider_options = {:id => 'topic-creation-slider'}
  83 + slider_options = general_options.keys.inject(slider_options) do |result, option|
  84 + result.merge!({'data-'+option => general_options[option]})
  85 + end
  86 +
  87 + content_tag('h4', _('Topic creation')) +
  88 + content_tag( 'small', _('Who will be able to create new topics on this forum?')) +
  89 + content_tag('div', '', slider_options) +
  90 + hidden_field_tag('article[topic_creation]', article.topic_creation) +
  91 + javascript_include_tag('topic-creation-config')
  92 + end
  93 +
84 def privacity_exceptions(article, tokenized_children) 94 def privacity_exceptions(article, tokenized_children)
85 content_tag('div', 95 content_tag('div',
86 content_tag('div', 96 content_tag('div',
app/helpers/tinymce_helper.rb
@@ -20,7 +20,7 @@ module TinymceHelper @@ -20,7 +20,7 @@ module TinymceHelper
20 :image_advtab => true, 20 :image_advtab => true,
21 :language => tinymce_language 21 :language => tinymce_language
22 22
23 - options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" 23 + options[:toolbar1] = "fullscreen | insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
24 if options[:mode] == 'simple' 24 if options[:mode] == 'simple'
25 options[:menubar] = false 25 options[:menubar] = false
26 else 26 else
app/helpers/users_helper.rb
@@ -14,7 +14,7 @@ module UsersHelper @@ -14,7 +14,7 @@ module UsersHelper
14 select_field = select_tag(:filter, options, :onchange => onchange) 14 select_field = select_tag(:filter, options, :onchange => onchange)
15 content_tag('div', 15 content_tag('div',
16 content_tag('strong', _('Filter')) + ': ' + select_field, 16 content_tag('strong', _('Filter')) + ': ' + select_field,
17 - :class => "environment-users-customize-search" 17 + :class => "environment-profiles-customize-search"
18 ) 18 )
19 end 19 end
20 20
app/mailers/task_mailer.rb
@@ -5,7 +5,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -5,7 +5,7 @@ class TaskMailer &lt; ActionMailer::Base
5 @target = task.target.name 5 @target = task.target.name
6 @environment = task.environment.name 6 @environment = task.environment.name
7 @url = generate_environment_url(task, :controller => 'home') 7 @url = generate_environment_url(task, :controller => 'home')
8 - url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url) 8 + url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.tasks_url.merge(:script_name => Noosfero.root('/')))
9 @tasks_url = url_for_tasks_list 9 @tasks_url = url_for_tasks_list
10 10
11 mail( 11 mail(
@@ -56,7 +56,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -56,7 +56,7 @@ class TaskMailer &lt; ActionMailer::Base
56 end 56 end
57 57
58 def generate_environment_url(task, url = {}) 58 def generate_environment_url(task, url = {})
59 - url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url)) 59 + url_for(Noosfero.url_options.merge(:host => task.environment.default_hostname).merge(url).merge(:script_name => Noosfero.root('/')))
60 end 60 end
61 61
62 end 62 end
app/models/article.rb
@@ -25,6 +25,16 @@ class Article &lt; ActiveRecord::Base @@ -25,6 +25,16 @@ class Article &lt; ActiveRecord::Base
25 :display => %w[full] 25 :display => %w[full]
26 } 26 }
27 27
  28 + def initialize(*params)
  29 + super
  30 +
  31 + if !params.blank? && params.first.has_key?(:profile)
  32 + profile = params.first[:profile]
  33 + self.published = false unless profile.public?
  34 + end
  35 +
  36 + end
  37 +
28 def self.default_search_display 38 def self.default_search_display
29 'full' 39 'full'
30 end 40 end
@@ -491,11 +501,11 @@ class Article &lt; ActiveRecord::Base @@ -491,11 +501,11 @@ class Article &lt; ActiveRecord::Base
491 return [] if user.nil? || (profile && !profile.public? && !user.follows?(profile)) 501 return [] if user.nil? || (profile && !profile.public? && !user.follows?(profile))
492 where( 502 where(
493 [ 503 [
494 - "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?  
495 - OR (show_to_followers = ? AND ?)", true, user.id, user.id, 504 + "published = ? OR last_changed_by_id = ? OR profile_id = ? OR ?
  505 + OR (show_to_followers = ? AND ? AND profile_id = ?)", true, user.id, user.id,
496 profile.nil? ? false : user.has_permission?(:view_private_content, profile), 506 profile.nil? ? false : user.has_permission?(:view_private_content, profile),
497 - true, user.follows?(profile)  
498 - ] 507 + true, user.follows?(profile), (profile.nil? ? nil : profile.id)
  508 + ]
499 ) 509 )
500 } 510 }
501 511
@@ -509,7 +519,7 @@ class Article &lt; ActiveRecord::Base @@ -509,7 +519,7 @@ class Article &lt; ActiveRecord::Base
509 519
510 def display_to?(user = nil) 520 def display_to?(user = nil)
511 if published? 521 if published?
512 - profile.display_info_to?(user) 522 + (profile.secret? || !profile.visible?) ? profile.display_info_to?(user) : true
513 else 523 else
514 if !user 524 if !user
515 false 525 false
@@ -567,25 +577,24 @@ class Article &lt; ActiveRecord::Base @@ -567,25 +577,24 @@ class Article &lt; ActiveRecord::Base
567 profile.visible? && profile.public? && published? 577 profile.visible? && profile.public? && published?
568 end 578 end
569 579
570 -  
571 - def copy(options = {}) 580 + def copy_without_save(options = {})
572 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) } 581 attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
573 attrs.merge!(options) 582 attrs.merge!(options)
574 object = self.class.new 583 object = self.class.new
575 attrs.each do |key, value| 584 attrs.each do |key, value|
576 object.send(key.to_s+'=', value) 585 object.send(key.to_s+'=', value)
577 end 586 end
  587 + object
  588 + end
  589 +
  590 + def copy(options = {})
  591 + object = copy_without_save(options)
578 object.save 592 object.save
579 object 593 object
580 end 594 end
581 595
582 def copy!(options = {}) 596 def copy!(options = {})
583 - attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }  
584 - attrs.merge!(options)  
585 - object = self.class.new  
586 - attrs.each do |key, value|  
587 - object.send(key.to_s+'=', value)  
588 - end 597 + object = copy_without_save(options)
589 object.save! 598 object.save!
590 object 599 object
591 end 600 end
app/models/block.rb
@@ -2,7 +2,7 @@ class Block &lt; ActiveRecord::Base @@ -2,7 +2,7 @@ class Block &lt; ActiveRecord::Base
2 2
3 attr_accessible :title, :display, :limit, :box_id, :posts_per_page, 3 attr_accessible :title, :display, :limit, :box_id, :posts_per_page,
4 :visualization_format, :language, :display_user, 4 :visualization_format, :language, :display_user,
5 - :box, :edit_modes, :move_modes 5 + :box, :edit_modes, :move_modes, :mirror
6 6
7 # to be able to generate HTML 7 # to be able to generate HTML
8 include ActionView::Helpers::UrlHelper 8 include ActionView::Helpers::UrlHelper
@@ -15,11 +15,23 @@ class Block &lt; ActiveRecord::Base @@ -15,11 +15,23 @@ class Block &lt; ActiveRecord::Base
15 15
16 acts_as_list :scope => :box 16 acts_as_list :scope => :box
17 belongs_to :box 17 belongs_to :box
  18 + belongs_to :mirror_block, :class_name => "Block"
  19 + has_many :observers, :class_name => "Block", :foreign_key => "mirror_block_id"
18 20
19 acts_as_having_settings 21 acts_as_having_settings
20 22
21 scope :enabled, :conditions => { :enabled => true } 23 scope :enabled, :conditions => { :enabled => true }
22 24
  25 + after_save do |block|
  26 + if block.owner.kind_of?(Profile) && block.owner.is_template? && block.mirror?
  27 + block.observers.each do |observer|
  28 + observer.copy_from(block)
  29 + observer.title = block.title
  30 + observer.save
  31 + end
  32 + end
  33 + end
  34 +
23 def embedable? 35 def embedable?
24 false 36 false
25 end 37 end
@@ -269,6 +281,10 @@ class Block &lt; ActiveRecord::Base @@ -269,6 +281,10 @@ class Block &lt; ActiveRecord::Base
269 self.position = block.position 281 self.position = block.position
270 end 282 end
271 283
  284 + def add_observer(block)
  285 + self.observers << block
  286 + end
  287 +
272 private 288 private
273 289
274 def home_page_path 290 def home_page_path
app/models/environment.rb
@@ -29,6 +29,7 @@ class Environment &lt; ActiveRecord::Base @@ -29,6 +29,7 @@ class Environment &lt; ActiveRecord::Base
29 'manage_environment_roles' => N_('Manage environment roles'), 29 'manage_environment_roles' => N_('Manage environment roles'),
30 'manage_environment_validators' => N_('Manage environment validators'), 30 'manage_environment_validators' => N_('Manage environment validators'),
31 'manage_environment_users' => N_('Manage environment users'), 31 'manage_environment_users' => N_('Manage environment users'),
  32 + 'manage_environment_organizations' => N_('Manage environment organizations'),
32 'manage_environment_templates' => N_('Manage environment templates'), 33 'manage_environment_templates' => N_('Manage environment templates'),
33 'manage_environment_licenses' => N_('Manage environment licenses'), 34 'manage_environment_licenses' => N_('Manage environment licenses'),
34 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'), 35 'manage_environment_trusted_sites' => N_('Manage environment trusted sites'),
@@ -339,6 +340,16 @@ class Environment &lt; ActiveRecord::Base @@ -339,6 +340,16 @@ class Environment &lt; ActiveRecord::Base
339 self.save! 340 self.save!
340 end 341 end
341 342
  343 + def enable_all_plugins
  344 + Noosfero::Plugin.available_plugin_names.each do |plugin|
  345 + plugin_name = plugin.to_s + "Plugin"
  346 + unless self.enabled_plugins.include?(plugin_name)
  347 + self.enabled_plugins += [plugin_name]
  348 + end
  349 + end
  350 + self.save!
  351 + end
  352 +
342 # Disables a feature identified by its name 353 # Disables a feature identified by its name
343 def disable(feature, must_save=true) 354 def disable(feature, must_save=true)
344 self.settings["#{feature}_enabled".to_sym] = false 355 self.settings["#{feature}_enabled".to_sym] = false
app/models/forum.rb
@@ -3,11 +3,11 @@ class Forum &lt; Folder @@ -3,11 +3,11 @@ class Forum &lt; Folder
3 acts_as_having_posts :order => 'updated_at DESC' 3 acts_as_having_posts :order => 'updated_at DESC'
4 include PostsLimit 4 include PostsLimit
5 5
6 - attr_accessible :has_terms_of_use, :terms_of_use, :allows_members_to_create_topics 6 + attr_accessible :has_terms_of_use, :terms_of_use, :topic_creation
7 7
8 settings_items :terms_of_use, :type => :string, :default => "" 8 settings_items :terms_of_use, :type => :string, :default => ""
9 settings_items :has_terms_of_use, :type => :boolean, :default => false 9 settings_items :has_terms_of_use, :type => :boolean, :default => false
10 - settings_items :allows_members_to_create_topics, :type => :boolean, :default => false 10 + settings_items :topic_creation, :type => :string, :default => 'self'
11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people' 11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
12 12
13 before_save do |forum| 13 before_save do |forum|
@@ -33,6 +33,23 @@ class Forum &lt; Folder @@ -33,6 +33,23 @@ class Forum &lt; Folder
33 _('An internet forum, also called message board, where discussions can be held.') 33 _('An internet forum, also called message board, where discussions can be held.')
34 end 34 end
35 35
  36 + module TopicCreation
  37 + BASE = ActiveSupport::OrderedHash.new
  38 + BASE['users'] = _('Logged users')
  39 +
  40 + PERSON = ActiveSupport::OrderedHash.new
  41 + PERSON['self'] = _('Me')
  42 + PERSON['related'] = _('Friends')
  43 +
  44 + GROUP = ActiveSupport::OrderedHash.new
  45 + GROUP['self'] = _('Administrators')
  46 + GROUP['related'] = _('Members')
  47 +
  48 + def self.general_options(forum)
  49 + forum.profile.person? ? PERSON.merge(BASE) : GROUP.merge(BASE)
  50 + end
  51 + end
  52 +
36 include ActionView::Helpers::TagHelper 53 include ActionView::Helpers::TagHelper
37 def to_html(options = {}) 54 def to_html(options = {})
38 proc do 55 proc do
@@ -69,11 +86,17 @@ class Forum &lt; Folder @@ -69,11 +86,17 @@ class Forum &lt; Folder
69 self.users_with_agreement.exists? user 86 self.users_with_agreement.exists? user
70 end 87 end
71 88
72 - def can_create_topic?(user, profile)  
73 - return profile.community? && profile.members.include?(user) && self.allows_members_to_create_topics 89 + def can_create_topic?(user)
  90 + return true if user == profile || profile.admins.include?(user) || profile.environment.admins.include?(user)
  91 + case topic_creation
  92 + when 'related'
  93 + profile.person? ? profile.friends.include?(user) : profile.members.include?(user)
  94 + when 'users'
  95 + user.present?
  96 + end
74 end 97 end
75 98
76 def allow_create?(user) 99 def allow_create?(user)
77 - super || can_create_topic?(user, profile) 100 + super || can_create_topic?(user)
78 end 101 end
79 end 102 end
app/models/profile.rb
@@ -392,6 +392,9 @@ class Profile &lt; ActiveRecord::Base @@ -392,6 +392,9 @@ class Profile &lt; ActiveRecord::Base
392 new_block = block.class.new(:title => block[:title]) 392 new_block = block.class.new(:title => block[:title])
393 new_block.copy_from(block) 393 new_block.copy_from(block)
394 new_box.blocks << new_block 394 new_box.blocks << new_block
  395 + if block.mirror?
  396 + block.add_observer(new_block)
  397 + end
395 end 398 end
396 end 399 end
397 end 400 end
@@ -957,11 +960,19 @@ private :generate_url, :url_options @@ -957,11 +960,19 @@ private :generate_url, :url_options
957 self.save 960 self.save
958 end 961 end
959 962
  963 + def disabled?
  964 + !visible
  965 + end
  966 +
960 def enable 967 def enable
961 self.visible = true 968 self.visible = true
962 self.save 969 self.save
963 end 970 end
964 971
  972 + def enabled?
  973 + visible
  974 + end
  975 +
965 def control_panel_settings_button 976 def control_panel_settings_button
966 {:title => _('Edit Profile'), :icon => 'edit-profile'} 977 {:title => _('Edit Profile'), :icon => 'edit-profile'}
967 end 978 end
app/models/suggest_article.rb
@@ -25,7 +25,7 @@ class SuggestArticle &lt; Task @@ -25,7 +25,7 @@ class SuggestArticle &lt; Task
25 25
26 def article_object 26 def article_object
27 if @article_object.nil? 27 if @article_object.nil?
28 - @article_object = article_type.new(article.merge({:profile => target}).except(:type)) 28 + @article_object = article_type.new(article.merge(target.present? ? {:profile => target} : {}).except(:type))
29 if requestor.present? 29 if requestor.present?
30 @article_object.author = requestor 30 @article_object.author = requestor
31 else 31 else
app/models/task.rb
@@ -239,6 +239,10 @@ class Task &lt; ActiveRecord::Base @@ -239,6 +239,10 @@ class Task &lt; ActiveRecord::Base
239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] } 239 scope :opened, :conditions => { :status => [Task::Status::ACTIVE, Task::Status::HIDDEN] }
240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } 240 scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} }
241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } 241 scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} }
  242 + scope :like, lambda { |field, value| where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value}
  243 + scope :pending_all, lambda { |profile, filter_type, filter_text|
  244 + self.to(profile).without_spam.pending.of(filter_type).like('data', filter_text)
  245 + }
242 246
243 scope :to, lambda { |profile| 247 scope :to, lambda { |profile|
244 environment_condition = nil 248 environment_condition = nil
app/views/admin_panel/index.html.erb
@@ -18,9 +18,9 @@ @@ -18,9 +18,9 @@
18 <table> 18 <table>
19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr> 19 <tr><td><%= link_to _('User roles'), :controller => 'role' %></td></tr>
20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr> 20 <tr><td><%= link_to _('Users'), :controller => 'users' %></td></tr>
  21 + <tr><td><%= link_to _('Organizations'), :controller => 'organizations' %></td></tr>
21 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr> 22 <tr><td><%= link_to _('Profile templates'), :controller => 'templates' %></td></tr>
22 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr> 23 <tr><td><%= link_to _('Fields'), :controller => 'features', :action => 'manage_fields' %></td></tr>
23 - <tr><td><%= link_to _('Manage organizations status'), :action => 'manage_organizations_status' %></td></tr>  
24 </table> 24 </table>
25 25
26 26
app/views/admin_panel/manage_organizations_status.html.erb
@@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
1 -<h1><%= _('Manage organizations') %></h1>  
2 -  
3 -<%= form_tag( { :action => 'manage_organizations_status' }, :method => 'get', :class => 'users-search' ) do %>  
4 -  
5 - <div class="search-field">  
6 - <span class="formfield">  
7 - <%= text_field_tag 'q', @q, :title => _("Find profiles"), :style=>"width:85%" %>  
8 - </span>  
9 -  
10 - <%= submit_button(:search, _('Search')) %>  
11 - </div>  
12 -  
13 - <div class="environment-users-results-header">  
14 - <div id='environment-users-filter-title'><%= @title %></div>  
15 -  
16 - <div id="environment-users-filter-filter">  
17 - <strong><%= _("Filter by: ") %></strong>  
18 -  
19 - <select id="profile_filter_select">  
20 - <%= options_for_select([['Any', 'any'],["Disabled profiles", "disabled"], ["Enabled profiles", "enabled"]], @filter) %>  
21 - </select>  
22 - </div>  
23 - <div style="clear: both"></div>  
24 - </div>  
25 -  
26 - <table>  
27 - <colgroup>  
28 - <col width="80%">  
29 - <col width="20%">  
30 - </colgroup>  
31 -  
32 - <tr>  
33 - <th><%= _('Member') %></th>  
34 - <th><%= _('Actions') %></th>  
35 - </tr>  
36 -  
37 - <% @collection.each do |p| %>  
38 - <tr title="<%= p.name %>">  
39 - <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>  
40 -  
41 - <td class='actions'>  
42 - <div class="members-buttons-cell">  
43 - <% if p.visible %>  
44 - <%= button_without_text :'deactivate-user', _('Deactivate'), {:controller => "profile_editor", :action => 'deactivate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to deactivate this profile ?") %>  
45 - <% else %>  
46 - <%= button_without_text :'activate-user', _('Activate'), {:controller => "profile_editor", :action => 'activate_profile', :profile => p.identifier, :id => p.id}, :confirm => _("Do you want to activate this profile ?") %>  
47 - <% end %>  
48 - <%= button_without_text :'delete', _('Remove'), {:controller => "profile_editor", :action => 'destroy_profile', :profile => p.identifier, :id => p.id, :return_to => "/admin/admin_panel/manage_organizations_status"}, :method => :post, :confirm => _("Do you want to deactivate this profile ?") %>  
49 - </div>  
50 - </td>  
51 - </tr>  
52 - <% end %>  
53 - </table>  
54 -  
55 -<% end %>  
56 -  
57 -<%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>  
58 -  
59 -<% button_bar do %>  
60 - <%= button :back, _('Back'), :controller => 'admin_panel' %>  
61 -<% end %>  
62 -  
63 -<script type="text/javascript">  
64 - jQuery(document).ready(function(){  
65 - jQuery("#profile_filter_select").change(function(){  
66 - document.location.href = '/admin/admin_panel/manage_organizations_status?filter='+this.value;  
67 - });  
68 - });  
69 -</script>  
70 \ No newline at end of file 0 \ No newline at end of file
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
1 -<div class='join-leave-button'> 1 +<div class='join-leave-button require-login-popup'>
2 <% if logged_in? %> 2 <% if logged_in? %>
3 <% if profile.members.include?(user) %> 3 <% if profile.members.include?(user) %>
4 <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, 4 <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url,
app/views/box_organizer/edit.html.erb
@@ -25,6 +25,11 @@ @@ -25,6 +25,11 @@
25 </div> 25 </div>
26 <div class="move-modes"> 26 <div class="move-modes">
27 <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %> 27 <%= labelled_form_field _('Move options:'), select_tag('block[move_modes]', options_from_collection_for_select(@block.move_block_options, :first, :last, @block.move_modes)) %>
  28 + <% end %>
  29 +
  30 + <% if @block.owner.kind_of?(Profile) && @block.owner.is_template? %>
  31 + <div class="mirror_block">
  32 + <%= labelled_check_box(_("Mirror"), "block[mirror]", value = "1", checked = @block.mirror) %>
28 </div> 33 </div>
29 <% end %> 34 <% end %>
30 35
app/views/cms/_forum.html.erb
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 <h1><%= _('My Forum') %></h1> 3 <h1><%= _('My Forum') %></h1>
4 4
  5 +<%= required_fields_message %>
  6 +
5 <%= render :file => 'shared/tiny_mce' %> 7 <%= render :file => 'shared/tiny_mce' %>
6 8
7 <%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %> 9 <%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %>
app/views/content_viewer/_article_toolbar.html.erb
1 <div<%= user && " class='logged-in'" %>> 1 <div<%= user && " class='logged-in'" %>>
2 <div id="article-actions"> 2 <div id="article-actions">
3 3
  4 + <%= fullscreen_buttons('#article') %>
4 5
5 <% if @page.allow_edit?(user) && !remove_content_button(:edit, @page) %> 6 <% if @page.allow_edit?(user) && !remove_content_button(:edit, @page) %>
6 <% content = content_tag('span', label_for_edit_article(@page)) %> 7 <% content = content_tag('span', label_for_edit_article(@page)) %>
@@ -29,6 +30,10 @@ @@ -29,6 +30,10 @@
29 <% end %> 30 <% end %>
30 31
31 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> 32 <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %>
  33 +
  34 + <% content = content_tag('span', label_for_clone_article(@page)) %>
  35 + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %>
  36 + <%= expirable_button @page, :clone, content, url %>
32 <% end %> 37 <% end %>
33 38
34 <% if @page.accept_uploads? && @page.allow_create?(user) %> 39 <% if @page.accept_uploads? && @page.allow_create?(user) %>
app/views/organizations/_results.html.erb 0 → 100644
@@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
  1 +<div class='results'>
  2 + <table id='organizations-list'>
  3 + <colgroup>
  4 + <col width="60%">
  5 + <col width="20%">
  6 + <col width="20%">
  7 + </colgroup>
  8 +
  9 + <tr>
  10 + <th><%= _('Profile') %></th>
  11 + <th><%= _('Actions') %></th>
  12 + <th><%= _('Type') %>
  13 +
  14 + <%= select_tag(:type, options_for_select(@types_filter, @type)) %>
  15 + </th>
  16 + </tr>
  17 +
  18 + <% @collection.each do |p| %>
  19 + <tr title="<%= p.name %>">
  20 + <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  21 +
  22 + <td class='actions'>
  23 + <div class="members-buttons-cell">
  24 + <% if p.visible %>
  25 + <%= button_without_text :'deactivate-user', _('Deactivate'), {:action => 'deactivate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to deactivate this organization?") %>
  26 + <% else %>
  27 + <%= button_without_text :'activate-user', _('Activate'), {:action => 'activate', :id => p.id}, :class => 'action', 'data-confirm' => _("Do you want to activate this organization?") %>
  28 + <% end %>
  29 + <%= button_without_text :'delete', _('Remove'), {:action => 'destroy', :id => p.id}, :class => 'action', 'data-method' => :post, 'data-confirm' => _("Do you want to destroy this organization?") %>
  30 + </div>
  31 + </td>
  32 +
  33 + <td> <%= _("#{p.type}") %> </td>
  34 + </tr>
  35 + <% end %>
  36 + </table>
  37 +
  38 + <div>
  39 + <%= pagination_links @collection, {:param_name => 'npage', :page_links => true} %>
  40 + </div>
  41 +</div>
app/views/organizations/index.html.erb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +<h1><%= _('Organizations') %></h1>
  2 +
  3 +<%= form_tag( { :action => 'index' }, :method => 'get', :id => 'manage-profiles' ) do %>
  4 +
  5 + <div class="search-field">
  6 + <span class="formfield">
  7 + <%= text_field_tag 'q', @q, :title => _('Find organizations'), :style=>"width:85%" %>
  8 + </span>
  9 +
  10 + <%= submit_button(:search, _('Search')) %>
  11 + </div>
  12 +
  13 + <div class="environment-profiles-results-header">
  14 + <div id='environment-profiles-filter-title'><%= @title %></div>
  15 +
  16 + <div id="environment-profiles-filter-filter">
  17 + <strong><%= _("Filter by: ") %></strong>
  18 + <%= select_tag(:filter, options_for_select([[_('Any'), 'any'],[_('Disabled'), "disabled"], [_('Enabled') , "enabled"]], @filter)) %>
  19 + </div>
  20 + <div style="clear: both"></div>
  21 + </div>
  22 +
  23 + <%= render :partial => 'results' %>
  24 +
  25 + <% button_bar do %>
  26 + <%= button :back, _('Back'), :controller => 'admin_panel' %>
  27 + <% end %>
  28 +<% end %>
  29 +
  30 +<%= javascript_include_tag 'manage-organizations' %>
app/views/organizations/index.js.erb 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +../../views/shared/admin/profiles/index.js.rb
0 \ No newline at end of file 2 \ No newline at end of file
app/views/shared/admin/profiles/index.js.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +jQuery('#manage-profiles .results').replaceWith('<%= escape_javascript(render 'results') %>');
app/views/tasks/_task.html.erb
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 %> 22 %>
23 </div><!-- class="task_decisions" --> 23 </div><!-- class="task_decisions" -->
24 24
  25 + <div class="task_date"><%= show_time(task.created_at) %></div>
  26 +
25 <%= render :partial => 'task_title', :locals => {:task => task} %> 27 <%= render :partial => 'task_title', :locals => {:task => task} %>
26 28
27 <div class="task_information"> 29 <div class="task_information">
app/views/tasks/index.html.erb
@@ -21,11 +21,24 @@ @@ -21,11 +21,24 @@
21 </div> 21 </div>
22 <% end %> 22 <% end %>
23 23
  24 +<%= form_tag '#', :method => 'get' do %>
  25 + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %>
  26 + <p>
  27 + <%= labelled_select(_('Type of task')+': ', :filter_type, :first, :last, @filter_type, type_collection, {:id => 'filter-type'}) %>
  28 + </p>
  29 + <p>
  30 + <%= labelled_text_field(_("Text filter")+': ', :filter_text, nil, {:id => 'filter-text',:value => @filter_text}) %>
  31 + </p>
  32 + <p>
  33 + <%= submit_button(:search, _('Search')) %>
  34 + </p>
  35 + <% end %>
  36 +<% end %>
  37 +
24 <% if @tasks.empty? %> 38 <% if @tasks.empty? %>
25 <p> 39 <p>
26 - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value")%> 40 + <em><%= _('No pending tasks for %s') % profile.name %></em>
27 </p> 41 </p>
28 - <em><%= _('No pending tasks for %s') % profile.name %></em>  
29 <% else %> 42 <% else %>
30 <%= form_tag :action => 'close' do%> 43 <%= form_tag :action => 'close' do%>
31 <% button_bar do %> 44 <% button_bar do %>
@@ -38,14 +51,12 @@ @@ -38,14 +51,12 @@
38 51
39 <ul class='task-list'> 52 <ul class='task-list'>
40 <p> 53 <p>
41 - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value") %>  
42 - </p>  
43 - <p>  
44 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %> 54 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
45 </p> 55 </p>
46 - <% @tasks.each do |task| %>  
47 - <%= render :partial => 'task', :locals => { :task => task } %>  
48 - <% end %> 56 +
  57 + <div class="task_boxes">
  58 + <%= render :partial => 'task', :collection => @tasks %>
  59 + </div>
49 <p> 60 <p>
50 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %> 61 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "down-set-all-tasks-to") %>
51 </p> 62 </p>
app/views/users/_users_list.html.erb
1 -<div class="environment-users-results-header">  
2 - <div id='environment-users-filter-title'><%= users_filter_title(@filter) %></div> 1 +<div class="environment-profiles-results-header">
  2 + <div id='environment-profiles-filter-title'><%= users_filter_title(@filter) %></div>
3 <%= filter_selector(@filter) %> 3 <%= filter_selector(@filter) %>
4 <div style="clear: both"></div> 4 <div style="clear: both"></div>
5 </div> 5 </div>
db/migrate/20150319114233_change_default_content_privacy.rb 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +class ChangeDefaultContentPrivacy < ActiveRecord::Migration
  2 + def up
  3 + update_sql('UPDATE articles SET published = (1>2), show_to_followers = (1=1)
  4 + FROM profiles WHERE articles.profile_id = profiles.id AND
  5 + NOT profiles.public_profile AND articles.published = (1=1)')
  6 +
  7 + Block.select('blocks.*').joins("INNER JOIN boxes ON blocks.box_id = boxes.id
  8 + INNER JOIN profiles ON boxes.owner_id = profiles.id AND boxes.owner_type = 'Profile'").
  9 + where("NOT profiles.public_profile AND blocks.type != 'MainBlock'").find_each do |block|
  10 + block.display_user = 'followers'
  11 + block.save
  12 + end
  13 + change_column :articles, :show_to_followers, :boolean, :default => true
  14 + end
  15 +
  16 + def down
  17 + say "this migration can't be reverted"
  18 + end
  19 +end
db/migrate/20150429145001_add_mirror_to_block.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class AddMirrorToBlock < ActiveRecord::Migration
  2 + def up
  3 + change_table :blocks do |t|
  4 + t.boolean :mirror, :default => false
  5 + t.references :mirror_block
  6 + t.references :observers
  7 + end
  8 + end
  9 +
  10 + def down
  11 + remove_column :blocks, :mirror
  12 + remove_column :blocks, :mirror_block_id
  13 + remove_column :blocks, :observers_id
  14 + end
  15 +end
db/migrate/20150513213939_update_topic_creation_configuration.rb 0 → 100644
@@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
  1 +class UpdateTopicCreationConfiguration < ActiveRecord::Migration
  2 + def up
  3 + Forum.where("setting LIKE '%:allows_members_to_create_topics: true%'").find_each do |forum|
  4 + forum.setting.delete(:allows_members_to_create_topics)
  5 + forum.setting.merge!(:topic_creation => 'related')
  6 + forum.save
  7 + end
  8 + end
  9 +
  10 + def down
  11 + say "this migration can't be reverted"
  12 + end
  13 +end
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 # 11 #
12 # It's strongly recommended to check this file into your version control system. 12 # It's strongly recommended to check this file into your version control system.
13 13
14 -ActiveRecord::Schema.define(:version => 20150408231524) do 14 +ActiveRecord::Schema.define(:version => 20150513213939) do
15 15
16 create_table "abuse_reports", :force => true do |t| 16 create_table "abuse_reports", :force => true do |t|
17 t.integer "reporter_id" 17 t.integer "reporter_id"
@@ -150,7 +150,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do @@ -150,7 +150,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
150 t.integer "spam_comments_count", :default => 0 150 t.integer "spam_comments_count", :default => 0
151 t.integer "author_id" 151 t.integer "author_id"
152 t.integer "created_by_id" 152 t.integer "created_by_id"
153 - t.boolean "show_to_followers", :default => false 153 + t.boolean "show_to_followers", :default => true
154 end 154 end
155 155
156 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count" 156 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
@@ -183,10 +183,13 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do @@ -183,10 +183,13 @@ ActiveRecord::Schema.define(:version =&gt; 20150408231524) do
183 t.string "type" 183 t.string "type"
184 t.text "settings" 184 t.text "settings"
185 t.integer "position" 185 t.integer "position"
186 - t.boolean "enabled", :default => true 186 + t.boolean "enabled", :default => true
187 t.datetime "created_at" 187 t.datetime "created_at"
188 t.datetime "updated_at" 188 t.datetime "updated_at"
189 t.datetime "fetched_at" 189 t.datetime "fetched_at"
  190 + t.boolean "mirror", :default => false
  191 + t.integer "mirror_block_id"
  192 + t.integer "observers_id"
190 end 193 end
191 194
192 add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id" 195 add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id"
db/seeds.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +# This file should contain all the record creation needed to seed the database with its default values.
  2 +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
  3 +#
  4 +# Examples:
  5 +#
  6 +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
  7 +# Mayor.create(name: 'Emanuel', city: cities.first)
  8 +
  9 +ENV['RAILS_ENV'] ||= 'development'
  10 +
  11 +# This is for plugins that wants to use seeds.rb
  12 +# Check for example on the Foo plugin
  13 +plugin_seed_dirs = Dir.glob(Rails.root.join('{baseplugins,config/plugins}', '*', 'db', 'seeds.rb'))
  14 +plugin_seed_dirs.each { |path| load path }
debian/apache2/conf.d/noosfero-chat 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +<IfModule mpm_worker_module>
  2 + StartServers 8
  3 + MinSpareThreads 25
  4 + MaxSpareThreads 75
  5 + ThreadLimit 128
  6 + ThreadsPerChild 128
  7 + MaxClients 2048
  8 + MaxRequestsPerChild 0
  9 +</IfModule>
debian/changelog
1 -noosfero (1.2~0) UNRELEASED; urgency=medium 1 +noosfero (1.2~1) UNRELEASED; urgency=medium
2 2
  3 + [ Antonio Terceiro ]
3 * Temporary version in heavy development 4 * Temporary version in heavy development
4 5
5 - -- Antonio Terceiro <terceiro@debian.org> Fri, 08 May 2015 16:08:18 -0300 6 + [ Joenio Costa ]
  7 + * Build noosfero-chat package
  8 +
  9 + -- Joenio Costa <joenio@colivre.coop.br> Mon, 18 May 2015 14:32:21 -0300
6 10
7 noosfero (1.1) wheezy; urgency=low 11 noosfero (1.1) wheezy; urgency=low
8 12
debian/control
@@ -85,3 +85,14 @@ Description: free web-based platform for social networks (apache frontend) @@ -85,3 +85,14 @@ Description: free web-based platform for social networks (apache frontend)
85 . 85 .
86 This package contains the configuration files needed to run Noosfero with the 86 This package contains the configuration files needed to run Noosfero with the
87 Apache HTTPD server as frontend. 87 Apache HTTPD server as frontend.
  88 +
  89 +Package: noosfero-chat
  90 +Architecture: all
  91 +Depends: noosfero (>= 1.2), ejabberd, odbc-postgresql, pidgin-data
  92 +Description: free web-based platform for social networks (ejabberd based chat)
  93 + Noosfero is a web platform for social and solidarity economy networks with
  94 + blog, e-Porfolios, CMS, RSS, thematic discussion, events agenda and collective
  95 + inteligence for solidarity economy in the same system.
  96 + .
  97 + This package contains the configuration files needed to run Noosfero with the
  98 + Ejabberd XMPP chat server.
debian/default/noosfero-chat 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +POLL=true
  2 +SMP=auto
debian/noosfero-chat.install 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +debian/default/noosfero-chat etc/default
  2 +util/chat/ejabberd.cfg etc/ejabberd
  3 +debian/update-noosfero-odbc usr/sbin
  4 +etc/security/limits.d/noosfero-chat.conf etc/security/limits.d
  5 +etc/pam.d/noosfero-chat etc/pam.d
  6 +debian/apache2/conf.d/noosfero-chat etc/apache2/conf.d
debian/noosfero-chat.postinst 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +#!/bin/bash
  2 +
  3 +set -e
  4 +
  5 +. /usr/share/debconf/confmodule
  6 +
  7 +echo -n "Fetching noosfero domain ..."
  8 +domain=$(noosfero-runner 'puts Environment.default.default_hostname(true)')
  9 +echo " [domain = $domain]"
  10 +
  11 +ejabberd_config='/etc/ejabberd/ejabberd.cfg'
  12 +if test -f $ejabberd_config; then
  13 + sed -i "s/acl, *\([^,]*\), *{user, *\([^,]*\), *[^}]*/acl, \1, {user, \2, \"$domain\"/" /etc/ejabberd/ejabberd.cfg
  14 + sed -i "s/hosts, *\[[^]]*/hosts, [\"$domain\"/" /etc/ejabberd/ejabberd.cfg
  15 +fi
  16 +
  17 +echo -n 'Fetching noosfero database name ...'
  18 +noosfero_database=$(noosfero-runner 'puts Environment.connection_config[:database]')
  19 +echo " [database = $noosfero_database]"
  20 +
  21 +echo 'Creating ejabberd schema ...'
  22 +. /etc/default/noosfero
  23 +noosfero_user="$NOOSFERO_USER"
  24 +su - postgres -c "psql -c 'GRANT CREATE ON DATABASE $noosfero_database TO $noosfero_user;' > /dev/null"
  25 +su - $noosfero_user -c 'rails dbconsole production < /usr/share/noosfero/util/chat/postgresql/ejabberd.sql > /dev/null'
  26 +
  27 +if which update-noosfero-odbc > /dev/null ; then
  28 + update-noosfero-odbc
  29 +fi
  30 +
  31 +ejabberd_default='/etc/default/ejabberd'
  32 +noosfero_chat_default='/etc/default/noosfero-chat'
  33 +if test -f $ejabberd_default; then
  34 + if ! cat $ejabberd_default | grep "^\. $noosfero_chat_default" > /dev/null ; then
  35 + echo 'Extending ejabberd defaults with noosfero-chat defaults ...'
  36 + echo ". $noosfero_chat_default" >> $ejabberd_default
  37 + fi
  38 +fi
  39 +
  40 +a2enmod proxy_http
  41 +
  42 +invoke-rc.d ejabberd restart
  43 +invoke-rc.d noosfero restart
  44 +invoke-rc.d apache2 restart
  45 +
  46 +# stop debconf to avoid the problem with infinite hanging, cfe
  47 +# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=295477
  48 +db_stop
  49 +
  50 +#DEBHELPER#
debian/noosfero-runner 0 → 100755
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +#!/bin/sh
  2 +
  3 +set -e
  4 +
  5 +environment="$2"
  6 +test -z "$environment" && environment=production
  7 +
  8 +su - noosfero -c "rails runner -e $environment '$1'"
debian/noosfero.install
@@ -17,6 +17,7 @@ debian/dbupgrade usr/lib/noosfero @@ -17,6 +17,7 @@ debian/dbupgrade usr/lib/noosfero
17 debian/default/noosfero etc/default 17 debian/default/noosfero etc/default
18 debian/noosfero-check-dbconfig usr/sbin 18 debian/noosfero-check-dbconfig usr/sbin
19 debian/noosfero-console usr/sbin 19 debian/noosfero-console usr/sbin
  20 +debian/noosfero-runner usr/sbin
20 debian/noosfero.yml etc/noosfero 21 debian/noosfero.yml etc/noosfero
21 debian/thin.yml etc/noosfero 22 debian/thin.yml etc/noosfero
22 doc usr/share/noosfero 23 doc usr/share/noosfero
debian/update-noosfero-odbc 0 → 100755
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +#!/bin/sh
  2 +
  3 +set -e
  4 +
  5 +# automatically update configuration, but if package noosfero is also installed
  6 +if test -x /usr/share/noosfero/script/odbcconf; then
  7 + config_file="/etc/odbc.ini"
  8 + if test -e "$config_file"; then
  9 + echo "Overwriting $config_file ..."
  10 + fi
  11 + /usr/share/noosfero/script/odbcconf > "$config_file"
  12 +
  13 + echo 'Noosfero ODBC configuration updated.'
  14 +fi
etc/pam.d/noosfero-chat 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +session required pam_limits.so
etc/security/limits.d/noosfero-chat.conf 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +ejabberd hard nofile 65536
  2 +ejabberd soft nofile 65536
features/article_versioning.feature
@@ -80,8 +80,8 @@ Feature: article versioning @@ -80,8 +80,8 @@ Feature: article versioning
80 80
81 Scenario: deny access to specific version when disabled, private and not logged 81 Scenario: deny access to specific version when disabled, private and not logged
82 Given the article "Edited Article" is updated with 82 Given the article "Edited Article" is updated with
83 - | display_versions | published |  
84 - | false | false | 83 + | display_versions | published | show_to_followers |
  84 + | false | false | false |
85 And I am not logged in 85 And I am not logged in
86 And I go to /joaosilva/edited-article?version=1 86 And I go to /joaosilva/edited-article?version=1
87 Then I should see "Access denied" 87 Then I should see "Access denied"
features/edit_article.feature
@@ -41,6 +41,7 @@ Feature: edit article @@ -41,6 +41,7 @@ Feature: edit article
41 When I follow "Folder" 41 When I follow "Folder"
42 And I fill in "Title" with "My Folder" 42 And I fill in "Title" with "My Folder"
43 And I choose "article_published_false" 43 And I choose "article_published_false"
  44 + And I uncheck "article_show_to_followers"
44 And I press "Save" 45 And I press "Save"
45 And I log off 46 And I log off
46 And I go to /freesoftware/my-folder 47 And I go to /freesoftware/my-folder
@@ -87,6 +88,7 @@ Feature: edit article @@ -87,6 +88,7 @@ Feature: edit article
87 When I follow "Folder" 88 When I follow "Folder"
88 And I fill in "Title" with "My Folder" 89 And I fill in "Title" with "My Folder"
89 And I choose "article_published_false" 90 And I choose "article_published_false"
  91 + And I uncheck "article_show_to_followers"
90 Then I should see "Fill in the search field to add the exception users to see this content" 92 Then I should see "Fill in the search field to add the exception users to see this content"
91 93
92 @selenium 94 @selenium
features/forum.feature
@@ -169,124 +169,3 @@ Feature: forum @@ -169,124 +169,3 @@ Feature: forum
169 | Post one | joaosilva | Hi all | Hi all | 169 | Post one | joaosilva | Hi all | Hi all |
170 When I go to /joaosilva/forum 170 When I go to /joaosilva/forum
171 Then I should see "Joao Silva" within ".forum-post-last-answer" 171 Then I should see "Joao Silva" within ".forum-post-last-answer"
172 -  
173 - @selenium  
174 - Scenario: community member should be able to see the discussion topic button  
175 - Given the following community  
176 - | identifier | name | owner |  
177 - | sample-community | Sample Community | joaosilva |  
178 - And the following forums  
179 - | owner | name |  
180 - | sample-community | Forum |  
181 - And the following users  
182 - | login | name |  
183 - | mariasilva | Maria Silva|  
184 - And "Maria Silva" is a member of "Sample Community"  
185 - And I am logged in as "joaosilva"  
186 - When I go to /sample-community/forum  
187 - And I follow "Configure forum"  
188 - And I check "Allow members to create topics"  
189 - And I press "Save"  
190 - And I am logged in as "mariasilva"  
191 - And I go to /sample-community/forum  
192 - Then I should see "New discussion topic"  
193 -  
194 - @selenium  
195 - Scenario: a non community member should not be able to see the discussion topic button  
196 - Given the following community  
197 - | identifier | name | owner |  
198 - | sample-community | Sample Community | joaosilva |  
199 - And the following forums  
200 - | owner | name |  
201 - | sample-community | Forum |  
202 - And the following users  
203 - | login | name |  
204 - | mariasilva | Maria Silva|  
205 - And I am logged in as "joaosilva"  
206 - When I go to /sample-community/forum  
207 - And I follow "Configure forum"  
208 - And I check "Allow members to create topics"  
209 - And I press "Save"  
210 - And I am logged in as "mariasilva"  
211 - And I go to /sample-community/forum  
212 - Then I should not see "New discussion topic"  
213 -  
214 - @selenium  
215 - Scenario: community member should not be able to see the discussion topic button  
216 - Given the following community  
217 - | identifier | name | owner |  
218 - | sample-community | Sample Community | joaosilva |  
219 - And the following forums  
220 - | owner | name |  
221 - | sample-community | Forum |  
222 - And the following users  
223 - | login | name |  
224 - | mariasilva | Maria Silva|  
225 - And "Maria Silva" is a member of "Sample Community"  
226 - And I am logged in as "joaosilva"  
227 - When I go to /sample-community/forum  
228 - And I follow "Configure forum"  
229 - And I uncheck "Allow members to create topics"  
230 - And I press "Save"  
231 - And I am logged in as "mariasilva"  
232 - And I go to /sample-community/forum  
233 - Then I should not see "New discussion topic"  
234 -  
235 - @selenium  
236 - Scenario: community member should be able to create a topic with the discussion topic button  
237 - Given the following community  
238 - | identifier | name | owner |  
239 - | sample-community | Sample Community | joaosilva |  
240 - And the following forums  
241 - | owner | name |  
242 - | sample-community | Forum |  
243 - And the following users  
244 - | login | name |  
245 - | mariasilva | Maria Silva|  
246 - And "Maria Silva" is a member of "Sample Community"  
247 - And I am logged in as "joaosilva"  
248 - When I go to /sample-community/forum  
249 - And I follow "Configure forum"  
250 - And I check "Allow members to create topics"  
251 - And I press "Save"  
252 - And I am logged in as "mariasilva"  
253 - And I go to /sample-community/forum  
254 - And I follow "New discussion topic"  
255 - And I should see "Text article with visual editor"  
256 - And I follow "Text article with visual editor"  
257 - And I fill in "Title" with "Test"  
258 - And I press "Save"  
259 - Then I should see "Test"  
260 -  
261 - @selenium  
262 - Scenario: community member should be able to create a topic on a topic page  
263 - Given the following community  
264 - | identifier | name | owner |  
265 - | sample-community | Sample Community | joaosilva |  
266 - And the following forums  
267 - | owner | name |  
268 - | sample-community | Forum |  
269 - And the following users  
270 - | login | name |  
271 - | mariasilva | Maria Silva|  
272 - And "Maria Silva" is a member of "Sample Community"  
273 - And I am logged in as "joaosilva"  
274 - When I go to /sample-community/forum  
275 - And I follow "Configure forum"  
276 - And I check "Allow members to create topics"  
277 - And I press "Save"  
278 - And I am logged in as "mariasilva"  
279 - And I go to /sample-community/forum  
280 - And I follow "New discussion topic"  
281 - And I should see "Text article with visual editor"  
282 - And I follow "Text article with visual editor"  
283 - And I fill in "Title" with "Test"  
284 - And I press "Save"  
285 - And I go to /sample-community/forum/test  
286 - And I follow "New discussion topic"  
287 - And I should see "Text article with visual editor"  
288 - And I follow "Text article with visual editor"  
289 - And I fill in "Title" with "Test inside the topic page"  
290 - And I press "Save"  
291 - And I go to /sample-community/forum  
292 - Then I should see "Test inside the topic page"  
features/secret_community.feature
@@ -33,7 +33,7 @@ Feature: Use a secret community @@ -33,7 +33,7 @@ Feature: Use a secret community
33 Scenario: Non members shouldn't see secret communit's content 33 Scenario: Non members shouldn't see secret communit's content
34 Given I am logged in as "maria" 34 Given I am logged in as "maria"
35 And I go to mycommunity's homepage 35 And I go to mycommunity's homepage
36 - And I should see "Access denied" 36 + And I should see "Oops ... you cannot go ahead here"
37 And I follow "Communities" 37 And I follow "Communities"
38 Then I should not see "My Community" 38 Then I should not see "My Community"
39 39
features/template_block_management.feature 0 → 100644
@@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
  1 +Feature: user template
  2 + As an user
  3 + I want to create templates with mirror blocks
  4 + In order to keep these blocks always updated
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name | is_template |
  9 + | person | person | true |
  10 + And the following blocks
  11 + | owner | type | mirror |
  12 + | person | ArticleBlock | true |
  13 + | person | RawHTMLBlock | false |
  14 + And I go to /account/signup
  15 + And I fill in "Username" with "mario"
  16 + And I fill in "Password" with "123456"
  17 + And I fill in "Password confirmation" with "123456"
  18 + And I fill in "e-Mail" with "mario@mario.com"
  19 + And I fill in "Full name" with "Mario"
  20 + And wait for the captcha signup time
  21 + And I press "Create my account"
  22 + And I am logged in as admin
  23 +
  24 + @selenium
  25 + Scenario: The block Article name is changed
  26 + Given I am on person's control panel
  27 + And I follow "Edit sideboxes"
  28 + And display ".button-bar"
  29 + And I follow "Edit" within ".article-block"
  30 + And I fill in "Custom title for this block:" with "Mirror"
  31 + And I press "Save"
  32 + And I go to /profile/mario
  33 + Then I should see "Mirror"
  34 +
  35 + @selenium
  36 + Scenario: The block LinkList is changed but the user's block doesnt change
  37 + Given I am on person's control panel
  38 + And I follow "Edit sideboxes"
  39 + And display ".button-bar"
  40 + And I follow "Edit" within ".raw-html-block"
  41 + And I fill in "Custom title for this block:" with "Raw HTML Block"
  42 + And I press "Save"
  43 + And I go to /profile/mario
  44 + Then I should not see "Raw HTML Block"
  45 +
  46 + @selenium
  47 + Scenario: The block Article cannot move or modify
  48 + Given I am on person's control panel
  49 + And I follow "Edit sideboxes"
  50 + And display ".button-bar"
  51 + And I follow "Edit" within ".article-block"
  52 + And I select "Cannot be moved" from "Move options:"
  53 + And I select "Cannot be modified" from "Edit options:"
  54 + And I press "Save"
  55 + And I follow "Logout"
  56 + And Mario's account is activated
  57 + And I follow "Login"
  58 + And I fill in "Username / Email" with "mario"
  59 + And I fill in "Password" with "123456"
  60 + And I press "Log in"
  61 + And I go to /myprofile/mario
  62 + And I follow "Edit sideboxes"
  63 + And display ".button-bar"
  64 + Then I should not see "Edit" within ".article-block"
lib/authenticated_system.rb
@@ -60,7 +60,11 @@ module AuthenticatedSystem @@ -60,7 +60,11 @@ module AuthenticatedSystem
60 if logged_in? && authorized? 60 if logged_in? && authorized?
61 true 61 true
62 else 62 else
63 - access_denied 63 + if params[:require_login_popup]
  64 + render :json => { :require_login_popup => true }
  65 + else
  66 + access_denied
  67 + end
64 end 68 end
65 end 69 end
66 70
lib/noosfero/plugin.rb
@@ -299,6 +299,18 @@ class Noosfero::Plugin @@ -299,6 +299,18 @@ class Noosfero::Plugin
299 nil 299 nil
300 end 300 end
301 301
  302 + # -> Filters the types of organizations that are shown on manage organizations
  303 + # returns a scope filtered by the specified type
  304 + def filter_manage_organization_scope type
  305 + nil
  306 + end
  307 +
  308 + # -> Add new options for manage organization filters
  309 + # returns an array of new options
  310 + # i.e [[_('Type'), 'type'], [_('Type2'), 'type2']]
  311 + def organization_types_filter_options
  312 + nil
  313 + end
302 # -> Adds content to profile editor info and settings 314 # -> Adds content to profile editor info and settings
303 # returns = lambda block that creates html code or raw rhtml/html.erb 315 # returns = lambda block that creates html code or raw rhtml/html.erb
304 def profile_editor_extras 316 def profile_editor_extras
lib/tasks/enable_plugins.rake 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +namespace :noosfero do
  2 + namespace :plugins do
  3 + task :enable_all => :environment do
  4 + Environment.all.each do |env|
  5 + puts "Plugins Activated on #{env.name}" if env.enable_all_plugins
  6 + end
  7 + end
  8 + end
  9 +end
plugins/foo/db/seeds.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +# This file should contain all the record creation needed to seed the database with its default values.
  2 +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
  3 +#
  4 +# Examples:
  5 +#
  6 +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
  7 +# Mayor.create(name: 'Emanuel', city: cities.first)
  8 +
  9 +FooPlugin::Bar.create()
plugins/require_auth_to_comment/controllers/require_auth_to_comment_plugin_admin_controller.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +class RequireAuthToCommentPluginAdminController < AdminController
  2 +
  3 + def index
  4 + settings = params[:settings]
  5 + settings ||= {}
  6 + @settings = Noosfero::Plugin::Settings.new(environment, RequireAuthToCommentPlugin, settings)
  7 + if request.post?
  8 + @settings.save!
  9 + session[:notice] = 'Settings succefully saved.'
  10 + redirect_to :action => 'index'
  11 + end
  12 + end
  13 +
  14 +end
plugins/require_auth_to_comment/lib/require_auth_to_comment_plugin.rb
@@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin &lt; Noosfero::Plugin @@ -21,11 +21,20 @@ class RequireAuthToCommentPlugin &lt; Noosfero::Plugin
21 end 21 end
22 22
23 def stylesheet? 23 def stylesheet?
24 - true 24 + !display_login_popup?
  25 + end
  26 +
  27 + def display_login_popup?
  28 + settings = Noosfero::Plugin::Settings.new(context.environment, self.class)
  29 + settings.require_type == 'display_login_popup'
  30 + end
  31 +
  32 + def self.require_type_default_setting
  33 + 'hide_button'
25 end 34 end
26 35
27 def js_files 36 def js_files
28 - ['hide_comment_form.js', 'jquery.livequery.min.js'] 37 + ['hide_comment_form.js', 'jquery.livequery.min.js'] + (display_login_popup? ? ['comment_require_login.js'] : [])
29 end 38 end
30 39
31 def body_beginning 40 def body_beginning
plugins/require_auth_to_comment/public/comment_require_login.js 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +(function($) {
  2 + $(window).bind('userDataLoaded', function(event, data) {
  3 + if (!data.login && $('meta[name="profile.allow_unauthenticated_comments"]').length <= 0) {
  4 + $('.display-comment-form').unbind();
  5 + $('.display-comment-form').addClass('require-login-popup');
  6 + }
  7 + });
  8 +})(jQuery);
plugins/require_auth_to_comment/test/unit/require_auth_to_comment_plugin_test.rb
@@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase @@ -5,9 +5,10 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase
5 def setup 5 def setup
6 @plugin = RequireAuthToCommentPlugin.new 6 @plugin = RequireAuthToCommentPlugin.new
7 @comment = Comment.new 7 @comment = Comment.new
  8 + @environment = fast_create(Environment)
8 end 9 end
9 10
10 - attr_reader :plugin, :comment 11 + attr_reader :plugin, :comment, :environment
11 12
12 should 'reject comments for unauthenticated users' do 13 should 'reject comments for unauthenticated users' do
13 plugin.context = logged_in(false) 14 plugin.context = logged_in(false)
@@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase @@ -29,6 +30,35 @@ class RequireAuthToCommentPluginTest &lt; ActiveSupport::TestCase
29 assert !comment.rejected? 30 assert !comment.rejected?
30 end 31 end
31 32
  33 + should 'the default require type setting be hide_button' do
  34 + assert_equal 'hide_button', plugin.class.require_type_default_setting
  35 + end
  36 +
  37 + should 'display_login_popup? be false by default' do
  38 + context = mock();
  39 + context.expects(:environment).returns(environment)
  40 + plugin.expects(:context).returns(context)
  41 + assert !plugin.display_login_popup?
  42 + end
  43 +
  44 + should 'display_login_popup? be true if require_type is defined as display_login_popup' do
  45 + context = mock();
  46 + context.expects(:environment).returns(environment)
  47 + environment[:settings] = {:require_auth_to_comment_plugin => {:require_type => "display_login_popup"}}
  48 + plugin.expects(:context).returns(context)
  49 + assert plugin.display_login_popup?
  50 + end
  51 +
  52 + should 'not display stylesheet if login popup is active' do
  53 + plugin.expects(:display_login_popup?).returns(true)
  54 + assert !plugin.stylesheet?
  55 + end
  56 +
  57 + should 'display stylesheet if login popup is inactive' do
  58 + plugin.expects(:display_login_popup?).returns(false)
  59 + assert plugin.stylesheet?
  60 + end
  61 +
32 protected 62 protected
33 63
34 def logged_in(boolean) 64 def logged_in(boolean)
plugins/require_auth_to_comment/views/require_auth_to_comment_plugin_admin/index.html.erb 0 → 100644
@@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@
  1 +<h1><%= _('Require auth to comment Settings')%></h1>
  2 +
  3 +<%= form_for(:settings) do |f| %>
  4 +
  5 + <div class="require-type">
  6 + <strong>
  7 + <div class="hide-button">
  8 + <%= radio_button(:settings, :require_type, 'hide_button') %> <%= _('Hide button') %>
  9 + </div>
  10 + <div class="display-login-popup">
  11 + <%= radio_button(:settings, :require_type, 'display_login_popup') %> <%= _('Display login popup') %>
  12 + </div>
  13 + </strong>
  14 + </div>
  15 +
  16 + <% button_bar do %>
  17 + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
  18 + <% end %>
  19 +
  20 +<% end %>
plugins/tolerance_time/lib/tolerance_time_plugin.rb
@@ -56,9 +56,18 @@ class ToleranceTimePlugin &lt; Noosfero::Plugin @@ -56,9 +56,18 @@ class ToleranceTimePlugin &lt; Noosfero::Plugin
56 end 56 end
57 57
58 def content_expire_edit(content) 58 def content_expire_edit(content)
  59 + content_expire_for(content, _('editing'))
  60 + end
  61 +
  62 + def content_expire_clone(content)
  63 + content_expire_for(content, _('cloning'))
  64 + end
  65 +
  66 + private
  67 +
  68 + def content_expire_for(content, action)
59 if ToleranceTimePlugin.expired?(content) 69 if ToleranceTimePlugin.expired?(content)
60 - _('The tolerance time for editing this content is over.') 70 + _('The tolerance time for %s this content is over.') % action
61 end 71 end
62 end 72 end
63 -  
64 end 73 end
plugins/vote/public/style.css
1 .vote-actions { 1 .vote-actions {
2 - position: absolute;  
3 top: 40px; 2 top: 40px;
4 right: 0px; 3 right: 0px;
5 } 4 }
plugins/vote/views/vote/_vote.html.erb
@@ -5,7 +5,7 @@ reload_url = url_for(:controller =&gt; &#39;vote_plugin_profile&#39;, :profile =&gt; profile.i @@ -5,7 +5,7 @@ reload_url = url_for(:controller =&gt; &#39;vote_plugin_profile&#39;, :profile =&gt; profile.i
5 5
6 <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action"> 6 <span id="vote_<%= model %>_<%= target.id %>_<%= vote %>" data-reload_url=<%= reload_url %> class="vote-action action <%= action %>-action">
7 7
8 - <%= link_to_remote content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), :url => url, :html => {:class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'}"} %> 8 + <%= link_to content_tag(:span, count, :class=>'like-action-counter') + content_tag(:span, '', :class=>"action-icon #{action}"), url, :class => "#{active ? 'like-action-active':''} #{user ? '':'disabled'} require-login-popup" %>
9 9
10 <% if !voters.blank? %> 10 <% if !voters.blank? %>
11 <span class="vote-detail"> 11 <span class="vote-detail">
public/designs/icons/tango/style.css
@@ -114,6 +114,7 @@ @@ -114,6 +114,7 @@
114 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) } 114 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
115 .icon-reset-admin-role { background-image: url(../../../images/icons-app/person-icon.png) } 115 .icon-reset-admin-role { background-image: url(../../../images/icons-app/person-icon.png) }
116 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) } 116 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
  117 +.icon-fullscreen { background-image: url(Tango/16x16/actions/view-fullscreen.png) }
117 118
118 /******************LARGE ICONS********************/ 119 /******************LARGE ICONS********************/
119 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } 120 .image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) }
public/javascripts/application.js
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 *= require manage-products.js 27 *= require manage-products.js
28 *= require catalog.js 28 *= require catalog.js
29 *= require autogrow.js 29 *= require autogrow.js
  30 +*= require require_login.js
30 */ 31 */
31 32
32 // scope for noosfero stuff 33 // scope for noosfero stuff
@@ -1164,3 +1165,35 @@ function add_new_file_fields() { @@ -1164,3 +1165,35 @@ function add_new_file_fields() {
1164 } 1165 }
1165 1166
1166 window.isHidden = function isHidden() { return (typeof(document.hidden) != 'undefined') ? document.hidden : !document.hasFocus() }; 1167 window.isHidden = function isHidden() { return (typeof(document.hidden) != 'undefined') ? document.hidden : !document.hasFocus() };
  1168 +
  1169 +function $_GET(id){
  1170 + var a = new RegExp(id+"=([^&#=]*)");
  1171 + return decodeURIComponent(a.exec(window.location.search)[1]);
  1172 +}
  1173 +
  1174 +var fullwidth=false;
  1175 +function toggle_fullwidth(itemId){
  1176 + if(fullwidth){
  1177 + jQuery(itemId).removeClass("fullwidth");
  1178 + jQuery("#fullscreen-btn").show()
  1179 + jQuery("#exit-fullscreen-btn").hide()
  1180 + fullwidth = false;
  1181 + }
  1182 + else{
  1183 + jQuery(itemId).addClass("fullwidth");
  1184 + jQuery("#exit-fullscreen-btn").show()
  1185 + jQuery("#fullscreen-btn").hide()
  1186 + fullwidth = true;
  1187 + }
  1188 + jQuery(window).trigger("toggleFullwidth", fullwidth);
  1189 +}
  1190 +
  1191 +function fullscreenPageLoad(itemId){
  1192 + jQuery(document).ready(function(){
  1193 +
  1194 + if ($_GET('fullscreen') == 1){
  1195 + toggle_fullwidth(itemId);
  1196 + }
  1197 + });
  1198 +}
  1199 +
public/javascripts/manage-organizations.js 0 → 100644
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +(function($) {
  2 + // Pagination
  3 + $('#manage-profiles').on('click', '.pagination a', function () {
  4 + $.ajax({
  5 + url: this.href,
  6 + beforeSend: function(){$('#manage-profiles .results').addClass('fetching')},
  7 + complete: function() {$('#manage-profiles .results').removeClass('fetching')},
  8 + dataType: 'script'
  9 + })
  10 + return false;
  11 + });
  12 +
  13 + // Actions
  14 + $('#manage-profiles').on('click', '.action', function () {
  15 + if(confirm($(this).data('confirm'))) {
  16 + $.ajax({
  17 + url: this.href,
  18 + method: $(this).data('method') || 'get',
  19 + dataType: 'script',
  20 + success: function(data){
  21 + if(data)
  22 + display_notice(JSON.parse(data));
  23 + },
  24 + error: function(xhr, textStatus, message){
  25 + display_notice(message);
  26 + }
  27 + });
  28 + $('#manage-profiles').submit();
  29 + }
  30 + return false;
  31 + });
  32 +
  33 + // Sorting and Views
  34 + $('#manage-profiles select').live('change', function(){
  35 + $('#manage-profiles').submit();
  36 + });
  37 +
  38 + // Form Ajax submission
  39 + $('#manage-profiles').submit(function () {
  40 + $.ajax({
  41 + url: this.action,
  42 + data: $(this).serialize(),
  43 + beforeSend: function(){$('#manage-profiles .results').addClass('fetching')},
  44 + complete: function() {$('#manage-profiles .results').removeClass('fetching')},
  45 + dataType: 'script'
  46 + })
  47 + return false;
  48 + });
  49 +})(jQuery);
public/javascripts/require_login.js 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +(function($) {
  2 + $(window).bind('userDataLoaded', function(event, data) {
  3 + $(".require-login-popup").live('click', function(){
  4 + clicked = $(this);
  5 + url = clicked.attr("href");
  6 + if(url!=undefined && url!='' && url!='#') {
  7 + if(!data.login) {
  8 + url = $.param.querystring(url, "require_login_popup=true");
  9 + }
  10 + loading_for_button(this);
  11 + $.post(url, function(data){
  12 + if(data.require_login_popup) {
  13 + $('#link_login').click(); //TODO see a better way to show login popup
  14 + }
  15 + }).complete(function() {
  16 + clicked.css("cursor","");
  17 + $(".small-loading").remove();
  18 + });
  19 + } else {
  20 + $('#link_login').click();
  21 + }
  22 + return false;
  23 + });
  24 + });
  25 +})(jQuery);
public/javascripts/topic-creation-config.js 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +var values_map = {2: 'self', 1: 'related', 0: 'users'};
  2 +var keys_map = {};
  3 +Object.keys(values_map).forEach(function(value){
  4 + keys_map[values_map[value]] = value;
  5 +});
  6 +var s = jQuery('#topic-creation-slider');
  7 +
  8 +function setValue(event, ui){
  9 + jQuery('#article_topic_creation').val(values_map[ui.value]);
  10 +}
  11 +
  12 +s.slider({
  13 + orientation: 'vertical',
  14 + min: 0,
  15 + max: 2,
  16 + step: 1,
  17 + value: keys_map[jQuery('#article_topic_creation').val()],
  18 + range: 'max',
  19 + change: setValue
  20 +}).each(function() {
  21 + var opt = jQuery(this).data()['ui-slider'].options;
  22 + var vals = opt.max - opt.min;
  23 +
  24 + for (var i = 0; i <= vals; i++) {
  25 + var n = vals - i;
  26 + var el = jQuery('<label>' + s.data(values_map[i]) + '</label>').css('top', ((n/vals*100) - 7 - n) + '%');
  27 + s.append(el);
  28 + }
  29 +});
  30 +
public/stylesheets/application.css
@@ -4763,7 +4763,7 @@ h1#agenda-title { @@ -4763,7 +4763,7 @@ h1#agenda-title {
4763 float: right; 4763 float: right;
4764 } 4764 }
4765 4765
4766 -#environment-users-search form { 4766 +#environment-profiles-search form {
4767 padding: 10px; 4767 padding: 10px;
4768 margin-bottom: 15px; 4768 margin-bottom: 15px;
4769 background-color: #E6E6E6; 4769 background-color: #E6E6E6;
@@ -4771,14 +4771,14 @@ h1#agenda-title { @@ -4771,14 +4771,14 @@ h1#agenda-title {
4771 -webkit-border-radius: 5px; 4771 -webkit-border-radius: 5px;
4772 } 4772 }
4773 4773
4774 -.environment-users-results-header { 4774 +.environment-profiles-results-header {
4775 font-size: 0.9em; 4775 font-size: 0.9em;
4776 padding: 6px 0px 0px 0px; 4776 padding: 6px 0px 0px 0px;
4777 margin:0 0 5px 0; 4777 margin:0 0 5px 0;
4778 border-bottom: 2px dotted #999; 4778 border-bottom: 2px dotted #999;
4779 text-align: right; 4779 text-align: right;
4780 } 4780 }
4781 -#environment-users-filter-title { 4781 +#environment-profiles-filter-title {
4782 font-weight: bold; 4782 font-weight: bold;
4783 font-size: 130%; 4783 font-size: 130%;
4784 line-height: 35px; 4784 line-height: 35px;
@@ -6239,6 +6239,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6239,6 +6239,20 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6239 .forum-posts .pagination { 6239 .forum-posts .pagination {
6240 margin-top: 20px; 6240 margin-top: 20px;
6241 } 6241 }
  6242 +
  6243 +#topic-creation-slider{
  6244 + margin-top: 15px;
  6245 +}
  6246 +
  6247 +#topic-creation-slider .ui-slider-range {
  6248 + background: #73D216;
  6249 +}
  6250 +
  6251 +#topic-creation-slider label {
  6252 + left: 20px;
  6253 + position: absolute;
  6254 + width: 200px;
  6255 +}
6242 /* Task */ 6256 /* Task */
6243 6257
6244 #user a#pending-tasks-count { 6258 #user a#pending-tasks-count {
@@ -6971,3 +6985,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -6971,3 +6985,19 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6971 body .ui-widget-overlay { 6985 body .ui-widget-overlay {
6972 background: #000; 6986 background: #000;
6973 } 6987 }
  6988 +
  6989 +.fullwidth{
  6990 + position: fixed !important;
  6991 + left: 0 !important;
  6992 + top: 0 !important;
  6993 + background: white !important;
  6994 + width: 97% !important;
  6995 + width: 100% !important;
  6996 + z-index: 999 !important;
  6997 + padding: 2em !important;
  6998 + bottom:0 !important;
  6999 + overflow: auto !important;
  7000 + -webkit-box-sizing: border-box !important;
  7001 + -moz-box-sizing: border-box !important;
  7002 + box-sizing: border-box !important;
  7003 +}
public/stylesheets/tasks.css
@@ -17,6 +17,11 @@ @@ -17,6 +17,11 @@
17 font-size: 120%; 17 font-size: 120%;
18 } 18 }
19 19
  20 +.task_date {
  21 + color: gray;
  22 + font-size: 12px;
  23 +}
  24 +
20 .task_icon { 25 .task_icon {
21 float: left; 26 float: left;
22 margin-right: 10px; 27 margin-right: 10px;
script/apacheconf
@@ -32,6 +32,7 @@ when &#39;virtualhosts&#39; @@ -32,6 +32,7 @@ when &#39;virtualhosts&#39;
32 puts " #{server_directive} #{domain.name}" 32 puts " #{server_directive} #{domain.name}"
33 server_directive = 'ServerAlias' 33 server_directive = 'ServerAlias'
34 end 34 end
  35 + puts " Include /usr/share/noosfero/util/chat/apache/xmpp.conf"
35 puts " Include /etc/noosfero/apache/virtualhost.conf" 36 puts " Include /etc/noosfero/apache/virtualhost.conf"
36 puts "</VirtualHost>" 37 puts "</VirtualHost>"
37 end 38 end
script/noosfero-test-chat-session 0 → 100755
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +#!/usr/bin/env ruby
  2 +require File.dirname(__FILE__) + '/../config/environment'
  3 +
  4 +environment = Environment.default
  5 +person = Person.first
  6 +password = person.user.crypted_password
  7 +login = person.jid
  8 +
  9 +begin
  10 + RubyBOSH.initialize_session(
  11 + login,
  12 + password,
  13 + "http://#{environment.default_hostname}/http-bind",
  14 + :wait => 30,
  15 + :hold => 1,
  16 + :window => 5
  17 + )
  18 +rescue Exception => e
  19 + puts ""
  20 + puts "[ERROR] XMPP/Chat setup isn't working"
  21 + puts "-------------------------------------"
  22 + puts e.to_s
  23 + exit 1
  24 +else
  25 + puts ""
  26 + puts "[OK] XMPP/Chat setup is working"
  27 + exit 0
  28 +end
script/odbcconf 0 → 100755
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +require 'yaml'
  4 +config = YAML.load_file(File.dirname(__FILE__) + '/../config/database.yml')['production']
  5 +
  6 +
  7 +puts "[PostgreSQLEjabberdNoosfero]"
  8 +puts "Description = PostgreSQL Noosfero ejabberd database"
  9 +puts "Driver = PostgreSQL Unicode"
  10 +puts "Trace = No"
  11 +puts "TraceFile = /tmp/psqlodbc.log"
  12 +puts "Database = #{config['database']}"
  13 +puts "Servername = #{config['host'] || 'localhost'}"
  14 +puts "UserName = #{config['username']}"
  15 +puts "Password = #{config['password']}"
  16 +puts "Port = #{config['port'] || '5432'}"
  17 +puts "ReadOnly = No"
  18 +puts "RowVersioning = No"
  19 +puts "ShowSystemTables = No"
  20 +puts "ShowOidColumn = No"
  21 +puts "FakeOidIndex = No"
  22 +puts "ConnSettings = SET search_path TO ejabberd"
test/factories.rb
@@ -65,7 +65,7 @@ module Noosfero::Factory @@ -65,7 +65,7 @@ module Noosfero::Factory
65 ###### old stuff to be rearranged 65 ###### old stuff to be rearranged
66 def create_admin_user(env) 66 def create_admin_user(env)
67 admin_user = User.find_by_login('adminuser') || create_user('adminuser', :email => 'adminuser@noosfero.org', :password => 'adminuser', :password_confirmation => 'adminuser', :environment => env) 67 admin_user = User.find_by_login('adminuser') || create_user('adminuser', :email => 'adminuser@noosfero.org', :password => 'adminuser', :password_confirmation => 'adminuser', :environment => env)
68 - admin_role = Role.find_by_name('admin_role') || Role.create!(:name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_templates', 'manage_environment_licenses', 'edit_appearance']) 68 + admin_role = Role.find_by_name('admin_role') || Role.create!(:name => 'admin_role', :permissions => ['view_environment_admin_panel','edit_environment_features', 'edit_environment_design', 'manage_environment_categories', 'manage_environment_roles', 'manage_environment_trusted_sites', 'manage_environment_validators', 'manage_environment_users', 'manage_environment_organizations', 'manage_environment_templates', 'manage_environment_licenses', 'edit_appearance'])
69 create(RoleAssignment, :accessor => admin_user.person, :role => admin_role, :resource => env) unless admin_user.person.role_assignments.map{|ra|[ra.role, ra.accessor, ra.resource]}.include?([admin_role, admin_user, env]) 69 create(RoleAssignment, :accessor => admin_user.person, :role => admin_role, :resource => env) unless admin_user.person.role_assignments.map{|ra|[ra.role, ra.accessor, ra.resource]}.include?([admin_role, admin_user, env])
70 admin_user.login 70 admin_user.login
71 end 71 end
test/fixtures/roles.yml
@@ -35,6 +35,7 @@ four: @@ -35,6 +35,7 @@ four:
35 - moderate_comments 35 - moderate_comments
36 - perform_task 36 - perform_task
37 - manage_environment_users 37 - manage_environment_users
  38 + - manage_environment_organizations
38 - manage_environment_templates 39 - manage_environment_templates
39 - manage_environment_licenses 40 - manage_environment_licenses
40 profile_admin: 41 profile_admin:
@@ -94,6 +95,7 @@ environment_administrator: @@ -94,6 +95,7 @@ environment_administrator:
94 - manage_environment_validators 95 - manage_environment_validators
95 - moderate_comments 96 - moderate_comments
96 - manage_environment_users 97 - manage_environment_users
  98 + - manage_environment_organizations
97 - edit_profile 99 - edit_profile
98 - destroy_profile 100 - destroy_profile
99 - manage_environment_templates 101 - manage_environment_templates
test/functional/admin_panel_controller_test.rb
@@ -17,12 +17,12 @@ class AdminPanelControllerTest &lt; ActionController::TestCase @@ -17,12 +17,12 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
17 should 'manage the correct environment' do 17 should 'manage the correct environment' do
18 current = fast_create(Environment, :name => 'test environment', :is_default => false) 18 current = fast_create(Environment, :name => 'test environment', :is_default => false)
19 current.domains.create!(:name => 'example.com') 19 current.domains.create!(:name => 'example.com')
20 - 20 +
21 @request.expects(:host).returns('example.com').at_least_once 21 @request.expects(:host).returns('example.com').at_least_once
22 get :index 22 get :index
23 assert_equal current, assigns(:environment) 23 assert_equal current, assigns(:environment)
24 end 24 end
25 - 25 +
26 should 'link to site_info editing page' do 26 should 'link to site_info editing page' do
27 get :index 27 get :index
28 assert_tag :tag => 'a', :attributes => { :href => '/admin/admin_panel/site_info' } 28 assert_tag :tag => 'a', :attributes => { :href => '/admin/admin_panel/site_info' }
@@ -379,36 +379,4 @@ class AdminPanelControllerTest &lt; ActionController::TestCase @@ -379,36 +379,4 @@ class AdminPanelControllerTest &lt; ActionController::TestCase
379 assert_equal body, Environment.default.signup_welcome_screen_body 379 assert_equal body, Environment.default.signup_welcome_screen_body
380 assert !Environment.default.signup_welcome_screen_body.blank? 380 assert !Environment.default.signup_welcome_screen_body.blank?
381 end 381 end
382 -  
383 - should 'show list to deactivate organizations' do  
384 - enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")  
385 - disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")  
386 - user = create_user('user')  
387 -  
388 - disabled_community.disable  
389 -  
390 - Environment.default.add_admin user.person  
391 - login_as('user')  
392 -  
393 - get :manage_organizations_status, :filter=>"enabled"  
394 - assert_match(/Organization profiles - enabled/, @response.body)  
395 - assert_match(/enabled community/, @response.body)  
396 - assert_not_match(/disabled community/, @response.body)  
397 - end  
398 -  
399 - should 'show list to activate organizations' do  
400 - enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")  
401 - disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")  
402 - user = create_user('user')  
403 -  
404 - disabled_community.disable  
405 -  
406 - Environment.default.add_admin user.person  
407 - login_as('user')  
408 -  
409 - get :manage_organizations_status, :filter=>"disabled"  
410 - assert_match(/Organization profiles - disabled/, @response.body)  
411 - assert_not_match(/enabled community/, @response.body)  
412 - assert_match(/disabled community/, @response.body)  
413 - end  
414 end 382 end
test/functional/cms_controller_test.rb
@@ -1811,6 +1811,14 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1811,6 +1811,14 @@ class CmsControllerTest &lt; ActionController::TestCase
1811 assert_equal 'first version', assigns(:article).name 1811 assert_equal 'first version', assigns(:article).name
1812 end 1812 end
1813 1813
  1814 + should 'clone article with its content' do
  1815 + article = profile.articles.create(:name => 'first version')
  1816 +
  1817 + get :new, :profile => profile.identifier, :id => article.id, :clone => true, :type => 'TinyMceArticle'
  1818 +
  1819 + assert_match article.name, @response.body
  1820 + end
  1821 +
1814 should 'save article with content from older version' do 1822 should 'save article with content from older version' do
1815 article = profile.articles.create(:name => 'first version') 1823 article = profile.articles.create(:name => 'first version')
1816 article.name = 'second version'; article.save 1824 article.name = 'second version'; article.save
test/functional/contact_controller_test.rb
@@ -131,7 +131,7 @@ class ContactControllerTest &lt; ActionController::TestCase @@ -131,7 +131,7 @@ class ContactControllerTest &lt; ActionController::TestCase
131 post :new, :profile => community.identifier 131 post :new, :profile => community.identifier
132 132
133 assert_response :forbidden 133 assert_response :forbidden
134 - assert_template :private_profile 134 + assert_template "profile/_private_profile"
135 end 135 end
136 136
137 should 'not show send e-mail page to non members of invisible community' do 137 should 'not show send e-mail page to non members of invisible community' do
test/functional/content_viewer_controller_test.rb
@@ -257,22 +257,22 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -257,22 +257,22 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
257 end 257 end
258 258
259 should 'not give access to private articles if logged off' do 259 should 'not give access to private articles if logged off' do
260 - profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile') 260 + profile = Community.create!(:name => 'test profile', :identifier => 'test_profile')
261 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false) 261 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false)
262 262
263 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ] 263 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
264 264
265 - assert_template 'access_denied' 265 + assert_template "profile/_private_profile"
266 end 266 end
267 267
268 should 'not give access to private articles if logged in but not member' do 268 should 'not give access to private articles if logged in but not member' do
269 login_as('testinguser') 269 login_as('testinguser')
270 - profile = Profile.create!(:name => 'test profile', :identifier => 'test_profile') 270 + profile = Community.create!(:name => 'test profile', :identifier => 'test_profile')
271 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false) 271 intranet = Folder.create!(:name => 'my_intranet', :profile => profile, :published => false)
272 272
273 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ] 273 get :view_page, :profile => 'test_profile', :page => [ 'my-intranet' ]
274 274
275 - assert_template 'access_denied' 275 + assert_template "profile/_private_profile"
276 end 276 end
277 277
278 should 'not give access to private articles if logged in and only member' do 278 should 'not give access to private articles if logged in and only member' do
@@ -1252,9 +1252,11 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1252,9 +1252,11 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1252 should 'expire article actions button if any plugins says so' do 1252 should 'expire article actions button if any plugins says so' do
1253 class Plugin1 < Noosfero::Plugin 1253 class Plugin1 < Noosfero::Plugin
1254 def content_expire_edit(content); 'This button is expired.'; end 1254 def content_expire_edit(content); 'This button is expired.'; end
  1255 + def content_expire_clone(content); 'This button is expired.'; end
1255 end 1256 end
1256 class Plugin2 < Noosfero::Plugin 1257 class Plugin2 < Noosfero::Plugin
1257 def content_expire_edit(content); nil; end 1258 def content_expire_edit(content); nil; end
  1259 + def content_expire_clone(content); nil; end
1258 end 1260 end
1259 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name]) 1261 Noosfero::Plugin.stubs(:all).returns([Plugin1.name, Plugin2.name])
1260 1262
@@ -1428,7 +1430,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase @@ -1428,7 +1430,7 @@ class ContentViewerControllerTest &lt; ActionController::TestCase
1428 1430
1429 article = TinyMceArticle.create(:name => 'Article to be shared with images', 1431 article = TinyMceArticle.create(:name => 'Article to be shared with images',
1430 :body => 'This article should be shared with all social networks', 1432 :body => 'This article should be shared with all social networks',
1431 - :profile => @profile, 1433 + :profile => community,
1432 :published => false, 1434 :published => false,
1433 :show_to_followers => true) 1435 :show_to_followers => true)
1434 article.parent = blog 1436 article.parent = blog
test/functional/events_controller_test.rb
@@ -60,7 +60,7 @@ class EventsControllerTest &lt; ActionController::TestCase @@ -60,7 +60,7 @@ class EventsControllerTest &lt; ActionController::TestCase
60 post :events, :profile => community.identifier 60 post :events, :profile => community.identifier
61 61
62 assert_response :forbidden 62 assert_response :forbidden
63 - assert_template :private_profile 63 + assert_template "profile/_private_profile"
64 end 64 end
65 65
66 should 'not show events page to non members of invisible community' do 66 should 'not show events page to non members of invisible community' do
test/functional/organizations_controller_test.rb 0 → 100644
@@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
  1 +require_relative "../test_helper"
  2 +require 'organizations_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class OrganizationsController; def rescue_action(e) raise e end; end
  6 +
  7 +class OrganizationsControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @controller = OrganizationsController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 +
  14 + Environment.destroy_all
  15 + @environment = fast_create(Environment, :is_default => true)
  16 +
  17 + admin_user = create_user_with_permission('adminuser', 'manage_environment_organizations', environment)
  18 + login_as('adminuser')
  19 + end
  20 +
  21 + attr_accessor :environment
  22 +
  23 + should 'not access without right permission' do
  24 + create_user('guest')
  25 + login_as 'guest'
  26 + get :index
  27 + assert_response 403 # forbidden
  28 + end
  29 +
  30 + should 'grant access with right permission' do
  31 + get :index
  32 + assert_response :success
  33 + end
  34 +
  35 + should 'show list to deactivate organizations' do
  36 + enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
  37 + disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
  38 + disabled_community.disable
  39 +
  40 + get :index, :filter => 'enabled'
  41 +
  42 + assert_match(/enabled community/, @response.body)
  43 + assert_not_match(/disabled community/, @response.body)
  44 + end
  45 +
  46 + should 'show list to activate organizations' do
  47 + enabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"enabled community")
  48 + disabled_community = fast_create(Community, :environment_id => Environment.default, :name=>"disabled community")
  49 + disabled_community.disable
  50 +
  51 + get :index, :filter => 'disabled'
  52 +
  53 + assert_not_match(/enabled community/, @response.body)
  54 + assert_match(/disabled community/, @response.body)
  55 + end
  56 +
  57 + should 'show list only of enterprises' do
  58 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  59 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  60 +
  61 + get :index, :type => 'Enterprise'
  62 +
  63 + assert_match(/Enterprise Test/, @response.body)
  64 + assert_not_match(/Community Test/, @response.body)
  65 + end
  66 +
  67 + should 'show list only of communities' do
  68 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  69 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  70 +
  71 + get :index, :type => 'Community'
  72 +
  73 + assert_not_match(/Enterprise Test/, @response.body)
  74 + assert_match(/Community Test/, @response.body)
  75 + end
  76 +
  77 + should 'show list all organizations' do
  78 + community = fast_create(Community, :environment_id => Environment.default, :name=>"Community Test")
  79 + enterprise = fast_create(Enterprise, :environment_id => Environment.default, :name=>"Enterprise Test")
  80 +
  81 + get :index, :type => 'any'
  82 +
  83 + assert_match(/Enterprise Test/, @response.body)
  84 + assert_match(/Community Test/, @response.body)
  85 + end
  86 +
  87 + should 'activate organization profile' do
  88 + organization = fast_create(Organization, :visible => false, :environment_id => environment.id)
  89 + assert organization.disabled?
  90 +
  91 + get :activate, {:id => organization.id}
  92 + organization.reload
  93 +
  94 + assert organization.enabled?
  95 + end
  96 +
  97 + should 'deactivate organization profile' do
  98 + organization = fast_create(Organization, :visible => true, :environment_id => environment.id)
  99 + assert organization.enabled?
  100 +
  101 + get :deactivate, {:id => organization.id}
  102 + organization.reload
  103 +
  104 + assert organization.disabled?
  105 + end
  106 +
  107 + should 'destroy organization profile' do
  108 + organization = fast_create(Organization, :environment_id => environment.id)
  109 +
  110 + post :destroy, {:id => organization.id}
  111 +
  112 + assert_raise ActiveRecord::RecordNotFound do
  113 + organization.reload
  114 + end
  115 + end
  116 +end
test/functional/profile_editor_controller_test.rb
@@ -1152,57 +1152,4 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase @@ -1152,57 +1152,4 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
1152 get :index, :profile => user.identifier 1152 get :index, :profile => user.identifier
1153 assert_tag :tag => 'div', :descendant => { :tag => 'a', :content => 'Edit Header and Footer' } 1153 assert_tag :tag => 'div', :descendant => { :tag => 'a', :content => 'Edit Header and Footer' }
1154 end 1154 end
1155 -  
1156 - should 'deactivate organization profile' do  
1157 - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'  
1158 - user = create_user('user').person  
1159 - Environment.default.add_admin user  
1160 - login_as('user')  
1161 -  
1162 - community = fast_create(Community)  
1163 - assert_equal true, community.enable  
1164 -  
1165 - get :index, :profile => community.identifier  
1166 - get :deactivate_profile, {:profile => community.identifier, :id => community.id}  
1167 - assert_equal @request.session[:notice], "The profile '#{community.name}' was deactivated."  
1168 - end  
1169 -  
1170 - should 'activate organization profile' do  
1171 - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'  
1172 - user = create_user('user').person  
1173 - Environment.default.add_admin user  
1174 - login_as('user')  
1175 -  
1176 - community = fast_create(Community)  
1177 - assert_equal true, community.disable  
1178 -  
1179 - get :index, :profile => community.identifier  
1180 - get :activate_profile, {:profile => community.identifier, :id => community.id}  
1181 - assert_equal @request.session[:notice], "The profile '#{community.name}' was activated."  
1182 - end  
1183 -  
1184 - should 'not deactivate organization profile if user is not an admin' do  
1185 - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'  
1186 - user = create_user('user').person  
1187 - login_as('user')  
1188 -  
1189 - community = fast_create(Community)  
1190 - get :index, :profile => community.identifier  
1191 - get :deactivate_profile, {:profile => community.identifier, :id => community.id}  
1192 - assert_not_equal @request.session[:notice], "The profile '#{community.name}' was disabled."  
1193 - end  
1194 -  
1195 - should 'destroy organization profile' do  
1196 - @request.env['HTTP_REFERER'] = 'http://localhost:3000/admin/admin_panel/manage_organizations_status'  
1197 - user = create_user('user').person  
1198 - Environment.default.add_admin user  
1199 - login_as('user')  
1200 -  
1201 - community = fast_create(Community)  
1202 - assert_equal true, community.enable  
1203 -  
1204 - get :index, :profile => community.identifier  
1205 - post :destroy_profile, {:profile => community.identifier, :id => community.id}  
1206 - assert_equal @request.session[:notice], "The profile was deleted."  
1207 - end  
1208 end 1155 end
test/functional/tasks_controller_test.rb
@@ -5,7 +5,7 @@ class TasksController; def rescue_action(e) raise e end; end @@ -5,7 +5,7 @@ class TasksController; def rescue_action(e) raise e end; end
5 5
6 class TasksControllerTest < ActionController::TestCase 6 class TasksControllerTest < ActionController::TestCase
7 7
8 - noosfero_test :profile => 'testuser' 8 + noosfero_test :profile => 'testuser'
9 9
10 def setup 10 def setup
11 @controller = TasksController.new 11 @controller = TasksController.new
@@ -49,6 +49,12 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -49,6 +49,12 @@ class TasksControllerTest &lt; ActionController::TestCase
49 assert_kind_of Array, assigns(:tasks) 49 assert_kind_of Array, assigns(:tasks)
50 end 50 end
51 51
  52 + should 'display task created_at' do
  53 + Task.create!(:requestor => fast_create(Person), :target => profile, :spam => false)
  54 + get :index
  55 + assert_select '.task_date'
  56 + end
  57 +
52 should 'list processed tasks without spam' do 58 should 'list processed tasks without spam' do
53 requestor = fast_create(Person) 59 requestor = fast_create(Person)
54 task_spam = create(Task, :status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :spam => true) 60 task_spam = create(Task, :status => Task::Status::FINISHED, :requestor => requestor, :target => profile, :spam => true)
@@ -388,6 +394,28 @@ class TasksControllerTest &lt; ActionController::TestCase @@ -388,6 +394,28 @@ class TasksControllerTest &lt; ActionController::TestCase
388 assert_includes assigns(:tasks), t3 394 assert_includes assigns(:tasks), t3
389 end 395 end
390 396
  397 + should 'filter tasks by type and data content' do
  398 + class CleanHouse < Task; end
  399 + class FeedDog < Task; end
  400 + Task.stubs(:per_page).returns(3)
  401 + requestor = fast_create(Person)
  402 + t1 = CleanHouse.create!(:requestor => requestor, :target => profile, :data => {:name => 'Task Test'})
  403 + t2 = CleanHouse.create!(:requestor => requestor, :target => profile)
  404 + t3 = FeedDog.create!(:requestor => requestor, :target => profile)
  405 +
  406 + get :index, :filter_type => t1.type, :filter_text => 'test'
  407 +
  408 + assert_includes assigns(:tasks), t1
  409 + assert_not_includes assigns(:tasks), t2
  410 + assert_not_includes assigns(:tasks), t3
  411 +
  412 + get :index
  413 +
  414 + assert_includes assigns(:tasks), t1
  415 + assert_includes assigns(:tasks), t2
  416 + assert_includes assigns(:tasks), t3
  417 + end
  418 +
391 should 'return tasks ordered accordingly and limited by pages' do 419 should 'return tasks ordered accordingly and limited by pages' do
392 time = Time.now 420 time = Time.now
393 person = fast_create(Person) 421 person = fast_create(Person)
test/integration/http_caching_test.rb
@@ -85,7 +85,7 @@ class HttpCachingTest &lt; ActionController::IntegrationTest @@ -85,7 +85,7 @@ class HttpCachingTest &lt; ActionController::IntegrationTest
85 85
86 test 'private community content should not return cache headers' do 86 test 'private community content should not return cache headers' do
87 community = create_private_community('the-community') 87 community = create_private_community('the-community')
88 - create(Article, profile_id: community.id, name: 'Test page') 88 + create(Article, profile_id: community.id, name: 'Test page', published: false)
89 89
90 get "/the-community/test-page" 90 get "/the-community/test-page"
91 assert_response 403 91 assert_response 403
@@ -139,4 +139,3 @@ class HttpCachingTest &lt; ActionController::IntegrationTest @@ -139,4 +139,3 @@ class HttpCachingTest &lt; ActionController::IntegrationTest
139 end 139 end
140 140
141 end 141 end
142 -  
test/unit/application_helper_test.rb
@@ -1002,6 +1002,21 @@ class ApplicationHelperTest &lt; ActionView::TestCase @@ -1002,6 +1002,21 @@ class ApplicationHelperTest &lt; ActionView::TestCase
1002 assert_equal file, from_theme_include('atheme', 'afile')[:file] # exists? = true 1002 assert_equal file, from_theme_include('atheme', 'afile')[:file] # exists? = true
1003 end 1003 end
1004 1004
  1005 + should 'enable fullscreen buttons' do
  1006 + html = fullscreen_buttons("#article")
  1007 + assert html.include?("<script>fullscreenPageLoad('#article')</script>")
  1008 + assert html.include?("class=\"button with-text icon-fullscreen\"")
  1009 + assert html.include?("onClick=\"toggle_fullwidth('#article')\"")
  1010 + end
  1011 +
  1012 + should "return the related class string" do
  1013 + assert_equal "Clone Folder", label_for_clone_article(Folder.new)
  1014 + assert_equal "Clone Blog", label_for_clone_article(Blog.new)
  1015 + assert_equal "Clone Event", label_for_clone_article(Event.new)
  1016 + assert_equal "Clone Forum", label_for_clone_article(Forum.new)
  1017 + assert_equal "Clone Article", label_for_clone_article(TinyMceArticle.new)
  1018 + end
  1019 +
1005 protected 1020 protected
1006 include NoosferoTestHelper 1021 include NoosferoTestHelper
1007 1022
test/unit/article_test.rb
@@ -484,7 +484,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -484,7 +484,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
484 484
485 should 'say that member user can not see private article' do 485 should 'say that member user can not see private article' do
486 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile') 486 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile')
487 - article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => false) 487 + article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => false, :show_to_followers => false)
488 person = create_user('test_user').person 488 person = create_user('test_user').person
489 profile.affiliate(person, Profile::Roles.member(profile.environment.id)) 489 profile.affiliate(person, Profile::Roles.member(profile.environment.id))
490 490
@@ -509,15 +509,15 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -509,15 +509,15 @@ class ArticleTest &lt; ActiveSupport::TestCase
509 assert article.display_to?(person) 509 assert article.display_to?(person)
510 end 510 end
511 511
512 - should 'not show article to non member if article public but profile private' do 512 + should 'show article to non member if article public but profile private' do
513 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile', :public_profile => false) 513 profile = fast_create(Profile, :name => 'test profile', :identifier => 'test_profile', :public_profile => false)
514 article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => true) 514 article = fast_create(Article, :name => 'test article', :profile_id => profile.id, :published => true)
515 person1 = create_user('test_user1').person 515 person1 = create_user('test_user1').person
516 profile.affiliate(person1, Profile::Roles.member(profile.environment.id)) 516 profile.affiliate(person1, Profile::Roles.member(profile.environment.id))
517 person2 = create_user('test_user2').person 517 person2 = create_user('test_user2').person
518 518
519 - assert !article.display_to?(nil)  
520 - assert !article.display_to?(person2) 519 + assert article.display_to?(nil)
  520 + assert article.display_to?(person2)
521 assert article.display_to?(person1) 521 assert article.display_to?(person1)
522 end 522 end
523 523
@@ -543,7 +543,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -543,7 +543,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
543 543
544 should 'not allow friends of private person see the article' do 544 should 'not allow friends of private person see the article' do
545 person = create_user('test_user').person 545 person = create_user('test_user').person
546 - article = create(Article, :name => 'test article', :profile => person, :published => false) 546 + article = create(Article, :name => 'test article', :profile => person, :published => false, :show_to_followers => false)
547 friend = create_user('test_friend').person 547 friend = create_user('test_friend').person
548 person.add_friend(friend) 548 person.add_friend(friend)
549 person.save! 549 person.save!
@@ -1686,7 +1686,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1686,7 +1686,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1686 a.allow_members_to_edit = true 1686 a.allow_members_to_edit = true
1687 assert !a.allow_edit?(nil) 1687 assert !a.allow_edit?(nil)
1688 end 1688 end
1689 - 1689 +
1690 should 'allow author to edit topic' do 1690 should 'allow author to edit topic' do
1691 community = fast_create(Community) 1691 community = fast_create(Community)
1692 admin = fast_create(Person) 1692 admin = fast_create(Person)
@@ -1905,7 +1905,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1905,7 +1905,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1905 end 1905 end
1906 1906
1907 should 'display_filter display only public articles if there is no user' do 1907 should 'display_filter display only public articles if there is no user' do
1908 - p = fast_create(Person) 1908 + p = fast_create(Person)
1909 Article.delete_all 1909 Article.delete_all
1910 a = fast_create(Article, :published => true, :profile_id => p.id) 1910 a = fast_create(Article, :published => true, :profile_id => p.id)
1911 fast_create(Article, :published => false, :profile_id => p.id) 1911 fast_create(Article, :published => false, :profile_id => p.id)
@@ -1915,7 +1915,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1915,7 +1915,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1915 1915
1916 should 'display_filter display public articles for users' do 1916 should 'display_filter display public articles for users' do
1917 user = create_user('someuser').person 1917 user = create_user('someuser').person
1918 - p = fast_create(Person) 1918 + p = fast_create(Person)
1919 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 1919 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1920 Article.delete_all 1920 Article.delete_all
1921 a = fast_create(Article, :published => true, :profile_id => p.id) 1921 a = fast_create(Article, :published => true, :profile_id => p.id)
@@ -1926,7 +1926,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1926,7 +1926,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1926 1926
1927 should 'display_filter display private article last changed by user' do 1927 should 'display_filter display private article last changed by user' do
1928 user = create_user('someuser').person 1928 user = create_user('someuser').person
1929 - p = fast_create(Person) 1929 + p = fast_create(Person)
1930 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 1930 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1931 Article.delete_all 1931 Article.delete_all
1932 a = fast_create(Article, :published => false, :last_changed_by_id => user.id, :profile_id => p.id) 1932 a = fast_create(Article, :published => false, :last_changed_by_id => user.id, :profile_id => p.id)
@@ -1938,7 +1938,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1938,7 +1938,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1938 should 'display_filter display user private article of his own profile' do 1938 should 'display_filter display user private article of his own profile' do
1939 user = create_user('someuser').person 1939 user = create_user('someuser').person
1940 user.stubs(:has_permission?).with(:view_private_content, user).returns(false) 1940 user.stubs(:has_permission?).with(:view_private_content, user).returns(false)
1941 - p = fast_create(Person) 1941 + p = fast_create(Person)
1942 Article.delete_all 1942 Article.delete_all
1943 a = fast_create(Article, :published => false, :profile_id => user.id) 1943 a = fast_create(Article, :published => false, :profile_id => user.id)
1944 fast_create(Article, :published => false, :profile_id => p.id) 1944 fast_create(Article, :published => false, :profile_id => p.id)
@@ -1948,7 +1948,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1948,7 +1948,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
1948 1948
1949 should 'display_filter show profile private content if the user has view_private_content permission' do 1949 should 'display_filter show profile private content if the user has view_private_content permission' do
1950 user = create_user('someuser').person 1950 user = create_user('someuser').person
1951 - p = fast_create(Person) 1951 + p = fast_create(Person)
1952 Article.delete_all 1952 Article.delete_all
1953 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 1953 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1954 a = fast_create(Article, :published => false, :profile_id => p.id) 1954 a = fast_create(Article, :published => false, :profile_id => p.id)
@@ -1965,8 +1965,8 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1965,8 +1965,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
1965 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 1965 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1966 Article.delete_all 1966 Article.delete_all
1967 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id) 1967 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id)
1968 - fast_create(Article, :published => false, :profile_id => p.id)  
1969 - fast_create(Article, :published => false, :profile_id => p.id) 1968 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  1969 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
1970 assert_equal [a], Article.display_filter(user, p) 1970 assert_equal [a], Article.display_filter(user, p)
1971 end 1971 end
1972 1972
@@ -1977,8 +1977,8 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1977,8 +1977,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
1977 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 1977 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
1978 Article.delete_all 1978 Article.delete_all
1979 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id) 1979 a = fast_create(Article, :published => false, :show_to_followers => true, :profile_id => p.id)
1980 - fast_create(Article, :published => false, :profile_id => p.id)  
1981 - fast_create(Article, :published => false, :profile_id => p.id) 1980 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  1981 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
1982 assert_equal [a], Article.display_filter(user, p) 1982 assert_equal [a], Article.display_filter(user, p)
1983 end 1983 end
1984 1984
@@ -2040,6 +2040,17 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2040,6 +2040,17 @@ class ArticleTest &lt; ActiveSupport::TestCase
2040 assert_equal [], Article.display_filter(user, nil) 2040 assert_equal [], Article.display_filter(user, nil)
2041 end 2041 end
2042 2042
  2043 + should 'display_filter show person public content to non friends passing nil as profile parameter' do
  2044 + user = create_user('someuser').person
  2045 + p = fast_create(Person)
  2046 + assert !p.is_a_friend?(user)
  2047 + assert !user.is_admin?
  2048 + Article.delete_all
  2049 + a1 = fast_create(Article, :profile_id => p.id)
  2050 + a2 = fast_create(Article)
  2051 + assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2052 + end
  2053 +
2043 should 'display_filter do not show community private content to non members passing nil as profile parameter' do 2054 should 'display_filter do not show community private content to non members passing nil as profile parameter' do
2044 user = create_user('someuser').person 2055 user = create_user('someuser').person
2045 p = fast_create(Community) 2056 p = fast_create(Community)
@@ -2049,6 +2060,16 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2049,6 +2060,16 @@ class ArticleTest &lt; ActiveSupport::TestCase
2049 assert_equal [], Article.display_filter(user, nil) 2060 assert_equal [], Article.display_filter(user, nil)
2050 end 2061 end
2051 2062
  2063 + should 'display_filter show community public content to non members passing nil as profile parameter' do
  2064 + user = create_user('someuser').person
  2065 + p = fast_create(Community)
  2066 + assert !user.is_member_of?(p)
  2067 + Article.delete_all
  2068 + a1 = fast_create(Article, :profile_id => p.id)
  2069 + a2 = fast_create(Article)
  2070 + assert_equivalent [a1,a2], Article.display_filter(user, nil)
  2071 + end
  2072 +
2052 should 'display_filter show community public content of private community for user members' do 2073 should 'display_filter show community public content of private community for user members' do
2053 user = create_user('someuser').person 2074 user = create_user('someuser').person
2054 p = fast_create(Community, :public_profile => false) 2075 p = fast_create(Community, :public_profile => false)
@@ -2057,8 +2078,8 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2057,8 +2078,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
2057 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 2078 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
2058 Article.delete_all 2079 Article.delete_all
2059 a = fast_create(Article, :published => true, :profile_id => p.id) 2080 a = fast_create(Article, :published => true, :profile_id => p.id)
2060 - fast_create(Article, :published => false, :profile_id => p.id)  
2061 - fast_create(Article, :published => false, :profile_id => p.id) 2081 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  2082 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
2062 assert_equal [a], Article.display_filter(user, p) 2083 assert_equal [a], Article.display_filter(user, p)
2063 end 2084 end
2064 2085
@@ -2088,7 +2109,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2088,7 +2109,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
2088 a1 = fast_create(Article, :published => true, :profile_id => user.id) 2109 a1 = fast_create(Article, :published => true, :profile_id => user.id)
2089 a2 = fast_create(Article, :published => true, :profile_id => p.id) 2110 a2 = fast_create(Article, :published => true, :profile_id => p.id)
2090 fast_create(Article, :published => false, :profile_id => p.id) 2111 fast_create(Article, :published => false, :profile_id => p.id)
2091 - assert_equivalent [a1,a2], Article.display_filter(user, nil) 2112 + assert_equivalent [a1,a2], Article.display_filter(nil, user)
2092 end 2113 end
2093 2114
2094 should 'display_filter show person public content of private person profile for user friends' do 2115 should 'display_filter show person public content of private person profile for user friends' do
@@ -2099,8 +2120,8 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2099,8 +2120,8 @@ class ArticleTest &lt; ActiveSupport::TestCase
2099 user.stubs(:has_permission?).with(:view_private_content, p).returns(false) 2120 user.stubs(:has_permission?).with(:view_private_content, p).returns(false)
2100 Article.delete_all 2121 Article.delete_all
2101 a = fast_create(Article, :published => true, :profile_id => p.id) 2122 a = fast_create(Article, :published => true, :profile_id => p.id)
2102 - fast_create(Article, :published => false, :profile_id => p.id)  
2103 - fast_create(Article, :published => false, :profile_id => p.id) 2123 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
  2124 + fast_create(Article, :published => false, :show_to_followers => false, :profile_id => p.id)
2104 assert_equal [a], Article.display_filter(user, p) 2125 assert_equal [a], Article.display_filter(user, p)
2105 end 2126 end
2106 2127
@@ -2130,7 +2151,7 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -2130,7 +2151,7 @@ class ArticleTest &lt; ActiveSupport::TestCase
2130 a1 = fast_create(Article, :published => true, :profile_id => user.id) 2151 a1 = fast_create(Article, :published => true, :profile_id => user.id)
2131 a2 = fast_create(Article, :published => true, :profile_id => p.id) 2152 a2 = fast_create(Article, :published => true, :profile_id => p.id)
2132 fast_create(Article, :published => false, :profile_id => p.id) 2153 fast_create(Article, :published => false, :profile_id => p.id)
2133 - assert_equivalent [a1,a2], Article.display_filter(user, nil) 2154 + assert_equivalent [a1,a2], Article.display_filter(nil, user)
2134 end 2155 end
2135 2156
2136 end 2157 end
test/unit/environment_test.rb
@@ -524,7 +524,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -524,7 +524,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
524 p1= fast_create(Person, :is_template => true, :environment_id => e.id) 524 p1= fast_create(Person, :is_template => true, :environment_id => e.id)
525 p2 = fast_create(Person, :environment_id => e.id) 525 p2 = fast_create(Person, :environment_id => e.id)
526 p3 = fast_create(Person, :is_template => true, :environment_id => e.id) 526 p3 = fast_create(Person, :is_template => true, :environment_id => e.id)
527 - assert_equivalent [p1,p3], e.person_templates 527 + assert_equivalent [p1,p3], e.person_templates
528 end 528 end
529 529
530 should 'person_templates return an empty array if there is no templates of person' do 530 should 'person_templates return an empty array if there is no templates of person' do
@@ -532,7 +532,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -532,7 +532,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
532 532
533 fast_create(Person, :environment_id => e.id) 533 fast_create(Person, :environment_id => e.id)
534 fast_create(Person, :environment_id => e.id) 534 fast_create(Person, :environment_id => e.id)
535 - assert_equivalent [], e.person_templates 535 + assert_equivalent [], e.person_templates
536 end 536 end
537 537
538 should 'person_default_template return the template defined as default' do 538 should 'person_default_template return the template defined as default' do
@@ -585,7 +585,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -585,7 +585,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
585 c1= fast_create(Community, :is_template => true, :environment_id => e.id) 585 c1= fast_create(Community, :is_template => true, :environment_id => e.id)
586 c2 = fast_create(Community, :environment_id => e.id) 586 c2 = fast_create(Community, :environment_id => e.id)
587 c3 = fast_create(Community, :is_template => true, :environment_id => e.id) 587 c3 = fast_create(Community, :is_template => true, :environment_id => e.id)
588 - assert_equivalent [c1,c3], e.community_templates 588 + assert_equivalent [c1,c3], e.community_templates
589 end 589 end
590 590
591 should 'community_templates return an empty array if there is no templates of community' do 591 should 'community_templates return an empty array if there is no templates of community' do
@@ -646,7 +646,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -646,7 +646,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
646 e1= fast_create(Enterprise, :is_template => true, :environment_id => env.id) 646 e1= fast_create(Enterprise, :is_template => true, :environment_id => env.id)
647 e2 = fast_create(Enterprise, :environment_id => env.id) 647 e2 = fast_create(Enterprise, :environment_id => env.id)
648 e3 = fast_create(Enterprise, :is_template => true, :environment_id => env.id) 648 e3 = fast_create(Enterprise, :is_template => true, :environment_id => env.id)
649 - assert_equivalent [e1,e3], env.enterprise_templates 649 + assert_equivalent [e1,e3], env.enterprise_templates
650 end 650 end
651 651
652 should 'enterprise_templates return an empty array if there is no templates of enterprise' do 652 should 'enterprise_templates return an empty array if there is no templates of enterprise' do
@@ -654,7 +654,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -654,7 +654,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
654 654
655 fast_create(Enterprise, :environment_id => env.id) 655 fast_create(Enterprise, :environment_id => env.id)
656 fast_create(Enterprise, :environment_id => env.id) 656 fast_create(Enterprise, :environment_id => env.id)
657 - assert_equivalent [], env.enterprise_templates 657 + assert_equivalent [], env.enterprise_templates
658 end 658 end
659 659
660 should 'enterprise_default_template return the template defined as default' do 660 should 'enterprise_default_template return the template defined as default' do
@@ -1428,6 +1428,36 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -1428,6 +1428,36 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1428 assert !environment.plugin_enabled?(Plugin) 1428 assert !environment.plugin_enabled?(Plugin)
1429 end 1429 end
1430 1430
  1431 + should 'activate on database all available plugins' do
  1432 + plugins_enable = ["Statistics", "Foo", "PeopleBlock"]
  1433 + Noosfero::Plugins.stubs(:available_plugin_names).returns(plugins_enable)
  1434 + env1 = Environment.create(:name => "Test")
  1435 + env2 = Environment.create(:name => "Test 2")
  1436 +
  1437 + env1.enable_all_plugins
  1438 + env2.enable_all_plugins
  1439 +
  1440 + plugins = ["PeopleBlockPlugin", "StatisticsPlugin", "FooPlugin"]
  1441 + plugins.each do |plugin|
  1442 + assert env1.enabled_plugins.include?(plugin)
  1443 + assert env2.enabled_plugins.include?(plugin)
  1444 + end
  1445 + end
  1446 +
  1447 + should 'dont activate plugins that are not available' do
  1448 + env1 = Environment.create(:name => "Test")
  1449 + env2 = Environment.create(:name => "Test 2")
  1450 +
  1451 + env1.enable_all_plugins
  1452 + env2.enable_all_plugins
  1453 +
  1454 + plugins = ["SomePlugin", "OtherPlugin", "ThirdPlugin"]
  1455 + plugins.each do |plugin|
  1456 + assert_equal false, env1.enabled_plugins.include?(plugin)
  1457 + assert_equal false, env2.enabled_plugins.include?(plugin)
  1458 + end
  1459 + end
  1460 +
1431 should 'have production costs' do 1461 should 'have production costs' do
1432 assert_respond_to Environment.default, :production_costs 1462 assert_respond_to Environment.default, :production_costs
1433 end 1463 end
test/unit/folder_helper_test.rb
@@ -68,7 +68,7 @@ class FolderHelperTest &lt; ActionView::TestCase @@ -68,7 +68,7 @@ class FolderHelperTest &lt; ActionView::TestCase
68 profile.public_profile = false 68 profile.public_profile = false
69 profile.save! 69 profile.save!
70 profile2 = create_user('Folder Viwer').person 70 profile2 = create_user('Folder Viwer').person
71 - folder = fast_create(Folder, :profile_id => profile.id) 71 + folder = fast_create(Folder, :profile_id => profile.id, :published => false)
72 article = fast_create(Article, {:parent_id => folder.id, :profile_id => profile.id}) 72 article = fast_create(Article, {:parent_id => folder.id, :profile_id => profile.id})
73 73
74 result = available_articles(folder.children, profile2) 74 result = available_articles(folder.children, profile2)
test/unit/forum_test.rb
@@ -174,4 +174,70 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -174,4 +174,70 @@ class ForumTest &lt; ActiveSupport::TestCase
174 assert_equal true, Forum.find(forum.id).agrees_with_terms?(person) 174 assert_equal true, Forum.find(forum.id).agrees_with_terms?(person)
175 end 175 end
176 176
  177 + should 'always allow topic creation to the person himself' do
  178 + person = fast_create(Person)
  179 + someone = fast_create(Person)
  180 + forum = Forum.new(:profile => person)
  181 +
  182 + assert forum.can_create_topic?(person)
  183 + assert !forum.can_create_topic?(someone)
  184 + end
  185 +
  186 + should 'always allow topic creation to profile admins' do
  187 + admin = fast_create(Person)
  188 + someone = fast_create(Person)
  189 + profile = fast_create(Profile)
  190 + admins = [admin]
  191 + profile.stubs(:admins).returns(admins)
  192 + forum = Forum.new(:profile => profile)
  193 +
  194 + assert forum.can_create_topic?(admin)
  195 + assert !forum.can_create_topic?(someone)
  196 + end
  197 +
  198 + should 'always allow topic creation to environment admins' do
  199 + admin = fast_create(Person)
  200 + someone = fast_create(Person)
  201 + profile = fast_create(Profile)
  202 + admins = [admin]
  203 + environment = profile.environment
  204 + environment.stubs(:admins).returns(admins)
  205 + forum = Forum.new(:profile => profile)
  206 +
  207 + assert forum.can_create_topic?(admin)
  208 + assert !forum.can_create_topic?(someone)
  209 + end
  210 +
  211 + should 'allow only person friends to create topics when topic_creation is related' do
  212 + person = fast_create(Person)
  213 + friend = fast_create(Person)
  214 + someone = fast_create(Person)
  215 + friends = [friend]
  216 + person.stubs(:friends).returns(friends)
  217 + forum = Forum.new(:profile => person, :topic_creation => 'related')
  218 +
  219 + assert forum.can_create_topic?(friend)
  220 + assert !forum.can_create_topic?(someone)
  221 + end
  222 +
  223 + should 'allow only group members to create topics when topic_creation is related' do
  224 + organization = fast_create(Organization)
  225 + member = fast_create(Person)
  226 + someone = fast_create(Person)
  227 + members = [member]
  228 + organization.stubs(:members).returns(members)
  229 + forum = Forum.new(:profile => organization, :topic_creation => 'related')
  230 +
  231 + assert forum.can_create_topic?(member)
  232 + assert !forum.can_create_topic?(someone)
  233 + end
  234 +
  235 + should 'allow every user to create topics when topic_creation is users' do
  236 + profile = fast_create(Profile)
  237 + user = fast_create(Person)
  238 + forum = Forum.new(:profile => profile, :topic_creation => 'users')
  239 +
  240 + assert forum.can_create_topic?(user)
  241 + assert !forum.can_create_topic?(nil)
  242 + end
177 end 243 end
test/unit/profile_test.rb
@@ -1122,6 +1122,23 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1122,6 +1122,23 @@ class ProfileTest &lt; ActiveSupport::TestCase
1122 assert_equal 'default title', p.boxes[0].blocks.first[:title] 1122 assert_equal 'default title', p.boxes[0].blocks.first[:title]
1123 end 1123 end
1124 1124
  1125 + should 'have blocks observer on template when applying template with mirror' do
  1126 + template = fast_create(Profile)
  1127 + template.boxes.destroy_all
  1128 + template.boxes << Box.new
  1129 + b = Block.new(:title => 'default title', :mirror => true)
  1130 + template.boxes[0].blocks << b
  1131 +
  1132 + p = create(Profile)
  1133 + assert !b[:title].blank?
  1134 +
  1135 + p.copy_blocks_from(template)
  1136 +
  1137 + assert_equal 'default title', p.boxes[0].blocks.first[:title]
  1138 + assert_equal p.boxes[0].blocks.first, template.boxes[0].blocks.first.observers.first
  1139 +
  1140 + end
  1141 +
1125 TMP_THEMES_DIR = Rails.root.join('test', 'tmp', 'profile_themes') 1142 TMP_THEMES_DIR = Rails.root.join('test', 'tmp', 'profile_themes')
1126 should 'have themes' do 1143 should 'have themes' do
1127 Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR) 1144 Theme.stubs(:user_themes_dir).returns(TMP_THEMES_DIR)
test/unit/task_mailer_test.rb
@@ -119,7 +119,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -119,7 +119,7 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
119 assert_match(/#{task.target_notification_description}/, mail.subject) 119 assert_match(/#{task.target_notification_description}/, mail.subject)
120 120
121 assert_equal "Hello friend name, my name invite you, please follow this link: http://example.com/account/signup?invitation_code=123456", mail.body.to_s 121 assert_equal "Hello friend name, my name invite you, please follow this link: http://example.com/account/signup?invitation_code=123456", mail.body.to_s
122 - 122 +
123 mail.deliver 123 mail.deliver
124 assert !ActionMailer::Base.deliveries.empty? 124 assert !ActionMailer::Base.deliveries.empty?
125 end 125 end
@@ -135,6 +135,36 @@ class TaskMailerTest &lt; ActiveSupport::TestCase @@ -135,6 +135,36 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
135 assert_equal 'My name <email@example.com>', TaskMailer.generate_from(task) 135 assert_equal 'My name <email@example.com>', TaskMailer.generate_from(task)
136 end 136 end
137 137
  138 + should 'return the email with the subdirectory defined' do
  139 + Noosfero.stubs(:root).returns('/subdir')
  140 +
  141 + task = InviteFriend.new
  142 + task.expects(:code).returns('123456')
  143 +
  144 + task.stubs(:message).returns('Hello <friend>, <user> invite you, please follow this link: <url>')
  145 + task.expects(:friend_email).returns('friend@exemple.com')
  146 + task.expects(:friend_name).returns('friend name').at_least_once
  147 +
  148 + requestor = mock()
  149 + requestor.stubs(:name).returns('my name')
  150 + requestor.stubs(:public_profile_url).returns('requestor_path')
  151 +
  152 + environment = mock()
  153 + environment.expects(:noreply_email).returns('sender@example.com')
  154 + environment.expects(:default_hostname).returns('example.com')
  155 + environment.expects(:name).returns('example').at_least_once
  156 +
  157 + task.expects(:requestor).returns(requestor).at_least_once
  158 + task.expects(:person).returns(requestor).at_least_once
  159 + requestor.expects(:environment).returns(environment).at_least_once
  160 + task.expects(:environment).returns(environment).at_least_once
  161 +
  162 + mail = TaskMailer.invitation_notification(task)
  163 +
  164 + url_to_compare = "/subdir/account/signup"
  165 +
  166 + assert_match(/#{url_to_compare}/, mail.body.to_s)
  167 + end
138 168
139 private 169 private
140 def read_fixture(action) 170 def read_fixture(action)
util/chat/apache/xmpp.conf
1 # If your XMPP XMPP/BOSH isn't in localhost, change the config below to correct 1 # If your XMPP XMPP/BOSH isn't in localhost, change the config below to correct
2 # point to address 2 # point to address
3 3
  4 + RewriteEngine On
4 RewriteRule /http-bind http://localhost:5280/http-bind [P,QSA,L] 5 RewriteRule /http-bind http://localhost:5280/http-bind [P,QSA,L]
5 <Proxy http://localhost:5280/http-bind> 6 <Proxy http://localhost:5280/http-bind>
6 Order Allow,Deny 7 Order Allow,Deny