Commit aa2a78b578427a64fe816c0c8c92f3c8086c14db

Authored by Daniela Feitosa
2 parents 7214021c 7e25eaaa

Merge commit 'refs/merge-requests/30' of git://gitorious.org/noosfero/noosfero i…

…nto merge-requests/30
Showing 49 changed files with 674 additions and 24 deletions   Show diff stats
app/controllers/admin/admin_panel_controller.rb
1 1 class AdminPanelController < AdminController
2 2  
3   - before_filter :login_required
4   -
5 3 protect 'view_environment_admin_panel', :environment
6 4  
7 5 def boxes_holder
... ...
app/controllers/admin/plugins_controller.rb
1 1 class PluginsController < AdminController
  2 + protect 'edit_environment_features', :environment
2 3  
3 4 def index
4 5 @active_plugins = Noosfero::Plugin.all.map {|plugin_name| plugin_name.constantize }.compact
... ...
app/controllers/admin_controller.rb
1 1 class AdminController < ApplicationController
2 2 require_ssl
  3 + before_filter :login_required
3 4 end
... ...
app/controllers/application.rb
... ... @@ -25,11 +25,6 @@ class ApplicationController &lt; ActionController::Base
25 25 helper :document
26 26 helper :language
27 27  
28   - def boxes_editor?
29   - false
30   - end
31   - protected :boxes_editor?
32   -
33 28 def self.no_design_blocks
34 29 @no_design_blocks = true
35 30 end
... ... @@ -106,6 +101,14 @@ class ApplicationController &lt; ActionController::Base
106 101  
107 102 protected
108 103  
  104 + def boxes_editor?
  105 + false
  106 + end
  107 +
  108 + def content_editor?
  109 + false
  110 + end
  111 +
109 112 def user
110 113 current_user.person if logged_in?
111 114 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -52,6 +52,9 @@ class CmsController &lt; MyProfileController
52 52 if @parent && @parent.blog?
53 53 articles -= Article.folder_types.map(&:constantize)
54 54 end
  55 + if user.is_admin?(profile.environment)
  56 + articles << RawHTMLArticle
  57 + end
55 58 articles
56 59 end
57 60  
... ... @@ -380,5 +383,9 @@ class CmsController &lt; MyProfileController
380 383 @selected_locale = @article.language || FastGettext.locale
381 384 end
382 385  
  386 + def content_editor?
  387 + true
  388 + end
  389 +
383 390 end
384 391  
... ...
app/controllers/my_profile/manage_products_controller.rb
... ... @@ -50,7 +50,7 @@ class ManageProductsController &lt; ApplicationController
50 50 render :partial => 'shared/redirect_via_javascript',
51 51 :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) }
52 52 else
53   - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' }
  53 + render_dialog_error_messages 'product'
54 54 end
55 55 end
56 56 end
... ... @@ -81,7 +81,7 @@ class ManageProductsController &lt; ApplicationController
81 81 render :partial => 'shared/redirect_via_javascript',
82 82 :locals => { :url => url_for(:controller => 'manage_products', :action => 'show', :id => @product) }
83 83 else
84   - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' }
  84 + render_dialog_error_messages 'product'
85 85 end
86 86 end
87 87 end
... ... @@ -96,7 +96,7 @@ class ManageProductsController &lt; ApplicationController
96 96 @inputs = @product.inputs
97 97 render :partial => 'display_inputs'
98 98 else
99   - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' }
  99 + render_dialog_error_messages 'product'
100 100 end
101 101 else
102 102 render :partial => 'add_input'
... ... @@ -147,7 +147,7 @@ class ManageProductsController &lt; ApplicationController
147 147 @inputs = @product.inputs
148 148 render :partial => 'display_inputs'
149 149 else
150   - render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'input' }
  150 + render_dialog_error_messages 'input'
151 151 end
152 152 end
153 153 end
... ...
app/helpers/application_helper.rb
... ... @@ -997,7 +997,10 @@ module ApplicationHelper
997 997 def article_to_html(article, options = {})
998 998 options.merge!(:page => params[:npage])
999 999 content = article.to_html(options)
1000   - return self.instance_eval(&content) if content.kind_of?(Proc)
  1000 + content = content.kind_of?(Proc) ? self.instance_eval(&content) : content
  1001 + @plugins && @plugins.enabled_plugins.each do |plugin|
  1002 + content = plugin.parse_content(content)
  1003 + end
1001 1004 content
1002 1005 end
1003 1006  
... ... @@ -1238,4 +1241,8 @@ module ApplicationHelper
1238 1241 end
1239 1242 end
1240 1243  
  1244 + def render_dialog_error_messages(instance_name)
  1245 + render :partial => 'shared/dialog_error_messages', :locals => { :object_name => instance_name }
  1246 + end
  1247 +
1241 1248 end
... ...
app/helpers/boxes_helper.rb
... ... @@ -99,7 +99,9 @@ module BoxesHelper
99 99 unless block.visible?
100 100 options[:title] = _("This block is invisible. Your visitors will not see it.")
101 101 end
102   -
  102 + @controller.send(:content_editor?) || @plugins.enabled_plugins.each do |plugin|
  103 + result = plugin.parse_content(result)
  104 + end
103 105 box_decorator.block_target(block.box, block) +
104 106 content_tag('div',
105 107 content_tag('div',
... ...
app/models/raw_html_article.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class RawHTMLArticle < TextArticle
  2 +
  3 + def self.short_description
  4 + _('Raw HTML text article.')
  5 + end
  6 +
  7 + def self.description
  8 + _('Allows HTML without filter (only for admins)')
  9 + end
  10 +
  11 + xss_terminate :only => [ ]
  12 +
  13 +end
... ...
app/views/cms/_raw_html_article.rhtml 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<%= required_fields_message %>
  2 +
  3 +<%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64')) %>
  4 +
  5 +<%= render :partial => 'translatable' %>
  6 +<%= render :partial => 'shared/lead_and_body' %>
... ...
app/views/manage_products/_edit_image.rhtml
... ... @@ -22,5 +22,5 @@
22 22 </script>
23 23  
24 24 <% if errors %>
25   - <%= render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } %>
  25 + <%= render_dialog_error_messages 'product' %>
26 26 <% end %>
... ...
app/views/manage_products/_edit_info.rhtml
1 1 <% if errors %>
2   - <%= render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } %>
  2 + <%= render_dialog_error_messages 'product' %>
3 3 <% end %>
4 4  
5 5 <% remote_form_for(@product,
... ...
app/views/manage_products/_edit_name.rhtml
... ... @@ -17,5 +17,5 @@
17 17 </script>
18 18  
19 19 <% if errors %>
20   - <%= render :partial => 'shared/dialog_error_messages', :locals => { :object_name => 'product' } %>
  20 + <%= render_dialog_error_messages 'product' %>
21 21 <% end %>
... ...
app/views/plugins/index.rhtml
... ... @@ -12,7 +12,7 @@
12 12 <%= hidden_field_tag('environment[enabled_plugins][]', '') %>
13 13 <% @active_plugins.each do |plugin| %>
14 14 <tr>
15   - <td><%= plugin.plugin_name %></td>
  15 + <td><%= plugin.has_admin_url? ? link_to(plugin.plugin_name, plugin.admin_url) : plugin.plugin_name %></td>
16 16 <td><%= plugin.plugin_description %></td>
17 17 <td><%= check_box_tag "environment[enabled_plugins][]", plugin, @environment.enabled_plugins.include?(plugin.to_s), :id => plugin.plugin_name %></td>
18 18 </tr>
... ...
config/cucumber.yml
1   -default: --tags ~@selenium,~@wip --exclude features/support/selenium.rb --exclude features/step_definitions/selenium_steps.rb
2   -selenium: --tags @selenium,~@wip
  1 +default: --tags ~@selenium,~@wip --exclude features/support/selenium.rb --exclude features/step_definitions/selenium_steps.rb -r features/support -r features/step_definitions
  2 +selenium: --tags @selenium,~@wip -r features/support -r features/step_definitions
... ...
doc/noosfero/plugins/index.textile 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +h1. Plugins
  2 +
... ...
features/plugins.feature
... ... @@ -56,4 +56,3 @@ Feature: plugins
56 56 Then I should not see "Test plugin button"
57 57 When I go to the profile
58 58 Then I should not see "Test plugin tab"
59   -
... ...
features/send_email_to_environment_members.feature
... ... @@ -5,7 +5,7 @@ Feature: send emails to environment members users
5 5 Scenario: Cant access if not logged in
6 6 Given I am not logged in
7 7 When I go to /admin/users/send_mail
8   - Then I should see "Access denied"
  8 + Then I should be on login page
9 9  
10 10 Scenario: Cant access as normal user
11 11 Given the following user
... ...
lib/noosfero/i18n.rb
... ... @@ -71,7 +71,9 @@ module ActionView::Helpers::ActiveRecordHelper
71 71 end
72 72 end
73 73  
74   - if options[:message_title]
  74 + if options[:header_message]
  75 + header_message = options[:header_message]
  76 + elsif options[:message_title]
75 77 header_message = instance.error_message(options[:message_title], count) % {:num => count, :record => record}
76 78 else
77 79 header_message = ((count == 1) ? _(@error_message_title[0]) : _(@error_message_title[1])) % {:num => count, :record => record}
... ...
lib/noosfero/plugin.rb
... ... @@ -52,6 +52,13 @@ class Noosfero::Plugin
52 52 _("No description informed.")
53 53 end
54 54  
  55 + def admin_url
  56 + {:controller => "#{name.underscore}_admin", :action => 'index'}
  57 + end
  58 +
  59 + def has_admin_url?
  60 + File.exists?(File.join(root_path, 'controllers', "#{name.underscore}_admin_controller.rb"))
  61 + end
55 62 end
56 63  
57 64 def expanded_template(file_path, locals = {})
... ... @@ -121,4 +128,10 @@ class Noosfero::Plugin
121 128 []
122 129 end
123 130  
  131 + # -> Parse and possibly make changes of content (article, block, etc) during HTML rendering
  132 + # returns = content as string after parser and changes
  133 + def parse_content(raw_content)
  134 + raw_content
  135 + end
  136 +
124 137 end
... ...
lib/tasks/doc.rake
1 1 namespace :noosfero do
2 2 namespace :doc do
  3 + Dir.glob('plugins/**/doc/*.textile').each do |file|
  4 + ln_sf File.join(RAILS_ROOT, file), 'doc/noosfero/plugins/'
  5 + end
3 6 input = Dir.glob('doc/noosfero/**/*.textile')
4 7 topics_xhtml = input.map { |item| item.sub('.textile', '.en.xhtml') }
5 8 sections = Dir.glob('doc/noosfero/*').select {|item| File.directory?(item) }
... ...
plugins/send_email/controllers/send_email_plugin_admin_controller.rb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +class SendEmailPluginAdminController < PluginsController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def index
  5 + @environment = environment
  6 + if request.post?
  7 + if environment.update_attributes(params[:environment])
  8 + session[:notice] = _('Configurations was saved')
  9 + redirect_to :controller => 'plugins'
  10 + else
  11 + session[:notice] = _('Configurations could not be saved')
  12 + end
  13 + end
  14 + end
  15 +
  16 +end
... ...
plugins/send_email/controllers/send_email_plugin_base_controller.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +module SendEmailPluginBaseController
  2 + def deliver
  3 + if request.post?
  4 + @context_url = profile ? profile.url : {:host => environment.default_hostname, :controller => 'home'}
  5 + @mail = SendEmailPlugin::Mail.new(
  6 + :from => environment.contact_email,
  7 + :to => params[:to],
  8 + :message => params[:message],
  9 + :environment => environment,
  10 + :params => params.dup
  11 + )
  12 + @mail.subject = params[:subject] unless params[:subject].blank?
  13 + if @mail.valid?
  14 + SendEmailPlugin::Sender.deliver_mail(request.referer, @context_url, @mail)
  15 + if request.xhr?
  16 + render :text => _('Message sent')
  17 + else
  18 + render :action => 'success'
  19 + end
  20 + else
  21 + if request.xhr?
  22 + render_dialog_error_messages :mail
  23 + else
  24 + render :action => 'fail'
  25 + end
  26 + end
  27 + else
  28 + render_access_denied
  29 + end
  30 + end
  31 +end
... ...
plugins/send_email/controllers/send_email_plugin_environment_controller.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +class SendEmailPluginEnvironmentController < ApplicationController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 + include SendEmailPluginBaseController
  4 +end
... ...
plugins/send_email/controllers/send_email_plugin_profile_controller.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +class SendEmailPluginProfileController < ProfileController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 + include SendEmailPluginBaseController
  4 +end
... ...
plugins/send_email/db/migrate/20110804180047_add_send_email_plugin_config_to_environment.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddSendEmailPluginConfigToEnvironment < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :environments, :send_email_plugin_allow_to, :text
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :environments, :send_email_plugin_allow_to
  8 + end
  9 +end
... ...
plugins/send_email/doc/send_email.textile 0 → 100644
... ... @@ -0,0 +1,61 @@
  1 +h1. SendEmailPlugin
  2 +
  3 +Allows to send e-mails through an e-mail form.
  4 +
  5 +h2. Usage
  6 +
  7 +* Create a HTML form using RawHTMLBlock or RawHTMLArticle that invokes the {sendemail} action
  8 +* Add a "to" and "message" field and a submit button
  9 +* Make sure to fill in allowed 'to' addresses in plugin settings
  10 +
  11 +h2. HTML form
  12 +
  13 +h3. Form action
  14 +
  15 +You should use {sendemail} macro as form action, it will be expanded as:
  16 +
  17 +* */profile/&lt;identifier&gt;/plugins/send_email/deliver* in profile context
  18 +* */plugin/send_email/deliver* in environment context
  19 +
  20 +h3. 'Subject' field
  21 +
  22 +Subject of message.
  23 +
  24 +(default: 'New mail')
  25 +
  26 +h3. 'Message' field
  27 +
  28 +Body of message.
  29 +
  30 +(required)
  31 +
  32 +h3. 'To' field
  33 +
  34 +Target address. Accepts multiple addresses separated by comma.
  35 +
  36 +(required)
  37 +
  38 +h3. extra fields
  39 +
  40 +Each other params in HTML form will compose message body in a format "key: value"
  41 +
  42 +h2. Options
  43 +
  44 +h3. Using ajax
  45 +
  46 +Ajax is supported using #ajax-form as id of HTML form.
  47 +
  48 +Example:
  49 +
  50 +<pre>
  51 +<form action='{sendemail}' id='ajax-form'>
  52 + <input type='text' name='to'/>
  53 + <input type='text' name='subject'/>
  54 + <input type='text' name='message'/>
  55 + <input type='subject'/>
  56 +</form>
  57 +</pre>
  58 +
  59 +h2. Info
  60 +
  61 +This plugin was inspired by "Foswiki SendEmailPlugin":http://foswiki.org/Extensions/SendEmailPlugin
... ...
plugins/send_email/lib/send_email_plugin.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +class SendEmailPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "SendEmailPlugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that allows sending e-mails via HTML forms.")
  9 + end
  10 +
  11 + def stylesheet?
  12 + true
  13 + end
  14 +
  15 + def parse_content(raw_content)
  16 + if context.profile
  17 + raw_content.gsub(/\{sendemail\}/, "/profile/#{context.profile.identifier}/plugins/send_email/deliver")
  18 + else
  19 + raw_content.gsub(/\{sendemail\}/, '/plugin/send_email/deliver')
  20 + end
  21 + end
  22 +
  23 +end
... ...
plugins/send_email/lib/send_email_plugin/mail.rb 0 → 100644
... ... @@ -0,0 +1,42 @@
  1 +class SendEmailPlugin::Mail < ActiveRecord::Base #WithoutTable
  2 +
  3 + N_('Subject'); N_('Message'); N_('To'); N_('From')
  4 + tableless :columns => [
  5 + [:from, :string],
  6 + [:to, :string],
  7 + [:subject, :string, _('New mail')],
  8 + [:message, :string],
  9 + [:params, :hash, {}],
  10 + ]
  11 + attr_accessor :environment
  12 +
  13 + validates_presence_of :environment
  14 + validates_presence_of :to, :message
  15 +
  16 + def validate
  17 + if to_as_list.any? do |value|
  18 + if value !~ Noosfero::Constants::EMAIL_FORMAT
  19 + self.errors.add(:to, _("%{fn} '%s' isn't a valid e-mail address") % value)
  20 + end
  21 + end
  22 + else
  23 + allowed_emails = environment ? environment.send_email_plugin_allow_to.to_s.gsub(/\s+/, '').split(/,/) : []
  24 + if to_as_list.any? do |value|
  25 + if !allowed_emails.include?(value)
  26 + self.errors.add(:to, _("%{fn} '%s' address is not allowed (see SendEmailPlugin config)") % value)
  27 + end
  28 + end
  29 + end
  30 + end
  31 + end
  32 +
  33 + def params=(value = {})
  34 + [:action, :controller, :to, :message, :subject, :from].each{|k| value.delete(k)}
  35 + self[:params] = value
  36 + end
  37 +
  38 + def to_as_list
  39 + to && to.split(/,/) || []
  40 + end
  41 +
  42 +end
... ...
plugins/send_email/lib/send_email_plugin/sender.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class SendEmailPlugin::Sender < Noosfero::Plugin::MailerBase
  2 + prepend_view_path(SendEmailPlugin.root_path+'/views')
  3 +
  4 + def mail(referer, url, mail)
  5 + recipients mail.to
  6 + from mail.from
  7 + subject "[#{mail.environment.name}] #{mail.subject}"
  8 + body :message => mail.message,
  9 + :referer => referer,
  10 + :context_url => url,
  11 + :params => mail.params
  12 + end
  13 +end
... ...
plugins/send_email/public/style.css 0 → 100644
... ... @@ -0,0 +1,22 @@
  1 +.sendemail-plugin-message-sent {
  2 + width: 100%;
  3 + background-color: #F0F0F0;
  4 + border: 1px solid #CFCFCF;
  5 +}
  6 +.sendemail-plugin-message-sent td {
  7 + border: 0;
  8 +}
  9 +.sendemail-plugin-message-sent tr:hover,
  10 +.sendemail-plugin-message-sent td:hover,
  11 +.sendemail-plugin-message-sent tr:hover td {
  12 + background-color: auto;
  13 +}
  14 +.sendemail-plugin-message-sent pre {
  15 + margin: 0 auto;
  16 +}
  17 +.sendemail-plugin-message-sent td {
  18 + vertical-align: top;
  19 +}
  20 +.sendemail-plugin-message-sent .value {
  21 + width: 100%;
  22 +}
... ...
plugins/send_email/test/features/send_email_plugin.feature 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +Feature: send_email_plugin
  2 +
  3 + Background:
  4 + Given the following users
  5 + | login | name |
  6 + | joaosilva | Joao Silva |
  7 + And I am logged in as "joaosilva"
  8 +
  9 + Scenario: expand macro in article content
  10 + Given plugin SendEmailPlugin is enabled on environment
  11 + And the following articles
  12 + | owner | name | body |
  13 + | joaosilva | sample-article | URL path to {sendemail} action |
  14 + When I go to /joaosilva/sample-article
  15 + Then I should see "URL path to /profile/joaosilva/plugins/send_email/deliver action"
  16 +
  17 + Scenario: expand macro in block content
  18 + Given plugin SendEmailPlugin is enabled on environment
  19 + And the following blocks
  20 + | owner | type | html |
  21 + | joaosilva | RawHTMLBlock | URL path to {sendemail} action |
  22 + When I go to Joao Silva's homepage
  23 + Then I should see "URL path to /profile/joaosilva/plugins/send_email/deliver action"
  24 +
  25 + Scenario: as admin I can configure plugin
  26 + Given I am logged in as admin
  27 + When I go to the environment control panel
  28 + And I follow "Enable/disable plugins"
  29 + Then I should see "SendEmailPlugin" linking to "/admin/plugin/send_email"
  30 +
  31 + Scenario: configure plugin to allow emails to john@example.com
  32 + Given I am logged in as admin
  33 + And I go to the environment control panel
  34 + And I follow "Enable/disable plugins"
  35 + When I follow "SendEmailPlugin"
  36 + Then I should not see "john@example.com"
  37 + When I fill in "E-Mail addresses you want to allow to send" with "john@example.com"
  38 + And I press "Save"
  39 + Then I should be on /admin/plugins
  40 + When I follow "SendEmailPlugin"
  41 + Then I should see "john@example.com"
... ...
plugins/send_email/test/functional/send_email_plugin_admin_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/send_email_plugin_admin_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class SendEmailPluginAdminController; def rescue_action(e) raise e end; end
  6 +
  7 +class SendEmailPluginAdminControllerTest < Test::Unit::TestCase
  8 +
  9 + def setup
  10 + @controller = SendEmailPluginAdminController.new
  11 + @request = ActionController::TestRequest.new
  12 + @response = ActionController::TestResponse.new
  13 + @admin = create_user('adminplug').person
  14 + @environment = @admin.environment
  15 + @environment.add_admin(@admin)
  16 + end
  17 +
  18 + should 'deny access to guests and redirect to login' do
  19 + get :index
  20 + assert_response :redirect
  21 + assert_redirected_to :controller => 'account', :action => 'login'
  22 + end
  23 +
  24 + should 'allow access to admin' do
  25 + login_as @admin.identifier
  26 + get :index
  27 + assert_response :success
  28 + end
  29 +
  30 + should 'deny access to ordinary users' do
  31 + @user = create_user('normaluser').person
  32 + login_as @user.identifier
  33 + get :index
  34 + assert_response 403
  35 + end
  36 +
  37 +end
... ...
plugins/send_email/test/functional/send_email_plugin_base_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,81 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/send_email_plugin_profile_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class SendEmailPluginProfileController; def rescue_action(e) raise e end; end
  6 +
  7 +def run_common_tests
  8 + should 'not deliver emails via GET requests' do
  9 + get :deliver, @extra_args
  10 + assert_response 403 # forbidden
  11 + end
  12 +
  13 + should 'deliver emails only via POST requests' do
  14 + post :deliver, @extra_args
  15 + assert_response :success
  16 + end
  17 +
  18 + should 'render fail template if could not deliver mail' do
  19 + post :deliver, @extra_args
  20 + assert_template 'fail'
  21 + end
  22 +
  23 + should 'render success template after deliver mail' do
  24 + SendEmailPlugin::Mail.any_instance.stubs(:valid?).returns(true)
  25 + post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john')
  26 + assert_template 'success'
  27 + end
  28 +
  29 + should 'render dialog error if could not deliver mail by ajax request' do
  30 + xhr :post, :deliver, @extra_args
  31 + assert_template '_dialog_error_messages'
  32 + end
  33 +
  34 + should 'render success message after deliver mail by ajax request' do
  35 + SendEmailPlugin::Mail.any_instance.stubs(:valid?).returns(true)
  36 + xhr :post, :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john')
  37 + assert_equal 'Message sent', @response.body
  38 + end
  39 +
  40 + should 'deliver mail' do
  41 + Environment.any_instance.stubs(:send_email_plugin_allow_to).returns('john@example.com')
  42 + assert_difference ActionMailer::Base.deliveries, :size do
  43 + post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john')
  44 + end
  45 + end
  46 +
  47 + should 'deliver mail with nondefault subject' do
  48 + Environment.any_instance.stubs(:send_email_plugin_allow_to).returns('john@example.com')
  49 + post :deliver, @extra_args.merge(:to => 'john@example.com', :message => 'Hi john', :subject => 'Hello john')
  50 + assert_equal '[Colivre.net] Hello john', ActionMailer::Base.deliveries.first.subject
  51 + end
  52 +end
  53 +
  54 +class SendEmailPluginProfileControllerTest < Test::Unit::TestCase
  55 + def setup
  56 + @controller = SendEmailPluginProfileController.new
  57 + @request = ActionController::TestRequest.new
  58 + @response = ActionController::TestResponse.new
  59 + ActionMailer::Base.delivery_method = :test
  60 + ActionMailer::Base.perform_deliveries = true
  61 + ActionMailer::Base.deliveries = []
  62 + community = fast_create(Community)
  63 + @extra_args = {:profile => community.identifier}
  64 + end
  65 +
  66 + run_common_tests()
  67 +end
  68 +
  69 +class SendEmailPluginEnvironmentControllerTest < Test::Unit::TestCase
  70 + def setup
  71 + @controller = SendEmailPluginEnvironmentController.new
  72 + @request = ActionController::TestRequest.new
  73 + @response = ActionController::TestResponse.new
  74 + ActionMailer::Base.delivery_method = :test
  75 + ActionMailer::Base.perform_deliveries = true
  76 + ActionMailer::Base.deliveries = []
  77 + @extra_args = {}
  78 + end
  79 +
  80 + run_common_tests()
  81 +end
... ...
plugins/send_email/test/unit/send_email_plugin_mail_test.rb 0 → 100644
... ... @@ -0,0 +1,63 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class SendEmailPluginMailTest < Test::Unit::TestCase
  4 +
  5 + def setup
  6 + @environment = mock()
  7 + @environment.stubs(:send_email_plugin_allow_to).returns('john@example.com, someone@example.com, someother@example.com')
  8 + end
  9 +
  10 + should 'instance a valid object with fields to be fired in mail' do
  11 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'john@example.com', :environment => @environment)
  12 + assert mail.valid?
  13 + end
  14 +
  15 + should 'requires to field' do
  16 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :environment => @environment)
  17 + assert !mail.valid?
  18 + end
  19 +
  20 + should 'require message field' do
  21 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :to => 'john@example.com', :environment => @environment)
  22 + assert !mail.valid?
  23 + end
  24 +
  25 + should 'require environment field' do
  26 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :to => 'john@example.com', :message => 'Hi john')
  27 + assert !mail.valid?
  28 + end
  29 +
  30 + should 'have a default subject' do
  31 + mail = SendEmailPlugin::Mail.new
  32 + assert_equal 'New mail', mail.subject
  33 + end
  34 +
  35 + should 'not accept invalid email address' do
  36 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'invalid-mail-address', :environment => @environment)
  37 + assert !mail.valid?
  38 + end
  39 +
  40 + should 'not accept email that is not in allowed address list' do
  41 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'unknow@example.com', :environment => @environment)
  42 + assert !mail.valid?
  43 + end
  44 +
  45 + should 'discard some keys on set params hash' do
  46 + mail = SendEmailPlugin::Mail.new(:params => {:action => 1, :controller => 2, :to => 3, :message => 4, :subject => 5, :age => 6})
  47 + [:action, :controller, :to, :message, :subject].each do |k|
  48 + assert !mail.params.include?(k)
  49 + end
  50 + assert mail.params.include?(:age)
  51 + end
  52 +
  53 + should "accept multiple 'to' emails" do
  54 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'john@example.com,someother@example.com', :environment => @environment)
  55 + assert mail.valid?
  56 + end
  57 +
  58 + should "invalid if just one listed in 'to' list was not allowed" do
  59 + mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'john@example.com,notallowed@example.com,someother@example.com', :environment => @environment)
  60 + assert !mail.valid?
  61 + end
  62 +
  63 +end
... ...
plugins/send_email/test/unit/send_email_plugin_sender_test.rb 0 → 100644
... ... @@ -0,0 +1,35 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class SendEmailPluginSenderTest < Test::Unit::TestCase
  4 +
  5 + def setup
  6 + ActionMailer::Base.delivery_method = :test
  7 + ActionMailer::Base.perform_deliveries = true
  8 + ActionMailer::Base.deliveries = []
  9 + @environment = mock()
  10 + @environment.stubs(:contact_email).returns('noreply@localhost')
  11 + @environment.stubs(:default_hostname).returns('localhost')
  12 + @environment.stubs(:name).returns('Noosfero')
  13 + @environment.stubs(:send_email_plugin_allow_to).returns('john@example.com, someone@example.com, someother@example.com')
  14 + @mail = SendEmailPlugin::Mail.new(:subject => 'Hi', :message => 'Hi john', :to => 'john@example.com', :from => 'noreply@localhost', :environment => @environment)
  15 + end
  16 +
  17 + should 'be able to deliver mail' do
  18 + response = SendEmailPlugin::Sender.deliver_mail("http://localhost/contact", 'http//profile', @mail)
  19 + assert_equal 'noreply@localhost', response.from.to_s
  20 + assert_equal "[Noosfero] #{@mail.subject}", response.subject
  21 + end
  22 +
  23 + should 'deliver mail to john@example.com' do
  24 + response = SendEmailPlugin::Sender.deliver_mail("http://localhost/contact", 'http//profile', @mail)
  25 + assert_equal ['john@example.com'], response.to
  26 + end
  27 +
  28 + should 'add each key value pair to message body' do
  29 + @mail.params = {:param1 => 'value1', :param2 => 'value2'}
  30 + response = SendEmailPlugin::Sender.deliver_mail("http://localhost/contact", 'http//profile', @mail)
  31 + assert_match /param1.+value1/m, response.body
  32 + assert_match /param2.+value2/m, response.body
  33 + end
  34 +
  35 +end
... ...
plugins/send_email/test/unit/send_email_plugin_test.rb 0 → 100644
... ... @@ -0,0 +1,29 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +
  3 +class SendEmailPluginTest < Test::Unit::TestCase
  4 +
  5 + def setup
  6 + @plugin = SendEmailPlugin.new
  7 + @context = mock()
  8 + @plugin.context = @context
  9 + end
  10 +
  11 + should 'return true to stylesheet?' do
  12 + assert @plugin.stylesheet?
  13 + end
  14 +
  15 + should 'have admin controller' do
  16 + assert SendEmailPlugin.has_admin_url?
  17 + end
  18 +
  19 + should 'expand macro in parse_content event' do
  20 + @plugin.context.stubs(:profile).returns(nil)
  21 + assert_match /plugin\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}")
  22 + end
  23 +
  24 + should 'expand macro in parse_content event on profile context' do
  25 + @plugin.context.stubs(:profile).returns(fast_create(Community))
  26 + assert_match /profile\/#{@plugin.context.profile.identifier}\/plugins\/send_email\/deliver/, @plugin.parse_content("expand this macro {sendemail}")
  27 + end
  28 +
  29 +end
... ...
plugins/send_email/views/send_email_plugin/sender/mail.rhtml 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<%= _('Contact from %s') % @referer %>
  2 +
  3 +<%= word_wrap(@message || @mail.message) %>
  4 +<% (@params || @mail.params).each_pair do |key, value| %>
  5 +<%= key %>: <%= word_wrap(value) %>
  6 +<% end %>
  7 +---
  8 +<%= url_for @context_url %>
... ...
plugins/send_email/views/send_email_plugin_admin/index.rhtml 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +<h1><%= _("SendEmailPlugin's config") %></h1>
  2 +
  3 +<% form_for :environment, :url => {:action => 'index'}, :html => {:method => 'post'} do |f| %>
  4 + <%= labelled_form_field(_("E-Mail addresses you want to allow to send"), f.text_area(:send_email_plugin_allow_to, :rows => 8)) %>
  5 + <small><%= _('(list of email addresses separated by comma)') %></small>
  6 + <% button_bar do %>
  7 + <%= submit_button 'save', _('Save'), :cancel => {:controller => 'plugins'} %>
  8 + <% end %>
  9 +<% end %>
... ...
plugins/send_email/views/send_email_plugin_base/fail.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<%= error_messages_for 'mail', :header_message => _('The message could not be sent') %>
  2 +
  3 +<%= button :back, _('Back'), :back %>
... ...
plugins/send_email/views/send_email_plugin_base/success.rhtml 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<h2><%= _('Message sent') %></h2>
  2 +
  3 +<table class='sendemail-plugin-message-sent'>
  4 + <tr><td class='label'><strong><%= _('Subject') %>:</strong></td><td class='value'><em><%=h @mail.subject %></em></td></tr>
  5 + <tr><td class='label'><strong><%= _('Message') %>:</strong></td><td class='value'><pre><%=h render :file => 'send_email_plugin/sender/mail' %></pre></td></tr>
  6 +</table>
  7 +
  8 +<p><%= button :back, _('Back'), :back %></p>
... ...
plugins/send_email/views/send_email_plugin_environment 0 → 120000
... ... @@ -0,0 +1 @@
  1 +send_email_plugin_base
0 2 \ No newline at end of file
... ...
plugins/send_email/views/send_email_plugin_profile 0 → 120000
... ... @@ -0,0 +1 @@
  1 +send_email_plugin_base
0 2 \ No newline at end of file
... ...
public/javascripts/application.js
... ... @@ -677,3 +677,18 @@ function original_image_dimensions(src) {
677 677 img.src = src;
678 678 return { 'width' : img.width, 'height' : img.height };
679 679 }
  680 +
  681 +jQuery(function() {
  682 + jQuery("#ajax-form").before("<div id='ajax-form-loading-area' style='display:block;width:16px;height:16px;'></div>");
  683 + jQuery("#ajax-form").before("<div id='ajax-form-message-area'></div>");
  684 + jQuery("#ajax-form").ajaxForm({
  685 + beforeSubmit: function(a,f,o) {
  686 + jQuery('#ajax-form-message-area').html('');
  687 + o.loading = small_loading('ajax-form-loading-area');
  688 + },
  689 + success: function() {
  690 + loading_done('ajax-form-loading-area');
  691 + },
  692 + target: "#ajax-form-message-area"
  693 + })
  694 +});
... ...
test/functional/admin_controller_test.rb
... ... @@ -25,6 +25,7 @@ class AdminControllerTest &lt; Test::Unit::TestCase
25 25 end
26 26  
27 27 should 'detect ssl' do
  28 + login_as 'ze'
28 29 @request.expects(:ssl?).returns(true).at_least_once
29 30 get :index
30 31 assert_response :success
... ...
test/functional/cms_controller_test.rb
... ... @@ -16,6 +16,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
16 16  
17 17 @profile = create_user_with_permission('testinguser', 'post_content')
18 18 login_as :testinguser
  19 + @controller.stubs(:user).returns(@profile)
19 20 end
20 21  
21 22 attr_reader :profile
... ... @@ -614,7 +615,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
614 615 end
615 616  
616 617 should 'not make enterprise homepage available to person' do
617   - @controller.stubs(:profile).returns(create_user('test_user').person)
  618 + @controller.stubs(:profile).returns(profile)
618 619 assert_not_includes @controller.available_article_types, EnterpriseHomepage
619 620 end
620 621  
... ... @@ -1278,6 +1279,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1278 1279 c = Community.create!(:name => 'test_comm', :identifier => 'test_comm')
1279 1280 u = create_user_with_permission('test_user', 'publish_content', c)
1280 1281 login_as :test_user
  1282 + @controller.stubs(:user).returns(u)
1281 1283  
1282 1284 get :new, :profile => c.identifier, :type => 'TinyMceArticle'
1283 1285 assert_response :success
... ... @@ -1311,6 +1313,7 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1311 1313 u = create_user_with_permission('test_user', 'publish_content', c)
1312 1314 a = c.articles.create!(:name => 'test_article', :last_changed_by => u)
1313 1315 login_as :test_user
  1316 + @controller.stubs(:user).returns(u)
1314 1317  
1315 1318 get :edit, :profile => c.identifier, :id => a.id
1316 1319  
... ... @@ -1618,4 +1621,11 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1618 1621 end
1619 1622 end
1620 1623  
  1624 + should 'make RawHTMLArticle available only to environment admins' do
  1625 + @controller.stubs(:profile).returns(profile)
  1626 + assert_not_includes @controller.available_article_types, RawHTMLArticle
  1627 + profile.environment.add_admin(profile)
  1628 + assert_includes @controller.available_article_types, RawHTMLArticle
  1629 + end
  1630 +
1621 1631 end
... ...
test/functional/users_controller_test.rb
... ... @@ -15,6 +15,8 @@ class UsersControllerTest &lt; Test::Unit::TestCase
15 15 end
16 16  
17 17 should 'not access without right permission' do
  18 + create_user('guest')
  19 + login_as 'guest'
18 20 get :index
19 21 assert_response 403 # forbidden
20 22 end
... ...
test/unit/plugin_test.rb
... ... @@ -18,6 +18,12 @@ class PluginTest &lt; Test::Unit::TestCase
18 18 assert_includes Noosfero::Plugin.all, Plugin1.to_s
19 19 end
20 20  
21   -end
  21 + should 'returns url to plugin management if plugin has admin_controller' do
  22 + class Plugin1 < Noosfero::Plugin
  23 + end
  24 + File.stubs(:exists?).with(anything).returns(true)
22 25  
  26 + assert_equal({:controller => 'plugin_test/plugin1_admin', :action => 'index'}, Plugin1.admin_url)
  27 + end
23 28  
  29 +end
... ...
test/unit/raw_html_article_test.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class RawHTMLArticleTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @profile = create_user('testing').person
  7 + end
  8 +
  9 + should 'not filter HTML' do
  10 + article = RawHTMLArticle.create!(
  11 + :name => 'Raw HTML',
  12 + :body => '<strong>HTML!</strong><form action="#"></form>',
  13 + :profile => @profile
  14 + )
  15 + assert_equal '<strong>HTML!</strong><form action="#"></form>', article.body
  16 + end
  17 +
  18 +end
... ...