Commit 946bd81026a5103e75454301a0118840015a5d4c

Authored by Joenio Costa
1 parent f0141cef

ActionItem791: 'contact us' feature for enterprises

    users can send message to enterprises
    the enterprise must choose if 'contact us' is available or not
app/controllers/public/contact_controller.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +class ContactController < PublicController
  2 +
  3 + needs_profile
  4 +
  5 + def new
  6 + @contact = Contact.new(params[:contact])
  7 + if request.post?
  8 + if @contact.save
  9 + flash[:notice] = _('Contact successfully sent')
  10 + redirect_to :controller => 'profile', :profile => profile.identifier
  11 + else
  12 + flash[:notice] = _('Contact not sent')
  13 + end
  14 + end
  15 + end
  16 +
  17 +end
... ...
app/helpers/contact_helper.rb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +module ContactHelper
  2 +end
... ...
app/models/contact.rb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +class Contact < Task
  2 +
  3 + validates_presence_of :target_id, :subject, :email, :message
  4 + validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT
  5 +
  6 + acts_as_having_settings :field => :data
  7 + settings_items :subject, :message, :city_and_state, :email, :phone
  8 +
  9 + def description
  10 + _('%s sent a new message') % (requestor ? requestor.name : _('Someone'))
  11 + end
  12 +
  13 +end
... ...
app/models/enterprise.rb
... ... @@ -57,7 +57,6 @@ class Enterprise &lt; Organization
57 57 end
58 58 end
59 59  
60   -
61 60 def default_set_of_blocks
62 61 blocks = [
63 62 [MainBlock],
... ... @@ -74,6 +73,8 @@ class Enterprise &lt; Organization
74 73 environment.enterprise_template
75 74 end
76 75  
  76 + settings_items :enable_contact_us, :type => :boolean, :default => true
  77 +
77 78 protected
78 79  
79 80 def default_homepage(attrs)
... ...
app/views/blocks/profile_info_actions/enterprise.rhtml
... ... @@ -9,4 +9,7 @@
9 9 <li><%= link_to content_tag('span', _('Join')), { :profile => user.identifier, :controller => 'memberships', :action => 'join', :id => profile.id }, :class => 'button with-text icon-add', :title => __('Join this enterprise') %></li>
10 10 <% end %>
11 11 <% end %>
  12 + <% if profile.enable_contact_us %>
  13 + <li> <%= link_to content_tag('span', _('Contact us')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li>
  14 + <% end %>
12 15 </ul>
... ...
app/views/contact/new.rhtml 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +<h1><%= _('Contact %s') % profile.name %></h1>
  2 +
  3 +<%= error_messages_for 'contact' %>
  4 +
  5 +<% labelled_form_for :contact, @contact do |f| %>
  6 +
  7 + <%= hidden_field_tag 'contact[target_id]', profile.id %>
  8 + <%= hidden_field_tag 'contact[requestor_id]', (logged_in? ? current_user.person.id : nil) %>
  9 + <%= f.text_field :subject %>
  10 + <%= f.text_field :email %>
  11 + <%= f.text_field :city_and_state %>
  12 + <%= f.text_field :phone %>
  13 + <%= f.text_area :message, :rows => 5 %>
  14 +
  15 + <%= submit_button(:send, _('Send')) %>
  16 +
  17 +<% end %>
... ...
app/views/profile_editor/_organization.rhtml
... ... @@ -9,12 +9,13 @@
9 9  
10 10 </div>
11 11 <%= f.text_field(:acronym) %>
12   - <%= f.text_field(:address, 'size' => 50) if @profile.kind_of?(Enterprise) %>
  12 + <%= f.text_field(:address, 'size' => 50) if @profile.enterprise? %>
13 13 <%= f.text_field(:foundation_year) %>
14 14 <%= f.text_field(:contact_person) %>
15 15 <%= f.text_field(:contact_email) %>
16 16 <%= f.text_field(:economic_activity) %>
17   - <%= f.text_area(:description, :rows => 5) if @profile.kind_of?(Community) %>
  17 + <%= f.text_area(:description, :rows => 5) if @profile.community? %>
  18 + <%= f.check_box(:enable_contact_us) if @profile.enterprise? %>
18 19 <h1><%= _('Moderation options') %></h1>
19 20 <div style='margin-bottom: 1em'>
20 21 <%= _('New members must be approved:')%>
... ...
app/views/tasks/_contact.rhtml 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +<h2><%= task.description %></h2>
  2 +
  3 +<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %>
  4 +
  5 + <%= hidden_field_tag(:decision, :finish) %>
  6 + <table>
  7 + <% %w[ subject email phone city_and_state message ].each do |field| %>
  8 + <% if task.respond_to?(field) and !task.send(field).nil? and !task.send(field).empty? %>
  9 + <tr> <td><strong><%= _(field.humanize) %></strong></td> <td><%= task.send(field) %></td> </tr>
  10 + <% end %>
  11 + <% end %>
  12 + </table>
  13 +
  14 + <% button_bar do %>
  15 + <%= submit_button(:ok, _('Ok!')) %>
  16 + <% end %>
  17 +
  18 +<% end %>
... ...
config/routes.rb
... ... @@ -53,6 +53,9 @@ ActionController::Routing::Routes.draw do |map|
53 53 map.catalog 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/
54 54 map.product 'catalog/:profile/:id', :controller => 'catalog', :action => 'show', :profile => /#{Noosfero.identifier_format}/
55 55  
  56 + # contact
  57 + map.contact 'contact/:profile/:action/:id', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/
  58 +
56 59 ######################################################
57 60 ## Controllers that are profile-specific (for profile admins )
58 61 ######################################################
... ...
public/designs/icons/default/style.css
... ... @@ -5,6 +5,7 @@
5 5 .icon-open { background-image: url(folder-open.gif) }
6 6 .icon-cms { background-image: url(abiword_48.png) }
7 7 .icon-save { background-image: url(save-HC.gif) }
  8 +.icon-send { background-image: url(mail-HC.gif) }
8 9 .icon-up { background-image: url(go-up-HC.gif) }
9 10 .icon-cancel { background-image: url(cancel-HC.gif) }
10 11 .icon-person { background-image: url(user_icon.png) }
... ...
test/functional/contact_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,75 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +require 'contact_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class ContactController; def rescue_action(e) raise e end; end
  6 +
  7 +class ContactControllerTest < Test::Unit::TestCase
  8 +
  9 + all_fixtures
  10 +
  11 + def setup
  12 + @controller = ContactController.new
  13 + @request = ActionController::TestRequest.new
  14 + @response = ActionController::TestResponse.new
  15 +
  16 + @profile = create_user('contact_test_user').person
  17 + @enterprise = Enterprise.create!(:identifier => 'contact_test_enterprise', :name => 'Test contact enteprise')
  18 + end
  19 + attr_reader :profile, :enterprise
  20 +
  21 + should 'respond to new' do
  22 + get :new, :profile => enterprise.identifier
  23 + assert_response :success
  24 + end
  25 +
  26 + should 'display destinatary name in title' do
  27 + get :new, :profile => enterprise.identifier
  28 + assert_tag :tag => 'h1', :content => "Contact #{enterprise.name}"
  29 + end
  30 +
  31 + should 'add form to create contact via post' do
  32 + get :new, :profile => enterprise.identifier
  33 + assert_tag :tag => 'form', :attributes => { :action => "/contact/#{enterprise.identifier}/new", :method => 'post' }
  34 + end
  35 +
  36 + should 'display input for destinatary email' do
  37 + get :new, :profile => enterprise.identifier
  38 + assert_tag :tag => 'input', :attributes => { :name => 'contact[email]', :type => 'text' }
  39 + end
  40 +
  41 + should 'display input for message' do
  42 + get :new, :profile => enterprise.identifier
  43 + assert_tag :tag => 'textarea', :attributes => { :name => 'contact[message]' }
  44 + end
  45 +
  46 + should 'add hidden field with target_id' do
  47 + get :new, :profile => enterprise.identifier
  48 + assert_tag :tag => 'input', :attributes => { :name => 'contact[target_id]', :value => enterprise.id, :type => 'hidden' }
  49 + end
  50 +
  51 + should 'add requestor id if logged in' do
  52 + login_as(profile.identifier)
  53 + @controller.stubs(:current_user).returns(profile.user)
  54 + get :new, :profile => enterprise.identifier
  55 + assert_tag :tag => 'input', :attributes => { :name => 'contact[requestor_id]', :value => profile.id }
  56 + end
  57 +
  58 + should 'nil requestor id if not logged in' do
  59 + get :new, :profile => enterprise.identifier
  60 + assert_tag :tag => 'input', :attributes => { :name => 'contact[requestor_id]', :value => nil }
  61 + end
  62 +
  63 + should 'redirect to profile page after contact' do
  64 + post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :email => 'visitor@mail.invalid', :message => 'Hi, all', :target_id => enterprise.id}
  65 + assert_response :redirect
  66 + assert_redirected_to :controller => 'profile', :profile => enterprise.identifier
  67 + end
  68 +
  69 + should 'be able to send contact' do
  70 + assert_difference Contact, :count do
  71 + post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :email => 'visitor@mail.invalid', :message => 'Hi, all', :target_id => enterprise.id}
  72 + end
  73 + end
  74 +
  75 +end
... ...
test/functional/profile_controller_test.rb
... ... @@ -249,7 +249,7 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
249 249 get :index, :profile => 'my-test-enterprise'
250 250 assert_tag :tag => 'a', :attributes => { :href => '/catalog/my-test-enterprise'}, :content => /Products\/Services/
251 251 end
252   -
  252 +
253 253 should 'not display "Products" link for enterprise if environment do not let' do
254 254 env = Environment.default
255 255 env.enable('disable_products_for_enterprises')
... ... @@ -304,4 +304,21 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
304 304 assert_no_tag :content => /t2@t2.com/
305 305 end
306 306  
  307 + should 'display contact us for enterprises' do
  308 + ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise')
  309 + get :index, :profile => 'my-test-enterprise'
  310 + assert_tag :tag => 'a', :attributes => { :href => "/contact/my-test-enterprise/new" }, :content => 'Contact us'
  311 + end
  312 +
  313 + should 'not display contact us for non-enterprises' do
  314 + get :index, :profile => @profile.identifier
  315 + assert_no_tag :tag => 'a', :attributes => { :href => "/contact/#{@profile.identifier}/new" }, :content => 'Contact us'
  316 + end
  317 +
  318 + should 'display contact us only if enabled' do
  319 + ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise', :enable_contact_us => false)
  320 + get :index, :profile => 'my-test-enterprise'
  321 + assert_no_tag :tag => 'a', :attributes => { :href => "/contact/my-test-enterprise/new" }, :content => 'Contact us'
  322 + end
  323 +
307 324 end
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -517,4 +517,10 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
517 517 :attributes => { :name=>'profile_data[email]', :value=>'teste_user@teste.com' }
518 518 end
519 519  
  520 + should 'display enable contact us for enterprise' do
  521 + org = Enterprise.create!(:name => 'test org', :identifier => 'testorg')
  522 + get :edit, :profile => 'testorg'
  523 + assert_tag :tag => 'input', :attributes => {:name => 'profile_data[enable_contact_us]', :type => 'checkbox'}
  524 + end
  525 +
520 526 end
... ...
test/functional/tasks_controller_test.rb
... ... @@ -151,4 +151,16 @@ class TasksControllerTest &lt; Test::Unit::TestCase
151 151  
152 152 assert_equal f, assigns(:ticket).target
153 153 end
  154 +
  155 + should 'list enterprise contacts' do
  156 + ent = Enterprise.create!(:identifier => 'contact_test_enterprise', :name => 'Test contact enteprise')
  157 + task = Contact.create!(:subject => 'test', :target_id => profile.id, :email => 'visitor@invalid.com', :message => 'Hi, all')
  158 +
  159 + login_as(profile.identifier)
  160 + get :index, :profile => ent.identifier
  161 +
  162 + assert_includes assigns(:tasks), task
  163 + assert_tag :tag => 'li', :attributes => { :class => 'task-Contact' }, :content => 'Someone sent a new message'
  164 + end
  165 +
154 166 end
... ...
test/integration/routing_test.rb
... ... @@ -186,4 +186,8 @@ class RoutingTest &lt; ActionController::IntegrationTest
186 186 assert_routing('/myprofile/profile.withdot', :controller => 'profile_editor', :action => 'index', :profile => 'profile.withdot')
187 187 end
188 188  
  189 + def test_contact_routing
  190 + assert_routing('/contact/wintermute/new', :controller => 'contact', :action => 'new', :profile => 'wintermute')
  191 + end
  192 +
189 193 end
... ...
test/unit/contact_test.rb 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ContactTest < ActiveSupport::TestCase
  4 +
  5 + should 'have serialized data' do
  6 + t = Contact.new
  7 + t.data[:test] = 'test'
  8 +
  9 + assert_equal({:test => 'test'}, t.data)
  10 + end
  11 +
  12 + should 'validates required fields' do
  13 + contact = Contact.new
  14 + assert !contact.valid?
  15 + contact.subject = 'Hi'
  16 + assert !contact.valid?
  17 + contact.email = 'visitor@invalid.com'
  18 + assert !contact.valid?
  19 + contact.message = 'Hi, all'
  20 + assert !contact.valid?
  21 + contact.target = create_user('contact_user_test').person
  22 + assert contact.save!
  23 + end
  24 +
  25 +end
... ...
test/unit/enterprise_test.rb
... ... @@ -211,5 +211,9 @@ class EnterpriseTest &lt; Test::Unit::TestCase
211 211 assert_kind_of Enterprise, p.template
212 212 end
213 213  
  214 + should 'contact us enabled by default' do
  215 + e = Enterprise.create!(:name => 'test_com', :identifier => 'test_com', :environment => Environment.default)
  216 + assert e.enable_contact_us
  217 + end
214 218  
215 219 end
... ...