Commit 9e766d4036b94c0f92b84fa80b22bb02dacbf7a9

Authored by Joenio Costa
1 parent 24bb5d14

ActionItem628: Squashed commit of the following:

    enhancement pending task mail message
    list pending tasks in communities/groups where the user is a member and can solve the tasks
    loop through users with pending tasks and notify them
    determine wheter a user has pending tasks
app/models/pending_task_notifier.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class PendingTaskNotifier < ActionMailer::Base
  2 +
  3 + def notification(person)
  4 + recipients person.email
  5 + from "#{person.environment.name} <#{person.environment.contact_email}>"
  6 + subject _("%s - Pending tasks") % person.environment.name
  7 + body :person => person,
  8 + :tasks => person.tasks.pending,
  9 + :organizations_with_pending_tasks => person.organizations_with_pending_tasks,
  10 + :environment => person.environment.name,
  11 + :url => url_for(:host => person.environment.default_hostname, :controller => 'home'),
  12 + :default_hostname => person.environment.default_hostname,
  13 + :url_for_pending_tasks => url_for(:host => person.environment.default_hostname, :controller => 'tasks', :profile => person.identifier)
  14 + end
  15 +
  16 +end
... ...
app/models/person.rb
... ... @@ -119,4 +119,22 @@ class Person &lt; Profile
119 119 environment.person_template
120 120 end
121 121  
  122 + def self.with_pending_tasks
  123 + Person.find(:all).select{ |person| !person.tasks.pending.empty? or person.has_organization_pending_tasks? }
  124 + end
  125 +
  126 + def has_organization_pending_tasks?
  127 + self.memberships.any?{ |group| group.tasks.pending.any?{ |task| self.has_permission?(task.permission, group) } }
  128 + end
  129 +
  130 + def organizations_with_pending_tasks
  131 + self.memberships.select do |organization|
  132 + organization.tasks.pending.any?{|task| self.has_permission?(task.permission, organization)}
  133 + end
  134 + end
  135 +
  136 + def pending_tasks_for_organization(organization)
  137 + organization.tasks.pending.select{|task| self.has_permission?(task.permission, organization)}
  138 + end
  139 +
122 140 end
... ...
app/views/pending_task_notifier/notification.rhtml 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +<%= _("Dear %s") % @person.name %>,
  2 +
  3 +<%= _("You have %d pending task(s).") % @tasks.size %>
  4 +
  5 +<%= @tasks.map{|i| " * #{i.description}"}.join("\n") %>
  6 +
  7 +<%= _("Click in address below to process task(s):") %>
  8 +
  9 +<%= @url_for_pending_tasks %>
  10 +<% @organizations_with_pending_tasks.each do |organization| %>
  11 +<% pending_tasks = @person.pending_tasks_for_organization(organization) %>
  12 +<%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %>
  13 +
  14 +<%= pending_tasks.map{|i| " * #{i.description}"}.join("\n") %>
  15 +
  16 +<%= _("Click in address below to process task(s):") %>
  17 +
  18 +<%= url_for(:host => @default_hostname, :controller => 'tasks', :profile => organization.identifier) %>
  19 +<% end %>
  20 +--
  21 +<%= _('%s environment system') % @environment %>
  22 +<%= @url %>
... ...
script/task-notifier 0 → 100755
... ... @@ -0,0 +1,7 @@
  1 +#!/usr/bin/env ruby
  2 +require File.dirname(__FILE__) + '/../config/environment'
  3 +
  4 +Person.with_pending_tasks.each do |p|
  5 + PendingTaskNotifier.deliver_notification(p)
  6 + RAILS_DEFAULT_LOGGER.info('deliver notification for ' + p.identifier)
  7 +end
... ...
test/fixtures/roles.yml
... ... @@ -28,6 +28,7 @@ four:
28 28 - manage_environment_roles
29 29 - manage_environment_validators
30 30 - moderate_comments
  31 + - perform_task
31 32 profile_admin:
32 33 id: 5
33 34 key: 'profile_admin'
... ... @@ -37,6 +38,7 @@ profile_admin:
37 38 - edit_profile_design
38 39 - moderate_comments
39 40 - destroy_profile
  41 + - perform_task
40 42 profile_member:
41 43 id: 6
42 44 key: 'profile_member'
... ...
test/unit/pending_task_notifier_test.rb 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class PendingTaskNotifierTest < Test::Unit::TestCase
  4 + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
  5 + CHARSET = "utf-8"
  6 +
  7 + def setup
  8 + ActionMailer::Base.delivery_method = :test
  9 + ActionMailer::Base.perform_deliveries = true
  10 + ActionMailer::Base.deliveries = []
  11 +
  12 + @expected = TMail::Mail.new
  13 + @expected.set_content_type "text", "plain", { "charset" => CHARSET }
  14 + end
  15 +
  16 + should 'be able to deliver notification' do
  17 + p = create_user('maelcum').person
  18 + response = PendingTaskNotifier.deliver_notification(p)
  19 + assert_equal 'Pending tasks', response.subject
  20 + assert_equal p.email, response.to[0]
  21 + end
  22 +
  23 + should 'list organization pending tasks' do
  24 + p = create_user('maelcum').person
  25 + c = Community.create!(:name => 'my test community')
  26 + c.add_admin(p)
  27 + c.tasks << Task.new
  28 +
  29 + response = PendingTaskNotifier.deliver_notification(p)
  30 + assert_match /Generic task/, response.body
  31 + end
  32 +
  33 + private
  34 +
  35 + def read_fixture(action)
  36 + IO.readlines("#{FIXTURES_PATH}/mail_sender/#{action}")
  37 + end
  38 +
  39 + def encode(subject)
  40 + quoted_printable(subject, CHARSET)
  41 + end
  42 +
  43 +end
... ...
test/unit/person_test.rb
... ... @@ -326,4 +326,54 @@ class PersonTest &lt; Test::Unit::TestCase
326 326 end
327 327 end
328 328  
  329 + should 'person has pending tasks' do
  330 + p1 = create_user('user_with_tasks').person
  331 + p1.tasks << Task.new
  332 + p2 = create_user('user_without_tasks').person
  333 + assert_includes Person.with_pending_tasks, p1
  334 + assert_not_includes Person.with_pending_tasks, p2
  335 + end
  336 +
  337 + should 'person has group with pending tasks' do
  338 + p1 = create_user('user_with_tasks').person
  339 + c1 = Community.create!(:name => 'my test community')
  340 + c1.tasks << Task.new
  341 + assert !c1.tasks.pending.empty?
  342 + c1.add_admin(p1)
  343 +
  344 + c2 = Community.create!(:name => 'my other test community')
  345 + p2 = create_user('user_without_tasks').person
  346 + c2.add_admin(p2)
  347 +
  348 + assert_includes Person.with_pending_tasks, p1
  349 + assert_not_includes Person.with_pending_tasks, p2
  350 + end
  351 +
  352 + should 'not allow simple member to view group pending tasks' do
  353 + c = Community.create!(:name => 'my test community')
  354 + c.tasks << Task.new
  355 + p = create_user('user_without_tasks').person
  356 + c.add_member(p)
  357 +
  358 + assert_not_includes Person.with_pending_tasks, p
  359 + end
  360 +
  361 + should 'person has organization pending tasks' do
  362 + c = Community.create!(:name => 'my test community')
  363 + c.tasks << Task.new
  364 + p = create_user('user_with_tasks').person
  365 + c.add_admin(p)
  366 +
  367 + assert p.has_organization_pending_tasks?
  368 + end
  369 +
  370 + should 'select organization pending tasks' do
  371 + c = Community.create!(:name => 'my test community')
  372 + c.tasks << Task.new
  373 + p = create_user('user_with_tasks').person
  374 + c.add_admin(p)
  375 +
  376 + assert_equal p.pending_tasks_for_organization(c), c.tasks
  377 + end
  378 +
329 379 end
... ...