Commit e7464a3d47aa5a204943ccec669355fb4eede45b

Authored by Rodrigo Souto
Committed by Daniela Feitosa
1 parent 4456c409

Multitask

+ Multi-processing tasks.
  + Graciously show/hide functions with the smooth slide of
  + Jquery. ^^
  + Using Unobtrusive Javascript.
  + Customized messages for each task type.
  + Button "Set all to approve/reject/skip".
  + Icons related to the task action.

  * Missing
    - Need to make selenium tests.

(ActionItem1527)
Showing 69 changed files with 1528 additions and 513 deletions   Show diff stats
app/controllers/my_profile/tasks_controller.rb
@@ -4,26 +4,38 @@ class TasksController < MyProfileController @@ -4,26 +4,38 @@ class TasksController < MyProfileController
4 4
5 def index 5 def index
6 @tasks = profile.all_pending_tasks.sort_by(&:created_at) 6 @tasks = profile.all_pending_tasks.sort_by(&:created_at)
  7 + @failed = params ? params[:failed] : {}
7 end 8 end
8 9
9 def processed 10 def processed
10 @tasks = profile.all_finished_tasks.sort_by(&:created_at) 11 @tasks = profile.all_finished_tasks.sort_by(&:created_at)
11 end 12 end
12 13
13 - VALID_DECISIONS = [ 'finish', 'cancel' ] 14 + VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ]
14 15
15 def close 16 def close
16 - decision = params[:decision]  
17 - if request.post? && VALID_DECISIONS.include?(decision) && params[:id]  
18 - task = profile.find_in_all_tasks(params[:id])  
19 - task.update_attributes(params[:task])  
20 - begin  
21 - task.send(decision)  
22 - rescue Exception => ex  
23 - session[:notice] = ex.clean_message 17 + failed = {}
  18 +
  19 + params[:tasks].each do |id, value|
  20 + decision = value[:decision]
  21 + if request.post? && VALID_DECISIONS.include?(decision) && id && decision != 'skip'
  22 + task = profile.find_in_all_tasks(id)
  23 + task.update_attributes!(value[:task])
  24 + begin
  25 + task.send(decision)
  26 + rescue Exception => ex
  27 + message = "#{task.title} (#{task.requestor ? task.requestor.name : task.author_name})"
  28 + failed[ex.clean_message] ? failed[ex.clean_message] << message : failed[ex.clean_message] = [message]
  29 + end
24 end 30 end
25 end 31 end
26 - redirect_to :action => 'index' 32 +
  33 + if failed.blank?
  34 + session[:notice] = _("All decisions were applied successfully.")
  35 + else
  36 + session[:notice] = _("Some tasks couldn't be applied.")
  37 + end
  38 + redirect_to params.merge!(:action => 'index', :failed => failed)
27 end 39 end
28 40
29 def new 41 def new
app/helpers/application_helper.rb
@@ -279,6 +279,19 @@ module ApplicationHelper @@ -279,6 +279,19 @@ module ApplicationHelper
279 end 279 end
280 end 280 end
281 281
  282 + def partial_for_task_class(klass, action)
  283 + if klass.nil?
  284 + raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?'
  285 + end
  286 +
  287 + name = "#{klass.name.underscore}_#{action.to_s}"
  288 + if File.exists?(File.join(RAILS_ROOT, 'app', 'views', params[:controller], "_#{name}.rhtml"))
  289 + name
  290 + else
  291 + partial_for_task_class(klass.superclass, action)
  292 + end
  293 + end
  294 +
282 def user 295 def user
283 @controller.send(:user) 296 @controller.send(:user)
284 end 297 end
@@ -621,7 +634,16 @@ module ApplicationHelper @@ -621,7 +634,16 @@ module ApplicationHelper
621 end 634 end
622 635
623 def select_folder(label, object, method, collection, html_options = {}, js_options = {}) 636 def select_folder(label, object, method, collection, html_options = {}, js_options = {})
624 - labelled_form_field(label, select(object, method, collection.map {|f| [ profile.identifier + '/' + f.full_name, f.id ] }, html_options.merge({:include_blank => "#{profile.identifier}"}), js_options)) 637 + root = profile ? profile.identifier : _("root")
  638 + labelled_form_field(label, select(object, method,
  639 + collection.map {|f| [ root + '/' + f.full_name, f.id ]},
  640 + {:include_blank => root}, html_options.merge(js_options)))
  641 + end
  642 +
  643 + def select_profile_folder(label, object, method, profile, html_options = {}, js_options = {})
  644 + labelled_form_field(label, select(object, method,
  645 + profile.folders.map {|f| [ profile.identifier + '/' + f.full_name, f.id ]},
  646 + {:include_blank => profile.identifier}, html_options.merge(js_options)))
625 end 647 end
626 648
627 def theme_option(opt = nil) 649 def theme_option(opt = nil)
@@ -1094,10 +1116,16 @@ module ApplicationHelper @@ -1094,10 +1116,16 @@ module ApplicationHelper
1094 end 1116 end
1095 1117
1096 def usermenu_logged_in 1118 def usermenu_logged_in
  1119 + pending_tasks_count = ''
  1120 + if user && user.all_pending_tasks.count > 0
  1121 + pending_tasks_count = link_to(user.all_pending_tasks.count.to_s, '/myprofile/{login}/tasks', :id => 'pending-tasks-count')
  1122 + end
  1123 +
1097 (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + 1124 (_('Welcome, %s') % link_to('<i></i><strong>{login}</strong>', '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) +
1098 render_environment_features(:usermenu) + 1125 render_environment_features(:usermenu) +
1099 link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + 1126 link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', { :controller => 'admin_panel', :action => 'index' }, :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') +
1100 link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) + 1127 link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) +
  1128 + pending_tasks_count +
1101 link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) 1129 link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system"))
1102 end 1130 end
1103 1131
@@ -1164,4 +1192,13 @@ module ApplicationHelper @@ -1164,4 +1192,13 @@ module ApplicationHelper
1164 content_tag(:div, _('Source: %s') % source_url, :id => 'article-source') unless source_url.nil? 1192 content_tag(:div, _('Source: %s') % source_url, :id => 'article-source') unless source_url.nil?
1165 end 1193 end
1166 1194
  1195 + def task_information(task)
  1196 + values = {}
  1197 + values.merge!({:requestor => link_to(task.requestor.name, task.requestor.public_profile_url)}) if task.requestor
  1198 + values.merge!({:subject => content_tag('span', task.subject, :class=>'task_target')}) if task.subject
  1199 + values.merge!({:linked_subject => link_to(content_tag('span', task.linked_subject[:text], :class => 'task_target'), task.linked_subject[:url])}) if task.linked_subject
  1200 + values.merge!(task.information[:variables]) if task.information[:variables]
  1201 + task.information[:message] % values
  1202 + end
  1203 +
1167 end 1204 end
app/models/add_friend.rb
@@ -6,7 +6,7 @@ class AddFriend &lt; Task @@ -6,7 +6,7 @@ class AddFriend &lt; Task
6 6
7 validates_uniqueness_of :target_id, :scope => [ :requestor_id ] 7 validates_uniqueness_of :target_id, :scope => [ :requestor_id ]
8 8
9 - validates_length_of :group_for_person, :group_for_friend, :maximum => 150, :allow_nil => true 9 + validates_length_of :group_for_person, :group_for_friend, :maximum => 150, :allow_nil => true
10 10
11 alias :person :requestor 11 alias :person :requestor
12 alias :person= :requestor= 12 alias :person= :requestor=
@@ -19,17 +19,29 @@ class AddFriend &lt; Task @@ -19,17 +19,29 @@ class AddFriend &lt; Task
19 requestor.add_friend(target, group_for_person) 19 requestor.add_friend(target, group_for_person)
20 end 20 end
21 21
22 - def description  
23 - _('%s wants to be your friend.') % requestor.name  
24 - end  
25 -  
26 def permission 22 def permission
27 :manage_friends 23 :manage_friends
28 end 24 end
29 25
30 def target_notification_message 26 def target_notification_message
31 - description + "\n\n" + 27 + _('%{requestor} wants to be your friend.') % {:requestor => requestor.name} + "\n\n" +
32 _('You need to login to %{system} in order to accept %{requestor} as your friend.') % { :system => target.environment.name, :requestor => requestor.name } 28 _('You need to login to %{system} in order to accept %{requestor} as your friend.') % { :system => target.environment.name, :requestor => requestor.name }
33 end 29 end
34 30
  31 + def title
  32 + _("New friend")
  33 + end
  34 +
  35 + def information
  36 + {:message => _('%{requestor} wants to be your friend.') }
  37 + end
  38 +
  39 + def accept_details
  40 + true
  41 + end
  42 +
  43 + def icon
  44 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
  45 + end
  46 +
35 end 47 end
app/models/add_member.rb
@@ -15,8 +15,20 @@ class AddMember &lt; Task @@ -15,8 +15,20 @@ class AddMember &lt; Task
15 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)}) 15 target.affiliate(requestor, self.roles.select{|r| !r.to_i.zero? }.map{|i| Role.find(i)})
16 end 16 end
17 17
18 - def description  
19 - _('%s wants to be a member of "%s".') % [requestor.name, organization.name] 18 + def title
  19 + _("New member")
  20 + end
  21 +
  22 + def information
  23 + {:message => _('%{requestor} wants to be a member of this community.')}
  24 + end
  25 +
  26 + def accept_details
  27 + true
  28 + end
  29 +
  30 + def icon
  31 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
20 end 32 end
21 33
22 def permission 34 def permission
@@ -24,7 +36,7 @@ class AddMember &lt; Task @@ -24,7 +36,7 @@ class AddMember &lt; Task
24 end 36 end
25 37
26 def target_notification_message 38 def target_notification_message
27 - description + "\n\n" + 39 + _('%{requestor} wants to be a member of this community.') % {:requestor => requestor.name} + "\n\n" +
28 _('You will need login to %{system} in order to accept or reject %{requestor} as a member of %{organization}.') % { :system => target.environment.name, :requestor => requestor.name, :organization => organization.name } 40 _('You will need login to %{system} in order to accept or reject %{requestor} as a member of %{organization}.') % { :system => target.environment.name, :requestor => requestor.name, :organization => organization.name }
29 end 41 end
30 42
app/models/approve_article.rb
@@ -3,10 +3,6 @@ class ApproveArticle &lt; Task @@ -3,10 +3,6 @@ class ApproveArticle &lt; Task
3 3
4 validates_presence_of :requestor_id, :target_id 4 validates_presence_of :requestor_id, :target_id
5 5
6 - def description  
7 - _('%{author} wants to publish "%{article}" on %{community}') % { :author => requestor.name, :article => article_title, :community => target.name }  
8 - end  
9 -  
10 def article_title 6 def article_title
11 article ? article.title : _('(The original text was removed)') 7 article ? article.title : _('(The original text was removed)')
12 end 8 end
@@ -24,7 +20,7 @@ class ApproveArticle &lt; Task @@ -24,7 +20,7 @@ class ApproveArticle &lt; Task
24 end 20 end
25 21
26 def name 22 def name
27 - data[:name].blank? ? article.name : data[:name] 23 + data[:name].blank? ? (article ? article.name : _("Article removed.")) : data[:name]
28 end 24 end
29 25
30 def name= value 26 def name= value
@@ -68,7 +64,7 @@ class ApproveArticle &lt; Task @@ -68,7 +64,7 @@ class ApproveArticle &lt; Task
68 end 64 end
69 65
70 def abstract 66 def abstract
71 - data[:abstract].blank? ? article.abstract : data[:abstract] 67 + data[:abstract].blank? ? (article ? article.abstract : '') : data[:abstract]
72 end 68 end
73 69
74 def body= value 70 def body= value
@@ -76,17 +72,63 @@ class ApproveArticle &lt; Task @@ -76,17 +72,63 @@ class ApproveArticle &lt; Task
76 end 72 end
77 73
78 def body 74 def body
79 - data[:body].blank? ? article.body : data[:body] 75 + data[:body].blank? ? (article ? article.body : "") : data[:body]
80 end 76 end
81 77
82 def perform 78 def perform
83 article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source) 79 article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source)
84 end 80 end
85 81
  82 + def title
  83 + _("New article")
  84 + end
  85 +
  86 + def icon
  87 + result = {:type => :defined_image, :src => '/images/icons-app/article-minor.png', :name => name}
  88 + result.merge({:url => article.url}) if article
  89 + return result
  90 + end
  91 +
  92 + def linked_subject
  93 + {:text => name, :url => article.url} if article
  94 + end
  95 +
  96 + def information
  97 + if article
  98 + {:message => _('%{requestor} wants to publish the article: %{linked_subject}.')}
  99 + else
  100 + {:message => _("The article was removed.")}
  101 + end
  102 + end
  103 +
  104 + def accept_details
  105 + true
  106 + end
  107 +
  108 + def default_decision
  109 + if article
  110 + 'skip'
  111 + else
  112 + 'reject'
  113 + end
  114 + end
  115 +
  116 + def accept_disabled?
  117 + article.blank?
  118 + end
  119 +
86 def target_notification_message 120 def target_notification_message
87 return nil if target.organization? && !target.moderated_articles? 121 return nil if target.organization? && !target.moderated_articles?
88 - description + "\n\n" + 122 + _('%{requestor} wants to publish the article: %{article}.') % {:requestor => requestor.name, :article => article.name} + "\n\n"
89 _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name } 123 _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name }
90 end 124 end
91 125
  126 + def task_finished_message
  127 + if !closing_statment.blank?
  128 + _("Your request for publishing the article \"%{article}\" was approved. Here is the comment left by the admin who approved your article:\n\n%{comment} ") % {:article => name, :comment => closing_statment}
  129 + else
  130 + _('Your request for publishing the article "%{article}" was approved.') % {:article => name}
  131 + end
  132 + end
  133 +
92 end 134 end
app/models/change_password.rb
@@ -61,6 +61,18 @@ class ChangePassword &lt; Task @@ -61,6 +61,18 @@ class ChangePassword &lt; Task
61 self[:data] = {} 61 self[:data] = {}
62 end 62 end
63 63
  64 + def title
  65 + _("Change password")
  66 + end
  67 +
  68 + def information
  69 + {:message => _('%{requestor} wants to change its password.')}
  70 + end
  71 +
  72 + def icon
  73 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
  74 + end
  75 +
64 def perform 76 def perform
65 user = self.requestor.user 77 user = self.requestor.user
66 user.force_change_password!(self.password, self.password_confirmation) 78 user.force_change_password!(self.password, self.password_confirmation)
@@ -87,10 +99,6 @@ class ChangePassword &lt; Task @@ -87,10 +99,6 @@ class ChangePassword &lt; Task
87 end 99 end
88 end 100 end
89 101
90 - def description  
91 - _('Password change request')  
92 - end  
93 -  
94 def environment 102 def environment
95 self.requestor.environment 103 self.requestor.environment
96 end 104 end
app/models/community.rb
@@ -39,6 +39,10 @@ class Community &lt; Organization @@ -39,6 +39,10 @@ class Community &lt; Organization
39 end 39 end
40 end 40 end
41 41
  42 + def display_name
  43 + self.name
  44 + end
  45 +
42 def active_fields 46 def active_fields
43 environment ? environment.active_community_fields : [] 47 environment ? environment.active_community_fields : []
44 end 48 end
app/models/create_community.rb
@@ -48,16 +48,34 @@ class CreateCommunity &lt; Task @@ -48,16 +48,34 @@ class CreateCommunity &lt; Task
48 community.add_admin(self.requestor) 48 community.add_admin(self.requestor)
49 end 49 end
50 50
51 - def description  
52 - _('%s wants to create community %s.') % [requestor.name, self.name] 51 + def title
  52 + _("New community")
53 end 53 end
54 54
55 - def closing_statement  
56 - data[:closing_statement] 55 + def icon
  56 + src = image ? image.public_filename(:minor) : '/images/icons-app/community-minor.png'
  57 + {:type => :defined_image, :src => src, :name => name}
57 end 58 end
58 59
59 - def closing_statement= value  
60 - data[:closing_statement] = value 60 + def subject
  61 + name
  62 + end
  63 +
  64 + def information
  65 + if description.blank?
  66 + { :message => _('%{requestor} wants to create community %{subject} with no description.') }
  67 + else
  68 + { :message => _('%{requestor} wants to create community %{subject} with this description:<p><em>%{description}</em></p>'),
  69 + :variables => {:description => description} }
  70 + end
  71 + end
  72 +
  73 + def reject_details
  74 + true
  75 + end
  76 +
  77 + def display_name
  78 + self.name
61 end 79 end
62 80
63 # tells if this request was rejected 81 # tells if this request was rejected
@@ -71,7 +89,6 @@ class CreateCommunity &lt; Task @@ -71,7 +89,6 @@ class CreateCommunity &lt; Task
71 end 89 end
72 90
73 def target_notification_message 91 def target_notification_message
74 - description + "\n\n" +  
75 _("User \"%{user}\" just requested to create community %{community}. You have to approve or reject it through the \"Pending Validations\" section in your control panel.\n") % { :user => self.requestor.name, :community => self.name } 92 _("User \"%{user}\" just requested to create community %{community}. You have to approve or reject it through the \"Pending Validations\" section in your control panel.\n") % { :user => self.requestor.name, :community => self.name }
76 end 93 end
77 94
@@ -82,7 +99,7 @@ class CreateCommunity &lt; Task @@ -82,7 +99,7 @@ class CreateCommunity &lt; Task
82 end 99 end
83 100
84 def task_cancelled_message 101 def task_cancelled_message
85 - _("Your request for registering community %{community} at %{environment} was not approved by the environment administrator. The following explanation was given: \n\n%{explanation}") % { :community => self.name, :environment => self.environment, :explanation => self.closing_statement } 102 + _("Your request for registering community %{community} at %{environment} was not approved by the environment administrator. The following explanation was given: \n\n%{explanation}") % { :community => self.name, :environment => self.environment, :explanation => self.reject_explanation }
86 end 103 end
87 104
88 def task_finished_message 105 def task_finished_message
app/models/create_enterprise.rb
@@ -11,7 +11,7 @@ class CreateEnterprise &lt; Task @@ -11,7 +11,7 @@ class CreateEnterprise &lt; Task
11 N_('Economic activity') 11 N_('Economic activity')
12 N_('Management information') 12 N_('Management information')
13 13
14 - DATA_FIELDS = Enterprise.fields + %w[name identifier region_id reject_explanation] 14 + DATA_FIELDS = Enterprise.fields + %w[name identifier region_id]
15 15
16 serialize :data, Hash 16 serialize :data, Hash
17 attr_protected :data 17 attr_protected :data
@@ -48,7 +48,6 @@ class CreateEnterprise &lt; Task @@ -48,7 +48,6 @@ class CreateEnterprise &lt; Task
48 48
49 # check for explanation when rejecting 49 # check for explanation when rejecting
50 validates_presence_of :reject_explanation, :if => (lambda { |record| record.status == Task::Status::CANCELLED } ) 50 validates_presence_of :reject_explanation, :if => (lambda { |record| record.status == Task::Status::CANCELLED } )
51 -  
52 xss_terminate :only => [ :acronym, :address, :contact_person, :contact_phone, :economic_activity, :legal_form, :management_information, :name ], :on => 'validation' 51 xss_terminate :only => [ :acronym, :address, :contact_person, :contact_phone, :economic_activity, :legal_form, :management_information, :name ], :on => 'validation'
53 52
54 def validate 53 def validate
@@ -153,8 +152,24 @@ class CreateEnterprise &lt; Task @@ -153,8 +152,24 @@ class CreateEnterprise &lt; Task
153 enterprise.add_admin(enterprise.user.person) 152 enterprise.add_admin(enterprise.user.person)
154 end 153 end
155 154
156 - def description  
157 - __('Enterprise registration: "%s"') % self.name 155 + def title
  156 + _("Enterprise registration")
  157 + end
  158 +
  159 + def icon
  160 + {:type => :defined_image, :src => '/images/icons-app/enterprise-minor.png', :name => name}
  161 + end
  162 +
  163 + def subject
  164 + name
  165 + end
  166 +
  167 + def information
  168 + {:message => _('%{requestor} wants to create enterprise %{subject}.')}
  169 + end
  170 +
  171 + def reject_details
  172 + true
158 end 173 end
159 174
160 def task_created_message 175 def task_created_message
app/models/email_activation.rb
@@ -11,8 +11,20 @@ class EmailActivation &lt; Task @@ -11,8 +11,20 @@ class EmailActivation &lt; Task
11 end 11 end
12 end 12 end
13 13
14 - def description  
15 - _("'%{user} wants to activate email '%{email}'") % { :user => person.name, :email => person.email_addresses.join(', ') } 14 + def title
  15 + _("Email activation")
  16 + end
  17 +
  18 + def subject
  19 + person.email_addresses.join(', ')
  20 + end
  21 +
  22 + def information
  23 + {:message => _("%{requestor} wants to activate the following email: %{subject}.")}
  24 + end
  25 +
  26 + def icon
  27 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
16 end 28 end
17 29
18 def perform 30 def perform
app/models/enterprise_activation.rb
@@ -20,4 +20,20 @@ class EnterpriseActivation &lt; Task @@ -20,4 +20,20 @@ class EnterpriseActivation &lt; Task
20 self.enterprise.enable(requestor) 20 self.enterprise.enable(requestor)
21 end 21 end
22 22
  23 + def title
  24 + _("Enterprise activation")
  25 + end
  26 +
  27 + def linked_subject
  28 + {:text => target.name, :url => target.public_profile_url}
  29 + end
  30 +
  31 + def information
  32 + {:message => _('%{requestor} wants to activate enterprise %{linked_subject}.')}
  33 + end
  34 +
  35 + def icon
  36 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
  37 + end
  38 +
23 end 39 end
app/models/invite_friend.rb
@@ -7,8 +7,20 @@ class InviteFriend &lt; Invitation @@ -7,8 +7,20 @@ class InviteFriend &lt; Invitation
7 friend.add_friend(person, group_for_friend) 7 friend.add_friend(person, group_for_friend)
8 end 8 end
9 9
10 - def description  
11 - _('%s invited you to join %s') % [person.name, person.environment.name] 10 + def title
  11 + _("New friend")
  12 + end
  13 +
  14 + def information
  15 + {:message => _('%{requestor} wants to be your friend.')}
  16 + end
  17 +
  18 + def accept_details
  19 + true
  20 + end
  21 +
  22 + def icon
  23 + {:type => :profile_image, :profile => requestor, :url => requestor.url}
12 end 24 end
13 25
14 def permission 26 def permission
app/models/invite_member.rb
@@ -15,8 +15,24 @@ class InviteMember &lt; Invitation @@ -15,8 +15,24 @@ class InviteMember &lt; Invitation
15 community.add_member(friend) 15 community.add_member(friend)
16 end 16 end
17 17
18 - def description  
19 - _('%s invited you to join the community %s') % [person.name, community.name] 18 + def title
  19 + _("Community invitation")
  20 + end
  21 +
  22 + def linked_subject
  23 + {:text => community.name, :url => community.public_profile_url}
  24 + end
  25 +
  26 + def information
  27 + {:message => _('%{requestor} invited you to join %{linked_subject}.')}
  28 + end
  29 +
  30 + def url
  31 + community.url
  32 + end
  33 +
  34 + def icon
  35 + {:type => :profile_image, :profile => community, :url => community.url}
20 end 36 end
21 37
22 def expanded_message 38 def expanded_message
app/models/suggest_article.rb
@@ -7,10 +7,6 @@ class SuggestArticle &lt; Task @@ -7,10 +7,6 @@ class SuggestArticle &lt; Task
7 7
8 validates_presence_of :target_id, :article_name, :email, :name, :article_body 8 validates_presence_of :target_id, :article_name, :email, :name, :article_body
9 9
10 - def description  
11 - _('%{sender} suggested to publish "%{article}" on %{community}') % { :sender => sender, :article => article_name, :community => target.name }  
12 - end  
13 -  
14 settings_items :email, :type => String 10 settings_items :email, :type => String
15 settings_items :name, :type => String 11 settings_items :name, :type => String
16 settings_items :article_name, :type => String 12 settings_items :article_name, :type => String
@@ -39,8 +35,30 @@ class SuggestArticle &lt; Task @@ -39,8 +35,30 @@ class SuggestArticle &lt; Task
39 ) 35 )
40 end 36 end
41 37
  38 + def title
  39 + _("Article suggestion")
  40 + end
  41 +
  42 + def subject
  43 + article_name
  44 + end
  45 +
  46 + def information
  47 + { :message => _('%{sender} suggested the publication of the article: %{subject}.'),
  48 + :variables => {:sender => sender} }
  49 + end
  50 +
  51 + def accept_details
  52 + true
  53 + end
  54 +
  55 + def icon
  56 + result = {:type => :defined_image, :src => '/images/icons-app/article-minor.png', :name => article_name}
  57 + end
  58 +
42 def target_notification_message 59 def target_notification_message
43 - description + "\n\n" + 60 + _('%{sender} suggested the publication of the article: %{article}.') %
  61 + {:sender => sender, :article => article_name} + "\n\n" +
44 _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name } 62 _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name }
45 end 63 end
46 64
app/models/task.rb
@@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
11 # will need to declare <ttserialize</tt> itself). 11 # will need to declare <ttserialize</tt> itself).
12 class Task < ActiveRecord::Base 12 class Task < ActiveRecord::Base
13 13
  14 + acts_as_having_settings :field => :data
  15 +
14 module Status 16 module Status
15 # the status of tasks just created 17 # the status of tasks just created
16 ACTIVE = 1 18 ACTIVE = 1
@@ -86,6 +88,14 @@ class Task &lt; ActiveRecord::Base @@ -86,6 +88,14 @@ class Task &lt; ActiveRecord::Base
86 def after_finish 88 def after_finish
87 end 89 end
88 90
  91 + def reject_explanation=(reject_explanation='')
  92 + self.data[:reject_explanation] = reject_explanation
  93 + end
  94 +
  95 + def reject_explanation
  96 + self.data[:reject_explanation]
  97 + end
  98 +
89 # this method cancels the task. At the end a message (as returned by 99 # this method cancels the task. At the end a message (as returned by
90 # #cancel_message) is sent to the requestor with #notify_requestor. 100 # #cancel_message) is sent to the requestor with #notify_requestor.
91 def cancel 101 def cancel
@@ -101,13 +111,50 @@ class Task &lt; ActiveRecord::Base @@ -101,13 +111,50 @@ class Task &lt; ActiveRecord::Base
101 end 111 end
102 end 112 end
103 113
  114 + # Here are the tasks customizable options.
104 115
105 - # Returns the description of the task.  
106 - #  
107 - # This method +must+ be overriden in subclasses to return something  
108 - # meaningful for each kind of task  
109 - def description  
110 - _('Generic task') 116 + def title
  117 + _("Task")
  118 + end
  119 +
  120 + def subject
  121 + nil
  122 + end
  123 +
  124 + def linked_subject
  125 + nil
  126 + end
  127 +
  128 + def information
  129 + {:message => _('%{requestor} sent you a task.')}
  130 + end
  131 +
  132 + def accept_details
  133 + false
  134 + end
  135 +
  136 + def reject_details
  137 + false
  138 + end
  139 +
  140 + def icon
  141 + {:type => :defined_image, :src => "/images/icons-app/user-minor.png", :name => requestor.name, :url => requestor.url}
  142 + end
  143 +
  144 + def default_decision
  145 + 'skip'
  146 + end
  147 +
  148 + def accept_disabled?
  149 + false
  150 + end
  151 +
  152 + def reject_disabled?
  153 + false
  154 + end
  155 +
  156 + def skip_disabled?
  157 + false
111 end 158 end
112 159
113 # The message that will be sent to the requestor of the task when the task is 160 # The message that will be sent to the requestor of the task when the task is
app/models/task_mailer.rb
@@ -17,7 +17,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -17,7 +17,7 @@ class TaskMailer &lt; ActionMailer::Base
17 url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.url.merge(:controller => 'tasks', :action => 'index')) 17 url_for_tasks_list = task.target.kind_of?(Environment) ? '' : url_for(task.target.url.merge(:controller => 'tasks', :action => 'index'))
18 18
19 from self.class.generate_from(task) 19 from self.class.generate_from(task)
20 - subject '[%s] %s' % [task.environment.name, task.description] 20 + subject '[%s] %s' % [task.environment.name, task.information]
21 body :target => task.target.name, 21 body :target => task.target.name,
22 :message => msg, 22 :message => msg,
23 :environment => task.environment.name, 23 :environment => task.environment.name,
@@ -32,7 +32,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -32,7 +32,7 @@ class TaskMailer &lt; ActionMailer::Base
32 recipients task.friend_email 32 recipients task.friend_email
33 33
34 from self.class.generate_from(task) 34 from self.class.generate_from(task)
35 - subject '[%s] %s' % [ task.requestor.environment.name, task.description ] 35 + subject '[%s] %s' % [ task.requestor.environment.name, task.information ]
36 body :message => msg 36 body :message => msg
37 end 37 end
38 38
@@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base @@ -52,7 +52,7 @@ class TaskMailer &lt; ActionMailer::Base
52 52
53 recipients task.requestor.notification_emails 53 recipients task.requestor.notification_emails
54 from self.class.generate_from(task) 54 from self.class.generate_from(task)
55 - subject '[%s] %s' % [task.requestor.environment.name, task.description] 55 + subject '[%s] %s' % [task.requestor.environment.name, task.information]
56 body :requestor => task.requestor.name, 56 body :requestor => task.requestor.name,
57 :message => text, 57 :message => text,
58 :environment => task.requestor.environment.name, 58 :environment => task.requestor.environment.name,
app/models/ticket.rb
1 class Ticket < Task 1 class Ticket < Task
2 acts_as_having_settings :field => :data 2 acts_as_having_settings :field => :data
3 - settings_items :title, :description, :closing_statment 3 + settings_items :title, :message
4 end 4 end
app/views/pending_task_notifier/notification.rhtml
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 <% pending_tasks = @person.pending_tasks_for_organization(organization) %> 11 <% pending_tasks = @person.pending_tasks_for_organization(organization) %>
12 <%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %> 12 <%= _("%s has %d pending task(s).") % [organization.name, pending_tasks.size] %>
13 13
14 -<%= pending_tasks.map{|i| " * #{i.description}"}.join("\n") %> 14 +<%= pending_tasks.map{|i| " * #{i.information}"}.join("\n") %>
15 15
16 <%= _("Click in address below to process task(s):") %> 16 <%= _("Click in address below to process task(s):") %>
17 17
app/views/profile_editor/_pending_tasks.rhtml
  1 +<%= stylesheet_link_tag 'tasks' %>
  2 +
1 <% unless @pending_tasks.empty? %> 3 <% unless @pending_tasks.empty? %>
2 <div class='pending-tasks'> 4 <div class='pending-tasks'>
3 <h2><%= _('You have pending requests') %></h2> 5 <h2><%= _('You have pending requests') %></h2>
4 <ul> 6 <ul>
5 - <%= @pending_tasks.map {|item| content_tag('li', item.description)} %> 7 + <%= @pending_tasks.map {|task| content_tag('li', task_information(task))} %>
6 </ul> 8 </ul>
7 <%= button(:todo, _('Process requests'), :controller => 'tasks', :action => 'index') %> 9 <%= button(:todo, _('Process requests'), :controller => 'tasks', :action => 'index') %>
8 </div> 10 </div>
app/views/tasks/_add_friend.rhtml
@@ -1,40 +0,0 @@ @@ -1,40 +0,0 @@
1 -<h2><%= _('New friend') %></h2>  
2 -  
3 -<%= link_to( profile_image(task.requestor, :minor, :border => 0), task.requestor.public_profile_url ) %>  
4 -  
5 -<%= _('%s wants to be your friend.') %  
6 - content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ) %>  
7 -  
8 -<% form_for('task', task, :url => { :action => 'close', :id => task.id } ) do |f| %>  
9 -  
10 - <div>  
11 -  
12 - <%= radio_button_tag(:decision, 'finish', true,  
13 - :id => "decision-finish-#{task.id}",  
14 - :onclick => "Element.show('group-for-friend-#{task.id}')") %>  
15 - <label for="<%= "decision-finish-#{task.id}" %>"><b><%= _('Accept') %></b></label>  
16 -  
17 - &nbsp; &nbsp;  
18 -  
19 - <%= radio_button_tag(:decision, 'cancel', false,  
20 - :id => "decision-cancel-#{task.id}",  
21 - :onclick => "Element.hide('group-for-friend-#{task.id}')") %>  
22 - <label for="<%= "decision-cancel-#{task.id}" %>"><b><%= _('Ignore') %></b></label>  
23 -  
24 - <% content_tag('div', :id => "group-for-friend-#{task.id}", :class => "add-friend-tags") do %>  
25 - <%= _('Classify your new friend:') %>  
26 - <%= text_field_with_local_autocomplete("task[group_for_friend]",  
27 - profile.suggested_friend_groups,  
28 - {:id => "field-group-for-friend-#{task.id}", :maxlength => 150}) %>  
29 -  
30 - <p class="friend-classify-suggestions">  
31 - <%= _('Suggestions: %s') % profile.suggested_friend_groups.join(', ') %>  
32 - </p>  
33 - <% end %>  
34 -  
35 - </div>  
36 -  
37 - <% button_bar do %>  
38 - <%= submit_button(:ok, _('Ok!')) %>  
39 - <% end %>  
40 -<% end %>  
app/views/tasks/_add_friend_accept_details.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%=_('Classify your new friend:') +
  2 +text_field_with_local_autocomplete("tasks[#{task.id}][task][group_for_friend]",
  3 + task.target.suggested_friend_groups,
  4 + {:id => "field-group-for-friend-#{task.id}", :maxlength => 150})
  5 +%>
  6 +<p class="friend-classify-suggestions">
  7 + <%=_('Suggestions: %s') % task.target.suggested_friend_groups.join(', ') %>
  8 +</p>
app/views/tasks/_add_member.rhtml
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -<h2><%= _('New member') %></h2>  
2 -  
3 -<%= link_to( profile_image(task.requestor, :minor, :border => 0), task.requestor.public_profile_url ) %>  
4 -  
5 -<%= _('%s wants to be a member of %s.') %  
6 - [content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ),  
7 - content_tag('strong', link_to( task.target.name, task.target.public_profile_url ) )] %>  
8 -  
9 -<% form_for('task', task, :url => { :action => 'close', :id => task.id } ) do |f| %>  
10 -  
11 - <div>  
12 - <%= radio_button_tag(:decision, 'finish', true,  
13 - :id => "decision-finish-#{task.id}",  
14 - :onclick => "Element.show('group-for-friend-#{task.id}')") %>  
15 - <label for="<%= "decision-finish-#{task.id}" %>"><b><%= _('Accept') %></b></label>  
16 -  
17 - &nbsp; &nbsp;  
18 -  
19 - <%= radio_button_tag(:decision, 'cancel', false,  
20 - :id => "decision-cancel-#{task.id}",  
21 - :onclick => "Element.hide('group-for-friend-#{task.id}')") %>  
22 - <label for="<%= "decision-cancel-#{task.id}" %>"><b><%= _('Ignore') %></b></label>  
23 -  
24 - <p class="member-classify-suggestions">  
25 - <%= _('Roles:') %> <br>  
26 - <%  
27 - @roles = task.target.environment.roles.find(:all).select{ |r| r.has_kind?('Profile') }  
28 - %>  
29 - <% @roles.each do |r| %>  
30 - <%= labelled_check_box(r.name, 'task[roles][]', r.id, ( task.target.members.empty? ? true : ( r.id == Profile::Roles.member(r.environment.id).id ) ) ) %><br/>  
31 - <% end %>  
32 - </p>  
33 - </div>  
34 -  
35 - <% button_bar do %>  
36 - <%= submit_button(:ok, _('Ok!')) %>  
37 - <% end %>  
38 -<% end %>  
app/views/tasks/_add_member_accept_details.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<%= content = _("Roles:")+"<br />"
  2 +roles = Profile::Roles.organization_member_roles(task.target.environment.id)
  3 +roles.each do |role|
  4 + content += labelled_check_box(role.name, "tasks[#{task.id}][roles][]", role.id, false)+"<br />"
  5 +end
  6 +content_tag('p', content, :class => 'member-classify-suggestion')
  7 +%>
  8 +
app/views/tasks/_approve_article.rhtml
@@ -1,43 +0,0 @@ @@ -1,43 +0,0 @@
1 -<h2><%= _('New article') %></h2>  
2 -  
3 -<% form_for('task', task, :url => { :action => 'close', :id => task.id } ) do |f| %>  
4 -  
5 - <% if task.article.nil? %>  
6 - <%= _('%s wanted to publish some content, but this content was deleted and cannot be published anymore.') % content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ) %>  
7 - <%= hidden_field_tag(:decision, 'cancel') %>  
8 - <% else %>  
9 - <%= _('%s wants to publish content: %s.') %  
10 - [content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ),  
11 - content_tag('strong', link_to( task.article.name, task.article.url ) )] %>  
12 -  
13 - <div>  
14 - <%= radio_button_tag(:decision, 'finish', true,  
15 - :id => "decision-finish-#{task.id}",  
16 - :onclick => "Element.show('group-for-friend-#{task.id}')") %>  
17 - <label for="<%= "decision-finish-#{task.id}" %>"><b><%= _('Accept') %></b></label>  
18 -  
19 - &nbsp; &nbsp;  
20 -  
21 - <%= radio_button_tag(:decision, 'cancel', false,  
22 - :id => "decision-cancel-#{task.id}",  
23 - :onclick => "Element.hide('group-for-friend-#{task.id}')") %>  
24 - <label for="<%= "decision-cancel-#{task.id}" %>"><b><%= _('Ignore') %></b></label>  
25 -  
26 - <%= labelled_form_field _('Name for publishing'), f.text_field(:name, :style => 'width:80%;') %>  
27 -  
28 - <%= select_folder(_('Select the folder where the article must be published'), 'task', 'article_parent_id', task.target.folders) %>  
29 - <div>  
30 - <%= f.check_box(:highlighted) %>  
31 - <label for="article_highlighted"><%= _('Highlight this article')%></label>  
32 - </div>  
33 -  
34 - <%= labelled_form_field _('Comment for author'), f.text_field(:closing_statment, :style => 'width:80%;') %>  
35 - <%= render :partial => partial_for_class(task.article.class), :locals => { :f => f } %>  
36 -  
37 - </div>  
38 - <% end %>  
39 -  
40 - <% button_bar do %>  
41 - <%= submit_button(:ok, _('Ok!')) %>  
42 - <% end %>  
43 -<% end %>  
app/views/tasks/_approve_article_accept_details.rhtml 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +<%= labelled_form_field(_('Name for publishing'), f.text_field(:name)) %>
  2 +<%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task]", 'article_parent_id', task.target) %>
  3 +<%= labelled_form_field(_('Highlight this article'), f.check_box(:highlighted)) %>
  4 +
  5 +<div>
  6 + <%= labelled_form_field(_('Lead'), f.text_area(:abstract, :style => 'width: 482px; height: 200px;')) %>
  7 +</div>
  8 +<em><%= _('Used when a short version your text is needed.') %></em>
  9 +
  10 +<div style="margin-top: 10px;">
  11 + <%= labelled_form_field(_('Text'), f.text_area(:body, :style => 'width:482px; height: 500px;')) %>
  12 +</div>
  13 +<%= labelled_form_field _('Comment for author'), f.text_field(:closing_statment, :style => 'width: 488px;') %>
  14 +
app/views/tasks/_create_community.rhtml
@@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
1 -<h2><%= _('New community') %></h2>  
2 -  
3 -<%= link_to( profile_image(task.requestor, :minor, :border => 0), task.requestor.public_profile_url ) %>  
4 -  
5 -<%= _('%s wants to create community %s.') %  
6 - [content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ),  
7 - content_tag('strong', task.name )] %>  
8 -  
9 -<% form_for('task', task, :url => { :action => 'close', :id => task.id } ) do |f| %>  
10 -  
11 - <div>  
12 - <% if !Profile.is_available?(task.name.to_slug, environment) %>  
13 - <p><b><%= _('This name was already taken, this community cannot be approved') %></b></p>  
14 - <%= hidden_field_tag(:decision, 'cancel') %>  
15 - <% else %>  
16 - <%= radio_button_tag(:decision, 'finish', true,  
17 - :id => "decision-finish-#{task.id}",  
18 - :onclick => "hide_closing_statement_area(#{task.id})") %>  
19 - <label for="<%= "decision-finish-#{task.id}" %>"><b><%= _('Approve') %></b></label>  
20 -  
21 - &nbsp; &nbsp;  
22 -  
23 - <%= radio_button_tag(:decision, 'cancel', false,  
24 - :id => "decision-cancel-#{task.id}",  
25 - :onclick => "show_closing_statement_area(#{task.id})") %>  
26 - <label for="<%= "decision-cancel-#{task.id}" %>"><b><%= _('Reject') %></b></label>  
27 - <% end %>  
28 -  
29 - <script type='text/javascript'>  
30 - function show_closing_statement_area(id) {  
31 - $('task-closing-statement-' + id).show();  
32 - }  
33 - function hide_closing_statement_area(id) {  
34 - $('task-closing-statement-' + id).hide();  
35 - }  
36 - </script>  
37 -  
38 - <div style='display:none' id=<%= "task-closing-statement-#{task.id}" %> >  
39 - <%= labelled_form_field _('Please provide an explanation for the rejection'), f.text_area(:closing_statement, :style => 'height:200px; width:80%;') %>  
40 - </div>  
41 -  
42 - </div>  
43 -  
44 - <% button_bar do %>  
45 - <%= submit_button(:ok, _('Ok!')) %>  
46 - <% end %>  
47 -<% end %>  
app/views/tasks/_create_enterprise_reject_details.rhtml 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +<%= required labelled_form_field(_('Rejection explanation'), f.text_area(:reject_explanation, :rows => 5)) %>
  2 +
app/views/tasks/_invite_friend.rhtml
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -<%= render :partial => 'add_friend', :locals => {:task => task} %>  
app/views/tasks/_invite_friend_accept_details.rhtml 0 → 120000
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +_add_friend_accept_details.rhtml
0 \ No newline at end of file 2 \ No newline at end of file
app/views/tasks/_invite_member.rhtml
@@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
1 -<h2><%= _('Join community') %></h2>  
2 -  
3 -<%= link_to( profile_image(task.requestor, :minor, :border => 0), task.requestor.public_profile_url ) %>  
4 -  
5 -<%= _('%s invited you to join the community %s') %  
6 - [content_tag('strong', link_to( task.requestor.name, task.requestor.public_profile_url ) ),  
7 - content_tag('strong', link_to( task.community.name, task.community.public_profile_url ) )] %>  
8 -  
9 -<% form_for('task', task, :url => { :action => 'close', :id => task.id } ) do |f| %>  
10 -  
11 - <div>  
12 - <%= radio_button_tag(:decision, 'finish', true,  
13 - :id => "decision-finish-#{task.id}",  
14 - :onclick => "Element.show('group-for-friend-#{task.id}')") %>  
15 - <label for="<%= "decision-finish-#{task.id}" %>"><b><%= _('Accept') %></b></label>  
16 -  
17 - &nbsp; &nbsp;  
18 -  
19 - <%= radio_button_tag(:decision, 'cancel', false,  
20 - :id => "decision-cancel-#{task.id}",  
21 - :onclick => "Element.hide('group-for-friend-#{task.id}')") %>  
22 - <label for="<%= "decision-cancel-#{task.id}" %>"><b><%= _('Reject') %></b></label>  
23 -  
24 - </div>  
25 -  
26 - <% button_bar do %>  
27 - <%= submit_button(:ok, _('Ok!')) %>  
28 - <% end %>  
29 -<% end %>  
app/views/tasks/_suggest_article.rhtml
@@ -1,41 +0,0 @@ @@ -1,41 +0,0 @@
1 -<h2><%= _('Processing task: %s') % task.description %></h2>  
2 -  
3 -<%= render :file => 'shared/tiny_mce' %>  
4 -  
5 -<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %>  
6 -  
7 -  
8 - <%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %>  
9 - <p><%= label_tag(_("Email: %s") % task.email) %> </p>  
10 - <%= required labelled_form_field(_('Title'), f.text_field(:article_name, :size => 50)) %>  
11 - <%= labelled_form_field(_('Source'), f.text_field(:source_name)) %>  
12 - <%= labelled_form_field(_("Source URL"), f.text_field(:source)) %>  
13 -  
14 - <%= select_folder(_('Select the folder where the article must be published'), 'task', 'article_parent_id', task.target.folders) %>  
15 -  
16 - <br style="clear: both;"/>  
17 - <%= button :add, _("Lead"), '#', :id => "lead-button", :style => "margin-left: 0px;" %>  
18 - <em><%= _('Used when a short version your text is needed.') %></em>  
19 -  
20 - <div id="article-lead">  
21 - <%= labelled_form_field(_('Lead'), text_area_tag('task[article_abstract]', task.article_abstract, :style => 'width: 100%; height: 200px;')) %>  
22 - </div>  
23 - <div style="margin-top: 10px;">  
24 - <%= labelled_form_field(_('Text'), text_area_tag('task[article_body]', task.article_body, :style => 'width:100%; height: 500px;')) %>  
25 - </div>  
26 -  
27 - <div>  
28 - <%= labelled_radio_button _('OK'), :decision, 'finish', true, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='none'" %>  
29 - </div>  
30 - <div>  
31 - <%= labelled_radio_button _('Cancel'), :decision, 'cancel', false, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='block'" %>  
32 - </div>  
33 -  
34 - <% button_bar do %>  
35 - <%= submit_button(:ok, _('OK')) %>  
36 - <% end %>  
37 -  
38 -<% end %>  
39 -  
40 -<%= javascript_include_tag 'article' %>  
41 -  
app/views/tasks/_suggest_article_accept_details.rhtml 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +<%= render :file => 'shared/tiny_mce' %>
  2 +
  3 +<%= labelled_form_field(_("Sent by: "), f.text_field(:name)) %>
  4 +<p><%= label_tag(_("Email: %s") % task.email) %> </p>
  5 +<%= required labelled_form_field(_('Title'), f.text_field(:article_name, :size => 50)) %>
  6 +<%= labelled_form_field(_('Source'), f.text_field(:source_name)) %>
  7 +<%= labelled_form_field(_("Source URL"), f.text_field(:source)) %>
  8 +
  9 +<%= select_profile_folder(_('Select the folder where the article must be published'), "tasks[#{task.id}][task]", 'article_parent_id', task.target) %>
  10 +
  11 +<div>
  12 + <%= labelled_form_field(_('Lead'), f.text_area(:article_abstract, :style => 'width: 482px; height: 200px;')) %>
  13 +</div>
  14 +<em><%= _('Used when a short version your text is needed.') %></em>
  15 +
  16 +<div style="margin-top: 10px;">
  17 + <%= labelled_form_field(_('Text'), f.text_area(:article_body, :style => 'width:482px; height: 500px;')) %>
  18 +</div>
app/views/tasks/_task.rhtml
1 -<%# a generic task solver %>  
2 -<h2><%= _('Processing task: %s') % task.description %></h2> 1 +<div class="task_box">
3 2
4 -<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %> 3 + <div class="task_icon">
  4 + <%
  5 + icon_info = task.icon
  6 + if icon_info[:type] == :profile_image
  7 + icon = profile_image(icon_info[:profile], :minor)
  8 + elsif icon_info[:type] == :defined_image
  9 + icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />"
  10 + end
  11 + %>
  12 + <%=
  13 + if icon_info[:url]
  14 + link_to(icon, icon_info[:url])
  15 + else
  16 + icon
  17 + end
  18 + %>
5 19
6 - <div>  
7 - <%= labelled_radio_button _('OK'), :decision, 'finish', true, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='none'" %>  
8 - </div>  
9 - <div>  
10 - <%= labelled_radio_button _('Cancel'), :decision, 'cancel', false, :onclick => "if(this.checked) $('rejection-field-#{task.id}').style.display='block'" %>  
11 </div> 20 </div>
12 21
13 - <div id="rejection-field-<%= task.id %>" style='display: none'>  
14 - <%= required labelled_form_field(_('Rejection explanation'), text_area(:task, :reject_explanation, :rows => 5))%> 22 + <div class="task_decisions">
  23 + <%=
  24 + labelled_radio_button(_("Accept"), "tasks[#{task.id}][decision]", 'finish', task.default_decision == 'accept',
  25 + :id => "decision-finish-#{task.id}",
  26 + :class => 'task_accept_radio',
  27 + :disabled => task.accept_disabled?,
  28 + :task_id => "#{task.id}") +
  29 + labelled_radio_button(_("Reject"), "tasks[#{task.id}][decision]", 'cancel', task.default_decision == 'reject',
  30 + :id => "decision-cancel-#{task.id}",
  31 + :class => 'task_reject_radio',
  32 + :disabled => task.reject_disabled?,
  33 + :task_id => "#{task.id}") +
  34 + labelled_radio_button(_("Skip"), "tasks[#{task.id}][decision]", 'skip', task.default_decision == 'skip',
  35 + :id => "decision-skip-#{task.id}",
  36 + :class => 'task_skip_radio',
  37 + :disabled => task.skip_disabled?,
  38 + :task_id => "#{task.id}")
  39 + %>
  40 + </div><!-- class="task_decisions" -->
  41 +
  42 + <strong class="task_title">
  43 + <%= task.title %>
  44 + </strong>
  45 +
  46 + <div class="task_information">
  47 + <%= task_information(task) %>
15 </div> 48 </div>
16 49
17 - <% button_bar do %>  
18 - <%= submit_button(:ok, _('OK')) %> 50 + <% fields_for "tasks[#{task.id}][task]", task do |f| %>
  51 + <% if task.accept_details %>
  52 + <div id="on-accept-information-<%=task.id%>" style="display: none">
  53 + <%= render :partial => partial_for_task_class(task.class, :accept_details), :locals => {:task => task, :f => f} %>
  54 + </div>
  55 + <% end %>
  56 +
  57 + <% if task.reject_details %>
  58 + <div id="on-reject-information-<%=task.id%>" style="display: none">
  59 + <%= render :partial => partial_for_task_class(task.class, :reject_details), :locals => {:task => task, :f => f} %>
  60 + </div>
  61 + <% end %>
19 <% end %> 62 <% end %>
20 63
21 -<% end %> 64 +</div><!-- class="task_box" -->
app/views/tasks/_task_reject_details.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= labelled_form_field(_('Rejection explanation'), f.text_area(:reject_explanation, :rows => 5)) %>
app/views/tasks/_ticket.rhtml
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -<h2><%= _('Processing ticket: %s') % task.title %></h2>  
2 -  
3 -<%= task.description %>  
4 -  
5 -<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %>  
6 -  
7 - <%= labelled_form_field(_('Closing statment'), f.text_area(:closing_statment) ) %>  
8 -  
9 - <div>  
10 - <%= radio_button_tag(:decision, 'finish', true) %>  
11 - <%= _('OK') %>  
12 - </div>  
13 - <div>  
14 - <%= radio_button_tag(:decision, 'cancel', false) %>  
15 - <%= _('Cancel') %>  
16 - </div>  
17 -  
18 - <% button_bar do %>  
19 - <%= submit_button(:ok, _('OK')) %>  
20 - <% end %>  
21 -  
22 -<% end %>  
app/views/tasks/index.rhtml
1 -<h1><%= _("%s's pending tasks") % profile.name %></h1> 1 +<%= stylesheet_link_tag 'tasks' %>
2 2
  3 +<h1><%= _("%s's pending tasks") % profile.name %></h1>
3 <p> 4 <p>
  5 +
  6 +<% if !@failed.blank? %>
  7 + <div id="errorExplanation">
  8 + <% @failed.each do |error, tasks_descriptions|%>
  9 + <h2> <%= error %></h2>
  10 + <p><%=_("This error happened with the following tasks: ")%></p>
  11 + <ul>
  12 + <% tasks_descriptions.each do |description| %>
  13 + <li> <%= description %> </li>
  14 + <% end %>
  15 + </ul>
  16 + <% end %>
  17 + </div>
  18 +<% end %>
  19 +
4 <% if @tasks.empty? %> 20 <% if @tasks.empty? %>
5 <em><%= _('No pending tasks for %s') % profile.name %></em> 21 <em><%= _('No pending tasks for %s') % profile.name %></em>
6 <% else %> 22 <% else %>
7 - <ul class='task-list'>  
8 - <% @tasks.each do |item| %>  
9 - <li class="task-<%= item.class %>"><%= render :partial => partial_for_class(item.class), :locals => { :task => item } %></li> 23 + <% form_tag :action => 'close' do%>
  24 + <% button_bar do %>
  25 + <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
  26 + <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
  27 + <%= submit_button :save, _("Apply!") %>
  28 + <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
  29 + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
10 <% end %> 30 <% end %>
11 - </ul> 31 +
  32 + <ul class='task-list'>
  33 + <p>
  34 + <%= labelled_select(_("Set all to: "), 'set-decisions', 'downcase', 'to_s', nil, ["","Accept", "Reject", "Skip"], :id => "up-set-all-tasks-to") %>
  35 + </p>
  36 + <% @tasks.each do |task| %>
  37 + <%= render :partial => 'task', :locals => { :task => task } %>
  38 + <% end %>
  39 + <p>
  40 + <%= labelled_select(_("Set all to: "), 'set-decisions', 'downcase', 'to_s', nil, ["","Accept", "Reject", "Skip"], :id => "down-set-all-tasks-to") %>
  41 + </p>
  42 + </ul>
  43 +
  44 + <% button_bar do %>
  45 + <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>
  46 + <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>
  47 + <%= submit_button :save, _("Apply!") %>
  48 + <%= button(:edit, _('View processed tasks'), :action => 'processed') %>
  49 + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
  50 + <% end %>
  51 + <% end %>
12 <% end %> 52 <% end %>
13 </p> 53 </p>
14 54
15 -<% button_bar do %>  
16 - <%= button(:edit, _('View processed tasks'), :action => 'processed') %>  
17 - <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %>  
18 - <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %>  
19 - <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>  
20 -<% end %> 55 +
  56 +<%= javascript_include_tag 'tasks' %>
app/views/tasks/list_requested.rhtml
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 <ul> 3 <ul>
4 <% @tasks.each do |task| %> 4 <% @tasks.each do |task| %>
5 <li> 5 <li>
6 - <strong><%= task.respond_to?(:title) ? link_to( task.title, :action => 'ticket_details', :id => task.id) : task.description %></strong><br/> 6 + <strong><%= task.respond_to?(:title) ? link_to( task.title, :action => 'ticket_details', :id => task.id) : task.information %></strong><br/>
7 <small> 7 <small>
8 <%= _('Created:') + ' ' + show_date(task.created_at) %> 8 <%= _('Created:') + ' ' + show_date(task.created_at) %>
9 &nbsp; &#151; &nbsp; 9 &nbsp; &#151; &nbsp;
app/views/tasks/new.rhtml
@@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
9 <% end %> 9 <% end %>
10 <%= hidden_field_tag 'ticket[target_type]', 'Profile' %> 10 <%= hidden_field_tag 'ticket[target_type]', 'Profile' %>
11 <%= f.text_field :title, :style => 'width:80%;' %> 11 <%= f.text_field :title, :style => 'width:80%;' %>
12 - <%= f.text_area :description, :style => 'height:200px; width:80%;' %> 12 + <%= f.text_area :message, :style => 'height:200px; width:80%;' %>
13 13
14 <% button_bar do %> 14 <% button_bar do %>
15 <%= submit_button(:ok, _('Send'), :cancel => {:action => 'index'}) %> 15 <%= submit_button(:ok, _('Send'), :cancel => {:action => 'index'}) %>
app/views/tasks/processed.rhtml
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
7 <ul> 7 <ul>
8 <% @tasks.each do |item| %> 8 <% @tasks.each do |item| %>
9 <li> 9 <li>
10 - <strong><%= item.description %></strong> <br/> 10 + <strong><%= item.information %></strong> <br/>
11 <small> 11 <small>
12 <%= _('Created:') +' '+ show_date(item.created_at) %> 12 <%= _('Created:') +' '+ show_date(item.created_at) %>
13 &nbsp; &#151; &nbsp; 13 &nbsp; &#151; &nbsp;
features/approve_article.feature
@@ -28,7 +28,8 @@ Feature: approve article @@ -28,7 +28,8 @@ Feature: approve article
28 And I go to Sample Community's control panel 28 And I go to Sample Community's control panel
29 And I follow "Process requests" 29 And I follow "Process requests"
30 And I fill in "Text" with "This is an article edited" 30 And I fill in "Text" with "This is an article edited"
31 - And I press "Ok!" 31 + And I choose "Accept"
  32 + And I press "Apply!"
32 And I go to Sample Community's sitemap 33 And I go to Sample Community's sitemap
33 When I follow "Sample Article" 34 When I follow "Sample Article"
34 Then I should see "This is an article edited" 35 Then I should see "This is an article edited"
features/create_community.feature
@@ -51,8 +51,8 @@ Feature: create community @@ -51,8 +51,8 @@ Feature: create community
51 And I go to the Control panel 51 And I go to the Control panel
52 And I follow "Process requests" 52 And I follow "Process requests"
53 And I should see "admin_user wants to create community Community for approval" 53 And I should see "admin_user wants to create community Community for approval"
54 - And I choose "Approve"  
55 - When I press "Ok!" 54 + And I choose "Accept"
  55 + When I press "Apply!"
56 Then I should not see "admin_user wants to create community Community for approval" 56 Then I should not see "admin_user wants to create community Community for approval"
57 When I go to the Control panel 57 When I go to the Control panel
58 And I follow "Manage my groups" 58 And I follow "Manage my groups"
@@ -66,7 +66,7 @@ Feature: create community @@ -66,7 +66,7 @@ Feature: create community
66 And I follow "Process requests" 66 And I follow "Process requests"
67 And I should see "admin_user wants to create community Community for approval" 67 And I should see "admin_user wants to create community Community for approval"
68 And I choose "Reject" 68 And I choose "Reject"
69 - When I press "Ok!" 69 + When I press "Apply!"
70 Then I should not see "admin_user wants to create community Community for approval" 70 Then I should not see "admin_user wants to create community Community for approval"
71 When I go to the Control panel 71 When I go to the Control panel
72 And I follow "Manage my groups" 72 And I follow "Manage my groups"
@@ -89,12 +89,3 @@ Feature: create community @@ -89,12 +89,3 @@ Feature: create community
89 When I go to the Control panel 89 When I go to the Control panel
90 And I follow "Manage my groups" 90 And I follow "Manage my groups"
91 Then I should not see "Community for approval" 91 Then I should not see "Community for approval"
92 -  
93 - Scenario: environment admin accepts new community task but identifier was already taken  
94 - Given I am logged in as admin  
95 - And feature "admin_must_approve_new_communities" is enabled on environment  
96 - And I create community "Community for approval"  
97 - And I create community "Community for approval"  
98 - When I approve community "Community for approval"  
99 - Then I should see "This name was already taken, this community cannot be approved"  
100 - And I should see "admin_user wants to create community Community for approval"  
features/invitation.feature
@@ -93,7 +93,7 @@ Feature: invitation @@ -93,7 +93,7 @@ Feature: invitation
93 Given there are no pending jobs 93 Given there are no pending jobs
94 When I am logged in as "josesantos" 94 When I am logged in as "josesantos"
95 And I go to the Control panel 95 And I go to the Control panel
96 - And I should see "josesilva invited you to join the community 26 Bsslines" 96 + And I should see "josesilva invited you to join 26 Bsslines."
97 97
98 Scenario: noosfero user accepts to join community 98 Scenario: noosfero user accepts to join community
99 Given I invite email "santos@invalid.br" to join community "26 Bsslines" 99 Given I invite email "santos@invalid.br" to join community "26 Bsslines"
@@ -101,10 +101,10 @@ Feature: invitation @@ -101,10 +101,10 @@ Feature: invitation
101 When I am logged in as "josesantos" 101 When I am logged in as "josesantos"
102 And I go to the Control panel 102 And I go to the Control panel
103 And I follow "Process requests" 103 And I follow "Process requests"
104 - And I should see "josesilva invited you to join the community 26 Bsslines" 104 + And I should see "josesilva invited you to join 26 Bsslines."
105 And I choose "Accept" 105 And I choose "Accept"
106 - When I press "Ok!"  
107 - Then I should not see "josesilva invited you to join the community 26 Bsslines" 106 + When I press "Apply!"
  107 + Then I should not see "josesilva invited you to join 26 Bsslines."
108 When I go to the Control panel 108 When I go to the Control panel
109 And I follow "Manage my groups" 109 And I follow "Manage my groups"
110 Then I should see "26 Bsslines" 110 Then I should see "26 Bsslines"
@@ -115,10 +115,10 @@ Feature: invitation @@ -115,10 +115,10 @@ Feature: invitation
115 When I am logged in as "josesantos" 115 When I am logged in as "josesantos"
116 And I go to the Control panel 116 And I go to the Control panel
117 And I follow "Process requests" 117 And I follow "Process requests"
118 - And I should see "josesilva invited you to join the community 26 Bsslines" 118 + And I should see "josesilva invited you to join 26 Bsslines."
119 And I choose "Reject" 119 And I choose "Reject"
120 - When I press "Ok!"  
121 - Then I should not see "josesilva invited you to join the community 26 Bsslines" 120 + When I press "Apply!"
  121 + Then I should not see "josesilva invited you to join 26 Bsslines."
122 When I go to the Control panel 122 When I go to the Control panel
123 And I follow "Manage my groups" 123 And I follow "Manage my groups"
124 Then I should not see "26 Bsslines" 124 Then I should not see "26 Bsslines"
@@ -135,7 +135,7 @@ Feature: invitation @@ -135,7 +135,7 @@ Feature: invitation
135 When I am logged in as "josesantos" 135 When I am logged in as "josesantos"
136 And I go to the Control panel 136 And I go to the Control panel
137 And I follow "Process requests" 137 And I follow "Process requests"
138 - And I should see "josesilva wants to be your friend." 138 + Then I should see "josesilva wants to be your friend."
139 139
140 Scenario: noosfero user accepts to be friend 140 Scenario: noosfero user accepts to be friend
141 Given I invite email "santos@invalid.br" to be my friend 141 Given I invite email "santos@invalid.br" to be my friend
@@ -145,7 +145,7 @@ Feature: invitation @@ -145,7 +145,7 @@ Feature: invitation
145 And I follow "Process requests" 145 And I follow "Process requests"
146 And I should see "josesilva wants to be your friend." 146 And I should see "josesilva wants to be your friend."
147 And I choose "Accept" 147 And I choose "Accept"
148 - When I press "Ok!" 148 + When I press "Apply!"
149 And I should not see "josesilva wants to be your friend." 149 And I should not see "josesilva wants to be your friend."
150 When I go to the Control panel 150 When I go to the Control panel
151 And I follow "Manage friends" 151 And I follow "Manage friends"
@@ -158,8 +158,8 @@ Feature: invitation @@ -158,8 +158,8 @@ Feature: invitation
158 And I go to the Control panel 158 And I go to the Control panel
159 And I follow "Process requests" 159 And I follow "Process requests"
160 And I should see "josesilva wants to be your friend." 160 And I should see "josesilva wants to be your friend."
161 - And I choose "Ignore"  
162 - When I press "Ok!" 161 + And I choose "Reject"
  162 + When I press "Apply!"
163 And I should not see "josesilva wants to be your friend." 163 And I should not see "josesilva wants to be your friend."
164 When I go to the Control panel 164 When I go to the Control panel
165 And I follow "Manage friends" 165 And I follow "Manage friends"
features/publish_article.feature
@@ -95,6 +95,33 @@ Feature: publish article @@ -95,6 +95,33 @@ Feature: publish article
95 When I go to Another Community2's sitemap 95 When I go to Another Community2's sitemap
96 Then I should see "Sample Article" 96 Then I should see "Sample Article"
97 97
  98 + Scenario: publishing articles with the same name in a moderated community
  99 + Given I am logged in as "joaosilva"
  100 + And "Joao Silva" is a member of "Sample Community"
  101 + And "Joao Silva" is admin of "Sample Community"
  102 + And I am on Sample Community's control panel
  103 + And I follow "Community Info and settings"
  104 + And I choose "profile_data_moderated_articles_true"
  105 + And I press "Save"
  106 + And I am on Joao Silva's control panel
  107 + And I follow "Manage Content"
  108 + And I follow "Spread"
  109 + And I check "Sample Community"
  110 + And I press "Spread this"
  111 + And I am on Joao Silva's control panel
  112 + And I follow "Manage Content"
  113 + And I follow "Spread"
  114 + And I check "Sample Community"
  115 + And I press "Spread this"
  116 + And I am on Sample Community's control panel
  117 + And I follow "Tasks"
  118 + And I choose "Accept"
  119 + And I press "Apply!"
  120 + And I should not see "The title (article name) is already being used by another article, please use another title."
  121 + And I choose "Accept"
  122 + When I press "Apply!"
  123 + Then I should see "The title (article name) is already being used by another article, please use another title."
  124 +
98 Scenario: ask to publish an article that was deleted before approval 125 Scenario: ask to publish an article that was deleted before approval
99 Given I am logged in as "joaosilva" 126 Given I am logged in as "joaosilva"
100 And "Joao Silva" is admin of "Sample Community" 127 And "Joao Silva" is admin of "Sample Community"
@@ -110,6 +137,6 @@ Feature: publish article @@ -110,6 +137,6 @@ Feature: publish article
110 And "joaosilva" has no articles 137 And "joaosilva" has no articles
111 And I am on Sample Community's control panel 138 And I am on Sample Community's control panel
112 When I follow "Tasks" 139 When I follow "Tasks"
113 - Then I should see /Joao Silva wanted.*deleted/  
114 - And I press "Ok!"  
115 - Then I should not see /Joao Silva wanted.*deleted/ 140 + Then I should see "The article was removed."
  141 + And I press "Apply!"
  142 + Then I should not see "The article was removed."
features/register_enterprise.feature
@@ -94,9 +94,10 @@ Feature: register enterprise @@ -94,9 +94,10 @@ Feature: register enterprise
94 And I am logged in as admin 94 And I am logged in as admin
95 And I go to the Control panel 95 And I go to the Control panel
96 When I follow "Tasks" 96 When I follow "Tasks"
97 - Then I should see /Processing task: Enterprise registration: "My Enterprise"/ 97 + Then I should see "Joao Silva wants to create enterprise My Enterprise."
98 And the first mail is to admin_user@example.com 98 And the first mail is to admin_user@example.com
99 - And I press "Ok" 99 + And I choose "Accept"
  100 + And I press "Apply!"
100 Then the last mail is to joaosilva@example.com 101 Then the last mail is to joaosilva@example.com
101 And I am logged in as "joaosilva" 102 And I am logged in as "joaosilva"
102 And I am on Joao Silva's control panel 103 And I am on Joao Silva's control panel
@@ -120,11 +121,11 @@ Feature: register enterprise @@ -120,11 +121,11 @@ Feature: register enterprise
120 And I am logged in as admin 121 And I am logged in as admin
121 And I go to the Control panel 122 And I go to the Control panel
122 When I follow "Tasks" 123 When I follow "Tasks"
123 - Then I should see /Processing task: Enterprise registration: "My Enterprise"/ 124 + Then I should see "Joao Silva wants to create enterprise My Enterprise."
124 And the first mail is to admin_user@example.com 125 And the first mail is to admin_user@example.com
125 - And I choose "Cancel" 126 + And I choose "Reject"
126 And I fill in "Rejection explanation" with "This enterprise has some irregularities." 127 And I fill in "Rejection explanation" with "This enterprise has some irregularities."
127 - When I press "Ok" 128 + And I press "Apply!"
128 Then the last mail is to joaosilva@example.com 129 Then the last mail is to joaosilva@example.com
129 And I am logged in as "joaosilva" 130 And I am logged in as "joaosilva"
130 And I am on Joao Silva's control panel 131 And I am on Joao Silva's control panel
@@ -157,9 +158,9 @@ Feature: register enterprise @@ -157,9 +158,9 @@ Feature: register enterprise
157 Then I should see "Enterprise registration completed" 158 Then I should see "Enterprise registration completed"
158 And I am on Validator's control panel 159 And I am on Validator's control panel
159 When I follow "Tasks" 160 When I follow "Tasks"
160 - Then I should see /Processing task: Enterprise registration: "My Enterprise"/  
161 - And I choose "Ok"  
162 - And I press "Ok" 161 + Then I should see "Joao Silva wants to create enterprise My Enterprise."
  162 + And I choose "Accept"
  163 + And I press "Apply!"
163 And I am on Joao Silva's control panel 164 And I am on Joao Silva's control panel
164 When I follow "Manage my groups" 165 When I follow "Manage my groups"
165 Then I should see "My Enterprise" 166 Then I should see "My Enterprise"
@@ -190,10 +191,10 @@ Feature: register enterprise @@ -190,10 +191,10 @@ Feature: register enterprise
190 Then I should see "Enterprise registration completed" 191 Then I should see "Enterprise registration completed"
191 And I am on Validator's control panel 192 And I am on Validator's control panel
192 When I follow "Tasks" 193 When I follow "Tasks"
193 - Then I should see /Processing task: Enterprise registration: "My Enterprise"/  
194 - And I choose "Cancel" 194 + Then I should see "Joao Silva wants to create enterprise My Enterprise."
  195 + And I choose "Reject"
195 And I fill in "Rejection explanation" with "This enterprise has some irregularities." 196 And I fill in "Rejection explanation" with "This enterprise has some irregularities."
196 - And I press "Ok" 197 + And I press "Apply"
197 And I am on Joao Silva's control panel 198 And I am on Joao Silva's control panel
198 When I follow "Manage my groups" 199 When I follow "Manage my groups"
199 Then I should not see "My Enterprise" 200 Then I should not see "My Enterprise"
features/step_definitions/create_community_steps.rb
@@ -11,7 +11,7 @@ Given /^I approve community &quot;(.+)&quot;$/ do |community| @@ -11,7 +11,7 @@ Given /^I approve community &quot;(.+)&quot;$/ do |community|
11 Given 'I go to the Control panel' 11 Given 'I go to the Control panel'
12 click_link('Process requests') 12 click_link('Process requests')
13 choose("decision-finish-#{task.id}") 13 choose("decision-finish-#{task.id}")
14 - click_button('OK!') 14 + click_button('Apply!')
15 end 15 end
16 16
17 Given /^I reject community "(.+)"$/ do |community| 17 Given /^I reject community "(.+)"$/ do |community|
@@ -19,5 +19,5 @@ Given /^I reject community &quot;(.+)&quot;$/ do |community| @@ -19,5 +19,5 @@ Given /^I reject community &quot;(.+)&quot;$/ do |community|
19 Given 'I go to the Control panel' 19 Given 'I go to the Control panel'
20 click_link('Process requests') 20 click_link('Process requests')
21 choose("decision-cancel-#{task.id}") 21 choose("decision-cancel-#{task.id}")
22 - click_button('OK!') 22 + click_button('Apply!')
23 end 23 end
public/images/icons-app/article-minor.png 0 → 100644

3 KB

public/images/icons-app/article-portrait.png 0 → 100644

2.69 KB

public/images/icons-app/article-thumb.png 0 → 100644

4.85 KB

public/images/icons-task/closed-arrow-hover.png 0 → 100644

216 Bytes

public/images/icons-task/closed-arrow.png 0 → 100644

204 Bytes

public/images/icons-task/opened-arrow-hover.png 0 → 100644

189 Bytes

public/images/icons-task/opened-arrow.png 0 → 100644

199 Bytes

public/img-source/article-icon.svg 0 → 100644
@@ -0,0 +1,788 @@ @@ -0,0 +1,788 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
  3 +
  4 +<svg
  5 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  6 + xmlns:cc="http://creativecommons.org/ns#"
  7 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  8 + xmlns:svg="http://www.w3.org/2000/svg"
  9 + xmlns="http://www.w3.org/2000/svg"
  10 + xmlns:xlink="http://www.w3.org/1999/xlink"
  11 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  12 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  13 + inkscape:export-ydpi="900"
  14 + inkscape:export-xdpi="900"
  15 + inkscape:export-filename="article.png"
  16 + sodipodi:docname="article-icon.svg"
  17 + inkscape:version="0.47pre4 r22446"
  18 + sodipodi:version="0.32"
  19 + id="svg249"
  20 + height="50"
  21 + width="50"
  22 + inkscape:output_extension="org.inkscape.output.svg.inkscape"
  23 + version="1.1">
  24 + <defs
  25 + id="defs3">
  26 + <linearGradient
  27 + inkscape:collect="always"
  28 + id="linearGradient4248">
  29 + <stop
  30 + style="stop-color:#ffcc00;stop-opacity:1"
  31 + offset="0"
  32 + id="stop4250" />
  33 + <stop
  34 + style="stop-color:#d40000;stop-opacity:1"
  35 + offset="1"
  36 + id="stop4252" />
  37 + </linearGradient>
  38 + <inkscape:perspective
  39 + sodipodi:type="inkscape:persp3d"
  40 + inkscape:vp_x="0 : 24 : 1"
  41 + inkscape:vp_y="0 : 1000 : 0"
  42 + inkscape:vp_z="48 : 24 : 1"
  43 + inkscape:persp3d-origin="24 : 16 : 1"
  44 + id="perspective91" />
  45 + <radialGradient
  46 + inkscape:collect="always"
  47 + xlink:href="#linearGradient5060"
  48 + id="radialGradient6719"
  49 + gradientUnits="userSpaceOnUse"
  50 + gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
  51 + cx="605.71429"
  52 + cy="486.64789"
  53 + fx="605.71429"
  54 + fy="486.64789"
  55 + r="117.14286" />
  56 + <linearGradient
  57 + inkscape:collect="always"
  58 + id="linearGradient5060">
  59 + <stop
  60 + style="stop-color:black;stop-opacity:1;"
  61 + offset="0"
  62 + id="stop5062" />
  63 + <stop
  64 + style="stop-color:black;stop-opacity:0;"
  65 + offset="1"
  66 + id="stop5064" />
  67 + </linearGradient>
  68 + <radialGradient
  69 + inkscape:collect="always"
  70 + xlink:href="#linearGradient5060"
  71 + id="radialGradient6717"
  72 + gradientUnits="userSpaceOnUse"
  73 + gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
  74 + cx="605.71429"
  75 + cy="486.64789"
  76 + fx="605.71429"
  77 + fy="486.64789"
  78 + r="117.14286" />
  79 + <linearGradient
  80 + id="linearGradient5048">
  81 + <stop
  82 + style="stop-color:black;stop-opacity:0;"
  83 + offset="0"
  84 + id="stop5050" />
  85 + <stop
  86 + id="stop5056"
  87 + offset="0.5"
  88 + style="stop-color:black;stop-opacity:1;" />
  89 + <stop
  90 + style="stop-color:black;stop-opacity:0;"
  91 + offset="1"
  92 + id="stop5052" />
  93 + </linearGradient>
  94 + <linearGradient
  95 + inkscape:collect="always"
  96 + xlink:href="#linearGradient5048"
  97 + id="linearGradient6715"
  98 + gradientUnits="userSpaceOnUse"
  99 + gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
  100 + x1="302.85715"
  101 + y1="366.64789"
  102 + x2="302.85715"
  103 + y2="609.50507" />
  104 + <linearGradient
  105 + id="linearGradient7648"
  106 + gradientUnits="userSpaceOnUse"
  107 + x1="21.9326"
  108 + y1="24.627399"
  109 + x2="21.9326"
  110 + y2="7.1090999">
  111 + <stop
  112 + offset="0"
  113 + style="stop-color:#8595bc;stop-opacity:1;"
  114 + id="stop7650" />
  115 + <stop
  116 + offset="1"
  117 + style="stop-color:#041a3b;stop-opacity:1;"
  118 + id="stop7652" />
  119 + </linearGradient>
  120 + <linearGradient
  121 + inkscape:collect="always"
  122 + id="linearGradient4542">
  123 + <stop
  124 + style="stop-color:#000000;stop-opacity:1;"
  125 + offset="0"
  126 + id="stop4544" />
  127 + <stop
  128 + style="stop-color:#000000;stop-opacity:0;"
  129 + offset="1"
  130 + id="stop4546" />
  131 + </linearGradient>
  132 + <linearGradient
  133 + id="linearGradient15662">
  134 + <stop
  135 + id="stop15664"
  136 + offset="0.0000000"
  137 + style="stop-color:#ffffff;stop-opacity:1.0000000;" />
  138 + <stop
  139 + id="stop15666"
  140 + offset="1.0000000"
  141 + style="stop-color:#f8f8f8;stop-opacity:1.0000000;" />
  142 + </linearGradient>
  143 + <radialGradient
  144 + id="aigrd3"
  145 + cx="20.892099"
  146 + cy="64.567902"
  147 + r="5.257"
  148 + fx="20.892099"
  149 + fy="64.567902"
  150 + gradientUnits="userSpaceOnUse">
  151 + <stop
  152 + offset="0"
  153 + style="stop-color:#F0F0F0"
  154 + id="stop15573" />
  155 + <stop
  156 + offset="1"
  157 + style="stop-color:#515151;stop-opacity:1;"
  158 + id="stop15575" />
  159 + </radialGradient>
  160 + <radialGradient
  161 + id="aigrd2"
  162 + cx="20.892099"
  163 + cy="114.5684"
  164 + r="5.256"
  165 + fx="20.892099"
  166 + fy="114.5684"
  167 + gradientUnits="userSpaceOnUse">
  168 + <stop
  169 + offset="0"
  170 + style="stop-color:#F0F0F0"
  171 + id="stop15566" />
  172 + <stop
  173 + offset="1.0000000"
  174 + style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
  175 + id="stop15568" />
  176 + </radialGradient>
  177 + <linearGradient
  178 + id="linearGradient269">
  179 + <stop
  180 + id="stop270"
  181 + offset="0.0000000"
  182 + style="stop-color:#a3a3a3;stop-opacity:1.0000000;" />
  183 + <stop
  184 + id="stop271"
  185 + offset="1.0000000"
  186 + style="stop-color:#4c4c4c;stop-opacity:1.0000000;" />
  187 + </linearGradient>
  188 + <linearGradient
  189 + id="linearGradient259">
  190 + <stop
  191 + id="stop260"
  192 + offset="0.0000000"
  193 + style="stop-color:#fafafa;stop-opacity:1.0000000;" />
  194 + <stop
  195 + id="stop261"
  196 + offset="1.0000000"
  197 + style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
  198 + </linearGradient>
  199 + <radialGradient
  200 + inkscape:collect="always"
  201 + xlink:href="#linearGradient269"
  202 + id="radialGradient15656"
  203 + gradientUnits="userSpaceOnUse"
  204 + gradientTransform="matrix(0.9980597,0,0,1.1091725,4.1760961,-0.6958675)"
  205 + cx="8.824419"
  206 + cy="3.7561285"
  207 + fx="8.824419"
  208 + fy="3.7561285"
  209 + r="37.751713" />
  210 + <radialGradient
  211 + inkscape:collect="always"
  212 + xlink:href="#linearGradient259"
  213 + id="radialGradient15658"
  214 + gradientUnits="userSpaceOnUse"
  215 + gradientTransform="matrix(0.99004037,0,0,1.1181563,0.71937872,-1.3901395)"
  216 + cx="33.966679"
  217 + cy="35.736916"
  218 + fx="33.966679"
  219 + fy="35.736916"
  220 + r="86.70845" />
  221 + <radialGradient
  222 + inkscape:collect="always"
  223 + xlink:href="#linearGradient15662"
  224 + id="radialGradient15668"
  225 + gradientUnits="userSpaceOnUse"
  226 + gradientTransform="matrix(1.0027787,0,0,1.1122543,4.0618664,-0.7125018)"
  227 + cx="8.1435566"
  228 + cy="7.2678967"
  229 + fx="8.1435566"
  230 + fy="7.2678967"
  231 + r="38.158695" />
  232 + <radialGradient
  233 + inkscape:collect="always"
  234 + xlink:href="#linearGradient4542"
  235 + id="radialGradient4548"
  236 + cx="24.306795"
  237 + cy="42.07798"
  238 + fx="24.306795"
  239 + fy="42.07798"
  240 + r="15.821514"
  241 + gradientTransform="matrix(1,0,0,0.284916,0,30.08928)"
  242 + gradientUnits="userSpaceOnUse" />
  243 + <inkscape:perspective
  244 + id="perspective3216"
  245 + inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
  246 + inkscape:vp_z="1 : 0.5 : 1"
  247 + inkscape:vp_y="0 : 1000 : 0"
  248 + inkscape:vp_x="0 : 0.5 : 1"
  249 + sodipodi:type="inkscape:persp3d" />
  250 + <radialGradient
  251 + r="28.622223"
  252 + fy="21.208994"
  253 + fx="25.103651"
  254 + cy="25.913044"
  255 + cx="28.347824"
  256 + gradientTransform="translate(2.0080471e-6,0)"
  257 + gradientUnits="userSpaceOnUse"
  258 + id="radialGradient3909"
  259 + xlink:href="#linearGradient3942"
  260 + inkscape:collect="always" />
  261 + <linearGradient
  262 + id="linearGradient3942">
  263 + <stop
  264 + id="stop3944"
  265 + offset="0"
  266 + style="stop-color:#f57900;stop-opacity:0;" />
  267 + <stop
  268 + id="stop3946"
  269 + offset="1"
  270 + style="stop-color:#cc0000;stop-opacity:1" />
  271 + </linearGradient>
  272 + <mask
  273 + maskUnits="userSpaceOnUse"
  274 + id="mask3951">
  275 + <rect
  276 + style="color:#000000;fill:url(#linearGradient3955);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  277 + id="rect3953"
  278 + width="60.666664"
  279 + height="60.666664"
  280 + x="1.6666656"
  281 + y="1.6666654" />
  282 + </mask>
  283 + <linearGradient
  284 + inkscape:collect="always"
  285 + xlink:href="#linearGradient3795-2"
  286 + id="linearGradient3955"
  287 + gradientUnits="userSpaceOnUse"
  288 + gradientTransform="matrix(4.6666665,0,0,4.6666665,-10.000001,-28.666667)"
  289 + x1="9.500001"
  290 + y1="8.5"
  291 + x2="9.5"
  292 + y2="12.5" />
  293 + <linearGradient
  294 + inkscape:collect="always"
  295 + id="linearGradient3795-2">
  296 + <stop
  297 + style="stop-color:#000000;stop-opacity:1"
  298 + offset="0"
  299 + id="stop3797-1" />
  300 + <stop
  301 + style="stop-color:#ffffff;stop-opacity:1"
  302 + offset="1"
  303 + id="stop3799-3" />
  304 + </linearGradient>
  305 + <clipPath
  306 + clipPathUnits="userSpaceOnUse"
  307 + id="clipPath3975">
  308 + <path
  309 + sodipodi:nodetypes="cssscccsc"
  310 + id="path3977"
  311 + d="M 60,32 C 60,47.456 47.456,60 32,60 16.544,60 4,47.456 4,32 4,24.272 7.136,17.272 12.204,12.204 c 5.068,-5.068 13.334459,-23.280923 21.949843,-29.742461 -1.025992,6.66895 0,14.2153844 4.307693,18.52307669 0,0 0,-8.61538459 4.307692,-12.92307669 C 47.07692,0.98461569 50.523074,8.3076924 52.67692,12.172942 55.418861,17.093574 59.999999,22.388434 60,32 z"
  312 + style="opacity:0.6;color:#000000;fill:#73d216;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.30769205;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  313 + </clipPath>
  314 + <filter
  315 + color-interpolation-filters="sRGB"
  316 + inkscape:collect="always"
  317 + id="filter3963"
  318 + x="-0.28615385"
  319 + width="1.5723077"
  320 + y="-0.20666666"
  321 + height="1.4133333">
  322 + <feGaussianBlur
  323 + inkscape:collect="always"
  324 + stdDeviation="6.676923"
  325 + id="feGaussianBlur3965" />
  326 + </filter>
  327 + <clipPath
  328 + clipPathUnits="userSpaceOnUse"
  329 + id="clipPath3878">
  330 + <path
  331 + sodipodi:nodetypes="csssssssc"
  332 + id="path3880"
  333 + d="m 27.200893,15.993392 c 0,6.150858 -4.991999,11.142858 -11.142856,11.142858 -6.150858,0 -11.142858,-4.992 -11.142858,-11.142858 0,-2.185214 1.714285,-5.954659 1.714285,-7.7142849 0,-8.57142868 5.832926,-12.0000001 10.285715,-12.0000001 1.714286,0 2.493799,1.946371 1.714286,3.42857146 -0.661208,1.25725054 -3.428572,1.71428574 -1.714286,3.42857144 1.212183,1.2121831 6.215414,4.1736984 7.020858,4.9791428 2.016856,2.0168573 3.264856,4.8025713 3.264856,7.8779993 z"
  334 + style="color:#000000;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.71428561;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  335 + </clipPath>
  336 + <filter
  337 + color-interpolation-filters="sRGB"
  338 + inkscape:collect="always"
  339 + id="filter3870"
  340 + x="-0.29058462"
  341 + width="1.5811692"
  342 + y="-0.20441557"
  343 + height="1.4088312">
  344 + <feGaussianBlur
  345 + inkscape:collect="always"
  346 + stdDeviation="2.459375"
  347 + id="feGaussianBlur3872" />
  348 + </filter>
  349 + <radialGradient
  350 + inkscape:collect="always"
  351 + xlink:href="#linearGradient3471-4"
  352 + id="radialGradient2759-9"
  353 + gradientUnits="userSpaceOnUse"
  354 + gradientTransform="translate(2.0080471e-6,0)"
  355 + cx="28.347824"
  356 + cy="25.913044"
  357 + fx="25.103651"
  358 + fy="21.208994"
  359 + r="28.622223" />
  360 + <linearGradient
  361 + id="linearGradient3471-4">
  362 + <stop
  363 + style="stop-color:#729fcf;stop-opacity:0;"
  364 + offset="0"
  365 + id="stop3473-7" />
  366 + <stop
  367 + style="stop-color:#204a87;stop-opacity:1"
  368 + offset="1"
  369 + id="stop3475-8" />
  370 + </linearGradient>
  371 + <mask
  372 + maskUnits="userSpaceOnUse"
  373 + id="mask3828">
  374 + <rect
  375 + y="1.6666656"
  376 + x="1.6666653"
  377 + height="60.666664"
  378 + width="60.666664"
  379 + id="rect3830"
  380 + style="color:#000000;fill:url(#linearGradient3832);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  381 + </mask>
  382 + <linearGradient
  383 + inkscape:collect="always"
  384 + xlink:href="#linearGradient3795"
  385 + id="linearGradient3832"
  386 + gradientUnits="userSpaceOnUse"
  387 + gradientTransform="matrix(4.6666666,0,0,4.6666666,-10.000001,-28.666667)"
  388 + x1="8.5"
  389 + y1="8.5"
  390 + x2="9.5"
  391 + y2="12.5" />
  392 + <linearGradient
  393 + inkscape:collect="always"
  394 + id="linearGradient3795">
  395 + <stop
  396 + style="stop-color:#000000;stop-opacity:1"
  397 + offset="0"
  398 + id="stop3797" />
  399 + <stop
  400 + style="stop-color:#ffffff;stop-opacity:1"
  401 + offset="1"
  402 + id="stop3799" />
  403 + </linearGradient>
  404 + <radialGradient
  405 + inkscape:collect="always"
  406 + xlink:href="#linearGradient3471-4"
  407 + id="radialGradient3416"
  408 + gradientUnits="userSpaceOnUse"
  409 + gradientTransform="translate(2.0080471e-6,0)"
  410 + cx="28.347824"
  411 + cy="25.913044"
  412 + fx="25.103651"
  413 + fy="21.208994"
  414 + r="28.622223" />
  415 + <radialGradient
  416 + inkscape:collect="always"
  417 + xlink:href="#linearGradient3942"
  418 + id="radialGradient3428"
  419 + gradientUnits="userSpaceOnUse"
  420 + gradientTransform="translate(2.0080471e-6,0)"
  421 + cx="28.347824"
  422 + cy="25.913044"
  423 + fx="25.103651"
  424 + fy="21.208994"
  425 + r="28.622223" />
  426 + <radialGradient
  427 + inkscape:collect="always"
  428 + xlink:href="#linearGradient3942"
  429 + id="radialGradient3442"
  430 + gradientUnits="userSpaceOnUse"
  431 + gradientTransform="translate(2.0080471e-6,0)"
  432 + cx="28.347824"
  433 + cy="25.913044"
  434 + fx="25.103651"
  435 + fy="21.208994"
  436 + r="28.622223" />
  437 + <radialGradient
  438 + inkscape:collect="always"
  439 + xlink:href="#linearGradient4248"
  440 + id="radialGradient4254"
  441 + cx="16.000992"
  442 + cy="11.373981"
  443 + fx="16.000992"
  444 + fy="11.373981"
  445 + r="9.5902691"
  446 + gradientTransform="matrix(1.1061205,-0.39028044,0.43577759,1.235069,-6.3491962,4.30218)"
  447 + gradientUnits="userSpaceOnUse" />
  448 + </defs>
  449 + <sodipodi:namedview
  450 + inkscape:window-y="25"
  451 + inkscape:window-x="0"
  452 + inkscape:window-height="694"
  453 + inkscape:window-width="1024"
  454 + inkscape:document-units="px"
  455 + inkscape:grid-bbox="true"
  456 + showgrid="false"
  457 + inkscape:current-layer="layer5"
  458 + inkscape:cy="25"
  459 + inkscape:cx="24.886621"
  460 + inkscape:zoom="8.82"
  461 + inkscape:pageshadow="2"
  462 + inkscape:pageopacity="0.0"
  463 + borderopacity="0.25490196"
  464 + bordercolor="#666666"
  465 + pagecolor="#ffffff"
  466 + id="base"
  467 + inkscape:showpageshadow="false"
  468 + fill="#729fcf"
  469 + inkscape:window-maximized="1" />
  470 + <metadata
  471 + id="metadata4">
  472 + <rdf:RDF>
  473 + <cc:Work
  474 + rdf:about="">
  475 + <dc:format>image/svg+xml</dc:format>
  476 + <dc:type
  477 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  478 + <dc:title></dc:title>
  479 + <dc:subject>
  480 + <rdf:Bag>
  481 + <rdf:li>rich</rdf:li>
  482 + <rdf:li>text</rdf:li>
  483 + <rdf:li>document</rdf:li>
  484 + <rdf:li>pdf</rdf:li>
  485 + <rdf:li>openoffice</rdf:li>
  486 + <rdf:li>word</rdf:li>
  487 + <rdf:li>rtf</rdf:li>
  488 + </rdf:Bag>
  489 + </dc:subject>
  490 + <cc:license
  491 + rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
  492 + <dc:creator>
  493 + <cc:Agent>
  494 + <dc:title>Jakub Steiner</dc:title>
  495 + </cc:Agent>
  496 + </dc:creator>
  497 + <dc:source>http://jimmac.musichall.cz</dc:source>
  498 + </cc:Work>
  499 + <cc:License
  500 + rdf:about="http://creativecommons.org/licenses/publicdomain/">
  501 + <cc:permits
  502 + rdf:resource="http://creativecommons.org/ns#Reproduction" />
  503 + <cc:permits
  504 + rdf:resource="http://creativecommons.org/ns#Distribution" />
  505 + <cc:permits
  506 + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
  507 + </cc:License>
  508 + </rdf:RDF>
  509 + </metadata>
  510 + <g
  511 + inkscape:groupmode="layer"
  512 + id="layer6"
  513 + inkscape:label="Shadow">
  514 + <g
  515 + style="display:inline"
  516 + transform="matrix(0.02203962,0,0,0.02086758,45.477817,43.162522)"
  517 + id="g6707">
  518 + <rect
  519 + style="opacity:0.40206185;color:#000000;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  520 + id="rect6709"
  521 + width="1339.6335"
  522 + height="478.35718"
  523 + x="-1559.2523"
  524 + y="-150.69685" />
  525 + <path
  526 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  527 + d="m -219.61876,-150.68038 c 0,0 0,478.33079 0,478.33079 142.874166,0.90045 345.40022,-107.16966 345.40014,-239.196175 0,-132.026537 -159.436816,-239.134595 -345.40014,-239.134615 z"
  528 + id="path6711"
  529 + sodipodi:nodetypes="cccc" />
  530 + <path
  531 + sodipodi:nodetypes="cccc"
  532 + id="path6713"
  533 + d="m -1559.2523,-150.68038 c 0,0 0,478.33079 0,478.33079 -142.8742,0.90045 -345.4002,-107.16966 -345.4002,-239.196175 0,-132.026537 159.4368,-239.134595 345.4002,-239.134615 z"
  534 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" />
  535 + </g>
  536 + </g>
  537 + <g
  538 + style="display:inline"
  539 + inkscape:groupmode="layer"
  540 + inkscape:label="Base"
  541 + id="layer1">
  542 + <rect
  543 + style="color:#000000;fill:url(#radialGradient15658);fill-opacity:1;fill-rule:nonzero;stroke:url(#radialGradient15656);stroke-width:1.05215013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:block;overflow:visible"
  544 + id="rect15391"
  545 + width="35.947849"
  546 + height="43.947849"
  547 + x="7.5260749"
  548 + y="2.5260756"
  549 + ry="1.2340567" />
  550 + <rect
  551 + style="color:#000000;fill:none;stroke:url(#radialGradient15668);stroke-width:1.05609882;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:block;overflow:visible"
  552 + id="rect15660"
  553 + width="33.943901"
  554 + height="41.943901"
  555 + x="8.5280485"
  556 + y="3.528048"
  557 + ry="0.16052011"
  558 + rx="0.1543601" />
  559 + <g
  560 + transform="translate(1.6464467,-0.0379893)"
  561 + id="g2270">
  562 + <g
  563 + id="g1440"
  564 + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4"
  565 + transform="matrix(0.229703,0,0,0.229703,4.967081,4.244972)">
  566 + <radialGradient
  567 + id="radialGradient1442"
  568 + cx="20.892099"
  569 + cy="114.5684"
  570 + r="5.256"
  571 + fx="20.892099"
  572 + fy="114.5684"
  573 + gradientUnits="userSpaceOnUse">
  574 + <stop
  575 + offset="0"
  576 + style="stop-color:#F0F0F0"
  577 + id="stop1444" />
  578 + <stop
  579 + offset="1"
  580 + style="stop-color:#474747"
  581 + id="stop1446" />
  582 + </radialGradient>
  583 + <path
  584 + style="stroke:none"
  585 + d="m 23.428,113.07 c 0,1.973 -1.6,3.572 -3.573,3.572 -1.974,0 -3.573,-1.6 -3.573,-3.572 0,-1.974 1.6,-3.573 3.573,-3.573 1.973,0 3.573,1.6 3.573,3.573 z"
  586 + id="path1448" />
  587 + <radialGradient
  588 + id="radialGradient1450"
  589 + cx="20.892099"
  590 + cy="64.567902"
  591 + r="5.257"
  592 + fx="20.892099"
  593 + fy="64.567902"
  594 + gradientUnits="userSpaceOnUse">
  595 + <stop
  596 + offset="0"
  597 + style="stop-color:#F0F0F0"
  598 + id="stop1452" />
  599 + <stop
  600 + offset="1"
  601 + style="stop-color:#474747"
  602 + id="stop1454" />
  603 + </radialGradient>
  604 + <path
  605 + style="stroke:none"
  606 + d="m 23.428,63.07 c 0,1.973 -1.6,3.573 -3.573,3.573 -1.974,0 -3.573,-1.6 -3.573,-3.573 0,-1.974 1.6,-3.573 3.573,-3.573 1.973,0 3.573,1.6 3.573,3.573 z"
  607 + id="path1456" />
  608 + </g>
  609 + <path
  610 + style="fill:#4d4d4d;fill-rule:nonzero;stroke:none"
  611 + d="m 9.9950109,29.952326 c 0,0.453204 -0.3675248,0.820499 -0.8207288,0.820499 -0.4534338,0 -0.8207289,-0.367524 -0.8207289,-0.820499 0,-0.453434 0.3675248,-0.820729 0.8207289,-0.820729 0.453204,0 0.8207288,0.367525 0.8207288,0.820729 z"
  612 + id="path15570" />
  613 + <path
  614 + style="fill:#4d4d4d;fill-rule:nonzero;stroke:none"
  615 + d="m 9.9950109,18.467176 c 0,0.453204 -0.3675248,0.820729 -0.8207288,0.820729 -0.4534338,0 -0.8207289,-0.367525 -0.8207289,-0.820729 0,-0.453434 0.3675248,-0.820729 0.8207289,-0.820729 0.453204,0 0.8207288,0.367525 0.8207288,0.820729 z"
  616 + id="path15577" />
  617 + </g>
  618 + <path
  619 + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1.01333487;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
  620 + d="m 12.506667,4.0973012 0,40.8551318"
  621 + id="path15672"
  622 + sodipodi:nodetypes="cc" />
  623 + <path
  624 + style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1.02506876;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
  625 + d="m 13.512534,4.0125702 0,40.9748958"
  626 + id="path15674"
  627 + sodipodi:nodetypes="cc" />
  628 + </g>
  629 + <g
  630 + inkscape:groupmode="layer"
  631 + id="layer5"
  632 + inkscape:label="Text"
  633 + style="display:inline">
  634 + <rect
  635 + ry="0.065390877"
  636 + rx="0.096450485"
  637 + y="41"
  638 + x="17"
  639 + height="1"
  640 + width="14.000014"
  641 + id="rect15744"
  642 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  643 + <rect
  644 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  645 + id="rect1768"
  646 + width="20.000006"
  647 + height="1"
  648 + x="17"
  649 + y="11.000006"
  650 + rx="0.13778631"
  651 + ry="0.065390877" />
  652 + <g
  653 + transform="matrix(0.58333333,0,0,0.58333333,23.082298,18.666667)"
  654 + id="g2782">
  655 + <path
  656 + sodipodi:nodetypes="cscccss"
  657 + id="path3991"
  658 + d="M 16.186589,21.142857 C 10.932592,21.442092 5.8719316,14.98028 8.1220005,8.1219995 9.0674911,5.2401146 13.42857,-1.1428578 16.857142,-3.7142862 c -0.408303,2.6539699 0,5.6571428 1.714286,7.3714286 0,0 0,-3.42857151 1.714285,-5.1428572 1.714286,5.1428572 3.271486,7.9716527 3.942857,9.5953544 2.058215,4.9777654 0.483956,12.5476324 -8.041981,13.0332174 z"
  659 + style="color:#000000;fill:url(#radialGradient4254);fill-opacity:1;stroke:#a40000;stroke-width:1.71428561;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  660 + <path
  661 + sodipodi:type="inkscape:offset"
  662 + inkscape:radius="-1.5"
  663 + inkscape:original="M 16.84375 -3.71875 C 13.415178 -1.1473216 9.0704906 5.2431151 8.125 8.125 C 5.8749311 14.983281 10.933503 21.455485 16.1875 21.15625 C 24.713437 20.670665 26.276965 13.102765 24.21875 8.125 C 23.547379 6.5012983 21.995536 3.6428572 20.28125 -1.5 C 18.566965 0.21428569 18.5625 3.65625 18.5625 3.65625 C 16.848214 1.9419642 16.435447 -1.0647801 16.84375 -3.71875 z "
  664 + xlink:href="#path3991"
  665 + style="opacity:0.5;color:#000000;fill:none;stroke:#fcaf3e;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:9;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  666 + id="path3997"
  667 + inkscape:href="#path3991"
  668 + d="m 15.40625,-0.3125 c -0.903867,0.99041796 -1.796184,2.124373 -2.625,3.28125 -1.575827,2.1995678 -2.8557776,4.5186488 -3.21875,5.625 -1.9553465,5.959958 2.557716,11.288808 6.53125,11.0625 3.8265,-0.217934 5.732916,-1.852251 6.71875,-3.96875 0.985834,-2.116499 0.906542,-4.883117 0.03125,-7 -0.430922,-1.0421792 -1.493333,-3.2862791 -2.65625,-6.21875 -0.07263,0.5661553 -0.125,1.1875 -0.125,1.1875 A 1.50015,1.50015 0 0 1 17.5,4.71875 C 16.13821,3.3569603 15.617625,1.5548002 15.40625,-0.3125 z" />
  669 + </g>
  670 + <rect
  671 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  672 + id="rect3450"
  673 + width="9.1020555"
  674 + height="1"
  675 + x="17"
  676 + y="22.538467"
  677 + rx="0.06270691"
  678 + ry="0.065390877" />
  679 + <rect
  680 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  681 + id="rect3464"
  682 + width="20.000006"
  683 + height="1"
  684 + x="17"
  685 + y="38.692307"
  686 + rx="0.13778631"
  687 + ry="0.065390877" />
  688 + <rect
  689 + ry="0.065390877"
  690 + rx="0.13778631"
  691 + y="13.307699"
  692 + x="17"
  693 + height="1"
  694 + width="20.000006"
  695 + id="rect3466"
  696 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  697 + <rect
  698 + ry="0.065390877"
  699 + rx="0.06270691"
  700 + y="24.846159"
  701 + x="17"
  702 + height="1"
  703 + width="9.1020555"
  704 + id="rect4256"
  705 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  706 + <rect
  707 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  708 + id="rect4258"
  709 + width="9.1020555"
  710 + height="1"
  711 + x="17"
  712 + y="27.153851"
  713 + rx="0.06270691"
  714 + ry="0.065390877" />
  715 + <rect
  716 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  717 + id="rect4262"
  718 + width="9.1020555"
  719 + height="1"
  720 + x="17"
  721 + y="29.461542"
  722 + rx="0.06270691"
  723 + ry="0.065390877" />
  724 + <rect
  725 + ry="0.065390877"
  726 + rx="0.06270691"
  727 + y="31.769234"
  728 + x="17"
  729 + height="1"
  730 + width="9.1020555"
  731 + id="rect4264"
  732 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  733 + <rect
  734 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  735 + id="rect4268"
  736 + width="20.000006"
  737 + height="1"
  738 + x="17"
  739 + y="36.384617"
  740 + rx="0.13778631"
  741 + ry="0.065390877" />
  742 + <rect
  743 + ry="0.065390877"
  744 + rx="0.13778631"
  745 + y="34.076923"
  746 + x="17"
  747 + height="1"
  748 + width="20.000006"
  749 + id="rect4270"
  750 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  751 + <rect
  752 + ry="0.065390877"
  753 + rx="0.06270691"
  754 + y="17.923084"
  755 + x="17"
  756 + height="1"
  757 + width="9.1020555"
  758 + id="rect4272"
  759 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  760 + <rect
  761 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible"
  762 + id="rect4274"
  763 + width="9.1020555"
  764 + height="1"
  765 + x="17"
  766 + y="15.615393"
  767 + rx="0.06270691"
  768 + ry="0.065390877" />
  769 + <rect
  770 + ry="0.065390877"
  771 + rx="0.06270691"
  772 + y="20.230776"
  773 + x="17"
  774 + height="1"
  775 + width="9.1020555"
  776 + id="rect4278"
  777 + style="opacity:0.4;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:block;overflow:visible" />
  778 + <rect
  779 + ry="0.13078175"
  780 + rx="0.13778631"
  781 + y="7"
  782 + x="17"
  783 + height="2"
  784 + width="20.000006"
  785 + id="rect4280"
  786 + style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4;marker:none;visibility:visible;display:block;overflow:visible" />
  787 + </g>
  788 +</svg>
public/javascripts/tasks.js 0 → 100644
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +(function($) {
  2 +
  3 + $("input.task_accept_radio").click(function(){
  4 + task_id = this.getAttribute("task_id");
  5 + $('#on-accept-information-' + task_id).show('fast');
  6 + $('#on-reject-information-' + task_id).hide('fast');
  7 + $('#on-skip-information-' + task_id).hide('fast');
  8 + })
  9 +
  10 + $("input.task_reject_radio").click(function(){
  11 + task_id = this.getAttribute("task_id");
  12 + $('#on-accept-information-' + task_id).hide('fast');
  13 + $('#on-reject-information-' + task_id).show('fast');
  14 + $('#on-skip-information-' + task_id).hide('fast');
  15 + })
  16 +
  17 + $("input.task_skip_radio").click(function(){
  18 + task_id = this.getAttribute("task_id");
  19 + $('#on-accept-information-' + task_id).hide('fast');
  20 + $('#on-reject-information-' + task_id).hide('fast');
  21 + $('#on-skip-information-' + task_id).show('fast');
  22 + })
  23 +
  24 + // There is probably an elegant way to do this...
  25 + $('#up-set-all-tasks-to').selectedIndex = 0;
  26 + $('#down-set-all-tasks-to').selectedIndex = 0;
  27 +
  28 + $('#down-set-all-tasks-to').change(function(){
  29 + value = $('#down-set-all-tasks-to').selected().val();
  30 + up = $('#up-set-all-tasks-to')
  31 + up.attr('value', value).change();
  32 + })
  33 +
  34 + $('#up-set-all-tasks-to').change(function(){
  35 + value = $('#up-set-all-tasks-to').selected().val();
  36 + down = $('#down-set-all-tasks-to')
  37 + down.attr('value', value);
  38 + $('.task_'+value+'_radio').each( function(){
  39 + if(!this.disabled){
  40 + $(this).attr('checked', 'checked').click();
  41 + }
  42 + })
  43 + })
  44 +
  45 + $('.task_title').css('margin-right', $('.task_decisions').width()+'px');
  46 + $('.task_title').css('margin-left', $('.task_arrow').width()+'px');
  47 +
  48 +})(jQuery)
  49 +
public/stylesheets/application.css
@@ -305,7 +305,7 @@ div.auto-complete li.selected { @@ -305,7 +305,7 @@ div.auto-complete li.selected {
305 color: #204A87; 305 color: #204A87;
306 } 306 }
307 307
308 -/* pending tasks list */ 308 +/* pending tasks */
309 309
310 div.pending-tasks { 310 div.pending-tasks {
311 padding: 10px; 311 padding: 10px;
@@ -313,6 +313,19 @@ div.pending-tasks { @@ -313,6 +313,19 @@ div.pending-tasks {
313 margin-bottom: 20px; 313 margin-bottom: 20px;
314 } 314 }
315 315
  316 +#pending-tasks-count {
  317 + padding-left: 5px;
  318 + padding-right: 5px;
  319 + margin-left: 2px;
  320 + text-decoration: none;
  321 + background-color: #F57900;
  322 + color: #FFFFFF;
  323 + -moz-border-radius: 2px;
  324 + -webkit-border-radius: 2px;
  325 + -khtml-border-radius: 2px;
  326 + border-radius: 2px;
  327 +}
  328 +
316 /* sitemap and agenda */ 329 /* sitemap and agenda */
317 330
318 .agenda-item a.icon, 331 .agenda-item a.icon,
public/stylesheets/tasks.css 0 → 100644
@@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
  1 +.task_box {
  2 + position: relative;
  3 + border: 1px solid #888;
  4 + -moz-border-radius: 10px;
  5 + -webkit-border-radius: 10px;
  6 + -khtml-border-radius: 10px;
  7 + border-radius: 10px;
  8 + padding: 6px 4px 9px 4px;
  9 + margin-top: 5px;
  10 + background: #EEE;
  11 +}
  12 +
  13 +.task_title {
  14 + margin: 0px;
  15 + display: block;
  16 + line-height: 28px;
  17 + font-size: 120%;
  18 +}
  19 +
  20 +.task_icon {
  21 + float: left;
  22 + margin-right: 10px;
  23 + width: 50px;
  24 + height: 50px;
  25 + text-align: center;
  26 +}
  27 +
  28 +.task_decisions {
  29 + float: right;
  30 + padding-right: 5px;
  31 +}
  32 +
  33 +.task_information {
  34 + line-height: 18px;
  35 + padding: 2px 0px;
  36 + clear: right;
  37 +}
  38 +
  39 +.task_information p {
  40 + margin: 0px;
  41 +}
  42 +
  43 +.task_target {
  44 + text-decoration: underline;
  45 + font-weight: bold;
  46 +}
test/functional/tasks_controller_test.rb
@@ -46,7 +46,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -46,7 +46,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase
46 should 'be able to finish a task' do 46 should 'be able to finish a task' do
47 t = profile.tasks.build; t.save! 47 t = profile.tasks.build; t.save!
48 48
49 - post :close, :decision => 'finish', :id => t.id 49 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {}}}
50 assert_redirected_to :action => 'index' 50 assert_redirected_to :action => 'index'
51 51
52 t.reload 52 t.reload
@@ -56,52 +56,46 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -56,52 +56,46 @@ class TasksControllerTest &lt; Test::Unit::TestCase
56 should 'be able to cancel a task' do 56 should 'be able to cancel a task' do
57 t = profile.tasks.build; t.save! 57 t = profile.tasks.build; t.save!
58 58
59 - post :close, :decision => 'cancel', :id => t.id 59 + post :close, :tasks => {t.id => {:decision => 'cancel', :task => {}}}
60 assert_redirected_to :action => 'index' 60 assert_redirected_to :action => 'index'
61 61
62 t.reload 62 t.reload
63 ok('task should be cancelled') { t.status == Task::Status::CANCELLED } 63 ok('task should be cancelled') { t.status == Task::Status::CANCELLED }
64 end 64 end
65 65
66 - should 'affiliate roles to user after finish add member task' do  
67 - t = AddMember.create!(:person => profile, :organization => profile)  
68 - count = profile.members.size  
69 - post :close, :decision => 'finish', :id => t.id  
70 - profile = Profile.find(@profile.id)  
71 - assert_equal count + 1, profile.members.size  
72 - end 66 + should 'be able to skip a task' do
  67 + t = profile.tasks.build; t.save!
73 68
74 - should 'display custom form to add members task' do  
75 - t = AddMember.create!(:person => profile, :organization => profile)  
76 - get :index, :profile => profile.identifier  
77 - assert_tag :tag => 'form', :attributes => { :action => "/myprofile/#{profile.identifier}/tasks/close/#{t.id}" }  
78 - end 69 + post :close, :tasks => {t.id => {:decision => 'skip', :task => {}}}
  70 + assert_redirected_to :action => 'index'
79 71
80 - should 'display member role checked if target has members' do  
81 - profile.affiliate(profile, Profile::Roles.admin(profile.environment.id))  
82 - assert_equal 1, profile.members.size  
83 - t = AddMember.create!(:person => profile, :organization => profile)  
84 - get :index, :profile => profile.identifier  
85 - assert_tag :tag => 'input', :attributes => { :name => 'task[roles][]', :checked => 'checked', :value => Profile::Roles.member(profile.environment.id).id } 72 + t.reload
  73 + ok('task should be skipped') { t.status == Task::Status::ACTIVE }
86 end 74 end
87 75
88 - should 'display roles besides role member unchecked if target has members' do  
89 - profile.affiliate(profile, Profile::Roles.admin(profile.environment.id))  
90 - assert_equal 1, profile.members.size  
91 - t = AddMember.create!(:person => profile, :organization => profile)  
92 - get :index, :profile => profile.identifier  
93 - Role.find(:all).select{ |r| r.has_kind?('Profile') and r.id != Profile::Roles.member(profile.environment.id).id }.each do |i|  
94 - assert_no_tag :tag => 'input', :attributes => { :name => 'task[roles][]', :checked => 'checked', :value => i.id }  
95 - end 76 + should 'be able to apply different decisions to multiples tasks at the same time' do
  77 + t1 = profile.tasks.build; t1.save!
  78 + t2 = profile.tasks.build; t2.save!
  79 + t3 = profile.tasks.build; t3.save!
  80 +
  81 + post :close, :tasks => {t1.id => {:decision => 'finish', :task => {}}, t2.id => {:decision => 'cancel', :task => {}}, t3.id => {:decision => 'skip', :task => {}}}
  82 + assert_redirected_to :action => 'index'
  83 +
  84 + t1.reload
  85 + t2.reload
  86 + t3.reload
  87 +
  88 + ok('task should be finished') { t1.status == Task::Status::FINISHED }
  89 + ok('task should be canceled') { t2.status == Task::Status::CANCELLED }
  90 + ok('task should be skipped') { t3.status == Task::Status::ACTIVE }
96 end 91 end
97 92
98 - should 'display all roles checked if target has no members' do  
99 - assert_equal 0, profile.members.size 93 + should 'affiliate roles to user after finish add member task' do
100 t = AddMember.create!(:person => profile, :organization => profile) 94 t = AddMember.create!(:person => profile, :organization => profile)
101 - get :index, :profile => profile.identifier  
102 - Role.find(:all).select{ |r| r.has_kind?('Profile') }.each do |i|  
103 - assert_tag :tag => 'input', :attributes => { :name => 'task[roles][]', :checked => 'checked', :value => i.id }  
104 - end 95 + count = profile.members.size
  96 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {}}}
  97 + profile = Profile.find(@profile.id)
  98 + assert_equal count + 1, profile.members.size
105 end 99 end
106 100
107 should 'display a create ticket form' do 101 should 'display a create ticket form' do
@@ -161,8 +155,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -161,8 +155,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase
161 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails') 155 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails')
162 t = ApproveArticle.create!(:name => 'test name', :article => article, :target => c, :requestor => profile) 156 t = ApproveArticle.create!(:name => 'test name', :article => article, :target => c, :requestor => profile)
163 157
164 - post :close, :decision => 'finish', :id => t.id, :task => { :name => 'new name'}  
165 - assert_equal article, c.articles.find_by_name('new name').reference_article 158 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {:name => 'new_name'}}}
  159 + assert_equal article, c.articles.find_by_name('new_name').reference_article
166 end 160 end
167 161
168 should 'create published article in folder after finish approve article task' do 162 should 'create published article in folder after finish approve article task' do
@@ -174,8 +168,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -174,8 +168,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase
174 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails') 168 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails')
175 t = ApproveArticle.create!(:name => 'test name', :article => article, :target => c, :requestor => profile) 169 t = ApproveArticle.create!(:name => 'test name', :article => article, :target => c, :requestor => profile)
176 170
177 - post :close, :decision => 'finish', :id => t.id, :task => { :name => 'new name', :article_parent_id => folder.id}  
178 - assert_equal folder, c.articles.find_by_name('new name').parent 171 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {:name => 'new_name', :article_parent_id => folder.id}}}
  172 + assert_equal folder, c.articles.find_by_name('new_name').parent
179 end 173 end
180 174
181 should 'be highlighted if asked when approving a published article' do 175 should 'be highlighted if asked when approving a published article' do
@@ -187,8 +181,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -187,8 +181,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase
187 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails') 181 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails')
188 t = ApproveArticle.create!(:article => article, :target => c, :requestor => profile) 182 t = ApproveArticle.create!(:article => article, :target => c, :requestor => profile)
189 183
190 - post :close, :decision => 'finish', :id => t.id, :task => { :name => 'new name', :article_parent_id => folder.id, :highlighted => true}  
191 - assert_equal true, c.articles.find_by_name('new name').highlighted 184 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {:name => 'new_name', :article_parent_id => folder.id, :highlighted => true}}}
  185 + assert_equal true, c.articles.find_by_name('new_name').highlighted
192 end 186 end
193 187
194 should 'create article of same class after choosing root folder on approve article task' do 188 should 'create article of same class after choosing root folder on approve article task' do
@@ -199,8 +193,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -199,8 +193,8 @@ class TasksControllerTest &lt; Test::Unit::TestCase
199 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails') 193 article = profile.articles.create!(:name => 'something interesting', :body => 'ruby on rails')
200 t = ApproveArticle.create!(:article => article, :target => c, :requestor => profile) 194 t = ApproveArticle.create!(:article => article, :target => c, :requestor => profile)
201 195
202 - post :close, :decision => 'finish', :id => t.id, :task => { :name => 'new name', :article_parent_id => ""}  
203 - assert_equal article.class, c.articles.find_by_name('new name').class 196 + post :close, :tasks => {t.id => {:decision => 'finish', :task => {:name => 'new_name', :article_parent_id => ""}}}
  197 + assert_not_nil c.articles.find_by_name('new_name')
204 end 198 end
205 199
206 should 'handle blank names for published articles' do 200 should 'handle blank names for published articles' do
@@ -217,24 +211,24 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -217,24 +211,24 @@ class TasksControllerTest &lt; Test::Unit::TestCase
217 assert_includes c.tasks, a 211 assert_includes c.tasks, a
218 212
219 assert_difference article.class, :count do 213 assert_difference article.class, :count do
220 - post :close, {"commit"=>"Ok!", "id"=> a.id.to_s, "task"=>{"name"=>"", "closing_statment"=>"", "highlighted"=>"0", "article_parent_id"=>c_blog2.id.to_s}, "decision"=>"finish"} 214 + post :close, :tasks => {a.id => {:decision => 'finish', :task => {:name => "", :highlighted => "0", :article_parent_id => c_blog2.id.to_s}}}
221 end 215 end
222 assert p_article = article.class.find_by_reference_article_id(article.id) 216 assert p_article = article.class.find_by_reference_article_id(article.id)
223 assert_includes c_blog2.children(true), p_article 217 assert_includes c_blog2.children(true), p_article
224 end 218 end
225 219
226 - should 'cancel an enterprise registration task even if there is an enterprise with the same identifier' do 220 + should 'raise error if there is an enterprise with the same identifier and keep the task active' do
227 e = Environment.default 221 e = Environment.default
228 e.add_admin(profile) 222 e.add_admin(profile)
229 task = CreateEnterprise.create!(:name => "My Enterprise", :identifier => "my-enterprise", :requestor => profile, :target => e) 223 task = CreateEnterprise.create!(:name => "My Enterprise", :identifier => "my-enterprise", :requestor => profile, :target => e)
230 enterprise = fast_create(Enterprise, :name => "My Enterprise", :identifier => "my-enterprise") 224 enterprise = fast_create(Enterprise, :name => "My Enterprise", :identifier => "my-enterprise")
231 225
232 - assert_nothing_raised do  
233 - post :close, {:profile => profile.identifier, :id => task.id, :task => {:reject_explanation => "Bla bla"}, :decision => "cancel"} 226 + assert_raise ActiveRecord::RecordInvalid do
  227 + post :close, :tasks => {task.id => { :task => {:reject_explanation => "Bla bla"}, :decision => "cancel"}}
234 end 228 end
235 229
236 task.reload 230 task.reload
237 - assert_equal Task::Status::CANCELLED, task.status 231 + assert_equal Task::Status::ACTIVE, task.status
238 end 232 end
239 233
240 should 'create TinyMceArticle article after finish approve suggested article task' do 234 should 'create TinyMceArticle article after finish approve suggested article task' do
@@ -245,7 +239,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -245,7 +239,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase
245 SuggestArticle.skip_captcha! 239 SuggestArticle.skip_captcha!
246 t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) 240 t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c)
247 241
248 - post :close, :decision => 'finish', :id => t.id, :task => {} 242 + post :close, :tasks => {t.id => { :task => {}, :decision => "finish"}}
249 assert_not_nil TinyMceArticle.find(:first) 243 assert_not_nil TinyMceArticle.find(:first)
250 end 244 end
251 245
@@ -265,7 +259,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -265,7 +259,7 @@ class TasksControllerTest &lt; Test::Unit::TestCase
265 t.target = c 259 t.target = c
266 t.save! 260 t.save!
267 261
268 - post :close, :decision => 'finish', :id => t.id, :task => {:article_name => 'new article name', :article_body => 'new body', :source => 'http://www.noosfero.com', :source_name => 'new source', :name => 'new name'} 262 + post :close, :tasks => {t.id => { :task => {:article_name => 'new article name', :article_body => 'new body', :source => 'http://www.noosfero.com', :source_name => 'new source', :name => 'new name'}, :decision => "finish"}}
269 assert_equal 'new article name', TinyMceArticle.find(:first).name 263 assert_equal 'new article name', TinyMceArticle.find(:first).name
270 assert_equal 'new name', TinyMceArticle.find(:first).author_name 264 assert_equal 'new name', TinyMceArticle.find(:first).author_name
271 assert_equal 'new body', TinyMceArticle.find(:first).body 265 assert_equal 'new body', TinyMceArticle.find(:first).body
test/unit/add_friend_test.rb
@@ -71,15 +71,6 @@ class AddFriendTest &lt; ActiveSupport::TestCase @@ -71,15 +71,6 @@ class AddFriendTest &lt; ActiveSupport::TestCase
71 task = AddFriend.create!(:person => p1, :friend => p2) 71 task = AddFriend.create!(:person => p1, :friend => p2)
72 end 72 end
73 73
74 - should 'provide proper description' do  
75 - p1 = create_user('testuser1').person  
76 - p2 = create_user('testuser2').person  
77 -  
78 - task = fast_create(AddFriend, :requestor_id => p1.id, :target_id => p2.id)  
79 -  
80 - assert_equal 'testuser1 wants to be your friend.', task.description  
81 - end  
82 -  
83 should 'has permission to manage friends' do 74 should 'has permission to manage friends' do
84 t = AddFriend.new 75 t = AddFriend.new
85 assert_equal :manage_friends, t.permission 76 assert_equal :manage_friends, t.permission
test/unit/add_member_test.rb
@@ -49,18 +49,6 @@ class AddMemberTest &lt; ActiveSupport::TestCase @@ -49,18 +49,6 @@ class AddMemberTest &lt; ActiveSupport::TestCase
49 task = AddMember.create!(:person => p, :organization => c) 49 task = AddMember.create!(:person => p, :organization => c)
50 end 50 end
51 51
52 - should 'provide proper description' do  
53 - p = create_user('testuser1').person  
54 - c = fast_create(Community, :name => 'closed community')  
55 - c.update_attribute(:closed, true)  
56 -  
57 - TaskMailer.stubs(:deliver_target_notification)  
58 -  
59 - task = fast_create(AddMember, :requestor_id => p.id, :target_id => c.id, :target_type => 'Community')  
60 -  
61 - assert_equal 'testuser1 wants to be a member of "closed community".', task.description  
62 - end  
63 -  
64 should 'has permission to manage members' do 52 should 'has permission to manage members' do
65 t = AddMember.new 53 t = AddMember.new
66 assert_equal :manage_memberships, t.permission 54 assert_equal :manage_memberships, t.permission
test/unit/application_helper_test.rb
@@ -588,6 +588,12 @@ class ApplicationHelperTest &lt; Test::Unit::TestCase @@ -588,6 +588,12 @@ class ApplicationHelperTest &lt; Test::Unit::TestCase
588 assert_equal ["1 for b", "2 for c", "3 for a"], unique_with_count(%w(a b c a c a)) 588 assert_equal ["1 for b", "2 for c", "3 for a"], unique_with_count(%w(a b c a c a))
589 end 589 end
590 590
  591 + should 'show task information with the requestor' do
  592 + person = create_user('usertest').person
  593 + task = Task.create(:requestor => person)
  594 + assert_match person.name, task_information(task)
  595 + end
  596 +
591 protected 597 protected
592 598
593 def url_for(args = {}) 599 def url_for(args = {})
test/unit/approve_article_test.rb
@@ -62,7 +62,7 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase @@ -62,7 +62,7 @@ class ApproveArticleTest &lt; ActiveSupport::TestCase
62 article.destroy 62 article.destroy
63 a.reload 63 a.reload
64 64
65 - assert_match /text was removed/, a.description 65 + assert_equal "The article was removed.", a.information[:message]
66 end 66 end
67 67
68 should 'preserve article_parent' do 68 should 'preserve article_parent' do
test/unit/email_activation_test.rb
@@ -37,7 +37,7 @@ class EmailActivationTest &lt; Test::Unit::TestCase @@ -37,7 +37,7 @@ class EmailActivationTest &lt; Test::Unit::TestCase
37 task = EmailActivation.create!(:requestor => ze.person, :target => Environment.default) 37 task = EmailActivation.create!(:requestor => ze.person, :target => Environment.default)
38 task.finish 38 task.finish
39 39
40 - assert_equal ['zezinho@colivre.net'], ActionMailer::Base.deliveries.first.to 40 + assert_equal ["zezinho@#{ze.email_domain}"], ActionMailer::Base.deliveries.first.to
41 end 41 end
42 42
43 should 'create only once pending task by user' do 43 should 'create only once pending task by user' do
@@ -49,11 +49,4 @@ class EmailActivationTest &lt; Test::Unit::TestCase @@ -49,11 +49,4 @@ class EmailActivationTest &lt; Test::Unit::TestCase
49 assert !anothertask.save 49 assert !anothertask.save
50 end 50 end
51 51
52 - should 'display email address on description of task' do  
53 - ze = create_user('zezinho', :environment_id => Environment.default.id)  
54 - Environment.default.domains = [Domain.create!(:name => 'env_test.invalid')]  
55 - task = EmailActivation.new(:requestor => ze.person, :target => Environment.default)  
56 - assert_match /zezinho@env_test.invalid/, task.description  
57 - end  
58 -  
59 end 52 end
test/unit/invite_friend_test.rb
@@ -105,13 +105,6 @@ class InviteFriendTest &lt; ActiveSupport::TestCase @@ -105,13 +105,6 @@ class InviteFriendTest &lt; ActiveSupport::TestCase
105 task = InviteFriend.create!(:person => p1, :friend => p2) 105 task = InviteFriend.create!(:person => p1, :friend => p2)
106 end 106 end
107 107
108 - should 'mention inviter in description' do  
109 - p1 = create_user('testuser1').person  
110 - task = InviteFriend.new(:person => p1)  
111 -  
112 - assert_match 'testuser1', task.description  
113 - end  
114 -  
115 should 'has permission to manage friends' do 108 should 'has permission to manage friends' do
116 t = InviteFriend.new 109 t = InviteFriend.new
117 assert_equal :manage_friends, t.permission 110 assert_equal :manage_friends, t.permission
test/unit/invite_member_test.rb
@@ -85,19 +85,6 @@ class InviteMemberTest &lt; ActiveSupport::TestCase @@ -85,19 +85,6 @@ class InviteMemberTest &lt; ActiveSupport::TestCase
85 task = InviteMember.create!(:person => p1, :friend => p2, :community_id => fast_create(Community).id) 85 task = InviteMember.create!(:person => p1, :friend => p2, :community_id => fast_create(Community).id)
86 end 86 end
87 87
88 - should 'provide proper description' do  
89 - p1 = create_user('testuser1').person  
90 - p2 = create_user('testuser2').person  
91 -  
92 - TaskMailer.expects(:deliver_task_finished).never  
93 - TaskMailer.expects(:deliver_task_created).never  
94 -  
95 - community = fast_create(Community)  
96 - task = InviteMember.create!(:person => p1, :friend => p2, :community_id => community.id)  
97 -  
98 - assert_match(/#{p1.name}.*#{community.name}/, task.description)  
99 - end  
100 -  
101 should 'not invite yourself' do 88 should 'not invite yourself' do
102 p = create_user('testuser1').person 89 p = create_user('testuser1').person
103 90
test/unit/pending_task_notifier_test.rb
@@ -23,10 +23,10 @@ class PendingTaskNotifierTest &lt; Test::Unit::TestCase @@ -23,10 +23,10 @@ class PendingTaskNotifierTest &lt; Test::Unit::TestCase
23 p = create_user('maelcum').person 23 p = create_user('maelcum').person
24 c = fast_create(Community) 24 c = fast_create(Community)
25 c.add_admin(p) 25 c.add_admin(p)
26 - c.tasks << Task.new 26 + c.tasks << Task.new(:requestor => p)
27 27
28 response = PendingTaskNotifier.deliver_notification(p) 28 response = PendingTaskNotifier.deliver_notification(p)
29 - assert_match /Generic task/, response.body 29 + assert_match /sent you a task/, response.body
30 end 30 end
31 31
32 private 32 private
test/unit/rss_feed_test.rb
@@ -206,7 +206,7 @@ class RssFeedTest &lt; Test::Unit::TestCase @@ -206,7 +206,7 @@ class RssFeedTest &lt; Test::Unit::TestCase
206 end 206 end
207 207
208 should 'display the referenced body of a article published' do 208 should 'display the referenced body of a article published' do
209 - article = fast_create(TextileArticle, :body => 'This is the content of the Sample Article.') 209 + article = fast_create(TextileArticle, :body => 'This is the content of the Sample Article.', :profile_id => fast_create(Person).id)
210 profile = fast_create(Profile) 210 profile = fast_create(Profile)
211 blog = fast_create(Blog, :profile_id => profile.id) 211 blog = fast_create(Blog, :profile_id => profile.id)
212 a = ApproveArticle.create!(:name => 'test name', :article => article, :target => profile, :requestor => fast_create(Person)) 212 a = ApproveArticle.create!(:name => 'test name', :article => article, :target => profile, :requestor => fast_create(Person))
test/unit/suggest_article_test.rb
@@ -97,12 +97,6 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase @@ -97,12 +97,6 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase
97 assert_equal 'http://www.gnu.org/', article.source 97 assert_equal 'http://www.gnu.org/', article.source
98 end 98 end
99 99
100 - should 'use sender name in description' do  
101 - t = build(SuggestArticle, :target => @profile)  
102 - t.stubs(:sender).returns('XYZ')  
103 - assert_match(/XYZ/, t.description)  
104 - end  
105 -  
106 should 'use name and e-mail as sender info' do 100 should 'use name and e-mail as sender info' do
107 t = build(SuggestArticle, :target => @profile) 101 t = build(SuggestArticle, :target => @profile)
108 t.name = 'Some One' 102 t.name = 'Some One'
test/unit/task_mailer_test.rb
@@ -17,7 +17,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase @@ -17,7 +17,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
17 17
18 task = Task.new 18 task = Task.new
19 task.expects(:task_finished_message).returns('the message') 19 task.expects(:task_finished_message).returns('the message')
20 - task.expects(:description).returns('the task') 20 + task.expects(:information).returns('the task')
21 21
22 requestor = mock() 22 requestor = mock()
23 requestor.expects(:notification_emails).returns(['requestor@example.com']) 23 requestor.expects(:notification_emails).returns(['requestor@example.com'])
@@ -40,7 +40,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase @@ -40,7 +40,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
40 40
41 task = Task.new 41 task = Task.new
42 task.expects(:task_cancelled_message).returns('the message') 42 task.expects(:task_cancelled_message).returns('the message')
43 - task.expects(:description).returns('the task') 43 + task.expects(:information).returns('the task')
44 44
45 requestor = mock() 45 requestor = mock()
46 requestor.expects(:notification_emails).returns(['requestor@example.com']) 46 requestor.expects(:notification_emails).returns(['requestor@example.com'])
@@ -64,7 +64,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase @@ -64,7 +64,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
64 task = Task.new 64 task = Task.new
65 65
66 task.expects(:task_created_message).returns('the message') 66 task.expects(:task_created_message).returns('the message')
67 - task.expects(:description).returns('the task') 67 + task.expects(:information).returns('the task')
68 68
69 requestor = mock() 69 requestor = mock()
70 requestor.expects(:notification_emails).returns(['requestor@example.com']) 70 requestor.expects(:notification_emails).returns(['requestor@example.com'])
@@ -85,7 +85,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase @@ -85,7 +85,7 @@ class TaskMailerTest &lt; Test::Unit::TestCase
85 85
86 should 'be able to send a "target notification" message' do 86 should 'be able to send a "target notification" message' do
87 task = Task.new 87 task = Task.new
88 - task.expects(:description).returns('the task') 88 + task.expects(:information).returns('the task')
89 89
90 target = mock() 90 target = mock()
91 target.expects(:notification_emails).returns(['target@example.com']) 91 target.expects(:notification_emails).returns(['target@example.com'])
@@ -104,18 +104,18 @@ class TaskMailerTest &lt; Test::Unit::TestCase @@ -104,18 +104,18 @@ class TaskMailerTest &lt; Test::Unit::TestCase
104 assert !ActionMailer::Base.deliveries.empty? 104 assert !ActionMailer::Base.deliveries.empty?
105 end 105 end
106 106
107 - should 'be able to send a "invitatiom notification" message' do 107 + should 'be able to send a "invitation notification" message' do
108 108
109 task = InviteFriend.new 109 task = InviteFriend.new
110 - task.expects(:description).returns('the task')  
111 task.expects(:code).returns('123456') 110 task.expects(:code).returns('123456')
112 111
113 - task.expects(:message).returns('Hello <friend>, <user> invite you, please follow this link: <url>') 112 + task.stubs(:message).returns('Hello <friend>, <user> invite you, please follow this link: <url>')
114 task.expects(:friend_email).returns('friend@exemple.com') 113 task.expects(:friend_email).returns('friend@exemple.com')
115 task.expects(:friend_name).returns('friend name').at_least_once 114 task.expects(:friend_name).returns('friend name').at_least_once
116 115
117 requestor = mock() 116 requestor = mock()
118 - requestor.expects(:name).returns('my name') 117 + requestor.stubs(:name).returns('my name')
  118 + requestor.stubs(:public_profile_url).returns('requestor_path')
119 119
120 environment = mock() 120 environment = mock()
121 environment.expects(:contact_email).returns('sender@example.com') 121 environment.expects(:contact_email).returns('sender@example.com')
test/unit/task_test.rb
@@ -87,7 +87,8 @@ class TaskTest &lt; Test::Unit::TestCase @@ -87,7 +87,8 @@ class TaskTest &lt; Test::Unit::TestCase
87 end 87 end
88 88
89 should 'provide a description method' do 89 should 'provide a description method' do
90 - assert_kind_of String, Task.new.description 90 + requestor = create_user('requestor').person
  91 + assert_kind_of Hash, Task.new(:requestor => requestor).information
91 end 92 end
92 93
93 should 'notify just after the task is created' do 94 should 'notify just after the task is created' do