Commit bc5ce53f04ef9ab9ce1a3c0ef4a9d59087605f43
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Merge branch 'production' of gitlab.com:participa/noosfero into production
Conflicts: app/views/cms/_event.html.erb
Showing
34 changed files
with
411 additions
and
59 deletions
Show diff stats
Gemfile
@@ -26,6 +26,7 @@ gem 'grape_logging' | @@ -26,6 +26,7 @@ gem 'grape_logging' | ||
26 | gem 'api-pagination', '~> 4.1.1' | 26 | gem 'api-pagination', '~> 4.1.1' |
27 | gem 'rack-cors' | 27 | gem 'rack-cors' |
28 | gem 'rack-contrib' | 28 | gem 'rack-contrib' |
29 | +gem 'liquid', '~> 3.0.3' | ||
29 | 30 | ||
30 | # asset pipeline | 31 | # asset pipeline |
31 | gem 'uglifier', '>= 1.0.3' | 32 | gem 'uglifier', '>= 1.0.3' |
app/controllers/my_profile/email_templates_controller.rb
0 → 100644
@@ -0,0 +1,63 @@ | @@ -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 < MyProfileController | @@ -4,6 +4,8 @@ class TasksController < MyProfileController | ||
4 | protect :perform_task, :profile, :except => [:index, :save_tags, :search_tags] | 4 | protect :perform_task, :profile, :except => [:index, :save_tags, :search_tags] |
5 | 5 | ||
6 | def index | 6 | def index |
7 | + @email_templates = profile.email_templates.find_all_by_template_type(:task_rejection) | ||
8 | + | ||
7 | @filter_type = params[:filter_type].presence | 9 | @filter_type = params[:filter_type].presence |
8 | @filter_text = params[:filter_text].presence | 10 | @filter_text = params[:filter_text].presence |
9 | @filter_responsible = params[:filter_responsible] | 11 | @filter_responsible = params[:filter_responsible] |
app/controllers/public/profile_controller.rb
@@ -356,6 +356,7 @@ class ProfileController < PublicController | @@ -356,6 +356,7 @@ class ProfileController < PublicController | ||
356 | 356 | ||
357 | def send_mail | 357 | def send_mail |
358 | @mailing = profile.mailings.build(params[:mailing]) | 358 | @mailing = profile.mailings.build(params[:mailing]) |
359 | + @email_templates = profile.email_templates.find_all_by_template_type(:organization_members) | ||
359 | if request.post? | 360 | if request.post? |
360 | @mailing.locale = locale | 361 | @mailing.locale = locale |
361 | @mailing.person = user | 362 | @mailing.person = user |
app/mailers/task_mailer.rb
@@ -33,11 +33,15 @@ class TaskMailer < ActionMailer::Base | @@ -33,11 +33,15 @@ class TaskMailer < ActionMailer::Base | ||
33 | @requestor = task.requestor.name | 33 | @requestor = task.requestor.name |
34 | @environment = task.requestor.environment.name | 34 | @environment = task.requestor.environment.name |
35 | @url = url_for(:host => task.requestor.environment.default_hostname, :controller => 'home') | 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 | mail( | 39 | mail( |
38 | to: task.requestor.notification_emails, | 40 | to: task.requestor.notification_emails, |
39 | from: self.class.generate_from(task), | 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 | end | 46 | end |
43 | 47 |
@@ -0,0 +1,31 @@ | @@ -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 < ActiveRecord::Base | @@ -982,6 +982,10 @@ class Environment < ActiveRecord::Base | ||
982 | self.licenses.any? | 982 | self.licenses.any? |
983 | end | 983 | end |
984 | 984 | ||
985 | + def to_liquid | ||
986 | + HashWithIndifferentAccess.new :name => name | ||
987 | + end | ||
988 | + | ||
985 | private | 989 | private |
986 | 990 | ||
987 | def default_language_available | 991 | def default_language_available |
app/models/event.rb
@@ -3,7 +3,7 @@ require 'builder' | @@ -3,7 +3,7 @@ require 'builder' | ||
3 | 3 | ||
4 | class Event < Article | 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 | def self.type_name | 8 | def self.type_name |
9 | _('Event') | 9 | _('Event') |
app/models/profile.rb
@@ -189,6 +189,8 @@ class Profile < ActiveRecord::Base | @@ -189,6 +189,8 @@ class Profile < ActiveRecord::Base | ||
189 | 189 | ||
190 | has_many :comments_received, :class_name => 'Comment', :through => :articles, :source => :comments | 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 | # Although this should be a has_one relation, there are no non-silly names for | 194 | # Although this should be a has_one relation, there are no non-silly names for |
193 | # a foreign key on article to reference the template to which it is | 195 | # a foreign key on article to reference the template to which it is |
194 | # welcome_page... =P | 196 | # welcome_page... =P |
@@ -509,6 +511,10 @@ class Profile < ActiveRecord::Base | @@ -509,6 +511,10 @@ class Profile < ActiveRecord::Base | ||
509 | self.articles.find(:all, options) | 511 | self.articles.find(:all, options) |
510 | end | 512 | end |
511 | 513 | ||
514 | + def to_liquid | ||
515 | + HashWithIndifferentAccess.new :name => name, :identifier => identifier | ||
516 | + end | ||
517 | + | ||
512 | class << self | 518 | class << self |
513 | 519 | ||
514 | # finds a profile by its identifier. This method is a shortcut to | 520 | # finds a profile by its identifier. This method is a shortcut to |
app/models/task.rb
@@ -42,6 +42,8 @@ class Task < ActiveRecord::Base | @@ -42,6 +42,8 @@ class Task < ActiveRecord::Base | ||
42 | 42 | ||
43 | attr_protected :status | 43 | attr_protected :status |
44 | 44 | ||
45 | + settings_items :email_template_id, :type => :integer | ||
46 | + | ||
45 | def initialize(*args) | 47 | def initialize(*args) |
46 | super | 48 | super |
47 | self.status = (args.first ? args.first[:status] : nil) || Task::Status::ACTIVE | 49 | self.status = (args.first ? args.first[:status] : nil) || Task::Status::ACTIVE |
@@ -237,6 +239,17 @@ class Task < ActiveRecord::Base | @@ -237,6 +239,17 @@ class Task < ActiveRecord::Base | ||
237 | end | 239 | end |
238 | end | 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 | scope :pending, :conditions => { :status => Task::Status::ACTIVE } | 253 | scope :pending, :conditions => { :status => Task::Status::ACTIVE } |
241 | scope :hidden, :conditions => { :status => Task::Status::HIDDEN } | 254 | scope :hidden, :conditions => { :status => Task::Status::HIDDEN } |
242 | scope :finished, :conditions => { :status => Task::Status::FINISHED } | 255 | scope :finished, :conditions => { :status => Task::Status::FINISHED } |
app/views/cms/_event.html.erb
@@ -14,10 +14,6 @@ | @@ -14,10 +14,6 @@ | ||
14 | 14 | ||
15 | <%= labelled_form_field(_('Presenter:'), text_field(:article, :presenter)) %> | 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 | <%= labelled_form_field(_('Event website:'), text_field(:article, :link)) %> | 17 | <%= labelled_form_field(_('Event website:'), text_field(:article, :link)) %> |
22 | 18 | ||
23 | <%= labelled_form_field(_('Address:'), text_field(:article, :address)) %> | 19 | <%= labelled_form_field(_('Address:'), text_field(:article, :address)) %> |
@@ -0,0 +1,31 @@ | @@ -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 %> |
@@ -0,0 +1,27 @@ | @@ -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/profile/send_mail.html.erb
@@ -4,6 +4,12 @@ | @@ -4,6 +4,12 @@ | ||
4 | 4 | ||
5 | <%= error_messages_for :mailing %> | 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 | <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> | 13 | <%= form_for :mailing, :url => {:action => 'send_mail'}, :html => {:id => 'mailing-form'} do |f| %> |
8 | 14 | ||
9 | <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> | 15 | <%= labelled_form_field(_('Subject:'), f.text_field(:subject)) %> |
app/views/profile_editor/index.html.erb
@@ -72,6 +72,8 @@ | @@ -72,6 +72,8 @@ | ||
72 | 72 | ||
73 | <%= control_panel_button(_('Edit welcome page'), 'welcome-page', :action => 'welcome_page') if has_welcome_page %> | 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 | <% @plugins.dispatch(:control_panel_buttons).each do |button| %> | 77 | <% @plugins.dispatch(:control_panel_buttons).each do |button| %> |
76 | <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %> | 78 | <%= control_panel_button(button[:title], button[:icon], button[:url], button[:html_options]) %> |
77 | <% end %> | 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 | <%= labelled_form_field(_('Rejection explanation'), f.text_area(:reject_explanation, :rows => 5)) %> | 7 | <%= labelled_form_field(_('Rejection explanation'), f.text_area(:reject_explanation, :rows => 5)) %> |
@@ -0,0 +1,14 @@ | @@ -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,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
db/migrate/20150615222147_alter_column_article_versions_end_date.rb
@@ -1,13 +0,0 @@ | @@ -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,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 | \ No newline at end of file | 0 | \ No newline at end of file |
plugins/virtuoso/Gemfile
public/javascripts/application.js
@@ -32,6 +32,7 @@ | @@ -32,6 +32,7 @@ | ||
32 | *= require block-store.js | 32 | *= require block-store.js |
33 | *= require jquery.typewatch.js | 33 | *= require jquery.typewatch.js |
34 | *= require require_login.js | 34 | *= require require_login.js |
35 | +*= require email_templates.js | ||
35 | */ | 36 | */ |
36 | 37 | ||
37 | // scope for noosfero stuff | 38 | // scope for noosfero stuff |
@@ -0,0 +1,10 @@ | @@ -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,6 +15,7 @@ | ||
15 | *= require chat | 15 | *= require chat |
16 | *= require search | 16 | *= require search |
17 | *= require block-store | 17 | *= require block-store |
18 | + *= require email-templates | ||
18 | */ | 19 | */ |
19 | 20 | ||
20 | /* browser fixes */ | 21 | /* browser fixes */ |
@@ -4657,6 +4658,9 @@ h1#agenda-title { | @@ -4657,6 +4658,9 @@ h1#agenda-title { | ||
4657 | .controller-profile_editor a.control-panel-design-editor { | 4658 | .controller-profile_editor a.control-panel-design-editor { |
4658 | background-image: url(../images/control-panel/preferences-desktop-wallpaper.png) | 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 | .controller-profile_editor .msie6 a.control-panel-design-editor { | 4664 | .controller-profile_editor .msie6 a.control-panel-design-editor { |
4661 | background-image: url(../images/control-panel/preferences-desktop-wallpaper.gif) | 4665 | background-image: url(../images/control-panel/preferences-desktop-wallpaper.gif) |
4662 | } | 4666 | } |
@@ -0,0 +1,18 @@ | @@ -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 | +} |
@@ -0,0 +1,68 @@ | @@ -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 < ActionController::TestCase | @@ -1471,6 +1471,29 @@ class ProfileControllerTest < ActionController::TestCase | ||
1471 | assert_redirected_to :action => 'members' | 1471 | assert_redirected_to :action => 'members' |
1472 | end | 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 | should 'show all fields to anonymous user' do | 1497 | should 'show all fields to anonymous user' do |
1475 | viewed = create_user('person_1').person | 1498 | viewed = create_user('person_1').person |
1476 | Environment.any_instance.stubs(:active_person_fields).returns(['sex', 'birth_date']) | 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 < ActionController::TestCase | @@ -626,6 +626,17 @@ class ProfileEditorControllerTest < ActionController::TestCase | ||
626 | assert_tag :tag => 'a', :attributes => { :href => '/myprofile/default_user/cms' } | 626 | assert_tag :tag => 'a', :attributes => { :href => '/myprofile/default_user/cms' } |
627 | end | 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 | should 'offer to create blog in control panel' do | 640 | should 'offer to create blog in control panel' do |
630 | get :index, :profile => profile.identifier | 641 | get :index, :profile => profile.identifier |
631 | assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/new?type=Blog" } | 642 | assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/new?type=Blog" } |
@@ -0,0 +1,22 @@ | @@ -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 < ActiveSupport::TestCase | @@ -166,6 +166,35 @@ class TaskMailerTest < ActiveSupport::TestCase | ||
166 | assert_match(/#{url_to_compare}/, mail.body.to_s) | 166 | assert_match(/#{url_to_compare}/, mail.body.to_s) |
167 | end | 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 | private | 198 | private |
170 | def read_fixture(action) | 199 | def read_fixture(action) |
171 | IO.readlines("#{FIXTURES_PATH}/task_mailer/#{action}") | 200 | IO.readlines("#{FIXTURES_PATH}/task_mailer/#{action}") |