Commit 7c9de6dbf20c05d58abd5e951423d96e3746aa54

Authored by Rodrigo Souto
1 parent 82270a3f

forum: improved topic creation permissions configuration

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/models/forum.rb
@@ -3,11 +3,11 @@ class Forum < Folder @@ -3,11 +3,11 @@ class Forum < 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 < Folder @@ -33,6 +33,23 @@ class Forum < 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 < Folder @@ -69,11 +86,17 @@ class Forum < 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
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
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"  
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
@@ -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 {
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