Commit d1609c731d1a14066b2864a25196f5bbeb69b4a9
Exists in
master
and in
28 other branches
Merge remote branch 'unb-gama/AI2852-article_access_level' into AI2852
Conflicts: app/models/person.rb db/schema.rb
Showing
15 changed files
with
226 additions
and
79 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -2,6 +2,8 @@ class CmsController < MyProfileController | @@ -2,6 +2,8 @@ class CmsController < MyProfileController | ||
2 | 2 | ||
3 | protect 'edit_profile', :profile, :only => [:set_home_page] | 3 | protect 'edit_profile', :profile, :only => [:set_home_page] |
4 | 4 | ||
5 | + include ArticleHelper | ||
6 | + | ||
5 | def self.protect_if(*args) | 7 | def self.protect_if(*args) |
6 | before_filter(*args) do |c| | 8 | before_filter(*args) do |c| |
7 | user, profile = c.send(:user), c.send(:profile) | 9 | user, profile = c.send(:user), c.send(:profile) |
@@ -70,6 +72,14 @@ class CmsController < MyProfileController | @@ -70,6 +72,14 @@ class CmsController < MyProfileController | ||
70 | translations if @article.translatable? | 72 | translations if @article.translatable? |
71 | continue = params[:continue] | 73 | continue = params[:continue] |
72 | 74 | ||
75 | + @article.article_privacy_exceptions = params[:q].split(/,/).map{|n| environment.people.find n.to_i} unless params[:q].nil? | ||
76 | + | ||
77 | + @tokenized_children = prepare_to_token_input( | ||
78 | + profile.members.map{|m| | ||
79 | + m if @article.article_privacy_exceptions.include?(m) | ||
80 | + }.compact | ||
81 | + ) | ||
82 | + | ||
73 | refuse_blocks | 83 | refuse_blocks |
74 | record_coming | 84 | record_coming |
75 | if request.post? | 85 | if request.post? |
@@ -130,6 +140,8 @@ class CmsController < MyProfileController | @@ -130,6 +140,8 @@ class CmsController < MyProfileController | ||
130 | 140 | ||
131 | continue = params[:continue] | 141 | continue = params[:continue] |
132 | if request.post? | 142 | if request.post? |
143 | + @article.article_privacy_exceptions = params[:q].split(/,/).map{|n| environment.people.find n.to_i} unless params[:q].nil? | ||
144 | + | ||
133 | if @article.save | 145 | if @article.save |
134 | if continue | 146 | if continue |
135 | redirect_to :action => 'edit', :id => @article | 147 | redirect_to :action => 'edit', :id => @article |
@@ -290,6 +302,12 @@ class CmsController < MyProfileController | @@ -290,6 +302,12 @@ class CmsController < MyProfileController | ||
290 | render :text => article_list_to_json(results), :content_type => 'application/json' | 302 | render :text => article_list_to_json(results), :content_type => 'application/json' |
291 | end | 303 | end |
292 | 304 | ||
305 | + def search_article_privacy_exceptions | ||
306 | + arg = params[:q].downcase | ||
307 | + result = profile.members.find(:all, :conditions => ['LOWER(name) LIKE ?', "%#{arg}%"]) | ||
308 | + render :text => prepare_to_token_input(result).to_json | ||
309 | + end | ||
310 | + | ||
293 | def media_upload | 311 | def media_upload |
294 | files_uploaded = [] | 312 | files_uploaded = [] |
295 | parent = check_parent(params[:parent_id]) | 313 | parent = check_parent(params[:parent_id]) |
app/helpers/application_helper.rb
@@ -40,6 +40,8 @@ module ApplicationHelper | @@ -40,6 +40,8 @@ module ApplicationHelper | ||
40 | 40 | ||
41 | include Noosfero::Gravatar | 41 | include Noosfero::Gravatar |
42 | 42 | ||
43 | + include TokenHelper | ||
44 | + | ||
43 | def locale | 45 | def locale |
44 | (@page && !@page.language.blank?) ? @page.language : FastGettext.locale | 46 | (@page && !@page.language.blank?) ? @page.language : FastGettext.locale |
45 | end | 47 | end |
@@ -1300,10 +1302,6 @@ module ApplicationHelper | @@ -1300,10 +1302,6 @@ module ApplicationHelper | ||
1300 | content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs') | 1302 | content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs') |
1301 | end | 1303 | end |
1302 | 1304 | ||
1303 | - def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...')) | ||
1304 | - "hintText: '#{hintText}', noResultsText: '#{noResultsText}', searchingText: '#{searchingText}'" | ||
1305 | - end | ||
1306 | - | ||
1307 | def delete_article_message(article) | 1305 | def delete_article_message(article) |
1308 | if article.folder? | 1306 | if article.folder? |
1309 | _("Are you sure that you want to remove the folder \"#{article.name}\"? Note that all the items inside it will also be removed!") | 1307 | _("Are you sure that you want to remove the folder \"#{article.name}\"? Note that all the items inside it will also be removed!") |
@@ -1344,50 +1342,6 @@ module ApplicationHelper | @@ -1344,50 +1342,6 @@ module ApplicationHelper | ||
1344 | ) | 1342 | ) |
1345 | end | 1343 | end |
1346 | 1344 | ||
1347 | - def token_input_field_tag(name, element_id, search_action, options = {}, text_field_options = {}, html_options = {}) | ||
1348 | - options[:min_chars] ||= 3 | ||
1349 | - options[:hint_text] ||= _("Type in a search term") | ||
1350 | - options[:no_results_text] ||= _("No results") | ||
1351 | - options[:searching_text] ||= _("Searching...") | ||
1352 | - options[:search_delay] ||= 1000 | ||
1353 | - options[:prevent_duplicates] ||= true | ||
1354 | - options[:backspace_delete_item] ||= false | ||
1355 | - options[:focus] ||= false | ||
1356 | - options[:avoid_enter] ||= true | ||
1357 | - options[:on_result] ||= 'null' | ||
1358 | - options[:on_add] ||= 'null' | ||
1359 | - options[:on_delete] ||= 'null' | ||
1360 | - options[:on_ready] ||= 'null' | ||
1361 | - | ||
1362 | - result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) | ||
1363 | - result += javascript_tag("jQuery('##{element_id}') | ||
1364 | - .tokenInput('#{url_for(search_action)}', { | ||
1365 | - minChars: #{options[:min_chars].to_json}, | ||
1366 | - prePopulate: #{options[:pre_populate].to_json}, | ||
1367 | - hintText: #{options[:hint_text].to_json}, | ||
1368 | - noResultsText: #{options[:no_results_text].to_json}, | ||
1369 | - searchingText: #{options[:searching_text].to_json}, | ||
1370 | - searchDelay: #{options[:serach_delay].to_json}, | ||
1371 | - preventDuplicates: #{options[:prevent_duplicates].to_json}, | ||
1372 | - backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | ||
1373 | - queryParam: #{name.to_json}, | ||
1374 | - tokenLimit: #{options[:token_limit].to_json}, | ||
1375 | - onResult: #{options[:on_result]}, | ||
1376 | - onAdd: #{options[:on_add]}, | ||
1377 | - onDelete: #{options[:on_delete]}, | ||
1378 | - onReady: #{options[:on_ready]}, | ||
1379 | - }); | ||
1380 | - ") | ||
1381 | - result += javascript_tag("jQuery('##{element_id}').focus();") if options[:focus] | ||
1382 | - if options[:avoid_enter] | ||
1383 | - result += javascript_tag("jQuery('#token-input-#{element_id}') | ||
1384 | - .live('keydown', function(event){ | ||
1385 | - if(event.keyCode == '13') return false; | ||
1386 | - });") | ||
1387 | - end | ||
1388 | - result | ||
1389 | - end | ||
1390 | - | ||
1391 | def expirable_content_reference(content, action, text, url, options = {}) | 1345 | def expirable_content_reference(content, action, text, url, options = {}) |
1392 | reason = @plugins.dispatch("content_expire_#{action.to_s}", content).first | 1346 | reason = @plugins.dispatch("content_expire_#{action.to_s}", content).first |
1393 | options[:title] = reason | 1347 | options[:title] = reason |
app/helpers/article_helper.rb
1 | module ArticleHelper | 1 | module ArticleHelper |
2 | 2 | ||
3 | - def custom_options_for_article(article) | 3 | + include TokenHelper |
4 | + | ||
5 | + def custom_options_for_article(article, tokenized_children) | ||
4 | @article = article | 6 | @article = article |
5 | - content_tag('h4', _('Visibility')) + | ||
6 | - content_tag('div', | ||
7 | - content_tag('div', | ||
8 | - radio_button(:article, :published, true) + | ||
9 | - content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true') | ||
10 | - ) + | ||
11 | - content_tag('div', | ||
12 | - radio_button(:article, :published, false) + | ||
13 | - content_tag('label', _('Private'), :for => 'article_published_false') | ||
14 | - ) | ||
15 | - ) + | 7 | + |
8 | + visibility_options(@article, tokenized_children) + | ||
16 | content_tag('h4', _('Options')) + | 9 | content_tag('h4', _('Options')) + |
17 | content_tag('div', | 10 | content_tag('div', |
18 | (article.profile.has_members? ? | 11 | (article.profile.has_members? ? |
@@ -53,6 +46,28 @@ module ArticleHelper | @@ -53,6 +46,28 @@ module ArticleHelper | ||
53 | ) | 46 | ) |
54 | end | 47 | end |
55 | 48 | ||
49 | + def visibility_options(article, tokenized_children) | ||
50 | + content_tag('h4', _('Visibility')) + | ||
51 | + content_tag('div', | ||
52 | + content_tag('div', | ||
53 | + radio_button(:article, :published, true) + | ||
54 | + content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true') | ||
55 | + ) + | ||
56 | + content_tag('div', | ||
57 | + radio_button(:article, :published, false) + | ||
58 | + content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") | ||
59 | + ) + | ||
60 | + (article.profile.class == Community ? content_tag('div', | ||
61 | + content_tag('label', _('Fill in the search field to add the exception users to see this content'), :id => "text-input-search-exception-users") + | ||
62 | + token_input_field_tag(:q, 'search-article-privacy-exceptions', {:action => 'search_article_privacy_exceptions'}, | ||
63 | + {:focus => false, :hint_text => _('Type in a search term for a user'), :pre_populate => tokenized_children})) : | ||
64 | + '')) | ||
65 | + end | ||
66 | + | ||
67 | + def prepare_to_token_input(array) | ||
68 | + array.map { |object| {:id => object.id, :name => object.name} } | ||
69 | + end | ||
70 | + | ||
56 | def cms_label_for_new_children | 71 | def cms_label_for_new_children |
57 | _('New article') | 72 | _('New article') |
58 | end | 73 | end |
app/helpers/blog_helper.rb
1 | module BlogHelper | 1 | module BlogHelper |
2 | 2 | ||
3 | - def custom_options_for_article(article) | 3 | + include ArticleHelper |
4 | + | ||
5 | + def custom_options_for_article(article,tokenized_children) | ||
4 | @article = article | 6 | @article = article |
5 | hidden_field_tag('article[published]', 1) + | 7 | hidden_field_tag('article[published]', 1) + |
6 | - hidden_field_tag('article[accept_comments]', 0) | 8 | + hidden_field_tag('article[accept_comments]', 0) + |
9 | + visibility_options(article,tokenized_children) | ||
7 | end | 10 | end |
8 | 11 | ||
9 | def cms_label_for_new_children | 12 | def cms_label_for_new_children |
app/helpers/cms_helper.rb
@@ -22,9 +22,9 @@ module CmsHelper | @@ -22,9 +22,9 @@ module CmsHelper | ||
22 | 22 | ||
23 | attr_reader :environment | 23 | attr_reader :environment |
24 | 24 | ||
25 | - def options_for_article(article) | 25 | + def options_for_article(article, tokenized_children=nil) |
26 | article_helper = helper_for_article(article) | 26 | article_helper = helper_for_article(article) |
27 | - article_helper.custom_options_for_article(article) | 27 | + article_helper.custom_options_for_article(article, tokenized_children) |
28 | end | 28 | end |
29 | 29 | ||
30 | def link_to_article(article) | 30 | def link_to_article(article) |
app/helpers/folder_helper.rb
1 | module FolderHelper | 1 | module FolderHelper |
2 | 2 | ||
3 | include ShortFilename | 3 | include ShortFilename |
4 | + include ArticleHelper | ||
4 | 5 | ||
5 | def list_articles(articles, recursive = false) | 6 | def list_articles(articles, recursive = false) |
6 | if !articles.blank? | 7 | if !articles.blank? |
@@ -60,19 +61,10 @@ module FolderHelper | @@ -60,19 +61,10 @@ module FolderHelper | ||
60 | "icon-new icon-new%s" % klass.icon_name | 61 | "icon-new icon-new%s" % klass.icon_name |
61 | end | 62 | end |
62 | 63 | ||
63 | - def custom_options_for_article(article) | 64 | + def custom_options_for_article(article,tokenized_children) |
64 | @article = article | 65 | @article = article |
65 | - content_tag('h4', _('Visibility')) + | ||
66 | - content_tag('div', | ||
67 | - content_tag('div', | ||
68 | - radio_button(:article, :published, true) + | ||
69 | - content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true') | ||
70 | - ) + | ||
71 | - content_tag('div', | ||
72 | - radio_button(:article, :published, false) + | ||
73 | - content_tag('label', _('Private'), :for => 'article_published_false') | ||
74 | - ) | ||
75 | - ) + | 66 | + |
67 | + visibility_options(article,tokenized_children) + | ||
76 | content_tag('div', | 68 | content_tag('div', |
77 | hidden_field_tag('article[accept_comments]', 0) | 69 | hidden_field_tag('article[accept_comments]', 0) |
78 | ) | 70 | ) |
@@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
1 | +module TokenHelper | ||
2 | + | ||
3 | + def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...')) | ||
4 | + "hintText: '#{hintText}', noResultsText: '#{noResultsText}', searchingText: '#{searchingText}'" | ||
5 | + end | ||
6 | + | ||
7 | + def token_input_field_tag(name, element_id, search_action, options = {}, text_field_options = {}, html_options = {}) | ||
8 | + options[:min_chars] ||= 3 | ||
9 | + options[:hint_text] ||= _("Type in a search term") | ||
10 | + options[:no_results_text] ||= _("No results") | ||
11 | + options[:searching_text] ||= _("Searching...") | ||
12 | + options[:search_delay] ||= 1000 | ||
13 | + options[:prevent_duplicates] ||= true | ||
14 | + options[:backspace_delete_item] ||= false | ||
15 | + options[:focus] ||= false | ||
16 | + options[:avoid_enter] ||= true | ||
17 | + options[:on_result] ||= 'null' | ||
18 | + options[:on_add] ||= 'null' | ||
19 | + options[:on_delete] ||= 'null' | ||
20 | + options[:on_ready] ||= 'null' | ||
21 | + | ||
22 | + result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) | ||
23 | + result += javascript_tag("jQuery('##{element_id}') | ||
24 | + .tokenInput('#{url_for(search_action)}', { | ||
25 | + minChars: #{options[:min_chars].to_json}, | ||
26 | + prePopulate: #{options[:pre_populate].to_json}, | ||
27 | + hintText: #{options[:hint_text].to_json}, | ||
28 | + noResultsText: #{options[:no_results_text].to_json}, | ||
29 | + searchingText: #{options[:searching_text].to_json}, | ||
30 | + searchDelay: #{options[:serach_delay].to_json}, | ||
31 | + preventDuplicates: #{options[:prevent_duplicates].to_json}, | ||
32 | + backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | ||
33 | + queryParam: #{name.to_json}, | ||
34 | + tokenLimit: #{options[:token_limit].to_json}, | ||
35 | + onResult: #{options[:on_result]}, | ||
36 | + onAdd: #{options[:on_add]}, | ||
37 | + onDelete: #{options[:on_delete]}, | ||
38 | + onReady: #{options[:on_ready]}, | ||
39 | + }); | ||
40 | + ") | ||
41 | + result += javascript_tag("jQuery('##{element_id}').focus();") if options[:focus] | ||
42 | + if options[:avoid_enter] | ||
43 | + result += javascript_tag("jQuery('#token-input-#{element_id}') | ||
44 | + .live('keydown', function(event){ | ||
45 | + if(event.keyCode == '13') return false; | ||
46 | + });") | ||
47 | + end | ||
48 | + result | ||
49 | + end | ||
50 | + | ||
51 | +end | ||
0 | \ No newline at end of file | 52 | \ No newline at end of file |
app/models/article.rb
@@ -69,6 +69,7 @@ class Article < ActiveRecord::Base | @@ -69,6 +69,7 @@ class Article < ActiveRecord::Base | ||
69 | settings_items :allow_members_to_edit, :type => :boolean, :default => false | 69 | settings_items :allow_members_to_edit, :type => :boolean, :default => false |
70 | settings_items :moderate_comments, :type => :boolean, :default => false | 70 | settings_items :moderate_comments, :type => :boolean, :default => false |
71 | settings_items :followers, :type => Array, :default => [] | 71 | settings_items :followers, :type => Array, :default => [] |
72 | + has_and_belongs_to_many :article_privacy_exceptions, :class_name => 'Person', :join_table => 'article_privacy_exceptions' | ||
72 | 73 | ||
73 | belongs_to :reference_article, :class_name => "Article", :foreign_key => 'reference_article_id' | 74 | belongs_to :reference_article, :class_name => "Article", :foreign_key => 'reference_article_id' |
74 | 75 | ||
@@ -470,7 +471,8 @@ class Article < ActiveRecord::Base | @@ -470,7 +471,8 @@ class Article < ActiveRecord::Base | ||
470 | 471 | ||
471 | def display_unpublished_article_to?(user) | 472 | def display_unpublished_article_to?(user) |
472 | user == author || allow_view_private_content?(user) || user == profile || | 473 | user == author || allow_view_private_content?(user) || user == profile || |
473 | - user.is_admin?(profile.environment) || user.is_admin?(profile) | 474 | + user.is_admin?(profile.environment) || user.is_admin?(profile) || |
475 | + article_privacy_exceptions.include?(user) | ||
474 | end | 476 | end |
475 | 477 | ||
476 | def display_to?(user = nil) | 478 | def display_to?(user = nil) |
app/models/person.rb
@@ -64,6 +64,7 @@ class Person < Profile | @@ -64,6 +64,7 @@ class Person < Profile | ||
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' | 66 | has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' |
67 | + has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' | ||
67 | 68 | ||
68 | named_scope :more_popular, | 69 | named_scope :more_popular, |
69 | :select => "#{Profile.qualified_column_names}, count(friend_id) as total", | 70 | :select => "#{Profile.qualified_column_names}, count(friend_id) as total", |
app/views/cms/edit.rhtml
1 | <%= error_messages_for 'article' %> | 1 | <%= error_messages_for 'article' %> |
2 | +<%= javascript_include_tag "article.js" %> | ||
2 | 3 | ||
3 | <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'> | 4 | <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'> |
4 | <% labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %> | 5 | <% labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %> |
@@ -33,7 +34,7 @@ | @@ -33,7 +34,7 @@ | ||
33 | <%= content_tag( 'small', _('Separate tags with commas') ) %> | 34 | <%= content_tag( 'small', _('Separate tags with commas') ) %> |
34 | 35 | ||
35 | <div id='edit-article-options'> | 36 | <div id='edit-article-options'> |
36 | - <%= options_for_article(@article) %> | 37 | + <%= options_for_article(@article, @tokenized_children) %> |
37 | </div> | 38 | </div> |
38 | 39 | ||
39 | <% button_bar do %> | 40 | <% button_bar do %> |
@@ -0,0 +1,12 @@ | @@ -0,0 +1,12 @@ | ||
1 | +class ArticlePrivacyExceptions < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + create_table :article_privacy_exceptions, :id => false do |t| | ||
4 | + t.integer :article_id | ||
5 | + t.integer :person_id | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | + def self.down | ||
10 | + drop_table :article_privacy_exceptions | ||
11 | + end | ||
12 | +end |
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 => 20131128161159) do | 12 | +ActiveRecord::Schema.define(:version => 20140108132730) 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" |
@@ -46,6 +46,11 @@ ActiveRecord::Schema.define(:version => 20131128161159) do | @@ -46,6 +46,11 @@ ActiveRecord::Schema.define(:version => 20131128161159) do | ||
46 | add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], :name => "index_action_tracker_notif_on_prof_id_act_tracker_id", :unique => true | 46 | add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], :name => "index_action_tracker_notif_on_prof_id_act_tracker_id", :unique => true |
47 | add_index "action_tracker_notifications", ["profile_id"], :name => "index_action_tracker_notifications_on_profile_id" | 47 | add_index "action_tracker_notifications", ["profile_id"], :name => "index_action_tracker_notifications_on_profile_id" |
48 | 48 | ||
49 | + create_table "article_privacy_exceptions", :id => false, :force => true do |t| | ||
50 | + t.integer "article_id" | ||
51 | + t.integer "person_id" | ||
52 | + end | ||
53 | + | ||
49 | create_table "article_versions", :force => true do |t| | 54 | create_table "article_versions", :force => true do |t| |
50 | t.integer "article_id" | 55 | t.integer "article_id" |
51 | t.integer "version" | 56 | t.integer "version" |
@@ -460,6 +465,7 @@ ActiveRecord::Schema.define(:version => 20131128161159) do | @@ -460,6 +465,7 @@ ActiveRecord::Schema.define(:version => 20131128161159) do | ||
460 | t.boolean "is_template", :default => false | 465 | t.boolean "is_template", :default => false |
461 | t.integer "template_id" | 466 | t.integer "template_id" |
462 | t.string "redirection_after_login" | 467 | t.string "redirection_after_login" |
468 | + t.text "settings" | ||
463 | end | 469 | end |
464 | 470 | ||
465 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" | 471 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" |
features/edit_article.feature
@@ -22,6 +22,70 @@ Feature: edit article | @@ -22,6 +22,70 @@ Feature: edit article | ||
22 | And I go to joaosilva's control panel | 22 | And I go to joaosilva's control panel |
23 | Then I should see "My Folder" | 23 | Then I should see "My Folder" |
24 | 24 | ||
25 | + @selenium | ||
26 | + Scenario: denied access folder for a not logged user | ||
27 | + Given the following communities | ||
28 | + | name | identifier | owner | | ||
29 | + | Free Software | freesoftware | joaosilva | | ||
30 | + And the following users | ||
31 | + | login | name | | ||
32 | + | mario | Mario Souto | | ||
33 | + | maria | Maria Silva | | ||
34 | + And "Mario Souto" is a member of "Free Software" | ||
35 | + And "Maria Silva" is a member of "Free Software" | ||
36 | + And I am on freesoftware's control panel | ||
37 | + And I follow "Manage Content" | ||
38 | + And I follow "New content" | ||
39 | + When I follow "Folder" | ||
40 | + And I fill in "Title" with "My Folder" | ||
41 | + And I choose "article_published_false" | ||
42 | + And I press "Save" | ||
43 | + And I log off | ||
44 | + And I go to /freesoftware/my-folder | ||
45 | + Then I should see "Access denied" | ||
46 | + | ||
47 | + @selenium | ||
48 | + Scenario: show exception users field when you choose the private option | ||
49 | + Given the following communities | ||
50 | + | name | identifier | owner | | ||
51 | + | Free Software | freesoftware | joaosilva | | ||
52 | + And the following users | ||
53 | + | login | name | | ||
54 | + | mario | Mario Souto | | ||
55 | + | maria | Maria Silva | | ||
56 | + And "Mario Souto" is a member of "Free Software" | ||
57 | + And "Maria Silva" is a member of "Free Software" | ||
58 | + And I am on freesoftware's control panel | ||
59 | + And I follow "Manage Content" | ||
60 | + And I follow "New content" | ||
61 | + When I follow "Folder" | ||
62 | + And I fill in "Title" with "My Folder" | ||
63 | + And I choose "article_published_false" | ||
64 | + Then I should see "Fill in the search field to add the exception users to see this content" | ||
65 | + | ||
66 | + @selenium | ||
67 | + Scenario: allowed user should see the content of a folder | ||
68 | + Given the following communities | ||
69 | + | name | identifier | owner | | ||
70 | + | Free Software | freesoftware | joaosilva | | ||
71 | + And the following users | ||
72 | + | login | name | | ||
73 | + | mario | Mario Souto | | ||
74 | + | maria | Maria Silva | | ||
75 | + And the following articles | ||
76 | + | owner | name | body | | ||
77 | + | freesoftware | My Folder | ... | | ||
78 | + And "Mario Souto" is a member of "Free Software" | ||
79 | + And "Maria Silva" is a member of "Free Software" | ||
80 | + And I go to /freesoftware/my-folder | ||
81 | + When I follow "Edit" | ||
82 | + And I choose "article_published_false" | ||
83 | + And I press "Save" | ||
84 | + And I add to "My Folder" the following exception "Maria Silva" | ||
85 | + And I am logged in as "maria" | ||
86 | + And I go to /freesoftware/my-folder | ||
87 | + Then I should see "My Folder" | ||
88 | + | ||
25 | Scenario: redirect to the created folder | 89 | Scenario: redirect to the created folder |
26 | Given I am on joaosilva's control panel | 90 | Given I am on joaosilva's control panel |
27 | And I follow "Manage Content" | 91 | And I follow "Manage Content" |
@@ -40,6 +104,7 @@ Feature: edit article | @@ -40,6 +104,7 @@ Feature: edit article | ||
40 | When I follow "Cancel" within ".main-block" | 104 | When I follow "Cancel" within ".main-block" |
41 | Then I should be on joaosilva's cms | 105 | Then I should be on joaosilva's cms |
42 | 106 | ||
107 | + @selenium | ||
43 | Scenario: display tag list field when creating event | 108 | Scenario: display tag list field when creating event |
44 | Given I am on joaosilva's control panel | 109 | Given I am on joaosilva's control panel |
45 | And I follow "Manage Content" | 110 | And I follow "Manage Content" |
features/step_definitions/content_steps.rb
@@ -8,3 +8,15 @@ When /^I create a content of type "([^\"]*)" with the following data$/ do |conte | @@ -8,3 +8,15 @@ When /^I create a content of type "([^\"]*)" with the following data$/ do |conte | ||
8 | 8 | ||
9 | click_button "Save" | 9 | click_button "Save" |
10 | end | 10 | end |
11 | + | ||
12 | +And /^I add to "([^\"]*)" the following exception "([^\"]*)"$/ do |article_name, user_exception| | ||
13 | + article = Article.find_by_name(article_name) | ||
14 | + community = article.profile | ||
15 | + raise "The article profile is not a community." unless community.class == Community | ||
16 | + | ||
17 | + my_user = community.members.find_by_name(user_exception) | ||
18 | + raise "Could not find #{user_exception} in #{community.name} community." if my_user.nil? | ||
19 | + | ||
20 | + article.article_privacy_exceptions << my_user | ||
21 | + article.save | ||
22 | +end | ||
11 | \ No newline at end of file | 23 | \ No newline at end of file |
public/javascripts/article.js
@@ -172,4 +172,19 @@ jQuery(function($) { | @@ -172,4 +172,19 @@ jQuery(function($) { | ||
172 | return false; | 172 | return false; |
173 | }); | 173 | }); |
174 | 174 | ||
175 | + function show_hide_token_input() { | ||
176 | + if($("#article_published_false").attr('checked')) | ||
177 | + $("#text-input-search-exception-users").parent("div").css('display', 'block'); | ||
178 | + else | ||
179 | + $("#text-input-search-exception-users").parent("div").css('display', 'none'); | ||
180 | + } | ||
181 | + | ||
182 | + if( $("#token-input-search-article-privacy-exceptions").length == 1 ) { | ||
183 | + show_hide_token_input(); | ||
184 | + | ||
185 | + //Hide / Show the text area | ||
186 | + $("#article_published_false").click(show_hide_token_input); | ||
187 | + $("#article_published_true").click(show_hide_token_input); | ||
188 | + } | ||
189 | + | ||
175 | }); | 190 | }); |