Commit 91db1c995e9f5260478526428bffdc8282a8ba3d

Authored by Rodrigo Souto
2 parents fa2713e7 527a4b0d

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

app/controllers/my_profile/cms_controller.rb
@@ -387,4 +387,3 @@ class CmsController < MyProfileController @@ -387,4 +387,3 @@ class CmsController < MyProfileController
387 end 387 end
388 388
389 end 389 end
390 -  
app/controllers/public/content_viewer_controller.rb
@@ -50,6 +50,16 @@ class ContentViewerController < ApplicationController @@ -50,6 +50,16 @@ class ContentViewerController < ApplicationController
50 50
51 redirect_to_translation if @page.profile.redirect_l10n 51 redirect_to_translation if @page.profile.redirect_l10n
52 52
  53 + if request.post?
  54 + if @page.forum? && @page.has_terms_of_use && params[:terms_accepted] == "true"
  55 + @page.add_agreed_user(user)
  56 + end
  57 + elsif !@page.parent.nil? && @page.parent.forum?
  58 + unless @page.parent.agrees_with_terms?(user)
  59 + redirect_to @page.parent.url
  60 + end
  61 + end
  62 +
53 # At this point the page will be showed 63 # At this point the page will be showed
54 @page.hit 64 @page.hit
55 65
app/models/forum.rb
@@ -3,6 +3,21 @@ class Forum < Folder @@ -3,6 +3,21 @@ 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 + settings_items :terms_of_use, :type => :string, :default => ""
  7 + settings_items :has_terms_of_use, :type => :boolean, :default => false
  8 + has_and_belongs_to_many :users_with_agreement, :class_name => 'Person', :join_table => 'terms_forum_people'
  9 +
  10 + before_save do |forum|
  11 + if forum.has_terms_of_use
  12 + last_editor = forum.profile.environment.people.find_by_id(forum.last_changed_by_id)
  13 + if last_editor && !forum.users_with_agreement.exists?(last_editor)
  14 + forum.users_with_agreement << last_editor
  15 + end
  16 + else
  17 + forum.users_with_agreement.clear
  18 + end
  19 + end
  20 +
6 def self.type_name 21 def self.type_name
7 _('Forum') 22 _('Forum')
8 end 23 end
@@ -39,4 +54,16 @@ class Forum &lt; Folder @@ -39,4 +54,16 @@ class Forum &lt; Folder
39 paragraphs = Hpricot(body).search('p') 54 paragraphs = Hpricot(body).search('p')
40 paragraphs.empty? ? '' : paragraphs.first.to_html 55 paragraphs.empty? ? '' : paragraphs.first.to_html
41 end 56 end
  57 +
  58 + def add_agreed_user(user)
  59 + self.users_with_agreement << user
  60 + self.save
  61 + end
  62 +
  63 + def agrees_with_terms?(user)
  64 + return true unless self.has_terms_of_use
  65 + return false unless user
  66 + self.users_with_agreement.exists? user
  67 + end
  68 +
42 end 69 end
app/models/person.rb
@@ -63,6 +63,8 @@ class Person &lt; Profile @@ -63,6 +63,8 @@ class Person &lt; Profile
63 63
64 has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy 64 has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy
65 65
  66 + has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people'
  67 +
66 named_scope :more_popular, 68 named_scope :more_popular,
67 :select => "#{Profile.qualified_column_names}, count(friend_id) as total", 69 :select => "#{Profile.qualified_column_names}, count(friend_id) as total",
68 :group => Profile.qualified_column_names, 70 :group => Profile.qualified_column_names,
app/views/cms/_forum.rhtml
@@ -11,3 +11,9 @@ @@ -11,3 +11,9 @@
11 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %> 11 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %>
12 12
13 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Forum.posts_per_page_options)) %> 13 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Forum.posts_per_page_options)) %>
  14 +
  15 +<%= labelled_form_field(_('Has terms of use:'), check_box(:article, :has_terms_of_use))%>
  16 +
  17 +<div id="text_area_terms_of_use">
  18 + <%= labelled_form_field(_('Terms of use:'), text_area(:article, :terms_of_use, :class => 'mceEditor',:cols => 64, :rows => 10)) %>
  19 +</div>
app/views/content_viewer/forum_page.rhtml
1 <% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.forum? && @page.feed %> 1 <% add_rss_feed_to_head(@page.name, @page.feed.url) if @page.forum? && @page.feed %>
  2 +<% if @page.agrees_with_terms?(user) %>
2 3
3 -<div>  
4 - <div class='forum-description'>  
5 - <%= @page.body %> 4 + <div>
  5 + <div class='forum-description'>
  6 + <%= @page.body %>
  7 + </div>
6 </div> 8 </div>
7 -</div>  
8 -<hr class="pre-posts"/>  
9 -<div class="forum-posts">  
10 - <%= (@posts.compact.empty? ? content_tag('em', _('(no posts)')) : list_forum_posts(@posts)) %>  
11 -</div> 9 + <hr class="pre-posts"/>
  10 + <div class="forum-posts">
  11 + <%= (@posts.compact.empty? ? content_tag('em', _('(no posts)')) : list_forum_posts(@posts)) %>
  12 + </div>
  13 +
  14 +<% else %>
  15 +
  16 + <p><%= @page.terms_of_use %></p>
  17 +
  18 + <% form_tag @page.url.merge(:terms_accepted => true) do %>
  19 + <% button_bar do %>
  20 + <% if user %>
  21 + <%= submit_button :save, _("Accept") %>
  22 + <% else %>
  23 + <%= button :save, _("Accept"), login_url %>
  24 + <% end %>
  25 + <%= button :cancel, _("Cancel"), profile.url %>
  26 + <% end %>
  27 + <% end %>
  28 +<% end %>
db/migrate/20131128161159_terms_forum_people.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class TermsForumPeople < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :terms_forum_people, :id => false do |t|
  4 + t.integer :forum_id
  5 + t.integer :person_id
  6 + end
  7 + add_index :terms_forum_people, [:forum_id, :person_id]
  8 + end
  9 +
  10 + def self.down
  11 + remove_index :terms_forum_people, [:forum_id, :person_id]
  12 + drop_table :terms_forum_people
  13 + end
  14 +
  15 +end
0 \ No newline at end of file 16 \ No newline at end of file
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 # 9 #
10 # It's strongly recommended to check this file into your version control system. 10 # It's strongly recommended to check this file into your version control system.
11 11
12 -ActiveRecord::Schema.define(:version => 20131121162641) do 12 +ActiveRecord::Schema.define(:version => 20131128161159) do
13 13
14 create_table "abuse_reports", :force => true do |t| 14 create_table "abuse_reports", :force => true do |t|
15 t.integer "reporter_id" 15 t.integer "reporter_id"
@@ -566,6 +566,13 @@ ActiveRecord::Schema.define(:version =&gt; 20131121162641) do @@ -566,6 +566,13 @@ ActiveRecord::Schema.define(:version =&gt; 20131121162641) do
566 566
567 add_index "tasks", ["spam"], :name => "index_tasks_on_spam" 567 add_index "tasks", ["spam"], :name => "index_tasks_on_spam"
568 568
  569 + create_table "terms_forum_people", :id => false, :force => true do |t|
  570 + t.integer "forum_id"
  571 + t.integer "person_id"
  572 + end
  573 +
  574 + add_index "terms_forum_people", ["forum_id", "person_id"], :name => "index_terms_forum_people_on_forum_id_and_person_id"
  575 +
569 create_table "thumbnails", :force => true do |t| 576 create_table "thumbnails", :force => true do |t|
570 t.integer "size" 577 t.integer "size"
571 t.string "content_type" 578 t.string "content_type"
features/forum.feature
@@ -70,28 +70,99 @@ Feature: forum @@ -70,28 +70,99 @@ Feature: forum
70 When I follow "Configure forum" 70 When I follow "Configure forum"
71 Then I should be on edit "Forum One" by joaosilva 71 Then I should be on edit "Forum One" by joaosilva
72 72
  73 + @selenium
  74 + Scenario: show forum with terms of use for owner
  75 + Given the following forums
  76 + | owner | name |
  77 + | joaosilva | Forum One |
  78 + And I go to /joaosilva/forum-one
  79 + When I follow "Configure forum"
  80 + And I fill in "Description" with "My description"
  81 + And I check "Has terms of use:"
  82 + And I press "Save"
  83 + Then I should see "Forum One"
  84 + And I should see "My description"
  85 +
  86 + @selenium
  87 + Scenario: accept terms in topics page
  88 + Given the following forums
  89 + | owner | name |
  90 + | joaosilva | Forum One |
  91 + And the following users
  92 + | login | name |
  93 + | mariasilva | Maria Silva |
  94 + And I go to /joaosilva/forum-one
  95 + When I follow "Configure forum"
  96 + And I fill in "Description" with "My description"
  97 + And I check "Has terms of use:"
  98 + And I press "Save"
  99 + When I follow "New discussion topic"
  100 + And I follow "Text article with visual editor"
  101 + And I fill in "Title" with "Topic"
  102 + And I press "Save"
  103 + And I am logged in as "mariasilva"
  104 + And I go to /joaosilva/forum-one/topic
  105 + And I press "Accept"
  106 + Then I should see "Topic"
  107 +
  108 + @selenium
  109 + Scenario: accept terms of use of a forum for others users
  110 + Given the following forums
  111 + | owner | name |
  112 + | joaosilva | Forum One |
  113 + And the following users
  114 + | login | name |
  115 + | mariasilva | Maria Silva |
  116 + And I go to /joaosilva/forum-one
  117 + When I follow "Configure forum"
  118 + And I fill in "Description" with "My description"
  119 + And I check "Has terms of use:"
  120 + And I press "Save"
  121 + When I follow "Logout"
  122 + And I am logged in as "mariasilva"
  123 + And I go to /joaosilva/forum-one?terms=terms
  124 + When I press "Accept"
  125 + Then I should see "Forum One"
  126 + And I should see "My description"
  127 +
  128 + @selenium
  129 + Scenario: redirect user not logged
  130 + Given the following forums
  131 + | owner | name |
  132 + | joaosilva | Forum One |
  133 + And I go to /joaosilva/forum-one
  134 + When I follow "Configure forum"
  135 + And I fill in "Description" with "My description"
  136 + And I check "Has terms of use:"
  137 + And I press "Save"
  138 + When I follow "Logout"
  139 + And I go to /joaosilva/forum-one?terms=terms
  140 + When I follow "Accept"
  141 + Then I should see "Login" within ".login-box"
  142 +
  143 + @selenium
73 Scenario: last topic update by unautenticated user should not link 144 Scenario: last topic update by unautenticated user should not link
74 Given the following forums 145 Given the following forums
75 - | owner | name | 146 + | owner | name |
76 | joaosilva | Forum | 147 | joaosilva | Forum |
77 And the following articles 148 And the following articles
78 - | owner | name | parent |  
79 - | joaosilva | Post one | Forum | 149 + | owner | name | parent |
  150 + | joaosilva | Post one | Forum |
80 And the following comments 151 And the following comments
81 - | article | name | email | title | body | 152 + | article | name | email | title | body |
82 | Post one | Joao | joao@example.com | Hi all | Hi all | 153 | Post one | Joao | joao@example.com | Hi all | Hi all |
83 When I go to /joaosilva/forum 154 When I go to /joaosilva/forum
84 Then I should not see "Joao" link 155 Then I should not see "Joao" link
85 156
86 Scenario: last topic update by autenticated user should link to profile url 157 Scenario: last topic update by autenticated user should link to profile url
87 Given the following forums 158 Given the following forums
88 - | owner | name | 159 + | owner | name |
89 | joaosilva | Forum | 160 | joaosilva | Forum |
90 And the following articles 161 And the following articles
91 - | owner | name | parent |  
92 - | joaosilva | Post one | Forum | 162 + | owner | name | parent |
  163 + | joaosilva | Post one | Forum |
93 And the following comments 164 And the following comments
94 - | article | author | title | body | 165 + | article | author | title | body |
95 | Post one | joaosilva | Hi all | Hi all | 166 | Post one | joaosilva | Hi all | Hi all |
96 When I go to /joaosilva/forum 167 When I go to /joaosilva/forum
97 Then I should see "Joao" linking to "http://localhost/joaosilva" 168 Then I should see "Joao" linking to "http://localhost/joaosilva"
public/javascripts/application.js
@@ -1084,3 +1084,21 @@ jQuery(function($) { @@ -1084,3 +1084,21 @@ jQuery(function($) {
1084 }); 1084 });
1085 1085
1086 }); 1086 });
  1087 +
  1088 +function showHideTermsOfUse() {
  1089 + if( jQuery("#article_has_terms_of_use").attr("checked") )
  1090 + jQuery("#text_area_terms_of_use").show();
  1091 + else {
  1092 + jQuery("#text_area_terms_of_use").hide();
  1093 + jQuery("#article_terms_of_use").val("");
  1094 + jQuery("#article_terms_of_use_ifr").contents().find("body").html("");
  1095 + }
  1096 +}
  1097 +
  1098 +jQuery(document).ready(function(){
  1099 + showHideTermsOfUse();
  1100 +
  1101 + jQuery("#article_has_terms_of_use").click(function(){
  1102 + showHideTermsOfUse();
  1103 + });
  1104 +});
1087 \ No newline at end of file 1105 \ No newline at end of file
public/stylesheets/application.css
@@ -3338,6 +3338,9 @@ table.cms-articles .icon:hover { @@ -3338,6 +3338,9 @@ table.cms-articles .icon:hover {
3338 div.with_media_panel .formfield input { 3338 div.with_media_panel .formfield input {
3339 width: 100%; 3339 width: 100%;
3340 } 3340 }
  3341 +div.with_media_panel .formfield input[type="checkbox"] {
  3342 + width: auto;
  3343 +}
3341 3344
3342 .text-editor-sidebar { 3345 .text-editor-sidebar {
3343 position: absolute; 3346 position: absolute;
test/functional/cms_controller_test.rb
@@ -1324,10 +1324,11 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1324,10 +1324,11 @@ class CmsControllerTest &lt; ActionController::TestCase
1324 end 1324 end
1325 1325
1326 should 'back to forum after config forum' do 1326 should 'back to forum after config forum' do
1327 - profile.articles << Forum.new(:name => 'my-forum', :profile => profile)  
1328 - post :edit, :profile => profile.identifier, :id => profile.forum.id  
1329 -  
1330 - assert_redirected_to @profile.articles.find_by_name('my-forum').view_url 1327 + assert_difference Forum, :count do
  1328 + post :new, :type => Forum.name, :profile => profile.identifier, :article => { :name => 'my-forum' }, :back_to => 'control_panel'
  1329 + end
  1330 + post :edit, :type => Forum.name, :profile => profile.identifier, :article => { :name => 'my forum' }, :id => profile.forum.id
  1331 + assert_redirected_to @profile.articles.find_by_name('my forum').view_url
1331 end 1332 end
1332 1333
1333 should 'back to control panel if cancel create forum' do 1334 should 'back to control panel if cancel create forum' do
@@ -1697,6 +1698,16 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -1697,6 +1698,16 @@ class CmsControllerTest &lt; ActionController::TestCase
1697 :attributes => { :value => article.id.to_s }} 1698 :attributes => { :value => article.id.to_s }}
1698 end 1699 end
1699 1700
  1701 + should 'remove users that agreed with forum terms after removing terms' do
  1702 + forum = Forum.create(:name => 'Forum test', :profile_id => profile.id, :has_terms_of_use => true)
  1703 + person = fast_create(Person)
  1704 + forum.users_with_agreement << person
  1705 +
  1706 + assert_difference Forum.find(forum.id).users_with_agreement, :count, -1 do
  1707 + post :edit, :profile => profile.identifier, :id => forum.id, :article => { :has_terms_of_use => 'false' }
  1708 + end
  1709 + end
  1710 +
1700 protected 1711 protected
1701 1712
1702 # FIXME this is to avoid adding an extra dependency for a proper JSON parser. 1713 # FIXME this is to avoid adding an extra dependency for a proper JSON parser.
test/unit/forum_test.rb
@@ -133,4 +133,44 @@ class ForumTest &lt; ActiveSupport::TestCase @@ -133,4 +133,44 @@ class ForumTest &lt; ActiveSupport::TestCase
133 assert_equal '', f.first_paragraph 133 assert_equal '', f.first_paragraph
134 end 134 end
135 135
  136 + should 'include user that changes a forum as agreed with terms' do
  137 + author = fast_create(Person)
  138 + editor = fast_create(Person)
  139 + forum = Forum.create(:profile => author, :name => 'Forum test', :body => 'Forum test', :has_terms_of_use => true, :last_changed_by => author)
  140 + forum.last_changed_by = editor
  141 + forum.save
  142 +
  143 + assert_equivalent [author, editor], forum.users_with_agreement
  144 + end
  145 +
  146 + should 'not crash if forum has terms and last_changed does not exist' do
  147 + profile = fast_create(Person)
  148 + forum = Forum.create(:profile => profile, :name => 'Forum test', :body => 'Forum test', :has_terms_of_use => true)
  149 +
  150 + assert_equal [], forum.users_with_agreement
  151 + end
  152 +
  153 + should 'agree with terms if forum doesn\'t have terms' do
  154 + person = fast_create(Person)
  155 + forum = fast_create(Forum)
  156 +
  157 + assert_equal true, forum.agrees_with_terms?(person)
  158 + end
  159 +
  160 + should 'not agree with terms if user is logged in but did not accept it' do
  161 + person = fast_create(Person)
  162 + forum = Forum.create(:profile => person, :name => 'Forum test', :body => 'Forum test', :has_terms_of_use => true)
  163 +
  164 + assert_equal false, forum.agrees_with_terms?(person)
  165 + end
  166 +
  167 + should 'agree with terms if user is logged in and accept it' do
  168 + person = fast_create(Person)
  169 + forum = Forum.create(:profile => person, :name => 'Forum test', :body => 'Forum test', :has_terms_of_use => true)
  170 + forum.users_with_agreement << person
  171 + forum.save
  172 +
  173 + assert_equal true, Forum.find(forum.id).agrees_with_terms?(person)
  174 + end
  175 +
136 end 176 end