From 9e766d4036b94c0f92b84fa80b22bb02dacbf7a9 Mon Sep 17 00:00:00 2001 From: Joenio Costa Date: Mon, 24 Nov 2008 19:46:12 -0300 Subject: [PATCH] ActionItem628: Squashed commit of the following: --- app/models/pending_task_notifier.rb | 16 ++++++++++++++++ app/models/person.rb | 18 ++++++++++++++++++ app/views/pending_task_notifier/notification.rhtml | 22 ++++++++++++++++++++++ script/task-notifier | 7 +++++++ test/fixtures/roles.yml | 2 ++ test/unit/pending_task_notifier_test.rb | 43 +++++++++++++++++++++++++++++++++++++++++++ test/unit/person_test.rb | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 158 insertions(+), 0 deletions(-) create mode 100644 app/models/pending_task_notifier.rb create mode 100644 app/views/pending_task_notifier/notification.rhtml create mode 100755 script/task-notifier create mode 100644 test/unit/pending_task_notifier_test.rb diff --git a/app/models/pending_task_notifier.rb b/app/models/pending_task_notifier.rb new file mode 100644 index 0000000..e5e5dcb --- /dev/null +++ b/app/models/pending_task_notifier.rb @@ -0,0 +1,16 @@ +class PendingTaskNotifier < ActionMailer::Base + + def notification(person) + recipients person.email + from "#{person.environment.name} <#{person.environment.contact_email}>" + subject _("%s - Pending tasks") % person.environment.name + body :person => person, + :tasks => person.tasks.pending, + :organizations_with_pending_tasks => person.organizations_with_pending_tasks, + :environment => person.environment.name, + :url => url_for(:host => person.environment.default_hostname, :controller => 'home'), + :default_hostname => person.environment.default_hostname, + :url_for_pending_tasks => url_for(:host => person.environment.default_hostname, :controller => 'tasks', :profile => person.identifier) + end + +end diff --git a/app/models/person.rb b/app/models/person.rb index 0dcd179..8f10edf 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -119,4 +119,22 @@ class Person < Profile environment.person_template end + def self.with_pending_tasks + Person.find(:all).select{ |person| !person.tasks.pending.empty? or person.has_organization_pending_tasks? } + end + + def has_organization_pending_tasks? + self.memberships.any?{ |group| group.tasks.pending.any?{ |task| self.has_permission?(task.permission, group) } } + end + + def organizations_with_pending_tasks + self.memberships.select do |organization| + organization.tasks.pending.any?{|task| self.has_permission?(task.permission, organization)} + end + end + + def pending_tasks_for_organization(organization) + organization.tasks.pending.select{|task| self.has_permission?(task.permission, organization)} + end + end diff --git a/app/views/pending_task_notifier/notification.rhtml b/app/views/pending_task_notifier/notification.rhtml new file mode 100644 index 0000000..0dedd8e --- /dev/null +++ b/app/views/pending_task_notifier/notification.rhtml @@ -0,0 +1,22 @@ +<%= _("Dear %s") % @person.name %>, + +<%= _("You have %d pending task(s).") % @tasks.size %> + +<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %> + +<%= _("Click in address below to process task(s):") %> + +<%= @url_for_pending_tasks %> +<% @organizations_with_pending_tasks.each do |organization| %> +<% pending_tasks = @person.pending_tasks_for_organization(organization) %> +<%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %> + +<%= pending_tasks.map{|i| " * #{i.description}"}.join("\n") %> + +<%= _("Click in address below to process task(s):") %> + +<%= url_for(:host => @default_hostname, :controller => 'tasks', :profile => organization.identifier) %> +<% end %> +-- +<%= _('%s environment system') % @environment %> +<%= @url %> diff --git a/script/task-notifier b/script/task-notifier new file mode 100755 index 0000000..cf5833d --- /dev/null +++ b/script/task-notifier @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require File.dirname(__FILE__) + '/../config/environment' + +Person.with_pending_tasks.each do |p| + PendingTaskNotifier.deliver_notification(p) + RAILS_DEFAULT_LOGGER.info('deliver notification for ' + p.identifier) +end diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index e752727..8f7c87d 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -28,6 +28,7 @@ four: - manage_environment_roles - manage_environment_validators - moderate_comments + - perform_task profile_admin: id: 5 key: 'profile_admin' @@ -37,6 +38,7 @@ profile_admin: - edit_profile_design - moderate_comments - destroy_profile + - perform_task profile_member: id: 6 key: 'profile_member' diff --git a/test/unit/pending_task_notifier_test.rb b/test/unit/pending_task_notifier_test.rb new file mode 100644 index 0000000..7dcbb16 --- /dev/null +++ b/test/unit/pending_task_notifier_test.rb @@ -0,0 +1,43 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class PendingTaskNotifierTest < Test::Unit::TestCase + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' + CHARSET = "utf-8" + + def setup + ActionMailer::Base.delivery_method = :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries = [] + + @expected = TMail::Mail.new + @expected.set_content_type "text", "plain", { "charset" => CHARSET } + end + + should 'be able to deliver notification' do + p = create_user('maelcum').person + response = PendingTaskNotifier.deliver_notification(p) + assert_equal 'Pending tasks', response.subject + assert_equal p.email, response.to[0] + end + + should 'list organization pending tasks' do + p = create_user('maelcum').person + c = Community.create!(:name => 'my test community') + c.add_admin(p) + c.tasks << Task.new + + response = PendingTaskNotifier.deliver_notification(p) + assert_match /Generic task/, response.body + end + + private + + def read_fixture(action) + IO.readlines("#{FIXTURES_PATH}/mail_sender/#{action}") + end + + def encode(subject) + quoted_printable(subject, CHARSET) + end + +end diff --git a/test/unit/person_test.rb b/test/unit/person_test.rb index 3800aa0..30f6db6 100644 --- a/test/unit/person_test.rb +++ b/test/unit/person_test.rb @@ -326,4 +326,54 @@ class PersonTest < Test::Unit::TestCase end end + should 'person has pending tasks' do + p1 = create_user('user_with_tasks').person + p1.tasks << Task.new + p2 = create_user('user_without_tasks').person + assert_includes Person.with_pending_tasks, p1 + assert_not_includes Person.with_pending_tasks, p2 + end + + should 'person has group with pending tasks' do + p1 = create_user('user_with_tasks').person + c1 = Community.create!(:name => 'my test community') + c1.tasks << Task.new + assert !c1.tasks.pending.empty? + c1.add_admin(p1) + + c2 = Community.create!(:name => 'my other test community') + p2 = create_user('user_without_tasks').person + c2.add_admin(p2) + + assert_includes Person.with_pending_tasks, p1 + assert_not_includes Person.with_pending_tasks, p2 + end + + should 'not allow simple member to view group pending tasks' do + c = Community.create!(:name => 'my test community') + c.tasks << Task.new + p = create_user('user_without_tasks').person + c.add_member(p) + + assert_not_includes Person.with_pending_tasks, p + end + + should 'person has organization pending tasks' do + c = Community.create!(:name => 'my test community') + c.tasks << Task.new + p = create_user('user_with_tasks').person + c.add_admin(p) + + assert p.has_organization_pending_tasks? + end + + should 'select organization pending tasks' do + c = Community.create!(:name => 'my test community') + c.tasks << Task.new + p = create_user('user_with_tasks').person + c.add_admin(p) + + assert_equal p.pending_tasks_for_organization(c), c.tasks + end + end -- libgit2 0.21.2