Commit be66917b09dd234c35e2ed493bcf4bc63089627b
Exists in
web_steps_improvements
and in
9 other branches
Merge branch 'master_profile_members_filter' into 'master'
Added filter section on profile members list - Adds use of filtered members to mailing queue executed by send_mail action Signed-off-by: Gustavo Jaruga <darksshades@gmail.com> Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com> Signed-off-by: Michel Felipe de Oliveira Ferreira <michel.ferreira@serpro.gov.br> See merge request !800
Showing
21 changed files
with
244 additions
and
27 deletions
Show diff stats
app/controllers/my_profile/profile_members_controller.rb
| @@ -2,8 +2,26 @@ class ProfileMembersController < MyProfileController | @@ -2,8 +2,26 @@ class ProfileMembersController < MyProfileController | ||
| 2 | protect 'manage_memberships', :profile | 2 | protect 'manage_memberships', :profile |
| 3 | 3 | ||
| 4 | def index | 4 | def index |
| 5 | - @members = profile.members_by_name | ||
| 6 | - @member_role = environment.roles.find_by_name('member') | 5 | + @filters = params[:filters] || {:roles => []} |
| 6 | + @filters[:roles] = [] unless @filters[:roles] | ||
| 7 | + @data = {} | ||
| 8 | + field = 'name' | ||
| 9 | + field = 'email' if @filters[:name] =~ /\@/ | ||
| 10 | + | ||
| 11 | + @data[:members] = profile.members_by(field,@filters[:name]).by_role(@filters[:roles]) | ||
| 12 | + session[:members_filtered] = @data[:members].map{|m|m.id} if request.post? | ||
| 13 | + @data[:roles] = Profile::Roles.organization_member_roles(environment.id) | Profile::Roles.organization_custom_roles(environment.id, profile.id) | ||
| 14 | + | ||
| 15 | + end | ||
| 16 | + | ||
| 17 | + def send_mail | ||
| 18 | + session[:members_filtered] = params[:members_filtered].select{|value| value!="0"} | ||
| 19 | + if session[:members_filtered].present? | ||
| 20 | + redirect_to :controller => :profile, :action => :send_mail | ||
| 21 | + else | ||
| 22 | + session[:notice] = _("Select at least one member.") | ||
| 23 | + redirect_to :action => :index | ||
| 24 | + end | ||
| 7 | end | 25 | end |
| 8 | 26 | ||
| 9 | def update_roles | 27 | def update_roles |
| @@ -156,4 +174,13 @@ class ProfileMembersController < MyProfileController | @@ -156,4 +174,13 @@ class ProfileMembersController < MyProfileController | ||
| 156 | end | 174 | end |
| 157 | end | 175 | end |
| 158 | 176 | ||
| 177 | + def search_members | ||
| 178 | + field = 'name' | ||
| 179 | + field = 'email' if params[:filter_name] =~ /\@/ | ||
| 180 | + | ||
| 181 | + result = profile.members_like field, params[:filter_name] | ||
| 182 | + result = result.select{|member| member.can_view_field?(current_person, "email") } if field=="email" | ||
| 183 | + render :json => result.map { |member| {:label => "#{member.name}#{member.can_view_field?(current_person, "email") ? " <#{member.email}>" : ""}", :value => member.name }} | ||
| 184 | + end | ||
| 185 | + | ||
| 159 | end | 186 | end |
app/controllers/public/profile_controller.rb
| @@ -370,6 +370,7 @@ class ProfileController < PublicController | @@ -370,6 +370,7 @@ class ProfileController < PublicController | ||
| 370 | 370 | ||
| 371 | def send_mail | 371 | def send_mail |
| 372 | @mailing = profile.mailings.build(params[:mailing]) | 372 | @mailing = profile.mailings.build(params[:mailing]) |
| 373 | + @mailing.data = session[:members_filtered] ? {:members_filtered => session[:members_filtered]} : {} | ||
| 373 | if request.post? | 374 | if request.post? |
| 374 | @mailing.locale = locale | 375 | @mailing.locale = locale |
| 375 | @mailing.person = user | 376 | @mailing.person = user |
app/helpers/forms_helper.rb
| @@ -7,9 +7,10 @@ module FormsHelper | @@ -7,9 +7,10 @@ module FormsHelper | ||
| 7 | 7 | ||
| 8 | def labelled_check_box( human_name, name, value = "1", checked = false, options = {} ) | 8 | def labelled_check_box( human_name, name, value = "1", checked = false, options = {} ) |
| 9 | options[:id] ||= 'checkbox-' + FormsHelper.next_id_number | 9 | options[:id] ||= 'checkbox-' + FormsHelper.next_id_number |
| 10 | - hidden_field_tag(name, '0') + | ||
| 11 | - check_box_tag( name, value, checked, options ) + | ||
| 12 | - content_tag( 'label', human_name, :for => options[:id] ) | 10 | + html = options[:add_hidden] == false ? "" : hidden_field_tag(name, '0') |
| 11 | + | ||
| 12 | + html += check_box_tag( name, value, checked, options ) + | ||
| 13 | + content_tag( 'label', human_name, :for => options[:id] ) | ||
| 13 | end | 14 | end |
| 14 | 15 | ||
| 15 | def labelled_text_field( human_name, name, value=nil, options={} ) | 16 | def labelled_text_field( human_name, name, value=nil, options={} ) |
app/mailers/mailing.rb
| @@ -2,7 +2,10 @@ require_dependency 'mailing_job' | @@ -2,7 +2,10 @@ require_dependency 'mailing_job' | ||
| 2 | 2 | ||
| 3 | class Mailing < ActiveRecord::Base | 3 | class Mailing < ActiveRecord::Base |
| 4 | 4 | ||
| 5 | - attr_accessible :subject, :body | 5 | + acts_as_having_settings :field => :data |
| 6 | + | ||
| 7 | + attr_accessible :subject, :body, :data | ||
| 8 | + | ||
| 6 | validates_presence_of :source_id, :subject, :body | 9 | validates_presence_of :source_id, :subject, :body |
| 7 | belongs_to :source, :foreign_key => :source_id, :polymorphic => true | 10 | belongs_to :source, :foreign_key => :source_id, :polymorphic => true |
| 8 | belongs_to :person | 11 | belongs_to :person |
app/mailers/organization_mailing.rb
| @@ -5,9 +5,17 @@ class OrganizationMailing < Mailing | @@ -5,9 +5,17 @@ class OrganizationMailing < Mailing | ||
| 5 | end | 5 | end |
| 6 | 6 | ||
| 7 | def recipients(offset=0, limit=100) | 7 | def recipients(offset=0, limit=100) |
| 8 | - source.members.order(:id).offset(offset).limit(limit) | ||
| 9 | - .joins("LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)") | 8 | + result = source.members.order(:id).offset(offset).limit(limit) |
| 9 | + | ||
| 10 | + if data.present? and data.is_a?(Hash) and data[:members_filtered] | ||
| 11 | + result = result.where('profiles.id IN (?)', data[:members_filtered]) | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + if result.blank? | ||
| 15 | + result = result.joins("LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)") | ||
| 10 | .where("m.person_id" => nil) | 16 | .where("m.person_id" => nil) |
| 17 | + end | ||
| 18 | + result | ||
| 11 | end | 19 | end |
| 12 | 20 | ||
| 13 | def each_recipient | 21 | def each_recipient |
app/models/person.rb
| @@ -16,10 +16,13 @@ class Person < Profile | @@ -16,10 +16,13 @@ class Person < Profile | ||
| 16 | acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)} | 16 | acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)} |
| 17 | acts_as_accessor | 17 | acts_as_accessor |
| 18 | 18 | ||
| 19 | - scope :members_of, -> resources { | 19 | + scope :members_of, lambda { |resources, field = ''| |
| 20 | resources = Array(resources) | 20 | resources = Array(resources) |
| 21 | + joins = [:role_assignments] | ||
| 22 | + joins << :user if User.attribute_names.include? field | ||
| 23 | + | ||
| 21 | conditions = resources.map {|resource| "role_assignments.resource_type = '#{resource.class.base_class.name}' AND role_assignments.resource_id = #{resource.id || -1}"}.join(' OR ') | 24 | conditions = resources.map {|resource| "role_assignments.resource_type = '#{resource.class.base_class.name}' AND role_assignments.resource_id = #{resource.id || -1}"}.join(' OR ') |
| 22 | - distinct.select('profiles.*').joins(:role_assignments).where([conditions]) | 25 | + select('DISTINCT profiles.*').joins(joins).where([conditions]) |
| 23 | } | 26 | } |
| 24 | 27 | ||
| 25 | scope :not_members_of, -> resources { | 28 | scope :not_members_of, -> resources { |
| @@ -48,6 +51,14 @@ class Person < Profile | @@ -48,6 +51,14 @@ class Person < Profile | ||
| 48 | ['( roles.key = ? AND role_assignments.accessor_type = ? AND role_assignments.accessor_id = ? ) OR ( | 51 | ['( roles.key = ? AND role_assignments.accessor_type = ? AND role_assignments.accessor_id = ? ) OR ( |
| 49 | ( ( friendships.person_id = ? ) OR (profiles.public_profile = ?)) AND (profiles.visible = ?) )', 'environment_administrator', Profile.name, person.id, person.id, true, true] | 52 | ( ( friendships.person_id = ? ) OR (profiles.public_profile = ?)) AND (profiles.visible = ?) )', 'environment_administrator', Profile.name, person.id, person.id, true, true] |
| 50 | ).uniq | 53 | ).uniq |
| 54 | + } | ||
| 55 | + scope :by_role, lambda { |roles| | ||
| 56 | + | ||
| 57 | + roles = [roles] unless roles.kind_of?(Array) | ||
| 58 | + | ||
| 59 | + if roles.length > 0 | ||
| 60 | + {:select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.role_id IN (?)', roles] } | ||
| 61 | + end | ||
| 51 | } | 62 | } |
| 52 | 63 | ||
| 53 | 64 |
app/models/profile.rb
| @@ -49,6 +49,9 @@ class Profile < ActiveRecord::Base | @@ -49,6 +49,9 @@ class Profile < ActiveRecord::Base | ||
| 49 | def self.organization_member_roles(env_id) | 49 | def self.organization_member_roles(env_id) |
| 50 | all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? || !r.profile_id.nil?} | 50 | all_roles(env_id).select{ |r| r.key.match(/^profile_/) unless r.key.blank? || !r.profile_id.nil?} |
| 51 | end | 51 | end |
| 52 | + def self.organization_custom_roles(env_id, profile_id) | ||
| 53 | + all_roles(env_id).where('profile_id = ?', profile_id) | ||
| 54 | + end | ||
| 52 | def self.all_roles(env_id) | 55 | def self.all_roles(env_id) |
| 53 | Role.where(environment_id: env_id) | 56 | Role.where(environment_id: env_id) |
| 54 | end | 57 | end |
| @@ -155,15 +158,23 @@ class Profile < ActiveRecord::Base | @@ -155,15 +158,23 @@ class Profile < ActiveRecord::Base | ||
| 155 | 158 | ||
| 156 | include TimeScopes | 159 | include TimeScopes |
| 157 | 160 | ||
| 158 | - def members | 161 | + def members(by_field = '') |
| 159 | scopes = plugins.dispatch_scopes(:organization_members, self) | 162 | scopes = plugins.dispatch_scopes(:organization_members, self) |
| 160 | - scopes << Person.members_of(self) | 163 | + scopes << Person.members_of(self,by_field) |
| 161 | return scopes.first if scopes.size == 1 | 164 | return scopes.first if scopes.size == 1 |
| 162 | ScopeTool.union *scopes | 165 | ScopeTool.union *scopes |
| 163 | end | 166 | end |
| 164 | 167 | ||
| 165 | - def members_by_name | ||
| 166 | - members.order('profiles.name') | 168 | + def members_by(field,value = nil) |
| 169 | + if value and !value.blank? | ||
| 170 | + members_like(field,value).order('profiles.name') | ||
| 171 | + else | ||
| 172 | + members.order('profiles.name') | ||
| 173 | + end | ||
| 174 | + end | ||
| 175 | + | ||
| 176 | + def members_like(field,value) | ||
| 177 | + members(field).where("LOWER(#{field}) LIKE ?", "%#{value.downcase}%") if value | ||
| 167 | end | 178 | end |
| 168 | 179 | ||
| 169 | class << self | 180 | class << self |
| @@ -1098,6 +1109,10 @@ private :generate_url, :url_options | @@ -1098,6 +1109,10 @@ private :generate_url, :url_options | ||
| 1098 | end | 1109 | end |
| 1099 | end | 1110 | end |
| 1100 | 1111 | ||
| 1112 | + def can_view_field? current_person, field | ||
| 1113 | + display_private_info_to?(current_person) || (public_fields.include?(field) && public?) | ||
| 1114 | + end | ||
| 1115 | + | ||
| 1101 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true | 1116 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true |
| 1102 | def preferred_login_redirection | 1117 | def preferred_login_redirection |
| 1103 | redirection_after_login.blank? ? environment.redirection_after_login : redirection_after_login | 1118 | redirection_after_login.blank? ? environment.redirection_after_login : redirection_after_login |
app/views/profile/send_mail.html.erb
| @@ -4,6 +4,9 @@ | @@ -4,6 +4,9 @@ | ||
| 4 | 4 | ||
| 5 | <%= error_messages_for :mailing %> | 5 | <%= error_messages_for :mailing %> |
| 6 | 6 | ||
| 7 | + <% to = @mailing.data[:members_filtered].present? ? @mailing.recipients.map{|r| r.name}.join(', ') : _('All members')%> | ||
| 8 | + <%= labelled_form_field(_('To:'), text_area(:data, 'members_filtered', :value => to, :rows => 4, :disabled => 'disabled', :class => 'send-mail-recipients')) %> | ||
| 9 | + | ||
| 7 | <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> | 10 | <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> |
| 8 | 11 | ||
| 9 | <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> | 12 | <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> |
app/views/profile_members/_index_buttons.html.erb
| @@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
| 5 | <%= button :person, _('Invite people to join'), :controller => 'invite', :action => 'invite_friends' %> | 5 | <%= button :person, _('Invite people to join'), :controller => 'invite', :action => 'invite_friends' %> |
| 6 | <% end %> | 6 | <% end %> |
| 7 | <% if profile.community? and user.has_permission?(:send_mail_to_members, profile) %> | 7 | <% if profile.community? and user.has_permission?(:send_mail_to_members, profile) %> |
| 8 | - <%= button :send, _('Send e-mail to members'), :controller => 'profile', :action => 'send_mail' %> | 8 | + <%= submit_button(:send, _('Send e-mail to members')) %> |
| 9 | <% end %> | 9 | <% end %> |
| 10 | <% @plugins.dispatch(:manage_members_extra_buttons).each do |plugin_button| %> | 10 | <% @plugins.dispatch(:manage_members_extra_buttons).each do |plugin_button| %> |
| 11 | <%= button plugin_button[:icon], plugin_button[:title], plugin_button[:url] %> | 11 | <%= button plugin_button[:icon], plugin_button[:title], plugin_button[:url] %> |
| @@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
| 1 | +<%= form_tag '#', :method => 'post' do %> | ||
| 2 | + | ||
| 3 | + <%= field_set_tag _('Filter'), :class => 'filter_fields' do %> | ||
| 4 | + <p> | ||
| 5 | + <%= labelled_text_field(_('Name or Email')+': ', "filters[name]", @filters[:name], {:id => 'filter-name-autocomplete',:size => 30}) %> | ||
| 6 | + </p> | ||
| 7 | + | ||
| 8 | + <p><%= _('Roles:') %> </p> | ||
| 9 | + <% @data[:roles].each do |r| %> | ||
| 10 | + <%= labelled_check_box(r.name, 'filters[roles][]', r.id, @filters[:roles].include?(r.id.to_s), :add_hidden => false) %><br/> | ||
| 11 | + <% end %> | ||
| 12 | + <p> | ||
| 13 | + <%= submit_button(:search, _('Search')) %> | ||
| 14 | + </p> | ||
| 15 | + <% end %> | ||
| 16 | +<% end %> | ||
| 17 | + | ||
| 18 | +<%= javascript_include_tag params[:controller] %> | ||
| 0 | \ No newline at end of file | 19 | \ No newline at end of file |
app/views/profile_members/_members_list.html.erb
| 1 | -<% collection = @collection == :profile_admins ? profile.admins : profile.members_by_name %> | 1 | +<% members = @data ? @data[:members] : profile.members_by('name') %> |
| 2 | +<% collection = @collection == :profile_admins ? profile.admins : members %> | ||
| 2 | <% title = @title ? @title : _('Current members') %> | 3 | <% title = @title ? @title : _('Current members') %> |
| 3 | <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> | 4 | <% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> |
| 5 | +<%= javascript_include_tag params[:controller] %> | ||
| 4 | 6 | ||
| 5 | <h3><%= title %></h3> | 7 | <h3><%= title %></h3> |
| 6 | 8 | ||
| 7 | <table> | 9 | <table> |
| 10 | + <col width="1"> | ||
| 8 | <tr> | 11 | <tr> |
| 12 | + <th><%= check_box_tag 'checkbox-all', 1, false, :onClick => "toggle(this)" %></th> | ||
| 9 | <th><%= _('Member') %></th> | 13 | <th><%= _('Member') %></th> |
| 10 | <th><%= _('Actions') %></th> | 14 | <th><%= _('Actions') %></th> |
| 11 | </tr> | 15 | </tr> |
| 16 | + | ||
| 12 | <% collection.each do |m| %> | 17 | <% collection.each do |m| %> |
| 13 | <tr title="<%= m.name %>"> | 18 | <tr title="<%= m.name %>"> |
| 19 | + <td><%= labelled_check_box('', 'members_filtered[]', m.id.to_s, false, :id => 'checkbox-'+m.identifier) %></td> | ||
| 14 | <td><%= link_to_profile m.short_name, m.identifier, :title => m.name %> </td> | 20 | <td><%= link_to_profile m.short_name, m.identifier, :title => m.name %> </td> |
| 15 | <td> | 21 | <td> |
| 16 | <div class="members-buttons-cell"> | 22 | <div class="members-buttons-cell"> |
| @@ -26,3 +32,8 @@ | @@ -26,3 +32,8 @@ | ||
| 26 | </tr> | 32 | </tr> |
| 27 | <% end %> | 33 | <% end %> |
| 28 | </table> | 34 | </table> |
| 35 | +<% if collection.empty? %> | ||
| 36 | + <p> | ||
| 37 | + <em><%= _('No members found to: %s') % profile.name %></em> | ||
| 38 | + </p> | ||
| 39 | +<% end %> |
app/views/profile_members/index.html.erb
| 1 | <h1><%= h profile.short_name(50) %></h1> | 1 | <h1><%= h profile.short_name(50) %></h1> |
| 2 | 2 | ||
| 3 | -<%= render :partial => 'index_buttons' %> | 3 | +<%= render :partial => 'members_filter' %> |
| 4 | 4 | ||
| 5 | -<div id="members-list"> | ||
| 6 | - <%= render :partial => 'members_list' %> | ||
| 7 | -</div> | 5 | +<%= form_tag 'profile_members/send_mail', :method => 'post' do %> |
| 6 | + <div id="members-list"> | ||
| 7 | + <%= render :partial => 'members_list' %> | ||
| 8 | + </div> | ||
| 8 | 9 | ||
| 9 | -<%= render :partial => 'index_buttons' %> | 10 | + <%= render :partial => 'index_buttons' %> |
| 11 | + | ||
| 12 | +<% end %> |
db/schema.rb
| @@ -11,7 +11,7 @@ | @@ -11,7 +11,7 @@ | ||
| 11 | # | 11 | # |
| 12 | # It's strongly recommended that you check this file into your version control system. | 12 | # It's strongly recommended that you check this file into your version control system. |
| 13 | 13 | ||
| 14 | -ActiveRecord::Schema.define(version: 20160202142247) do | 14 | +ActiveRecord::Schema.define(version: 20160224132937) do |
| 15 | 15 | ||
| 16 | # These are extensions that must be enabled in order to support this database | 16 | # These are extensions that must be enabled in order to support this database |
| 17 | enable_extension "plpgsql" | 17 | enable_extension "plpgsql" |
| @@ -471,6 +471,7 @@ ActiveRecord::Schema.define(version: 20160202142247) do | @@ -471,6 +471,7 @@ ActiveRecord::Schema.define(version: 20160202142247) do | ||
| 471 | t.string "locale" | 471 | t.string "locale" |
| 472 | t.datetime "created_at" | 472 | t.datetime "created_at" |
| 473 | t.datetime "updated_at" | 473 | t.datetime "updated_at" |
| 474 | + t.text "data" | ||
| 474 | end | 475 | end |
| 475 | 476 | ||
| 476 | create_table "national_region_types", force: :cascade do |t| | 477 | create_table "national_region_types", force: :cascade do |t| |
features/send_email_to_organization_members.feature
| @@ -31,7 +31,8 @@ Feature: send emails to organization members | @@ -31,7 +31,8 @@ Feature: send emails to organization members | ||
| 31 | Scenario: Send e-mail to members | 31 | Scenario: Send e-mail to members |
| 32 | Given I am logged in as "joaosilva" | 32 | Given I am logged in as "joaosilva" |
| 33 | And I go to Sample Community's members management | 33 | And I go to Sample Community's members management |
| 34 | - And I follow "Send e-mail to members" | 34 | + And I check "checkbox-manoel" |
| 35 | + And I press "Send e-mail to members" | ||
| 35 | And I fill in "Subject" with "Hello, member!" | 36 | And I fill in "Subject" with "Hello, member!" |
| 36 | And I fill in "Body" with "We have some news" | 37 | And I fill in "Body" with "We have some news" |
| 37 | When I press "Send" | 38 | When I press "Send" |
| @@ -40,7 +41,8 @@ Feature: send emails to organization members | @@ -40,7 +41,8 @@ Feature: send emails to organization members | ||
| 40 | Scenario: Not send e-mail to members if subject is blank | 41 | Scenario: Not send e-mail to members if subject is blank |
| 41 | Given I am logged in as "joaosilva" | 42 | Given I am logged in as "joaosilva" |
| 42 | And I go to Sample Community's members management | 43 | And I go to Sample Community's members management |
| 43 | - And I follow "Send e-mail to members" | 44 | + And I check "checkbox-manoel" |
| 45 | + And I press "Send e-mail to members" | ||
| 44 | And I fill in "Body" with "We have some news" | 46 | And I fill in "Body" with "We have some news" |
| 45 | When I press "Send" | 47 | When I press "Send" |
| 46 | Then I should be on /profile/sample-community/send_mail | 48 | Then I should be on /profile/sample-community/send_mail |
| @@ -48,7 +50,8 @@ Feature: send emails to organization members | @@ -48,7 +50,8 @@ Feature: send emails to organization members | ||
| 48 | Scenario: Not send e-mail to members if body is blank | 50 | Scenario: Not send e-mail to members if body is blank |
| 49 | Given I am logged in as "joaosilva" | 51 | Given I am logged in as "joaosilva" |
| 50 | And I go to Sample Community's members management | 52 | And I go to Sample Community's members management |
| 51 | - And I follow "Send e-mail to members" | 53 | + And I check "checkbox-manoel" |
| 54 | + And I press "Send e-mail to members" | ||
| 52 | And I fill in "Subject" with "Hello, user!" | 55 | And I fill in "Subject" with "Hello, user!" |
| 53 | When I press "Send" | 56 | When I press "Send" |
| 54 | Then I should be on /profile/sample-community/send_mail | 57 | Then I should be on /profile/sample-community/send_mail |
| @@ -56,7 +59,8 @@ Feature: send emails to organization members | @@ -56,7 +59,8 @@ Feature: send emails to organization members | ||
| 56 | Scenario: Cancel creation of mailing | 59 | Scenario: Cancel creation of mailing |
| 57 | Given I am logged in as "joaosilva" | 60 | Given I am logged in as "joaosilva" |
| 58 | And I go to Sample Community's members management | 61 | And I go to Sample Community's members management |
| 59 | - And I follow "Send e-mail to members" | 62 | + And I check "checkbox-manoel" |
| 63 | + And I press "Send e-mail to members" | ||
| 60 | When I follow "Cancel e-mail" | 64 | When I follow "Cancel e-mail" |
| 61 | Then I should be on Sample Community's members management | 65 | Then I should be on Sample Community's members management |
| 62 | 66 |
public/designs/themes/noosfero/style.css
| @@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
| 1 | +(function($) { | ||
| 2 | + | ||
| 3 | + //Autocomplete to list members | ||
| 4 | + $('#filter-name-autocomplete').autocomplete({ | ||
| 5 | + minLength:2, | ||
| 6 | + source:function(request,response){ | ||
| 7 | + $.ajax({ | ||
| 8 | + url:document.location.pathname+'/search_members', | ||
| 9 | + dataType:'json', | ||
| 10 | + data:{ | ||
| 11 | + filter_name:request.term | ||
| 12 | + }, | ||
| 13 | + success:response | ||
| 14 | + }); | ||
| 15 | + } | ||
| 16 | + }); | ||
| 17 | +})(jQuery); | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +function toggle(source) { | ||
| 21 | + checkboxes = document.getElementsByName('members_filtered[]'); | ||
| 22 | + for(var i=0, n=checkboxes.length;i<n;i++) { | ||
| 23 | + checkboxes[i].checked = source.checked; | ||
| 24 | + } | ||
| 25 | +} |
test/functional/profile_controller_test.rb
| @@ -1465,11 +1465,41 @@ class ProfileControllerTest < ActionController::TestCase | @@ -1465,11 +1465,41 @@ class ProfileControllerTest < ActionController::TestCase | ||
| 1465 | create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) | 1465 | create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) |
| 1466 | login_as('profile_moderator_user') | 1466 | login_as('profile_moderator_user') |
| 1467 | @controller.stubs(:locale).returns('pt') | 1467 | @controller.stubs(:locale).returns('pt') |
| 1468 | + | ||
| 1468 | assert_difference 'Delayed::Job.count', 1 do | 1469 | assert_difference 'Delayed::Job.count', 1 do |
| 1469 | post :send_mail, :profile => community.identifier, :mailing => {:subject => 'Hello', :body => 'We have some news'} | 1470 | post :send_mail, :profile => community.identifier, :mailing => {:subject => 'Hello', :body => 'We have some news'} |
| 1470 | end | 1471 | end |
| 1471 | end | 1472 | end |
| 1472 | 1473 | ||
| 1474 | + should 'send to members_filtered if available' do | ||
| 1475 | + community = fast_create(Community) | ||
| 1476 | + create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) | ||
| 1477 | + person = create_user('Any').person | ||
| 1478 | + community.add_member(person) | ||
| 1479 | + community.save! | ||
| 1480 | + login_as('profile_moderator_user') | ||
| 1481 | + | ||
| 1482 | + post :send_mail, :profile => community.identifier, :mailing => {:subject => 'Hello', :body => 'We have some news'} | ||
| 1483 | + assert_equivalent community.members, OrganizationMailing.last.recipients | ||
| 1484 | + | ||
| 1485 | + @request.session[:members_filtered] = [person.id] | ||
| 1486 | + post :send_mail, :profile => community.identifier, :mailing => {:subject => 'RUN!!', :body => 'Run to the hills!!'} | ||
| 1487 | + assert_equal [person], OrganizationMailing.last.recipients | ||
| 1488 | + end | ||
| 1489 | + | ||
| 1490 | + should 'send email to all members if there is no valid member in members_filtered' do | ||
| 1491 | + community = fast_create(Community) | ||
| 1492 | + create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) | ||
| 1493 | + person = create_user('Any').person | ||
| 1494 | + community.add_member(person) | ||
| 1495 | + community.save! | ||
| 1496 | + login_as('profile_moderator_user') | ||
| 1497 | + | ||
| 1498 | + @request.session[:members_filtered] = [Profile.last.id+1] | ||
| 1499 | + post :send_mail, :profile => community.identifier, :mailing => {:subject => 'RUN!!', :body => 'Run to the hills!!'} | ||
| 1500 | + assert_empty OrganizationMailing.last.recipients | ||
| 1501 | + end | ||
| 1502 | + | ||
| 1473 | should 'save mailing' do | 1503 | should 'save mailing' do |
| 1474 | community = fast_create(Community) | 1504 | community = fast_create(Community) |
| 1475 | create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) | 1505 | create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) |
test/functional/profile_members_controller_test.rb
| @@ -31,6 +31,31 @@ class ProfileMembersControllerTest < ActionController::TestCase | @@ -31,6 +31,31 @@ class ProfileMembersControllerTest < ActionController::TestCase | ||
| 31 | assert_template 'index' | 31 | assert_template 'index' |
| 32 | end | 32 | end |
| 33 | 33 | ||
| 34 | + should 'access index and filter members by name and roles' do | ||
| 35 | + | ||
| 36 | + ent = fast_create(Enterprise, :identifier => 'test_enterprise', :name => 'test enterprise') | ||
| 37 | + roles = { | ||
| 38 | + :admin => Profile::Roles.admin(Environment.default), | ||
| 39 | + :member => Profile::Roles.member(Environment.default) | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + member = create_user('test_member', :email => 'testmember@test.com.br').person | ||
| 43 | + member.add_role(roles[:member], ent) | ||
| 44 | + | ||
| 45 | + admin = create_user('test_admin').person | ||
| 46 | + admin.add_role roles[:admin], ent | ||
| 47 | + | ||
| 48 | + user = create_user_with_permission('test_user', 'manage_memberships', ent) | ||
| 49 | + login_as :test_user | ||
| 50 | + | ||
| 51 | + post :index, :profile => 'test_enterprise' , :filters => {:name => 'testmember@test.com.br', :roles => [roles[:member].id]} | ||
| 52 | + | ||
| 53 | + assert_response :success | ||
| 54 | + assert_template 'index' | ||
| 55 | + | ||
| 56 | + assert_includes assigns(:data)[:members], member | ||
| 57 | + end | ||
| 58 | + | ||
| 34 | should 'show form to change role' do | 59 | should 'show form to change role' do |
| 35 | ent = fast_create(Enterprise, :identifier => 'test_enterprise', :name => 'test enterprise') | 60 | ent = fast_create(Enterprise, :identifier => 'test_enterprise', :name => 'test enterprise') |
| 36 | role = Profile::Roles.member(Environment.default) | 61 | role = Profile::Roles.member(Environment.default) |
| @@ -171,7 +196,7 @@ class ProfileMembersControllerTest < ActionController::TestCase | @@ -171,7 +196,7 @@ class ProfileMembersControllerTest < ActionController::TestCase | ||
| 171 | login_as :test_user | 196 | login_as :test_user |
| 172 | 197 | ||
| 173 | get :index, :profile => community.identifier | 198 | get :index, :profile => community.identifier |
| 174 | - assert_tag :tag => 'a', :attributes => {:href => /send_mail/} | 199 | + assert_tag :tag => 'input', :attributes => {:value => 'Send e-mail to members'} |
| 175 | end | 200 | end |
| 176 | 201 | ||
| 177 | should 'not display send email to members if doesn\'t have the permission' do | 202 | should 'not display send email to members if doesn\'t have the permission' do |
test/unit/organization_mailing_test.rb
| @@ -98,6 +98,11 @@ class OrganizationMailingTest < ActiveSupport::TestCase | @@ -98,6 +98,11 @@ class OrganizationMailingTest < ActiveSupport::TestCase | ||
| 98 | assert_equal [Person['user_one'], Person['user_two']], mailing.recipients | 98 | assert_equal [Person['user_one'], Person['user_two']], mailing.recipients |
| 99 | end | 99 | end |
| 100 | 100 | ||
| 101 | + should 'return recipients previously filtered' do | ||
| 102 | + mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person, :data => {:members_filtered => [Person['user_one'].id,Person['user_two'].id]}) | ||
| 103 | + assert_equivalent [Person['user_one'], Person['user_two']], mailing.recipients | ||
| 104 | + end | ||
| 105 | + | ||
| 101 | should 'return recipients according to limit' do | 106 | should 'return recipients according to limit' do |
| 102 | mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) | 107 | mailing = create(OrganizationMailing, :source => community, :subject => 'Hello', :body => 'We have some news', :person => person) |
| 103 | assert_equal [Person['user_one']], mailing.recipients(0, 1) | 108 | assert_equal [Person['user_one']], mailing.recipients(0, 1) |
test/unit/profile_test.rb
| @@ -1816,6 +1816,21 @@ class ProfileTest < ActiveSupport::TestCase | @@ -1816,6 +1816,21 @@ class ProfileTest < ActiveSupport::TestCase | ||
| 1816 | assert_equal [person], community.members | 1816 | assert_equal [person], community.members |
| 1817 | end | 1817 | end |
| 1818 | 1818 | ||
| 1819 | + should 'return a list members by email of a community' do | ||
| 1820 | + someone = create_user('Someone', email:'someone@test.com.br') | ||
| 1821 | + someperson = create_user('Someperson',email:'someperson@test.com.br') | ||
| 1822 | + | ||
| 1823 | + community = fast_create(Community) | ||
| 1824 | + community.add_member(someone.person) | ||
| 1825 | + community.add_member(someperson.person) | ||
| 1826 | + | ||
| 1827 | + result = community.members_like 'email', '@test.com.br' | ||
| 1828 | + | ||
| 1829 | + assert_includes result, someone.person | ||
| 1830 | + assert_includes result, someperson.person | ||
| 1831 | + | ||
| 1832 | + end | ||
| 1833 | + | ||
| 1819 | should 'count unique members of a community' do | 1834 | should 'count unique members of a community' do |
| 1820 | person = fast_create(Person) | 1835 | person = fast_create(Person) |
| 1821 | community = fast_create(Community) | 1836 | community = fast_create(Community) |