Commit bc5ce53f04ef9ab9ce1a3c0ef4a9d59087605f43

Authored by Evandro Jr
2 parents 8f14851f cbe76440

Merge branch 'production' of gitlab.com:participa/noosfero into production

Conflicts:
	app/views/cms/_event.html.erb
Gemfile
... ... @@ -26,6 +26,7 @@ gem 'grape_logging'
26 26 gem 'api-pagination', '~> 4.1.1'
27 27 gem 'rack-cors'
28 28 gem 'rack-contrib'
  29 +gem 'liquid', '~> 3.0.3'
29 30  
30 31 # asset pipeline
31 32 gem 'uglifier', '>= 1.0.3'
... ...
app/controllers/my_profile/email_templates_controller.rb 0 → 100644
... ... @@ -0,0 +1,63 @@
  1 +class EmailTemplatesController < MyProfileController
  2 +
  3 + protect 'send_mail_to_members', :profile
  4 +
  5 + def index
  6 + @email_templates = profile.email_templates
  7 + end
  8 +
  9 + def show
  10 + @email_template = profile.email_templates.find(params[:id])
  11 +
  12 + respond_to do |format|
  13 + format.html # show.html.erb
  14 + format.json { render json: @email_template }
  15 + end
  16 + end
  17 +
  18 + def show_parsed
  19 + @email_template = profile.email_templates.find(params[:id])
  20 + template_params = {:profile => profile, :environment => environment}
  21 + render json: {:parsed_body => @email_template.parsed_body(template_params), :parsed_subject => @email_template.parsed_subject(template_params)}
  22 + end
  23 +
  24 + def new
  25 + @email_template = profile.email_templates.build
  26 + end
  27 +
  28 + def edit
  29 + @email_template = profile.email_templates.find(params[:id])
  30 + end
  31 +
  32 + def create
  33 + @email_template = profile.email_templates.build(params[:email_template], :owner => profile)
  34 +
  35 + if @email_template.save
  36 + session[:notice] = _('Email template was successfully created.')
  37 + redirect_to url_for(:action => :index)
  38 + else
  39 + render action: "new"
  40 + end
  41 + end
  42 +
  43 + def update
  44 + @email_template = profile.email_templates.find(params[:id])
  45 +
  46 + if @email_template.update_attributes(params[:email_template])
  47 + session[:notice] = _('Email template was successfully updated.')
  48 + redirect_to url_for(:action => :index)
  49 + else
  50 + render action: "edit"
  51 + end
  52 + end
  53 +
  54 + def destroy
  55 + @email_template = profile.email_templates.find(params[:id])
  56 + @email_template.destroy
  57 +
  58 + respond_to do |format|
  59 + format.html { redirect_to url_for(:action => :index)}
  60 + format.json { head :no_content }
  61 + end
  62 + end
  63 +end
... ...
app/controllers/my_profile/tasks_controller.rb
... ... @@ -4,6 +4,8 @@ class TasksController &lt; MyProfileController
4 4 protect :perform_task, :profile, :except => [:index, :save_tags, :search_tags]
5 5  
6 6 def index
  7 + @email_templates = profile.email_templates.find_all_by_template_type(:task_rejection)
  8 +
7 9 @filter_type = params[:filter_type].presence
8 10 @filter_text = params[:filter_text].presence
9 11 @filter_responsible = params[:filter_responsible]
... ...
app/controllers/public/profile_controller.rb
... ... @@ -356,6 +356,7 @@ class ProfileController &lt; PublicController
356 356  
357 357 def send_mail
358 358 @mailing = profile.mailings.build(params[:mailing])
  359 + @email_templates = profile.email_templates.find_all_by_template_type(:organization_members)
359 360 if request.post?
360 361 @mailing.locale = locale
361 362 @mailing.person = user
... ...
app/mailers/task_mailer.rb
... ... @@ -33,11 +33,15 @@ class TaskMailer &lt; ActionMailer::Base
33 33 @requestor = task.requestor.name
34 34 @environment = task.requestor.environment.name
35 35 @url = url_for(:host => task.requestor.environment.default_hostname, :controller => 'home')
  36 + @email_template = task.email_template
  37 + template_params = {:environment => task.requestor.environment, :task => task}
36 38  
37 39 mail(
38 40 to: task.requestor.notification_emails,
39 41 from: self.class.generate_from(task),
40   - subject: '[%s] %s' % [task.requestor.environment.name, task.target_notification_description]
  42 + subject: @email_template.present? ? @email_template.parsed_subject(template_params) : '[%s] %s' % [task.requestor.environment.name, task.target_notification_description],
  43 + body: @email_template.present? ? @email_template.parsed_body(template_params) : nil,
  44 + content_type: @email_template.present? ? "text/html" : nil
41 45 )
42 46 end
43 47  
... ...
app/models/email_template.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +class EmailTemplate < ActiveRecord::Base
  2 +
  3 + belongs_to :owner, :polymorphic => true
  4 +
  5 + attr_accessible :template_type, :subject, :body, :owner, :name
  6 +
  7 + validates_presence_of :name
  8 +
  9 + def parsed_body(params)
  10 + @parsed_body ||= parse(body, params)
  11 + end
  12 +
  13 + def parsed_subject(params)
  14 + @parsed_subject ||= parse(subject, params)
  15 + end
  16 +
  17 + def available_types
  18 + HashWithIndifferentAccess.new ({
  19 + :task_rejection => {:description => _('Task Rejection')},
  20 + :organization_members => {:description => _('Organization Members')}
  21 + })
  22 + end
  23 +
  24 + protected
  25 +
  26 + def parse(source, params)
  27 + template = Liquid::Template.parse(source)
  28 + template.render(HashWithIndifferentAccess.new(params))
  29 + end
  30 +
  31 +end
... ...
app/models/environment.rb
... ... @@ -982,6 +982,10 @@ class Environment &lt; ActiveRecord::Base
982 982 self.licenses.any?
983 983 end
984 984  
  985 + def to_liquid
  986 + HashWithIndifferentAccess.new :name => name
  987 + end
  988 +
985 989 private
986 990  
987 991 def default_language_available
... ...
app/models/event.rb
... ... @@ -3,7 +3,7 @@ require &#39;builder&#39;
3 3  
4 4 class Event < Article
5 5  
6   - attr_accessible :start_date, :end_date, :link, :address, :start_hour, :start_minute, :presenter
  6 + attr_accessible :start_date, :end_date, :link, :address, :presenter
7 7  
8 8 def self.type_name
9 9 _('Event')
... ...
app/models/profile.rb
... ... @@ -189,6 +189,8 @@ class Profile &lt; ActiveRecord::Base
189 189  
190 190 has_many :comments_received, :class_name => 'Comment', :through => :articles, :source => :comments
191 191  
  192 + has_many :email_templates, :foreign_key => :owner_id
  193 +
192 194 # Although this should be a has_one relation, there are no non-silly names for
193 195 # a foreign key on article to reference the template to which it is
194 196 # welcome_page... =P
... ... @@ -509,6 +511,10 @@ class Profile &lt; ActiveRecord::Base
509 511 self.articles.find(:all, options)
510 512 end
511 513  
  514 + def to_liquid
  515 + HashWithIndifferentAccess.new :name => name, :identifier => identifier
  516 + end
  517 +
512 518 class << self
513 519  
514 520 # finds a profile by its identifier. This method is a shortcut to
... ...
app/models/task.rb
... ... @@ -42,6 +42,8 @@ class Task &lt; ActiveRecord::Base
42 42  
43 43 attr_protected :status
44 44  
  45 + settings_items :email_template_id, :type => :integer
  46 +
45 47 def initialize(*args)
46 48 super
47 49 self.status = (args.first ? args.first[:status] : nil) || Task::Status::ACTIVE
... ... @@ -237,6 +239,17 @@ class Task &lt; ActiveRecord::Base
237 239 end
238 240 end
239 241  
  242 + def email_template
  243 + @email_template ||= email_template_id.present? ? EmailTemplate.find_by_id(email_template_id) : nil
  244 + end
  245 +
  246 + def to_liquid
  247 + HashWithIndifferentAccess.new({
  248 + :requestor => requestor,
  249 + :reject_explanation => reject_explanation
  250 + })
  251 + end
  252 +
240 253 scope :pending, :conditions => { :status => Task::Status::ACTIVE }
241 254 scope :hidden, :conditions => { :status => Task::Status::HIDDEN }
242 255 scope :finished, :conditions => { :status => Task::Status::FINISHED }
... ...
app/views/cms/_event.html.erb
... ... @@ -14,10 +14,6 @@
14 14  
15 15 <%= labelled_form_field(_('Presenter:'), text_field(:article, :presenter)) %>
16 16  
17   -<%= labelled_form_field(_('End time'), time_select(:article, :end_date)) %>
18   -
19   -<%= labelled_form_field(_('Presenter:'), text_field(:article, :presenter)) %>
20   -
21 17 <%= labelled_form_field(_('Event website:'), text_field(:article, :link)) %>
22 18  
23 19 <%= labelled_form_field(_('Address:'), text_field(:article, :address)) %>
... ...
app/views/email_templates/_form.html.erb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +<%= form_for(@email_template, :url => {:controller => :email_templates, :action => @email_template.persisted? ? :update : :create, :id => @email_template.id}) do |f| %>
  2 +
  3 + <%= error_messages_for :email_template if @email_template.errors.any? %>
  4 +
  5 + <div class="template-fields">
  6 + <div class="header-fields">
  7 + <%= labelled_form_field(_('Template Name:'), f.text_field(:name)) %>
  8 + <%= labelled_form_field(_('Template Type:'), f.select(:template_type, @email_template.available_types.map {|k,v| [v[:description], k]}, :include_blank => true)) %>
  9 + <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %>
  10 + </div>
  11 + <div class="available-params">
  12 + <div class="reference">
  13 + <a target="_blank" href="https://github.com/Shopify/liquid/wiki/Liquid-for-Designers"><%= _('Template language reference') %></a>
  14 + </div>
  15 + <div class="label">
  16 + <%= _('The following parameters may be used in subject and body:') %>
  17 + </div>
  18 + <div class="values">
  19 + {{profile.name}}, {{profile.identifier}}, {{environment.name}}
  20 + </div>
  21 + </div>
  22 + <%= render :file => 'shared/tiny_mce' %>
  23 + <%= labelled_form_field(_('Body:'), f.text_area(:body, :class => 'mceEditor')) %>
  24 + </div>
  25 +
  26 + <div class="actions">
  27 + <%= submit_button(:save, _('Save')) %>
  28 + <%= button(:back, _('Back'), :controller => :email_templates) %>
  29 + </div>
  30 +
  31 +<% end %>
... ...
app/views/email_templates/edit.html.erb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h1>Editing Email Template</h1>
  2 +
  3 +<%= render 'form' %>
... ...
app/views/email_templates/index.html.erb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +<div class="email-templates">
  2 + <h1><%= _('Email Templates') %></h1>
  3 +
  4 + <table>
  5 + <tr>
  6 + <th><%= _('Name') %></th>
  7 + <th><%= _('Type') %></th>
  8 + <th><%= _('Actions') %></th>
  9 + </tr>
  10 +
  11 + <% @email_templates.each do |email_template| %>
  12 + <tr>
  13 + <td><%= email_template.name %></td>
  14 + <td><%= email_template.available_types[email_template.template_type][:description] if email_template.template_type.present? %></td>
  15 + <td>
  16 + <%= button_without_text(:edit, _('Edit'), {:controller => :email_templates, :action => :edit, :id => email_template.id}) %>
  17 + <%= button_without_text(:remove, _('Remove'), {:controller => :email_templates, :action => :destroy, :id => email_template.id}, method: :delete, data: { confirm: 'Are you sure?' }) %>
  18 + </td>
  19 + </tr>
  20 + <% end %>
  21 + </table>
  22 +
  23 + <br />
  24 +
  25 + <%= button(:new, _('New template'), :controller => :email_templates, :action => :new) %>
  26 + <%= button(:back, _('Back to control panel'), :controller => :profile_editor) %>
  27 +</div>
... ...
app/views/email_templates/new.html.erb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<h1>New Email Template</h1>
  2 +
  3 +<%= render 'form' %>
... ...
app/views/email_templates/show.html.erb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<p id="notice"><%= notice %></p>
  2 +
  3 +
  4 +<%= link_to 'Edit', url_for(:controller => :email_templates, :action => :edit, :id => @email_template.id) %> |
  5 +<%= link_to 'Back', url_for(:controller => :email_templates) %>
... ...
app/views/profile/send_mail.html.erb
... ... @@ -4,6 +4,12 @@
4 4  
5 5 <%= error_messages_for :mailing %>
6 6  
  7 +<% if @email_templates.present? %>
  8 + <div class="template-selection">
  9 + <%= labelled_form_field(_('Select a template:'), select_tag(:template, options_from_collection_for_select(@email_templates, :id, :name), :include_blank => true, 'data-url' => url_for(:controller => 'email_templates', :action => 'show_parsed'))) %>
  10 + </div>
  11 +<% end %>
  12 +
7 13 <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %>
8 14  
9 15 <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -72,6 +72,8 @@
72 72  
73 73 <%= control_panel_button(_('Edit welcome page'), 'welcome-page', :action => 'welcome_page') if has_welcome_page %>
74 74  
  75 + <%= control_panel_button(_('Email Templates'), 'email-templates', :controller => :email_templates) if profile.organization? %>
  76 +
75 77 <% @plugins.dispatch(:control_panel_buttons).each do |button| %>
76 78 <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %>
77 79 <% end %>
... ...
app/views/tasks/_task_reject_details.html.erb
  1 +<% if @email_templates.present? %>
  2 + <div class="template-selection">
  3 + <%= labelled_form_field(_('Select a rejection email template:'), select_tag("tasks[#{task.id}][task][email_template_id]", options_from_collection_for_select(@email_templates, :id, :name), :include_blank => true, 'data-url' => url_for(:controller => 'email_templates', :action => 'show_parsed'))) %>
  4 + </div>
  5 +<% end %>
  6 +
1 7 <%= labelled_form_field(_('Rejection explanation'), f.text_area(:reject_explanation, :rows => 5)) %>
... ...
db/migrate/20150609105354_create_email_template.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CreateEmailTemplate < ActiveRecord::Migration
  2 +
  3 + def change
  4 + create_table :email_templates do |t|
  5 + t.string :name
  6 + t.string :template_type
  7 + t.string :subject
  8 + t.text :body
  9 + t.references :owner, :polymorphic => true
  10 + t.timestamps
  11 + end
  12 + end
  13 +
  14 +end
... ...
db/migrate/20150615215500_alter_column_articles_start_date.rb
... ... @@ -1,13 +0,0 @@
1   -class AlterColumnArticlesStartDate < ActiveRecord::Migration
2   - def up
3   - change_table :articles do |t|
4   - t.change :start_date, :datetime
5   - end
6   - end
7   -
8   - def down
9   - change_table :articles do |t|
10   - t.change :start_date, :date
11   - end
12   - end
13   -end
db/migrate/20150615215658_alter_column_articles_end_date.rb
... ... @@ -1,13 +0,0 @@
1   -class AlterColumnArticlesEndDate < ActiveRecord::Migration
2   - def up
3   - change_table :articles do |t|
4   - t.change :end_date, :datetime
5   - end
6   - end
7   -
8   - def down
9   - change_table :articles do |t|
10   - t.change :end_date, :date
11   - end
12   - end
13   -end
db/migrate/20150615222147_alter_column_article_versions_end_date.rb
... ... @@ -1,13 +0,0 @@
1   -class AlterColumnArticleVersionsEndDate < ActiveRecord::Migration
2   - def up
3   - change_table :article_versions do |t|
4   - t.change :end_date, :datetime
5   - end
6   - end
7   -
8   - def down
9   - change_table :article_versions do |t|
10   - t.change :end_date, :date
11   - end
12   - end
13   -end
db/migrate/20150615222204_alter_column_article_versions_start_date.rb
... ... @@ -1,13 +0,0 @@
1   -class AlterColumnArticleVersionsStartDate < ActiveRecord::Migration
2   - def up
3   - change_table :article_versions do |t|
4   - t.change :start_date, :datetime
5   - end
6   - end
7   -
8   - def down
9   - change_table :article_versions do |t|
10   - t.change :start_date, :date
11   - end
12   - end
13   -end
14 0 \ No newline at end of file
plugins/virtuoso/Gemfile
1 1 gem 'rdf'
2 2 gem 'rdf-virtuoso'
3 3 gem 'oai'
4   -gem 'liquid'
  4 +gem 'liquid', '~> 3.0.3'
5 5 gem 'roadie'
6 6 gem 'roadie-rails'
... ...
public/javascripts/application.js
... ... @@ -32,6 +32,7 @@
32 32 *= require block-store.js
33 33 *= require jquery.typewatch.js
34 34 *= require require_login.js
  35 +*= require email_templates.js
35 36 */
36 37  
37 38 // scope for noosfero stuff
... ...
public/javascripts/email_templates.js 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +jQuery(document).ready(function($) {
  2 + $('.template-selection select').change(function() {
  3 + if(!$(this).val()) return;
  4 +
  5 + $.getJSON($(this).data('url'), {id: $(this).val()}, function(data) {
  6 + $('#mailing-form #mailing_subject').val(data.parsed_subject);
  7 + $('#mailing-form .mceEditor').val(data.parsed_body);
  8 + });
  9 + });
  10 +});
... ...
public/stylesheets/application.css
... ... @@ -15,6 +15,7 @@
15 15 *= require chat
16 16 *= require search
17 17 *= require block-store
  18 + *= require email-templates
18 19 */
19 20  
20 21 /* browser fixes */
... ... @@ -4657,6 +4658,9 @@ h1#agenda-title {
4657 4658 .controller-profile_editor a.control-panel-design-editor {
4658 4659 background-image: url(../images/control-panel/preferences-desktop-wallpaper.png)
4659 4660 }
  4661 +.controller-profile_editor a.control-panel-email-templates {
  4662 + background-image: url(../images/control-panel/email.png)
  4663 +}
4660 4664 .controller-profile_editor .msie6 a.control-panel-design-editor {
4661 4665 background-image: url(../images/control-panel/preferences-desktop-wallpaper.gif)
4662 4666 }
... ...
public/stylesheets/email-templates.css 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +.template-fields .header-fields, .template-fields .available-params {
  2 + width: 48%;
  3 + display: inline-block;
  4 +}
  5 +.template-fields .available-params .values {
  6 + color: rgb(111, 111, 111);
  7 +}
  8 +.template-fields .available-params .reference {
  9 + text-align: right;
  10 +}
  11 +.template-fields .available-params .reference a {
  12 + color: rgb(32, 101, 229);
  13 + text-decoration: none;
  14 + font-size: 10px;
  15 +}
  16 +.email-templates table td {
  17 + text-align: center;
  18 +}
... ...
test/functional/email_templates_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,68 @@
  1 +require 'test_helper'
  2 +
  3 +class EmailTemplatesControllerTest < ActionController::TestCase
  4 +
  5 + setup do
  6 + @profile = fast_create(Community)
  7 + @email_template = EmailTemplate.create!(:name => 'template', :owner => @profile)
  8 + @person = create_user_with_permission('templatemanager', 'send_mail_to_members', @profile)
  9 + login_as(@person.user.login)
  10 + end
  11 +
  12 + attr_accessor :profile, :person
  13 +
  14 + test "should get index" do
  15 + get :index, :profile => profile.identifier
  16 + assert_response :success
  17 + assert_not_nil assigns(:email_templates)
  18 + end
  19 +
  20 + test "should get new" do
  21 + get :new, :profile => profile.identifier
  22 + assert_response :success
  23 + end
  24 +
  25 + test "should create email_template" do
  26 + assert_difference('EmailTemplate.count') do
  27 + post :create, email_template: { :name => 'test' }, :profile => profile.identifier
  28 + end
  29 +
  30 + assert_redirected_to url_for(:action => :index)
  31 + end
  32 +
  33 + test "should show email_template" do
  34 + get :show, id: @email_template, :profile => profile.identifier
  35 + assert_response :success
  36 + end
  37 +
  38 + test "should get edit" do
  39 + get :edit, id: @email_template, :profile => profile.identifier
  40 + assert_response :success
  41 + end
  42 +
  43 + test "should update email_template" do
  44 + put :update, id: @email_template, email_template: { }, :profile => profile.identifier
  45 + assert_redirected_to url_for(:action => :index)
  46 + end
  47 +
  48 + test "should destroy email_template" do
  49 + assert_difference('EmailTemplate.count', -1) do
  50 + delete :destroy, id: @email_template, :profile => profile.identifier
  51 + end
  52 +
  53 + assert_redirected_to url_for(:action => :index)
  54 + end
  55 +
  56 + test "should get parsed template" do
  57 + environment = Environment.default
  58 + @email_template.subject = '{{profile.name}} - {{profile.identifier}}'
  59 + @email_template.body = '{{profile.name}} - {{profile.identifier}} - {{environment.name}}'
  60 + @email_template.save!
  61 + get :show_parsed, id: @email_template, :profile => profile.identifier
  62 + assert_response :success
  63 + json_response = ActiveSupport::JSON.decode(@response.body)
  64 + assert_equal "#{profile.name} - #{profile.identifier}", json_response['parsed_subject']
  65 + assert_equal "#{profile.name} - #{profile.identifier} - #{environment.name}", json_response['parsed_body']
  66 + end
  67 +
  68 +end
... ...
test/functional/profile_controller_test.rb
... ... @@ -1471,6 +1471,29 @@ class ProfileControllerTest &lt; ActionController::TestCase
1471 1471 assert_redirected_to :action => 'members'
1472 1472 end
1473 1473  
  1474 + should 'display email templates as an option to send mail' do
  1475 + community = fast_create(Community)
  1476 + create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community)
  1477 + login_as('profile_moderator_user')
  1478 +
  1479 + template1 = EmailTemplate.create!(:owner => community, :name => "Template 1", :template_type => :organization_members)
  1480 + template2 = EmailTemplate.create!(:owner => community, :name => "Template 2")
  1481 +
  1482 + get :send_mail, :profile => community.identifier, :mailing => {:subject => 'Hello', :body => 'We have some news'}
  1483 + assert_select '.template-selection'
  1484 + assert_equal [template1], assigns(:email_templates)
  1485 + end
  1486 +
  1487 + should 'do not display email template selection when there is no template for organization members' do
  1488 + community = fast_create(Community)
  1489 + create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community)
  1490 + login_as('profile_moderator_user')
  1491 +
  1492 + get :send_mail, :profile => community.identifier, :mailing => {:subject => 'Hello', :body => 'We have some news'}
  1493 + assert_select '.template-selection', 0
  1494 + assert assigns(:email_templates).empty?
  1495 + end
  1496 +
1474 1497 should 'show all fields to anonymous user' do
1475 1498 viewed = create_user('person_1').person
1476 1499 Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date'])
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -626,6 +626,17 @@ class ProfileEditorControllerTest &lt; ActionController::TestCase
626 626 assert_tag :tag => 'a', :attributes => { :href => '/myprofile/default_user/cms' }
627 627 end
628 628  
  629 + should 'display email template link for organizations in control panel' do
  630 + profile = fast_create(Organization)
  631 + get :index, :profile => profile.identifier
  632 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/email_templates" }
  633 + end
  634 +
  635 + should 'not display email template link in control panel for person' do
  636 + get :index, :profile => profile.identifier
  637 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{profile.identifier}/email_templates" }
  638 + end
  639 +
629 640 should 'offer to create blog in control panel' do
630 641 get :index, :profile => profile.identifier
631 642 assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/new?type=Blog" }
... ...
test/unit/email_template_test.rb 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +require_relative "../test_helper"
  2 +
  3 +class EmailTemplateTest < ActiveSupport::TestCase
  4 +
  5 + should 'filter templates by type' do
  6 + EmailTemplate.create!(:template_type => :type1, :name => 'template1')
  7 + EmailTemplate.create!(:template_type => :type2, :name => 'template2')
  8 + EmailTemplate.create!(:template_type => :type2, :name => 'template3')
  9 + assert_equal ['template2', 'template3'], EmailTemplate.find_all_by_template_type(:type2).map(&:name)
  10 + end
  11 +
  12 + should 'parse body using params' do
  13 + template = EmailTemplate.new(:body => 'Hi {{person}}')
  14 + assert_equal 'Hi John', template.parsed_body({:person => 'John'})
  15 + end
  16 +
  17 + should 'parse subject using params' do
  18 + template = EmailTemplate.new(:subject => 'Hi {{person}}')
  19 + assert_equal 'Hi John', template.parsed_subject({:person => 'John'})
  20 + end
  21 +
  22 +end
... ...
test/unit/task_mailer_test.rb
... ... @@ -166,6 +166,35 @@ class TaskMailerTest &lt; ActiveSupport::TestCase
166 166 assert_match(/#{url_to_compare}/, mail.body.to_s)
167 167 end
168 168  
  169 + should 'be able to send rejection notification based on a selected template' do
  170 + task = Task.new
  171 + task.expects(:task_cancelled_message).returns('the message')
  172 + task.reject_explanation = 'explanation'
  173 +
  174 + profile = fast_create(Community)
  175 + email_template = EmailTemplate.create!(:owner => profile, :name => 'Template 1', :subject => 'template subject - {{environment.name}}', :body => 'template body - {{environment.name}} - {{task.requestor.name}} - {{task.reject_explanation}}')
  176 + task.email_template_id = email_template.id
  177 +
  178 + requestor = Profile.new(:name => 'my name')
  179 + requestor.expects(:notification_emails).returns(['requestor@example.com']).at_least_once
  180 +
  181 + environment = Environment.default
  182 + environment.expects(:noreply_email).returns('sender@example.com')
  183 + environment.expects(:default_hostname).returns('example.com')
  184 + environment.expects(:name).returns('example').at_least_once
  185 +
  186 + task.expects(:requestor).returns(requestor).at_least_once
  187 + requestor.expects(:environment).returns(environment).at_least_once
  188 + task.expects(:environment).returns(environment).at_least_once
  189 +
  190 + task.send(:send_notification, :cancelled).deliver
  191 + assert !ActionMailer::Base.deliveries.empty?
  192 + mail = ActionMailer::Base.deliveries.last
  193 + assert_match /text\/html/, mail.content_type
  194 + assert_equal 'template subject - example', mail.subject.to_s
  195 + assert_equal 'template body - example - my name - explanation', mail.body.to_s
  196 + end
  197 +
169 198 private
170 199 def read_fixture(action)
171 200 IO.readlines("#{FIXTURES_PATH}/task_mailer/#{action}")
... ...