Commit 91db1c995e9f5260478526428bffdc8282a8ba3d
Exists in
master
and in
29 other branches
Merge branch 'master' of https://gitlab.com/noosfero/noosfero
Showing
13 changed files
with
248 additions
and
22 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
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 < Folder | @@ -39,4 +54,16 @@ class Forum < 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 < Profile | @@ -63,6 +63,8 @@ class Person < 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 %> |
| @@ -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 |
db/schema.rb
| @@ -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 => 20131121162641) do | @@ -566,6 +566,13 @@ ActiveRecord::Schema.define(:version => 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 < ActionController::TestCase | @@ -1324,10 +1324,11 @@ class CmsControllerTest < 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 < ActionController::TestCase | @@ -1697,6 +1698,16 @@ class CmsControllerTest < 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 < ActiveSupport::TestCase | @@ -133,4 +133,44 @@ class ForumTest < 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 |