Commit 9f616e0b9baf3bad75d3308531b824591c396aa9
Committed by
Fabio Teixeira
1 parent
c9eccb09
Exists in
master
and in
28 other branches
access_level: Custom permission for community users to access an article
- Added a field on article new/edit to specify which users can access the article - Added a relationship has_and_belongs_to_many between Article and Person - Created a new table article_privacy_exceptions for has_and_belongs_to_many - Added cucumber tests - Added a new cucumber step to add a user to the exception users list (ActionItem2852) Signed-off-by: Alex de Souza <campelo.al1@gmail.com> Signed-off-by: Athos Ribeiro <athoscribeiro@gmail.com> Signed-off-by: Andre Bedran <bedran.fleck@gmail.com> Signed-off-by: Arthur Del Esposte <arthurmde@gmail.com> Signed-off-by: Carlos Andre <carlos.andre.souza@msn.com> Signed-off-by: Fabio Teixeira <fabio1079@gmail.com> Signed-off-by: Gabriela Navarro <navarro1703@gmail.com> Signed-off-by: Gustavo Jaruga <darksshades@hotmail.com> Signed-off-by: Matheus Faria <matheus.sousa.faria@gmail.com> Signed-off-by: Tales Martins <tales.martins@gmail.com>
Showing
15 changed files
with
232 additions
and
80 deletions
Show diff stats
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -2,6 +2,8 @@ class CmsController < MyProfileController |
2 | 2 | |
3 | 3 | protect 'edit_profile', :profile, :only => [:set_home_page] |
4 | 4 | |
5 | + include ArticleHelper | |
6 | + | |
5 | 7 | def self.protect_if(*args) |
6 | 8 | before_filter(*args) do |c| |
7 | 9 | user, profile = c.send(:user), c.send(:profile) |
... | ... | @@ -70,6 +72,14 @@ class CmsController < MyProfileController |
70 | 72 | translations if @article.translatable? |
71 | 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 | 83 | refuse_blocks |
74 | 84 | record_coming |
75 | 85 | if request.post? |
... | ... | @@ -130,6 +140,8 @@ class CmsController < MyProfileController |
130 | 140 | |
131 | 141 | continue = params[:continue] |
132 | 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 | 145 | if @article.save |
134 | 146 | if continue |
135 | 147 | redirect_to :action => 'edit', :id => @article |
... | ... | @@ -290,6 +302,12 @@ class CmsController < MyProfileController |
290 | 302 | render :text => article_list_to_json(results), :content_type => 'application/json' |
291 | 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 | 311 | def media_upload |
294 | 312 | files_uploaded = [] |
295 | 313 | parent = check_parent(params[:parent_id]) | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -40,6 +40,8 @@ module ApplicationHelper |
40 | 40 | |
41 | 41 | include Noosfero::Gravatar |
42 | 42 | |
43 | + include TokenHelper | |
44 | + | |
43 | 45 | def locale |
44 | 46 | (@page && !@page.language.blank?) ? @page.language : FastGettext.locale |
45 | 47 | end |
... | ... | @@ -1299,10 +1301,6 @@ module ApplicationHelper |
1299 | 1301 | content_tag(:div, content_tag(:ul, titles) + raw(contents), :class => 'ui-tabs') |
1300 | 1302 | end |
1301 | 1303 | |
1302 | - def jquery_token_input_messages_json(hintText = _('Type in an keyword'), noResultsText = _('No results'), searchingText = _('Searching...')) | |
1303 | - "hintText: '#{hintText}', noResultsText: '#{noResultsText}', searchingText: '#{searchingText}'" | |
1304 | - end | |
1305 | - | |
1306 | 1304 | def delete_article_message(article) |
1307 | 1305 | if article.folder? |
1308 | 1306 | _("Are you sure that you want to remove the folder \"#{article.name}\"? Note that all the items inside it will also be removed!") |
... | ... | @@ -1343,50 +1341,6 @@ module ApplicationHelper |
1343 | 1341 | ) |
1344 | 1342 | end |
1345 | 1343 | |
1346 | - def token_input_field_tag(name, element_id, search_action, options = {}, text_field_options = {}, html_options = {}) | |
1347 | - options[:min_chars] ||= 3 | |
1348 | - options[:hint_text] ||= _("Type in a search term") | |
1349 | - options[:no_results_text] ||= _("No results") | |
1350 | - options[:searching_text] ||= _("Searching...") | |
1351 | - options[:search_delay] ||= 1000 | |
1352 | - options[:prevent_duplicates] ||= true | |
1353 | - options[:backspace_delete_item] ||= false | |
1354 | - options[:focus] ||= false | |
1355 | - options[:avoid_enter] ||= true | |
1356 | - options[:on_result] ||= 'null' | |
1357 | - options[:on_add] ||= 'null' | |
1358 | - options[:on_delete] ||= 'null' | |
1359 | - options[:on_ready] ||= 'null' | |
1360 | - | |
1361 | - result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) | |
1362 | - result += javascript_tag("jQuery('##{element_id}') | |
1363 | - .tokenInput('#{url_for(search_action)}', { | |
1364 | - minChars: #{options[:min_chars].to_json}, | |
1365 | - prePopulate: #{options[:pre_populate].to_json}, | |
1366 | - hintText: #{options[:hint_text].to_json}, | |
1367 | - noResultsText: #{options[:no_results_text].to_json}, | |
1368 | - searchingText: #{options[:searching_text].to_json}, | |
1369 | - searchDelay: #{options[:serach_delay].to_json}, | |
1370 | - preventDuplicates: #{options[:prevent_duplicates].to_json}, | |
1371 | - backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | |
1372 | - queryParam: #{name.to_json}, | |
1373 | - tokenLimit: #{options[:token_limit].to_json}, | |
1374 | - onResult: #{options[:on_result]}, | |
1375 | - onAdd: #{options[:on_add]}, | |
1376 | - onDelete: #{options[:on_delete]}, | |
1377 | - onReady: #{options[:on_ready]}, | |
1378 | - }); | |
1379 | - ") | |
1380 | - result += javascript_tag("jQuery('##{element_id}').focus();") if options[:focus] | |
1381 | - if options[:avoid_enter] | |
1382 | - result += javascript_tag("jQuery('#token-input-#{element_id}') | |
1383 | - .live('keydown', function(event){ | |
1384 | - if(event.keyCode == '13') return false; | |
1385 | - });") | |
1386 | - end | |
1387 | - result | |
1388 | - end | |
1389 | - | |
1390 | 1344 | def expirable_content_reference(content, action, text, url, options = {}) |
1391 | 1345 | reason = @plugins.dispatch("content_expire_#{action.to_s}", content).first |
1392 | 1346 | options[:title] = reason | ... | ... |
app/helpers/article_helper.rb
1 | 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 | 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 | 9 | content_tag('h4', _('Options')) + |
17 | 10 | content_tag('div', |
18 | 11 | (article.profile.has_members? ? |
... | ... | @@ -53,6 +46,28 @@ module ArticleHelper |
53 | 46 | ) |
54 | 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 | 71 | def cms_label_for_new_children |
57 | 72 | _('New article') |
58 | 73 | end | ... | ... |
app/helpers/blog_helper.rb
1 | 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 | 6 | @article = article |
5 | 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 | 10 | end |
8 | 11 | |
9 | 12 | def cms_label_for_new_children | ... | ... |
app/helpers/cms_helper.rb
... | ... | @@ -22,9 +22,9 @@ module CmsHelper |
22 | 22 | |
23 | 23 | attr_reader :environment |
24 | 24 | |
25 | - def options_for_article(article) | |
25 | + def options_for_article(article, tokenized_children=nil) | |
26 | 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 | 28 | end |
29 | 29 | |
30 | 30 | def link_to_article(article) | ... | ... |
app/helpers/folder_helper.rb
1 | 1 | module FolderHelper |
2 | 2 | |
3 | 3 | include ShortFilename |
4 | + include ArticleHelper | |
4 | 5 | |
5 | 6 | def list_articles(articles, recursive = false) |
6 | 7 | if !articles.blank? |
... | ... | @@ -60,19 +61,10 @@ module FolderHelper |
60 | 61 | "icon-new icon-new%s" % klass.icon_name |
61 | 62 | end |
62 | 63 | |
63 | - def custom_options_for_article(article) | |
64 | + def custom_options_for_article(article,tokenized_children) | |
64 | 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 | 68 | content_tag('div', |
77 | 69 | hidden_field_tag('article[accept_comments]', 0) |
78 | 70 | ) | ... | ... |
... | ... | @@ -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 | 52 | \ No newline at end of file | ... | ... |
app/models/article.rb
... | ... | @@ -69,6 +69,7 @@ class Article < ActiveRecord::Base |
69 | 69 | settings_items :allow_members_to_edit, :type => :boolean, :default => false |
70 | 70 | settings_items :moderate_comments, :type => :boolean, :default => false |
71 | 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 | 74 | belongs_to :reference_article, :class_name => "Article", :foreign_key => 'reference_article_id' |
74 | 75 | |
... | ... | @@ -470,7 +471,8 @@ class Article < ActiveRecord::Base |
470 | 471 | |
471 | 472 | def display_unpublished_article_to?(user) |
472 | 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 | 476 | end |
475 | 477 | |
476 | 478 | def display_to?(user = nil) | ... | ... |
app/models/person.rb
... | ... | @@ -63,6 +63,8 @@ class Person < Profile |
63 | 63 | |
64 | 64 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy |
65 | 65 | |
66 | + has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' | |
67 | + | |
66 | 68 | named_scope :more_popular, |
67 | 69 | :select => "#{Profile.qualified_column_names}, count(friend_id) as total", |
68 | 70 | :group => Profile.qualified_column_names, | ... | ... |
app/views/cms/edit.rhtml
1 | 1 | <%= error_messages_for 'article' %> |
2 | +<%= javascript_include_tag "article.js" %> | |
2 | 3 | |
3 | 4 | <div class='<%= (environment.enabled?('media_panel') ? 'with_media_panel' : 'no_media_panel') %>'> |
4 | 5 | <% labelled_form_for 'article', @article, :html => { :multipart => true, :class => @type } do |f| %> |
... | ... | @@ -33,7 +34,7 @@ |
33 | 34 | <%= content_tag( 'small', _('Separate tags with commas') ) %> |
34 | 35 | |
35 | 36 | <div id='edit-article-options'> |
36 | - <%= options_for_article(@article) %> | |
37 | + <%= options_for_article(@article, @tokenized_children) %> | |
37 | 38 | </div> |
38 | 39 | |
39 | 40 | <% button_bar do %> | ... | ... |
... | ... | @@ -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,8 +9,7 @@ |
9 | 9 | # |
10 | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | |
12 | -ActiveRecord::Schema.define(:version => 20131121162641) do | |
13 | - | |
12 | +ActiveRecord::Schema.define(:version => 20140108132730) do | |
14 | 13 | create_table "abuse_reports", :force => true do |t| |
15 | 14 | t.integer "reporter_id" |
16 | 15 | t.integer "abuse_complaint_id" |
... | ... | @@ -46,6 +45,11 @@ ActiveRecord::Schema.define(:version => 20131121162641) do |
46 | 45 | add_index "action_tracker_notifications", ["profile_id", "action_tracker_id"], :name => "index_action_tracker_notif_on_prof_id_act_tracker_id", :unique => true |
47 | 46 | add_index "action_tracker_notifications", ["profile_id"], :name => "index_action_tracker_notifications_on_profile_id" |
48 | 47 | |
48 | + create_table "article_privacy_exceptions", :id => false, :force => true do |t| | |
49 | + t.integer "article_id" | |
50 | + t.integer "person_id" | |
51 | + end | |
52 | + | |
49 | 53 | create_table "article_versions", :force => true do |t| |
50 | 54 | t.integer "article_id" |
51 | 55 | t.integer "version" |
... | ... | @@ -460,6 +464,7 @@ ActiveRecord::Schema.define(:version => 20131121162641) do |
460 | 464 | t.boolean "is_template", :default => false |
461 | 465 | t.integer "template_id" |
462 | 466 | t.string "redirection_after_login" |
467 | + t.text "settings" | |
463 | 468 | end |
464 | 469 | |
465 | 470 | add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" |
... | ... | @@ -566,6 +571,11 @@ ActiveRecord::Schema.define(:version => 20131121162641) do |
566 | 571 | |
567 | 572 | add_index "tasks", ["spam"], :name => "index_tasks_on_spam" |
568 | 573 | |
574 | + create_table "terms_forum_people", :id => false, :force => true do |t| | |
575 | + t.integer "forum_id" | |
576 | + t.integer "person_id" | |
577 | + end | |
578 | + | |
569 | 579 | create_table "thumbnails", :force => true do |t| |
570 | 580 | t.integer "size" |
571 | 581 | t.string "content_type" | ... | ... |
features/edit_article.feature
... | ... | @@ -22,6 +22,70 @@ Feature: edit article |
22 | 22 | And I go to joaosilva's control panel |
23 | 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 | 89 | Scenario: redirect to the created folder |
26 | 90 | Given I am on joaosilva's control panel |
27 | 91 | And I follow "Manage Content" |
... | ... | @@ -40,6 +104,7 @@ Feature: edit article |
40 | 104 | When I follow "Cancel" within ".main-block" |
41 | 105 | Then I should be on joaosilva's cms |
42 | 106 | |
107 | + @selenium | |
43 | 108 | Scenario: display tag list field when creating event |
44 | 109 | Given I am on joaosilva's control panel |
45 | 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 | 8 | |
9 | 9 | click_button "Save" |
10 | 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 | 23 | \ No newline at end of file | ... | ... |
public/javascripts/article.js
... | ... | @@ -172,4 +172,19 @@ jQuery(function($) { |
172 | 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 | }); | ... | ... |