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 12 @article = article
13 13  
14 14 visibility_options(@article, tokenized_children) +
  15 + topic_creation(@article) +
15 16 content_tag('h4', _('Options')) +
16 17 content_tag('div',
17 18 (article.profile.has_members? ?
... ... @@ -55,14 +56,7 @@ module ArticleHelper
55 56 'div',
56 57 check_box(:article, :display_versions) +
57 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 61 end
68 62  
... ... @@ -81,6 +75,22 @@ module ArticleHelper
81 75 )
82 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 94 def privacity_exceptions(article, tokenized_children)
85 95 content_tag('div',
86 96 content_tag('div',
... ...
app/models/forum.rb
... ... @@ -3,11 +3,11 @@ class Forum < Folder
3 3 acts_as_having_posts :order => 'updated_at DESC'
4 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 8 settings_items :terms_of_use, :type => :string, :default => ""
9 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 11 has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
12 12  
13 13 before_save do |forum|
... ... @@ -33,6 +33,23 @@ class Forum < Folder
33 33 _('An internet forum, also called message board, where discussions can be held.')
34 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 53 include ActionView::Helpers::TagHelper
37 54 def to_html(options = {})
38 55 proc do
... ... @@ -69,11 +86,17 @@ class Forum < Folder
69 86 self.users_with_agreement.exists? user
70 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 97 end
75 98  
76 99 def allow_create?(user)
77   - super || can_create_topic?(user, profile)
  100 + super || can_create_topic?(user)
78 101 end
79 102 end
... ...
db/migrate/20150513213939_update_topic_creation_configuration.rb 0 → 100644
... ... @@ -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 169 | Post one | joaosilva | Hi all | Hi all |
170 170 When I go to /joaosilva/forum
171 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 @@
  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 6239 .forum-posts .pagination {
6240 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 6256 /* Task */
6243 6257  
6244 6258 #user a#pending-tasks-count {
... ...
test/unit/forum_test.rb
... ... @@ -174,4 +174,70 @@ class ForumTest &lt; ActiveSupport::TestCase
174 174 assert_equal true, Forum.find(forum.id).agrees_with_terms?(person)
175 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 243 end
... ...